00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_FREETYPE_H
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_INTERNAL_SFNT_H
00024 #include FT_SERVICE_CID_H
00025 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00026 #include FT_SERVICE_POSTSCRIPT_INFO_H
00027 #include FT_SERVICE_POSTSCRIPT_NAME_H
00028 #include FT_SERVICE_TT_CMAP_H
00029
00030 #include "cffdrivr.h"
00031 #include "cffgload.h"
00032 #include "cffload.h"
00033 #include "cffcmap.h"
00034 #include "cffparse.h"
00035
00036 #include "cfferrs.h"
00037 #include "cffpic.h"
00038
00039 #include FT_SERVICE_XFREE86_NAME_H
00040 #include FT_SERVICE_GLYPH_DICT_H
00041
00042
00043
00044
00045
00046
00047
00048
00049 #undef FT_COMPONENT
00050 #define FT_COMPONENT trace_cffdriver
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #undef PAIR_TAG
00067 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
00068 (FT_ULong)right )
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 FT_CALLBACK_DEF( FT_Error )
00104 cff_get_kerning( FT_Face ttface,
00105 FT_UInt left_glyph,
00106 FT_UInt right_glyph,
00107 FT_Vector* kerning )
00108 {
00109 TT_Face face = (TT_Face)ttface;
00110 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
00111
00112
00113 kerning->x = 0;
00114 kerning->y = 0;
00115
00116 if ( sfnt )
00117 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
00118
00119 return CFF_Err_Ok;
00120 }
00121
00122
00123 #undef PAIR_TAG
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 FT_CALLBACK_DEF( FT_Error )
00153 Load_Glyph( FT_GlyphSlot cffslot,
00154 FT_Size cffsize,
00155 FT_UInt glyph_index,
00156 FT_Int32 load_flags )
00157 {
00158 FT_Error error;
00159 CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot;
00160 CFF_Size size = (CFF_Size)cffsize;
00161
00162
00163 if ( !slot )
00164 return CFF_Err_Invalid_Slot_Handle;
00165
00166
00167 if ( !size )
00168 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
00169
00170
00171 if ( load_flags & FT_LOAD_NO_SCALE )
00172 size = NULL;
00173
00174 if ( size )
00175 {
00176
00177 if ( cffsize->face != cffslot->face )
00178 return CFF_Err_Invalid_Face_Handle;
00179 }
00180
00181
00182 error = cff_slot_load( slot, size, glyph_index, load_flags );
00183
00184
00185
00186
00187 return error;
00188 }
00189
00190
00191 FT_CALLBACK_DEF( FT_Error )
00192 cff_get_advances( FT_Face face,
00193 FT_UInt start,
00194 FT_UInt count,
00195 FT_Int32 flags,
00196 FT_Fixed* advances )
00197 {
00198 FT_UInt nn;
00199 FT_Error error = CFF_Err_Ok;
00200 FT_GlyphSlot slot = face->glyph;
00201
00202
00203 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
00204
00205 for ( nn = 0; nn < count; nn++ )
00206 {
00207 error = Load_Glyph( slot, face->size, start + nn, flags );
00208 if ( error )
00209 break;
00210
00211 advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
00212 ? slot->linearVertAdvance
00213 : slot->linearHoriAdvance;
00214 }
00215
00216 return error;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225 static FT_Error
00226 cff_get_glyph_name( CFF_Face face,
00227 FT_UInt glyph_index,
00228 FT_Pointer buffer,
00229 FT_UInt buffer_max )
00230 {
00231 CFF_Font font = (CFF_Font)face->extra.data;
00232 FT_Memory memory = FT_FACE_MEMORY( face );
00233 FT_String* gname;
00234 FT_UShort sid;
00235 FT_Service_PsCMaps psnames;
00236 FT_Error error;
00237
00238
00239 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
00240 if ( !psnames )
00241 {
00242 FT_ERROR(( "cff_get_glyph_name:"
00243 " cannot get glyph name from CFF & CEF fonts\n"
00244 " "
00245 " without the `PSNames' module\n" ));
00246 error = CFF_Err_Unknown_File_Format;
00247 goto Exit;
00248 }
00249
00250
00251 sid = font->charset.sids[glyph_index];
00252
00253
00254 gname = cff_index_get_sid_string( &font->string_index, sid, psnames );
00255
00256 if ( gname )
00257 FT_STRCPYN( buffer, gname, buffer_max );
00258
00259 FT_FREE( gname );
00260 error = CFF_Err_Ok;
00261
00262 Exit:
00263 return error;
00264 }
00265
00266
00267 static FT_UInt
00268 cff_get_name_index( CFF_Face face,
00269 FT_String* glyph_name )
00270 {
00271 CFF_Font cff;
00272 CFF_Charset charset;
00273 FT_Service_PsCMaps psnames;
00274 FT_Memory memory = FT_FACE_MEMORY( face );
00275 FT_String* name;
00276 FT_UShort sid;
00277 FT_UInt i;
00278 FT_Int result;
00279
00280
00281 cff = (CFF_FontRec *)face->extra.data;
00282 charset = &cff->charset;
00283
00284 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
00285 if ( !psnames )
00286 return 0;
00287
00288 for ( i = 0; i < cff->num_glyphs; i++ )
00289 {
00290 sid = charset->sids[i];
00291
00292 if ( sid > 390 )
00293 name = cff_index_get_name( &cff->string_index, sid - 391 );
00294 else
00295 name = (FT_String *)psnames->adobe_std_strings( sid );
00296
00297 if ( !name )
00298 continue;
00299
00300 result = ft_strcmp( glyph_name, name );
00301
00302 if ( sid > 390 )
00303 FT_FREE( name );
00304
00305 if ( !result )
00306 return i;
00307 }
00308
00309 return 0;
00310 }
00311
00312
00313 FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
00314 (FT_GlyphDict_GetNameFunc) cff_get_glyph_name,
00315 (FT_GlyphDict_NameIndexFunc)cff_get_name_index
00316 )
00317
00318
00319
00320
00321
00322
00323
00324 static FT_Int
00325 cff_ps_has_glyph_names( FT_Face face )
00326 {
00327 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
00328 }
00329
00330
00331 static FT_Error
00332 cff_ps_get_font_info( CFF_Face face,
00333 PS_FontInfoRec* afont_info )
00334 {
00335 CFF_Font cff = (CFF_Font)face->extra.data;
00336 FT_Error error = FT_Err_Ok;
00337
00338
00339 if ( cff && cff->font_info == NULL )
00340 {
00341 CFF_FontRecDict dict = &cff->top_font.font_dict;
00342 PS_FontInfoRec *font_info;
00343 FT_Memory memory = face->root.memory;
00344 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
00345
00346
00347 if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
00348 goto Fail;
00349
00350 font_info->version = cff_index_get_sid_string( &cff->string_index,
00351 dict->version,
00352 psnames );
00353 font_info->notice = cff_index_get_sid_string( &cff->string_index,
00354 dict->notice,
00355 psnames );
00356 font_info->full_name = cff_index_get_sid_string( &cff->string_index,
00357 dict->full_name,
00358 psnames );
00359 font_info->family_name = cff_index_get_sid_string( &cff->string_index,
00360 dict->family_name,
00361 psnames );
00362 font_info->weight = cff_index_get_sid_string( &cff->string_index,
00363 dict->weight,
00364 psnames );
00365 font_info->italic_angle = dict->italic_angle;
00366 font_info->is_fixed_pitch = dict->is_fixed_pitch;
00367 font_info->underline_position = (FT_Short)dict->underline_position;
00368 font_info->underline_thickness = (FT_Short)dict->underline_thickness;
00369
00370 cff->font_info = font_info;
00371 }
00372
00373 if ( cff )
00374 *afont_info = *cff->font_info;
00375
00376 Fail:
00377 return error;
00378 }
00379
00380
00381 FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
00382 (PS_GetFontInfoFunc) cff_ps_get_font_info,
00383 (PS_GetFontExtraFunc) NULL,
00384 (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
00385 (PS_GetFontPrivateFunc)NULL
00386 )
00387
00388
00389
00390
00391
00392
00393
00394 static const char*
00395 cff_get_ps_name( CFF_Face face )
00396 {
00397 CFF_Font cff = (CFF_Font)face->extra.data;
00398
00399
00400 return (const char*)cff->font_name;
00401 }
00402
00403
00404 FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,
00405 (FT_PsName_GetFunc)cff_get_ps_name
00406 )
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 static FT_Error
00420 cff_get_cmap_info( FT_CharMap charmap,
00421 TT_CMapInfo *cmap_info )
00422 {
00423 FT_CMap cmap = FT_CMAP( charmap );
00424 FT_Error error = CFF_Err_Ok;
00425 FT_Face face = FT_CMAP_FACE( cmap );
00426 FT_Library library = FT_FACE_LIBRARY( face );
00427
00428
00429 cmap_info->language = 0;
00430 cmap_info->format = 0;
00431
00432 if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&
00433 cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET )
00434 {
00435 FT_Module sfnt = FT_Get_Module( library, "sfnt" );
00436 FT_Service_TTCMaps service =
00437 (FT_Service_TTCMaps)ft_module_get_service( sfnt,
00438 FT_SERVICE_ID_TT_CMAP );
00439
00440
00441 if ( service && service->get_cmap_info )
00442 error = service->get_cmap_info( charmap, cmap_info );
00443 }
00444
00445 return error;
00446 }
00447
00448
00449 FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,
00450 (TT_CMap_Info_GetFunc)cff_get_cmap_info
00451 )
00452
00453
00454
00455
00456
00457
00458 static FT_Error
00459 cff_get_ros( CFF_Face face,
00460 const char* *registry,
00461 const char* *ordering,
00462 FT_Int *supplement )
00463 {
00464 FT_Error error = CFF_Err_Ok;
00465 CFF_Font cff = (CFF_Font)face->extra.data;
00466
00467
00468 if ( cff )
00469 {
00470 CFF_FontRecDict dict = &cff->top_font.font_dict;
00471 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
00472
00473
00474 if ( dict->cid_registry == 0xFFFFU )
00475 {
00476 error = CFF_Err_Invalid_Argument;
00477 goto Fail;
00478 }
00479
00480 if ( registry )
00481 {
00482 if ( cff->registry == NULL )
00483 cff->registry = cff_index_get_sid_string( &cff->string_index,
00484 dict->cid_registry,
00485 psnames );
00486 *registry = cff->registry;
00487 }
00488
00489 if ( ordering )
00490 {
00491 if ( cff->ordering == NULL )
00492 cff->ordering = cff_index_get_sid_string( &cff->string_index,
00493 dict->cid_ordering,
00494 psnames );
00495 *ordering = cff->ordering;
00496 }
00497
00498
00499
00500
00501
00502
00503 if ( supplement )
00504 {
00505 if ( dict->cid_supplement < FT_INT_MIN ||
00506 dict->cid_supplement > FT_INT_MAX )
00507 FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
00508 dict->cid_supplement ));
00509 *supplement = (FT_Int)dict->cid_supplement;
00510 }
00511 }
00512
00513 Fail:
00514 return error;
00515 }
00516
00517
00518 static FT_Error
00519 cff_get_is_cid( CFF_Face face,
00520 FT_Bool *is_cid )
00521 {
00522 FT_Error error = CFF_Err_Ok;
00523 CFF_Font cff = (CFF_Font)face->extra.data;
00524
00525
00526 *is_cid = 0;
00527
00528 if ( cff )
00529 {
00530 CFF_FontRecDict dict = &cff->top_font.font_dict;
00531
00532
00533 if ( dict->cid_registry != 0xFFFFU )
00534 *is_cid = 1;
00535 }
00536
00537 return error;
00538 }
00539
00540
00541 static FT_Error
00542 cff_get_cid_from_glyph_index( CFF_Face face,
00543 FT_UInt glyph_index,
00544 FT_UInt *cid )
00545 {
00546 FT_Error error = CFF_Err_Ok;
00547 CFF_Font cff;
00548
00549
00550 cff = (CFF_Font)face->extra.data;
00551
00552 if ( cff )
00553 {
00554 FT_UInt c;
00555 CFF_FontRecDict dict = &cff->top_font.font_dict;
00556
00557
00558 if ( dict->cid_registry == 0xFFFFU )
00559 {
00560 error = CFF_Err_Invalid_Argument;
00561 goto Fail;
00562 }
00563
00564 if ( glyph_index > cff->num_glyphs )
00565 {
00566 error = CFF_Err_Invalid_Argument;
00567 goto Fail;
00568 }
00569
00570 c = cff->charset.sids[glyph_index];
00571
00572 if ( cid )
00573 *cid = c;
00574 }
00575
00576 Fail:
00577 return error;
00578 }
00579
00580
00581 FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,
00582 (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
00583 (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid,
00584 (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index
00585 )
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
00600 FT_DEFINE_SERVICEDESCREC6(cff_services,
00601 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
00602 FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
00603 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
00604 FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET,
00605 FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
00606 FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
00607 )
00608 #else
00609 FT_DEFINE_SERVICEDESCREC5(cff_services,
00610 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
00611 FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
00612 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
00613 FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
00614 FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
00615 )
00616 #endif
00617
00618 FT_CALLBACK_DEF( FT_Module_Interface )
00619 cff_get_interface( FT_Module driver,
00620 const char* module_interface )
00621 {
00622 FT_Module sfnt;
00623 FT_Module_Interface result;
00624
00625
00626 result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
00627 if ( result != NULL )
00628 return result;
00629
00630 if ( !driver )
00631 return NULL;
00632
00633
00634 sfnt = FT_Get_Module( driver->library, "sfnt" );
00635
00636 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
00637 }
00638
00639
00640
00641
00642 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00643 #define CFF_SIZE_SELECT cff_size_select
00644 #else
00645 #define CFF_SIZE_SELECT 0
00646 #endif
00647
00648 FT_DEFINE_DRIVER(cff_driver_class,
00649 FT_MODULE_FONT_DRIVER |
00650 FT_MODULE_DRIVER_SCALABLE |
00651 FT_MODULE_DRIVER_HAS_HINTER,
00652
00653 sizeof( CFF_DriverRec ),
00654 "cff",
00655 0x10000L,
00656 0x20000L,
00657
00658 0,
00659
00660 cff_driver_init,
00661 cff_driver_done,
00662 cff_get_interface,
00663
00664
00665 sizeof( TT_FaceRec ),
00666 sizeof( CFF_SizeRec ),
00667 sizeof( CFF_GlyphSlotRec ),
00668
00669 cff_face_init,
00670 cff_face_done,
00671 cff_size_init,
00672 cff_size_done,
00673 cff_slot_init,
00674 cff_slot_done,
00675
00676 ft_stub_set_char_sizes,
00677 ft_stub_set_pixel_sizes,
00678
00679 Load_Glyph,
00680
00681 cff_get_kerning,
00682 0,
00683 cff_get_advances,
00684
00685 cff_size_request,
00686
00687 CFF_SIZE_SELECT
00688 )
00689
00690
00691