// -*- c++ -*-
// PCF File Format from /xc/lib/font/bitmap/pcfread.c,pcfwrite.c
// miscellaneous definition ///////////////////////////////////////////////////
/* Type names are 'TypeSize_Endien'.
* name Type Size(bits) Endien
* --------------- --------------- --------------- -------
* char8 char 8 none
* bool8 bool 8 none
* int32_little int 32 big
* type32_little type32 32 big
* format32_little format32 32 big
* etc.
* In the *SECTION*, the endieness is determined by the format.byte
*/
enum type32 {
PCF_PROPERTIES = (1 << 0),
PCF_ACCELERATORS = (1 << 1),
PCF_METRICS = (1 << 2),
PCF_BITMAPS = (1 << 3),
PCF_INK_METRICS = (1 << 4),
PCF_BDF_ENCODINGS = (1 << 5),
PCF_SWIDTHS = (1 << 6),
PCF_GLYPH_NAMES = (1 << 7),
PCF_BDF_ACCELERATORS = (1 << 8),
};
struct format32 {
uint32 format:24; // format << 8
uint32 dummy:2; // = 0 padding << 6
uint32 scan:2; // bitmap scan unit is (1 << scan) bytes << 4
uint32 bit:1; // 0:LSBbit first, 1:MSBit first << 3
uint32 byte:1; // 0:LSByte first, 1:MSByte first << 2
uint32 glyph:2; // glyph pad is (1 << glyph) bytes << 0
};
// format32.format is one of the followings
#define PCF_DEFAULT_FORMAT 0
#define PCF_INKBOUNDS 2
#define PCF_ACCEL_W_INKBOUNDS 1
#define PCF_COMPRESSED_METRICS 1
struct metric_t
{
int16 leftSideBearing;
int16 rightSideBearing;
int16 characterWidth;
int16 ascent;
int16 descent;
int16 attributes;
};
struct compressedMetric_t
{
uint8 leftSideBearing; // - 0x80 == metric_t.leftSideBearing
uint8 rightSideBearing; // - 0x80 == metric_t.rightSideBearing
uint8 characterWidth; // - 0x80 == metric_t.characterWidth
uint8 ascent; // - 0x80 == metric_t.ascent
uint8 descent; // - 0x80 == metric_t.descent
};
#define GLYPHPADOPTIONS 4 // 1, 2, 4, or 8
#define MAKE_CHARCODE(row,col) (row * 256 + col)
// begining of the PCF file ///////////////////////////////////////////////////
// table of contents
char8[4] version = { 'p', 'c', 'f', 1 };
int32_little nTables;
struct table_t { // sections
type32_little type; // type of this section
format32_little format; // format of this section
int32_little size; // size of this section
int32_little offset; // offset of this section from the begining of the file
} tables[nTables];
/*** SECTION ***/
// properties section (tables[i].type = PCF_PROPERTIES)
format32_little format; // format.id = PCF_DEFAULT_FORMAT
int32 nProps;
struct {
int32 name; // offset from &string[0]
bool8 isStringProp; // is this property is string ?
int32 value; // isStringProp ? offset from &string[0]
} props[nProps];
byte8 dummy[3 - ((sizeof(props) + 3) % 4)]; // padding
int32 stringSize;
char8 string[stringSize]; // pointed by property_t.{name,value}
/*** SECTION ***/
// old accelerators section (tables[i].type = PCF_ACCELERATORS)
/* if PCF_BDF_ACCELERATORS section exists, this section is omitted. */
format32_little format; // format.id = PCF_DEFAULT_FORMAT
// // or PCF_ACCEL_W_INKBOUNDS
bool8 noOverlap;
bool8 constantMetrics;
bool8 terminalFont;
bool8 constantWidth;
bool8 inkInside;
bool8 inkMetrics;
bool8 drawDirection;
bool8 dummy; // padding
int32 fontAscent;
int32 fontDescent;
int32 maxOverlap;
metric_t minBounds;
metric_t maxBounds;
#if format.id == PCF_ACCEL_W_INKBOUNDS
metric_t ink_minBounds;
metric_t ink_maxBounds;
#endif
/*** SECTION ***/
// metrics section (tables[i].type = PCF_METRICS)
format32_little format; // format.id = PCF_DEFAULT_FORMAT
// // or PCF_COMPRESSEDMETRICS
#if format.id == PCF_DEFAULT_FORMAT
int32 nMetrics;
metric_t metrics[nMetrics];
#else
int16 nMetrics;
compressedMetric_t cmetrics[nMetrics];
#end
/*** SECTION ***/
// bitmaps section (tables[i].type = PCF_BITMAPS)
format32_little format; // format.id = PCF_DEFAULT_FORMAT
int32 nBitmaps; // == nMetrics
uint32 bitmapOffsets[nBitmaps];
uint32 bitmapSizes[GLYPHPADOPTIONS];
byte8 bitmaps[bitmapSizes[format.glyph]];
/* if (format.bit != THIS_MACHINE.bit)
* BitOrderInvert(bitmaps, sizeof(bitmaps));
* if ((format.bit == format.byte) != * (THIS_MACHINE.bit == THIS_MACHINE.byte)) {
* switch (1 << (THIS_MACHINE.bit == THIS_MACHINE.byte ?
* format.scan : THIS_MACHINE.scan)) {
* case 1: break;
* case 2: TwoByteSwap(bitmaps, sizeof(bitmaps)); break;
* case 4: FourByteSwap(bitmaps, sizeof(bitmaps)); break;
* }
* } */
/* each line of the bitmaps is aligned by 1<<format.glyph bytes. */
/*** SECTION ***/
// ink metrics secion (tables[i].type = PCF_INK_METRICS)
/* this section may be omitted */
/* same as PCF_METRICS */
/*** SECTION ***/
// encodings section (tables[i].type = PCF_BDF_ENCODINGS)
format32_little format; // format.id = PCF_DEFAULT_FORMAT
int16 firstCol;
int16 lastCol;
int16 firstRow;
int16 lastRow;
int16 defaultCh; // default char or NO_SUCH_CHAR (= -1)
int16 encodings[n];
/* |0 firstCol lastCol 255
* row\column |v v v v
* -----------+---------------------
* 0->|
* firstRow->|A B C D E F G H
* |I J K L M N O P
* |Q R S T U V W X
* lastRow->|Y Z a b c d e f
* 255->|
*
* The charcode MAKE_CHARCODE(firstCol, firstRow)'s metrics is metrics[B].
* And, encodings = { B,C,D,E,F,G, J,K,L,M,N,O, R,S,T,U,V,W, Z,a,b,c,d,e, };
* If Z == 0xffff, then the charcode MAKE_CHARCODE(firstCol, lastRow) does not
* exist. */
/*** SECTION ***/
// swidths section (tables[i].type = PCF_SWIDTHS)
/* this section may be omitted */
format32_little format; // format.id = PCF_DEFAULT_FORMAT
int32 nSwidths; // == nMetrics
int32 swidths[nSwidths];
/*** SECTION ***/
// glyph names section (tables[i].type = PCF_GLYPH_NAMES)
/* this section may be omitted */
format32_little format; // format.id = PCF_DEFAULT_FORMAT
int32 nGlyphNames; // == nMetrics
int32 glyphNameOffsets[nGlyphNames]; // offset from &glyph_names[0]
int32 glyphNamesSize;
char8 glyphNames[glyphNamesSize]; // pointed by glyphNameOffsets[]
/*** SECTION ***/
// BDF style accelerators section (tables[i].type = PCF_BDF_ACCELERATORS)
/* if PCF_ACCELERATORS section exists, this section is omitted. */
/* same as PCF_ACCELERATORS */
// end of the PCF file ////////////////////////////////////////////////////////
|