Daniel When not delving into obscure PDF or Java bugs, Daniel is exploring the new features in JavaFX.

Make your own PDF file – Part 6: Graphics State

1 min read

This is part of a series on How to make your own PDF files.

It would be nice to get some color on the screen this time round and in doing so give a introduction to the Graphics State.  Associated with a Pdf file is a Graphics State.  This data structure holds information that describe how graphics are rendered to the screen.  Values such as what the current colour is and what colours are available are stored in the Graphics State.  As well as weird and wonderful elements like the current clip, the transformation matrix, funny things you can do with lines and other instructions that alter the way the graphics will be rendered from the user space (The coordinates system of the Pdf) to the device space (the monitor).

As there is just one Graphics State available and a Pdf may contains lots of graphics objects that may want to do entirely different things, the current graphics state is usually stored when a object stream is going to draw something.  The graphics state is stored on a stack with the q command.  Captial Q pops back the previously stored graphics state.

The Graphics State also has an associated colorspace.  A Colorspace basically describes what colours are available and how they are rendered to the current page.  They can be defined yourself and there are also default ones that the a Pdf viewer has to know about.  For example, there is DeviceGray (Grayscale colours) , DeviceRGB (red-green-blue)  and a load more that represent colour in different ways.  We’re going to stick with DeviceRGB for this article.  If you want to learn a bit more about colorspaces Mark has done an article on color in Pdf files.

One way to define which colorspace is selected is by using an ExtGState (external graphics state) dictionary.  This is used in the same way as Font is accessed in the resource dictionary that I discussed in Hello World Pdf.  You associate a ExtGState with a reference like /GS1 and then get at the colour space that way using the gs command.  Fortunatly, you dont have to bother with that for the default ones so you should find that an object stream containing:

0.9 0.5 0.0 rg 100 400 300 300 re f

Will draw an orange box on the screen.  The rg command set the colour space to DeviceRGB and describes the red/green/blue components (maximum 1.0 and minimum 0.0) of the colour used to fill the rectangle (If you use a capital RG it represents the stroke colour to use).  The following Pdf documents draws three coloured rectangles on a page, note how the graphic state is stored and restored.

%PDF-2.0
1 0 obj <</Type /Catalog /Pages 2 0 R>>
endobj
2 0 obj <<MediaBox [0 0 500 800]>>
endobj
3 0 obj <</Type /Page /Parent 2 0 R /Contents 4 0 R>>
endobj
4 0 obj
<</Length 105>>
stream
0.9 0.5 0.0 rg 100 400 300 300 re f q 0.1 0.9 0.5 rg 100 200 200 200 re f Q 350 200 50 50 re f
endstream
endobj
xref
0 5
0000000000 65535 f
0000000010 00000 n
0000000059 00000 n
0000000140 00000 n
0000000203 00000 n
trailer <</Size 5/Root 1 0 R>>
startxref
352
%%EOF

Final Words

And that’s it. We are done. Congratulations on manually creating your own PDF file. I hope you at least appreciate how complex it is, and why we generally recommend using software libraries to do it.



Our software libraries allow you to

Convert PDF files to HTML
Use PDF Forms in a web browser
Convert PDF Documents to an image
Work with PDF Documents in Java
Read and write HEIC and other Image formats in Java
Daniel When not delving into obscure PDF or Java bugs, Daniel is exploring the new features in JavaFX.

7 Replies to “Make your own PDF file – Part 6: Graphics…”

  1. Hello!
    First of all thanks for this amazing tutorial, it helps me a lot!

    The example code has an error in the “2 0 obj >”, is missing the Page Tree information. I tried to replace with this: “2 0 obj <>” and works fine!

  2. Ops, sorry about the comment. It seems the website does not permit some characters in the comment section.

    The correct code is 2 0 obj <>

  3. Thank you very much for this Tutorial!
    It is fantastic to learn to write plotting routines for pdfs, without having to read hundreds of pages in the reference manual.
    When I tried the code an error occured and I tried to replace the 4th line in the example with:
    2 0 obj <>
    which was used in the previous example and it worked.

  4. The pdf created from copy/pasting this example won’t open because the line for the 2nd obj is wrong. It needs to be:

    2 0 obj <>

  5. 2 0 obj <<⁄Type ⁄Pages ⁄Kids [3 0 R] ⁄Count 1 ⁄MediaBox [0 0 500 800]>>

    (Needed to escape the “<” because of html)

  6. I had a silly idea: replace references by their value. This lets you delete most of the xref table. I wonder how horrible the performance would be on a real world pdf if you did this, or if it would crash. I removed the /Parent key because I didn’t know how to best handle that…

    %PDF-1.6
    xref
    0 1
    0000000000 65535 f
    trailer <</Size 1/Root <</Type /Catalog /Pages <</Type /Pages /Kids [<</Type /Page /Contents <>
    stream
    .9 1 0 rg 220 400 180 300 re f q .1 .9 .5 rg 100 200 200 200 re f Q 350 200 50 51 re 35 200 50 51 re f
    endstream
    >>] /Count 1 /MediaBox [0 0 500 800]>>>>>>
    startxref
    9
    %%EOF

Comments are closed.