ReactOS 0.4.16-dev-2332-g4cba65d
pcfread.c
Go to the documentation of this file.
1/* pcfread.c
2
3 FreeType font driver for pcf fonts
4
5 Copyright 2000-2010, 2012-2014 by
6 Francesco Zappa Nardelli
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in
16all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24THE SOFTWARE.
25*/
26
27
28
32
33#include "pcf.h"
34#include "pcfread.h"
35
36#include "pcferror.h"
37
38
39 /**************************************************************************
40 *
41 * The macro FT_COMPONENT is used in trace mode. It is an implicit
42 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
43 * messages during execution.
44 */
45#undef FT_COMPONENT
46#define FT_COMPONENT pcfread
47
48
49#ifdef FT_DEBUG_LEVEL_TRACE
50 static const char* const tableNames[] =
51 {
52 "properties",
53 "accelerators",
54 "metrics",
55 "bitmaps",
56 "ink metrics",
57 "encodings",
58 "swidths",
59 "glyph names",
60 "BDF accelerators"
61 };
62#endif
63
64
65 static
67 {
68#undef FT_STRUCTURE
69#define FT_STRUCTURE PCF_TocRec
70
71 FT_FRAME_START( 8 ),
75 };
76
77
78 static
80 {
81#undef FT_STRUCTURE
82#define FT_STRUCTURE PCF_TableRec
83
84 FT_FRAME_START( 16 ),
87 FT_FRAME_ULONG_LE( size ), /* rounded up to a multiple of 4 */
90 };
91
92
93 static FT_Error
96 {
98 PCF_Toc toc = &face->toc;
100
101 FT_Memory memory = FT_FACE( face )->memory;
102 FT_UInt n;
103
105
106
107 if ( FT_STREAM_SEEK( 0 ) ||
109 return FT_THROW( Cannot_Open_Resource );
110
111 if ( toc->version != PCF_FILE_VERSION ||
112 toc->count == 0 )
113 return FT_THROW( Invalid_File_Format );
114
115 if ( stream->size < 16 )
116 return FT_THROW( Invalid_File_Format );
117
118 /* we need 16 bytes per TOC entry, */
119 /* and there can be most 9 tables */
120 if ( toc->count > ( stream->size >> 4 ) ||
121 toc->count > 9 )
122 {
123 FT_TRACE0(( "pcf_read_TOC: adjusting number of tables"
124 " (from %ld to %ld)\n",
125 toc->count,
126 FT_MIN( stream->size >> 4, 9 ) ));
127 toc->count = FT_MIN( stream->size >> 4, 9 );
128 }
129
130 if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
131 return error;
132
133 tables = face->toc.tables;
134 for ( n = 0; n < toc->count; n++ )
135 {
137 goto Exit;
138 tables++;
139 }
140
141 /* Sort tables and check for overlaps. Because they are almost */
142 /* always ordered already, an in-place bubble sort with simultaneous */
143 /* boundary checking seems appropriate. */
144 tables = face->toc.tables;
145
146 for ( n = 0; n < toc->count - 1; n++ )
147 {
148 FT_UInt i, have_change;
149
150
151 have_change = 0;
152
153 for ( i = 0; i < toc->count - 1 - n; i++ )
154 {
155 PCF_TableRec tmp;
156
157
158 if ( tables[i].offset > tables[i + 1].offset )
159 {
160 tmp = tables[i];
161 tables[i] = tables[i + 1];
162 tables[i + 1] = tmp;
163
164 have_change = 1;
165 }
166
167 if ( ( tables[i].size > tables[i + 1].offset ) ||
168 ( tables[i].offset > tables[i + 1].offset - tables[i].size ) )
169 {
170 error = FT_THROW( Invalid_Offset );
171 goto Exit;
172 }
173 }
174
175 if ( !have_change )
176 break;
177 }
178
179 /*
180 * We now check whether the `size' and `offset' values are reasonable:
181 * `offset' + `size' must not exceed the stream size.
182 *
183 * Note, however, that X11's `pcfWriteFont' routine (used by the
184 * `bdftopcf' program to create PCF font files) has two special
185 * features.
186 *
187 * - It always assigns the accelerator table a size of 100 bytes in the
188 * TOC, regardless of its real size, which can vary between 34 and 72
189 * bytes.
190 *
191 * - Due to the way the routine is designed, it ships out the last font
192 * table with its real size, ignoring the TOC's size value. Since
193 * the TOC size values are always rounded up to a multiple of 4, the
194 * difference can be up to three bytes for all tables except the
195 * accelerator table, for which the difference can be as large as 66
196 * bytes.
197 *
198 */
199
200 tables = face->toc.tables;
201 size = stream->size;
202
203 for ( n = 0; n < toc->count - 1; n++ )
204 {
205 /* we need two checks to avoid overflow */
206 if ( ( tables->size > size ) ||
207 ( tables->offset > size - tables->size ) )
208 {
209 error = FT_THROW( Invalid_Table );
210 goto Exit;
211 }
212 tables++;
213 }
214
215 /* only check `tables->offset' for last table element ... */
216 if ( ( tables->offset > size ) )
217 {
218 error = FT_THROW( Invalid_Table );
219 goto Exit;
220 }
221 /* ... and adjust `tables->size' to the real value if necessary */
222 if ( tables->size > size - tables->offset )
223 tables->size = size - tables->offset;
224
225#ifdef FT_DEBUG_LEVEL_TRACE
226
227 {
228 FT_UInt i, j;
229 const char* name = "?";
230
231
232 FT_TRACE4(( "pcf_read_TOC:\n" ));
233
234 FT_TRACE4(( " number of tables: %ld\n", face->toc.count ));
235
236 tables = face->toc.tables;
237 for ( i = 0; i < toc->count; i++ )
238 {
239 for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
240 j++ )
241 if ( tables[i].type == (FT_UInt)( 1 << j ) )
242 name = tableNames[j];
243
244 FT_TRACE4(( " %d: type=%s, format=0x%lX,"
245 " size=%ld (0x%lX), offset=%ld (0x%lX)\n",
246 i, name,
247 tables[i].format,
250 }
251 }
252
253#endif
254
255 return FT_Err_Ok;
256
257 Exit:
258 FT_FREE( face->toc.tables );
259 return error;
260 }
261
262
263#define PCF_METRIC_SIZE 12
264
265 static
267 {
268#undef FT_STRUCTURE
269#define FT_STRUCTURE PCF_MetricRec
270
272 FT_FRAME_SHORT_LE( leftSideBearing ),
273 FT_FRAME_SHORT_LE( rightSideBearing ),
274 FT_FRAME_SHORT_LE( characterWidth ),
275 FT_FRAME_SHORT_LE( ascent ),
276 FT_FRAME_SHORT_LE( descent ),
277 FT_FRAME_SHORT_LE( attributes ),
279 };
280
281
282 static
284 {
285#undef FT_STRUCTURE
286#define FT_STRUCTURE PCF_MetricRec
287
289 FT_FRAME_SHORT( leftSideBearing ),
290 FT_FRAME_SHORT( rightSideBearing ),
291 FT_FRAME_SHORT( characterWidth ),
292 FT_FRAME_SHORT( ascent ),
293 FT_FRAME_SHORT( descent ),
294 FT_FRAME_SHORT( attributes ),
296 };
297
298
299#define PCF_COMPRESSED_METRIC_SIZE 5
300
301 static
303 {
304#undef FT_STRUCTURE
305#define FT_STRUCTURE PCF_Compressed_MetricRec
306
308 FT_FRAME_BYTE( leftSideBearing ),
309 FT_FRAME_BYTE( rightSideBearing ),
310 FT_FRAME_BYTE( characterWidth ),
311 FT_FRAME_BYTE( ascent ),
312 FT_FRAME_BYTE( descent ),
314 };
315
316
317 static FT_Error
320 PCF_Metric metric )
321 {
323
324
326 {
327 const FT_Frame_Field* fields;
328
329
330 /* parsing normal metrics */
334
335 /* the following sets `error' but doesn't return in case of failure */
337 }
338 else
339 {
341
342
343 /* parsing compressed metrics */
345 goto Exit;
346
347 metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 );
348 metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 );
349 metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 );
350 metric->ascent = (FT_Short)( compr.ascent - 0x80 );
351 metric->descent = (FT_Short)( compr.descent - 0x80 );
352 metric->attributes = 0;
353 }
354
355 FT_TRACE5(( " width=%d,"
356 " lsb=%d, rsb=%d,"
357 " ascent=%d, descent=%d,"
358 " attributes=%d\n",
359 metric->characterWidth,
360 metric->leftSideBearing,
361 metric->rightSideBearing,
362 metric->ascent,
363 metric->descent,
364 metric->attributes ));
365
366 Exit:
367 return error;
368 }
369
370
371 static FT_Error
374 FT_ULong ntables, /* same as PCF_Toc->count */
376 FT_ULong *aformat,
377 FT_ULong *asize )
378 {
379 FT_Error error = FT_ERR( Invalid_File_Format );
380 FT_ULong i;
381
382
383 for ( i = 0; i < ntables; i++ )
384 if ( tables[i].type == type )
385 {
386 if ( stream->pos > tables[i].offset )
387 {
388 error = FT_THROW( Invalid_Stream_Skip );
389 goto Fail;
390 }
391
392 if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )
393 {
394 error = FT_THROW( Invalid_Stream_Skip );
395 goto Fail;
396 }
397
398 *asize = tables[i].size;
399 *aformat = tables[i].format;
400
401 return FT_Err_Ok;
402 }
403
404 Fail:
405 *asize = 0;
406 return error;
407 }
408
409
410 static FT_Bool
412 FT_ULong ntables, /* same as PCF_Toc->count */
413 FT_ULong type )
414 {
415 FT_ULong i;
416
417
418 for ( i = 0; i < ntables; i++ )
419 if ( tables[i].type == type )
420 return TRUE;
421
422 return FALSE;
423 }
424
425
426#define PCF_PROPERTY_SIZE 9
427
428 static
430 {
431#undef FT_STRUCTURE
432#define FT_STRUCTURE PCF_ParsePropertyRec
433
436 FT_FRAME_BYTE ( isString ),
439 };
440
441
442 static
444 {
445#undef FT_STRUCTURE
446#define FT_STRUCTURE PCF_ParsePropertyRec
447
450 FT_FRAME_BYTE( isString ),
453 };
454
455
458 const FT_String* prop )
459 {
460 PCF_Property properties = face->properties;
461 FT_Bool found = 0;
462 int i;
463
464
465 for ( i = 0; i < face->nprops && !found; i++ )
466 {
467 if ( !ft_strcmp( properties[i].name, prop ) )
468 found = 1;
469 }
470
471 if ( found )
472 return properties + i - 1;
473 else
474 return NULL;
475 }
476
477
478 static FT_Error
480 PCF_Face face )
481 {
483 PCF_Property properties = NULL;
484 FT_ULong nprops, orig_nprops, i;
487 FT_Memory memory = FT_FACE( face )->memory;
488 FT_ULong string_size;
490
491
493 face->toc.tables,
494 face->toc.count,
496 &format,
497 &size );
498 if ( error )
499 goto Bail;
500
501 if ( FT_READ_ULONG_LE( format ) )
502 goto Bail;
503
504 FT_TRACE4(( "pcf_get_properties:\n"
505 " format: 0x%lX (%s)\n",
506 format,
507 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
508
510 goto Bail;
511
512 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
513 (void)FT_READ_ULONG( orig_nprops );
514 else
515 (void)FT_READ_ULONG_LE( orig_nprops );
516 if ( error )
517 goto Bail;
518
519 FT_TRACE4(( " number of properties: %ld\n", orig_nprops ));
520
521 /* rough estimate */
522 if ( orig_nprops > size / PCF_PROPERTY_SIZE )
523 {
524 error = FT_THROW( Invalid_Table );
525 goto Bail;
526 }
527
528 /* as a heuristic limit to avoid excessive allocation in */
529 /* gzip bombs (i.e., very small, invalid input data that */
530 /* pretends to expand to an insanely large file) we only */
531 /* load the first 256 properties */
532 if ( orig_nprops > 256 )
533 {
534 FT_TRACE0(( "pcf_get_properties:"
535 " only loading first 256 properties\n" ));
536 nprops = 256;
537 }
538 else
539 nprops = orig_nprops;
540
541 face->nprops = (int)nprops;
542
543 if ( FT_NEW_ARRAY( props, nprops ) )
544 goto Bail;
545
546 for ( i = 0; i < nprops; i++ )
547 {
548 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
549 {
551 goto Bail;
552 }
553 else
554 {
556 goto Bail;
557 }
558 }
559
560 /* this skip will only work if we really have an extremely large */
561 /* number of properties; it will fail for fake data, avoiding an */
562 /* unnecessarily large allocation later on */
563 if ( FT_STREAM_SKIP( ( orig_nprops - nprops ) * PCF_PROPERTY_SIZE ) )
564 {
565 error = FT_THROW( Invalid_Stream_Skip );
566 goto Bail;
567 }
568
569 /* pad the property array */
570 /* */
571 /* clever here - nprops is the same as the number of odd-units read, */
572 /* as only isStringProp are odd length (Keith Packard) */
573 /* */
574 if ( orig_nprops & 3 )
575 {
576 i = 4 - ( orig_nprops & 3 );
577 if ( FT_STREAM_SKIP( i ) )
578 {
579 error = FT_THROW( Invalid_Stream_Skip );
580 goto Bail;
581 }
582 }
583
584 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
585 (void)FT_READ_ULONG( string_size );
586 else
587 (void)FT_READ_ULONG_LE( string_size );
588 if ( error )
589 goto Bail;
590
591 FT_TRACE4(( " string size: %ld\n", string_size ));
592
593 /* rough estimate */
594 if ( string_size > size - orig_nprops * PCF_PROPERTY_SIZE )
595 {
596 error = FT_THROW( Invalid_Table );
597 goto Bail;
598 }
599
600 /* the strings in the `strings' array are PostScript strings, */
601 /* which can have a maximum length of 65536 characters each */
602 if ( string_size > 16777472 ) /* 256 * (65536 + 1) */
603 {
604 FT_TRACE0(( "pcf_get_properties:"
605 " loading only 16777472 bytes of strings array\n" ));
606 string_size = 16777472;
607 }
608
609 /* allocate one more byte so that we have a final null byte */
610 if ( FT_NEW_ARRAY( strings, string_size + 1 ) )
611 goto Bail;
612
613 error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size );
614 if ( error )
615 goto Bail;
616
617 if ( FT_NEW_ARRAY( properties, nprops ) )
618 goto Bail;
619
620 face->properties = properties;
621
622 FT_TRACE4(( "\n" ));
623 for ( i = 0; i < nprops; i++ )
624 {
625 FT_Long name_offset = props[i].name;
626
627
628 if ( ( name_offset < 0 ) ||
629 ( (FT_ULong)name_offset > string_size ) )
630 {
631 error = FT_THROW( Invalid_Offset );
632 goto Bail;
633 }
634
635 if ( FT_STRDUP( properties[i].name, strings + name_offset ) )
636 goto Bail;
637
638 FT_TRACE4(( " %s:", properties[i].name ));
639
640 properties[i].isString = props[i].isString;
641
642 if ( props[i].isString )
643 {
644 FT_Long value_offset = props[i].value;
645
646
647 if ( ( value_offset < 0 ) ||
648 ( (FT_ULong)value_offset > string_size ) )
649 {
650 error = FT_THROW( Invalid_Offset );
651 goto Bail;
652 }
653
654 if ( FT_STRDUP( properties[i].value.atom, strings + value_offset ) )
655 goto Bail;
656
657 FT_TRACE4(( " `%s'\n", properties[i].value.atom ));
658 }
659 else
660 {
661 properties[i].value.l = props[i].value;
662
663 FT_TRACE4(( " %ld\n", properties[i].value.l ));
664 }
665 }
666
668
669 Bail:
670 FT_FREE( props );
671 FT_FREE( strings );
672
673 return error;
674 }
675
676
677 static FT_Error
679 PCF_Face face )
680 {
682 FT_Memory memory = FT_FACE( face )->memory;
685 FT_ULong nmetrics, orig_nmetrics, i;
686
687
689 face->toc.tables,
690 face->toc.count,
692 &format,
693 &size );
694 if ( error )
695 return error;
696
697 if ( FT_READ_ULONG_LE( format ) )
698 goto Bail;
699
700 FT_TRACE4(( "pcf_get_metrics:\n"
701 " format: 0x%lX (%s, %s)\n",
702 format,
703 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB",
705 "compressed" : "uncompressed" ));
706
709 return FT_THROW( Invalid_File_Format );
710
712 {
713 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
714 (void)FT_READ_ULONG( orig_nmetrics );
715 else
716 (void)FT_READ_ULONG_LE( orig_nmetrics );
717 }
718 else
719 {
720 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
721 (void)FT_READ_USHORT( orig_nmetrics );
722 else
723 (void)FT_READ_USHORT_LE( orig_nmetrics );
724 }
725 if ( error )
726 return FT_THROW( Invalid_File_Format );
727
728 FT_TRACE4(( " number of metrics: %ld\n", orig_nmetrics ));
729
730 /* rough estimate */
732 {
733 if ( orig_nmetrics > size / PCF_METRIC_SIZE )
734 return FT_THROW( Invalid_Table );
735 }
736 else
737 {
738 if ( orig_nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
739 return FT_THROW( Invalid_Table );
740 }
741
742 if ( !orig_nmetrics )
743 return FT_THROW( Invalid_Table );
744
745 /*
746 * PCF is a format from ancient times; Unicode was in its infancy, and
747 * widely used two-byte character sets for CJK scripts (Big 5, GB 2312,
748 * JIS X 0208, etc.) did have at most 15000 characters. Even the more
749 * exotic CNS 11643 and CCCII standards, which were essentially
750 * three-byte character sets, provided less then 65536 assigned
751 * characters.
752 *
753 * While technically possible to have a larger number of glyphs in PCF
754 * files, we thus limit the number to 65535, taking into account that we
755 * synthesize the metrics of glyph 0 to be a copy of the `default
756 * character', and that 0xFFFF in the encodings array indicates a
757 * missing glyph.
758 */
759 if ( orig_nmetrics > 65534 )
760 {
761 FT_TRACE0(( "pcf_get_metrics:"
762 " only loading first 65534 metrics\n" ));
763 nmetrics = 65534;
764 }
765 else
766 nmetrics = orig_nmetrics;
767
768 face->nmetrics = nmetrics + 1;
769
770 if ( FT_NEW_ARRAY( face->metrics, face->nmetrics ) )
771 return error;
772
773 /* we handle glyph index 0 later on */
774 metrics = face->metrics + 1;
775
776 FT_TRACE4(( "\n" ));
777 for ( i = 1; i < face->nmetrics; i++, metrics++ )
778 {
779 FT_TRACE5(( " idx %ld:", i ));
781
782 metrics->bits = 0;
783
784 if ( error )
785 break;
786
787 /* sanity checks -- those values are used in `PCF_Glyph_Load' to */
788 /* compute a glyph's bitmap dimensions, thus setting them to zero in */
789 /* case of an error disables this particular glyph only */
790 if ( metrics->rightSideBearing < metrics->leftSideBearing ||
791 metrics->ascent < -metrics->descent )
792 {
793 metrics->characterWidth = 0;
794 metrics->leftSideBearing = 0;
795 metrics->rightSideBearing = 0;
796 metrics->ascent = 0;
797 metrics->descent = 0;
798
799 FT_TRACE0(( "pcf_get_metrics:"
800 " invalid metrics for glyph %ld\n", i ));
801 }
802 }
803
804 if ( error )
805 FT_FREE( face->metrics );
806
807 Bail:
808 return error;
809 }
810
811
812 static FT_Error
814 PCF_Face face )
815 {
817 FT_ULong bitmapSizes[GLYPHPADOPTIONS];
819 FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
820
821
823 face->toc.tables,
824 face->toc.count,
826 &format,
827 &size );
828 if ( error )
829 return error;
830
832 if ( error )
833 return error;
834
836 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
837 orig_nbitmaps = FT_GET_ULONG();
838 else
839 orig_nbitmaps = FT_GET_ULONG_LE();
840
842
843 FT_TRACE4(( "pcf_get_bitmaps:\n"
844 " format: 0x%lX\n"
845 " (%s, %s,\n"
846 " padding=%d bit%s, scanning=%d bit%s)\n",
847 format,
849 ? "most significant byte first"
850 : "least significant byte first",
852 ? "most significant bit first"
853 : "least significant bit first",
855 ( 8 << PCF_GLYPH_PAD_INDEX( format ) ) == 1 ? "" : "s",
857 ( 8 << PCF_SCAN_UNIT_INDEX( format ) ) == 1 ? "" : "s" ));
858
860 return FT_THROW( Invalid_File_Format );
861
862 FT_TRACE4(( " number of bitmaps: %ld\n", orig_nbitmaps ));
863
864 /* see comment in `pcf_get_metrics' */
865 if ( orig_nbitmaps > 65534 )
866 {
867 FT_TRACE0(( "pcf_get_bitmaps:"
868 " only loading first 65534 bitmaps\n" ));
869 nbitmaps = 65534;
870 }
871 else
872 nbitmaps = orig_nbitmaps;
873
874 /* no extra bitmap for glyph 0 */
875 if ( nbitmaps != face->nmetrics - 1 )
876 return FT_THROW( Invalid_File_Format );
877
878 /* start position of bitmap data */
879 pos = stream->pos + nbitmaps * 4 + 4 * 4;
880
881 FT_TRACE5(( "\n" ));
882 for ( i = 1; i <= nbitmaps; i++ )
883 {
885
886
887 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
889 else
890 (void)FT_READ_ULONG_LE( offset );
891
892 FT_TRACE5(( " bitmap %lu: offset %lu (0x%lX)\n",
893 i, offset, offset ));
894
895 /* right now, we only check the offset with a rough estimate; */
896 /* actual bitmaps are only loaded on demand */
897 if ( offset > size )
898 {
899 FT_TRACE0(( "pcf_get_bitmaps:"
900 " invalid offset to bitmap data of glyph %lu\n", i ));
901 face->metrics[i].bits = pos;
902 }
903 else
904 face->metrics[i].bits = pos + offset;
905 }
906 if ( error )
907 goto Bail;
908
909 for ( i = 0; i < GLYPHPADOPTIONS; i++ )
910 {
911 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
912 (void)FT_READ_ULONG( bitmapSizes[i] );
913 else
914 (void)FT_READ_ULONG_LE( bitmapSizes[i] );
915 if ( error )
916 goto Bail;
917
918 sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
919
920 FT_TRACE4(( " %d-bit padding implies a size of %lu\n",
921 8 << i, bitmapSizes[i] ));
922 }
923
924 FT_TRACE4(( " %lu bitmaps, using %d-bit padding\n",
925 nbitmaps,
926 8 << PCF_GLYPH_PAD_INDEX( format ) ));
927 FT_TRACE4(( " bitmap size: %lu\n", sizebitmaps ));
928
929 FT_UNUSED( sizebitmaps ); /* only used for debugging */
930
931 face->bitmapsFormat = format;
932
933 Bail:
934 return error;
935 }
936
937
938 /*
939 * This file uses X11 terminology for PCF data; an `encoding' in X11 speak
940 * is the same as a character code in FreeType speak.
941 */
942#define PCF_ENC_SIZE 10
943
944 static
946 {
947#undef FT_STRUCTURE
948#define FT_STRUCTURE PCF_EncRec
949
951 FT_FRAME_USHORT_LE( firstCol ),
952 FT_FRAME_USHORT_LE( lastCol ),
953 FT_FRAME_USHORT_LE( firstRow ),
954 FT_FRAME_USHORT_LE( lastRow ),
955 FT_FRAME_USHORT_LE( defaultChar ),
957 };
958
959
960 static
962 {
963#undef FT_STRUCTURE
964#define FT_STRUCTURE PCF_EncRec
965
967 FT_FRAME_USHORT( firstCol ),
968 FT_FRAME_USHORT( lastCol ),
969 FT_FRAME_USHORT( firstRow ),
970 FT_FRAME_USHORT( lastRow ),
971 FT_FRAME_USHORT( defaultChar ),
973 };
974
975
976 static FT_Error
978 PCF_Face face )
979 {
981 FT_Memory memory = FT_FACE( face )->memory;
983 PCF_Enc enc = &face->enc;
984 FT_ULong nencoding;
986 FT_UShort defaultCharRow, defaultCharCol;
987 FT_UShort encodingOffset, defaultCharEncodingOffset;
988 FT_UShort i, j;
989 FT_Byte* pos;
990
991
993 face->toc.tables,
994 face->toc.count,
996 &format,
997 &size );
998 if ( error )
999 goto Bail;
1000
1001 if ( FT_READ_ULONG_LE( format ) )
1002 goto Bail;
1003
1004 FT_TRACE4(( "pcf_get_encodings:\n"
1005 " format: 0x%lX (%s)\n",
1006 format,
1007 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
1008
1011 return FT_THROW( Invalid_File_Format );
1012
1013 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
1014 {
1016 goto Bail;
1017 }
1018 else
1019 {
1021 goto Bail;
1022 }
1023
1024 FT_TRACE4(( " firstCol 0x%X, lastCol 0x%X\n"
1025 " firstRow 0x%X, lastRow 0x%X\n"
1026 " defaultChar 0x%X\n",
1027 enc->firstCol, enc->lastCol,
1028 enc->firstRow, enc->lastRow,
1029 enc->defaultChar ));
1030
1031 /* sanity checks; we limit numbers of rows and columns to 256 */
1032 if ( enc->firstCol > enc->lastCol ||
1033 enc->lastCol > 0xFF ||
1034 enc->firstRow > enc->lastRow ||
1035 enc->lastRow > 0xFF )
1036 return FT_THROW( Invalid_Table );
1037
1038 nencoding = (FT_ULong)( enc->lastCol - enc->firstCol + 1 ) *
1039 (FT_ULong)( enc->lastRow - enc->firstRow + 1 );
1040
1041 if ( FT_NEW_ARRAY( enc->offset, nencoding ) )
1042 goto Bail;
1043
1044 error = FT_Stream_EnterFrame( stream, 2 * nencoding );
1045 if ( error )
1046 goto Exit;
1047
1048 FT_TRACE5(( "\n" ));
1049
1050 defaultCharRow = enc->defaultChar >> 8;
1051 defaultCharCol = enc->defaultChar & 0xFF;
1052
1053 /* validate default character */
1054 if ( defaultCharRow < enc->firstRow ||
1055 defaultCharRow > enc->lastRow ||
1056 defaultCharCol < enc->firstCol ||
1057 defaultCharCol > enc->lastCol )
1058 {
1059 enc->defaultChar = enc->firstRow * 256U + enc->firstCol;
1060 FT_TRACE0(( "pcf_get_encodings:"
1061 " Invalid default character set to %u\n",
1062 enc->defaultChar ));
1063
1064 defaultCharRow = enc->firstRow;
1065 defaultCharCol = enc->firstCol;
1066 }
1067
1068 /*
1069 * FreeType mandates that glyph index 0 is the `undefined glyph', which
1070 * PCF calls the `default character'. However, FreeType needs glyph
1071 * index 0 to be used for the undefined glyph only, which is is not the
1072 * case for PCF. For this reason, we add one slot for glyph index 0 and
1073 * simply copy the default character to it.
1074 *
1075 * `stream->cursor' still points to the beginning of the frame; we can
1076 * thus easily get the offset to the default character.
1077 */
1078 pos = stream->cursor +
1079 2 * ( ( defaultCharRow - enc->firstRow ) *
1080 ( enc->lastCol - enc->firstCol + 1 ) +
1081 defaultCharCol - enc->firstCol );
1082
1083 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
1084 defaultCharEncodingOffset = FT_PEEK_USHORT( pos );
1085 else
1086 defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos );
1087
1088 if ( defaultCharEncodingOffset == 0xFFFF )
1089 {
1090 FT_TRACE0(( "pcf_get_encodings:"
1091 " No glyph for default character,\n"
1092 " "
1093 " setting it to the first glyph of the font\n" ));
1094 defaultCharEncodingOffset = 1;
1095 }
1096 else
1097 {
1098 defaultCharEncodingOffset++;
1099
1100 if ( defaultCharEncodingOffset >= face->nmetrics )
1101 {
1102 FT_TRACE0(( "pcf_get_encodings:"
1103 " Invalid glyph index for default character,\n"
1104 " "
1105 " setting it to the first glyph of the font\n" ));
1106 defaultCharEncodingOffset = 1;
1107 }
1108 }
1109
1110 /* copy metrics of default character to index 0 */
1111 face->metrics[0] = face->metrics[defaultCharEncodingOffset];
1112
1113 /* now loop over all values */
1114 offset = enc->offset;
1115 for ( i = enc->firstRow; i <= enc->lastRow; i++ )
1116 {
1117 for ( j = enc->firstCol; j <= enc->lastCol; j++ )
1118 {
1119 /* X11's reference implementation uses the equivalent to */
1120 /* `FT_GET_SHORT', however PCF fonts with more than 32768 */
1121 /* characters (e.g., `unifont.pcf') clearly show that an */
1122 /* unsigned value is needed. */
1123 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
1124 encodingOffset = FT_GET_USHORT();
1125 else
1126 encodingOffset = FT_GET_USHORT_LE();
1127
1128 /* everything is off by 1 due to the artificial glyph 0 */
1129 *offset++ = encodingOffset == 0xFFFF ? 0xFFFF
1130 : encodingOffset + 1;
1131 }
1132 }
1134
1135 return error;
1136
1137 Exit:
1138 FT_FREE( enc->offset );
1139
1140 Bail:
1141 return error;
1142 }
1143
1144
1145 static
1147 {
1148#undef FT_STRUCTURE
1149#define FT_STRUCTURE PCF_AccelRec
1150
1151 FT_FRAME_START( 20 ),
1152 FT_FRAME_BYTE ( noOverlap ),
1153 FT_FRAME_BYTE ( constantMetrics ),
1154 FT_FRAME_BYTE ( terminalFont ),
1155 FT_FRAME_BYTE ( constantWidth ),
1156 FT_FRAME_BYTE ( inkInside ),
1157 FT_FRAME_BYTE ( inkMetrics ),
1158 FT_FRAME_BYTE ( drawDirection ),
1160 FT_FRAME_LONG_LE ( fontAscent ),
1161 FT_FRAME_LONG_LE ( fontDescent ),
1162 FT_FRAME_LONG_LE ( maxOverlap ),
1164 };
1165
1166
1167 static
1169 {
1170#undef FT_STRUCTURE
1171#define FT_STRUCTURE PCF_AccelRec
1172
1173 FT_FRAME_START( 20 ),
1174 FT_FRAME_BYTE ( noOverlap ),
1175 FT_FRAME_BYTE ( constantMetrics ),
1176 FT_FRAME_BYTE ( terminalFont ),
1177 FT_FRAME_BYTE ( constantWidth ),
1178 FT_FRAME_BYTE ( inkInside ),
1179 FT_FRAME_BYTE ( inkMetrics ),
1180 FT_FRAME_BYTE ( drawDirection ),
1182 FT_FRAME_LONG ( fontAscent ),
1183 FT_FRAME_LONG ( fontDescent ),
1184 FT_FRAME_LONG ( maxOverlap ),
1186 };
1187
1188
1189 static FT_Error
1191 PCF_Face face,
1192 FT_ULong type )
1193 {
1196 PCF_Accel accel = &face->accel;
1197
1198
1200 face->toc.tables,
1201 face->toc.count,
1202 type,
1203 &format,
1204 &size );
1205 if ( error )
1206 goto Bail;
1207
1208 if ( FT_READ_ULONG_LE( format ) )
1209 goto Bail;
1210
1211 FT_TRACE4(( "pcf_get_accel%s:\n"
1212 " format: 0x%lX (%s, %s)\n",
1213 type == PCF_BDF_ACCELERATORS ? " (getting BDF accelerators)"
1214 : "",
1215 format,
1216 PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB",
1218 "accelerated" : "not accelerated" ));
1219
1222 goto Bail;
1223
1224 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
1225 {
1227 goto Bail;
1228 }
1229 else
1230 {
1232 goto Bail;
1233 }
1234
1235 FT_TRACE5(( " noOverlap=%s, constantMetrics=%s,"
1236 " terminalFont=%s, constantWidth=%s\n"
1237 " inkInside=%s, inkMetrics=%s, drawDirection=%s\n"
1238 " fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n",
1239 accel->noOverlap ? "yes" : "no",
1240 accel->constantMetrics ? "yes" : "no",
1241 accel->terminalFont ? "yes" : "no",
1242 accel->constantWidth ? "yes" : "no",
1243 accel->inkInside ? "yes" : "no",
1244 accel->inkMetrics ? "yes" : "no",
1245 accel->drawDirection ? "RTL" : "LTR",
1246 accel->fontAscent,
1247 accel->fontDescent,
1248 accel->maxOverlap ));
1249
1250 /* sanity checks */
1251 if ( FT_ABS( accel->fontAscent ) > 0x7FFF )
1252 {
1253 accel->fontAscent = accel->fontAscent < 0 ? -0x7FFF : 0x7FFF;
1254 FT_TRACE0(( "pfc_get_accel: clamping font ascent to value %ld\n",
1255 accel->fontAscent ));
1256 }
1257 if ( FT_ABS( accel->fontDescent ) > 0x7FFF )
1258 {
1259 accel->fontDescent = accel->fontDescent < 0 ? -0x7FFF : 0x7FFF;
1260 FT_TRACE0(( "pfc_get_accel: clamping font descent to value %ld\n",
1261 accel->fontDescent ));
1262 }
1263
1264 FT_TRACE5(( " minbounds:" ));
1266 format & ( ~PCF_FORMAT_MASK ),
1267 &(accel->minbounds) );
1268 if ( error )
1269 goto Bail;
1270
1271 FT_TRACE5(( " maxbounds:" ));
1273 format & ( ~PCF_FORMAT_MASK ),
1274 &(accel->maxbounds) );
1275 if ( error )
1276 goto Bail;
1277
1279 {
1280 FT_TRACE5(( " ink minbounds:" ));
1282 format & ( ~PCF_FORMAT_MASK ),
1283 &(accel->ink_minbounds) );
1284 if ( error )
1285 goto Bail;
1286
1287 FT_TRACE5(( " ink maxbounds:" ));
1289 format & ( ~PCF_FORMAT_MASK ),
1290 &(accel->ink_maxbounds) );
1291 if ( error )
1292 goto Bail;
1293 }
1294 else
1295 {
1296 accel->ink_minbounds = accel->minbounds;
1297 accel->ink_maxbounds = accel->maxbounds;
1298 }
1299
1300 Bail:
1301 return error;
1302 }
1303
1304
1305 static FT_Error
1307 {
1309 FT_Face face = FT_FACE( pcf );
1310 FT_Memory memory = face->memory;
1311
1312 PCF_Property prop;
1313
1314 const char* strings[4] = { NULL, NULL, NULL, NULL };
1315 size_t lengths[4], nn, len;
1316
1317
1318 face->style_flags = 0;
1319
1320 prop = pcf_find_property( pcf, "SLANT" );
1321 if ( prop && prop->isString &&
1322 ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
1323 *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )
1324 {
1325 face->style_flags |= FT_STYLE_FLAG_ITALIC;
1326 strings[2] = ( *(prop->value.atom) == 'O' ||
1327 *(prop->value.atom) == 'o' ) ? "Oblique"
1328 : "Italic";
1329 }
1330
1331 prop = pcf_find_property( pcf, "WEIGHT_NAME" );
1332 if ( prop && prop->isString &&
1333 ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
1334 {
1335 face->style_flags |= FT_STYLE_FLAG_BOLD;
1336 strings[1] = "Bold";
1337 }
1338
1339 prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
1340 if ( prop && prop->isString &&
1341 *(prop->value.atom) &&
1342 !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
1343 strings[3] = (const char*)( prop->value.atom );
1344
1345 prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
1346 if ( prop && prop->isString &&
1347 *(prop->value.atom) &&
1348 !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
1349 strings[0] = (const char*)( prop->value.atom );
1350
1351 for ( len = 0, nn = 0; nn < 4; nn++ )
1352 {
1353 lengths[nn] = 0;
1354 if ( strings[nn] )
1355 {
1356 lengths[nn] = ft_strlen( strings[nn] );
1357 len += lengths[nn] + 1;
1358 }
1359 }
1360
1361 if ( len == 0 )
1362 {
1363 strings[0] = "Regular";
1364 lengths[0] = ft_strlen( strings[0] );
1365 len = lengths[0] + 1;
1366 }
1367
1368 {
1369 char* s;
1370
1371
1372 if ( FT_ALLOC( face->style_name, len ) )
1373 return error;
1374
1375 s = face->style_name;
1376
1377 for ( nn = 0; nn < 4; nn++ )
1378 {
1379 const char* src = strings[nn];
1380
1381
1382 len = lengths[nn];
1383
1384 if ( !src )
1385 continue;
1386
1387 /* separate elements with a space */
1388 if ( s != face->style_name )
1389 *s++ = ' ';
1390
1391 ft_memcpy( s, src, len );
1392
1393 /* need to convert spaces to dashes for */
1394 /* add_style_name and setwidth_name */
1395 if ( nn == 0 || nn == 3 )
1396 {
1397 size_t mm;
1398
1399
1400 for ( mm = 0; mm < len; mm++ )
1401 if ( s[mm] == ' ' )
1402 s[mm] = '-';
1403 }
1404
1405 s += len;
1406 }
1407 *s = 0;
1408 }
1409
1410 return error;
1411 }
1412
1413
1416 PCF_Face face,
1417 FT_Long face_index )
1418 {
1419 FT_Face root = FT_FACE( face );
1421 FT_Memory memory = FT_FACE( face )->memory;
1422 FT_Bool hasBDFAccelerators;
1423
1424
1426 if ( error )
1427 goto Exit;
1428
1429 root->num_faces = 1;
1430 root->face_index = 0;
1431
1432 /* If we are performing a simple font format check, exit immediately. */
1433 if ( face_index < 0 )
1434 return FT_Err_Ok;
1435
1437 if ( error )
1438 goto Exit;
1439
1440 /* Use the old accelerators if no BDF accelerators are in the file. */
1441 hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
1442 face->toc.count,
1444 if ( !hasBDFAccelerators )
1445 {
1447 if ( error )
1448 goto Exit;
1449 }
1450
1451 /* metrics */
1453 if ( error )
1454 goto Exit;
1455
1456 /* bitmaps */
1458 if ( error )
1459 goto Exit;
1460
1461 /* encodings */
1463 if ( error )
1464 goto Exit;
1465
1466 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
1467 if ( hasBDFAccelerators )
1468 {
1470 if ( error )
1471 goto Exit;
1472 }
1473
1474 /* XXX: TO DO: inkmetrics and glyph_names are missing */
1475
1476 /* now construct the face object */
1477 {
1478 PCF_Property prop;
1479
1480
1481 root->face_flags |= FT_FACE_FLAG_FIXED_SIZES |
1483
1484 if ( face->accel.constantWidth )
1485 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
1486
1488 goto Exit;
1489
1490 prop = pcf_find_property( face, "FAMILY_NAME" );
1491 if ( prop && prop->isString )
1492 {
1493
1494#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
1495
1497
1498
1499 if ( !driver->no_long_family_names )
1500 {
1501 /* Prepend the foundry name plus a space to the family name. */
1502 /* There are many fonts just called `Fixed' which look */
1503 /* completely different, and which have nothing to do with each */
1504 /* other. When selecting `Fixed' in KDE or Gnome one gets */
1505 /* results that appear rather random, the style changes often if */
1506 /* one changes the size and one cannot select some fonts at all. */
1507 /* */
1508 /* We also check whether we have `wide' characters; all put */
1509 /* together, we get family names like `Sony Fixed' or `Misc */
1510 /* Fixed Wide'. */
1511
1512 PCF_Property foundry_prop, point_size_prop, average_width_prop;
1513
1514 int l = ft_strlen( prop->value.atom ) + 1;
1515 int wide = 0;
1516
1517
1518 foundry_prop = pcf_find_property( face, "FOUNDRY" );
1519 point_size_prop = pcf_find_property( face, "POINT_SIZE" );
1520 average_width_prop = pcf_find_property( face, "AVERAGE_WIDTH" );
1521
1522 if ( point_size_prop && average_width_prop )
1523 {
1524 if ( average_width_prop->value.l >= point_size_prop->value.l )
1525 {
1526 /* This font is at least square shaped or even wider */
1527 wide = 1;
1528 l += ft_strlen( " Wide" );
1529 }
1530 }
1531
1532 if ( foundry_prop && foundry_prop->isString )
1533 {
1534 l += ft_strlen( foundry_prop->value.atom ) + 1;
1535
1536 if ( FT_NEW_ARRAY( root->family_name, l ) )
1537 goto Exit;
1538
1539 ft_strcpy( root->family_name, foundry_prop->value.atom );
1540 ft_strcat( root->family_name, " " );
1541 ft_strcat( root->family_name, prop->value.atom );
1542 }
1543 else
1544 {
1545 if ( FT_NEW_ARRAY( root->family_name, l ) )
1546 goto Exit;
1547
1548 ft_strcpy( root->family_name, prop->value.atom );
1549 }
1550
1551 if ( wide )
1552 ft_strcat( root->family_name, " Wide" );
1553 }
1554 else
1555
1556#endif /* PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
1557
1558 {
1559 if ( FT_STRDUP( root->family_name, prop->value.atom ) )
1560 goto Exit;
1561 }
1562 }
1563 else
1564 root->family_name = NULL;
1565
1566 root->num_glyphs = (FT_Long)face->nmetrics;
1567
1568 root->num_fixed_sizes = 1;
1569 if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
1570 goto Exit;
1571
1572 {
1573 FT_Bitmap_Size* bsize = root->available_sizes;
1574 FT_Short resolution_x = 0, resolution_y = 0;
1575
1576
1577 FT_ZERO( bsize );
1578
1579 /* for simplicity, we take absolute values of integer properties */
1580
1581#if 0
1582 bsize->height = face->accel.maxbounds.ascent << 6;
1583#endif
1584
1585#ifdef FT_DEBUG_LEVEL_TRACE
1586 if ( face->accel.fontAscent + face->accel.fontDescent < 0 )
1587 FT_TRACE0(( "pcf_load_font: negative height\n" ));
1588#endif
1589 if ( FT_ABS( face->accel.fontAscent +
1590 face->accel.fontDescent ) > 0x7FFF )
1591 {
1592 bsize->height = 0x7FFF;
1593 FT_TRACE0(( "pcf_load_font: clamping height to value %d\n",
1594 bsize->height ));
1595 }
1596 else
1597 bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent +
1598 face->accel.fontDescent ) );
1599
1600 prop = pcf_find_property( face, "AVERAGE_WIDTH" );
1601 if ( prop )
1602 {
1603#ifdef FT_DEBUG_LEVEL_TRACE
1604 if ( prop->value.l < 0 )
1605 FT_TRACE0(( "pcf_load_font: negative average width\n" ));
1606#endif
1607 if ( ( FT_ABS( prop->value.l ) > 0x7FFFL * 10 - 5 ) )
1608 {
1609 bsize->width = 0x7FFF;
1610 FT_TRACE0(( "pcf_load_font: clamping average width to value %d\n",
1611 bsize->width ));
1612 }
1613 else
1614 bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) );
1615 }
1616 else
1617 {
1618 /* this is a heuristical value */
1619 bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 );
1620 }
1621
1622 prop = pcf_find_property( face, "POINT_SIZE" );
1623 if ( prop )
1624 {
1625#ifdef FT_DEBUG_LEVEL_TRACE
1626 if ( prop->value.l < 0 )
1627 FT_TRACE0(( "pcf_load_font: negative point size\n" ));
1628#endif
1629 /* convert from 722.7 decipoints to 72 points per inch */
1630 if ( FT_ABS( prop->value.l ) > 0x504C2L ) /* 0x7FFF * 72270/7200 */
1631 {
1632 bsize->size = 0x7FFF;
1633 FT_TRACE0(( "pcf_load_font: clamping point size to value %ld\n",
1634 bsize->size ));
1635 }
1636 else
1637 bsize->size = FT_MulDiv( FT_ABS( prop->value.l ),
1638 64 * 7200,
1639 72270L );
1640 }
1641
1642 prop = pcf_find_property( face, "PIXEL_SIZE" );
1643 if ( prop )
1644 {
1645#ifdef FT_DEBUG_LEVEL_TRACE
1646 if ( prop->value.l < 0 )
1647 FT_TRACE0(( "pcf_load_font: negative pixel size\n" ));
1648#endif
1649 if ( FT_ABS( prop->value.l ) > 0x7FFF )
1650 {
1651 bsize->y_ppem = 0x7FFF << 6;
1652 FT_TRACE0(( "pcf_load_font: clamping pixel size to value %ld\n",
1653 bsize->y_ppem ));
1654 }
1655 else
1656 bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6;
1657 }
1658
1659 prop = pcf_find_property( face, "RESOLUTION_X" );
1660 if ( prop )
1661 {
1662#ifdef FT_DEBUG_LEVEL_TRACE
1663 if ( prop->value.l < 0 )
1664 FT_TRACE0(( "pcf_load_font: negative X resolution\n" ));
1665#endif
1666 if ( FT_ABS( prop->value.l ) > 0x7FFF )
1667 {
1668 resolution_x = 0x7FFF;
1669 FT_TRACE0(( "pcf_load_font: clamping X resolution to value %d\n",
1670 resolution_x ));
1671 }
1672 else
1673 resolution_x = FT_ABS( (FT_Short)prop->value.l );
1674 }
1675
1676 prop = pcf_find_property( face, "RESOLUTION_Y" );
1677 if ( prop )
1678 {
1679#ifdef FT_DEBUG_LEVEL_TRACE
1680 if ( prop->value.l < 0 )
1681 FT_TRACE0(( "pcf_load_font: negative Y resolution\n" ));
1682#endif
1683 if ( FT_ABS( prop->value.l ) > 0x7FFF )
1684 {
1685 resolution_y = 0x7FFF;
1686 FT_TRACE0(( "pcf_load_font: clamping Y resolution to value %d\n",
1687 resolution_y ));
1688 }
1689 else
1690 resolution_y = FT_ABS( (FT_Short)prop->value.l );
1691 }
1692
1693 if ( bsize->y_ppem == 0 )
1694 {
1695 bsize->y_ppem = bsize->size;
1696 if ( resolution_y )
1697 bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 );
1698 }
1699 if ( resolution_x && resolution_y )
1700 bsize->x_ppem = FT_MulDiv( bsize->y_ppem,
1701 resolution_x,
1702 resolution_y );
1703 else
1704 bsize->x_ppem = bsize->y_ppem;
1705 }
1706
1707 /* set up charset */
1708 {
1709 PCF_Property charset_registry, charset_encoding;
1710
1711
1712 charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
1713 charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );
1714
1715 if ( charset_registry && charset_registry->isString &&
1716 charset_encoding && charset_encoding->isString )
1717 {
1718 if ( FT_STRDUP( face->charset_encoding,
1719 charset_encoding->value.atom ) ||
1720 FT_STRDUP( face->charset_registry,
1721 charset_registry->value.atom ) )
1722 goto Exit;
1723 }
1724 }
1725 }
1726
1727 Exit:
1728 if ( error )
1729 {
1730 /* This is done to respect the behaviour of the original */
1731 /* PCF font driver. */
1732 error = FT_THROW( Invalid_File_Format );
1733 }
1734
1735 return error;
1736 }
1737
1738
1739/* END */
r l[0]
Definition: byte_order.h:168
#define FT_LOCAL_DEF(x)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR version[]
Definition: asmname.c:66
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
struct nls_table * tables
Definition: nls_base.c:22
int Fail
Definition: ehthrow.cxx:24
#define FT_STYLE_FLAG_ITALIC
Definition: freetype.h:1475
#define FT_FACE_FLAG_FIXED_SIZES
Definition: freetype.h:1198
#define FT_FACE_FLAG_FIXED_WIDTH
Definition: freetype.h:1199
#define FT_STYLE_FLAG_BOLD
Definition: freetype.h:1476
#define FT_FACE_FLAG_HORIZONTAL
Definition: freetype.h:1201
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:415
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_TRACE0(varformat)
Definition: ftdebug.h:187
#define FT_TRACE5(varformat)
Definition: ftdebug.h:192
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:341
#define FT_STRDUP(dst, str)
Definition: ftmemory.h:372
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:43
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:311
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_ZERO(p)
Definition: ftmemory.h:246
#define FT_FACE(x)
Definition: ftobjs.h:597
#define FT_ABS(a)
Definition: ftobjs.h:73
#define FT_MIN(a, b)
Definition: ftobjs.h:70
#define FT_FACE_DRIVER(x)
Definition: ftobjs.h:601
#define ft_memcpy
Definition: ftstdlib.h:82
#define ft_strcmp
Definition: ftstdlib.h:86
#define ft_strcat
Definition: ftstdlib.h:85
#define ft_strlen
Definition: ftstdlib.h:88
#define ft_strcpy
Definition: ftstdlib.h:87
#define FT_GET_ULONG_LE()
Definition: ftstream.h:321
#define FT_READ_USHORT(var)
Definition: ftstream.h:339
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_GET_ULONG()
Definition: ftstream.h:315
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:525
#define FT_READ_ULONG(var)
Definition: ftstream.h:343
#define FT_FRAME_SHORT(f)
Definition: ftstream.h:122
#define FT_GET_USHORT_LE()
Definition: ftstream.h:319
#define FT_FRAME_BYTE(f)
Definition: ftstream.h:126
FT_Stream_EnterFrame(FT_Stream stream, FT_ULong count)
Definition: ftstream.c:234
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:186
FT_Stream_ExitFrame(FT_Stream stream)
Definition: ftstream.c:317
#define FT_FRAME_SHORT_LE(f)
Definition: ftstream.h:131
#define FT_PEEK_USHORT_LE(p)
Definition: ftstream.h:210
#define FT_FRAME_SKIP_BYTES(count)
Definition: ftstream.h:147
#define FT_FRAME_USHORT_LE(f)
Definition: ftstream.h:132
#define FT_FRAME_ULONG_LE(f)
Definition: ftstream.h:130
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:544
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:529
FT_Stream_Read(FT_Stream stream, FT_Byte *buffer, FT_ULong count)
Definition: ftstream.c:109
#define FT_FRAME_LONG_LE(f)
Definition: ftstream.h:129
#define FT_READ_USHORT_LE(var)
Definition: ftstream.h:346
#define FT_READ_ULONG_LE(var)
Definition: ftstream.h:348
#define FT_FRAME_START(size)
Definition: ftstream.h:117
#define FT_FRAME_USHORT(f)
Definition: ftstream.h:123
#define FT_FRAME_LONG(f)
Definition: ftstream.h:120
#define FT_GET_USHORT()
Definition: ftstream.h:311
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
signed long FT_Long
Definition: fttypes.h:242
#define FT_ERR(e)
Definition: fttypes.h:599
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
Definition: glext.h:7753
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:122
const char * fields[10]
Definition: parser.c:313
struct @1789::@1790 driver
#define PCF_ACCEL_W_INKBOUNDS
Definition: pcf.h:191
FT_BEGIN_HEADER struct PCF_TableRec_ PCF_TableRec
#define GLYPHPADOPTIONS
Definition: pcf.h:239
struct PCF_DriverRec_ * PCF_Driver
#define PCF_BITMAPS
Definition: pcf.h:232
#define PCF_FORMAT_MATCH(a, b)
Definition: pcf.h:194
FT_BEGIN_HEADER struct PCF_TableRec_ * PCF_Table
#define PCF_PROPERTIES
Definition: pcf.h:229
#define PCF_GLYPH_PAD_INDEX(f)
Definition: pcf.h:206
#define PCF_FILE_VERSION
Definition: pcf.h:184
#define PCF_ACCELERATORS
Definition: pcf.h:230
#define PCF_DEFAULT_FORMAT
Definition: pcf.h:189
#define PCF_BYTE_ORDER(f)
Definition: pcf.h:202
#define PCF_COMPRESSED_METRICS
Definition: pcf.h:192
#define PCF_FORMAT_MASK
Definition: pcf.h:187
#define PCF_BDF_ACCELERATORS
Definition: pcf.h:237
#define PCF_SCAN_UNIT_INDEX(f)
Definition: pcf.h:210
#define PCF_BDF_ENCODINGS
Definition: pcf.h:234
#define PCF_METRICS
Definition: pcf.h:231
#define MSBFirst
Definition: pcf.h:182
#define PCF_BIT_ORDER(f)
Definition: pcf.h:204
pcf_load_font(FT_Stream stream, PCF_Face face, FT_Long face_index)
Definition: pcfread.c:1415
static FT_Error pcf_get_properties(FT_Stream stream, PCF_Face face)
Definition: pcfread.c:479
static const FT_Frame_Field pcf_property_header[]
Definition: pcfread.c:429
static FT_Error pcf_get_encodings(FT_Stream stream, PCF_Face face)
Definition: pcfread.c:977
static const FT_Frame_Field pcf_enc_msb_header[]
Definition: pcfread.c:961
static const FT_Frame_Field pcf_accel_msb_header[]
Definition: pcfread.c:1168
static const FT_Frame_Field pcf_table_header[]
Definition: pcfread.c:79
#define PCF_METRIC_SIZE
Definition: pcfread.c:263
static const FT_Frame_Field pcf_property_msb_header[]
Definition: pcfread.c:443
#define PCF_COMPRESSED_METRIC_SIZE
Definition: pcfread.c:299
static FT_Bool pcf_has_table_type(PCF_Table tables, FT_ULong ntables, FT_ULong type)
Definition: pcfread.c:411
static FT_Error pcf_get_bitmaps(FT_Stream stream, PCF_Face face)
Definition: pcfread.c:813
static FT_Error pcf_get_metric(FT_Stream stream, FT_ULong format, PCF_Metric metric)
Definition: pcfread.c:318
#define PCF_ENC_SIZE
Definition: pcfread.c:942
static const FT_Frame_Field pcf_toc_header[]
Definition: pcfread.c:66
pcf_find_property(PCF_Face face, const FT_String *prop)
Definition: pcfread.c:457
static FT_Error pcf_seek_to_table_type(FT_Stream stream, PCF_Table tables, FT_ULong ntables, FT_ULong type, FT_ULong *aformat, FT_ULong *asize)
Definition: pcfread.c:372
static FT_Error pcf_get_accel(FT_Stream stream, PCF_Face face, FT_ULong type)
Definition: pcfread.c:1190
static FT_Error pcf_interpret_style(PCF_Face pcf)
Definition: pcfread.c:1306
static FT_Error pcf_read_TOC(FT_Stream stream, PCF_Face face)
Definition: pcfread.c:94
#define PCF_PROPERTY_SIZE
Definition: pcfread.c:426
static const FT_Frame_Field pcf_metric_msb_header[]
Definition: pcfread.c:283
static const FT_Frame_Field pcf_accel_header[]
Definition: pcfread.c:1146
static const FT_Frame_Field pcf_enc_header[]
Definition: pcfread.c:945
static const FT_Frame_Field pcf_metric_header[]
Definition: pcfread.c:266
static const FT_Frame_Field pcf_compressed_metric_header[]
Definition: pcfread.c:302
static FT_Error pcf_get_metrics(FT_Stream stream, PCF_Face face)
Definition: pcfread.c:678
#define FT_UNUSED(arg)
static void Exit(void)
Definition: sock.c:1330
FT_Pos y_ppem
Definition: freetype.h:363
FT_Pos x_ppem
Definition: freetype.h:362
FT_Short width
Definition: freetype.h:358
FT_Short height
Definition: freetype.h:357
FT_Byte constantMetrics
Definition: pcf.h:123
FT_Byte drawDirection
Definition: pcf.h:128
FT_Long fontDescent
Definition: pcf.h:130
FT_Long fontAscent
Definition: pcf.h:129
PCF_MetricRec minbounds
Definition: pcf.h:132
FT_Byte constantWidth
Definition: pcf.h:125
PCF_MetricRec ink_minbounds
Definition: pcf.h:134
FT_Byte inkMetrics
Definition: pcf.h:127
PCF_MetricRec ink_maxbounds
Definition: pcf.h:135
FT_Byte noOverlap
Definition: pcf.h:122
PCF_MetricRec maxbounds
Definition: pcf.h:133
FT_Byte inkInside
Definition: pcf.h:126
FT_Byte terminalFont
Definition: pcf.h:124
FT_Long maxOverlap
Definition: pcf.h:131
FT_UShort * offset
Definition: pcf.h:115
FT_UShort firstCol
Definition: pcf.h:109
FT_UShort firstRow
Definition: pcf.h:111
FT_UShort lastRow
Definition: pcf.h:112
FT_UShort lastCol
Definition: pcf.h:110
FT_UShort defaultChar
Definition: pcf.h:113
FT_Short attributes
Definition: pcf.h:100
FT_Short characterWidth
Definition: pcf.h:97
FT_Short leftSideBearing
Definition: pcf.h:95
FT_Short ascent
Definition: pcf.h:98
FT_Short rightSideBearing
Definition: pcf.h:96
FT_Short descent
Definition: pcf.h:99
FT_String * atom
Definition: pcf.h:73
FT_Long l
Definition: pcf.h:74
FT_Byte isString
Definition: pcf.h:69
union PCF_PropertyRec_::@4541 value
FT_ULong version
Definition: pcf.h:50
FT_ULong count
Definition: pcf.h:51
Definition: format.c:58
Definition: name.c:39
Definition: parse.h:23
ULARGE_INTEGER pos
Definition: request.c:4380
unsigned int size
Definition: parse.h:27
Definition: pdh_main.c:96
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641
static const WCHAR props[]
Definition: wbemdisp.c:288
#define const
Definition: zconf.h:233