pax_global_header00006660000000000000000000000064125263141420014512gustar00rootroot0000000000000052 comment=8ec5bb9fc7633e3282c98a8af0cf8d1c63b7a75a pcf2bdf-1.05/000077500000000000000000000000001252631414200127455ustar00rootroot00000000000000pcf2bdf-1.05/Makefile.gcc000066400000000000000000000010441252631414200151370ustar00rootroot00000000000000# Makefile for pcf2bdf (gcc) -*- makefile -*- CFLAGS ?= -Wall -O2 CXXFLAGS ?= -Wall -O2 PREFIX ?= /usr/local BINPATH ?= $(PREFIX)/bin MANPATH ?= $(PREFIX)/share/man/man1 INSTALL ?= install INSTALL_PROGRAM ?= $(INSTALL) INSTALL_DATA ?= $(INSTALL) -m 644 INSTALL_DIR ?= $(INSTALL) -d all: pcf2bdf clean: rm -f pcf2bdf pcf2bdf.exe pcf2bdf.o *~ install: all $(INSTALL_DIR) $(DESTDIR)$(BINPATH) $(INSTALL_PROGRAM) pcf2bdf $(DESTDIR)$(BINPATH) $(INSTALL_DIR) $(DESTDIR)$(MANPATH) $(INSTALL_DATA) pcf2bdf.man $(DESTDIR)$(MANPATH)/pcf2bdf.1 pcf2bdf-1.05/Makefile.vc000066400000000000000000000003271252631414200150160ustar00rootroot00000000000000# Makefile for pcf2bdf (Visual C++ 5.0) -*- makefile -*- CXX = cl CXXFLAGS = /O2 RM = del all: pcf2bdf pcf2bdf: pcf2bdf.cc $(CXX) $(CXXFLAGS) /Tppcf2bdf.cc clean: -$(RM) pcf2bdf pcf2bdf.exe pcf2bdf.obj *~ pcf2bdf-1.05/README.txt000066400000000000000000000046631252631414200144540ustar00rootroot00000000000000 pcf2bdf INSTALL for gcc: make -f Makefile.gcc install for visual c++: nmake -f Makefile.vc NAME pcf2bdf - convert X font from Portable Compiled Format to Bitmap Distribution Format SYNOPSIS pcf2bdf [ -v ] [ -o outputfile ] [ fontfile.pcf[.gz] ] DESCRIPTION Pcf2bdf is a font de-compiler. It converts X font from Portable Compiled Format (PCF) to Bitmap Distribution For- mat (BDF). It can also accept a compressed/gzipped PCF file as input, but gzip must be found in your PATH. FONTBOUNDINGBOX in a BDF file is not used by bdftopcf , so pcf2bdf generates irresponsible values. OPTIONS -v very verbose output. -o output-file-name By default pcf2bdf writes the bdf file to standard output; this option gives the name of a file to be used instead. SEE ALSO bdftopcf(1), X(7) COPYRIGHT Copyright (c) 2002, 2015, TAGA Nayuta Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. HISTORY 1.05 2015/05/18 - The size should come from POINT_SIZE instead of PIXEL_SIZE. - Internal quotation characters in a string property should be indicated (or "quoted”) by using two quotation characters in a row. - Fix avoid crash with large compressed metrics tables. (Colin Watson) - Fix support gzipped source. (Colin Watson) - Fix use C++ compiler and simplify using GNU extensions. (Jonas Smedegaard) - other fixes. 1.04 2002/10/21 1.03 1999/03/01 1.02 1998/04/27 1.01 1998/03/21 1.00 1998/03/16 pcf2bdf-1.05/pcf.txt000066400000000000000000000155111252631414200142610ustar00rootroot00000000000000// -*- c++ -*- // PCF File Format from libXfont-1.4.5 // include/X11/fonts/pcf.h // src/bitmap/pcfread.c // src/bitmap/pcfwrite.c // miscellaneous definition /////////////////////////////////////////////////// /* Type names are formatted as 'TypeSize_Endian'. * name Type Size(bits) Endian * --------------- --------------- --------------- ------- * 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 endianess is determined by the format.byte */ #define PCF_FILE_VERSION (('p'<<24)|('c'<<16)|('f'<<8)|1) 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 typedef struct _PCFTable { 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 } PCFTableRec; struct metric_t { int16 leftSideBearing; int16 rightSideBearing; int16 characterWidth; int16 ascent; int16 descent; uint16 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 uint32_little version = PCF_FILE_VERSION; int32_little nTables; // 1 <= nTables <= 134217727 // note: 134217727 == INT32_MAX / sizeof(PCFTableRec) == 0x7fffffff / 16 PCFTableRec tables[nTables]; /*** SECTION ***/ // properties section (tables[i].type = PCF_PROPERTIES) format32_little format; // format.id = PCF_DEFAULT_FORMAT int32 nProps; // 1 <= nProps <= 268435455 // note: 268435455 == INT32_MAX / sizeof(FontPropRec) == 0x7fffffff / 8 struct property_t { int32 name; // offset from &string[0] (0 <= name) bool8 isStringProp; // is this property is string ? (0 or 1) int32 value; // offset from &string[0] if isStringProp is 1 } props[nProps]; byte8 dummy[3 - ((sizeof(props) + 3) % 4)]; // padding int32 stringSize; // 0 <= 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; // 0 <= nMetrics <= 134217727 // note: 134217727 == INT32_MAX / sizeof(CharInfoRec) == 0x7fffffff / 16 metric_t metrics[nMetrics]; #else uint16 nMetrics; // 0 <= nMetrics <= 65535 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, bitmapSizes[format.glyph]); * 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<| * 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, encodingOffset={ 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 //////////////////////////////////////////////////////// pcf2bdf-1.05/pcf2bdf.cc000066400000000000000000000635421252631414200145740ustar00rootroot00000000000000// pcf2bdf.cc /* * see libXfont-1.4.5: src/bitmap/pcfread.c, pcfwrite.c, bcfread.c */ #include #include #include #if defined(_MSC_VER) // Microsoft Visual C++ # include # include # include # define popen _popen #elif defined(__CYGWIN__) // Cygnus GNU Win32 gcc # include # include # define _setmode setmode #else # define _setmode(fd, mode) #endif // miscellaneous definition /////////////////////////////////////////////////// typedef bool bool8; typedef unsigned char uint8; typedef unsigned char byte8; typedef short int16; typedef unsigned short uint16; typedef long int32; typedef unsigned long uint32; // section ID 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), }; // section format struct format32 { uint32 id :24; // one of four constants below uint32 dummy :2; // = 0 padding uint32 scan :2; // read bitmap by (1 << scan) bytes uint32 bit :1; // 0:LSBit first, 1:MSBit first uint32 byte :1; // 0:LSByte first, 1:MSByte first uint32 glyph :2; // a scanline of gryph is aligned by (1 << glyph) bytes bool is_little_endian(void) { return !byte; } }; // format32.id is: #define PCF_DEFAULT_FORMAT 0 #define PCF_INKBOUNDS 2 #define PCF_ACCEL_W_INKBOUNDS 1 #define PCF_COMPRESSED_METRICS 1 // BDF file is outputed: MSBit first and MSByte first const format32 BDF_format = { PCF_DEFAULT_FORMAT, 0, 0, 1, 1, 0 }; // string or value union sv { char *s; int32 v; }; // metric informations struct metric_t { int16 leftSideBearing; // leftmost coordinate of the gryph int16 rightSideBearing; // rightmost coordinate of the gryph int16 characterWidth; // offset to next gryph int16 ascent; // pixels below baseline int16 descent; // pixels above Baseline uint16 attributes; byte8 *bitmaps; // bitmap pattern of gryph int32 swidth; // swidth sv glyphName; // name of gryph metric_t(void) { bitmaps = NULL; glyphName.s = NULL; } // gryph width int16 widthBits(void) { return rightSideBearing - leftSideBearing; } // gryph height int16 height(void) { return ascent + descent; } // byts for one scanline int16 widthBytes(format32 f) { return bytesPerRow(widthBits(), 1 << f.glyph); } static int16 bytesPerRow(int bits, int nbytes) { return nbytes == 1 ? ((bits + 7) >> 3) // pad to 1 byte : nbytes == 2 ? (((bits + 15) >> 3) & ~1) // pad to 2 bytes : nbytes == 4 ? (((bits + 31) >> 3) & ~3) // pad to 4 bytes : nbytes == 8 ? (((bits + 63) >> 3) & ~7) // pad to 8 bytes : 0; } }; #define GLYPHPADOPTIONS 4 #define make_charcode(row,col) (row * 256 + col) #define NO_SUCH_CHAR 0xffff // global variables /////////////////////////////////////////////////////////// // table of contents int32 nTables; struct table_t { type32 type; // section ID format32 format; // section format int32 size; // size of section int32 offset; // byte offset from the beginning of the file } *tables; // properties section int32 nProps; // number of properties struct props_t { // property sv name; // name of property bool8 isStringProp; // whether this property is a string (or a value) sv value; // the value of this property } *props; int32 stringSize; // size of string char *string; // string used in property // accelerators section struct accelerators_t { bool8 noOverlap; /* true if: * max(rightSideBearing - characterWidth) <= * minbounds->metrics.leftSideBearing */ bool8 constantMetrics; bool8 terminalFont; /* true if: * constantMetrics && leftSideBearing == 0 && * rightSideBearing == characterWidth && * ascent == fontAscent && * descent == fontDescent */ bool8 constantWidth; /* true if: * minbounds->metrics.characterWidth * == * maxbounds->metrics.characterWidth */ bool8 inkInside; /* true if for all defined glyphs: * 0 <= leftSideBearing && * rightSideBearing <= characterWidth && * -fontDescent <= ascent <= fontAscent && * -fontAscent <= descent <= fontDescent */ bool8 inkMetrics; /* ink metrics != bitmap metrics */ bool8 drawDirection; /* 0:L->R 1:R->L*/ int32 fontAscent; int32 fontDescent; int32 maxOverlap; metric_t minBounds; metric_t maxBounds; metric_t ink_minBounds; metric_t ink_maxBounds; } accelerators; // metrics section int32 nMetrics; metric_t *metrics; // bitmaps section int32 nBitmaps; uint32 *bitmapOffsets; uint32 bitmapSizes[GLYPHPADOPTIONS]; byte8 *bitmaps; // bitmap patterns of the gryph int32 bitmapSize; // size of bitmaps // encodings section uint16 firstCol; uint16 lastCol; uint16 firstRow; uint16 lastRow; uint16 defaultCh; // default character uint16 *encodings; int nEncodings; // number of encodings int nValidEncodings; // number of valid encodings // swidths section int32 nSwidths; // glyph names section int32 nGlyphNames; int32 glyphNamesSize; char *glyphNames; // other globals FILE *ifp; // input file pointer FILE *ofp; // output file pointer long read_bytes; // read bytes format32 format; // current section format metric_t fontbbx; // font bounding box bool verbose; // show messages verbosely // miscellaneous functions //////////////////////////////////////////////////// int error_exit(const char *str) { fprintf(stderr, "pcf2bdf: %s\n", str); exit(1); return 1; } int error_invalid_exit(const char *str) { fprintf(stderr, "pcf2bdf: <%s> invalid PCF file\n", str); exit(1); return 1; } int check_memory(void *ptr) { if (!ptr) return error_exit("out of memory"); return 0; } byte8 *read_byte8s(byte8 *mem, size_t size) { size_t read_size = fread(mem, 1, size, ifp); if (read_size != size) error_exit("unexpected eof"); read_bytes += size; return mem; } char read8(void) { int a = fgetc(ifp); read_bytes ++; if (a == EOF) return (char)error_exit("unexpected eof"); return (char)a; } bool8 read_bool8(void) { return (bool8)!!read8(); } uint8 read_uint8(void) { return (uint8)read8(); } /* These all return int rather than int16 in order to handle values * between 32768 and 65535 more gracefully. */ int make_int16(int a, int b) { int value; value = (a & 0xff) << 8; value |= (b & 0xff); return value; } int read_int16_big(void) { int a = read8(); int b = read8(); return make_int16(a, b); } int read_int16_little(void) { int a = read8(); int b = read8(); return make_int16(b, a); } int read_int16(void) { if (format.is_little_endian()) return read_int16_little(); else return read_int16_big(); } int32 make_int32(int a, int b, int c, int d) { int32 value; value = (int32)(a & 0xff) << 24; value |= (int32)(b & 0xff) << 16; value |= (int32)(c & 0xff) << 8; value |= (int32)(d & 0xff); return value; } int32 read_int32_big(void) { int a = read8(); int b = read8(); int c = read8(); int d = read8(); return make_int32(a, b, c, d); } int32 read_int32_little(void) { int a = read8(); int b = read8(); int c = read8(); int d = read8(); return make_int32(d, c, b, a); } int32 read_int32(void) { if (format.is_little_endian()) return read_int32_little(); else return read_int32_big(); } uint32 read_uint32(void) { return (uint32)read_int32(); } format32 read_format32_little(void) { int32 v = read_int32_little(); format32 f; f.id = v >> 8; f.dummy = 0; f.scan = v >> 4; f.bit = v >> 3; f.byte = v >> 2; f.glyph = v >> 0; return f; } void skip(int n) { for (; 0 < n; n--) read8(); } void bit_order_invert(byte8 *data, int size) { static const byte8 invert[16] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; for (int i = 0; i < size; i++) data[i] = (invert[data[i] & 15] << 4) | invert[(data[i] >> 4) & 15]; } void two_byte_swap(byte8 *data, int size) { size &= ~1; for (int i = 0; i < size; i += 2) { byte8 tmp = data[i]; data[i] = data[i + 1]; data[i + 1] = tmp; } } void four_byte_swap(byte8 *data, int size) { size &= ~3; for (int i = 0; i < size; i += 4) { byte8 tmp = data[i]; data[i] = data[i + 3]; data[i + 3] = tmp; tmp = data[i + 1]; data[i + 1] = data[i + 2]; data[i + 2] = tmp; } } // main /////////////////////////////////////////////////////////////////////// // search and seek a section of 'type' bool seek(type32 type) { for (int i = 0; i < nTables; i++) if (tables[i].type == type) { int s = tables[i].offset - read_bytes; if (s < 0) error_invalid_exit("seek"); skip(s); return true; } return false; } // does a section of 'type' exist? bool is_exist_section(type32 type) { for (int i = 0; i < nTables; i++) if (tables[i].type == type) return true; return false; } // read metric information void read_metric(metric_t *m) { m->leftSideBearing = read_int16(); m->rightSideBearing = read_int16(); m->characterWidth = read_int16(); m->ascent = read_int16(); m->descent = read_int16(); m->attributes = read_int16(); } // read compressed metric information void read_compressed_metric(metric_t *m) { m->leftSideBearing = (int16)read_uint8() - 0x80; m->rightSideBearing = (int16)read_uint8() - 0x80; m->characterWidth = (int16)read_uint8() - 0x80; m->ascent = (int16)read_uint8() - 0x80; m->descent = (int16)read_uint8() - 0x80; m->attributes = 0; } void verbose_metric(metric_t *m, const char *name) { if (verbose) { fprintf(stderr, "\t%s.leftSideBearing = %d\n", name, m->leftSideBearing); fprintf(stderr, "\t%s.rightSideBearing = %d\n", name, m->rightSideBearing); fprintf(stderr, "\t%s.characterWidth = %d\n", name, m->characterWidth); fprintf(stderr, "\t%s.ascent = %d\n", name, m->ascent); fprintf(stderr, "\t%s.descent = %d\n", name, m->descent); fprintf(stderr, "\t%s.attributes = %04x\n", name, m->attributes); } } // read accelerators section void read_accelerators(void) { format = read_format32_little(); if (!(format.id == PCF_DEFAULT_FORMAT || format.id == PCF_ACCEL_W_INKBOUNDS)) error_invalid_exit("accelerators"); accelerators.noOverlap = read_bool8(); accelerators.constantMetrics = read_bool8(); accelerators.terminalFont = read_bool8(); accelerators.constantWidth = read_bool8(); accelerators.inkInside = read_bool8(); accelerators.inkMetrics = read_bool8(); accelerators.drawDirection = read_bool8(); /* dummy */ read_bool8(); accelerators.fontAscent = read_int32(); accelerators.fontDescent = read_int32(); accelerators.maxOverlap = read_int32(); if (verbose) { fprintf(stderr, "\tnoOverlap = %d\n", (int)accelerators.noOverlap); fprintf(stderr, "\tconstantMetrics = %d\n", (int)accelerators.constantMetrics); fprintf(stderr, "\tterminalFont = %d\n", (int)accelerators.terminalFont); fprintf(stderr, "\tconstantWidth = %d\n", (int)accelerators.constantWidth); fprintf(stderr, "\tinkInside = %d\n", (int)accelerators.inkInside); fprintf(stderr, "\tinkMetrics = %d\n", (int)accelerators.inkMetrics); fprintf(stderr, "\tdrawDirection = %d\n", (int)accelerators.drawDirection); fprintf(stderr, "\tfontAscent = %d\n", (int)accelerators.fontAscent); fprintf(stderr, "\tfontDescent = %d\n", (int)accelerators.fontDescent); fprintf(stderr, "\tmaxOverlap = %d\n", (int)accelerators.maxOverlap); } read_metric(&accelerators.minBounds); read_metric(&accelerators.maxBounds); verbose_metric(&accelerators.minBounds, "minBounds"); verbose_metric(&accelerators.maxBounds, "maxBounds"); if (format.id == PCF_ACCEL_W_INKBOUNDS) { read_metric(&accelerators.ink_minBounds); read_metric(&accelerators.ink_maxBounds); verbose_metric(&accelerators.ink_minBounds, "ink_minBounds"); verbose_metric(&accelerators.ink_maxBounds, "ink_maxBounds"); } else { accelerators.ink_minBounds = accelerators.minBounds; accelerators.ink_maxBounds = accelerators.maxBounds; } } // search a property named 'name', and return its string if it is a string char *get_property_string(const char *name) { for (int i = 0; i < nProps; i++) { if (strcmp(name, props[i].name.s) == 0) if (props[i].isStringProp) return props[i].value.s; else error_invalid_exit("property_string"); } return NULL; } // search a property named 'name', and return its value if it is a value int32 get_property_value(const char *name) { for (int i = 0; i < nProps; i++) { if (strcmp(name, props[i].name.s) == 0) if (props[i].isStringProp) error_invalid_exit("property_value"); else return props[i].value.v; } return -1; } // does a property named 'name' exist? bool is_exist_property_value(const char *name) { for (int i = 0; i < nProps; i++) { if (strcmp(name, props[i].name.s) == 0) if (props[i].isStringProp) return false; else return true; } return false; } int usage_exit(void) { printf("usage: pcf2bdf [-v] [-o bdf file] [pcf file]\n"); return 1; } int main(int argc, char *argv[]) { int i; char *ifilename = NULL; char *ofilename = NULL; // read options for (i = 1; i < argc; i++) { if (argv[i][0] == '-') if (argv[i][1] == 'v') verbose = true; else if (i + 1 == argc || argv[i][1] != 'o' || ofilename) return usage_exit(); else ofilename = argv[++i]; else if (ifilename) return usage_exit(); else ifilename = argv[i]; } if (ifilename) { ifp = fopen(ifilename, "rb"); if (!ifp) return error_exit("failed to open input pcf file"); } else { _setmode(fileno(stdin), O_BINARY); ifp = stdin; } uint32 version = read_int32_big(); if ((version >> 16) == 0x1f9d || // compress'ed (version >> 16) == 0x1f8b) // gzip'ed { if (!ifilename) return error_exit("stdin is gzip'ed or compress'ed\n"); fclose(ifp); char buf[1024]; sprintf(buf, "gzip -dc %s", ifilename); // TODO ifp = popen(buf, "r"); _setmode(fileno(ifp), O_BINARY); read_bytes = 0; if (!ifp) return error_exit("failed to execute gzip\n"); } if (ofilename) { ofp = fopen(ofilename, "wb"); if (!ofp) return error_exit("failed to open output bdf file"); } else ofp = stdout; // read PCF file //////////////////////////////////////////////////////////// // read table of contents if (read_bytes == 0) version = read_int32_big(); if (version != make_int32(1, 'f', 'c', 'p')) error_exit("this is not PCF file format"); nTables = read_int32_little(); check_memory((tables = new table_t[nTables])); for (i = 0; i < nTables; i++) { tables[i].type = (type32)read_int32_little(); tables[i].format = read_format32_little(); tables[i].size = read_int32_little(); tables[i].offset = read_int32_little(); } // read properties section if (!seek(PCF_PROPERTIES)) error_exit("PCF_PROPERTIES does not found"); else if (verbose) fprintf(stderr, "PCF_PROPERTIES\n"); format = read_format32_little(); if (!(format.id == PCF_DEFAULT_FORMAT)) error_invalid_exit("properties(format)"); nProps = read_int32(); check_memory((props = new props_t[nProps])); for (i = 0; i < nProps; i++) { props[i].name.v = read_int32(); props[i].isStringProp = read_bool8(); props[i].value.v = read_int32(); } skip(3 - (((4 + 1 + 4) * nProps + 3) % 4)); stringSize = read_int32(); check_memory((string = new char[stringSize + 1])); read_byte8s((byte8 *)string, stringSize); string[stringSize] = '\0'; for (i = 0; i < nProps; i++) { if (stringSize <= props[i].name.v) error_invalid_exit("properties(name)"); props[i].name.s = string + props[i].name.v; if (verbose) fprintf(stderr, "\t%s ", props[i].name.s); if (props[i].isStringProp) { if (stringSize <= props[i].value.v) error_invalid_exit("properties(value)"); props[i].value.s = string + props[i].value.v; if (verbose) fprintf(stderr, "\"%s\"\n", props[i].value.s); } else if (verbose) fprintf(stderr, "%ld\n", props[i].value.v); } // read old accelerators section if (!is_exist_section(PCF_BDF_ACCELERATORS)) if (!seek(PCF_ACCELERATORS)) error_exit("PCF_ACCELERATORS and PCF_BDF_ACCELERATORS do not found"); else { if (verbose) fprintf(stderr, "PCF_ACCELERATORS\n"); read_accelerators(); } else if (verbose) fprintf(stderr, "(PCF_ACCELERATORS)\n"); // read metrics section if (!seek(PCF_METRICS)) error_exit("PCF_METRICS does not found"); else if (verbose) fprintf(stderr, "PCF_METRICS\n"); format = read_format32_little(); switch (format.id) { default: error_invalid_exit("metrics"); case PCF_DEFAULT_FORMAT: nMetrics = read_int32(); check_memory((metrics = new metric_t[nMetrics])); for (i = 0; i < nMetrics; i++) read_metric(&metrics[i]); break; case PCF_COMPRESSED_METRICS: if (verbose) fprintf(stderr, "\tPCF_COMPRESSED_METRICS\n"); nMetrics = read_int16(); check_memory((metrics = new metric_t[nMetrics])); for (i = 0; i < nMetrics; i++) read_compressed_metric(&metrics[i]); break; } if (verbose) fprintf(stderr, "\tnMetrics = %ld\n", nMetrics); fontbbx = metrics[0]; for (i = 1; i < nMetrics; i++) { if (metrics[i].leftSideBearing < fontbbx.leftSideBearing) fontbbx.leftSideBearing = metrics[i].leftSideBearing; if (fontbbx.rightSideBearing < metrics[i].rightSideBearing) fontbbx.rightSideBearing = metrics[i].rightSideBearing; if (fontbbx.ascent < metrics[i].ascent) fontbbx.ascent = metrics[i].ascent; if (fontbbx.descent < metrics[i].descent) fontbbx.descent = metrics[i].descent; } // read bitmaps section if (!seek(PCF_BITMAPS)) error_exit("PCF_BITMAPS does not found"); else if (verbose) fprintf(stderr, "PCF_BITMAPS\n"); format = read_format32_little(); if (!(format.id == PCF_DEFAULT_FORMAT)) error_invalid_exit("bitmaps"); nBitmaps = read_int32(); check_memory((bitmapOffsets = new uint32[nBitmaps])); for (i = 0; i < nBitmaps; i++) bitmapOffsets[i] = read_uint32(); for (i = 0; i < GLYPHPADOPTIONS; i++) bitmapSizes[i] = read_uint32(); bitmapSize = bitmapSizes[format.glyph]; check_memory((bitmaps = new byte8[bitmapSize])); read_byte8s(bitmaps, bitmapSize); // if (verbose) { fprintf(stderr, "\t1<