Outside stream data, a PDF file is text in a small language taken from PostScript. It has eight kinds of object: booleans, numbers, strings, names, arrays, dictionaries, streams and the null object. Any object can be written inside another, or stand on its own as an indirect object with a number that others refer to. The same rules apply in the body of the file, in the trailer and, with operators added, in content streams.
| Type | Written as | Example |
|---|---|---|
| Boolean | the keywords true and false | true |
| Number | an integer or a real, in decimal | 612, -0.5 |
| String | bytes in parentheses, or hexadecimal in angle brackets | (Hello), <48656C6C6F> |
| Name | a slash and the name | /Type |
| Array | objects in square brackets | [0 0 612 792] |
| Dictionary | pairs of a name and an object in double angle brackets | << /Type /Page >> |
| Stream | a dictionary, then stream, bytes, endstream | page contents, images, fonts |
| Null | the keyword null | null |
White space
Six bytes count as white space. Any run of them separates two tokens and means the same as one space, except inside strings and stream data.
| Byte | Name |
|---|---|
00 | Null (NUL) |
09 | Horizontal tab (HT) |
0A | Line feed (LF) |
0C | Form feed (FF) |
0D | Carriage return (CR) |
20 | Space (SP) |
CR and LF are also the end-of-line markers. CR LF together is one line end.
Delimiters
Ten characters end a token without any white space before them:
( ) < > [
] { } / %. So
/Type/Page is two names and [1 2] is an array of two
numbers. Braces are used only in PostScript calculator functions. Every other
character is a regular character, part of the token it is in: numbers, names and
keywords such as obj and R are runs of regular characters.
Booleans
The keywords true and false, in lower case. They are used
for flags in dictionaries, such as /ImageMask true.
Numbers
There are two kinds, written in decimal:
- Integers: an optional sign and digits, such as
43,+17,-98,0. - Reals: an optional sign, digits and one decimal point, such as
34.5,-3.62,4.,-.002.
There is no exponent form (6.02E23 is not a number) and no other
radix. Where a real is expected, an integer is accepted and converted. Integers are
used for counts, object numbers and offsets; everything that measures is usually a
real.
Strings
A string is a run of bytes. It can be written in two ways that mean the same.
Literal strings
Bytes between parentheses: (This is a string). Balanced
parentheses inside need no escape, so (a (b) c) is one string. A
backslash starts an escape:
| Escape | Byte |
|---|---|
\n | Line feed, 0A |
\r | Carriage return, 0D |
\t | Horizontal tab, 09 |
\b | Backspace, 08 |
\f | Form feed, 0C |
\( | Left parenthesis |
\) | Right parenthesis |
\\ | Backslash |
\ddd | The byte with octal value ddd: one to three digits, so \053 and \53 are both + |
\ at the end of a line | Nothing: the string continues on the next line |
A backslash before any other character is ignored. A line end inside a literal string, whether CR, LF or CR LF, is read as a single LF. Bytes 128 to 255 can be written as they are, or as octal escapes in files that must stay 7-bit.
Hexadecimal strings
Pairs of hexadecimal digits between angle brackets:
<4E6F762073686D6F7A206B6120706F702E>. Upper and lower case
are the same, and white space between digits is ignored. If the number of digits
is odd, the last digit is taken as followed by 0: <901FA> is
the bytes 90 1F A0. Writers use this form for binary data such as the
file identifier in the trailer.
Names
A name is a slash followed by regular characters: /Type,
/FlateDecode, /A;Name_With-Various***Characters?. The slash
is not part of the name. Names are case-sensitive, so /Type and
/type differ, and two names with the same characters are the same
object. The slash alone, /, is a valid empty name.
From PDF 1.2 a # followed by two hexadecimal digits stands for one
byte. It lets a name hold white space, delimiters and bytes outside 33 to 126:
| Written | Name |
|---|---|
/Lime#20Green | Lime Green |
/paired#28#29parentheses | paired()parentheses |
/The_Key_of_F#23_Minor | The_Key_of_F#_Minor |
/A#42 | AB |
In PDF 1.0 and 1.1 files # was an ordinary character, so a reader
meets the rare old name with a # in it that does not mean a byte.
Names are bytes, not text; where they are shown to a reader they are taken as
UTF-8.
Arrays
Objects between square brackets, separated by white space where needed:
[549 3.14 false (Ralph) /SomeName]. The objects need not be of one
type, and an array can hold other arrays. An array is one-dimensional; a matrix is
written as an array of six numbers.
Dictionaries
Pairs of a key and a value between << and >>.
The key is always a name; the value is any object, a dictionary included:
<< /Type /Example
/Subtype /DictionaryExample
/Version 0.01
/IntegerItem 12
/StringItem (a string)
/Subdictionary << /Item1 0.4 /Item2 true /LastItem (not!) >>
>>
Keys should be unique within a dictionary; with duplicates, which value a reader
takes is undefined. A key whose value is null is the same as a key that
is missing. Order means nothing. Most dictionaries have a /Type entry
naming what they are, such as /Page or /Font, and often a
/Subtype; readers should accept unknown keys and ignore them.
Streams
A stream is a dictionary followed by a run of bytes of any length:
4 0 obj
<< /Length 44 >>
stream
BT /F1 24 Tf 100 700 Td (Hello, world) Tj ET
endstream
endobj
The keyword stream is followed by CR LF or by LF alone, never by CR
alone, and the data starts on the next byte. Length says how many
bytes the data has, not counting that line end; there should be a line end before
endstream, which is not counted either. Length may be an
indirect reference, so a writer can give it after the data, as in
/Length 5 0 R. A stream is always an indirect object. Its dictionary
can name filters that compress or encode the data; see
Streams and filters.
Null
The keyword null. It stands for no value. A reference to an object
that does not exist, or that is free in the cross-reference table, also gives null
rather than an error.
Indirect objects
Any object can be made indirect by giving it an object number and a generation
number and wrapping it in obj and endobj:
12 0 obj
(Brillig)
endobj
- The object number is a positive integer. Object 0 is never used; it heads the free list.
- The generation number is a non-negative integer, at most 65,535. It is 0 in a newly written file and goes up by one each time a number is freed and used again in an incremental update.
- The pair of numbers identifies the object. The
cross-reference table
gives the byte offset at which
12 0 objbegins.
Some objects must be indirect, such as streams, pages and the catalog. Others,
such as the number in a Length, may be either.
References
An indirect object is used elsewhere by a reference: its object number, its
generation number and the keyword R, as in 12 0 R. A
reference can stand wherever the object itself could, except as a dictionary key.
The reader looks the number up in the cross-reference table and reads the object
there when it needs it. References let objects share data and point at each other
in loops, as pages point at their parent and the parent at its pages.
Because 12 0 R looks like two integers followed by a keyword, a
reader parsing an array such as [1 0 R 2 0 R] has to look two tokens
ahead before it knows that two numbers are a reference.
Text strings
Strings that are meant for people, such as a title, an outline entry or an annotation’s text, are text strings. They are encoded one of two ways:
- PDFDocEncoding, a single-byte encoding defined by the PDF specification. Its printable ASCII range is the same as ASCII, and bytes above 127 hold Latin letters and typographic marks such as curly quotes, dashes and the bullet.
- UTF-16BE, from PDF 1.2: the string starts with the byte order
mark
FE FF, then two bytes a code unit, high byte first. Characters outside the Basic Multilingual Plane take a surrogate pair. A reader that only knows PDFDocEncoding showsFE FFas þÿ, which is how such strings look in old tools.
Strings used inside content streams to show text are not text strings: their bytes are character codes in the font’s encoding. See Fonts.
Dates
A date is a string in the form (D:YYYYMMDDHHmmSSOHH'mm'):
| Part | Meaning |
|---|---|
D: | The prefix, recommended but optional |
YYYY | The year; the only part that must be there |
MM DD | Month 01–12 and day 01–31 |
HH mm SS | Hour 00–23, minute and second 00–59 |
O | The relation to UTC: +, - or Z |
HH'mm' | The offset from UTC in hours and minutes |
Parts can be left off from the end; missing ones default to the first month, the
first day and zero. (D:20060214123151-08'00') is 14 February 2006,
12:31:51, eight hours behind UTC. Readers should be lenient: old files hold dates
with a two-digit year or no time zone.
Rectangles
A rectangle is an array of four numbers, the coordinates of two opposite corners,
usually the lower left and the upper right: [0 0 612 792] is a US
Letter page, 8.5 by 11 inches at 72 units an inch. A reader should normalise the
corners, because some writers give them the other way round.
Limits
The format sets no limits, but Adobe’s references list those of Acrobat, and writers keep within them so that files open everywhere. The values below are Acrobat’s on 32-bit computers, as listed in ISO 32000-1:
| What | Limit |
|---|---|
| Integer | −2,147,483,648 to 2,147,483,647 |
| Real | about ±3.403 × 1038 |
| String | 32,767 bytes |
| Name | 127 bytes |
| Indirect objects | 8,388,607 |
Nested q (saved graphics states) | 28 |
Comments
A
%outside a string or a stream starts a comment that runs to the end of the line. It counts as white space. The header%PDF-1.4and the%%EOFmarker are comments that readers look for on purpose.