home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / fonts / lib / font / bitmap / pcfread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  18.0 KB  |  667 lines

  1. /*
  2.  * $XConsortium: pcfread.c,v 1.10 92/05/12 18:07:47 gildea Exp $
  3.  *
  4.  * Copyright 1990 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Keith Packard, MIT X Consortium
  24.  */
  25.  
  26. #include    "fontfilest.h"
  27. #include    "bitmap.h"
  28. #include    "pcf.h"
  29.  
  30. /* Read PCF font files */
  31.  
  32. void        pcfUnloadFont();
  33. static int  position;
  34.  
  35. static int
  36. pcfGetLSB32(file)
  37.     FontFilePtr file;
  38. {
  39.     int         c;
  40.  
  41.     c = FontFileGetc(file);
  42.     c |= FontFileGetc(file) << 8;
  43.     c |= FontFileGetc(file) << 16;
  44.     c |= FontFileGetc(file) << 24;
  45.     position += 4;
  46.     return c;
  47. }
  48.  
  49. static int
  50. pcfGetINT32(file, format)
  51.     FontFilePtr file;
  52.     CARD32      format;
  53. {
  54.     int         c;
  55.  
  56.     if (PCF_BYTE_ORDER(format) == MSBFirst) {
  57.     c = FontFileGetc(file) << 24;
  58.     c |= FontFileGetc(file) << 16;
  59.     c |= FontFileGetc(file) << 8;
  60.     c |= FontFileGetc(file);
  61.     } else {
  62.     c = FontFileGetc(file);
  63.     c |= FontFileGetc(file) << 8;
  64.     c |= FontFileGetc(file) << 16;
  65.     c |= FontFileGetc(file) << 24;
  66.     }
  67.     position += 4;
  68.     return c;
  69. }
  70.  
  71. static int
  72. pcfGetINT16(file, format)
  73.     FontFilePtr file;
  74.     CARD32      format;
  75. {
  76.     int         c;
  77.  
  78.     if (PCF_BYTE_ORDER(format) == MSBFirst) {
  79.     c = FontFileGetc(file) << 8;
  80.     c |= FontFileGetc(file);
  81.     } else {
  82.     c = FontFileGetc(file);
  83.     c |= FontFileGetc(file) << 8;
  84.     }
  85.     position += 2;
  86.     return c;
  87. }
  88.  
  89. #define pcfGetINT8(file, format) (position++, FontFileGetc(file))
  90.  
  91. static      PCFTablePtr
  92. pcfReadTOC(file, countp)
  93.     FontFilePtr file;
  94.     int        *countp;
  95. {
  96.     CARD32      version;
  97.     PCFTablePtr tables;
  98.     int         count;
  99.     int         i;
  100.  
  101.     position = 0;
  102.     version = pcfGetLSB32(file);
  103.     if (version != PCF_FILE_VERSION)
  104.     return (PCFTablePtr) NULL;
  105.     count = pcfGetLSB32(file);
  106.     tables = (PCFTablePtr) xalloc(count * sizeof(PCFTableRec));
  107.     if (!tables)
  108.     return (PCFTablePtr) NULL;
  109.     for (i = 0; i < count; i++) {
  110.     tables[i].type = pcfGetLSB32(file);
  111.     tables[i].format = pcfGetLSB32(file);
  112.     tables[i].size = pcfGetLSB32(file);
  113.     tables[i].offset = pcfGetLSB32(file);
  114.     }
  115.     *countp = count;
  116.     return tables;
  117. }
  118.  
  119. /*
  120.  * PCF supports two formats for metrics, both the regular
  121.  * jumbo size, and 'lite' metrics, which are useful
  122.  * for most fonts which have even vaguely reasonable
  123.  * metrics
  124.  */
  125.  
  126. static
  127. pcfGetMetric(file, format, metric)
  128.     FontFilePtr file;
  129.     CARD32      format;
  130.     xCharInfo  *metric;
  131. {
  132.     metric->leftSideBearing = pcfGetINT16(file, format);
  133.     metric->rightSideBearing = pcfGetINT16(file, format);
  134.     metric->characterWidth = pcfGetINT16(file, format);
  135.     metric->ascent = pcfGetINT16(file, format);
  136.     metric->descent = pcfGetINT16(file, format);
  137.     metric->attributes = pcfGetINT16(file, format);
  138. }
  139.  
  140. static
  141. pcfGetCompressedMetric(file, format, metric)
  142.     FontFilePtr file;
  143.     CARD32      format;
  144.     xCharInfo  *metric;
  145. {
  146.     metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
  147.     metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
  148.     metric->characterWidth = pcfGetINT8(file, format) - 0x80;
  149.     metric->ascent = pcfGetINT8(file, format) - 0x80;
  150.     metric->descent = pcfGetINT8(file, format) - 0x80;
  151.     metric->attributes = 0;
  152. }
  153.  
  154. /*
  155.  * Position the file to the begining of the specified table
  156.  * in the font file
  157.  */
  158. static Bool
  159. pcfSeekToType(file, tables, ntables, type, formatp, sizep)
  160.     FontFilePtr file;
  161.     PCFTablePtr tables;
  162.     int         ntables;
  163.     CARD32      type;
  164.     CARD32     *formatp;
  165.     CARD32     *sizep;
  166. {
  167.     int         i;
  168.  
  169.     for (i = 0; i < ntables; i++)
  170.     if (tables[i].type == type) {
  171.         if (position > tables[i].offset)
  172.         return FALSE;
  173.         if (!FontFileSkip(file, tables[i].offset - position))
  174.         return FALSE;
  175.         position = tables[i].offset;
  176.         *sizep = tables[i].size;
  177.         *formatp = tables[i].format;
  178.         return TRUE;
  179.     }
  180.     return FALSE;
  181. }
  182.  
  183. static Bool
  184. pcfHasType (tables, ntables, type)
  185.     PCFTablePtr tables;
  186.     int         ntables;
  187.     CARD32      type;
  188. {
  189.     int         i;
  190.  
  191.     for (i = 0; i < ntables; i++)
  192.     if (tables[i].type == type)
  193.         return TRUE;
  194.     return FALSE;
  195. }
  196.  
  197. /*
  198.  * pcfGetProperties 
  199.  *
  200.  * Reads the font properties from the font file, filling in the FontInfo rec
  201.  * supplied.  Used by by both ReadFont and ReadFontInfo routines.
  202.  */
  203.  
  204. static Bool
  205. pcfGetProperties(pFontInfo, file, tables, ntables)
  206.     FontInfoPtr pFontInfo;
  207.     FontFilePtr file;
  208.     PCFTablePtr tables;
  209.     int         ntables;
  210. {
  211.     FontPropPtr props = 0;
  212.     int         nprops;
  213.     char       *isStringProp = 0;
  214.     CARD32      format;
  215.     int         i;
  216.     int         size;
  217.     int         string_size;
  218.     char       *strings;
  219.  
  220.     /* font properties */
  221.  
  222.     if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
  223.     goto Bail;
  224.     format = pcfGetLSB32(file);
  225.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  226.     goto Bail;
  227.     nprops = pcfGetINT32(file, format);
  228.     props = (FontPropPtr) xalloc(nprops * sizeof(FontPropRec));
  229.     if (!props)
  230.     goto Bail;
  231.     isStringProp = (char *) xalloc(nprops * sizeof(char));
  232.     if (!isStringProp)
  233.     goto Bail;
  234.     for (i = 0; i < nprops; i++) {
  235.     props[i].name = pcfGetINT32(file, format);
  236.     isStringProp[i] = pcfGetINT8(file, format);
  237.     props[i].value = pcfGetINT32(file, format);
  238.     }
  239.     /* pad the property array */
  240.     /*
  241.      * clever here - nprops is the same as the number of odd-units read, as
  242.      * only isStringProp are odd length
  243.      */
  244.     if (nprops & 3)
  245.     {
  246.     i = 4 - (nprops & 3);
  247.     FontFileSkip(file, i);
  248.     position += i;
  249.     }
  250.     string_size = pcfGetINT32(file, format);
  251.     strings = (char *) xalloc(string_size);
  252.     if (!strings) {
  253.     goto Bail;
  254.     }
  255.     FontFileRead(file, strings, string_size);
  256.     position += string_size;
  257.     for (i = 0; i < nprops; i++) {
  258.     props[i].name = MakeAtom(strings + props[i].name,
  259.                  strlen(strings + props[i].name), TRUE);
  260.     if (isStringProp[i]) {
  261.         props[i].value = MakeAtom(strings + props[i].value,
  262.                       strlen(strings + props[i].value), TRUE);
  263.     }
  264.     }
  265.     xfree(strings);
  266.     pFontInfo->isStringProp = isStringProp;
  267.     pFontInfo->props = props;
  268.     pFontInfo->nprops = nprops;
  269.     return TRUE;
  270. Bail:
  271.     xfree(isStringProp);
  272.     xfree(props);
  273.     return FALSE;
  274. }
  275.  
  276.  
  277. /*
  278.  * pcfReadAccel
  279.  *
  280.  * Fill in the accelerator information from the font file; used
  281.  * to read both BDF_ACCELERATORS and old style ACCELERATORS
  282.  */
  283.  
  284. static Bool
  285. pcfGetAccel(pFontInfo, file, tables, ntables, type)
  286.     FontInfoPtr pFontInfo;
  287.     FontFilePtr file;
  288.     PCFTablePtr    tables;
  289.     int        ntables;
  290.     CARD32    type;
  291. {
  292.     CARD32      format;
  293.     int        size;
  294.  
  295.     if (!pcfSeekToType(file, tables, ntables, type, &format, &size))
  296.     goto Bail;
  297.     format = pcfGetLSB32(file);
  298.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
  299.     !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) 
  300.     {
  301.     goto Bail;
  302.     }
  303.     pFontInfo->noOverlap = pcfGetINT8(file, format);
  304.     pFontInfo->constantMetrics = pcfGetINT8(file, format);
  305.     pFontInfo->terminalFont = pcfGetINT8(file, format);
  306.     pFontInfo->constantWidth = pcfGetINT8(file, format);
  307.     pFontInfo->inkInside = pcfGetINT8(file, format);
  308.     pFontInfo->inkMetrics = pcfGetINT8(file, format);
  309.     pFontInfo->drawDirection = pcfGetINT8(file, format);
  310.     pFontInfo->anamorphic = FALSE;
  311.      /* natural alignment */ pcfGetINT8(file, format);
  312.     pFontInfo->fontAscent = pcfGetINT32(file, format);
  313.     pFontInfo->fontDescent = pcfGetINT32(file, format);
  314.     pFontInfo->maxOverlap = pcfGetINT32(file, format);
  315.     pcfGetMetric(file, format, &pFontInfo->minbounds);
  316.     pcfGetMetric(file, format, &pFontInfo->maxbounds);
  317.     if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
  318.     pcfGetMetric(file, format, &pFontInfo->ink_minbounds);
  319.     pcfGetMetric(file, format, &pFontInfo->ink_maxbounds);
  320.     } else {
  321.     pFontInfo->ink_minbounds = pFontInfo->minbounds;
  322.     pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
  323.     }
  324.     return TRUE;
  325. Bail:
  326.     return FALSE;
  327. }
  328.  
  329. int
  330. pcfReadFont(pFont, file, bit, byte, glyph, scan)
  331.     FontPtr     pFont;
  332.     FontFilePtr file;
  333.     int         bit,
  334.                 byte,
  335.                 glyph,
  336.                 scan;
  337. {
  338.     CARD32      format;
  339.     CARD32      size;
  340.     BitmapFontPtr  bitmapFont = 0;
  341.     int         i;
  342.     PCFTablePtr tables = 0;
  343.     int         ntables;
  344.     int         nmetrics;
  345.     int         nbitmaps;
  346.     int         sizebitmaps;
  347.     int         nink_metrics;
  348.     CharInfoPtr metrics = 0;
  349.     xCharInfo  *ink_metrics = 0;
  350.     char       *bitmaps = 0;
  351.     CharInfoPtr *encoding = 0;
  352.     int         nencoding;
  353.     int         encodingOffset;
  354.     CARD32      bitmapSizes[GLYPHPADOPTIONS];
  355.     CARD32     *offsets = 0;
  356.     Bool    hasBDFAccelerators;
  357.  
  358.     pFont->info.props = 0;
  359.     if (!(tables = pcfReadTOC(file, &ntables)))
  360.     goto Bail;
  361.  
  362.     /* properties */
  363.  
  364.     if (!pcfGetProperties(&pFont->info, file, tables, ntables))
  365.     goto Bail;
  366.  
  367.     /* Use the old accelerators if no BDF accelerators are in the file */
  368.  
  369.     hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
  370.     if (!hasBDFAccelerators)
  371.     if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
  372.         goto Bail;
  373.  
  374.     /* metrics */
  375.  
  376.     if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
  377.     goto Bail;
  378.     }
  379.     format = pcfGetLSB32(file);
  380.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
  381.         !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
  382.     goto Bail;
  383.     }
  384.     if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  385.     nmetrics = pcfGetINT32(file, format);
  386.     else
  387.     nmetrics = pcfGetINT16(file, format);
  388.     metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec));
  389.     if (!metrics) {
  390.     goto Bail;
  391.     }
  392.     for (i = 0; i < nmetrics; i++)
  393.     if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  394.         pcfGetMetric(file, format, &(metrics + i)->metrics);
  395.     else
  396.         pcfGetCompressedMetric(file, format, &(metrics + i)->metrics);
  397.  
  398.     /* bitmaps */
  399.  
  400.     if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
  401.     goto Bail;
  402.     format = pcfGetLSB32(file);
  403.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  404.     goto Bail;
  405.  
  406.     nbitmaps = pcfGetINT32(file, format);
  407.     if (nbitmaps != nmetrics)
  408.     goto Bail;
  409.  
  410.     offsets = (CARD32 *) xalloc(nbitmaps * sizeof(CARD32));
  411.     if (!offsets)
  412.     goto Bail;
  413.  
  414.     for (i = 0; i < nbitmaps; i++)
  415.     offsets[i] = pcfGetINT32(file, format);
  416.  
  417.     for (i = 0; i < GLYPHPADOPTIONS; i++)
  418.     bitmapSizes[i] = pcfGetINT32(file, format);
  419.     sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
  420.     bitmaps = (char *) xalloc(sizebitmaps);
  421.     if (!bitmaps)
  422.     goto Bail;
  423.     FontFileRead(file, bitmaps, sizebitmaps);
  424.     position += sizebitmaps;
  425.  
  426.     if (PCF_BIT_ORDER(format) != bit)
  427.     BitOrderInvert(bitmaps, sizebitmaps);
  428.     if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
  429.     switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
  430.     case 1:
  431.         break;
  432.     case 2:
  433.         TwoByteSwap(bitmaps, sizebitmaps);
  434.         break;
  435.     case 4:
  436.         FourByteSwap(bitmaps, sizebitmaps);
  437.         break;
  438.     }
  439.     }
  440.     if (PCF_GLYPH_PAD(format) != glyph) {
  441.     char       *padbitmaps;
  442.     int         sizepadbitmaps;
  443.     int         old,
  444.                 new;
  445.     xCharInfo  *metric;
  446.  
  447.     sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
  448.     padbitmaps = (char *) xalloc(sizepadbitmaps);
  449.     if (!padbitmaps) {
  450.         goto Bail;
  451.     }
  452.     new = 0;
  453.     for (i = 0; i < nbitmaps; i++) {
  454.         old = offsets[i];
  455.         metric = &metrics[i].metrics;
  456.         offsets[i] = new;
  457.         new += RepadBitmap(bitmaps + old, padbitmaps + new,
  458.                    PCF_GLYPH_PAD(format), glyph,
  459.               metric->rightSideBearing - metric->leftSideBearing,
  460.                    metric->ascent + metric->descent);
  461.     }
  462.     xfree(bitmaps);
  463.     bitmaps = padbitmaps;
  464.     }
  465.     for (i = 0; i < nbitmaps; i++)
  466.     metrics[i].bits = bitmaps + offsets[i];
  467.  
  468.     xfree(offsets);
  469.  
  470.     /* ink metrics ? */
  471.  
  472.     ink_metrics = NULL;
  473.     if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
  474.     format = pcfGetLSB32(file);
  475.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
  476.         !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
  477.         goto Bail;
  478.     }
  479.     if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  480.         nink_metrics = pcfGetINT32(file, format);
  481.     else
  482.         nink_metrics = pcfGetINT16(file, format);
  483.     if (nink_metrics != nmetrics)
  484.         goto Bail;
  485.     ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo));
  486.     if (!ink_metrics)
  487.         goto Bail;
  488.     for (i = 0; i < nink_metrics; i++)
  489.         if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  490.         pcfGetMetric(file, format, ink_metrics + i);
  491.         else
  492.         pcfGetCompressedMetric(file, format, ink_metrics + i);
  493.     }
  494.  
  495.     /* encoding */
  496.  
  497.     if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
  498.     goto Bail;
  499.     format = pcfGetLSB32(file);
  500.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  501.     goto Bail;
  502.  
  503.     pFont->info.firstCol = pcfGetINT16(file, format);
  504.     pFont->info.lastCol = pcfGetINT16(file, format);
  505.     pFont->info.firstRow = pcfGetINT16(file, format);
  506.     pFont->info.lastRow = pcfGetINT16(file, format);
  507.     pFont->info.defaultCh = pcfGetINT16(file, format);
  508.  
  509.     nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
  510.     (pFont->info.lastRow - pFont->info.firstRow + 1);
  511.  
  512.     encoding = (CharInfoPtr *) xalloc(nencoding * sizeof(CharInfoPtr));
  513.     if (!encoding)
  514.     goto Bail;
  515.  
  516.     pFont->info.allExist = TRUE;
  517.     for (i = 0; i < nencoding; i++) {
  518.     encodingOffset = pcfGetINT16(file, format);
  519.     if (encodingOffset == 0xFFFF) {
  520.         pFont->info.allExist = FALSE;
  521.         encoding[i] = 0;
  522.     } else
  523.         encoding[i] = metrics + encodingOffset;
  524.     }
  525.  
  526.     /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
  527.  
  528.     if (hasBDFAccelerators)
  529.     if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
  530.         goto Bail;
  531.  
  532.     bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont);
  533.     if (!bitmapFont)
  534.     goto Bail;
  535.  
  536.     bitmapFont->version_num = PCF_FILE_VERSION;
  537.     bitmapFont->num_chars = nmetrics;
  538.     bitmapFont->num_tables = ntables;
  539.     bitmapFont->metrics = metrics;
  540.     bitmapFont->ink_metrics = ink_metrics;
  541.     bitmapFont->bitmaps = bitmaps;
  542.     bitmapFont->encoding = encoding;
  543.     bitmapFont->pDefault = (CharInfoPtr) 0;
  544.     if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
  545.     int         r,
  546.                 c,
  547.                 cols;
  548.  
  549.     r = pFont->info.defaultCh >> 8;
  550.     c = pFont->info.defaultCh & 0xFF;
  551.     if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
  552.         pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
  553.         cols = pFont->info.lastCol - pFont->info.firstCol + 1;
  554.         r = r - pFont->info.firstRow;
  555.         c = c - pFont->info.firstCol;
  556.         bitmapFont->pDefault = encoding[r * cols + c];
  557.     }
  558.     }
  559.     bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
  560.     pFont->fontPrivate = (pointer) bitmapFont;
  561.     pFont->get_glyphs = bitmapGetGlyphs;
  562.     pFont->get_metrics = bitmapGetMetrics;
  563.     pFont->unload_font = pcfUnloadFont;
  564.     pFont->bit = bit;
  565.     pFont->byte = byte;
  566.     pFont->glyph = glyph;
  567.     pFont->scan = scan;
  568.     xfree(tables);
  569.     return Successful;
  570. Bail:
  571.     xfree(ink_metrics);
  572.     xfree(encoding);
  573.     xfree(bitmaps);
  574.     xfree(offsets);
  575.     xfree(metrics);
  576.     xfree(pFont->info.props);
  577.     pFont->info.props = 0;
  578.     xfree(bitmapFont);
  579.     xfree(tables);
  580.     return AllocError;
  581. }
  582.  
  583. int
  584. pcfReadFontInfo(pFontInfo, file)
  585.     FontInfoPtr pFontInfo;
  586.     FontFilePtr file;
  587. {
  588.     PCFTablePtr tables;
  589.     int         ntables;
  590.     CARD32      format;
  591.     CARD32      size;
  592.     int         nencoding;
  593.     Bool    hasBDFAccelerators;
  594.  
  595.     pFontInfo->isStringProp = NULL;
  596.     pFontInfo->props = NULL;
  597.  
  598.     if (!(tables = pcfReadTOC(file, &ntables)))
  599.     goto Bail;
  600.  
  601.     /* properties */
  602.  
  603.     if (!pcfGetProperties(pFontInfo, file, tables, ntables))
  604.     goto Bail;
  605.  
  606.     /* Use the old accelerators if no BDF accelerators are in the file */
  607.  
  608.     hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
  609.     if (!hasBDFAccelerators)
  610.     if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
  611.         goto Bail;
  612.  
  613.     /* encoding */
  614.  
  615.     if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
  616.     goto Bail;
  617.     format = pcfGetLSB32(file);
  618.     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
  619.     goto Bail;
  620.  
  621.     pFontInfo->firstCol = pcfGetINT16(file, format);
  622.     pFontInfo->lastCol = pcfGetINT16(file, format);
  623.     pFontInfo->firstRow = pcfGetINT16(file, format);
  624.     pFontInfo->lastRow = pcfGetINT16(file, format);
  625.     pFontInfo->defaultCh = pcfGetINT16(file, format);
  626.  
  627.     nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
  628.     (pFontInfo->lastRow - pFontInfo->firstRow + 1);
  629.  
  630.     pFontInfo->allExist = TRUE;
  631.     while (nencoding--) {
  632.     if (pcfGetINT16(file, format) == 0xFFFF)
  633.         pFontInfo->allExist = FALSE;
  634.     }
  635.  
  636.     /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
  637.  
  638.     if (hasBDFAccelerators)
  639.     if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
  640.         goto Bail;
  641.  
  642.     xfree(tables);
  643.     return Successful;
  644. Bail:
  645.     xfree (pFontInfo->props);
  646.     xfree (pFontInfo->isStringProp);
  647.     xfree(tables);
  648.     return AllocError;
  649. }
  650.  
  651. void
  652. pcfUnloadFont(pFont)
  653.     FontPtr     pFont;
  654. {
  655.     BitmapFontPtr  bitmapFont;
  656.  
  657.     bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
  658.     xfree(bitmapFont->ink_metrics);
  659.     xfree(bitmapFont->encoding);
  660.     xfree(bitmapFont->bitmaps);
  661.     xfree(bitmapFont->metrics);
  662.     xfree(pFont->info.isStringProp);
  663.     xfree(pFont->info.props);
  664.     xfree(bitmapFont);
  665.     xfree(pFont);
  666. }
  667.