1*37da2899SCharles.Forsyth /* pcfread.c 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsyth FreeType font driver for pcf fonts 4*37da2899SCharles.Forsyth 5*37da2899SCharles.Forsyth Copyright 2000-2001, 2002 by 6*37da2899SCharles.Forsyth Francesco Zappa Nardelli 7*37da2899SCharles.Forsyth 8*37da2899SCharles.Forsyth Permission is hereby granted, free of charge, to any person obtaining a copy 9*37da2899SCharles.Forsyth of this software and associated documentation files (the "Software"), to deal 10*37da2899SCharles.Forsyth in the Software without restriction, including without limitation the rights 11*37da2899SCharles.Forsyth to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12*37da2899SCharles.Forsyth copies of the Software, and to permit persons to whom the Software is 13*37da2899SCharles.Forsyth furnished to do so, subject to the following conditions: 14*37da2899SCharles.Forsyth 15*37da2899SCharles.Forsyth The above copyright notice and this permission notice shall be included in 16*37da2899SCharles.Forsyth all copies or substantial portions of the Software. 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19*37da2899SCharles.Forsyth IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20*37da2899SCharles.Forsyth FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21*37da2899SCharles.Forsyth AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22*37da2899SCharles.Forsyth LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23*37da2899SCharles.Forsyth OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24*37da2899SCharles.Forsyth THE SOFTWARE. 25*37da2899SCharles.Forsyth */ 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth #include <ft2build.h> 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 31*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H 32*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsyth #include "pcf.h" 35*37da2899SCharles.Forsyth #include "pcfdriver.h" 36*37da2899SCharles.Forsyth 37*37da2899SCharles.Forsyth #include "pcferror.h" 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth /*************************************************************************/ 41*37da2899SCharles.Forsyth /* */ 42*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 43*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 44*37da2899SCharles.Forsyth /* messages during execution. */ 45*37da2899SCharles.Forsyth /* */ 46*37da2899SCharles.Forsyth #undef FT_COMPONENT 47*37da2899SCharles.Forsyth #define FT_COMPONENT trace_pcfread 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth 50*37da2899SCharles.Forsyth #if defined( FT_DEBUG_LEVEL_TRACE ) 51*37da2899SCharles.Forsyth static const char* tableNames[] = 52*37da2899SCharles.Forsyth { 53*37da2899SCharles.Forsyth "prop", "accl", "mtrcs", "bmps", "imtrcs", 54*37da2899SCharles.Forsyth "enc", "swidth", "names", "accel" 55*37da2899SCharles.Forsyth }; 56*37da2899SCharles.Forsyth #endif 57*37da2899SCharles.Forsyth 58*37da2899SCharles.Forsyth 59*37da2899SCharles.Forsyth static 60*37da2899SCharles.Forsyth const FT_Frame_Field pcf_toc_header[] = 61*37da2899SCharles.Forsyth { 62*37da2899SCharles.Forsyth #undef FT_STRUCTURE 63*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_TocRec 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth FT_FRAME_START( 8 ), 66*37da2899SCharles.Forsyth FT_FRAME_ULONG_LE( version ), 67*37da2899SCharles.Forsyth FT_FRAME_ULONG_LE( count ), 68*37da2899SCharles.Forsyth FT_FRAME_END 69*37da2899SCharles.Forsyth }; 70*37da2899SCharles.Forsyth 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth static 73*37da2899SCharles.Forsyth const FT_Frame_Field pcf_table_header[] = 74*37da2899SCharles.Forsyth { 75*37da2899SCharles.Forsyth #undef FT_STRUCTURE 76*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_TableRec 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsyth FT_FRAME_START( 16 ), 79*37da2899SCharles.Forsyth FT_FRAME_ULONG_LE( type ), 80*37da2899SCharles.Forsyth FT_FRAME_ULONG_LE( format ), 81*37da2899SCharles.Forsyth FT_FRAME_ULONG_LE( size ), 82*37da2899SCharles.Forsyth FT_FRAME_ULONG_LE( offset ), 83*37da2899SCharles.Forsyth FT_FRAME_END 84*37da2899SCharles.Forsyth }; 85*37da2899SCharles.Forsyth 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth static FT_Error pcf_read_TOC(FT_Stream stream,PCF_Face face)88*37da2899SCharles.Forsyth pcf_read_TOC( FT_Stream stream, 89*37da2899SCharles.Forsyth PCF_Face face ) 90*37da2899SCharles.Forsyth { 91*37da2899SCharles.Forsyth FT_Error error; 92*37da2899SCharles.Forsyth PCF_Toc toc = &face->toc; 93*37da2899SCharles.Forsyth PCF_Table tables; 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE(face)->memory; 96*37da2899SCharles.Forsyth FT_UInt n; 97*37da2899SCharles.Forsyth 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK ( 0 ) || 100*37da2899SCharles.Forsyth FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) 101*37da2899SCharles.Forsyth return PCF_Err_Cannot_Open_Resource; 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth if ( toc->version != PCF_FILE_VERSION ) 104*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 105*37da2899SCharles.Forsyth 106*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) 107*37da2899SCharles.Forsyth return PCF_Err_Out_Of_Memory; 108*37da2899SCharles.Forsyth 109*37da2899SCharles.Forsyth tables = face->toc.tables; 110*37da2899SCharles.Forsyth for ( n = 0; n < toc->count; n++ ) 111*37da2899SCharles.Forsyth { 112*37da2899SCharles.Forsyth if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) ) 113*37da2899SCharles.Forsyth goto Exit; 114*37da2899SCharles.Forsyth tables++; 115*37da2899SCharles.Forsyth } 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth #if defined( FT_DEBUG_LEVEL_TRACE ) 118*37da2899SCharles.Forsyth 119*37da2899SCharles.Forsyth { 120*37da2899SCharles.Forsyth FT_UInt i, j; 121*37da2899SCharles.Forsyth const char* name = "?"; 122*37da2899SCharles.Forsyth 123*37da2899SCharles.Forsyth 124*37da2899SCharles.Forsyth FT_TRACE4(( "Tables count: %ld\n", face->toc.count )); 125*37da2899SCharles.Forsyth tables = face->toc.tables; 126*37da2899SCharles.Forsyth for ( i = 0; i < toc->count; i++ ) 127*37da2899SCharles.Forsyth { 128*37da2899SCharles.Forsyth for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ ) 129*37da2899SCharles.Forsyth if ( tables[i].type == (FT_UInt)( 1 << j ) ) 130*37da2899SCharles.Forsyth name = tableNames[j]; 131*37da2899SCharles.Forsyth 132*37da2899SCharles.Forsyth FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX " 133*37da2899SCharles.Forsyth "size=0x%06lX (%8ld) offset=0x%04lX\n", 134*37da2899SCharles.Forsyth i, name, 135*37da2899SCharles.Forsyth tables[i].format, 136*37da2899SCharles.Forsyth tables[i].size, tables[i].size, 137*37da2899SCharles.Forsyth tables[i].offset )); 138*37da2899SCharles.Forsyth } 139*37da2899SCharles.Forsyth } 140*37da2899SCharles.Forsyth 141*37da2899SCharles.Forsyth #endif 142*37da2899SCharles.Forsyth 143*37da2899SCharles.Forsyth return PCF_Err_Ok; 144*37da2899SCharles.Forsyth 145*37da2899SCharles.Forsyth Exit: 146*37da2899SCharles.Forsyth FT_FREE( face->toc.tables ); 147*37da2899SCharles.Forsyth return error; 148*37da2899SCharles.Forsyth } 149*37da2899SCharles.Forsyth 150*37da2899SCharles.Forsyth 151*37da2899SCharles.Forsyth static 152*37da2899SCharles.Forsyth const FT_Frame_Field pcf_metric_header[] = 153*37da2899SCharles.Forsyth { 154*37da2899SCharles.Forsyth #undef FT_STRUCTURE 155*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_MetricRec 156*37da2899SCharles.Forsyth 157*37da2899SCharles.Forsyth FT_FRAME_START( 12 ), 158*37da2899SCharles.Forsyth FT_FRAME_SHORT_LE( leftSideBearing ), 159*37da2899SCharles.Forsyth FT_FRAME_SHORT_LE( rightSideBearing ), 160*37da2899SCharles.Forsyth FT_FRAME_SHORT_LE( characterWidth ), 161*37da2899SCharles.Forsyth FT_FRAME_SHORT_LE( ascent ), 162*37da2899SCharles.Forsyth FT_FRAME_SHORT_LE( descent ), 163*37da2899SCharles.Forsyth FT_FRAME_SHORT_LE( attributes ), 164*37da2899SCharles.Forsyth FT_FRAME_END 165*37da2899SCharles.Forsyth }; 166*37da2899SCharles.Forsyth 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth static 169*37da2899SCharles.Forsyth const FT_Frame_Field pcf_metric_msb_header[] = 170*37da2899SCharles.Forsyth { 171*37da2899SCharles.Forsyth #undef FT_STRUCTURE 172*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_MetricRec 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth FT_FRAME_START( 12 ), 175*37da2899SCharles.Forsyth FT_FRAME_SHORT( leftSideBearing ), 176*37da2899SCharles.Forsyth FT_FRAME_SHORT( rightSideBearing ), 177*37da2899SCharles.Forsyth FT_FRAME_SHORT( characterWidth ), 178*37da2899SCharles.Forsyth FT_FRAME_SHORT( ascent ), 179*37da2899SCharles.Forsyth FT_FRAME_SHORT( descent ), 180*37da2899SCharles.Forsyth FT_FRAME_SHORT( attributes ), 181*37da2899SCharles.Forsyth FT_FRAME_END 182*37da2899SCharles.Forsyth }; 183*37da2899SCharles.Forsyth 184*37da2899SCharles.Forsyth 185*37da2899SCharles.Forsyth static 186*37da2899SCharles.Forsyth const FT_Frame_Field pcf_compressed_metric_header[] = 187*37da2899SCharles.Forsyth { 188*37da2899SCharles.Forsyth #undef FT_STRUCTURE 189*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_Compressed_MetricRec 190*37da2899SCharles.Forsyth 191*37da2899SCharles.Forsyth FT_FRAME_START( 5 ), 192*37da2899SCharles.Forsyth FT_FRAME_BYTE( leftSideBearing ), 193*37da2899SCharles.Forsyth FT_FRAME_BYTE( rightSideBearing ), 194*37da2899SCharles.Forsyth FT_FRAME_BYTE( characterWidth ), 195*37da2899SCharles.Forsyth FT_FRAME_BYTE( ascent ), 196*37da2899SCharles.Forsyth FT_FRAME_BYTE( descent ), 197*37da2899SCharles.Forsyth FT_FRAME_END 198*37da2899SCharles.Forsyth }; 199*37da2899SCharles.Forsyth 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsyth static FT_Error pcf_get_metric(FT_Stream stream,FT_ULong format,PCF_Metric metric)202*37da2899SCharles.Forsyth pcf_get_metric( FT_Stream stream, 203*37da2899SCharles.Forsyth FT_ULong format, 204*37da2899SCharles.Forsyth PCF_Metric metric ) 205*37da2899SCharles.Forsyth { 206*37da2899SCharles.Forsyth FT_Error error = PCF_Err_Ok; 207*37da2899SCharles.Forsyth 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsyth if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) 210*37da2899SCharles.Forsyth { 211*37da2899SCharles.Forsyth const FT_Frame_Field* fields; 212*37da2899SCharles.Forsyth 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsyth /* parsing normal metrics */ 215*37da2899SCharles.Forsyth fields = PCF_BYTE_ORDER( format ) == MSBFirst 216*37da2899SCharles.Forsyth ? pcf_metric_msb_header 217*37da2899SCharles.Forsyth : pcf_metric_header; 218*37da2899SCharles.Forsyth 219*37da2899SCharles.Forsyth /* the following sets 'error' but doesn't return in case of failure */ 220*37da2899SCharles.Forsyth (void)FT_STREAM_READ_FIELDS( fields, metric ); 221*37da2899SCharles.Forsyth } 222*37da2899SCharles.Forsyth else 223*37da2899SCharles.Forsyth { 224*37da2899SCharles.Forsyth PCF_Compressed_MetricRec compr; 225*37da2899SCharles.Forsyth 226*37da2899SCharles.Forsyth 227*37da2899SCharles.Forsyth /* parsing compressed metrics */ 228*37da2899SCharles.Forsyth if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) ) 229*37da2899SCharles.Forsyth goto Exit; 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 ); 232*37da2899SCharles.Forsyth metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 ); 233*37da2899SCharles.Forsyth metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 ); 234*37da2899SCharles.Forsyth metric->ascent = (FT_Short)( compr.ascent - 0x80 ); 235*37da2899SCharles.Forsyth metric->descent = (FT_Short)( compr.descent - 0x80 ); 236*37da2899SCharles.Forsyth metric->attributes = 0; 237*37da2899SCharles.Forsyth } 238*37da2899SCharles.Forsyth 239*37da2899SCharles.Forsyth Exit: 240*37da2899SCharles.Forsyth return error; 241*37da2899SCharles.Forsyth } 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth 244*37da2899SCharles.Forsyth static FT_Error pcf_seek_to_table_type(FT_Stream stream,PCF_Table tables,FT_Int ntables,FT_ULong type,FT_ULong * aformat,FT_ULong * asize)245*37da2899SCharles.Forsyth pcf_seek_to_table_type( FT_Stream stream, 246*37da2899SCharles.Forsyth PCF_Table tables, 247*37da2899SCharles.Forsyth FT_Int ntables, 248*37da2899SCharles.Forsyth FT_ULong type, 249*37da2899SCharles.Forsyth FT_ULong *aformat, 250*37da2899SCharles.Forsyth FT_ULong *asize ) 251*37da2899SCharles.Forsyth { 252*37da2899SCharles.Forsyth FT_Error error = 0; 253*37da2899SCharles.Forsyth FT_Int i; 254*37da2899SCharles.Forsyth 255*37da2899SCharles.Forsyth 256*37da2899SCharles.Forsyth for ( i = 0; i < ntables; i++ ) 257*37da2899SCharles.Forsyth if ( tables[i].type == type ) 258*37da2899SCharles.Forsyth { 259*37da2899SCharles.Forsyth if ( stream->pos > tables[i].offset ) 260*37da2899SCharles.Forsyth return PCF_Err_Invalid_Stream_Skip; 261*37da2899SCharles.Forsyth 262*37da2899SCharles.Forsyth if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) 263*37da2899SCharles.Forsyth return PCF_Err_Invalid_Stream_Skip; 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth *asize = tables[i].size; /* unused - to be removed */ 266*37da2899SCharles.Forsyth *aformat = tables[i].format; 267*37da2899SCharles.Forsyth 268*37da2899SCharles.Forsyth return PCF_Err_Ok; 269*37da2899SCharles.Forsyth } 270*37da2899SCharles.Forsyth 271*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 272*37da2899SCharles.Forsyth } 273*37da2899SCharles.Forsyth 274*37da2899SCharles.Forsyth 275*37da2899SCharles.Forsyth static FT_Bool pcf_has_table_type(PCF_Table tables,FT_Int ntables,FT_ULong type)276*37da2899SCharles.Forsyth pcf_has_table_type( PCF_Table tables, 277*37da2899SCharles.Forsyth FT_Int ntables, 278*37da2899SCharles.Forsyth FT_ULong type ) 279*37da2899SCharles.Forsyth { 280*37da2899SCharles.Forsyth FT_Int i; 281*37da2899SCharles.Forsyth 282*37da2899SCharles.Forsyth 283*37da2899SCharles.Forsyth for ( i = 0; i < ntables; i++ ) 284*37da2899SCharles.Forsyth if ( tables[i].type == type ) 285*37da2899SCharles.Forsyth return TRUE; 286*37da2899SCharles.Forsyth 287*37da2899SCharles.Forsyth return FALSE; 288*37da2899SCharles.Forsyth } 289*37da2899SCharles.Forsyth 290*37da2899SCharles.Forsyth 291*37da2899SCharles.Forsyth static 292*37da2899SCharles.Forsyth const FT_Frame_Field pcf_property_header[] = 293*37da2899SCharles.Forsyth { 294*37da2899SCharles.Forsyth #undef FT_STRUCTURE 295*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_ParsePropertyRec 296*37da2899SCharles.Forsyth 297*37da2899SCharles.Forsyth FT_FRAME_START( 9 ), 298*37da2899SCharles.Forsyth FT_FRAME_LONG_LE( name ), 299*37da2899SCharles.Forsyth FT_FRAME_BYTE ( isString ), 300*37da2899SCharles.Forsyth FT_FRAME_LONG_LE( value ), 301*37da2899SCharles.Forsyth FT_FRAME_END 302*37da2899SCharles.Forsyth }; 303*37da2899SCharles.Forsyth 304*37da2899SCharles.Forsyth 305*37da2899SCharles.Forsyth static 306*37da2899SCharles.Forsyth const FT_Frame_Field pcf_property_msb_header[] = 307*37da2899SCharles.Forsyth { 308*37da2899SCharles.Forsyth #undef FT_STRUCTURE 309*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_ParsePropertyRec 310*37da2899SCharles.Forsyth 311*37da2899SCharles.Forsyth FT_FRAME_START( 9 ), 312*37da2899SCharles.Forsyth FT_FRAME_LONG( name ), 313*37da2899SCharles.Forsyth FT_FRAME_BYTE( isString ), 314*37da2899SCharles.Forsyth FT_FRAME_LONG( value ), 315*37da2899SCharles.Forsyth FT_FRAME_END 316*37da2899SCharles.Forsyth }; 317*37da2899SCharles.Forsyth 318*37da2899SCharles.Forsyth 319*37da2899SCharles.Forsyth static PCF_Property pcf_find_property(PCF_Face face,const FT_String * prop)320*37da2899SCharles.Forsyth pcf_find_property( PCF_Face face, 321*37da2899SCharles.Forsyth const FT_String* prop ) 322*37da2899SCharles.Forsyth { 323*37da2899SCharles.Forsyth PCF_Property properties = face->properties; 324*37da2899SCharles.Forsyth FT_Bool found = 0; 325*37da2899SCharles.Forsyth int i; 326*37da2899SCharles.Forsyth 327*37da2899SCharles.Forsyth 328*37da2899SCharles.Forsyth for ( i = 0 ; i < face->nprops && !found; i++ ) 329*37da2899SCharles.Forsyth { 330*37da2899SCharles.Forsyth if ( !ft_strcmp( properties[i].name, prop ) ) 331*37da2899SCharles.Forsyth found = 1; 332*37da2899SCharles.Forsyth } 333*37da2899SCharles.Forsyth 334*37da2899SCharles.Forsyth if ( found ) 335*37da2899SCharles.Forsyth return properties + i - 1; 336*37da2899SCharles.Forsyth else 337*37da2899SCharles.Forsyth return NULL; 338*37da2899SCharles.Forsyth } 339*37da2899SCharles.Forsyth 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth static FT_Error pcf_get_properties(FT_Stream stream,PCF_Face face)342*37da2899SCharles.Forsyth pcf_get_properties( FT_Stream stream, 343*37da2899SCharles.Forsyth PCF_Face face ) 344*37da2899SCharles.Forsyth { 345*37da2899SCharles.Forsyth PCF_ParseProperty props = 0; 346*37da2899SCharles.Forsyth PCF_Property properties = 0; 347*37da2899SCharles.Forsyth FT_Int nprops, i; 348*37da2899SCharles.Forsyth FT_ULong format, size; 349*37da2899SCharles.Forsyth FT_Error error; 350*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE(face)->memory; 351*37da2899SCharles.Forsyth FT_ULong string_size; 352*37da2899SCharles.Forsyth FT_String* strings = 0; 353*37da2899SCharles.Forsyth 354*37da2899SCharles.Forsyth 355*37da2899SCharles.Forsyth error = pcf_seek_to_table_type( stream, 356*37da2899SCharles.Forsyth face->toc.tables, 357*37da2899SCharles.Forsyth face->toc.count, 358*37da2899SCharles.Forsyth PCF_PROPERTIES, 359*37da2899SCharles.Forsyth &format, 360*37da2899SCharles.Forsyth &size ); 361*37da2899SCharles.Forsyth if ( error ) 362*37da2899SCharles.Forsyth goto Bail; 363*37da2899SCharles.Forsyth 364*37da2899SCharles.Forsyth if ( FT_READ_ULONG_LE( format ) ) 365*37da2899SCharles.Forsyth goto Bail; 366*37da2899SCharles.Forsyth 367*37da2899SCharles.Forsyth FT_TRACE4(( "get_prop: format = %ld\n", format )); 368*37da2899SCharles.Forsyth 369*37da2899SCharles.Forsyth if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) 370*37da2899SCharles.Forsyth goto Bail; 371*37da2899SCharles.Forsyth 372*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 373*37da2899SCharles.Forsyth (void)FT_READ_ULONG( nprops ); 374*37da2899SCharles.Forsyth else 375*37da2899SCharles.Forsyth (void)FT_READ_ULONG_LE( nprops ); 376*37da2899SCharles.Forsyth if ( error ) 377*37da2899SCharles.Forsyth goto Bail; 378*37da2899SCharles.Forsyth 379*37da2899SCharles.Forsyth FT_TRACE4(( "get_prop: nprop = %d\n", nprops )); 380*37da2899SCharles.Forsyth 381*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( props, nprops ) ) 382*37da2899SCharles.Forsyth goto Bail; 383*37da2899SCharles.Forsyth 384*37da2899SCharles.Forsyth for ( i = 0; i < nprops; i++ ) 385*37da2899SCharles.Forsyth { 386*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 387*37da2899SCharles.Forsyth { 388*37da2899SCharles.Forsyth if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) ) 389*37da2899SCharles.Forsyth goto Bail; 390*37da2899SCharles.Forsyth } 391*37da2899SCharles.Forsyth else 392*37da2899SCharles.Forsyth { 393*37da2899SCharles.Forsyth if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) ) 394*37da2899SCharles.Forsyth goto Bail; 395*37da2899SCharles.Forsyth } 396*37da2899SCharles.Forsyth } 397*37da2899SCharles.Forsyth 398*37da2899SCharles.Forsyth /* pad the property array */ 399*37da2899SCharles.Forsyth /* */ 400*37da2899SCharles.Forsyth /* clever here - nprops is the same as the number of odd-units read, */ 401*37da2899SCharles.Forsyth /* as only isStringProp are odd length (Keith Packard) */ 402*37da2899SCharles.Forsyth /* */ 403*37da2899SCharles.Forsyth if ( nprops & 3 ) 404*37da2899SCharles.Forsyth { 405*37da2899SCharles.Forsyth i = 4 - ( nprops & 3 ); 406*37da2899SCharles.Forsyth FT_Stream_Skip( stream, i ); 407*37da2899SCharles.Forsyth } 408*37da2899SCharles.Forsyth 409*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 410*37da2899SCharles.Forsyth (void)FT_READ_ULONG( string_size ); 411*37da2899SCharles.Forsyth else 412*37da2899SCharles.Forsyth (void)FT_READ_ULONG_LE( string_size ); 413*37da2899SCharles.Forsyth if ( error ) 414*37da2899SCharles.Forsyth goto Bail; 415*37da2899SCharles.Forsyth 416*37da2899SCharles.Forsyth FT_TRACE4(( "get_prop: string_size = %ld\n", string_size )); 417*37da2899SCharles.Forsyth 418*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( strings, string_size ) ) 419*37da2899SCharles.Forsyth goto Bail; 420*37da2899SCharles.Forsyth 421*37da2899SCharles.Forsyth error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); 422*37da2899SCharles.Forsyth if ( error ) 423*37da2899SCharles.Forsyth goto Bail; 424*37da2899SCharles.Forsyth 425*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( properties, nprops ) ) 426*37da2899SCharles.Forsyth goto Bail; 427*37da2899SCharles.Forsyth 428*37da2899SCharles.Forsyth for ( i = 0; i < nprops; i++ ) 429*37da2899SCharles.Forsyth { 430*37da2899SCharles.Forsyth /* XXX: make atom */ 431*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( properties[i].name, 432*37da2899SCharles.Forsyth ft_strlen( strings + props[i].name ) + 1 ) ) 433*37da2899SCharles.Forsyth goto Bail; 434*37da2899SCharles.Forsyth ft_strcpy( properties[i].name,strings + props[i].name ); 435*37da2899SCharles.Forsyth 436*37da2899SCharles.Forsyth properties[i].isString = props[i].isString; 437*37da2899SCharles.Forsyth 438*37da2899SCharles.Forsyth if ( props[i].isString ) 439*37da2899SCharles.Forsyth { 440*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( properties[i].value.atom, 441*37da2899SCharles.Forsyth ft_strlen( strings + props[i].value ) + 1 ) ) 442*37da2899SCharles.Forsyth goto Bail; 443*37da2899SCharles.Forsyth ft_strcpy( properties[i].value.atom, strings + props[i].value ); 444*37da2899SCharles.Forsyth } 445*37da2899SCharles.Forsyth else 446*37da2899SCharles.Forsyth properties[i].value.integer = props[i].value; 447*37da2899SCharles.Forsyth } 448*37da2899SCharles.Forsyth 449*37da2899SCharles.Forsyth face->properties = properties; 450*37da2899SCharles.Forsyth face->nprops = nprops; 451*37da2899SCharles.Forsyth 452*37da2899SCharles.Forsyth FT_FREE( props ); 453*37da2899SCharles.Forsyth FT_FREE( strings ); 454*37da2899SCharles.Forsyth 455*37da2899SCharles.Forsyth return PCF_Err_Ok; 456*37da2899SCharles.Forsyth 457*37da2899SCharles.Forsyth Bail: 458*37da2899SCharles.Forsyth FT_FREE( props ); 459*37da2899SCharles.Forsyth FT_FREE( strings ); 460*37da2899SCharles.Forsyth 461*37da2899SCharles.Forsyth return error; 462*37da2899SCharles.Forsyth } 463*37da2899SCharles.Forsyth 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth static FT_Error pcf_get_metrics(FT_Stream stream,PCF_Face face)466*37da2899SCharles.Forsyth pcf_get_metrics( FT_Stream stream, 467*37da2899SCharles.Forsyth PCF_Face face ) 468*37da2899SCharles.Forsyth { 469*37da2899SCharles.Forsyth FT_Error error = PCF_Err_Ok; 470*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE(face)->memory; 471*37da2899SCharles.Forsyth FT_ULong format = 0; 472*37da2899SCharles.Forsyth FT_ULong size = 0; 473*37da2899SCharles.Forsyth PCF_Metric metrics = 0; 474*37da2899SCharles.Forsyth int i; 475*37da2899SCharles.Forsyth int nmetrics = -1; 476*37da2899SCharles.Forsyth 477*37da2899SCharles.Forsyth 478*37da2899SCharles.Forsyth error = pcf_seek_to_table_type( stream, 479*37da2899SCharles.Forsyth face->toc.tables, 480*37da2899SCharles.Forsyth face->toc.count, 481*37da2899SCharles.Forsyth PCF_METRICS, 482*37da2899SCharles.Forsyth &format, 483*37da2899SCharles.Forsyth &size ); 484*37da2899SCharles.Forsyth if ( error ) 485*37da2899SCharles.Forsyth return error; 486*37da2899SCharles.Forsyth 487*37da2899SCharles.Forsyth error = FT_READ_ULONG_LE( format ); 488*37da2899SCharles.Forsyth 489*37da2899SCharles.Forsyth if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && 490*37da2899SCharles.Forsyth !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) 491*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 492*37da2899SCharles.Forsyth 493*37da2899SCharles.Forsyth if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) 494*37da2899SCharles.Forsyth { 495*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 496*37da2899SCharles.Forsyth (void)FT_READ_ULONG( nmetrics ); 497*37da2899SCharles.Forsyth else 498*37da2899SCharles.Forsyth (void)FT_READ_ULONG_LE( nmetrics ); 499*37da2899SCharles.Forsyth } 500*37da2899SCharles.Forsyth else 501*37da2899SCharles.Forsyth { 502*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 503*37da2899SCharles.Forsyth (void)FT_READ_USHORT( nmetrics ); 504*37da2899SCharles.Forsyth else 505*37da2899SCharles.Forsyth (void)FT_READ_USHORT_LE( nmetrics ); 506*37da2899SCharles.Forsyth } 507*37da2899SCharles.Forsyth if ( error || nmetrics == -1 ) 508*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 509*37da2899SCharles.Forsyth 510*37da2899SCharles.Forsyth face->nmetrics = nmetrics; 511*37da2899SCharles.Forsyth 512*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) 513*37da2899SCharles.Forsyth return PCF_Err_Out_Of_Memory; 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth metrics = face->metrics; 516*37da2899SCharles.Forsyth for ( i = 0; i < nmetrics; i++ ) 517*37da2899SCharles.Forsyth { 518*37da2899SCharles.Forsyth pcf_get_metric( stream, format, metrics + i ); 519*37da2899SCharles.Forsyth 520*37da2899SCharles.Forsyth metrics[i].bits = 0; 521*37da2899SCharles.Forsyth 522*37da2899SCharles.Forsyth FT_TRACE4(( "%d : width=%d, " 523*37da2899SCharles.Forsyth "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", 524*37da2899SCharles.Forsyth i, 525*37da2899SCharles.Forsyth ( metrics + i )->characterWidth, 526*37da2899SCharles.Forsyth ( metrics + i )->leftSideBearing, 527*37da2899SCharles.Forsyth ( metrics + i )->rightSideBearing, 528*37da2899SCharles.Forsyth ( metrics + i )->ascent, 529*37da2899SCharles.Forsyth ( metrics + i )->descent, 530*37da2899SCharles.Forsyth ( metrics + i )->attributes )); 531*37da2899SCharles.Forsyth 532*37da2899SCharles.Forsyth if ( error ) 533*37da2899SCharles.Forsyth break; 534*37da2899SCharles.Forsyth } 535*37da2899SCharles.Forsyth 536*37da2899SCharles.Forsyth if ( error ) 537*37da2899SCharles.Forsyth FT_FREE( face->metrics ); 538*37da2899SCharles.Forsyth return error; 539*37da2899SCharles.Forsyth } 540*37da2899SCharles.Forsyth 541*37da2899SCharles.Forsyth 542*37da2899SCharles.Forsyth static FT_Error pcf_get_bitmaps(FT_Stream stream,PCF_Face face)543*37da2899SCharles.Forsyth pcf_get_bitmaps( FT_Stream stream, 544*37da2899SCharles.Forsyth PCF_Face face ) 545*37da2899SCharles.Forsyth { 546*37da2899SCharles.Forsyth FT_Error error = PCF_Err_Ok; 547*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE(face)->memory; 548*37da2899SCharles.Forsyth FT_Long* offsets; 549*37da2899SCharles.Forsyth FT_Long bitmapSizes[GLYPHPADOPTIONS]; 550*37da2899SCharles.Forsyth FT_ULong format, size; 551*37da2899SCharles.Forsyth int nbitmaps, i, sizebitmaps = 0; 552*37da2899SCharles.Forsyth char* bitmaps; 553*37da2899SCharles.Forsyth 554*37da2899SCharles.Forsyth 555*37da2899SCharles.Forsyth error = pcf_seek_to_table_type( stream, 556*37da2899SCharles.Forsyth face->toc.tables, 557*37da2899SCharles.Forsyth face->toc.count, 558*37da2899SCharles.Forsyth PCF_BITMAPS, 559*37da2899SCharles.Forsyth &format, 560*37da2899SCharles.Forsyth &size ); 561*37da2899SCharles.Forsyth if ( error ) 562*37da2899SCharles.Forsyth return error; 563*37da2899SCharles.Forsyth 564*37da2899SCharles.Forsyth error = FT_Stream_EnterFrame( stream, 8 ); 565*37da2899SCharles.Forsyth if ( error ) 566*37da2899SCharles.Forsyth return error; 567*37da2899SCharles.Forsyth 568*37da2899SCharles.Forsyth format = FT_GET_ULONG_LE(); 569*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 570*37da2899SCharles.Forsyth nbitmaps = FT_GET_ULONG(); 571*37da2899SCharles.Forsyth else 572*37da2899SCharles.Forsyth nbitmaps = FT_GET_ULONG_LE(); 573*37da2899SCharles.Forsyth 574*37da2899SCharles.Forsyth FT_Stream_ExitFrame( stream ); 575*37da2899SCharles.Forsyth 576*37da2899SCharles.Forsyth if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) 577*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 578*37da2899SCharles.Forsyth 579*37da2899SCharles.Forsyth if ( nbitmaps != face->nmetrics ) 580*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 581*37da2899SCharles.Forsyth 582*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) 583*37da2899SCharles.Forsyth return error; 584*37da2899SCharles.Forsyth 585*37da2899SCharles.Forsyth for ( i = 0; i < nbitmaps; i++ ) 586*37da2899SCharles.Forsyth { 587*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 588*37da2899SCharles.Forsyth (void)FT_READ_LONG( offsets[i] ); 589*37da2899SCharles.Forsyth else 590*37da2899SCharles.Forsyth (void)FT_READ_LONG_LE( offsets[i] ); 591*37da2899SCharles.Forsyth 592*37da2899SCharles.Forsyth FT_TRACE4(( "bitmap %d is at offset %ld\n", i, offsets[i] )); 593*37da2899SCharles.Forsyth } 594*37da2899SCharles.Forsyth if ( error ) 595*37da2899SCharles.Forsyth goto Bail; 596*37da2899SCharles.Forsyth 597*37da2899SCharles.Forsyth for ( i = 0; i < GLYPHPADOPTIONS; i++ ) 598*37da2899SCharles.Forsyth { 599*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 600*37da2899SCharles.Forsyth (void)FT_READ_LONG( bitmapSizes[i] ); 601*37da2899SCharles.Forsyth else 602*37da2899SCharles.Forsyth (void)FT_READ_LONG_LE( bitmapSizes[i] ); 603*37da2899SCharles.Forsyth if ( error ) 604*37da2899SCharles.Forsyth goto Bail; 605*37da2899SCharles.Forsyth 606*37da2899SCharles.Forsyth sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; 607*37da2899SCharles.Forsyth 608*37da2899SCharles.Forsyth FT_TRACE4(( "padding %d implies a size of %ld\n", i, bitmapSizes[i] )); 609*37da2899SCharles.Forsyth } 610*37da2899SCharles.Forsyth 611*37da2899SCharles.Forsyth FT_TRACE4(( " %d bitmaps, padding index %ld\n", 612*37da2899SCharles.Forsyth nbitmaps, 613*37da2899SCharles.Forsyth PCF_GLYPH_PAD_INDEX( format ) )); 614*37da2899SCharles.Forsyth FT_TRACE4(( "bitmap size = %d\n", sizebitmaps )); 615*37da2899SCharles.Forsyth 616*37da2899SCharles.Forsyth FT_UNUSED( sizebitmaps ); /* only used for debugging */ 617*37da2899SCharles.Forsyth 618*37da2899SCharles.Forsyth for ( i = 0; i < nbitmaps; i++ ) 619*37da2899SCharles.Forsyth face->metrics[i].bits = stream->pos + offsets[i]; 620*37da2899SCharles.Forsyth 621*37da2899SCharles.Forsyth face->bitmapsFormat = format; 622*37da2899SCharles.Forsyth 623*37da2899SCharles.Forsyth FT_FREE ( offsets ); 624*37da2899SCharles.Forsyth return error; 625*37da2899SCharles.Forsyth 626*37da2899SCharles.Forsyth Bail: 627*37da2899SCharles.Forsyth FT_FREE ( offsets ); 628*37da2899SCharles.Forsyth FT_FREE ( bitmaps ); 629*37da2899SCharles.Forsyth return error; 630*37da2899SCharles.Forsyth } 631*37da2899SCharles.Forsyth 632*37da2899SCharles.Forsyth 633*37da2899SCharles.Forsyth static FT_Error pcf_get_encodings(FT_Stream stream,PCF_Face face)634*37da2899SCharles.Forsyth pcf_get_encodings( FT_Stream stream, 635*37da2899SCharles.Forsyth PCF_Face face ) 636*37da2899SCharles.Forsyth { 637*37da2899SCharles.Forsyth FT_Error error = PCF_Err_Ok; 638*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE(face)->memory; 639*37da2899SCharles.Forsyth FT_ULong format, size; 640*37da2899SCharles.Forsyth int firstCol, lastCol; 641*37da2899SCharles.Forsyth int firstRow, lastRow; 642*37da2899SCharles.Forsyth int nencoding, encodingOffset; 643*37da2899SCharles.Forsyth int i, j; 644*37da2899SCharles.Forsyth PCF_Encoding tmpEncoding, encoding = 0; 645*37da2899SCharles.Forsyth 646*37da2899SCharles.Forsyth 647*37da2899SCharles.Forsyth error = pcf_seek_to_table_type( stream, 648*37da2899SCharles.Forsyth face->toc.tables, 649*37da2899SCharles.Forsyth face->toc.count, 650*37da2899SCharles.Forsyth PCF_BDF_ENCODINGS, 651*37da2899SCharles.Forsyth &format, 652*37da2899SCharles.Forsyth &size ); 653*37da2899SCharles.Forsyth if ( error ) 654*37da2899SCharles.Forsyth return error; 655*37da2899SCharles.Forsyth 656*37da2899SCharles.Forsyth error = FT_Stream_EnterFrame( stream, 14 ); 657*37da2899SCharles.Forsyth if ( error ) 658*37da2899SCharles.Forsyth return error; 659*37da2899SCharles.Forsyth 660*37da2899SCharles.Forsyth format = FT_GET_ULONG_LE(); 661*37da2899SCharles.Forsyth 662*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 663*37da2899SCharles.Forsyth { 664*37da2899SCharles.Forsyth firstCol = FT_GET_SHORT(); 665*37da2899SCharles.Forsyth lastCol = FT_GET_SHORT(); 666*37da2899SCharles.Forsyth firstRow = FT_GET_SHORT(); 667*37da2899SCharles.Forsyth lastRow = FT_GET_SHORT(); 668*37da2899SCharles.Forsyth face->defaultChar = FT_GET_SHORT(); 669*37da2899SCharles.Forsyth } 670*37da2899SCharles.Forsyth else 671*37da2899SCharles.Forsyth { 672*37da2899SCharles.Forsyth firstCol = FT_GET_SHORT_LE(); 673*37da2899SCharles.Forsyth lastCol = FT_GET_SHORT_LE(); 674*37da2899SCharles.Forsyth firstRow = FT_GET_SHORT_LE(); 675*37da2899SCharles.Forsyth lastRow = FT_GET_SHORT_LE(); 676*37da2899SCharles.Forsyth face->defaultChar = FT_GET_SHORT_LE(); 677*37da2899SCharles.Forsyth } 678*37da2899SCharles.Forsyth 679*37da2899SCharles.Forsyth FT_Stream_ExitFrame( stream ); 680*37da2899SCharles.Forsyth 681*37da2899SCharles.Forsyth if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) 682*37da2899SCharles.Forsyth return PCF_Err_Invalid_File_Format; 683*37da2899SCharles.Forsyth 684*37da2899SCharles.Forsyth FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", 685*37da2899SCharles.Forsyth firstCol, lastCol, firstRow, lastRow )); 686*37da2899SCharles.Forsyth 687*37da2899SCharles.Forsyth nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); 688*37da2899SCharles.Forsyth 689*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( tmpEncoding, nencoding ) ) 690*37da2899SCharles.Forsyth return PCF_Err_Out_Of_Memory; 691*37da2899SCharles.Forsyth 692*37da2899SCharles.Forsyth error = FT_Stream_EnterFrame( stream, 2 * nencoding ); 693*37da2899SCharles.Forsyth if ( error ) 694*37da2899SCharles.Forsyth goto Bail; 695*37da2899SCharles.Forsyth 696*37da2899SCharles.Forsyth for ( i = 0, j = 0 ; i < nencoding; i++ ) 697*37da2899SCharles.Forsyth { 698*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 699*37da2899SCharles.Forsyth encodingOffset = FT_GET_SHORT(); 700*37da2899SCharles.Forsyth else 701*37da2899SCharles.Forsyth encodingOffset = FT_GET_SHORT_LE(); 702*37da2899SCharles.Forsyth 703*37da2899SCharles.Forsyth if ( encodingOffset != -1 ) 704*37da2899SCharles.Forsyth { 705*37da2899SCharles.Forsyth tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) + 706*37da2899SCharles.Forsyth firstRow ) * 256 ) + 707*37da2899SCharles.Forsyth ( ( i % ( lastCol - firstCol + 1 ) ) + 708*37da2899SCharles.Forsyth firstCol ); 709*37da2899SCharles.Forsyth 710*37da2899SCharles.Forsyth tmpEncoding[j].glyph = (FT_Short)encodingOffset; 711*37da2899SCharles.Forsyth j++; 712*37da2899SCharles.Forsyth } 713*37da2899SCharles.Forsyth 714*37da2899SCharles.Forsyth FT_TRACE4(( "enc n. %d ; Uni %ld ; Glyph %d\n", 715*37da2899SCharles.Forsyth i, tmpEncoding[j - 1].enc, encodingOffset )); 716*37da2899SCharles.Forsyth } 717*37da2899SCharles.Forsyth FT_Stream_ExitFrame( stream ); 718*37da2899SCharles.Forsyth 719*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( encoding, j ) ) 720*37da2899SCharles.Forsyth goto Bail; 721*37da2899SCharles.Forsyth 722*37da2899SCharles.Forsyth for ( i = 0; i < j; i++ ) 723*37da2899SCharles.Forsyth { 724*37da2899SCharles.Forsyth encoding[i].enc = tmpEncoding[i].enc; 725*37da2899SCharles.Forsyth encoding[i].glyph = tmpEncoding[i].glyph; 726*37da2899SCharles.Forsyth } 727*37da2899SCharles.Forsyth 728*37da2899SCharles.Forsyth face->nencodings = j; 729*37da2899SCharles.Forsyth face->encodings = encoding; 730*37da2899SCharles.Forsyth FT_FREE( tmpEncoding ); 731*37da2899SCharles.Forsyth 732*37da2899SCharles.Forsyth return error; 733*37da2899SCharles.Forsyth 734*37da2899SCharles.Forsyth Bail: 735*37da2899SCharles.Forsyth FT_FREE( encoding ); 736*37da2899SCharles.Forsyth FT_FREE( tmpEncoding ); 737*37da2899SCharles.Forsyth return error; 738*37da2899SCharles.Forsyth } 739*37da2899SCharles.Forsyth 740*37da2899SCharles.Forsyth 741*37da2899SCharles.Forsyth static 742*37da2899SCharles.Forsyth const FT_Frame_Field pcf_accel_header[] = 743*37da2899SCharles.Forsyth { 744*37da2899SCharles.Forsyth #undef FT_STRUCTURE 745*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_AccelRec 746*37da2899SCharles.Forsyth 747*37da2899SCharles.Forsyth FT_FRAME_START( 20 ), 748*37da2899SCharles.Forsyth FT_FRAME_BYTE ( noOverlap ), 749*37da2899SCharles.Forsyth FT_FRAME_BYTE ( constantMetrics ), 750*37da2899SCharles.Forsyth FT_FRAME_BYTE ( terminalFont ), 751*37da2899SCharles.Forsyth FT_FRAME_BYTE ( constantWidth ), 752*37da2899SCharles.Forsyth FT_FRAME_BYTE ( inkInside ), 753*37da2899SCharles.Forsyth FT_FRAME_BYTE ( inkMetrics ), 754*37da2899SCharles.Forsyth FT_FRAME_BYTE ( drawDirection ), 755*37da2899SCharles.Forsyth FT_FRAME_SKIP_BYTES( 1 ), 756*37da2899SCharles.Forsyth FT_FRAME_LONG_LE ( fontAscent ), 757*37da2899SCharles.Forsyth FT_FRAME_LONG_LE ( fontDescent ), 758*37da2899SCharles.Forsyth FT_FRAME_LONG_LE ( maxOverlap ), 759*37da2899SCharles.Forsyth FT_FRAME_END 760*37da2899SCharles.Forsyth }; 761*37da2899SCharles.Forsyth 762*37da2899SCharles.Forsyth 763*37da2899SCharles.Forsyth static 764*37da2899SCharles.Forsyth const FT_Frame_Field pcf_accel_msb_header[] = 765*37da2899SCharles.Forsyth { 766*37da2899SCharles.Forsyth #undef FT_STRUCTURE 767*37da2899SCharles.Forsyth #define FT_STRUCTURE PCF_AccelRec 768*37da2899SCharles.Forsyth 769*37da2899SCharles.Forsyth FT_FRAME_START( 20 ), 770*37da2899SCharles.Forsyth FT_FRAME_BYTE ( noOverlap ), 771*37da2899SCharles.Forsyth FT_FRAME_BYTE ( constantMetrics ), 772*37da2899SCharles.Forsyth FT_FRAME_BYTE ( terminalFont ), 773*37da2899SCharles.Forsyth FT_FRAME_BYTE ( constantWidth ), 774*37da2899SCharles.Forsyth FT_FRAME_BYTE ( inkInside ), 775*37da2899SCharles.Forsyth FT_FRAME_BYTE ( inkMetrics ), 776*37da2899SCharles.Forsyth FT_FRAME_BYTE ( drawDirection ), 777*37da2899SCharles.Forsyth FT_FRAME_SKIP_BYTES( 1 ), 778*37da2899SCharles.Forsyth FT_FRAME_LONG ( fontAscent ), 779*37da2899SCharles.Forsyth FT_FRAME_LONG ( fontDescent ), 780*37da2899SCharles.Forsyth FT_FRAME_LONG ( maxOverlap ), 781*37da2899SCharles.Forsyth FT_FRAME_END 782*37da2899SCharles.Forsyth }; 783*37da2899SCharles.Forsyth 784*37da2899SCharles.Forsyth 785*37da2899SCharles.Forsyth static FT_Error pcf_get_accel(FT_Stream stream,PCF_Face face,FT_ULong type)786*37da2899SCharles.Forsyth pcf_get_accel( FT_Stream stream, 787*37da2899SCharles.Forsyth PCF_Face face, 788*37da2899SCharles.Forsyth FT_ULong type ) 789*37da2899SCharles.Forsyth { 790*37da2899SCharles.Forsyth FT_ULong format, size; 791*37da2899SCharles.Forsyth FT_Error error = PCF_Err_Ok; 792*37da2899SCharles.Forsyth PCF_Accel accel = &face->accel; 793*37da2899SCharles.Forsyth 794*37da2899SCharles.Forsyth 795*37da2899SCharles.Forsyth error = pcf_seek_to_table_type( stream, 796*37da2899SCharles.Forsyth face->toc.tables, 797*37da2899SCharles.Forsyth face->toc.count, 798*37da2899SCharles.Forsyth type, 799*37da2899SCharles.Forsyth &format, 800*37da2899SCharles.Forsyth &size ); 801*37da2899SCharles.Forsyth if ( error ) 802*37da2899SCharles.Forsyth goto Bail; 803*37da2899SCharles.Forsyth 804*37da2899SCharles.Forsyth error = FT_READ_ULONG_LE( format ); 805*37da2899SCharles.Forsyth 806*37da2899SCharles.Forsyth if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && 807*37da2899SCharles.Forsyth !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) 808*37da2899SCharles.Forsyth goto Bail; 809*37da2899SCharles.Forsyth 810*37da2899SCharles.Forsyth if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 811*37da2899SCharles.Forsyth { 812*37da2899SCharles.Forsyth if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) ) 813*37da2899SCharles.Forsyth goto Bail; 814*37da2899SCharles.Forsyth } 815*37da2899SCharles.Forsyth else 816*37da2899SCharles.Forsyth { 817*37da2899SCharles.Forsyth if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) ) 818*37da2899SCharles.Forsyth goto Bail; 819*37da2899SCharles.Forsyth } 820*37da2899SCharles.Forsyth 821*37da2899SCharles.Forsyth error = pcf_get_metric( stream, 822*37da2899SCharles.Forsyth format & ( ~PCF_FORMAT_MASK ), 823*37da2899SCharles.Forsyth &(accel->minbounds) ); 824*37da2899SCharles.Forsyth if ( error ) 825*37da2899SCharles.Forsyth goto Bail; 826*37da2899SCharles.Forsyth 827*37da2899SCharles.Forsyth error = pcf_get_metric( stream, 828*37da2899SCharles.Forsyth format & ( ~PCF_FORMAT_MASK ), 829*37da2899SCharles.Forsyth &(accel->maxbounds) ); 830*37da2899SCharles.Forsyth if ( error ) 831*37da2899SCharles.Forsyth goto Bail; 832*37da2899SCharles.Forsyth 833*37da2899SCharles.Forsyth if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) 834*37da2899SCharles.Forsyth { 835*37da2899SCharles.Forsyth error = pcf_get_metric( stream, 836*37da2899SCharles.Forsyth format & ( ~PCF_FORMAT_MASK ), 837*37da2899SCharles.Forsyth &(accel->ink_minbounds) ); 838*37da2899SCharles.Forsyth if ( error ) 839*37da2899SCharles.Forsyth goto Bail; 840*37da2899SCharles.Forsyth 841*37da2899SCharles.Forsyth error = pcf_get_metric( stream, 842*37da2899SCharles.Forsyth format & ( ~PCF_FORMAT_MASK ), 843*37da2899SCharles.Forsyth &(accel->ink_maxbounds) ); 844*37da2899SCharles.Forsyth if ( error ) 845*37da2899SCharles.Forsyth goto Bail; 846*37da2899SCharles.Forsyth } 847*37da2899SCharles.Forsyth else 848*37da2899SCharles.Forsyth { 849*37da2899SCharles.Forsyth accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ 850*37da2899SCharles.Forsyth accel->ink_maxbounds = accel->maxbounds; 851*37da2899SCharles.Forsyth } 852*37da2899SCharles.Forsyth return error; 853*37da2899SCharles.Forsyth 854*37da2899SCharles.Forsyth Bail: 855*37da2899SCharles.Forsyth return error; 856*37da2899SCharles.Forsyth } 857*37da2899SCharles.Forsyth 858*37da2899SCharles.Forsyth 859*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pcf_load_font(FT_Stream stream,PCF_Face face)860*37da2899SCharles.Forsyth pcf_load_font( FT_Stream stream, 861*37da2899SCharles.Forsyth PCF_Face face ) 862*37da2899SCharles.Forsyth { 863*37da2899SCharles.Forsyth FT_Error error = PCF_Err_Ok; 864*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE(face)->memory; 865*37da2899SCharles.Forsyth FT_Bool hasBDFAccelerators; 866*37da2899SCharles.Forsyth 867*37da2899SCharles.Forsyth 868*37da2899SCharles.Forsyth error = pcf_read_TOC( stream, face ); 869*37da2899SCharles.Forsyth if ( error ) 870*37da2899SCharles.Forsyth goto Exit; 871*37da2899SCharles.Forsyth 872*37da2899SCharles.Forsyth error = pcf_get_properties( stream, face ); 873*37da2899SCharles.Forsyth if ( error ) 874*37da2899SCharles.Forsyth goto Exit; 875*37da2899SCharles.Forsyth 876*37da2899SCharles.Forsyth /* Use the old accelerators if no BDF accelerators are in the file. */ 877*37da2899SCharles.Forsyth hasBDFAccelerators = pcf_has_table_type( face->toc.tables, 878*37da2899SCharles.Forsyth face->toc.count, 879*37da2899SCharles.Forsyth PCF_BDF_ACCELERATORS ); 880*37da2899SCharles.Forsyth if ( !hasBDFAccelerators ) 881*37da2899SCharles.Forsyth { 882*37da2899SCharles.Forsyth error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); 883*37da2899SCharles.Forsyth if ( error ) 884*37da2899SCharles.Forsyth goto Exit; 885*37da2899SCharles.Forsyth } 886*37da2899SCharles.Forsyth 887*37da2899SCharles.Forsyth /* metrics */ 888*37da2899SCharles.Forsyth error = pcf_get_metrics( stream, face ); 889*37da2899SCharles.Forsyth if ( error ) 890*37da2899SCharles.Forsyth goto Exit; 891*37da2899SCharles.Forsyth 892*37da2899SCharles.Forsyth /* bitmaps */ 893*37da2899SCharles.Forsyth error = pcf_get_bitmaps( stream, face ); 894*37da2899SCharles.Forsyth if ( error ) 895*37da2899SCharles.Forsyth goto Exit; 896*37da2899SCharles.Forsyth 897*37da2899SCharles.Forsyth /* encodings */ 898*37da2899SCharles.Forsyth error = pcf_get_encodings( stream, face ); 899*37da2899SCharles.Forsyth if ( error ) 900*37da2899SCharles.Forsyth goto Exit; 901*37da2899SCharles.Forsyth 902*37da2899SCharles.Forsyth /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ 903*37da2899SCharles.Forsyth if ( hasBDFAccelerators ) 904*37da2899SCharles.Forsyth { 905*37da2899SCharles.Forsyth error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); 906*37da2899SCharles.Forsyth if ( error ) 907*37da2899SCharles.Forsyth goto Exit; 908*37da2899SCharles.Forsyth } 909*37da2899SCharles.Forsyth 910*37da2899SCharles.Forsyth /* XXX: TO DO: inkmetrics and glyph_names are missing */ 911*37da2899SCharles.Forsyth 912*37da2899SCharles.Forsyth /* now construct the face object */ 913*37da2899SCharles.Forsyth { 914*37da2899SCharles.Forsyth FT_Face root = FT_FACE( face ); 915*37da2899SCharles.Forsyth PCF_Property prop; 916*37da2899SCharles.Forsyth int size_set = 0; 917*37da2899SCharles.Forsyth 918*37da2899SCharles.Forsyth 919*37da2899SCharles.Forsyth root->num_faces = 1; 920*37da2899SCharles.Forsyth root->face_index = 0; 921*37da2899SCharles.Forsyth root->face_flags = FT_FACE_FLAG_FIXED_SIZES | 922*37da2899SCharles.Forsyth FT_FACE_FLAG_HORIZONTAL | 923*37da2899SCharles.Forsyth FT_FACE_FLAG_FAST_GLYPHS; 924*37da2899SCharles.Forsyth 925*37da2899SCharles.Forsyth if ( face->accel.constantWidth ) 926*37da2899SCharles.Forsyth root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; 927*37da2899SCharles.Forsyth 928*37da2899SCharles.Forsyth root->style_flags = 0; 929*37da2899SCharles.Forsyth prop = pcf_find_property( face, "SLANT" ); 930*37da2899SCharles.Forsyth if ( prop != NULL ) 931*37da2899SCharles.Forsyth if ( prop->isString ) 932*37da2899SCharles.Forsyth if ( ( *(prop->value.atom) == 'O' ) || 933*37da2899SCharles.Forsyth ( *(prop->value.atom) == 'I' ) ) 934*37da2899SCharles.Forsyth root->style_flags |= FT_STYLE_FLAG_ITALIC; 935*37da2899SCharles.Forsyth 936*37da2899SCharles.Forsyth prop = pcf_find_property( face, "WEIGHT_NAME" ); 937*37da2899SCharles.Forsyth if ( prop != NULL ) 938*37da2899SCharles.Forsyth if ( prop->isString ) 939*37da2899SCharles.Forsyth if ( *(prop->value.atom) == 'B' ) 940*37da2899SCharles.Forsyth root->style_flags |= FT_STYLE_FLAG_BOLD; 941*37da2899SCharles.Forsyth 942*37da2899SCharles.Forsyth root->style_name = (char *)"Regular"; 943*37da2899SCharles.Forsyth 944*37da2899SCharles.Forsyth if ( root->style_flags & FT_STYLE_FLAG_BOLD ) { 945*37da2899SCharles.Forsyth if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) 946*37da2899SCharles.Forsyth root->style_name = (char *)"Bold Italic"; 947*37da2899SCharles.Forsyth else 948*37da2899SCharles.Forsyth root->style_name = (char *)"Bold"; 949*37da2899SCharles.Forsyth } 950*37da2899SCharles.Forsyth else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) 951*37da2899SCharles.Forsyth root->style_name = (char *)"Italic"; 952*37da2899SCharles.Forsyth 953*37da2899SCharles.Forsyth prop = pcf_find_property( face, "FAMILY_NAME" ); 954*37da2899SCharles.Forsyth if ( prop != NULL ) 955*37da2899SCharles.Forsyth { 956*37da2899SCharles.Forsyth if ( prop->isString ) 957*37da2899SCharles.Forsyth { 958*37da2899SCharles.Forsyth int l = ft_strlen( prop->value.atom ) + 1; 959*37da2899SCharles.Forsyth 960*37da2899SCharles.Forsyth 961*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( root->family_name, l ) ) 962*37da2899SCharles.Forsyth goto Exit; 963*37da2899SCharles.Forsyth ft_strcpy( root->family_name, prop->value.atom ); 964*37da2899SCharles.Forsyth } 965*37da2899SCharles.Forsyth } 966*37da2899SCharles.Forsyth else 967*37da2899SCharles.Forsyth root->family_name = 0; 968*37da2899SCharles.Forsyth 969*37da2899SCharles.Forsyth root->num_glyphs = face->nmetrics; 970*37da2899SCharles.Forsyth 971*37da2899SCharles.Forsyth root->num_fixed_sizes = 1; 972*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) 973*37da2899SCharles.Forsyth goto Exit; 974*37da2899SCharles.Forsyth 975*37da2899SCharles.Forsyth prop = pcf_find_property( face, "PIXEL_SIZE" ); 976*37da2899SCharles.Forsyth if ( prop != NULL ) 977*37da2899SCharles.Forsyth { 978*37da2899SCharles.Forsyth root->available_sizes->height = 979*37da2899SCharles.Forsyth root->available_sizes->width = (FT_Short)( prop->value.integer ); 980*37da2899SCharles.Forsyth 981*37da2899SCharles.Forsyth size_set = 1; 982*37da2899SCharles.Forsyth } 983*37da2899SCharles.Forsyth else 984*37da2899SCharles.Forsyth { 985*37da2899SCharles.Forsyth prop = pcf_find_property( face, "POINT_SIZE" ); 986*37da2899SCharles.Forsyth if ( prop != NULL ) 987*37da2899SCharles.Forsyth { 988*37da2899SCharles.Forsyth PCF_Property xres, yres, avgw; 989*37da2899SCharles.Forsyth 990*37da2899SCharles.Forsyth 991*37da2899SCharles.Forsyth xres = pcf_find_property( face, "RESOLUTION_X" ); 992*37da2899SCharles.Forsyth yres = pcf_find_property( face, "RESOLUTION_Y" ); 993*37da2899SCharles.Forsyth avgw = pcf_find_property( face, "AVERAGE_WIDTH" ); 994*37da2899SCharles.Forsyth 995*37da2899SCharles.Forsyth if ( ( yres != NULL ) && ( xres != NULL ) ) 996*37da2899SCharles.Forsyth { 997*37da2899SCharles.Forsyth root->available_sizes->height = 998*37da2899SCharles.Forsyth (FT_Short)( prop->value.integer * 999*37da2899SCharles.Forsyth yres->value.integer / 720 ); 1000*37da2899SCharles.Forsyth 1001*37da2899SCharles.Forsyth root->available_sizes->width = 1002*37da2899SCharles.Forsyth (FT_Short)( prop->value.integer * 1003*37da2899SCharles.Forsyth xres->value.integer / 720 ); 1004*37da2899SCharles.Forsyth 1005*37da2899SCharles.Forsyth size_set = 1; 1006*37da2899SCharles.Forsyth } 1007*37da2899SCharles.Forsyth } 1008*37da2899SCharles.Forsyth } 1009*37da2899SCharles.Forsyth 1010*37da2899SCharles.Forsyth if (size_set == 0 ) 1011*37da2899SCharles.Forsyth { 1012*37da2899SCharles.Forsyth root->available_sizes->width = 12; 1013*37da2899SCharles.Forsyth root->available_sizes->height = 12; 1014*37da2899SCharles.Forsyth } 1015*37da2899SCharles.Forsyth 1016*37da2899SCharles.Forsyth /* set-up charset */ 1017*37da2899SCharles.Forsyth { 1018*37da2899SCharles.Forsyth PCF_Property charset_registry = 0, charset_encoding = 0; 1019*37da2899SCharles.Forsyth 1020*37da2899SCharles.Forsyth 1021*37da2899SCharles.Forsyth charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); 1022*37da2899SCharles.Forsyth charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); 1023*37da2899SCharles.Forsyth 1024*37da2899SCharles.Forsyth if ( ( charset_registry != NULL ) && 1025*37da2899SCharles.Forsyth ( charset_encoding != NULL ) ) 1026*37da2899SCharles.Forsyth { 1027*37da2899SCharles.Forsyth if ( ( charset_registry->isString ) && 1028*37da2899SCharles.Forsyth ( charset_encoding->isString ) ) 1029*37da2899SCharles.Forsyth { 1030*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( face->charset_encoding, 1031*37da2899SCharles.Forsyth ft_strlen( charset_encoding->value.atom ) + 1 ) ) 1032*37da2899SCharles.Forsyth goto Exit; 1033*37da2899SCharles.Forsyth 1034*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( face->charset_registry, 1035*37da2899SCharles.Forsyth ft_strlen( charset_registry->value.atom ) + 1 ) ) 1036*37da2899SCharles.Forsyth goto Exit; 1037*37da2899SCharles.Forsyth 1038*37da2899SCharles.Forsyth ft_strcpy( face->charset_registry, charset_registry->value.atom ); 1039*37da2899SCharles.Forsyth ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); 1040*37da2899SCharles.Forsyth } 1041*37da2899SCharles.Forsyth } 1042*37da2899SCharles.Forsyth } 1043*37da2899SCharles.Forsyth } 1044*37da2899SCharles.Forsyth 1045*37da2899SCharles.Forsyth Exit: 1046*37da2899SCharles.Forsyth if ( error ) 1047*37da2899SCharles.Forsyth { 1048*37da2899SCharles.Forsyth /* this is done to respect the behaviour of the original */ 1049*37da2899SCharles.Forsyth /* PCF font driver. */ 1050*37da2899SCharles.Forsyth error = PCF_Err_Invalid_File_Format; 1051*37da2899SCharles.Forsyth } 1052*37da2899SCharles.Forsyth 1053*37da2899SCharles.Forsyth return error; 1054*37da2899SCharles.Forsyth } 1055*37da2899SCharles.Forsyth 1056*37da2899SCharles.Forsyth 1057*37da2899SCharles.Forsyth /* END */ 1058