upload tizen1.0 source
[framework/uifw/xorg/lib/libxfont.git] / src / bitmap / pcfread.c
1 /*
2
3 Copyright 1990, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
25 from The Open Group.
26
27 */
28
29 /*
30  * Author:  Keith Packard, MIT X Consortium
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <X11/fonts/fntfilst.h>
38 #include <X11/fonts/bitmap.h>
39 #include <X11/fonts/pcf.h>
40
41 #ifndef MAX
42 #define   MAX(a,b)    (((a)>(b)) ? a : b)
43 #endif
44
45 #include <stdarg.h>
46 #include <stdint.h>
47
48 void
49 pcfError(const char* message, ...)
50 {
51     va_list args;
52
53     va_start(args, message);
54
55     fprintf(stderr, "PCF Error: ");
56     vfprintf(stderr, message, args);
57     va_end(args);
58 }
59                               
60 /* Read PCF font files */
61
62 static void pcfUnloadFont ( FontPtr pFont );
63 static int  position;
64
65
66 #define IS_EOF(file) ((file)->eof == BUFFILEEOF)
67
68 #define FONT_FILE_GETC_ERR(f)  (tmp = FontFileGetc(f), BAIL_ON_EOF)
69
70 static int
71 pcfGetLSB32(FontFilePtr file)
72 {
73     int         c;
74
75     c = FontFileGetc(file);
76     c |= FontFileGetc(file) << 8;
77     c |= FontFileGetc(file) << 16;
78     c |= FontFileGetc(file) << 24;
79     position += 4;
80     return c;
81 }
82
83 static int
84 pcfGetINT32(FontFilePtr file, CARD32 format)
85 {
86     int         c;
87
88     if (PCF_BYTE_ORDER(format) == MSBFirst) {
89         c = FontFileGetc(file) << 24;
90         c |= FontFileGetc(file) << 16;
91         c |= FontFileGetc(file) << 8;
92         c |= FontFileGetc(file);
93     } else {
94         c = FontFileGetc(file);
95         c |= FontFileGetc(file) << 8;
96         c |= FontFileGetc(file) << 16;
97         c |= FontFileGetc(file) << 24;
98     }
99     position += 4;
100     return c;
101 }
102
103 static int
104 pcfGetINT16(FontFilePtr file, CARD32 format)
105 {
106     int         c;
107
108     if (PCF_BYTE_ORDER(format) == MSBFirst) {
109         c = FontFileGetc(file) << 8;
110         c |= FontFileGetc(file);
111     } else {
112         c = FontFileGetc(file);
113         c |= FontFileGetc(file) << 8;
114     }
115     position += 2;
116     return c;
117 }
118
119 #define pcfGetINT8(file, format) (position++, FontFileGetc(file))
120
121 static      PCFTablePtr
122 pcfReadTOC(FontFilePtr file, int *countp)
123 {
124     CARD32      version;
125     PCFTablePtr tables;
126     int         count;
127     int         i;
128
129     position = 0;
130     version = pcfGetLSB32(file);
131     if (version != PCF_FILE_VERSION)
132         return (PCFTablePtr) NULL;
133     count = pcfGetLSB32(file);
134     if (IS_EOF(file)) return (PCFTablePtr) NULL;
135     if (count < 0 || count > INT32_MAX / sizeof(PCFTableRec)) {
136         pcfError("pcfReadTOC(): invalid file format\n");
137         return NULL;
138     }
139     tables = malloc(count * sizeof(PCFTableRec));
140     if (!tables) {
141       pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n", count, sizeof(PCFTableRec));
142         return (PCFTablePtr) NULL;
143     }
144     for (i = 0; i < count; i++) {
145         tables[i].type = pcfGetLSB32(file);
146         tables[i].format = pcfGetLSB32(file);
147         tables[i].size = pcfGetLSB32(file);
148         tables[i].offset = pcfGetLSB32(file);
149         if (IS_EOF(file)) goto Bail;
150     }
151
152     *countp = count;
153     return tables;
154
155  Bail:
156     free(tables);
157     return (PCFTablePtr) NULL;
158 }
159
160 /*
161  * PCF supports two formats for metrics, both the regular
162  * jumbo size, and 'lite' metrics, which are useful
163  * for most fonts which have even vaguely reasonable
164  * metrics
165  */
166
167 static Bool
168 pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
169 {
170     metric->leftSideBearing = pcfGetINT16(file, format);
171     metric->rightSideBearing = pcfGetINT16(file, format);
172     metric->characterWidth = pcfGetINT16(file, format);
173     metric->ascent = pcfGetINT16(file, format);
174     metric->descent = pcfGetINT16(file, format);
175     metric->attributes = pcfGetINT16(file, format);
176     if (IS_EOF(file)) return FALSE;
177
178     return TRUE;
179 }
180
181 static Bool
182 pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
183 {
184     metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
185     metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
186     metric->characterWidth = pcfGetINT8(file, format) - 0x80;
187     metric->ascent = pcfGetINT8(file, format) - 0x80;
188     metric->descent = pcfGetINT8(file, format) - 0x80;
189     metric->attributes = 0;
190     if (IS_EOF(file)) return FALSE;
191
192     return TRUE;
193 }
194
195 /*
196  * Position the file to the begining of the specified table
197  * in the font file
198  */
199 static Bool
200 pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables, 
201               CARD32 type, CARD32 *formatp, CARD32 *sizep)
202 {
203     int         i;
204
205     for (i = 0; i < ntables; i++)
206         if (tables[i].type == type) {
207             if (position > tables[i].offset)
208                 return FALSE;
209             if (!FontFileSkip(file, tables[i].offset - position))
210                 return FALSE;
211             position = tables[i].offset;
212             *sizep = tables[i].size;
213             *formatp = tables[i].format;
214             return TRUE;
215         }
216     return FALSE;
217 }
218
219 static Bool
220 pcfHasType (PCFTablePtr tables, int ntables, CARD32 type)
221 {
222     int         i;
223
224     for (i = 0; i < ntables; i++)
225         if (tables[i].type == type)
226             return TRUE;
227     return FALSE;
228 }
229
230 /*
231  * pcfGetProperties 
232  *
233  * Reads the font properties from the font file, filling in the FontInfo rec
234  * supplied.  Used by by both ReadFont and ReadFontInfo routines.
235  */
236
237 static Bool
238 pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file, 
239                  PCFTablePtr tables, int ntables)
240 {
241     FontPropPtr props = 0;
242     int         nprops;
243     char       *isStringProp = 0;
244     CARD32      format;
245     int         i;
246     CARD32      size;
247     int         string_size;
248     char       *strings;
249
250     /* font properties */
251
252     if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
253         goto Bail;
254     format = pcfGetLSB32(file);
255     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
256         goto Bail;
257     nprops = pcfGetINT32(file, format);
258     if (nprops <= 0 || nprops > INT32_MAX / sizeof(FontPropRec)) {
259         pcfError("pcfGetProperties(): invalid nprops value (%d)\n", nprops);
260         goto Bail;
261     }
262     if (IS_EOF(file)) goto Bail;
263     props = malloc(nprops * sizeof(FontPropRec));
264     if (!props) {
265       pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n", nprops, sizeof(FontPropRec));
266         goto Bail;
267     }
268     isStringProp = malloc(nprops * sizeof(char));
269     if (!isStringProp) {
270       pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n", nprops, sizeof(char));
271         goto Bail;
272     }
273     for (i = 0; i < nprops; i++) {
274         props[i].name = pcfGetINT32(file, format);
275         isStringProp[i] = pcfGetINT8(file, format);
276         props[i].value = pcfGetINT32(file, format);
277         if (props[i].name < 0 
278             || (isStringProp[i] != 0 && isStringProp[i] != 1)
279             || (isStringProp[i] && props[i].value < 0)) {
280             pcfError("pcfGetProperties(): invalid file format %d %d %d\n",
281                      props[i].name, isStringProp[i], props[i].value);
282             goto Bail;
283         }
284         if (IS_EOF(file)) goto Bail;
285     }
286     /* pad the property array */
287     /*
288      * clever here - nprops is the same as the number of odd-units read, as
289      * only isStringProp are odd length
290      */
291     if (nprops & 3)
292     {
293         i = 4 - (nprops & 3);
294         (void)FontFileSkip(file, i);
295         position += i;
296     }
297     if (IS_EOF(file)) goto Bail;
298     string_size = pcfGetINT32(file, format);
299     if (string_size < 0) goto Bail;
300     if (IS_EOF(file)) goto Bail;
301     strings = malloc(string_size);
302     if (!strings) {
303       pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size);
304         goto Bail;
305     }
306     FontFileRead(file, strings, string_size);
307     if (IS_EOF(file)) goto Bail;
308     position += string_size;
309     for (i = 0; i < nprops; i++) {
310         props[i].name = MakeAtom(strings + props[i].name,
311                                  strlen(strings + props[i].name), TRUE);
312         if (isStringProp[i]) {
313             props[i].value = MakeAtom(strings + props[i].value,
314                                       strlen(strings + props[i].value), TRUE);
315         }
316     }
317     free(strings);
318     pFontInfo->isStringProp = isStringProp;
319     pFontInfo->props = props;
320     pFontInfo->nprops = nprops;
321     return TRUE;
322 Bail:
323     free(isStringProp);
324     free(props);
325     return FALSE;
326 }
327
328
329 /*
330  * pcfReadAccel
331  *
332  * Fill in the accelerator information from the font file; used
333  * to read both BDF_ACCELERATORS and old style ACCELERATORS
334  */
335
336 static Bool
337 pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file, 
338             PCFTablePtr tables, int ntables, CARD32 type)
339 {
340     CARD32      format;
341     CARD32      size;
342
343     if (!pcfSeekToType(file, tables, ntables, type, &format, &size) ||
344         IS_EOF(file))
345         goto Bail;
346     format = pcfGetLSB32(file);
347     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
348         !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) 
349     {
350         goto Bail;
351     }
352     pFontInfo->noOverlap = pcfGetINT8(file, format);
353     pFontInfo->constantMetrics = pcfGetINT8(file, format);
354     pFontInfo->terminalFont = pcfGetINT8(file, format);
355     pFontInfo->constantWidth = pcfGetINT8(file, format);
356     pFontInfo->inkInside = pcfGetINT8(file, format);
357     pFontInfo->inkMetrics = pcfGetINT8(file, format);
358     pFontInfo->drawDirection = pcfGetINT8(file, format);
359     pFontInfo->anamorphic = FALSE;
360     pFontInfo->cachable = TRUE;
361      /* natural alignment */ pcfGetINT8(file, format);
362     pFontInfo->fontAscent = pcfGetINT32(file, format);
363     pFontInfo->fontDescent = pcfGetINT32(file, format);
364     pFontInfo->maxOverlap = pcfGetINT32(file, format);
365     if (IS_EOF(file)) goto Bail;
366     if (!pcfGetMetric(file, format, &pFontInfo->minbounds))
367         goto Bail;
368     if (!pcfGetMetric(file, format, &pFontInfo->maxbounds))
369         goto Bail;
370     if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
371         if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds))
372             goto Bail;
373         if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds))
374             goto Bail;
375     } else {
376         pFontInfo->ink_minbounds = pFontInfo->minbounds;
377         pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
378     }
379     return TRUE;
380 Bail:
381     return FALSE;
382 }
383
384 int
385 pcfReadFont(FontPtr pFont, FontFilePtr file, 
386             int bit, int byte, int glyph, int scan)
387 {
388     CARD32      format;
389     CARD32      size;
390     BitmapFontPtr  bitmapFont = 0;
391     int         i;
392     PCFTablePtr tables = 0;
393     int         ntables;
394     int         nmetrics;
395     int         nbitmaps;
396     int         sizebitmaps;
397     int         nink_metrics;
398     CharInfoPtr metrics = 0;
399     xCharInfo  *ink_metrics = 0;
400     char       *bitmaps = 0;
401     CharInfoPtr **encoding = 0;
402     int         nencoding = 0;
403     int         encodingOffset;
404     CARD32      bitmapSizes[GLYPHPADOPTIONS];
405     CARD32     *offsets = 0;
406     Bool        hasBDFAccelerators;
407
408     pFont->info.nprops = 0;
409     pFont->info.props = 0;
410     if (!(tables = pcfReadTOC(file, &ntables)))
411         goto Bail;
412
413     /* properties */
414
415     if (!pcfGetProperties(&pFont->info, file, tables, ntables))
416         goto Bail;
417
418     /* Use the old accelerators if no BDF accelerators are in the file */
419
420     hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
421     if (!hasBDFAccelerators)
422         if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
423             goto Bail;
424
425     /* metrics */
426
427     if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
428         goto Bail;
429     }
430     format = pcfGetLSB32(file);
431     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
432             !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
433         goto Bail;
434     }
435     if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
436         nmetrics = pcfGetINT32(file, format);
437     else
438         nmetrics = pcfGetINT16(file, format);
439     if (IS_EOF(file)) goto Bail;
440     if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) {
441         pcfError("pcfReadFont(): invalid file format\n");
442         goto Bail;
443     }
444     metrics = malloc(nmetrics * sizeof(CharInfoRec));
445     if (!metrics) {
446       pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec));
447         goto Bail;
448     }
449     for (i = 0; i < nmetrics; i++)
450         if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
451             if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
452                 goto Bail;
453         } else {
454             if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
455                 goto Bail;
456         }
457     
458     /* bitmaps */
459
460     if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
461         goto Bail;
462     format = pcfGetLSB32(file);
463     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
464         goto Bail;
465
466     nbitmaps = pcfGetINT32(file, format);
467     if (nbitmaps != nmetrics || IS_EOF(file))
468         goto Bail;
469     /* nmetrics is already ok, so nbitmap also is */
470     offsets = malloc(nbitmaps * sizeof(CARD32));
471     if (!offsets) {
472       pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", nbitmaps, sizeof(CARD32));
473         goto Bail;
474     }
475     for (i = 0; i < nbitmaps; i++) {
476         offsets[i] = pcfGetINT32(file, format);
477         if (IS_EOF(file)) goto Bail;
478     }
479
480     for (i = 0; i < GLYPHPADOPTIONS; i++) {
481         bitmapSizes[i] = pcfGetINT32(file, format);
482         if (IS_EOF(file)) goto Bail;
483         if (bitmapSizes[i] < 0) goto Bail;
484     }
485     
486     sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
487     /* guard against completely empty font */
488     bitmaps = malloc(sizebitmaps ? sizebitmaps : 1);
489     if (!bitmaps) {
490       pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1);
491         goto Bail;
492     }
493     FontFileRead(file, bitmaps, sizebitmaps);
494     if (IS_EOF(file)) goto Bail;
495     position += sizebitmaps;
496
497     if (PCF_BIT_ORDER(format) != bit)
498         BitOrderInvert((unsigned char *)bitmaps, sizebitmaps);
499     if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
500         switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
501         case 1:
502             break;
503         case 2:
504             TwoByteSwap((unsigned char *)bitmaps, sizebitmaps);
505             break;
506         case 4:
507             FourByteSwap((unsigned char *)bitmaps, sizebitmaps);
508             break;
509         }
510     }
511     if (PCF_GLYPH_PAD(format) != glyph) {
512         char       *padbitmaps;
513         int         sizepadbitmaps;
514         int         old,
515                     new;
516         xCharInfo  *metric;
517
518         sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
519         padbitmaps = malloc(sizepadbitmaps);
520         if (!padbitmaps) {
521           pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
522             goto Bail;
523         }
524         new = 0;
525         for (i = 0; i < nbitmaps; i++) {
526             old = offsets[i];
527             metric = &metrics[i].metrics;
528             offsets[i] = new;
529             new += RepadBitmap(bitmaps + old, padbitmaps + new,
530                                PCF_GLYPH_PAD(format), glyph,
531                           metric->rightSideBearing - metric->leftSideBearing,
532                                metric->ascent + metric->descent);
533         }
534         free(bitmaps);
535         bitmaps = padbitmaps;
536     }
537     for (i = 0; i < nbitmaps; i++)
538         metrics[i].bits = bitmaps + offsets[i];
539
540     free(offsets);
541     offsets = NULL;
542
543     /* ink metrics ? */
544
545     ink_metrics = NULL;
546     if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
547         format = pcfGetLSB32(file);
548         if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
549                 !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
550             goto Bail;
551         }
552         if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
553             nink_metrics = pcfGetINT32(file, format);
554         else
555             nink_metrics = pcfGetINT16(file, format);
556         if (IS_EOF(file)) goto Bail;
557         if (nink_metrics != nmetrics)
558             goto Bail;
559         /* nmetrics already checked */
560         ink_metrics = malloc(nink_metrics * sizeof(xCharInfo));
561       if (!ink_metrics) {
562           pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo));       
563             goto Bail;
564       }
565         for (i = 0; i < nink_metrics; i++)
566             if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
567                 if (!pcfGetMetric(file, format, ink_metrics + i))
568                     goto Bail;
569             } else {
570                 if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
571                     goto Bail;
572             }
573     }
574
575     /* encoding */
576
577     if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
578         goto Bail;
579     format = pcfGetLSB32(file);
580     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
581         goto Bail;
582
583     pFont->info.firstCol = pcfGetINT16(file, format);
584     pFont->info.lastCol = pcfGetINT16(file, format);
585     pFont->info.firstRow = pcfGetINT16(file, format);
586     pFont->info.lastRow = pcfGetINT16(file, format);
587     pFont->info.defaultCh = pcfGetINT16(file, format);
588     if (IS_EOF(file)) goto Bail;
589     if (pFont->info.firstCol > pFont->info.lastCol ||
590        pFont->info.firstRow > pFont->info.lastRow ||
591        pFont->info.lastCol-pFont->info.firstCol > 255) goto Bail;
592
593     nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
594         (pFont->info.lastRow - pFont->info.firstRow + 1);
595
596     encoding = calloc(NUM_SEGMENTS(nencoding), sizeof(CharInfoPtr*));
597     if (!encoding) {
598       pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr));    
599         goto Bail;
600     }
601     
602     pFont->info.allExist = TRUE;
603     for (i = 0; i < nencoding; i++) {
604         encodingOffset = pcfGetINT16(file, format);
605         if (IS_EOF(file)) goto Bail;
606         if (encodingOffset == 0xFFFF) {
607             pFont->info.allExist = FALSE;
608         } else {
609             if(!encoding[SEGMENT_MAJOR(i)]) {
610                 encoding[SEGMENT_MAJOR(i)]=
611                     calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
612                 if(!encoding[SEGMENT_MAJOR(i)])
613                     goto Bail;
614             }
615             ACCESSENCODINGL(encoding, i) = metrics + encodingOffset;
616         }
617     }
618
619     /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
620
621     if (hasBDFAccelerators)
622         if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
623             goto Bail;
624
625     bitmapFont = malloc(sizeof *bitmapFont);
626     if (!bitmapFont) {
627       pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont);
628         goto Bail;
629     }
630
631     bitmapFont->version_num = PCF_FILE_VERSION;
632     bitmapFont->num_chars = nmetrics;
633     bitmapFont->num_tables = ntables;
634     bitmapFont->metrics = metrics;
635     bitmapFont->ink_metrics = ink_metrics;
636     bitmapFont->bitmaps = bitmaps;
637     bitmapFont->encoding = encoding;
638     bitmapFont->pDefault = (CharInfoPtr) 0;
639     if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
640         unsigned int r,
641                     c,
642                     cols;
643
644         r = pFont->info.defaultCh >> 8;
645         c = pFont->info.defaultCh & 0xFF;
646         if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
647                 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
648             cols = pFont->info.lastCol - pFont->info.firstCol + 1;
649             r = r - pFont->info.firstRow;
650             c = c - pFont->info.firstCol;
651             bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c);
652         }
653     }
654     bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
655     pFont->fontPrivate = (pointer) bitmapFont;
656     pFont->get_glyphs = bitmapGetGlyphs;
657     pFont->get_metrics = bitmapGetMetrics;
658     pFont->unload_font = pcfUnloadFont;
659     pFont->unload_glyphs = NULL;
660     pFont->bit = bit;
661     pFont->byte = byte;
662     pFont->glyph = glyph;
663     pFont->scan = scan;
664     free(tables);
665     return Successful;
666 Bail:
667     free(ink_metrics);
668     if(encoding) {
669         for(i=0; i<NUM_SEGMENTS(nencoding); i++)
670             free(encoding[i]);
671     }
672     free(encoding);
673     free(bitmaps);
674     free(metrics);
675     free(pFont->info.props);
676     pFont->info.nprops = 0;
677     pFont->info.props = 0;
678     free (pFont->info.isStringProp);
679     free(bitmapFont);
680     free(tables);
681     free(offsets);
682     return AllocError;
683 }
684
685 int
686 pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
687 {
688     PCFTablePtr tables;
689     int         ntables;
690     CARD32      format;
691     CARD32      size;
692     int         nencoding;
693     Bool        hasBDFAccelerators;
694
695     pFontInfo->isStringProp = NULL;
696     pFontInfo->props = NULL;
697     pFontInfo->nprops = 0;
698
699     if (!(tables = pcfReadTOC(file, &ntables)))
700         goto Bail;
701
702     /* properties */
703
704     if (!pcfGetProperties(pFontInfo, file, tables, ntables))
705         goto Bail;
706
707     /* Use the old accelerators if no BDF accelerators are in the file */
708
709     hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
710     if (!hasBDFAccelerators)
711         if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
712             goto Bail;
713
714     /* encoding */
715
716     if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
717         goto Bail;
718     format = pcfGetLSB32(file);
719     if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
720         goto Bail;
721
722     pFontInfo->firstCol = pcfGetINT16(file, format);
723     pFontInfo->lastCol = pcfGetINT16(file, format);
724     pFontInfo->firstRow = pcfGetINT16(file, format);
725     pFontInfo->lastRow = pcfGetINT16(file, format);
726     pFontInfo->defaultCh = pcfGetINT16(file, format);
727     if (IS_EOF(file)) goto Bail;
728     if (pFontInfo->firstCol > pFontInfo->lastCol ||
729        pFontInfo->firstRow > pFontInfo->lastRow ||
730        pFontInfo->lastCol-pFontInfo->firstCol > 255) goto Bail;
731
732     nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
733         (pFontInfo->lastRow - pFontInfo->firstRow + 1);
734
735     pFontInfo->allExist = TRUE;
736     while (nencoding--) {
737         if (pcfGetINT16(file, format) == 0xFFFF)
738             pFontInfo->allExist = FALSE;
739         if (IS_EOF(file)) goto Bail;
740     }
741     if (IS_EOF(file)) goto Bail;
742
743     /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
744
745     if (hasBDFAccelerators)
746         if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
747             goto Bail;
748
749     free(tables);
750     return Successful;
751 Bail:
752     pFontInfo->nprops = 0;
753     free (pFontInfo->props);
754     free (pFontInfo->isStringProp);
755     free(tables);
756     return AllocError;
757 }
758
759 static void
760 pcfUnloadFont(FontPtr pFont)
761 {
762     BitmapFontPtr  bitmapFont;
763     int i,nencoding;
764
765     bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
766     free(bitmapFont->ink_metrics);
767     if(bitmapFont->encoding) {
768         nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
769             (pFont->info.lastRow - pFont->info.firstRow + 1);
770         for(i=0; i<NUM_SEGMENTS(nencoding); i++)
771             free(bitmapFont->encoding[i]);
772     }
773     free(bitmapFont->encoding);
774     free(bitmapFont->bitmaps);
775     free(bitmapFont->metrics);
776     free(pFont->info.isStringProp);
777     free(pFont->info.props);
778     free(bitmapFont);
779     DestroyFontRec(pFont);
780 }