1 /* $XConsortium: pcfread.c /main/18 1996/09/28 16:48:33 rws $ */
5 Copyright (c) 1990 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of the X Consortium shall
27 not be used in advertising or otherwise to promote the sale, use or
28 other dealings in this Software without prior written authorization
29 from the X Consortium.
34 * Author: Keith Packard, MIT X Consortium
41 #define MAX(a,b) (((a)>(b)) ? a : b)
44 /* Read PCF font files */
55 c = FontFileGetc(file);
56 c |= FontFileGetc(file) << 8;
57 c |= FontFileGetc(file) << 16;
58 c |= FontFileGetc(file) << 24;
64 pcfGetINT32(file, format)
70 if (PCF_BYTE_ORDER(format) == MSBFirst) {
71 c = FontFileGetc(file) << 24;
72 c |= FontFileGetc(file) << 16;
73 c |= FontFileGetc(file) << 8;
74 c |= FontFileGetc(file);
76 c = FontFileGetc(file);
77 c |= FontFileGetc(file) << 8;
78 c |= FontFileGetc(file) << 16;
79 c |= FontFileGetc(file) << 24;
86 pcfGetINT16(file, format)
92 if (PCF_BYTE_ORDER(format) == MSBFirst) {
93 c = FontFileGetc(file) << 8;
94 c |= FontFileGetc(file);
96 c = FontFileGetc(file);
97 c |= FontFileGetc(file) << 8;
103 #define pcfGetINT8(file, format) (position++, FontFileGetc(file))
106 pcfReadTOC(file, countp)
116 version = pcfGetLSB32(file);
117 if (version != PCF_FILE_VERSION)
118 return (PCFTablePtr) NULL;
119 count = pcfGetLSB32(file);
120 tables = (PCFTablePtr) xalloc(count * sizeof(PCFTableRec));
122 return (PCFTablePtr) NULL;
123 for (i = 0; i < count; i++) {
124 tables[i].type = pcfGetLSB32(file);
125 tables[i].format = pcfGetLSB32(file);
126 tables[i].size = pcfGetLSB32(file);
127 tables[i].offset = pcfGetLSB32(file);
134 * PCF supports two formats for metrics, both the regular
135 * jumbo size, and 'lite' metrics, which are useful
136 * for most fonts which have even vaguely reasonable
141 pcfGetMetric(file, format, metric)
146 metric->leftSideBearing = pcfGetINT16(file, format);
147 metric->rightSideBearing = pcfGetINT16(file, format);
148 metric->characterWidth = pcfGetINT16(file, format);
149 metric->ascent = pcfGetINT16(file, format);
150 metric->descent = pcfGetINT16(file, format);
151 metric->attributes = pcfGetINT16(file, format);
155 pcfGetCompressedMetric(file, format, metric)
160 metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
161 metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
162 metric->characterWidth = pcfGetINT8(file, format) - 0x80;
163 metric->ascent = pcfGetINT8(file, format) - 0x80;
164 metric->descent = pcfGetINT8(file, format) - 0x80;
165 metric->attributes = 0;
169 * Position the file to the begining of the specified table
173 pcfSeekToType(file, tables, ntables, type, formatp, sizep)
183 for (i = 0; i < ntables; i++)
184 if (tables[i].type == type) {
185 if (position > tables[i].offset)
187 if (!FontFileSkip(file, tables[i].offset - position))
189 position = tables[i].offset;
190 *sizep = tables[i].size;
191 *formatp = tables[i].format;
198 pcfHasType (tables, ntables, type)
205 for (i = 0; i < ntables; i++)
206 if (tables[i].type == type)
214 * Reads the font properties from the font file, filling in the FontInfo rec
215 * supplied. Used by by both ReadFont and ReadFontInfo routines.
219 pcfGetProperties(pFontInfo, file, tables, ntables)
220 FontInfoPtr pFontInfo;
225 FontPropPtr props = 0;
227 char *isStringProp = 0;
234 /* font properties */
236 if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
238 format = pcfGetLSB32(file);
239 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
241 nprops = pcfGetINT32(file, format);
242 props = (FontPropPtr) xalloc(nprops * sizeof(FontPropRec));
245 isStringProp = (char *) xalloc(nprops * sizeof(char));
248 for (i = 0; i < nprops; i++) {
249 props[i].name = pcfGetINT32(file, format);
250 isStringProp[i] = pcfGetINT8(file, format);
251 props[i].value = pcfGetINT32(file, format);
253 /* pad the property array */
255 * clever here - nprops is the same as the number of odd-units read, as
256 * only isStringProp are odd length
260 i = 4 - (nprops & 3);
261 FontFileSkip(file, i);
264 string_size = pcfGetINT32(file, format);
265 strings = (char *) xalloc(string_size);
269 FontFileRead(file, strings, string_size);
270 position += string_size;
271 for (i = 0; i < nprops; i++) {
272 props[i].name = MakeAtom(strings + props[i].name,
273 strlen(strings + props[i].name), TRUE);
274 if (isStringProp[i]) {
275 props[i].value = MakeAtom(strings + props[i].value,
276 strlen(strings + props[i].value), TRUE);
280 pFontInfo->isStringProp = isStringProp;
281 pFontInfo->props = props;
282 pFontInfo->nprops = nprops;
294 * Fill in the accelerator information from the font file; used
295 * to read both BDF_ACCELERATORS and old style ACCELERATORS
299 pcfGetAccel(pFontInfo, file, tables, ntables, type)
300 FontInfoPtr pFontInfo;
309 if (!pcfSeekToType(file, tables, ntables, type, &format, &size))
311 format = pcfGetLSB32(file);
312 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
313 !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS))
317 pFontInfo->noOverlap = pcfGetINT8(file, format);
318 pFontInfo->constantMetrics = pcfGetINT8(file, format);
319 pFontInfo->terminalFont = pcfGetINT8(file, format);
320 pFontInfo->constantWidth = pcfGetINT8(file, format);
321 pFontInfo->inkInside = pcfGetINT8(file, format);
322 pFontInfo->inkMetrics = pcfGetINT8(file, format);
323 pFontInfo->drawDirection = pcfGetINT8(file, format);
324 pFontInfo->anamorphic = FALSE;
325 pFontInfo->cachable = TRUE;
326 /* natural alignment */ pcfGetINT8(file, format);
327 pFontInfo->fontAscent = pcfGetINT32(file, format);
328 pFontInfo->fontDescent = pcfGetINT32(file, format);
329 pFontInfo->maxOverlap = pcfGetINT32(file, format);
330 pcfGetMetric(file, format, &pFontInfo->minbounds);
331 pcfGetMetric(file, format, &pFontInfo->maxbounds);
332 if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
333 pcfGetMetric(file, format, &pFontInfo->ink_minbounds);
334 pcfGetMetric(file, format, &pFontInfo->ink_maxbounds);
336 pFontInfo->ink_minbounds = pFontInfo->minbounds;
337 pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
345 pcfReadFont(pFont, file, bit, byte, glyph, scan)
355 BitmapFontPtr bitmapFont = 0;
357 PCFTablePtr tables = 0;
363 CharInfoPtr metrics = 0;
364 xCharInfo *ink_metrics = 0;
366 CharInfoPtr *encoding = 0;
369 CARD32 bitmapSizes[GLYPHPADOPTIONS];
371 Bool hasBDFAccelerators;
373 pFont->info.props = 0;
374 if (!(tables = pcfReadTOC(file, &ntables)))
379 if (!pcfGetProperties(&pFont->info, file, tables, ntables))
382 /* Use the old accelerators if no BDF accelerators are in the file */
384 hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
385 if (!hasBDFAccelerators)
386 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
391 if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
394 format = pcfGetLSB32(file);
395 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
396 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
399 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
400 nmetrics = pcfGetINT32(file, format);
402 nmetrics = pcfGetINT16(file, format);
403 metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec));
407 for (i = 0; i < nmetrics; i++)
408 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
409 pcfGetMetric(file, format, &(metrics + i)->metrics);
411 pcfGetCompressedMetric(file, format, &(metrics + i)->metrics);
415 if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
417 format = pcfGetLSB32(file);
418 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
421 nbitmaps = pcfGetINT32(file, format);
422 if (nbitmaps != nmetrics)
425 offsets = (CARD32 *) xalloc(nbitmaps * sizeof(CARD32));
429 for (i = 0; i < nbitmaps; i++)
430 offsets[i] = pcfGetINT32(file, format);
432 for (i = 0; i < GLYPHPADOPTIONS; i++)
433 bitmapSizes[i] = pcfGetINT32(file, format);
434 sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
435 /* guard against completely empty font */
436 bitmaps = (char *) xalloc(sizebitmaps ? sizebitmaps : 1);
439 FontFileRead(file, bitmaps, sizebitmaps);
440 position += sizebitmaps;
442 if (PCF_BIT_ORDER(format) != bit)
443 BitOrderInvert(bitmaps, sizebitmaps);
444 if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
445 switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
449 TwoByteSwap(bitmaps, sizebitmaps);
452 FourByteSwap(bitmaps, sizebitmaps);
456 if (PCF_GLYPH_PAD(format) != glyph) {
463 sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
464 padbitmaps = (char *) xalloc(sizepadbitmaps);
469 for (i = 0; i < nbitmaps; i++) {
471 metric = &metrics[i].metrics;
473 new += RepadBitmap(bitmaps + old, padbitmaps + new,
474 PCF_GLYPH_PAD(format), glyph,
475 metric->rightSideBearing - metric->leftSideBearing,
476 metric->ascent + metric->descent);
479 bitmaps = padbitmaps;
481 for (i = 0; i < nbitmaps; i++)
482 metrics[i].bits = bitmaps + offsets[i];
490 if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
491 format = pcfGetLSB32(file);
492 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
493 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
496 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
497 nink_metrics = pcfGetINT32(file, format);
499 nink_metrics = pcfGetINT16(file, format);
500 if (nink_metrics != nmetrics)
502 ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo));
505 for (i = 0; i < nink_metrics; i++)
506 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
507 pcfGetMetric(file, format, ink_metrics + i);
509 pcfGetCompressedMetric(file, format, ink_metrics + i);
514 if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
516 format = pcfGetLSB32(file);
517 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
520 pFont->info.firstCol = pcfGetINT16(file, format);
521 pFont->info.lastCol = pcfGetINT16(file, format);
522 pFont->info.firstRow = pcfGetINT16(file, format);
523 pFont->info.lastRow = pcfGetINT16(file, format);
524 pFont->info.defaultCh = pcfGetINT16(file, format);
526 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
527 (pFont->info.lastRow - pFont->info.firstRow + 1);
529 encoding = (CharInfoPtr *) xalloc(nencoding * sizeof(CharInfoPtr));
533 pFont->info.allExist = TRUE;
534 for (i = 0; i < nencoding; i++) {
535 encodingOffset = pcfGetINT16(file, format);
536 if (encodingOffset == 0xFFFF) {
537 pFont->info.allExist = FALSE;
540 encoding[i] = metrics + encodingOffset;
543 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
545 if (hasBDFAccelerators)
546 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
549 bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont);
553 bitmapFont->version_num = PCF_FILE_VERSION;
554 bitmapFont->num_chars = nmetrics;
555 bitmapFont->num_tables = ntables;
556 bitmapFont->metrics = metrics;
557 bitmapFont->ink_metrics = ink_metrics;
558 bitmapFont->bitmaps = bitmaps;
559 bitmapFont->encoding = encoding;
560 bitmapFont->pDefault = (CharInfoPtr) 0;
561 if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
566 r = pFont->info.defaultCh >> 8;
567 c = pFont->info.defaultCh & 0xFF;
568 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
569 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
570 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
571 r = r - pFont->info.firstRow;
572 c = c - pFont->info.firstCol;
573 bitmapFont->pDefault = encoding[r * cols + c];
576 bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
577 pFont->fontPrivate = (pointer) bitmapFont;
578 pFont->get_glyphs = bitmapGetGlyphs;
579 pFont->get_metrics = bitmapGetMetrics;
580 pFont->unload_font = pcfUnloadFont;
581 pFont->unload_glyphs = NULL;
584 pFont->glyph = glyph;
594 xfree(pFont->info.props);
595 pFont->info.props = 0;
602 pcfReadFontInfo(pFontInfo, file)
603 FontInfoPtr pFontInfo;
611 Bool hasBDFAccelerators;
613 pFontInfo->isStringProp = NULL;
614 pFontInfo->props = NULL;
616 if (!(tables = pcfReadTOC(file, &ntables)))
621 if (!pcfGetProperties(pFontInfo, file, tables, ntables))
624 /* Use the old accelerators if no BDF accelerators are in the file */
626 hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
627 if (!hasBDFAccelerators)
628 if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
633 if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
635 format = pcfGetLSB32(file);
636 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
639 pFontInfo->firstCol = pcfGetINT16(file, format);
640 pFontInfo->lastCol = pcfGetINT16(file, format);
641 pFontInfo->firstRow = pcfGetINT16(file, format);
642 pFontInfo->lastRow = pcfGetINT16(file, format);
643 pFontInfo->defaultCh = pcfGetINT16(file, format);
645 nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
646 (pFontInfo->lastRow - pFontInfo->firstRow + 1);
648 pFontInfo->allExist = TRUE;
649 while (nencoding--) {
650 if (pcfGetINT16(file, format) == 0xFFFF)
651 pFontInfo->allExist = FALSE;
654 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
656 if (hasBDFAccelerators)
657 if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
663 xfree (pFontInfo->props);
664 xfree (pFontInfo->isStringProp);
673 BitmapFontPtr bitmapFont;
675 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
676 xfree(bitmapFont->ink_metrics);
677 xfree(bitmapFont->encoding);
678 xfree(bitmapFont->bitmaps);
679 xfree(bitmapFont->metrics);
680 xfree(pFont->info.isStringProp);
681 xfree(pFont->info.props);
683 xfree(pFont->devPrivates);
688 pmfReadFont(pFont, file, bit, byte, glyph, scan)
698 BitmapFontPtr bitmapFont = 0;
700 PCFTablePtr tables = 0;
705 CharInfoPtr metrics = 0;
706 xCharInfo *ink_metrics = 0;
708 CharInfoPtr *encoding = 0;
711 CARD32 bitmapSizes[GLYPHPADOPTIONS];
712 Bool hasBDFAccelerators;
715 pFont->info.props = 0;
716 if (!(tables = pcfReadTOC(file, &ntables)))
721 if (!pcfGetProperties(&pFont->info, file, tables, ntables))
724 /* Use the old accelerators if no BDF accelerators are in the file */
726 hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
727 if (!hasBDFAccelerators)
728 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
733 if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
736 format = pcfGetLSB32(file);
737 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
738 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
741 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
742 nmetrics = pcfGetINT32(file, format);
744 nmetrics = pcfGetINT16(file, format);
745 metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec));
749 for (i = 0; i < nmetrics; i++)
750 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
751 pcfGetMetric(file, format, &(metrics + i)->metrics);
753 pcfGetCompressedMetric(file, format, &(metrics + i)->metrics);
755 /* Set the bitmaps to all point to the same zero filled array
756 * that is the size of the largest bitmap.
761 for (i = 0; i < nmetrics; i++)
763 sizebitmaps = MAX(sizebitmaps,BYTES_FOR_GLYPH(pci, glyph));
767 sizebitmaps = BUFSIZ;
768 /* guard against completely empty font */
769 bitmaps = (char *) xalloc(sizebitmaps);
773 memset(bitmaps,0,sizebitmaps);
774 for (i = 0; i < nmetrics; i++)
775 metrics[i].bits = bitmaps;
780 if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
781 format = pcfGetLSB32(file);
782 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
783 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
786 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
787 nink_metrics = pcfGetINT32(file, format);
789 nink_metrics = pcfGetINT16(file, format);
790 if (nink_metrics != nmetrics)
792 ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo));
795 for (i = 0; i < nink_metrics; i++)
796 if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
797 pcfGetMetric(file, format, ink_metrics + i);
799 pcfGetCompressedMetric(file, format, ink_metrics + i);
804 if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
806 format = pcfGetLSB32(file);
807 if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
810 pFont->info.firstCol = pcfGetINT16(file, format);
811 pFont->info.lastCol = pcfGetINT16(file, format);
812 pFont->info.firstRow = pcfGetINT16(file, format);
813 pFont->info.lastRow = pcfGetINT16(file, format);
814 pFont->info.defaultCh = pcfGetINT16(file, format);
816 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
817 (pFont->info.lastRow - pFont->info.firstRow + 1);
819 encoding = (CharInfoPtr *) xalloc(nencoding * sizeof(CharInfoPtr));
823 pFont->info.allExist = TRUE;
824 for (i = 0; i < nencoding; i++) {
825 encodingOffset = pcfGetINT16(file, format);
826 if (encodingOffset == 0xFFFF) {
827 pFont->info.allExist = FALSE;
830 encoding[i] = metrics + encodingOffset;
833 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
835 if (hasBDFAccelerators)
836 if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
839 bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont);
843 bitmapFont->version_num = PCF_FILE_VERSION;
844 bitmapFont->num_chars = nmetrics;
845 bitmapFont->num_tables = ntables;
846 bitmapFont->metrics = metrics;
847 bitmapFont->ink_metrics = ink_metrics;
848 bitmapFont->bitmaps = bitmaps;
849 bitmapFont->encoding = encoding;
850 bitmapFont->pDefault = (CharInfoPtr) 0;
851 if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
856 r = pFont->info.defaultCh >> 8;
857 c = pFont->info.defaultCh & 0xFF;
858 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
859 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
860 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
861 r = r - pFont->info.firstRow;
862 c = c - pFont->info.firstCol;
863 bitmapFont->pDefault = encoding[r * cols + c];
866 bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
867 pFont->fontPrivate = (pointer) bitmapFont;
868 pFont->get_glyphs = bitmapGetGlyphs;
869 pFont->get_metrics = bitmapGetMetrics;
870 pFont->unload_font = pcfUnloadFont;
871 pFont->unload_glyphs = NULL;
874 pFont->glyph = glyph;
882 xfree(pFont->info.props);
884 pFont->info.props = 0;