00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <ft2build.h>
00029
00030 #include FT_INTERNAL_DEBUG_H
00031 #include FT_INTERNAL_STREAM_H
00032 #include FT_INTERNAL_OBJECTS_H
00033 #include FT_GZIP_H
00034 #include FT_LZW_H
00035 #include FT_ERRORS_H
00036 #include FT_BDF_H
00037
00038 #include "pcf.h"
00039 #include "pcfdrivr.h"
00040 #include "pcfread.h"
00041
00042 #include "pcferror.h"
00043 #include "pcfutil.h"
00044
00045 #undef FT_COMPONENT
00046 #define FT_COMPONENT trace_pcfread
00047
00048 #include FT_SERVICE_BDF_H
00049 #include FT_SERVICE_XFREE86_NAME_H
00050
00051
00052
00053
00054
00055
00056
00057
00058 #undef FT_COMPONENT
00059 #define FT_COMPONENT trace_pcfdriver
00060
00061
00062 typedef struct PCF_CMapRec_
00063 {
00064 FT_CMapRec root;
00065 FT_UInt num_encodings;
00066 PCF_Encoding encodings;
00067
00068 } PCF_CMapRec, *PCF_CMap;
00069
00070
00071 FT_CALLBACK_DEF( FT_Error )
00072 pcf_cmap_init( FT_CMap pcfcmap,
00073 FT_Pointer init_data )
00074 {
00075 PCF_CMap cmap = (PCF_CMap)pcfcmap;
00076 PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap );
00077
00078 FT_UNUSED( init_data );
00079
00080
00081 cmap->num_encodings = (FT_UInt)face->nencodings;
00082 cmap->encodings = face->encodings;
00083
00084 return PCF_Err_Ok;
00085 }
00086
00087
00088 FT_CALLBACK_DEF( void )
00089 pcf_cmap_done( FT_CMap pcfcmap )
00090 {
00091 PCF_CMap cmap = (PCF_CMap)pcfcmap;
00092
00093
00094 cmap->encodings = NULL;
00095 cmap->num_encodings = 0;
00096 }
00097
00098
00099 FT_CALLBACK_DEF( FT_UInt )
00100 pcf_cmap_char_index( FT_CMap pcfcmap,
00101 FT_UInt32 charcode )
00102 {
00103 PCF_CMap cmap = (PCF_CMap)pcfcmap;
00104 PCF_Encoding encodings = cmap->encodings;
00105 FT_UInt min, max, mid;
00106 FT_UInt result = 0;
00107
00108
00109 min = 0;
00110 max = cmap->num_encodings;
00111
00112 while ( min < max )
00113 {
00114 FT_ULong code;
00115
00116
00117 mid = ( min + max ) >> 1;
00118 code = encodings[mid].enc;
00119
00120 if ( charcode == code )
00121 {
00122 result = encodings[mid].glyph + 1;
00123 break;
00124 }
00125
00126 if ( charcode < code )
00127 max = mid;
00128 else
00129 min = mid + 1;
00130 }
00131
00132 return result;
00133 }
00134
00135
00136 FT_CALLBACK_DEF( FT_UInt )
00137 pcf_cmap_char_next( FT_CMap pcfcmap,
00138 FT_UInt32 *acharcode )
00139 {
00140 PCF_CMap cmap = (PCF_CMap)pcfcmap;
00141 PCF_Encoding encodings = cmap->encodings;
00142 FT_UInt min, max, mid;
00143 FT_ULong charcode = *acharcode + 1;
00144 FT_UInt result = 0;
00145
00146
00147 min = 0;
00148 max = cmap->num_encodings;
00149
00150 while ( min < max )
00151 {
00152 FT_ULong code;
00153
00154
00155 mid = ( min + max ) >> 1;
00156 code = encodings[mid].enc;
00157
00158 if ( charcode == code )
00159 {
00160 result = encodings[mid].glyph + 1;
00161 goto Exit;
00162 }
00163
00164 if ( charcode < code )
00165 max = mid;
00166 else
00167 min = mid + 1;
00168 }
00169
00170 charcode = 0;
00171 if ( min < cmap->num_encodings )
00172 {
00173 charcode = encodings[min].enc;
00174 result = encodings[min].glyph + 1;
00175 }
00176
00177 Exit:
00178 if ( charcode > 0xFFFFFFFFUL )
00179 {
00180 FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));
00181 *acharcode = 0;
00182
00183 }
00184 else
00185 *acharcode = (FT_UInt32)charcode;
00186 return result;
00187 }
00188
00189
00190 FT_CALLBACK_TABLE_DEF
00191 const FT_CMap_ClassRec pcf_cmap_class =
00192 {
00193 sizeof ( PCF_CMapRec ),
00194 pcf_cmap_init,
00195 pcf_cmap_done,
00196 pcf_cmap_char_index,
00197 pcf_cmap_char_next,
00198
00199 NULL, NULL, NULL, NULL, NULL
00200 };
00201
00202
00203 FT_CALLBACK_DEF( void )
00204 PCF_Face_Done( FT_Face pcfface )
00205 {
00206 PCF_Face face = (PCF_Face)pcfface;
00207 FT_Memory memory;
00208
00209
00210 if ( !face )
00211 return;
00212
00213 memory = FT_FACE_MEMORY( face );
00214
00215 FT_FREE( face->encodings );
00216 FT_FREE( face->metrics );
00217
00218
00219 {
00220 PCF_Property prop;
00221 FT_Int i;
00222
00223
00224 if ( face->properties )
00225 {
00226 for ( i = 0; i < face->nprops; i++ )
00227 {
00228 prop = &face->properties[i];
00229
00230 if ( prop ) {
00231 FT_FREE( prop->name );
00232 if ( prop->isString )
00233 FT_FREE( prop->value.atom );
00234 }
00235 }
00236 }
00237 FT_FREE( face->properties );
00238 }
00239
00240 FT_FREE( face->toc.tables );
00241 FT_FREE( pcfface->family_name );
00242 FT_FREE( pcfface->style_name );
00243 FT_FREE( pcfface->available_sizes );
00244 FT_FREE( face->charset_encoding );
00245 FT_FREE( face->charset_registry );
00246
00247 FT_TRACE4(( "PCF_Face_Done: done face\n" ));
00248
00249
00250 if ( pcfface->stream == &face->gzip_stream )
00251 {
00252 FT_Stream_Close( &face->gzip_stream );
00253 pcfface->stream = face->gzip_source;
00254 }
00255 }
00256
00257
00258 FT_CALLBACK_DEF( FT_Error )
00259 PCF_Face_Init( FT_Stream stream,
00260 FT_Face pcfface,
00261 FT_Int face_index,
00262 FT_Int num_params,
00263 FT_Parameter* params )
00264 {
00265 PCF_Face face = (PCF_Face)pcfface;
00266 FT_Error error = PCF_Err_Ok;
00267
00268 FT_UNUSED( num_params );
00269 FT_UNUSED( params );
00270 FT_UNUSED( face_index );
00271
00272
00273 error = pcf_load_font( stream, face );
00274 if ( error )
00275 {
00276 PCF_Face_Done( pcfface );
00277
00278 #if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \
00279 defined( FT_CONFIG_OPTION_USE_LZW )
00280
00281 #ifdef FT_CONFIG_OPTION_USE_ZLIB
00282 {
00283 FT_Error error2;
00284
00285
00286
00287 error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );
00288 if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
00289 goto Fail;
00290
00291 error = error2;
00292 }
00293 #endif
00294
00295 #ifdef FT_CONFIG_OPTION_USE_LZW
00296 if ( error )
00297 {
00298 FT_Error error3;
00299
00300
00301
00302 error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream );
00303 if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature )
00304 goto Fail;
00305
00306 error = error3;
00307 }
00308 #endif
00309
00310 if ( error )
00311 goto Fail;
00312
00313 face->gzip_source = stream;
00314 pcfface->stream = &face->gzip_stream;
00315
00316 stream = pcfface->stream;
00317
00318 error = pcf_load_font( stream, face );
00319 if ( error )
00320 goto Fail;
00321
00322 #else
00323
00324 goto Fail;
00325
00326 #endif
00327 }
00328
00329
00330 {
00331 FT_String *charset_registry = face->charset_registry;
00332 FT_String *charset_encoding = face->charset_encoding;
00333 FT_Bool unicode_charmap = 0;
00334
00335
00336 if ( charset_registry && charset_encoding )
00337 {
00338 char* s = charset_registry;
00339
00340
00341
00342
00343 if ( ( s[0] == 'i' || s[0] == 'I' ) &&
00344 ( s[1] == 's' || s[1] == 'S' ) &&
00345 ( s[2] == 'o' || s[2] == 'O' ) )
00346 {
00347 s += 3;
00348 if ( !ft_strcmp( s, "10646" ) ||
00349 ( !ft_strcmp( s, "8859" ) &&
00350 !ft_strcmp( face->charset_encoding, "1" ) ) )
00351 unicode_charmap = 1;
00352 }
00353 }
00354
00355 {
00356 FT_CharMapRec charmap;
00357
00358
00359 charmap.face = FT_FACE( face );
00360 charmap.encoding = FT_ENCODING_NONE;
00361 charmap.platform_id = 0;
00362 charmap.encoding_id = 0;
00363
00364 if ( unicode_charmap )
00365 {
00366 charmap.encoding = FT_ENCODING_UNICODE;
00367 charmap.platform_id = 3;
00368 charmap.encoding_id = 1;
00369 }
00370
00371 error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
00372
00373 #if 0
00374
00375 if ( pcfface->num_charmaps )
00376 pcfface->charmap = pcfface->charmaps[0];
00377 #endif
00378 }
00379 }
00380
00381 Exit:
00382 return error;
00383
00384 Fail:
00385 FT_TRACE2(( "[not a valid PCF file]\n" ));
00386 PCF_Face_Done( pcfface );
00387 error = PCF_Err_Unknown_File_Format;
00388 goto Exit;
00389 }
00390
00391
00392 FT_CALLBACK_DEF( FT_Error )
00393 PCF_Size_Select( FT_Size size,
00394 FT_ULong strike_index )
00395 {
00396 PCF_Accel accel = &( (PCF_Face)size->face )->accel;
00397
00398
00399 FT_Select_Metrics( size->face, strike_index );
00400
00401 size->metrics.ascender = accel->fontAscent << 6;
00402 size->metrics.descender = -accel->fontDescent << 6;
00403 size->metrics.max_advance = accel->maxbounds.characterWidth << 6;
00404
00405 return PCF_Err_Ok;
00406 }
00407
00408
00409 FT_CALLBACK_DEF( FT_Error )
00410 PCF_Size_Request( FT_Size size,
00411 FT_Size_Request req )
00412 {
00413 PCF_Face face = (PCF_Face)size->face;
00414 FT_Bitmap_Size* bsize = size->face->available_sizes;
00415 FT_Error error = PCF_Err_Invalid_Pixel_Size;
00416 FT_Long height;
00417
00418
00419 height = FT_REQUEST_HEIGHT( req );
00420 height = ( height + 32 ) >> 6;
00421
00422 switch ( req->type )
00423 {
00424 case FT_SIZE_REQUEST_TYPE_NOMINAL:
00425 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
00426 error = PCF_Err_Ok;
00427 break;
00428
00429 case FT_SIZE_REQUEST_TYPE_REAL_DIM:
00430 if ( height == ( face->accel.fontAscent +
00431 face->accel.fontDescent ) )
00432 error = PCF_Err_Ok;
00433 break;
00434
00435 default:
00436 error = PCF_Err_Unimplemented_Feature;
00437 break;
00438 }
00439
00440 if ( error )
00441 return error;
00442 else
00443 return PCF_Size_Select( size, 0 );
00444 }
00445
00446
00447 FT_CALLBACK_DEF( FT_Error )
00448 PCF_Glyph_Load( FT_GlyphSlot slot,
00449 FT_Size size,
00450 FT_UInt glyph_index,
00451 FT_Int32 load_flags )
00452 {
00453 PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
00454 FT_Stream stream;
00455 FT_Error error = PCF_Err_Ok;
00456 FT_Bitmap* bitmap = &slot->bitmap;
00457 PCF_Metric metric;
00458 FT_Offset bytes;
00459
00460 FT_UNUSED( load_flags );
00461
00462
00463 FT_TRACE4(( "load_glyph %d ---", glyph_index ));
00464
00465 if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
00466 {
00467 error = PCF_Err_Invalid_Argument;
00468 goto Exit;
00469 }
00470
00471 stream = face->root.stream;
00472
00473 if ( glyph_index > 0 )
00474 glyph_index--;
00475
00476 metric = face->metrics + glyph_index;
00477
00478 bitmap->rows = metric->ascent + metric->descent;
00479 bitmap->width = metric->rightSideBearing - metric->leftSideBearing;
00480 bitmap->num_grays = 1;
00481 bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
00482
00483 FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
00484 PCF_BIT_ORDER( face->bitmapsFormat ),
00485 PCF_BYTE_ORDER( face->bitmapsFormat ),
00486 PCF_GLYPH_PAD( face->bitmapsFormat ) ));
00487
00488 switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
00489 {
00490 case 1:
00491 bitmap->pitch = ( bitmap->width + 7 ) >> 3;
00492 break;
00493
00494 case 2:
00495 bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
00496 break;
00497
00498 case 4:
00499 bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
00500 break;
00501
00502 case 8:
00503 bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
00504 break;
00505
00506 default:
00507 return PCF_Err_Invalid_File_Format;
00508 }
00509
00510
00511 bytes = bitmap->pitch * bitmap->rows;
00512
00513 error = ft_glyphslot_alloc_bitmap( slot, bytes );
00514 if ( error )
00515 goto Exit;
00516
00517 if ( FT_STREAM_SEEK( metric->bits ) ||
00518 FT_STREAM_READ( bitmap->buffer, bytes ) )
00519 goto Exit;
00520
00521 if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
00522 BitOrderInvert( bitmap->buffer, bytes );
00523
00524 if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
00525 PCF_BIT_ORDER( face->bitmapsFormat ) ) )
00526 {
00527 switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
00528 {
00529 case 1:
00530 break;
00531
00532 case 2:
00533 TwoByteSwap( bitmap->buffer, bytes );
00534 break;
00535
00536 case 4:
00537 FourByteSwap( bitmap->buffer, bytes );
00538 break;
00539 }
00540 }
00541
00542 slot->format = FT_GLYPH_FORMAT_BITMAP;
00543 slot->bitmap_left = metric->leftSideBearing;
00544 slot->bitmap_top = metric->ascent;
00545
00546 slot->metrics.horiAdvance = metric->characterWidth << 6;
00547 slot->metrics.horiBearingX = metric->leftSideBearing << 6;
00548 slot->metrics.horiBearingY = metric->ascent << 6;
00549 slot->metrics.width = ( metric->rightSideBearing -
00550 metric->leftSideBearing ) << 6;
00551 slot->metrics.height = bitmap->rows << 6;
00552
00553 ft_synthesize_vertical_metrics( &slot->metrics,
00554 ( face->accel.fontAscent +
00555 face->accel.fontDescent ) << 6 );
00556
00557 FT_TRACE4(( " --- ok\n" ));
00558
00559 Exit:
00560 return error;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570 static FT_Error
00571 pcf_get_bdf_property( PCF_Face face,
00572 const char* prop_name,
00573 BDF_PropertyRec *aproperty )
00574 {
00575 PCF_Property prop;
00576
00577
00578 prop = pcf_find_property( face, prop_name );
00579 if ( prop != NULL )
00580 {
00581 if ( prop->isString )
00582 {
00583 aproperty->type = BDF_PROPERTY_TYPE_ATOM;
00584 aproperty->u.atom = prop->value.atom;
00585 }
00586 else
00587 {
00588 if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )
00589 {
00590 FT_TRACE1(( "pcf_get_bdf_property: " ));
00591 FT_TRACE1(( "too large integer 0x%x is truncated\n" ));
00592 }
00593
00594
00595
00596
00597 aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
00598 aproperty->u.integer = (FT_Int32)prop->value.l;
00599 }
00600 return 0;
00601 }
00602
00603 return PCF_Err_Invalid_Argument;
00604 }
00605
00606
00607 static FT_Error
00608 pcf_get_charset_id( PCF_Face face,
00609 const char* *acharset_encoding,
00610 const char* *acharset_registry )
00611 {
00612 *acharset_encoding = face->charset_encoding;
00613 *acharset_registry = face->charset_registry;
00614
00615 return 0;
00616 }
00617
00618
00619 static const FT_Service_BDFRec pcf_service_bdf =
00620 {
00621 (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,
00622 (FT_BDF_GetPropertyFunc) pcf_get_bdf_property
00623 };
00624
00625
00626
00627
00628
00629
00630
00631
00632 static const FT_ServiceDescRec pcf_services[] =
00633 {
00634 { FT_SERVICE_ID_BDF, &pcf_service_bdf },
00635 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF },
00636 { NULL, NULL }
00637 };
00638
00639
00640 FT_CALLBACK_DEF( FT_Module_Interface )
00641 pcf_driver_requester( FT_Module module,
00642 const char* name )
00643 {
00644 FT_UNUSED( module );
00645
00646 return ft_service_list_lookup( pcf_services, name );
00647 }
00648
00649
00650 FT_CALLBACK_TABLE_DEF
00651 const FT_Driver_ClassRec pcf_driver_class =
00652 {
00653 {
00654 FT_MODULE_FONT_DRIVER |
00655 FT_MODULE_DRIVER_NO_OUTLINES,
00656 sizeof ( FT_DriverRec ),
00657
00658 "pcf",
00659 0x10000L,
00660 0x20000L,
00661
00662 0,
00663
00664 0,
00665 0,
00666 pcf_driver_requester
00667 },
00668
00669 sizeof ( PCF_FaceRec ),
00670 sizeof ( FT_SizeRec ),
00671 sizeof ( FT_GlyphSlotRec ),
00672
00673 PCF_Face_Init,
00674 PCF_Face_Done,
00675 0,
00676 0,
00677 0,
00678 0,
00679
00680 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00681 ft_stub_set_char_sizes,
00682 ft_stub_set_pixel_sizes,
00683 #endif
00684 PCF_Glyph_Load,
00685
00686 0,
00687 0,
00688 0,
00689
00690 PCF_Size_Request,
00691 PCF_Size_Select
00692 };
00693
00694
00695