1The X11 PCF bitmap font file format
2===================================
3
4This file is based on the
5`X11 sources <http://ftp.x.org/pub/R6.4/xc/lib/font/bitmap/>`__. If something
6here disagrees with what is found in the sources, my statement is incorrect. The
7sources are definitive.
8
9The pcf (portable compiled format) file format is a binary representation of a
10bitmap font used by the XServer. It consists of a file header followed by a
11series of tables, with the header containing pointers to all the tables.
12
13
14File Header
15-----------
16
17The file header contains 32 bit integers stored with the least significant byte
18first.
19
20.. highlight:: c
21
22::
23
24   char header[4];                  /* always "\1fcp" */
25   lsbint32 table_count;
26   struct toc_entry {
27       lsbint32 type;              /* See below, indicates which table */
28       lsbint32 format;            /* See below, indicates how the data are formatted in the table */
29       lsbint32 size;              /* In bytes */
30       lsbint32 offset;            /* from start of file */
31   } tables[table_count];
32
33The type field may be one of:
34
35::
36
37   #define PCF_PROPERTIES               (1<<0)
38   #define PCF_ACCELERATORS            (1<<1)
39   #define PCF_METRICS                 (1<<2)
40   #define PCF_BITMAPS                 (1<<3)
41   #define PCF_INK_METRICS             (1<<4)
42   #define PCF_BDF_ENCODINGS           (1<<5)
43   #define PCF_SWIDTHS                 (1<<6)
44   #define PCF_GLYPH_NAMES             (1<<7)
45   #define PCF_BDF_ACCELERATORS        (1<<8)
46
47The format field may be one of:
48
49::
50
51   #define PCF_DEFAULT_FORMAT       0x00000000
52   #define PCF_INKBOUNDS           0x00000200
53   #define PCF_ACCEL_W_INKBOUNDS   0x00000100
54   #define PCF_COMPRESSED_METRICS  0x00000100
55
56The format field may be modified by:
57
58::
59
60   #define PCF_GLYPH_PAD_MASK       (3<<0)            /* See the bitmap table for explanation */
61   #define PCF_BYTE_MASK           (1<<2)            /* If set then Most Sig Byte First */
62   #define PCF_BIT_MASK            (1<<3)            /* If set then Most Sig Bit First */
63   #define PCF_SCAN_UNIT_MASK      (3<<4)            /* See the bitmap table for explanation */
64
65The format will be repeated as the first word in each table. Most tables only
66have one format (default), but some have alternates. The high order three bytes
67of the format describe the gross format. The way integers and bits are stored
68can be altered by adding one of the mask bits above.
69
70All tables begin on a 32bit boundary (and will be padded with zeroes).
71
72
73Properties Table
74----------------
75
76::
77
78   lsbint32 format;                 /* Always stored with least significant byte first! */
79   int32 nprops;                   /* Stored in whatever byte order is specified in the format */
80   struct props {
81       int32 name_offset;          /* Offset into the following string table */
82       int8 isStringProp;
83       int32 value;                /* The value for integer props, the offset for string props */
84   } props[nprops];
85   char padding[(nprops&3)==0?0:(4-(nprops&3))];   /* pad to next int32 boundary */
86   int string_size;                /* total size of all strings (including their terminating NULs) */
87   char strings[string_size];
88   char padding2[];
89
90These properties are the Font Atoms that X provides to users. Many are described
91in
92`xc/doc/specs/XLFD/xlfd.tbl.ms <http://ftp.x.org/pub/R6.4/xc/doc/specs/XLFD/xlfd.tbl.ms>`__
93or
94`here <http://rpmfind.net/linux/RPM/redhat/6.2/i386/XFree86-doc-3.3.6-20.i386.html>`__
95(the X protocol does not limit these atoms so others could be defined for some
96fonts).
97
98To find the name of a property: ``strings + props[i].name_offset``
99
100
101.. _pcf-format.MetricsData:
102
103Metrics Data
104------------
105
106Several of the tables (PCF_METRICS, PCF_INK_METRICS, and within the accelerator
107tables) contain metrics data which may be in either compressed
108(PCF_COMPRESSED_METRICS) or uncompressed (DEFAULT) formats. The compressed
109format uses bytes to contain values, while the uncompressed uses shorts. The
110(compressed) bytes are unsigned bytes which are offset by 0x80 (so the actual
111value will be ``(getc(pcf_file)-0x80)``. The data are stored as:
112
113Compressed
114
115::
116
117   uint8 left_sided_bearing;
118   uint8 right_side_bearing;
119   uint8 character_width;
120   uint8 character_ascent;
121   uint8 character_descent;
122    /* Implied character attributes field = 0 */
123
124Uncompressed
125
126::
127
128   int16 left_sided_bearing;
129   int16 right_side_bearing;
130   int16 character_width;
131   int16 character_ascent;
132   int16 character_descent;
133   uint16 character_attributes;
134
135This provides the data needed for an XCharStruct.
136
137
138Accelerator Tables
139------------------
140
141These data provide various bits of information about the font as a whole. This
142data structure is used by two tables PCF_ACCELERATORS and PCF_BDF_ACCELERATORS.
143The tables may either be in DEFAULT format or in PCF_ACCEL_W_INKBOUNDS (in which
144case they will have some extra metrics data at the end.
145
146The accelerator tables look like:
147
148::
149
150   lsbint32 format;                 /* Always stored with least significant byte first! */
151   uint8 noOverlap;                /* if for all i, max(metrics[i].rightSideBearing - metrics[i].characterWidth) */
152                                   /*      <= minbounds.leftSideBearing */
153   uint8 constantMetrics;          /* Means the perchar field of the XFontStruct can be NULL */
154   uint8 terminalFont;             /* constantMetrics true and forall characters: */
155                                   /*      the left side bearing==0 */
156                                   /*      the right side bearing== the character's width */
157                                   /*      the character's ascent==the font's ascent */
158                                   /*      the character's descent==the font's descent */
159   uint8 constantWidth;            /* monospace font like courier */
160   uint8 inkInside;                /* Means that all inked bits are within the rectangle with x between [0,charwidth] */
161                                   /*  and y between [-descent,ascent]. So no ink overlaps another char when drawing */
162   uint8 inkMetrics;               /* true if the ink metrics differ from the metrics somewhere */
163   uint8 drawDirection;            /* 0=>left to right, 1=>right to left */
164   uint8 padding;
165   int32 fontAscent;               /* byte order as specified in format */
166   int32 fontDescent;
167   int32 maxOverlap;               /* ??? */
168   Uncompressed_Metrics minbounds;
169   Uncompressed_Metrics maxbounds;
170   /* If format is PCF_ACCEL_W_INKBOUNDS then include the following fields */
171       Uncompressed_Metrics ink_minbounds;
172       Uncompressed_Metrics ink_maxbounds;
173   /* Otherwise those fields are not in the file and should be filled by duplicating min/maxbounds above */
174
175BDF Accelerators should be preferred to plain Accelerators if both tables are
176present. BDF Accelerators contain data that refers only to the encoded
177characters in the font (while the simple Accelerator table includes all glyphs),
178therefore the BDF Accelerators are more accurate.
179
180
181Metrics Tables
182--------------
183
184There are two different metrics tables, PCF_METRICS and PCF_INK_METRICS, the
185former contains the size of the stored bitmaps, while the latter contains the
186minimum bounding box. The two may contain the same data, but many CJK fonts pad
187the bitmaps so all bitmaps are the same size. The table format may be either
188DEFAULT or PCF_COMPRESSED_METRICS (see the section on
189:ref:`Metrics Data <pcf-format.MetricsData>` for an explanation).
190
191::
192
193   lsbint32 format;                 /* Always stored with least significant byte first! */
194   /* if the format is compressed */
195       int16 metrics_count;
196       Compressed_Metrics metrics[metrics_count];
197   /* else if format is default (uncompressed) */
198       int32 metrics_count;
199       Uncompressed_Metrics metrics[metrics_count];
200   /* endif */
201
202
203The Bitmap Table
204----------------
205
206The bitmap table has type PCF_BITMAPS. Its format must be PCF_DEFAULT.
207
208::
209
210   lsbint32 format;                 /* Always stored with least significant byte first! */
211   int32 glyph_count;              /* byte ordering depends on format, should be the same as the metrics count */
212   int32 offsets[glyph_count];     /* byte offsets to bitmap data */
213   int32 bitmapSizes[4];           /* the size the bitmap data will take up depending on various padding options */
214                                   /*  which one is actually used in the file is given by (format&3) */
215   char bitmap_data[bitmapsizes[format&3]];    /* the bitmap data. format contains flags that indicate: */
216                                   /* the byte order (format&4 => LSByte first)*/
217                                   /* the bit order (format&8 => LSBit first) */
218                                   /* how each row in each glyph's bitmap is padded (format&3) */
219                                   /*  0=>bytes, 1=>shorts, 2=>ints */
220                                   /* what the bits are stored in (bytes, shorts, ints) (format>>4)&3 */
221                                   /*  0=>bytes, 1=>shorts, 2=>ints */
222
223
224The Encoding Table
225------------------
226
227The encoding table has type PCF_BDF_ENCODINGS. Its format must be PCF_DEFAULT.
228
229::
230
231   lsbint32 format;                 /* Always stored with least significant byte first! */
232   int16 min_char_or_byte2;        /* As in XFontStruct */
233   int16 max_char_or_byte2;        /* As in XFontStruct */
234   int16 min_byte1;                /* As in XFontStruct */
235   int16 max_byte1;                /* As in XFontStruct */
236   int16 default_char;             /* As in XFontStruct */
237   int16 glyphindeces[(max_char_or_byte2-min_char_or_byte2+1)*(max_byte1-min_byte1+1)];
238                                   /* Gives the glyph index that corresponds to each encoding value */
239                                   /* a value of 0xffff means no glyph for that encoding */
240
241For single byte encodings min_byte1==max_byte1==0, and encoded values are
242between [min_char_or_byte2,max_char_or_byte2]. The glyph index corresponding to
243an encoding is glyphindex[encoding-min_char_or_byte2].
244
245Otherwise [min_byte1,max_byte1] specifies the range allowed for the first (high
246order) byte of a two byte encoding, while [min_char_or_byte2,max_char_or_byte2]
247is the range of the second byte. The glyph index corresponding to a double byte
248encoding (enc1,enc2) is
249glyph_index[(enc1-min_byte1)*(max_char_or_byte2-min_char_or_byte2+1)+
250enc2-min_char_or_byte2].
251
252Not all glyphs need to be encoded. Not all encodings need to be associated with
253glyphs.
254
255
256The Scalable Widths Table
257-------------------------
258
259The encoding table has type PCF_SWIDTHS. Its format must be PCF_DEFAULT.
260
261::
262
263   lsbint32 format;                 /* Always stored with least significant byte first! */
264   int32 glyph_count;              /* byte ordering depends on format, should be the same as the metrics count */
265   int32 swidths[glyph_count];     /* byte offsets to bitmap data */
266
267The scalable width of a character is the width of the corresponding postscript
268character in em-units (1/1000ths of an em).
269
270
271The Glyph Names Table
272---------------------
273
274The encoding table has type PCF_GLYPH_NAMES. Its format must be PCF_DEFAULT.
275
276::
277
278   lsbint32 format;                 /* Always stored with least significant byte first! */
279   int32 glyph_count;              /* byte ordering depends on format, should be the same as the metrics count */
280   int32 offsets[glyph_count];     /* byte offsets to string data */
281   int32 string_size;
282   char string[string_size];
283
284The postscript name associated with each character.
285
286--------------------------------------------------------------------------------
287
288Other sources of info:
289
290* http://www.tsg.ne.jp/GANA/S/pcf2bdf/pcf.pdf
291* http://myhome.hananet.net/~bumchul/xfont/pcf.txt
292