Using ABCPDF draw another doc as an image with rounded corners

273 Views Asked by At

I find ABCPDF is very capable. However, so far I had not managed to find a way to draw one PDF into another with rounded corners - until now. But, the approach I discovered depends on getting the correct PDF object id for the inserted PDF stream, and herein lies the reason for this question.

Anyone who knows ABCPDF will ask why that is an issue ? Does not the addImageDoc() function which embeds one PDF inside another return the PDF object ID ? No - it returns something else - most likely the inserted PDF goes into the document catalogue as an isolated object and what you get in the returned ID is an object that refers to it. Unpacking the document streams seems to bear this out.

Long story short, in my experimenting I found that I needed to insert into the stream a 'Do' call, with the target of that derived as:

imgObjId = addImageDoc(some pdf object)  // inserted off-page 

insert into stream "/Iabc<imgObjId + 1> Do"

For example, if the returned imgObjId value is 5 then I need it to be 6 to make

/Iabc6 Do

Question: Whilst this works OK, I am relying on adding one to the returned value and I wonder how robust that is going to be. Or is there a correct way to achieve this ?

More info: I have kept the question short but readers may be wondering why the above matters? Because to achieve rounded corners you need to construct a stream of PDF commands which has a clipping region defined. Think of a path for a rectangle with Bezier curves for the corners. Having got that, you need to draw an image, or in my case another PDF, into the same context so as to get the clipping effect. After that you can close and reset the graphics state and be a good PDF stack citizen. However, there is no means, other than my approach above, that I can find in ABCPDF to get a handle on the inserted PDF doc stream in the catalogue so as to be able to ask for it to be drawn somewhere else.

Inserting an image seems to be a similar process, except the getinfo() function can discover the pixmap. There appears to be no like approach for an embedded PDF.

1

There are 1 best solutions below

1
On

I don't know if you can change the target abcpdf rectangle prior to do a "AddImageDoc".

Maybe you can do a trick, getting a Bitmap from the source, editing it by changing borders, and adding to a new doc. Something like this:

Dim oDoc As New WebSupergoo.ABCpdf10.Doc
Dim oImg As System.Drawing.Bitmap
oDoc.Read("D:\source.pdf")
oImg = oDoc.Rendering.GetBitmap() 
' image quality can be improved with .Rendering properties as 'AntiAliasImages', etc.
oDoc.Dispose()
oDoc = Nothing

Dim oGraph As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(oImg)
Dim gPath As New System.Drawing.Drawing2D.GraphicsPath
Dim oBrush As New System.Drawing.SolidBrush(System.Drawing.Color.Red) ' only to see the rectangle... white when be ready

gPath.AddRectangle(New System.Drawing.Rectangle(0, 0, oImg.Width, oImg.Height))

' 2 / 100 it's the percent factor for borders
Dim iLeftBorder As Integer = CInt(2 / 100 * (oImg.Width / 2))
Dim iTopBorder As Integer = CInt(2 / 100 * (oImg.Height / 2))
gPath.AddEllipse(New System.Drawing.Rectangle(iLeftBorder, iTopBorder, oImg.Width - (iLeftBorder * 2) - 1, oImg.Height - (iTopBorder * 2) - 1))

oGraph.FillPath(oBrush, gPath)
oBrush.Dispose()
oGraph.Dispose()
oDoc = New WebSupergoo.ABCpdf10.Doc
oDoc.AddImageBitmap(oImg, False)
oDoc.Save("D:\finalpath.pdf")
oDoc.Dispose()
oDoc = Nothing

But it's only a "trick".