#1 PDF Engine » Added alpha blending to SynPDF. How to cleanly modify the pdf layer? » Yesterday 15:19:57

hukmac
Replies: 0

Subtopic: ExtGState injection + xref handling in SynPDF - How to do it cleanly?

Hello,

I'm adding support for alpha blending to SynPDF. What I have now looks promising. Example of alpha blending generated with updated SynPDF as an effect of drawing on a canvas with GDI:

synpdf-alpha.png

Unfortunately I'm struggling with the layer of pdf creation. So I have a question related to the definition of PDF structures which I need to add to the PDF file to make it work nicely. What I have now is a dirty proof-of-concept solution, and I know I should improve it but I have problems doing it. So here goes the question to SynPDF developers.

Changes needed to appear in the structure of the generated PDF (example):

1. ExtGState definition object, e.g. directly after the header:

 25 0 obj << /Type /ExtGState /ca 0.1 /CA 0.1 >> 

2. Declaration of the ExtGState object in the Resources dictionary in the catalog object, e.g.:

 /Resources << /ExtGState << /GS1 25 0 R >> ... 

3. Update the xref structure to include information about object 25 (defined in point 1).

4. It would be great if I could force the ID of the object to be as I want (e.g. 1000025).
While this is against the automatic ID assignment done by SynPDF, it would be good to be able to override it. But I can live without it.


What I managed to do to achieve the above (assuming that 25 is not colliding with IDs of the other objects in the PDF file):

Ad. 2: Adding a predefined declaration of the object to the Resources dictionary — in function TPdfDocument.AddPage: TPdfPage;
with:

  FResources.AddItem('ExtGState', TPdfRawText.Create('<</GS1 25 0 R>>'));

Ad. 1: Adding the object by "manually" injecting it into the output stream just after the header — at the end of the procedure TPdfDocument.SaveToStreamDirectBegin;
with:

  fSaveToStreamWriter.Add('25 0 obj << /Type /ExtGState /ca 0.1 /CA 0.1 >>');

Ad. 3: While I was unable to actually create/register the above objects in SynPDF structures, the xref structure is not correct. A very, very dirty temporary solution I found is invalidating the xref address (found after startxref at the end of the PDF file) to force its regeneration by the Acrobat Reader. I'm doing it in the procedure TPdfDocument.SaveToStreamDirectEnd;
with:

  FTrailer.XrefAddress := fSaveToStreamWriter.Position - 2;

The above "works" as a proof of concept, but I would like to improve it — at least by properly registering an object in SynPDF structures (point 1) and making xref valid (point 3).

I would be grateful for advices — e.g. to which internal object and in which method I should add the object (point 1), and how to create it according to the SynPDF rules.

BR,
Ami

Board footer

Powered by FluxBB