3 FreeType font driver for pcf fonts
6 Francesco Zappa Nardelli
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:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
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
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
32 #include FT_INTERNAL_OBJECTS_H
35 #include "pcfdriver.h"
39 #include <string.h> /* strlen(), strcpy() */
42 /*************************************************************************/
44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
46 /* messages during execution. */
49 #define FT_COMPONENT trace_pcfread
52 #if defined( FT_DEBUG_LEVEL_TRACE )
53 static char* tableNames[] =
55 "prop", "accl", "mtrcs", "bmps", "imtrcs",
56 "enc", "swidth", "names", "accel"
62 const FT_Frame_Field pcf_toc_header[] =
65 #define FT_STRUCTURE PCF_TocRec
68 FT_FRAME_ULONG_LE( version ),
69 FT_FRAME_ULONG_LE( count ),
75 const FT_Frame_Field pcf_table_header[] =
78 #define FT_STRUCTURE PCF_TableRec
81 FT_FRAME_ULONG_LE( type ),
82 FT_FRAME_ULONG_LE( format ),
83 FT_FRAME_ULONG_LE( size ),
84 FT_FRAME_ULONG_LE( offset ),
90 pcf_read_TOC( FT_Stream stream,
94 PCF_Toc toc = &face->toc;
97 FT_Memory memory = FT_FACE(face)->memory;
101 if ( FILE_Seek ( 0 ) ||
102 READ_Fields ( pcf_toc_header, toc ) )
103 return PCF_Err_Cannot_Open_Resource;
105 if ( toc->version != PCF_FILE_VERSION )
106 return PCF_Err_Invalid_File_Format;
108 if ( ALLOC( face->toc.tables, toc->count * sizeof ( PCF_TableRec ) ) )
109 return PCF_Err_Out_Of_Memory;
111 tables = face->toc.tables;
112 for ( i = 0; i < toc->count; i++ )
114 if ( READ_Fields( pcf_table_header, tables ) )
119 #if defined( FT_DEBUG_LEVEL_TRACE )
126 FT_TRACE4(( "Tables count: %ld\n", face->toc.count ));
127 tables = face->toc.tables;
128 for ( i = 0; i < toc->count; i++ )
130 for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
131 if ( tables[i].type == (unsigned int)( 1 << j ) )
133 FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX "
134 "size=0x%06lX (%8ld) offset=0x%04lX\n",
137 tables[i].size, tables[i].size,
147 FREE( face->toc.tables );
153 const FT_Frame_Field pcf_metric_header[] =
156 #define FT_STRUCTURE PCF_MetricRec
158 FT_FRAME_START( 12 ),
159 FT_FRAME_SHORT_LE( leftSideBearing ),
160 FT_FRAME_SHORT_LE( rightSideBearing ),
161 FT_FRAME_SHORT_LE( characterWidth ),
162 FT_FRAME_SHORT_LE( ascent ),
163 FT_FRAME_SHORT_LE( descent ),
164 FT_FRAME_SHORT_LE( attributes ),
170 const FT_Frame_Field pcf_metric_msb_header[] =
173 #define FT_STRUCTURE PCF_MetricRec
175 FT_FRAME_START( 12 ),
176 FT_FRAME_SHORT( leftSideBearing ),
177 FT_FRAME_SHORT( rightSideBearing ),
178 FT_FRAME_SHORT( characterWidth ),
179 FT_FRAME_SHORT( ascent ),
180 FT_FRAME_SHORT( descent ),
181 FT_FRAME_SHORT( attributes ),
187 const FT_Frame_Field pcf_compressed_metric_header[] =
190 #define FT_STRUCTURE PCF_Compressed_MetricRec
193 FT_FRAME_BYTE( leftSideBearing ),
194 FT_FRAME_BYTE( rightSideBearing ),
195 FT_FRAME_BYTE( characterWidth ),
196 FT_FRAME_BYTE( ascent ),
197 FT_FRAME_BYTE( descent ),
203 pcf_parse_metric( FT_Stream stream,
204 const FT_Frame_Field* header,
207 FT_Error error = PCF_Err_Ok;
210 if ( READ_Fields( header, metric ) )
218 pcf_parse_compressed_metric( FT_Stream stream,
221 PCF_Compressed_MetricRec compr_metric;
222 FT_Error error = PCF_Err_Ok;
225 if ( READ_Fields( pcf_compressed_metric_header, &compr_metric ) )
228 metric->leftSideBearing =
229 (FT_Short)( compr_metric.leftSideBearing - 0x80 );
230 metric->rightSideBearing =
231 (FT_Short)( compr_metric.rightSideBearing - 0x80 );
232 metric->characterWidth =
233 (FT_Short)( compr_metric.characterWidth - 0x80 );
235 (FT_Short)( compr_metric.ascent - 0x80 );
237 (FT_Short)( compr_metric.descent - 0x80 );
238 metric->attributes = 0;
245 pcf_get_metric( FT_Stream stream,
249 FT_Error error = PCF_Err_Ok;
252 if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
254 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
255 error = pcf_parse_metric( stream, pcf_metric_msb_header, metric );
257 error = pcf_parse_metric( stream, pcf_metric_header, metric );
260 error = pcf_parse_compressed_metric( stream, metric );
267 pcfSeekToType( FT_Stream stream,
278 for ( i = 0; i < ntables; i++ )
279 if ( tables[i].type == type )
281 if ( stream->pos > tables[i].offset )
282 return PCF_Err_Invalid_Stream_Skip;
283 if ( FILE_Skip( tables[i].offset - stream->pos ) )
284 return PCF_Err_Invalid_Stream_Skip;
285 *sizep = tables[i].size; /* unused - to be removed */
286 *formatp = tables[i].format;
290 return PCF_Err_Invalid_File_Format;
295 pcfHasType( PCF_Table tables,
302 for ( i = 0; i < ntables; i++ )
303 if ( tables[i].type == type )
311 const FT_Frame_Field pcf_property_header[] =
314 #define FT_STRUCTURE PCF_ParsePropertyRec
317 FT_FRAME_LONG_LE( name ),
318 FT_FRAME_BYTE ( isString ),
319 FT_FRAME_LONG_LE( value ),
325 const FT_Frame_Field pcf_property_msb_header[] =
328 #define FT_STRUCTURE PCF_ParsePropertyRec
331 FT_FRAME_LONG( name ),
332 FT_FRAME_BYTE( isString ),
333 FT_FRAME_LONG( value ),
339 find_property( PCF_Face face,
340 const FT_String* prop )
342 PCF_Property properties = face->properties;
347 for ( i = 0 ; i < face->nprops && !found; i++ )
349 if ( !strcmp( properties[i].name, prop ) )
354 return properties + i - 1;
361 pcf_get_properties( FT_Stream stream,
364 PCF_ParseProperty props = 0;
365 PCF_Property properties = 0;
367 FT_ULong format, size;
369 FT_Memory memory = FT_FACE(face)->memory;
370 FT_ULong string_size;
371 FT_String* strings = 0;
374 error = pcfSeekToType( stream,
383 if ( READ_ULongLE( format ) )
386 FT_TRACE4(( "get_prop: format = %ld\n", format ));
388 if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
391 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
392 (void)READ_ULong( nprops );
394 (void)READ_ULongLE( nprops );
398 FT_TRACE4(( "get_prop: nprop = %d\n", nprops ));
400 if ( ALLOC( props, nprops * sizeof ( PCF_ParsePropertyRec ) ) )
403 for ( i = 0; i < nprops; i++ )
405 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
407 if ( READ_Fields( pcf_property_msb_header, props + i ) )
412 if ( READ_Fields( pcf_property_header, props + i ) )
417 /* pad the property array */
419 /* clever here - nprops is the same as the number of odd-units read, */
420 /* as only isStringProp are odd length (Keith Packard) */
424 i = 4 - ( nprops & 3 );
425 FT_Skip_Stream( stream, i );
428 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
429 (void)READ_ULong( string_size );
431 (void)READ_ULongLE( string_size );
435 FT_TRACE4(( "get_prop: string_size = %ld\n", string_size ));
437 if ( ALLOC( strings, string_size * sizeof ( char ) ) )
440 error = FT_Read_Stream( stream, (FT_Byte*)strings, string_size );
444 if ( ALLOC( properties, nprops * sizeof ( PCF_PropertyRec ) ) )
447 for ( i = 0; i < nprops; i++ )
450 if ( ALLOC( properties[i].name,
451 ( strlen( strings + props[i].name ) + 1 ) *
454 strcpy( properties[i].name,strings + props[i].name );
456 properties[i].isString = props[i].isString;
458 if ( props[i].isString )
460 if ( ALLOC( properties[i].value.atom,
461 ( strlen( strings + props[i].value ) + 1 ) *
464 strcpy( properties[i].value.atom, strings + props[i].value );
467 properties[i].value.integer = props[i].value;
470 face->properties = properties;
471 face->nprops = nprops;
487 pcf_get_metrics( FT_Stream stream,
490 FT_Error error = PCF_Err_Ok;
491 FT_Memory memory = FT_FACE(face)->memory;
494 PCF_Metric metrics = 0;
499 error = pcfSeekToType( stream,
508 error = READ_ULongLE( format );
510 if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
511 !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
512 return PCF_Err_Invalid_File_Format;
514 if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
516 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
517 (void)READ_ULong( nmetrics );
519 (void)READ_ULongLE( nmetrics );
523 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
524 (void)READ_UShort( nmetrics );
526 (void)READ_UShortLE( nmetrics );
528 if ( error || nmetrics == -1 )
529 return PCF_Err_Invalid_File_Format;
531 face->nmetrics = nmetrics;
533 if ( ALLOC( face->metrics, nmetrics * sizeof ( PCF_MetricRec ) ) )
534 return PCF_Err_Out_Of_Memory;
536 metrics = face->metrics;
537 for ( i = 0; i < nmetrics; i++ )
539 pcf_get_metric( stream, format, metrics + i );
543 FT_TRACE4(( "%d : width=%d, "
544 "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
546 ( metrics + i )->characterWidth,
547 ( metrics + i )->leftSideBearing,
548 ( metrics + i )->rightSideBearing,
549 ( metrics + i )->ascent,
550 ( metrics + i )->descent,
551 ( metrics + i )->attributes ));
558 FREE( face->metrics );
564 pcf_get_bitmaps( FT_Stream stream,
567 FT_Error error = PCF_Err_Ok;
568 FT_Memory memory = FT_FACE(face)->memory;
570 FT_Long bitmapSizes[GLYPHPADOPTIONS];
571 FT_ULong format, size;
572 int nbitmaps, i, sizebitmaps = 0;
576 error = pcfSeekToType( stream,
585 error = FT_Access_Frame( stream, 8 );
588 format = GET_ULongLE();
589 if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
590 return PCF_Err_Invalid_File_Format;
592 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
593 nbitmaps = GET_ULong();
595 nbitmaps = GET_ULongLE();
596 FT_Forget_Frame( stream );
597 if ( nbitmaps != face->nmetrics )
598 return PCF_Err_Invalid_File_Format;
600 if ( ALLOC( offsets, nbitmaps * sizeof ( FT_ULong ) ) )
605 for ( i = 0; i < nbitmaps; i++ )
607 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
608 (void)READ_Long( offsets[i] );
610 (void)READ_LongLE( offsets[i] );
612 FT_TRACE4(( "bitmap %d is at offset %ld\n", i, offsets[i] ));
619 for ( i = 0; i < GLYPHPADOPTIONS; i++ )
621 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
622 (void)READ_Long( bitmapSizes[i] );
624 (void)READ_LongLE( bitmapSizes[i] );
628 sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
630 FT_TRACE4(( "padding %d implies a size of %ld\n", i, bitmapSizes[i] ));
633 FT_TRACE4(( " %d bitmaps, padding index %ld\n",
635 PCF_GLYPH_PAD_INDEX( format ) ));
636 FT_TRACE4(( "bitmap size = %d\n", sizebitmaps ));
638 for ( i = 0; i < nbitmaps; i++ )
639 face->metrics[i].bits = stream->pos + offsets[i];
641 face->bitmapsFormat = format;
654 pcf_get_encodings( FT_Stream stream,
657 FT_Error error = PCF_Err_Ok;
658 FT_Memory memory = FT_FACE(face)->memory;
659 FT_ULong format, size;
660 int firstCol, lastCol;
661 int firstRow, lastRow;
662 int nencoding, encodingOffset;
664 PCF_Encoding tmpEncoding, encoding = 0;
667 error = pcfSeekToType( stream,
676 error = FT_Access_Frame( stream, 14 );
679 format = GET_ULongLE();
680 if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
681 return PCF_Err_Invalid_File_Format;
683 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
685 firstCol = GET_Short();
686 lastCol = GET_Short();
687 firstRow = GET_Short();
688 lastRow = GET_Short();
689 face->defaultChar = GET_Short();
693 firstCol = GET_ShortLE();
694 lastCol = GET_ShortLE();
695 firstRow = GET_ShortLE();
696 lastRow = GET_ShortLE();
697 face->defaultChar = GET_ShortLE();
700 FT_Forget_Frame( stream );
702 FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
703 firstCol, lastCol, firstRow, lastRow ));
705 nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );
707 if ( ALLOC( tmpEncoding, nencoding * sizeof ( PCF_EncodingRec ) ) )
708 return PCF_Err_Out_Of_Memory;
710 error = FT_Access_Frame( stream, 2 * nencoding );
714 for ( i = 0, j = 0 ; i < nencoding; i++ )
716 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
717 encodingOffset = GET_Short();
719 encodingOffset = GET_ShortLE();
721 if ( encodingOffset != -1 )
723 tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
725 ( ( i % ( lastCol - firstCol + 1 ) ) +
728 tmpEncoding[j].glyph = (FT_Short)encodingOffset;
732 FT_TRACE4(( "enc n. %d ; Uni %ld ; Glyph %d\n",
733 i, tmpEncoding[j - 1].enc, encodingOffset ));
735 FT_Forget_Frame( stream );
737 if ( ALLOC( encoding, (--j) * sizeof ( PCF_EncodingRec ) ) )
740 for ( i = 0; i < j; i++ )
742 encoding[i].enc = tmpEncoding[i].enc;
743 encoding[i].glyph = tmpEncoding[i].glyph;
746 face->nencodings = j;
747 face->encodings = encoding;
760 const FT_Frame_Field pcf_accel_header[] =
763 #define FT_STRUCTURE PCF_AccelRec
765 FT_FRAME_START( 20 ),
766 FT_FRAME_BYTE ( noOverlap ),
767 FT_FRAME_BYTE ( constantMetrics ),
768 FT_FRAME_BYTE ( terminalFont ),
769 FT_FRAME_BYTE ( constantWidth ),
770 FT_FRAME_BYTE ( inkInside ),
771 FT_FRAME_BYTE ( inkMetrics ),
772 FT_FRAME_BYTE ( drawDirection ),
773 FT_FRAME_SKIP_BYTES( 1 ),
774 FT_FRAME_LONG_LE ( fontAscent ),
775 FT_FRAME_LONG_LE ( fontDescent ),
776 FT_FRAME_LONG_LE ( maxOverlap ),
782 const FT_Frame_Field pcf_accel_msb_header[] =
785 #define FT_STRUCTURE PCF_AccelRec
787 FT_FRAME_START( 20 ),
788 FT_FRAME_BYTE ( noOverlap ),
789 FT_FRAME_BYTE ( constantMetrics ),
790 FT_FRAME_BYTE ( terminalFont ),
791 FT_FRAME_BYTE ( constantWidth ),
792 FT_FRAME_BYTE ( inkInside ),
793 FT_FRAME_BYTE ( inkMetrics ),
794 FT_FRAME_BYTE ( drawDirection ),
795 FT_FRAME_SKIP_BYTES( 1 ),
796 FT_FRAME_LONG ( fontAscent ),
797 FT_FRAME_LONG ( fontDescent ),
798 FT_FRAME_LONG ( maxOverlap ),
804 pcf_get_accel( FT_Stream stream,
808 FT_ULong format, size;
809 FT_Error error = PCF_Err_Ok;
810 PCF_Accel accel = &face->accel;
813 error = pcfSeekToType( stream,
822 error = READ_ULongLE( format );
823 if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
824 !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
827 if ( PCF_BYTE_ORDER( format ) == MSBFirst )
829 if ( READ_Fields( pcf_accel_msb_header, accel ) )
834 if ( READ_Fields( pcf_accel_header, accel ) )
838 error = pcf_get_metric( stream, format, &(accel->minbounds) );
841 error = pcf_get_metric( stream, format, &(accel->maxbounds) );
845 if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
847 error = pcf_get_metric( stream, format, &(accel->ink_minbounds) );
850 error = pcf_get_metric( stream, format, &(accel->ink_maxbounds) );
856 accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
857 accel->ink_maxbounds = accel->maxbounds;
866 FT_LOCAL_DEF FT_Error
867 pcf_load_font( FT_Stream stream,
870 FT_Error error = PCF_Err_Ok;
871 FT_Memory memory = FT_FACE(face)->memory;
872 FT_Bool hasBDFAccelerators;
875 error = pcf_read_TOC( stream, face );
879 error = pcf_get_properties( stream, face );
883 /* Use the old accelerators if no BDF accelerators are in the file. */
884 hasBDFAccelerators = pcfHasType( face->toc.tables,
886 PCF_BDF_ACCELERATORS );
887 if ( !hasBDFAccelerators )
889 error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
895 error = pcf_get_metrics( stream, face );
900 error = pcf_get_bitmaps( stream, face );
905 error = pcf_get_encodings( stream, face );
909 /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
910 if ( hasBDFAccelerators )
912 error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
917 /* XXX: TO DO: inkmetrics and glyph_names are missing */
919 /* now construct the face object */
921 FT_Face root = FT_FACE( face );
926 root->face_index = 0;
927 root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
928 FT_FACE_FLAG_HORIZONTAL |
929 FT_FACE_FLAG_FAST_GLYPHS;
931 if ( face->accel.constantWidth )
932 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
934 root->style_flags = 0;
935 prop = find_property( face, "SLANT" );
937 if ( prop->isString )
938 if ( ( *(prop->value.atom) == 'O' ) ||
939 ( *(prop->value.atom) == 'I' ) )
940 root->style_flags |= FT_STYLE_FLAG_ITALIC;
942 prop = find_property( face, "WEIGHT_NAME" );
944 if ( prop->isString )
945 if ( *(prop->value.atom) == 'B' )
946 root->style_flags |= FT_STYLE_FLAG_BOLD;
948 root->style_name = (char *)"Regular";
950 if ( root->style_flags & FT_STYLE_FLAG_BOLD ) {
951 if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
952 root->style_name = (char *)"Bold Italic";
954 root->style_name = (char *)"Bold";
956 else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
957 root->style_name = (char *)"Italic";
959 prop = find_property( face, "FAMILY_NAME" );
962 if ( prop->isString )
964 int l = strlen( prop->value.atom ) + 1;
967 if ( ALLOC( root->family_name, l * sizeof ( char ) ) )
969 strcpy( root->family_name, prop->value.atom );
973 root->family_name = 0;
975 root->num_glyphs = face->nmetrics;
977 root->num_fixed_sizes = 1;
978 if ( ALLOC_ARRAY( root->available_sizes, 1, FT_Bitmap_Size ) )
981 prop = find_property( face, "PIXEL_SIZE" );
984 PCF_Property xres = 0, yres = 0;
987 xres = find_property( face, "RESOLUTION_X" );
988 yres = find_property( face, "RESOLUTION_Y" );
989 if ( ( xres != NULL ) && ( yres != NULL ) )
991 root->available_sizes->width =
992 (FT_Short)( prop->value.integer * 75 / xres->value.integer );
993 root->available_sizes->height =
994 (FT_Short)( prop->value.integer * 75 / yres->value.integer );
1000 printf( "PCF Warning: Pixel Size undefined, assuming 12\n");
1002 root->available_sizes->width = 12;
1003 root->available_sizes->height = 12;
1007 root->charmaps = &face->charmap_handle;
1008 root->num_charmaps = 1;
1011 PCF_Property charset_registry = 0, charset_encoding = 0;
1014 charset_registry = find_property( face, "CHARSET_REGISTRY" );
1015 charset_encoding = find_property( face, "CHARSET_ENCODING" );
1017 if ( ( charset_registry != NULL ) &&
1018 ( charset_encoding != NULL ) )
1020 if ( ( charset_registry->isString ) &&
1021 ( charset_encoding->isString ) )
1023 if ( ALLOC( face->charset_encoding,
1024 ( strlen( charset_encoding->value.atom ) + 1 ) *
1027 if ( ALLOC( face->charset_registry,
1028 ( strlen( charset_registry->value.atom ) + 1 ) *
1031 strcpy( face->charset_registry, charset_registry->value.atom );
1032 strcpy( face->charset_encoding, charset_encoding->value.atom );
1035 if ( !strcmp( charset_registry, "ISO10646" ) )
1037 face->charmap.encoding = ft_encoding_unicode;
1038 face->charmap.platform_id = 3;
1039 face->charmap.encoding_id = 1;
1040 face->charmap.face = root;
1041 face->charmap_handle
1050 face->charmap.encoding = ft_encoding_none;
1051 face->charmap.platform_id = 0;
1052 face->charmap.encoding_id = 0;
1053 face->charmap.face = root;
1054 face->charmap_handle = &face->charmap;
1055 root->charmap = face->charmap_handle;
1060 PCF_Done_Face( face );
1061 return PCF_Err_Invalid_File_Format;