3
FreeType font driver for pcf fonts
5
Copyright 2000, 2001, 2002, 2003, 2004 by
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
41
/*************************************************************************/
43
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
44
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
45
/* messages during execution. */
48
#define FT_COMPONENT trace_pcfread
51
#if defined( FT_DEBUG_LEVEL_TRACE )
52
static const char* const tableNames[] =
54
"prop", "accl", "mtrcs", "bmps", "imtrcs",
55
"enc", "swidth", "names", "accel"
61
const FT_Frame_Field pcf_toc_header[] =
64
#define FT_STRUCTURE PCF_TocRec
67
FT_FRAME_ULONG_LE( version ),
68
FT_FRAME_ULONG_LE( count ),
74
const FT_Frame_Field pcf_table_header[] =
77
#define FT_STRUCTURE PCF_TableRec
80
FT_FRAME_ULONG_LE( type ),
81
FT_FRAME_ULONG_LE( format ),
82
FT_FRAME_ULONG_LE( size ),
83
FT_FRAME_ULONG_LE( offset ),
89
pcf_read_TOC( FT_Stream stream,
93
PCF_Toc toc = &face->toc;
96
FT_Memory memory = FT_FACE(face)->memory;
100
if ( FT_STREAM_SEEK ( 0 ) ||
101
FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) )
102
return PCF_Err_Cannot_Open_Resource;
104
if ( toc->version != PCF_FILE_VERSION )
105
return PCF_Err_Invalid_File_Format;
107
if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
108
return PCF_Err_Out_Of_Memory;
110
tables = face->toc.tables;
111
for ( n = 0; n < toc->count; n++ )
113
if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) )
118
#if defined( FT_DEBUG_LEVEL_TRACE )
122
const char* name = "?";
125
FT_TRACE4(( "pcf_read_TOC:\n" ));
127
FT_TRACE4(( " number of tables: %ld\n", face->toc.count ));
129
tables = face->toc.tables;
130
for ( i = 0; i < toc->count; i++ )
132
for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
133
if ( tables[i].type == (FT_UInt)( 1 << j ) )
134
name = tableNames[j];
136
FT_TRACE4(( " %d: type=%s, format=0x%X, "
137
"size=%ld (0x%lX), offset=%ld (0x%lX)\n",
140
tables[i].size, tables[i].size,
141
tables[i].offset, tables[i].offset ));
150
FT_FREE( face->toc.tables );
156
const FT_Frame_Field pcf_metric_header[] =
159
#define FT_STRUCTURE PCF_MetricRec
161
FT_FRAME_START( 12 ),
162
FT_FRAME_SHORT_LE( leftSideBearing ),
163
FT_FRAME_SHORT_LE( rightSideBearing ),
164
FT_FRAME_SHORT_LE( characterWidth ),
165
FT_FRAME_SHORT_LE( ascent ),
166
FT_FRAME_SHORT_LE( descent ),
167
FT_FRAME_SHORT_LE( attributes ),
173
const FT_Frame_Field pcf_metric_msb_header[] =
176
#define FT_STRUCTURE PCF_MetricRec
178
FT_FRAME_START( 12 ),
179
FT_FRAME_SHORT( leftSideBearing ),
180
FT_FRAME_SHORT( rightSideBearing ),
181
FT_FRAME_SHORT( characterWidth ),
182
FT_FRAME_SHORT( ascent ),
183
FT_FRAME_SHORT( descent ),
184
FT_FRAME_SHORT( attributes ),
190
const FT_Frame_Field pcf_compressed_metric_header[] =
193
#define FT_STRUCTURE PCF_Compressed_MetricRec
196
FT_FRAME_BYTE( leftSideBearing ),
197
FT_FRAME_BYTE( rightSideBearing ),
198
FT_FRAME_BYTE( characterWidth ),
199
FT_FRAME_BYTE( ascent ),
200
FT_FRAME_BYTE( descent ),
206
pcf_get_metric( FT_Stream stream,
210
FT_Error error = PCF_Err_Ok;
213
if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
215
const FT_Frame_Field* fields;
218
/* parsing normal metrics */
219
fields = PCF_BYTE_ORDER( format ) == MSBFirst
220
? pcf_metric_msb_header
223
/* the following sets 'error' but doesn't return in case of failure */
224
(void)FT_STREAM_READ_FIELDS( fields, metric );
228
PCF_Compressed_MetricRec compr;
231
/* parsing compressed metrics */
232
if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) )
235
metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 );
236
metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 );
237
metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 );
238
metric->ascent = (FT_Short)( compr.ascent - 0x80 );
239
metric->descent = (FT_Short)( compr.descent - 0x80 );
240
metric->attributes = 0;
249
pcf_seek_to_table_type( FT_Stream stream,
256
FT_Error error = PCF_Err_Invalid_File_Format;
260
for ( i = 0; i < ntables; i++ )
261
if ( tables[i].type == type )
263
if ( stream->pos > tables[i].offset ) {
264
error = PCF_Err_Invalid_Stream_Skip;
268
if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) {
269
error = PCF_Err_Invalid_Stream_Skip;
273
*asize = tables[i].size; /* unused - to be removed */
274
*aformat = tables[i].format;
285
pcf_has_table_type( PCF_Table tables,
292
for ( i = 0; i < ntables; i++ )
293
if ( tables[i].type == type )
301
const FT_Frame_Field pcf_property_header[] =
304
#define FT_STRUCTURE PCF_ParsePropertyRec
307
FT_FRAME_LONG_LE( name ),
308
FT_FRAME_BYTE ( isString ),
309
FT_FRAME_LONG_LE( value ),
315
const FT_Frame_Field pcf_property_msb_header[] =
318
#define FT_STRUCTURE PCF_ParsePropertyRec
321
FT_FRAME_LONG( name ),
322
FT_FRAME_BYTE( isString ),
323
FT_FRAME_LONG( value ),
328
FT_LOCAL_DEF( PCF_Property )
329
pcf_find_property( PCF_Face face,
330
const FT_String* prop )
332
PCF_Property properties = face->properties;
337
for ( i = 0 ; i < face->nprops && !found; i++ )
339
if ( !ft_strcmp( properties[i].name, prop ) )
344
return properties + i - 1;
351
pcf_get_properties( FT_Stream stream,
354
PCF_ParseProperty props = 0;
355
PCF_Property properties = 0;
357
FT_ULong format, size;
359
FT_Memory memory = FT_FACE(face)->memory;
360
FT_ULong string_size;
361
FT_String* strings = 0;
364
error = pcf_seek_to_table_type( stream,
373
if ( FT_READ_ULONG_LE( format ) )
376
FT_TRACE4(( "pcf_get_properties:\n" ));
378
FT_TRACE4(( " format = %ld\n", format ));
380
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
383
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
384
(void)FT_READ_ULONG( nprops );
386
(void)FT_READ_ULONG_LE( nprops );
390
FT_TRACE4(( " nprop = %d\n", nprops ));
392
if ( FT_NEW_ARRAY( props, nprops ) )
395
for ( i = 0; i < nprops; i++ )
397
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
399
if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) )
404
if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) )
409
/* pad the property array */
411
/* clever here - nprops is the same as the number of odd-units read, */
412
/* as only isStringProp are odd length (Keith Packard) */
416
i = 4 - ( nprops & 3 );
417
FT_Stream_Skip( stream, i );
420
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
421
(void)FT_READ_ULONG( string_size );
423
(void)FT_READ_ULONG_LE( string_size );
427
FT_TRACE4(( " string_size = %ld\n", string_size ));
429
if ( FT_NEW_ARRAY( strings, string_size ) )
432
error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size );
436
if ( FT_NEW_ARRAY( properties, nprops ) )
439
for ( i = 0; i < nprops; i++ )
442
if ( FT_NEW_ARRAY( properties[i].name,
443
ft_strlen( strings + props[i].name ) + 1 ) )
445
ft_strcpy( properties[i].name, strings + props[i].name );
447
FT_TRACE4(( " %s:", properties[i].name ));
449
properties[i].isString = props[i].isString;
451
if ( props[i].isString )
453
if ( FT_NEW_ARRAY( properties[i].value.atom,
454
ft_strlen( strings + props[i].value ) + 1 ) )
456
ft_strcpy( properties[i].value.atom, strings + props[i].value );
458
FT_TRACE4(( " `%s'\n", properties[i].value.atom ));
462
properties[i].value.integer = props[i].value;
464
FT_TRACE4(( " %d\n", properties[i].value.integer ));
468
face->properties = properties;
469
face->nprops = nprops;
485
pcf_get_metrics( FT_Stream stream,
488
FT_Error error = PCF_Err_Ok;
489
FT_Memory memory = FT_FACE(face)->memory;
492
PCF_Metric metrics = 0;
497
error = pcf_seek_to_table_type( stream,
506
error = FT_READ_ULONG_LE( format );
508
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
509
!PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
510
return PCF_Err_Invalid_File_Format;
512
if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
514
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
515
(void)FT_READ_ULONG( nmetrics );
517
(void)FT_READ_ULONG_LE( nmetrics );
521
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
522
(void)FT_READ_USHORT( nmetrics );
524
(void)FT_READ_USHORT_LE( nmetrics );
526
if ( error || nmetrics == -1 )
527
return PCF_Err_Invalid_File_Format;
529
face->nmetrics = nmetrics;
531
if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
532
return PCF_Err_Out_Of_Memory;
534
FT_TRACE4(( "pcf_get_metrics:\n" ));
536
metrics = face->metrics;
537
for ( i = 0; i < nmetrics; i++ )
539
pcf_get_metric( stream, format, metrics + i );
543
FT_TRACE4(( " idx %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
FT_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 = pcf_seek_to_table_type( stream,
585
error = FT_Stream_EnterFrame( stream, 8 );
589
format = FT_GET_ULONG_LE();
590
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
591
nbitmaps = FT_GET_ULONG();
593
nbitmaps = FT_GET_ULONG_LE();
595
FT_Stream_ExitFrame( stream );
597
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
598
return PCF_Err_Invalid_File_Format;
600
if ( nbitmaps != face->nmetrics )
601
return PCF_Err_Invalid_File_Format;
603
if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
606
FT_TRACE4(( "pcf_get_bitmaps:\n" ));
608
for ( i = 0; i < nbitmaps; i++ )
610
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
611
(void)FT_READ_LONG( offsets[i] );
613
(void)FT_READ_LONG_LE( offsets[i] );
615
FT_TRACE4(( " bitmap %d: offset %ld (0x%lX)\n",
616
i, offsets[i], offsets[i] ));
621
for ( i = 0; i < GLYPHPADOPTIONS; i++ )
623
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
624
(void)FT_READ_LONG( bitmapSizes[i] );
626
(void)FT_READ_LONG_LE( bitmapSizes[i] );
630
sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
632
FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] ));
635
FT_TRACE4(( " %d bitmaps, padding index %ld\n",
637
PCF_GLYPH_PAD_INDEX( format ) ));
638
FT_TRACE4(( " bitmap size = %d\n", sizebitmaps ));
640
FT_UNUSED( sizebitmaps ); /* only used for debugging */
642
for ( i = 0; i < nbitmaps; i++ )
643
face->metrics[i].bits = stream->pos + offsets[i];
645
face->bitmapsFormat = format;
658
pcf_get_encodings( FT_Stream stream,
661
FT_Error error = PCF_Err_Ok;
662
FT_Memory memory = FT_FACE(face)->memory;
663
FT_ULong format, size;
664
int firstCol, lastCol;
665
int firstRow, lastRow;
666
int nencoding, encodingOffset;
668
PCF_Encoding tmpEncoding, encoding = 0;
671
error = pcf_seek_to_table_type( stream,
680
error = FT_Stream_EnterFrame( stream, 14 );
684
format = FT_GET_ULONG_LE();
686
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
688
firstCol = FT_GET_SHORT();
689
lastCol = FT_GET_SHORT();
690
firstRow = FT_GET_SHORT();
691
lastRow = FT_GET_SHORT();
692
face->defaultChar = FT_GET_SHORT();
696
firstCol = FT_GET_SHORT_LE();
697
lastCol = FT_GET_SHORT_LE();
698
firstRow = FT_GET_SHORT_LE();
699
lastRow = FT_GET_SHORT_LE();
700
face->defaultChar = FT_GET_SHORT_LE();
703
FT_Stream_ExitFrame( stream );
705
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
706
return PCF_Err_Invalid_File_Format;
708
FT_TRACE4(( "pdf_get_encodings:\n" ));
710
FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
711
firstCol, lastCol, firstRow, lastRow ));
713
nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );
715
if ( FT_NEW_ARRAY( tmpEncoding, nencoding ) )
716
return PCF_Err_Out_Of_Memory;
718
error = FT_Stream_EnterFrame( stream, 2 * nencoding );
722
for ( i = 0, j = 0 ; i < nencoding; i++ )
724
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
725
encodingOffset = FT_GET_SHORT();
727
encodingOffset = FT_GET_SHORT_LE();
729
if ( encodingOffset != -1 )
731
tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
733
( ( i % ( lastCol - firstCol + 1 ) ) +
736
tmpEncoding[j].glyph = (FT_Short)encodingOffset;
738
FT_TRACE4(( " code %d (0x%04X): idx %d\n",
739
tmpEncoding[j].enc, tmpEncoding[j].enc,
740
tmpEncoding[j].glyph ));
745
FT_Stream_ExitFrame( stream );
747
if ( FT_NEW_ARRAY( encoding, j ) )
750
for ( i = 0; i < j; i++ )
752
encoding[i].enc = tmpEncoding[i].enc;
753
encoding[i].glyph = tmpEncoding[i].glyph;
756
face->nencodings = j;
757
face->encodings = encoding;
758
FT_FREE( tmpEncoding );
764
FT_FREE( tmpEncoding );
770
const FT_Frame_Field pcf_accel_header[] =
773
#define FT_STRUCTURE PCF_AccelRec
775
FT_FRAME_START( 20 ),
776
FT_FRAME_BYTE ( noOverlap ),
777
FT_FRAME_BYTE ( constantMetrics ),
778
FT_FRAME_BYTE ( terminalFont ),
779
FT_FRAME_BYTE ( constantWidth ),
780
FT_FRAME_BYTE ( inkInside ),
781
FT_FRAME_BYTE ( inkMetrics ),
782
FT_FRAME_BYTE ( drawDirection ),
783
FT_FRAME_SKIP_BYTES( 1 ),
784
FT_FRAME_LONG_LE ( fontAscent ),
785
FT_FRAME_LONG_LE ( fontDescent ),
786
FT_FRAME_LONG_LE ( maxOverlap ),
792
const FT_Frame_Field pcf_accel_msb_header[] =
795
#define FT_STRUCTURE PCF_AccelRec
797
FT_FRAME_START( 20 ),
798
FT_FRAME_BYTE ( noOverlap ),
799
FT_FRAME_BYTE ( constantMetrics ),
800
FT_FRAME_BYTE ( terminalFont ),
801
FT_FRAME_BYTE ( constantWidth ),
802
FT_FRAME_BYTE ( inkInside ),
803
FT_FRAME_BYTE ( inkMetrics ),
804
FT_FRAME_BYTE ( drawDirection ),
805
FT_FRAME_SKIP_BYTES( 1 ),
806
FT_FRAME_LONG ( fontAscent ),
807
FT_FRAME_LONG ( fontDescent ),
808
FT_FRAME_LONG ( maxOverlap ),
814
pcf_get_accel( FT_Stream stream,
818
FT_ULong format, size;
819
FT_Error error = PCF_Err_Ok;
820
PCF_Accel accel = &face->accel;
823
error = pcf_seek_to_table_type( stream,
832
error = FT_READ_ULONG_LE( format );
834
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
835
!PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
838
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
840
if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) )
845
if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) )
849
error = pcf_get_metric( stream,
850
format & ( ~PCF_FORMAT_MASK ),
851
&(accel->minbounds) );
855
error = pcf_get_metric( stream,
856
format & ( ~PCF_FORMAT_MASK ),
857
&(accel->maxbounds) );
861
if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
863
error = pcf_get_metric( stream,
864
format & ( ~PCF_FORMAT_MASK ),
865
&(accel->ink_minbounds) );
869
error = pcf_get_metric( stream,
870
format & ( ~PCF_FORMAT_MASK ),
871
&(accel->ink_maxbounds) );
877
accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
878
accel->ink_maxbounds = accel->maxbounds;
888
pcf_interpret_style( PCF_Face pcf )
890
FT_Error error = PCF_Err_Ok;
891
FT_Face face = FT_FACE( pcf );
892
FT_Memory memory = face->memory;
896
char *istr = NULL, *bstr = NULL;
897
char *sstr = NULL, *astr = NULL;
899
int parts = 0, len = 0;
902
face->style_flags = 0;
904
prop = pcf_find_property( pcf, "SLANT" );
905
if ( prop && prop->isString &&
906
( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
907
*(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )
909
face->style_flags |= FT_STYLE_FLAG_ITALIC;
910
istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
913
len += ft_strlen( istr );
917
prop = pcf_find_property( pcf, "WEIGHT_NAME" );
918
if ( prop && prop->isString &&
919
( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
921
face->style_flags |= FT_STYLE_FLAG_BOLD;
922
bstr = (char *)"Bold";
923
len += ft_strlen( bstr );
927
prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
928
if ( prop && prop->isString &&
929
*(prop->value.atom) &&
930
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
932
sstr = (char *)(prop->value.atom);
933
len += ft_strlen( sstr );
937
prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
938
if ( prop && prop->isString &&
939
*(prop->value.atom) &&
940
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
942
astr = (char *)(prop->value.atom);
943
len += ft_strlen( astr );
947
if ( !parts || !len )
948
face->style_name = (char *)"Regular";
955
if ( FT_ALLOC( style, len + parts ) )
962
ft_strcpy( s, astr );
963
for ( i = 0; i < ft_strlen( astr ); i++, s++ )
965
*s = '-'; /* replace spaces with dashes */
970
ft_strcpy( s, bstr );
971
s += ft_strlen( bstr );
976
ft_strcpy( s, istr );
977
s += ft_strlen( istr );
982
ft_strcpy( s, sstr );
983
for ( i = 0; i < ft_strlen( sstr ); i++, s++ )
985
*s = '-'; /* replace spaces with dashes */
988
*(--s) = '\0'; /* overwrite last ' ', terminate the string */
990
face->style_name = style; /* allocated string */
997
FT_LOCAL_DEF( FT_Error )
998
pcf_load_font( FT_Stream stream,
1001
FT_Error error = PCF_Err_Ok;
1002
FT_Memory memory = FT_FACE(face)->memory;
1003
FT_Bool hasBDFAccelerators;
1006
error = pcf_read_TOC( stream, face );
1010
error = pcf_get_properties( stream, face );
1014
/* Use the old accelerators if no BDF accelerators are in the file. */
1015
hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
1017
PCF_BDF_ACCELERATORS );
1018
if ( !hasBDFAccelerators )
1020
error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
1026
error = pcf_get_metrics( stream, face );
1031
error = pcf_get_bitmaps( stream, face );
1036
error = pcf_get_encodings( stream, face );
1040
/* BDF style accelerators (i.e. bounds based on encoded glyphs) */
1041
if ( hasBDFAccelerators )
1043
error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
1048
/* XXX: TO DO: inkmetrics and glyph_names are missing */
1050
/* now construct the face object */
1052
FT_Face root = FT_FACE( face );
1056
root->num_faces = 1;
1057
root->face_index = 0;
1058
root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
1059
FT_FACE_FLAG_HORIZONTAL |
1060
FT_FACE_FLAG_FAST_GLYPHS;
1062
if ( face->accel.constantWidth )
1063
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
1065
if ( ( error = pcf_interpret_style( face ) ) != 0 )
1068
prop = pcf_find_property( face, "FAMILY_NAME" );
1069
if ( prop && prop->isString )
1071
int l = ft_strlen( prop->value.atom ) + 1;
1074
if ( FT_NEW_ARRAY( root->family_name, l ) )
1076
ft_strcpy( root->family_name, prop->value.atom );
1079
root->family_name = NULL;
1081
/* Note: We shift all glyph indices by +1 since we must
1082
* respect the convention that glyph 0 always corresponds
1083
* to the "missing glyph".
1085
* This implies bumping the number of "available" glyphs by 1.
1087
root->num_glyphs = face->nmetrics + 1;
1089
root->num_fixed_sizes = 1;
1090
if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
1094
FT_Bitmap_Size* bsize = root->available_sizes;
1095
FT_Short resolution_x = 0, resolution_y = 0;
1098
FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );
1100
bsize->height = face->accel.fontAscent + face->accel.fontDescent;
1102
prop = pcf_find_property( face, "AVERAGE_WIDTH" );
1104
bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 );
1106
bsize->width = bsize->height * 2/3;
1108
prop = pcf_find_property( face, "POINT_SIZE" );
1110
/* convert from 722.7 decipoints to 72 points per inch */
1112
(FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L );
1114
prop = pcf_find_property( face, "PIXEL_SIZE" );
1116
bsize->y_ppem = (FT_Short)prop->value.integer << 6;
1118
prop = pcf_find_property( face, "RESOLUTION_X" );
1120
resolution_x = (FT_Short)prop->value.integer;
1122
prop = pcf_find_property( face, "RESOLUTION_Y" );
1124
resolution_y = (FT_Short)prop->value.integer;
1126
if ( bsize->y_ppem == 0 )
1128
bsize->y_ppem = bsize->size;
1130
bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
1132
if ( resolution_x && resolution_y )
1133
bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
1135
bsize->x_ppem = bsize->y_ppem;
1138
/* set up charset */
1140
PCF_Property charset_registry = 0, charset_encoding = 0;
1143
charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
1144
charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );
1146
if ( charset_registry && charset_registry->isString &&
1147
charset_encoding && charset_encoding->isString )
1149
if ( FT_NEW_ARRAY( face->charset_encoding,
1150
ft_strlen( charset_encoding->value.atom ) + 1 ) )
1153
if ( FT_NEW_ARRAY( face->charset_registry,
1154
ft_strlen( charset_registry->value.atom ) + 1 ) )
1157
ft_strcpy( face->charset_registry, charset_registry->value.atom );
1158
ft_strcpy( face->charset_encoding, charset_encoding->value.atom );
1166
/* this is done to respect the behaviour of the original */
1167
/* PCF font driver. */
1168
error = PCF_Err_Invalid_File_Format;