Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
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, 2013 by
6  Francesco Zappa Nardelli
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 */
26 
27 
28 #include <ft2build.h>
29 
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
32 #include FT_INTERNAL_OBJECTS_H
33 
34 #include "pcf.h"
35 #include "pcfread.h"
36 
37 #include "pcferror.h"
38 
39 
40  /*************************************************************************/
41  /* */
42  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
43  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
44  /* messages during execution. */
45  /* */
46 #undef FT_COMPONENT
47 #define FT_COMPONENT trace_pcfread
48 
49 
50 #ifdef FT_DEBUG_LEVEL_TRACE
51  static const char* const tableNames[] =
52  {
53  "prop", "accl", "mtrcs", "bmps", "imtrcs",
54  "enc", "swidth", "names", "accel"
55  };
56 #endif
57 
58 
59  static
60  const FT_Frame_Field pcf_toc_header[] =
61  {
62 #undef FT_STRUCTURE
63 #define FT_STRUCTURE PCF_TocRec
64 
65  FT_FRAME_START( 8 ),
69  };
70 
71 
72  static
73  const FT_Frame_Field pcf_table_header[] =
74  {
75 #undef FT_STRUCTURE
76 #define FT_STRUCTURE PCF_TableRec
77 
78  FT_FRAME_START( 16 ),
84  };
85 
86 
87  static FT_Error
88  pcf_read_TOC( FT_Stream stream,
89  PCF_Face face )
90  {
92  PCF_Toc toc = &face->toc;
93  PCF_Table tables;
94 
95  FT_Memory memory = FT_FACE(face)->memory;
96  FT_UInt n;
97 
98 
99  if ( FT_STREAM_SEEK ( 0 ) ||
100  FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) )
101  return FT_THROW( Cannot_Open_Resource );
102 
103  if ( toc->version != PCF_FILE_VERSION ||
104  toc->count > FT_ARRAY_MAX( face->toc.tables ) ||
105  toc->count == 0 )
106  return FT_THROW( Invalid_File_Format );
107 
108  if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
109  return FT_THROW( Out_Of_Memory );
110 
111  tables = face->toc.tables;
112  for ( n = 0; n < toc->count; n++ )
113  {
114  if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) )
115  goto Exit;
116  tables++;
117  }
118 
119  /* Sort tables and check for overlaps. Because they are almost */
120  /* always ordered already, an in-place bubble sort with simultaneous */
121  /* boundary checking seems appropriate. */
122  tables = face->toc.tables;
123 
124  for ( n = 0; n < toc->count - 1; n++ )
125  {
126  FT_UInt i, have_change;
127 
128 
129  have_change = 0;
130 
131  for ( i = 0; i < toc->count - 1 - n; i++ )
132  {
133  PCF_TableRec tmp;
134 
135 
136  if ( tables[i].offset > tables[i + 1].offset )
137  {
138  tmp = tables[i];
139  tables[i] = tables[i + 1];
140  tables[i + 1] = tmp;
141 
142  have_change = 1;
143  }
144 
145  if ( ( tables[i].size > tables[i + 1].offset ) ||
146  ( tables[i].offset > tables[i + 1].offset - tables[i].size ) )
147  return FT_THROW( Invalid_Offset );
148  }
149 
150  if ( !have_change )
151  break;
152  }
153 
154 #ifdef FT_DEBUG_LEVEL_TRACE
155 
156  {
157  FT_UInt i, j;
158  const char* name = "?";
159 
160 
161  FT_TRACE4(( "pcf_read_TOC:\n" ));
162 
163  FT_TRACE4(( " number of tables: %ld\n", face->toc.count ));
164 
165  tables = face->toc.tables;
166  for ( i = 0; i < toc->count; i++ )
167  {
168  for ( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] );
169  j++ )
170  if ( tables[i].type == (FT_UInt)( 1 << j ) )
171  name = tableNames[j];
172 
173  FT_TRACE4(( " %d: type=%s, format=0x%X, "
174  "size=%ld (0x%lX), offset=%ld (0x%lX)\n",
175  i, name,
176  tables[i].format,
177  tables[i].size, tables[i].size,
178  tables[i].offset, tables[i].offset ));
179  }
180  }
181 
182 #endif
183 
184  return FT_Err_Ok;
185 
186  Exit:
187  FT_FREE( face->toc.tables );
188  return error;
189  }
190 
191 
192 #define PCF_METRIC_SIZE 12
193 
194  static
195  const FT_Frame_Field pcf_metric_header[] =
196  {
197 #undef FT_STRUCTURE
198 #define FT_STRUCTURE PCF_MetricRec
199 
201  FT_FRAME_SHORT_LE( leftSideBearing ),
202  FT_FRAME_SHORT_LE( rightSideBearing ),
203  FT_FRAME_SHORT_LE( characterWidth ),
204  FT_FRAME_SHORT_LE( ascent ),
205  FT_FRAME_SHORT_LE( descent ),
206  FT_FRAME_SHORT_LE( attributes ),
208  };
209 
210 
211  static
212  const FT_Frame_Field pcf_metric_msb_header[] =
213  {
214 #undef FT_STRUCTURE
215 #define FT_STRUCTURE PCF_MetricRec
216 
218  FT_FRAME_SHORT( leftSideBearing ),
219  FT_FRAME_SHORT( rightSideBearing ),
220  FT_FRAME_SHORT( characterWidth ),
221  FT_FRAME_SHORT( ascent ),
222  FT_FRAME_SHORT( descent ),
223  FT_FRAME_SHORT( attributes ),
225  };
226 
227 
228 #define PCF_COMPRESSED_METRIC_SIZE 5
229 
230  static
231  const FT_Frame_Field pcf_compressed_metric_header[] =
232  {
233 #undef FT_STRUCTURE
234 #define FT_STRUCTURE PCF_Compressed_MetricRec
235 
237  FT_FRAME_BYTE( leftSideBearing ),
238  FT_FRAME_BYTE( rightSideBearing ),
239  FT_FRAME_BYTE( characterWidth ),
240  FT_FRAME_BYTE( ascent ),
241  FT_FRAME_BYTE( descent ),
243  };
244 
245 
246  static FT_Error
247  pcf_get_metric( FT_Stream stream,
249  PCF_Metric metric )
250  {
252 
253 
255  {
256  const FT_Frame_Field* fields;
257 
258 
259  /* parsing normal metrics */
260  fields = PCF_BYTE_ORDER( format ) == MSBFirst
261  ? pcf_metric_msb_header
262  : pcf_metric_header;
263 
264  /* the following sets `error' but doesn't return in case of failure */
265  (void)FT_STREAM_READ_FIELDS( fields, metric );
266  }
267  else
268  {
270 
271 
272  /* parsing compressed metrics */
273  if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) )
274  goto Exit;
275 
276  metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 );
277  metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 );
278  metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 );
279  metric->ascent = (FT_Short)( compr.ascent - 0x80 );
280  metric->descent = (FT_Short)( compr.descent - 0x80 );
281  metric->attributes = 0;
282  }
283 
284  Exit:
285  return error;
286  }
287 
288 
289  static FT_Error
290  pcf_seek_to_table_type( FT_Stream stream,
291  PCF_Table tables,
292  FT_ULong ntables, /* same as PCF_Toc->count */
293  FT_ULong type,
294  FT_ULong *aformat,
295  FT_ULong *asize )
296  {
297  FT_Error error = FT_ERR( Invalid_File_Format );
298  FT_ULong i;
299 
300 
301  for ( i = 0; i < ntables; i++ )
302  if ( tables[i].type == type )
303  {
304  if ( stream->pos > tables[i].offset )
305  {
306  error = FT_THROW( Invalid_Stream_Skip );
307  goto Fail;
308  }
309 
310  if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) )
311  {
312  error = FT_THROW( Invalid_Stream_Skip );
313  goto Fail;
314  }
315 
316  *asize = tables[i].size;
317  *aformat = tables[i].format;
318 
319  return FT_Err_Ok;
320  }
321 
322  Fail:
323  *asize = 0;
324  return error;
325  }
326 
327 
328  static FT_Bool
329  pcf_has_table_type( PCF_Table tables,
330  FT_ULong ntables, /* same as PCF_Toc->count */
331  FT_ULong type )
332  {
333  FT_ULong i;
334 
335 
336  for ( i = 0; i < ntables; i++ )
337  if ( tables[i].type == type )
338  return TRUE;
339 
340  return FALSE;
341  }
342 
343 
344 #define PCF_PROPERTY_SIZE 9
345 
346  static
347  const FT_Frame_Field pcf_property_header[] =
348  {
349 #undef FT_STRUCTURE
350 #define FT_STRUCTURE PCF_ParsePropertyRec
351 
354  FT_FRAME_BYTE ( isString ),
357  };
358 
359 
360  static
361  const FT_Frame_Field pcf_property_msb_header[] =
362  {
363 #undef FT_STRUCTURE
364 #define FT_STRUCTURE PCF_ParsePropertyRec
365 
367  FT_FRAME_LONG( name ),
368  FT_FRAME_BYTE( isString ),
369  FT_FRAME_LONG( value ),
371  };
372 
373 
376  const FT_String* prop )
377  {
378  PCF_Property properties = face->properties;
379  FT_Bool found = 0;
380  int i;
381 
382 
383  for ( i = 0 ; i < face->nprops && !found; i++ )
384  {
385  if ( !ft_strcmp( properties[i].name, prop ) )
386  found = 1;
387  }
388 
389  if ( found )
390  return properties + i - 1;
391  else
392  return NULL;
393  }
394 
395 
396  static FT_Error
397  pcf_get_properties( FT_Stream stream,
398  PCF_Face face )
399  {
400  PCF_ParseProperty props = 0;
401  PCF_Property properties = NULL;
402  FT_ULong nprops, i;
404  FT_Error error;
405  FT_Memory memory = FT_FACE(face)->memory;
406  FT_ULong string_size;
407  FT_String* strings = 0;
408 
409 
410  error = pcf_seek_to_table_type( stream,
411  face->toc.tables,
412  face->toc.count,
414  &format,
415  &size );
416  if ( error )
417  goto Bail;
418 
419  if ( FT_READ_ULONG_LE( format ) )
420  goto Bail;
421 
422  FT_TRACE4(( "pcf_get_properties:\n" ));
423 
424  FT_TRACE4(( " format = %ld\n", format ));
425 
426  if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
427  goto Bail;
428 
429  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
430  (void)FT_READ_ULONG( nprops );
431  else
432  (void)FT_READ_ULONG_LE( nprops );
433  if ( error )
434  goto Bail;
435 
436  FT_TRACE4(( " nprop = %d (truncate %d props)\n",
437  (int)nprops, nprops - (int)nprops ));
438 
439  nprops = (int)nprops;
440 
441  /* rough estimate */
442  if ( nprops > size / PCF_PROPERTY_SIZE )
443  {
444  error = FT_THROW( Invalid_Table );
445  goto Bail;
446  }
447 
448  face->nprops = (int)nprops;
449 
450  if ( FT_NEW_ARRAY( props, nprops ) )
451  goto Bail;
452 
453  for ( i = 0; i < nprops; i++ )
454  {
455  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
456  {
457  if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) )
458  goto Bail;
459  }
460  else
461  {
462  if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) )
463  goto Bail;
464  }
465  }
466 
467  /* pad the property array */
468  /* */
469  /* clever here - nprops is the same as the number of odd-units read, */
470  /* as only isStringProp are odd length (Keith Packard) */
471  /* */
472  if ( nprops & 3 )
473  {
474  i = 4 - ( nprops & 3 );
475  if ( FT_STREAM_SKIP( i ) )
476  {
477  error = FT_THROW( Invalid_Stream_Skip );
478  goto Bail;
479  }
480  }
481 
482  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
483  (void)FT_READ_ULONG( string_size );
484  else
485  (void)FT_READ_ULONG_LE( string_size );
486  if ( error )
487  goto Bail;
488 
489  FT_TRACE4(( " string_size = %ld\n", string_size ));
490 
491  /* rough estimate */
492  if ( string_size > size - nprops * PCF_PROPERTY_SIZE )
493  {
494  error = FT_THROW( Invalid_Table );
495  goto Bail;
496  }
497 
498  /* allocate one more byte so that we have a final null byte */
499  if ( FT_NEW_ARRAY( strings, string_size + 1 ) )
500  goto Bail;
501 
502  error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size );
503  if ( error )
504  goto Bail;
505 
506  if ( FT_NEW_ARRAY( properties, nprops ) )
507  goto Bail;
508 
509  face->properties = properties;
510 
511  for ( i = 0; i < nprops; i++ )
512  {
513  FT_Long name_offset = props[i].name;
514 
515 
516  if ( ( name_offset < 0 ) ||
517  ( (FT_ULong)name_offset > string_size ) )
518  {
519  error = FT_THROW( Invalid_Offset );
520  goto Bail;
521  }
522 
523  if ( FT_STRDUP( properties[i].name, strings + name_offset ) )
524  goto Bail;
525 
526  FT_TRACE4(( " %s:", properties[i].name ));
527 
528  properties[i].isString = props[i].isString;
529 
530  if ( props[i].isString )
531  {
532  FT_Long value_offset = props[i].value;
533 
534 
535  if ( ( value_offset < 0 ) ||
536  ( (FT_ULong)value_offset > string_size ) )
537  {
538  error = FT_THROW( Invalid_Offset );
539  goto Bail;
540  }
541 
542  if ( FT_STRDUP( properties[i].value.atom, strings + value_offset ) )
543  goto Bail;
544 
545  FT_TRACE4(( " `%s'\n", properties[i].value.atom ));
546  }
547  else
548  {
549  properties[i].value.l = props[i].value;
550 
551  FT_TRACE4(( " %d\n", properties[i].value.l ));
552  }
553  }
554 
555  error = FT_Err_Ok;
556 
557  Bail:
558  FT_FREE( props );
559  FT_FREE( strings );
560 
561  return error;
562  }
563 
564 
565  static FT_Error
566  pcf_get_metrics( FT_Stream stream,
567  PCF_Face face )
568  {
570  FT_Memory memory = FT_FACE(face)->memory;
572  PCF_Metric metrics = 0;
573  FT_ULong nmetrics, i;
574 
575 
576  error = pcf_seek_to_table_type( stream,
577  face->toc.tables,
578  face->toc.count,
579  PCF_METRICS,
580  &format,
581  &size );
582  if ( error )
583  return error;
584 
585  if ( FT_READ_ULONG_LE( format ) )
586  goto Bail;
587 
588  if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
590  return FT_THROW( Invalid_File_Format );
591 
592  if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
593  {
594  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
595  (void)FT_READ_ULONG( nmetrics );
596  else
597  (void)FT_READ_ULONG_LE( nmetrics );
598  }
599  else
600  {
601  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
602  (void)FT_READ_USHORT( nmetrics );
603  else
604  (void)FT_READ_USHORT_LE( nmetrics );
605  }
606  if ( error )
607  return FT_THROW( Invalid_File_Format );
608 
609  face->nmetrics = nmetrics;
610 
611  if ( !nmetrics )
612  return FT_THROW( Invalid_Table );
613 
614  FT_TRACE4(( "pcf_get_metrics:\n" ));
615 
616  FT_TRACE4(( " number of metrics: %d\n", nmetrics ));
617 
618  /* rough estimate */
619  if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
620  {
621  if ( nmetrics > size / PCF_METRIC_SIZE )
622  return FT_THROW( Invalid_Table );
623  }
624  else
625  {
626  if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
627  return FT_THROW( Invalid_Table );
628  }
629 
630  if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
631  return FT_THROW( Out_Of_Memory );
632 
633  metrics = face->metrics;
634  for ( i = 0; i < nmetrics; i++ )
635  {
636  error = pcf_get_metric( stream, format, metrics + i );
637 
638  metrics[i].bits = 0;
639 
640  FT_TRACE5(( " idx %d: width=%d, "
641  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
642  i,
643  ( metrics + i )->characterWidth,
644  ( metrics + i )->leftSideBearing,
645  ( metrics + i )->rightSideBearing,
646  ( metrics + i )->ascent,
647  ( metrics + i )->descent,
648  ( metrics + i )->attributes ));
649 
650  if ( error )
651  break;
652  }
653 
654  if ( error )
655  FT_FREE( face->metrics );
656 
657  Bail:
658  return error;
659  }
660 
661 
662  static FT_Error
663  pcf_get_bitmaps( FT_Stream stream,
664  PCF_Face face )
665  {
667  FT_Memory memory = FT_FACE(face)->memory;
668  FT_Long* offsets = NULL;
669  FT_Long bitmapSizes[GLYPHPADOPTIONS];
671  FT_ULong nbitmaps, i, sizebitmaps = 0;
672 
673 
674  error = pcf_seek_to_table_type( stream,
675  face->toc.tables,
676  face->toc.count,
677  PCF_BITMAPS,
678  &format,
679  &size );
680  if ( error )
681  return error;
682 
683  error = FT_Stream_EnterFrame( stream, 8 );
684  if ( error )
685  return error;
686 
687  format = FT_GET_ULONG_LE();
688  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
689  nbitmaps = FT_GET_ULONG();
690  else
691  nbitmaps = FT_GET_ULONG_LE();
692 
693  FT_Stream_ExitFrame( stream );
694 
695  if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
696  return FT_THROW( Invalid_File_Format );
697 
698  FT_TRACE4(( "pcf_get_bitmaps:\n" ));
699 
700  FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps ));
701 
702  /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */
703  if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics )
704  return FT_THROW( Invalid_File_Format );
705 
706  if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
707  return error;
708 
709  for ( i = 0; i < nbitmaps; i++ )
710  {
711  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
712  (void)FT_READ_LONG( offsets[i] );
713  else
714  (void)FT_READ_LONG_LE( offsets[i] );
715 
716  FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n",
717  i, offsets[i], offsets[i] ));
718  }
719  if ( error )
720  goto Bail;
721 
722  for ( i = 0; i < GLYPHPADOPTIONS; i++ )
723  {
724  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
725  (void)FT_READ_LONG( bitmapSizes[i] );
726  else
727  (void)FT_READ_LONG_LE( bitmapSizes[i] );
728  if ( error )
729  goto Bail;
730 
731  sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
732 
733  FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] ));
734  }
735 
736  FT_TRACE4(( " %d bitmaps, padding index %ld\n",
737  nbitmaps,
738  PCF_GLYPH_PAD_INDEX( format ) ));
739  FT_TRACE4(( " bitmap size = %d\n", sizebitmaps ));
740 
741  FT_UNUSED( sizebitmaps ); /* only used for debugging */
742 
743  for ( i = 0; i < nbitmaps; i++ )
744  {
745  /* rough estimate */
746  if ( ( offsets[i] < 0 ) ||
747  ( (FT_ULong)offsets[i] > size ) )
748  {
749  FT_TRACE0(( "pcf_get_bitmaps:"
750  " invalid offset to bitmap data of glyph %d\n", i ));
751  }
752  else
753  face->metrics[i].bits = stream->pos + offsets[i];
754  }
755 
756  face->bitmapsFormat = format;
757 
758  Bail:
759  FT_FREE( offsets );
760  return error;
761  }
762 
763 
764  static FT_Error
765  pcf_get_encodings( FT_Stream stream,
766  PCF_Face face )
767  {
769  FT_Memory memory = FT_FACE(face)->memory;
771  int firstCol, lastCol;
772  int firstRow, lastRow;
773  int nencoding, encodingOffset;
774  int i, j, k;
775  PCF_Encoding encoding = NULL;
776 
777 
778  error = pcf_seek_to_table_type( stream,
779  face->toc.tables,
780  face->toc.count,
782  &format,
783  &size );
784  if ( error )
785  return error;
786 
787  error = FT_Stream_EnterFrame( stream, 14 );
788  if ( error )
789  return error;
790 
791  format = FT_GET_ULONG_LE();
792 
793  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
794  {
795  firstCol = FT_GET_SHORT();
796  lastCol = FT_GET_SHORT();
797  firstRow = FT_GET_SHORT();
798  lastRow = FT_GET_SHORT();
799  face->defaultChar = FT_GET_SHORT();
800  }
801  else
802  {
803  firstCol = FT_GET_SHORT_LE();
804  lastCol = FT_GET_SHORT_LE();
805  firstRow = FT_GET_SHORT_LE();
806  lastRow = FT_GET_SHORT_LE();
807  face->defaultChar = FT_GET_SHORT_LE();
808  }
809 
810  FT_Stream_ExitFrame( stream );
811 
812  if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
813  return FT_THROW( Invalid_File_Format );
814 
815  FT_TRACE4(( "pdf_get_encodings:\n" ));
816 
817  FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
818  firstCol, lastCol, firstRow, lastRow ));
819 
820  nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );
821 
822  if ( FT_NEW_ARRAY( encoding, nencoding ) )
823  return FT_THROW( Out_Of_Memory );
824 
825  error = FT_Stream_EnterFrame( stream, 2 * nencoding );
826  if ( error )
827  goto Bail;
828 
829  k = 0;
830  for ( i = firstRow; i <= lastRow; i++ )
831  {
832  for ( j = firstCol; j <= lastCol; j++ )
833  {
834  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
835  encodingOffset = FT_GET_SHORT();
836  else
837  encodingOffset = FT_GET_SHORT_LE();
838 
839  if ( encodingOffset != -1 )
840  {
841  encoding[k].enc = i * 256 + j;
842  encoding[k].glyph = (FT_Short)encodingOffset;
843 
844  FT_TRACE5(( " code %d (0x%04X): idx %d\n",
845  encoding[k].enc, encoding[k].enc, encoding[k].glyph ));
846 
847  k++;
848  }
849  }
850  }
851  FT_Stream_ExitFrame( stream );
852 
853  if ( FT_RENEW_ARRAY( encoding, nencoding, k ) )
854  goto Bail;
855 
856  face->nencodings = k;
857  face->encodings = encoding;
858 
859  return error;
860 
861  Bail:
862  FT_FREE( encoding );
863  return error;
864  }
865 
866 
867  static
868  const FT_Frame_Field pcf_accel_header[] =
869  {
870 #undef FT_STRUCTURE
871 #define FT_STRUCTURE PCF_AccelRec
872 
873  FT_FRAME_START( 20 ),
874  FT_FRAME_BYTE ( noOverlap ),
875  FT_FRAME_BYTE ( constantMetrics ),
876  FT_FRAME_BYTE ( terminalFont ),
877  FT_FRAME_BYTE ( constantWidth ),
878  FT_FRAME_BYTE ( inkInside ),
879  FT_FRAME_BYTE ( inkMetrics ),
880  FT_FRAME_BYTE ( drawDirection ),
881  FT_FRAME_SKIP_BYTES( 1 ),
882  FT_FRAME_LONG_LE ( fontAscent ),
883  FT_FRAME_LONG_LE ( fontDescent ),
884  FT_FRAME_LONG_LE ( maxOverlap ),
886  };
887 
888 
889  static
890  const FT_Frame_Field pcf_accel_msb_header[] =
891  {
892 #undef FT_STRUCTURE
893 #define FT_STRUCTURE PCF_AccelRec
894 
895  FT_FRAME_START( 20 ),
896  FT_FRAME_BYTE ( noOverlap ),
897  FT_FRAME_BYTE ( constantMetrics ),
898  FT_FRAME_BYTE ( terminalFont ),
899  FT_FRAME_BYTE ( constantWidth ),
900  FT_FRAME_BYTE ( inkInside ),
901  FT_FRAME_BYTE ( inkMetrics ),
902  FT_FRAME_BYTE ( drawDirection ),
903  FT_FRAME_SKIP_BYTES( 1 ),
904  FT_FRAME_LONG ( fontAscent ),
905  FT_FRAME_LONG ( fontDescent ),
906  FT_FRAME_LONG ( maxOverlap ),
908  };
909 
910 
911  static FT_Error
912  pcf_get_accel( FT_Stream stream,
913  PCF_Face face,
914  FT_ULong type )
915  {
918  PCF_Accel accel = &face->accel;
919 
920 
921  error = pcf_seek_to_table_type( stream,
922  face->toc.tables,
923  face->toc.count,
924  type,
925  &format,
926  &size );
927  if ( error )
928  goto Bail;
929 
930  if ( FT_READ_ULONG_LE( format ) )
931  goto Bail;
932 
933  if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
935  goto Bail;
936 
937  if ( PCF_BYTE_ORDER( format ) == MSBFirst )
938  {
939  if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) )
940  goto Bail;
941  }
942  else
943  {
944  if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) )
945  goto Bail;
946  }
947 
948  error = pcf_get_metric( stream,
949  format & ( ~PCF_FORMAT_MASK ),
950  &(accel->minbounds) );
951  if ( error )
952  goto Bail;
953 
954  error = pcf_get_metric( stream,
955  format & ( ~PCF_FORMAT_MASK ),
956  &(accel->maxbounds) );
957  if ( error )
958  goto Bail;
959 
960  if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
961  {
962  error = pcf_get_metric( stream,
963  format & ( ~PCF_FORMAT_MASK ),
964  &(accel->ink_minbounds) );
965  if ( error )
966  goto Bail;
967 
968  error = pcf_get_metric( stream,
969  format & ( ~PCF_FORMAT_MASK ),
970  &(accel->ink_maxbounds) );
971  if ( error )
972  goto Bail;
973  }
974  else
975  {
976  accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
977  accel->ink_maxbounds = accel->maxbounds;
978  }
979 
980  Bail:
981  return error;
982  }
983 
984 
985  static FT_Error
986  pcf_interpret_style( PCF_Face pcf )
987  {
989  FT_Face face = FT_FACE( pcf );
990  FT_Memory memory = face->memory;
991 
992  PCF_Property prop;
993 
994  size_t nn, len;
995  char* strings[4] = { NULL, NULL, NULL, NULL };
996  size_t lengths[4];
997 
998 
999  face->style_flags = 0;
1000 
1001  prop = pcf_find_property( pcf, "SLANT" );
1002  if ( prop && prop->isString &&
1003  ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
1004  *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )
1005  {
1007  strings[2] = ( *(prop->value.atom) == 'O' ||
1008  *(prop->value.atom) == 'o' ) ? (char *)"Oblique"
1009  : (char *)"Italic";
1010  }
1011 
1012  prop = pcf_find_property( pcf, "WEIGHT_NAME" );
1013  if ( prop && prop->isString &&
1014  ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
1015  {
1017  strings[1] = (char *)"Bold";
1018  }
1019 
1020  prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
1021  if ( prop && prop->isString &&
1022  *(prop->value.atom) &&
1023  !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
1024  strings[3] = (char *)(prop->value.atom);
1025 
1026  prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
1027  if ( prop && prop->isString &&
1028  *(prop->value.atom) &&
1029  !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
1030  strings[0] = (char *)(prop->value.atom);
1031 
1032  for ( len = 0, nn = 0; nn < 4; nn++ )
1033  {
1034  lengths[nn] = 0;
1035  if ( strings[nn] )
1036  {
1037  lengths[nn] = ft_strlen( strings[nn] );
1038  len += lengths[nn] + 1;
1039  }
1040  }
1041 
1042  if ( len == 0 )
1043  {
1044  strings[0] = (char *)"Regular";
1045  lengths[0] = ft_strlen( strings[0] );
1046  len = lengths[0] + 1;
1047  }
1048 
1049  {
1050  char* s;
1051 
1052 
1053  if ( FT_ALLOC( face->style_name, len ) )
1054  return error;
1055 
1056  s = face->style_name;
1057 
1058  for ( nn = 0; nn < 4; nn++ )
1059  {
1060  char* src = strings[nn];
1061 
1062 
1063  len = lengths[nn];
1064 
1065  if ( src == NULL )
1066  continue;
1067 
1068  /* separate elements with a space */
1069  if ( s != face->style_name )
1070  *s++ = ' ';
1071 
1072  ft_memcpy( s, src, len );
1073 
1074  /* need to convert spaces to dashes for */
1075  /* add_style_name and setwidth_name */
1076  if ( nn == 0 || nn == 3 )
1077  {
1078  size_t mm;
1079 
1080 
1081  for ( mm = 0; mm < len; mm++ )
1082  if (s[mm] == ' ')
1083  s[mm] = '-';
1084  }
1085 
1086  s += len;
1087  }
1088  *s = 0;
1089  }
1090 
1091  return error;
1092  }
1093 
1094 
1097  PCF_Face face )
1098  {
1100  FT_Memory memory = FT_FACE(face)->memory;
1101  FT_Bool hasBDFAccelerators;
1102 
1103 
1104  error = pcf_read_TOC( stream, face );
1105  if ( error )
1106  goto Exit;
1107 
1108  error = pcf_get_properties( stream, face );
1109  if ( error )
1110  goto Exit;
1111 
1112  /* Use the old accelerators if no BDF accelerators are in the file. */
1113  hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
1114  face->toc.count,
1116  if ( !hasBDFAccelerators )
1117  {
1118  error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
1119  if ( error )
1120  goto Exit;
1121  }
1122 
1123  /* metrics */
1124  error = pcf_get_metrics( stream, face );
1125  if ( error )
1126  goto Exit;
1127 
1128  /* bitmaps */
1129  error = pcf_get_bitmaps( stream, face );
1130  if ( error )
1131  goto Exit;
1132 
1133  /* encodings */
1134  error = pcf_get_encodings( stream, face );
1135  if ( error )
1136  goto Exit;
1137 
1138  /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
1139  if ( hasBDFAccelerators )
1140  {
1141  error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
1142  if ( error )
1143  goto Exit;
1144  }
1145 
1146  /* XXX: TO DO: inkmetrics and glyph_names are missing */
1147 
1148  /* now construct the face object */
1149  {
1150  FT_Face root = FT_FACE( face );
1151  PCF_Property prop;
1152 
1153 
1154  root->num_faces = 1;
1155  root->face_index = 0;
1159 
1160  if ( face->accel.constantWidth )
1162 
1163  if ( ( error = pcf_interpret_style( face ) ) != 0 )
1164  goto Exit;
1165 
1166  prop = pcf_find_property( face, "FAMILY_NAME" );
1167  if ( prop && prop->isString )
1168  {
1169  if ( FT_STRDUP( root->family_name, prop->value.atom ) )
1170  goto Exit;
1171  }
1172  else
1173  root->family_name = NULL;
1174 
1175  /*
1176  * Note: We shift all glyph indices by +1 since we must
1177  * respect the convention that glyph 0 always corresponds
1178  * to the `missing glyph'.
1179  *
1180  * This implies bumping the number of `available' glyphs by 1.
1181  */
1182  root->num_glyphs = face->nmetrics + 1;
1183 
1184  root->num_fixed_sizes = 1;
1185  if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
1186  goto Exit;
1187 
1188  {
1189  FT_Bitmap_Size* bsize = root->available_sizes;
1190  FT_Short resolution_x = 0, resolution_y = 0;
1191 
1192 
1193  FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );
1194 
1195 #if 0
1196  bsize->height = face->accel.maxbounds.ascent << 6;
1197 #endif
1198  bsize->height = (FT_Short)( face->accel.fontAscent +
1199  face->accel.fontDescent );
1200 
1201  prop = pcf_find_property( face, "AVERAGE_WIDTH" );
1202  if ( prop )
1203  bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 );
1204  else
1205  bsize->width = (FT_Short)( bsize->height * 2/3 );
1206 
1207  prop = pcf_find_property( face, "POINT_SIZE" );
1208  if ( prop )
1209  /* convert from 722.7 decipoints to 72 points per inch */
1210  bsize->size =
1211  (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L );
1212 
1213  prop = pcf_find_property( face, "PIXEL_SIZE" );
1214  if ( prop )
1215  bsize->y_ppem = (FT_Short)prop->value.l << 6;
1216 
1217  prop = pcf_find_property( face, "RESOLUTION_X" );
1218  if ( prop )
1219  resolution_x = (FT_Short)prop->value.l;
1220 
1221  prop = pcf_find_property( face, "RESOLUTION_Y" );
1222  if ( prop )
1223  resolution_y = (FT_Short)prop->value.l;
1224 
1225  if ( bsize->y_ppem == 0 )
1226  {
1227  bsize->y_ppem = bsize->size;
1228  if ( resolution_y )
1229  bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
1230  }
1231  if ( resolution_x && resolution_y )
1232  bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
1233  else
1234  bsize->x_ppem = bsize->y_ppem;
1235  }
1236 
1237  /* set up charset */
1238  {
1239  PCF_Property charset_registry = 0, charset_encoding = 0;
1240 
1241 
1242  charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
1243  charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );
1244 
1245  if ( charset_registry && charset_registry->isString &&
1246  charset_encoding && charset_encoding->isString )
1247  {
1248  if ( FT_STRDUP( face->charset_encoding,
1249  charset_encoding->value.atom ) ||
1250  FT_STRDUP( face->charset_registry,
1251  charset_registry->value.atom ) )
1252  goto Exit;
1253  }
1254  }
1255  }
1256 
1257  Exit:
1258  if ( error )
1259  {
1260  /* This is done to respect the behaviour of the original */
1261  /* PCF font driver. */
1262  error = FT_THROW( Invalid_File_Format );
1263  }
1264 
1265  return error;
1266  }
1267 
1268 
1269 /* END */
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
FT_Byte constantWidth
Definition: pcf.h:112
int FT_Error
Definition: fttypes.h:296
GLuint GLuint stream
FT_Stream_EnterFrame(FT_Stream stream, FT_ULong count)
Definition: ftstream.c:234
#define FT_FRAME_LONG(f)
Definition: ftstream.h:120
FT_Short rightSideBearing
Definition: pcf.h:97
FT_Int num_fixed_sizes
Definition: freetype.h:932
signed long FT_Long
Definition: fttypes.h:238
FT_Pos x_ppem
Definition: freetype.h:305
unsigned long FT_ULong
Definition: fttypes.h:249
FT_Short width
Definition: freetype.h:301
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:59
#define FT_READ_USHORT_LE(var)
Definition: ftstream.h:316
#define PCF_BDF_ENCODINGS
Definition: pcf.h:221
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
#define FT_FACE_FLAG_FAST_GLYPHS
Definition: freetype.h:1083
#define NULL
Definition: ftobjs.h:61
char * charset_registry
Definition: pcf.h:143
FT_Long face_index
Definition: freetype.h:922
#define PCF_ACCEL_W_INKBOUNDS
Definition: pcf.h:178
FT_Long nmetrics
Definition: pcf.h:151
FT_Long num_faces
Definition: freetype.h:921
GLsizei const GLchar *const * strings
FT_Short height
Definition: freetype.h:300
return FT_THROW(Missing_Property)
FT_BEGIN_HEADER struct PCF_TableRec_ * PCF_Table
pcf_find_property(PCF_Face face, const FT_String *prop)
Definition: pcfread.c:375
#define MSBFirst
Definition: pcf.h:169
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
FT_Short attributes
Definition: pcf.h:101
FT_BEGIN_HEADER struct PCF_TableRec_ PCF_TableRec
FT_String * family_name
Definition: freetype.h:929
union PCF_PropertyRec_::@27 value
FT_String * style_name
Definition: freetype.h:930
FT_Bitmap_Size * available_sizes
Definition: freetype.h:933
#define FT_FACE_FLAG_FIXED_SIZES
Definition: freetype.h:1077
#define FT_FRAME_SHORT_LE(f)
Definition: ftstream.h:131
#define PCF_DEFAULT_FORMAT
Definition: pcf.h:176
return FT_Err_Ok
Definition: ftbbox.c:645
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
PCF_MetricRec ink_maxbounds
Definition: pcf.h:122
#define FT_FRAME_ULONG_LE(f)
Definition: ftstream.h:130
#define PCF_BDF_ACCELERATORS
Definition: pcf.h:224
png_uint_32 i
Definition: png.h:2640
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
FT_String * atom
Definition: pcf.h:74
GLenum GLuint GLint GLenum face
#define const
Definition: zconf.h:91
#define PCF_COMPRESSED_METRICS
Definition: pcf.h:179
unsigned char FT_Byte
Definition: fttypes.h:150
#define PCF_GLYPH_PAD_INDEX(f)
Definition: pcf.h:193
#define FT_STYLE_FLAG_BOLD
Definition: freetype.h:1297
#define FT_FRAME_SKIP_BYTES(count)
Definition: ftstream.h:147
int nprops
Definition: pcf.h:148
#define FT_ARRAY_MAX(ptr)
Definition: ftmemory.h:228
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
FT_Long fontDescent
Definition: pcf.h:117
FT_Byte leftSideBearing
Definition: pcf.h:85
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:506
#define PCF_BYTE_ORDER(f)
Definition: pcf.h:189
#define FT_FREE(ptr)
Definition: ftmemory.h:286
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:492
#define PCF_PROPERTY_SIZE
Definition: pcfread.c:344
#define FT_FACE_FLAG_FIXED_WIDTH
Definition: freetype.h:1078
GLenum GLsizei len
PCF_Encoding encodings
Definition: pcf.h:154
FT_Stream_Read(FT_Stream stream, FT_Byte *buffer, FT_ULong count)
Definition: ftstream.c:110
FT_Long fontAscent
Definition: pcf.h:116
char * charset_encoding
Definition: pcf.h:142
#define FT_ERR(e)
Definition: fttypes.h:582
FT_Long enc
Definition: pcf.h:129
FT_Error error
Definition: cffdrivr.c:411
FT_UShort glyph
Definition: pcf.h:130
#define FT_READ_ULONG(var)
Definition: ftstream.h:313
char FT_String
Definition: fttypes.h:183
#define FT_FACE_FLAG_HORIZONTAL
Definition: freetype.h:1080
FT_ULong version
Definition: pcf.h:51
GLdouble n
#define FT_GET_SHORT_LE()
Definition: ftstream.h:296
PCF_MetricRec ink_minbounds
Definition: pcf.h:121
local int root
Definition: enough.c:171
GLenum src
int const char * version
Definition: zlib.h:813
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:293
#define FT_READ_ULONG_LE(var)
Definition: ftstream.h:318
FT_Byte isString
Definition: pcf.h:70
GLintptr offset
#define FT_READ_LONG(var)
Definition: ftstream.h:312
#define FALSE
Definition: ftobjs.h:57
GLsizei const GLfloat * value
FT_Short characterWidth
Definition: pcf.h:98
FT_Short descent
Definition: pcf.h:100
FT_Long nencodings
Definition: pcf.h:153
#define PCF_FORMAT_MATCH(a, b)
Definition: pcf.h:181
signed short FT_Short
Definition: fttypes.h:194
FT_Short leftSideBearing
Definition: pcf.h:96
#define FT_READ_LONG_LE(var)
Definition: ftstream.h:317
FT_Long face_flags
Definition: freetype.h:924
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Short ascent
Definition: pcf.h:99
#define PCF_BITMAPS
Definition: pcf.h:219
#define PCF_METRICS
Definition: pcf.h:218
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
GLuint const GLchar * name
if(!abbox) return FT_THROW(Invalid_Argument)
GLenum type
PCF_AccelRec accel
Definition: pcf.h:146
FT_Short defaultChar
Definition: pcf.h:156
typedef int
Definition: png.h:978
#define FT_FACE(x)
Definition: ftobjs.h:557
pcf_load_font(FT_Stream stream, PCF_Face face)
Definition: pcfread.c:1096
FT_Long num_glyphs
Definition: freetype.h:927
PCF_MetricRec minbounds
Definition: pcf.h:119
#define PCF_FORMAT_MASK
Definition: pcf.h:174
unsigned int FT_UInt
Definition: fttypes.h:227
FT_Long name
Definition: pcf.h:60
#define FT_FRAME_BYTE(f)
Definition: ftstream.h:126
PCF_TocRec toc
Definition: pcf.h:145
FT_Byte rightSideBearing
Definition: pcf.h:86
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
GLdouble s
#define PCF_ACCELERATORS
Definition: pcf.h:217
PCF_Property properties
Definition: pcf.h:149
#define FT_GET_SHORT()
Definition: ftstream.h:288
FT_Byte isString
Definition: pcf.h:61
#define PCF_METRIC_SIZE
Definition: pcfread.c:192
FT_Stream_ExitFrame(FT_Stream stream)
Definition: ftstream.c:312
FT_ULong bits
Definition: pcf.h:102
FT_Long style_flags
Definition: freetype.h:925
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
GLuint GLuint GLsizei count
#define FT_GET_ULONG()
Definition: ftstream.h:293
FT_Pos y_ppem
Definition: freetype.h:306
FT_Byte characterWidth
Definition: pcf.h:87
FT_ULong bitmapsFormat
Definition: pcf.h:158
#define FT_STRDUP(dst, str)
Definition: ftmemory.h:351
#define PCF_FILE_VERSION
Definition: pcf.h:171
FT_TRACE0(("cff_property_set: missing property `%s'\, property_name))
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
PCF_Table tables
Definition: pcf.h:53
#define PCF_PROPERTIES
Definition: pcf.h:216
#define FT_FRAME_LONG_LE(f)
Definition: ftstream.h:129
#define FT_STYLE_FLAG_ITALIC
Definition: freetype.h:1296
unsigned long pos
Definition: ftsystem.h:325
FT_ULong count
Definition: pcf.h:52
#define ft_memcpy
Definition: ftstdlib.h:81
GLsizeiptr size
PCF_MetricRec maxbounds
Definition: pcf.h:120
#define FT_FRAME_SHORT(f)
Definition: ftstream.h:122
#define PCF_COMPRESSED_METRIC_SIZE
Definition: pcfread.c:228
#define TRUE
Definition: ftobjs.h:53
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define ft_strlen
Definition: ftstdlib.h:87
FT_Long l
Definition: pcf.h:75
#define FT_FRAME_START(size)
Definition: ftstream.h:117
#define FT_GET_ULONG_LE()
Definition: ftstream.h:299
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
FT_Long value
Definition: pcf.h:62
FT_Memory memory
Definition: freetype.h:963
#define ft_strcmp
Definition: ftstdlib.h:85
PCF_Metric metrics
Definition: pcf.h:152
#define GLYPHPADOPTIONS
Definition: pcf.h:226