| OLD | NEW |
| (Empty) |
| 1 /***************************************************************************/ | |
| 2 /* */ | |
| 3 /* cffdrivr.c */ | |
| 4 /* */ | |
| 5 /* OpenType font driver implementation (body). */ | |
| 6 /* */ | |
| 7 /* Copyright 1996-2013 by */ | |
| 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |
| 9 /* */ | |
| 10 /* This file is part of the FreeType project, and may only be used, */ | |
| 11 /* modified, and distributed under the terms of the FreeType project */ | |
| 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
| 13 /* this file you indicate that you have read the license and */ | |
| 14 /* understand and accept it fully. */ | |
| 15 /* */ | |
| 16 /***************************************************************************/ | |
| 17 | |
| 18 | |
| 19 #include "../../include/ft2build.h" | |
| 20 #include "../../include/freetype/freetype.h" | |
| 21 #include "../../include/freetype/internal/ftdebug.h" | |
| 22 #include "../../include/freetype/internal/ftstream.h" | |
| 23 #include "../../include/freetype/internal/sfnt.h" | |
| 24 #include "../../include/freetype/internal/services/svcid.h" | |
| 25 #include "../../include/freetype/internal/services/svpsinfo.h" | |
| 26 #include "../../include/freetype/internal/services/svpostnm.h" | |
| 27 #include "../../include/freetype/internal/services/svttcmap.h" | |
| 28 | |
| 29 #include "cffdrivr.h" | |
| 30 #include "cffgload.h" | |
| 31 #include "cffload.h" | |
| 32 #include "cffcmap.h" | |
| 33 #include "cffparse.h" | |
| 34 | |
| 35 #include "cfferrs.h" | |
| 36 #include "cffpic.h" | |
| 37 | |
| 38 #include "../../include/freetype/internal/services/svxf86nm.h" | |
| 39 #include "../../include/freetype/internal/services/svgldict.h" | |
| 40 #include "../../include/freetype/internal/services/svprop.h" | |
| 41 #include "../../include/freetype/ftcffdrv.h" | |
| 42 | |
| 43 | |
| 44 | |
| 45 /*************************************************************************/ | |
| 46 /* */ | |
| 47 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | |
| 48 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | |
| 49 /* messages during execution. */ | |
| 50 /* */ | |
| 51 #undef FT_COMPONENT | |
| 52 #define FT_COMPONENT trace_cffdriver | |
| 53 | |
| 54 | |
| 55 /*************************************************************************/ | |
| 56 /*************************************************************************/ | |
| 57 /*************************************************************************/ | |
| 58 /**** ****/ | |
| 59 /**** ****/ | |
| 60 /**** F A C E S ****/ | |
| 61 /**** ****/ | |
| 62 /**** ****/ | |
| 63 /*************************************************************************/ | |
| 64 /*************************************************************************/ | |
| 65 /*************************************************************************/ | |
| 66 | |
| 67 | |
| 68 #undef PAIR_TAG | |
| 69 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ | |
| 70 (FT_ULong)right ) | |
| 71 | |
| 72 | |
| 73 /*************************************************************************/ | |
| 74 /* */ | |
| 75 /* <Function> */ | |
| 76 /* cff_get_kerning */ | |
| 77 /* */ | |
| 78 /* <Description> */ | |
| 79 /* A driver method used to return the kerning vector between two */ | |
| 80 /* glyphs of the same face. */ | |
| 81 /* */ | |
| 82 /* <Input> */ | |
| 83 /* face :: A handle to the source face object. */ | |
| 84 /* */ | |
| 85 /* left_glyph :: The index of the left glyph in the kern pair. */ | |
| 86 /* */ | |
| 87 /* right_glyph :: The index of the right glyph in the kern pair. */ | |
| 88 /* */ | |
| 89 /* <Output> */ | |
| 90 /* kerning :: The kerning vector. This is in font units for */ | |
| 91 /* scalable formats, and in pixels for fixed-sizes */ | |
| 92 /* formats. */ | |
| 93 /* */ | |
| 94 /* <Return> */ | |
| 95 /* FreeType error code. 0 means success. */ | |
| 96 /* */ | |
| 97 /* <Note> */ | |
| 98 /* Only horizontal layouts (left-to-right & right-to-left) are */ | |
| 99 /* supported by this function. Other layouts, or more sophisticated */ | |
| 100 /* kernings, are out of scope of this method (the basic driver */ | |
| 101 /* interface is meant to be simple). */ | |
| 102 /* */ | |
| 103 /* They can be implemented by format-specific interfaces. */ | |
| 104 /* */ | |
| 105 FT_CALLBACK_DEF( FT_Error ) | |
| 106 cff_get_kerning( FT_Face ttface, /* TT_Face */ | |
| 107 FT_UInt left_glyph, | |
| 108 FT_UInt right_glyph, | |
| 109 FT_Vector* kerning ) | |
| 110 { | |
| 111 TT_Face face = (TT_Face)ttface; | |
| 112 SFNT_Service sfnt = (SFNT_Service)face->sfnt; | |
| 113 | |
| 114 | |
| 115 kerning->x = 0; | |
| 116 kerning->y = 0; | |
| 117 | |
| 118 if ( sfnt ) | |
| 119 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); | |
| 120 | |
| 121 return FT_Err_Ok; | |
| 122 } | |
| 123 | |
| 124 | |
| 125 #undef PAIR_TAG | |
| 126 | |
| 127 | |
| 128 /*************************************************************************/ | |
| 129 /* */ | |
| 130 /* <Function> */ | |
| 131 /* cff_glyph_load */ | |
| 132 /* */ | |
| 133 /* <Description> */ | |
| 134 /* A driver method used to load a glyph within a given glyph slot. */ | |
| 135 /* */ | |
| 136 /* <Input> */ | |
| 137 /* slot :: A handle to the target slot object where the glyph */ | |
| 138 /* will be loaded. */ | |
| 139 /* */ | |
| 140 /* size :: A handle to the source face size at which the glyph */ | |
| 141 /* must be scaled, loaded, etc. */ | |
| 142 /* */ | |
| 143 /* glyph_index :: The index of the glyph in the font file. */ | |
| 144 /* */ | |
| 145 /* load_flags :: A flag indicating what to load for this glyph. The */ | |
| 146 /* FT_LOAD_??? constants can be used to control the */ | |
| 147 /* glyph loading process (e.g., whether the outline */ | |
| 148 /* should be scaled, whether to load bitmaps or not, */ | |
| 149 /* whether to hint the outline, etc). */ | |
| 150 /* */ | |
| 151 /* <Return> */ | |
| 152 /* FreeType error code. 0 means success. */ | |
| 153 /* */ | |
| 154 FT_CALLBACK_DEF( FT_Error ) | |
| 155 cff_glyph_load( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ | |
| 156 FT_Size cffsize, /* CFF_Size */ | |
| 157 FT_UInt glyph_index, | |
| 158 FT_Int32 load_flags ) | |
| 159 { | |
| 160 FT_Error error; | |
| 161 CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; | |
| 162 CFF_Size size = (CFF_Size)cffsize; | |
| 163 | |
| 164 | |
| 165 if ( !slot ) | |
| 166 return FT_THROW( Invalid_Slot_Handle ); | |
| 167 | |
| 168 /* check whether we want a scaled outline or bitmap */ | |
| 169 if ( !size ) | |
| 170 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; | |
| 171 | |
| 172 /* reset the size object if necessary */ | |
| 173 if ( load_flags & FT_LOAD_NO_SCALE ) | |
| 174 size = NULL; | |
| 175 | |
| 176 if ( size ) | |
| 177 { | |
| 178 /* these two objects must have the same parent */ | |
| 179 if ( cffsize->face != cffslot->face ) | |
| 180 return FT_THROW( Invalid_Face_Handle ); | |
| 181 } | |
| 182 | |
| 183 /* now load the glyph outline if necessary */ | |
| 184 error = cff_slot_load( slot, size, glyph_index, load_flags ); | |
| 185 | |
| 186 /* force drop-out mode to 2 - irrelevant now */ | |
| 187 /* slot->outline.dropout_mode = 2; */ | |
| 188 | |
| 189 return error; | |
| 190 } | |
| 191 | |
| 192 | |
| 193 FT_CALLBACK_DEF( FT_Error ) | |
| 194 cff_get_advances( FT_Face face, | |
| 195 FT_UInt start, | |
| 196 FT_UInt count, | |
| 197 FT_Int32 flags, | |
| 198 FT_Fixed* advances ) | |
| 199 { | |
| 200 FT_UInt nn; | |
| 201 FT_Error error = FT_Err_Ok; | |
| 202 FT_GlyphSlot slot = face->glyph; | |
| 203 | |
| 204 | |
| 205 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; | |
| 206 | |
| 207 for ( nn = 0; nn < count; nn++ ) | |
| 208 { | |
| 209 error = cff_glyph_load( slot, face->size, start + nn, flags ); | |
| 210 if ( error ) | |
| 211 break; | |
| 212 | |
| 213 advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) | |
| 214 ? slot->linearVertAdvance | |
| 215 : slot->linearHoriAdvance; | |
| 216 } | |
| 217 | |
| 218 return error; | |
| 219 } | |
| 220 | |
| 221 | |
| 222 /* | |
| 223 * GLYPH DICT SERVICE | |
| 224 * | |
| 225 */ | |
| 226 | |
| 227 static FT_Error | |
| 228 cff_get_glyph_name( CFF_Face face, | |
| 229 FT_UInt glyph_index, | |
| 230 FT_Pointer buffer, | |
| 231 FT_UInt buffer_max ) | |
| 232 { | |
| 233 CFF_Font font = (CFF_Font)face->extra.data; | |
| 234 FT_String* gname; | |
| 235 FT_UShort sid; | |
| 236 FT_Error error; | |
| 237 | |
| 238 | |
| 239 if ( !font->psnames ) | |
| 240 { | |
| 241 FT_ERROR(( "cff_get_glyph_name:" | |
| 242 " cannot get glyph name from CFF & CEF fonts\n" | |
| 243 " " | |
| 244 " without the `PSNames' module\n" )); | |
| 245 error = FT_THROW( Missing_Module ); | |
| 246 goto Exit; | |
| 247 } | |
| 248 | |
| 249 /* first, locate the sid in the charset table */ | |
| 250 sid = font->charset.sids[glyph_index]; | |
| 251 | |
| 252 /* now, lookup the name itself */ | |
| 253 gname = cff_index_get_sid_string( font, sid ); | |
| 254 | |
| 255 if ( gname ) | |
| 256 FT_STRCPYN( buffer, gname, buffer_max ); | |
| 257 | |
| 258 error = FT_Err_Ok; | |
| 259 | |
| 260 Exit: | |
| 261 return error; | |
| 262 } | |
| 263 | |
| 264 | |
| 265 static FT_UInt | |
| 266 cff_get_name_index( CFF_Face face, | |
| 267 FT_String* glyph_name ) | |
| 268 { | |
| 269 CFF_Font cff; | |
| 270 CFF_Charset charset; | |
| 271 FT_Service_PsCMaps psnames; | |
| 272 FT_String* name; | |
| 273 FT_UShort sid; | |
| 274 FT_UInt i; | |
| 275 | |
| 276 | |
| 277 cff = (CFF_FontRec *)face->extra.data; | |
| 278 charset = &cff->charset; | |
| 279 | |
| 280 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); | |
| 281 if ( !psnames ) | |
| 282 return 0; | |
| 283 | |
| 284 for ( i = 0; i < cff->num_glyphs; i++ ) | |
| 285 { | |
| 286 sid = charset->sids[i]; | |
| 287 | |
| 288 if ( sid > 390 ) | |
| 289 name = cff_index_get_string( cff, sid - 391 ); | |
| 290 else | |
| 291 name = (FT_String *)psnames->adobe_std_strings( sid ); | |
| 292 | |
| 293 if ( !name ) | |
| 294 continue; | |
| 295 | |
| 296 if ( !ft_strcmp( glyph_name, name ) ) | |
| 297 return i; | |
| 298 } | |
| 299 | |
| 300 return 0; | |
| 301 } | |
| 302 | |
| 303 | |
| 304 FT_DEFINE_SERVICE_GLYPHDICTREC( | |
| 305 cff_service_glyph_dict, | |
| 306 (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, | |
| 307 (FT_GlyphDict_NameIndexFunc)cff_get_name_index | |
| 308 ) | |
| 309 | |
| 310 | |
| 311 /* | |
| 312 * POSTSCRIPT INFO SERVICE | |
| 313 * | |
| 314 */ | |
| 315 | |
| 316 static FT_Int | |
| 317 cff_ps_has_glyph_names( FT_Face face ) | |
| 318 { | |
| 319 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; | |
| 320 } | |
| 321 | |
| 322 | |
| 323 static FT_Error | |
| 324 cff_ps_get_font_info( CFF_Face face, | |
| 325 PS_FontInfoRec* afont_info ) | |
| 326 { | |
| 327 CFF_Font cff = (CFF_Font)face->extra.data; | |
| 328 FT_Error error = FT_Err_Ok; | |
| 329 | |
| 330 | |
| 331 if ( cff && cff->font_info == NULL ) | |
| 332 { | |
| 333 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
| 334 PS_FontInfoRec *font_info = NULL; | |
| 335 FT_Memory memory = face->root.memory; | |
| 336 | |
| 337 | |
| 338 if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) | |
| 339 goto Fail; | |
| 340 | |
| 341 font_info->version = cff_index_get_sid_string( cff, | |
| 342 dict->version ); | |
| 343 font_info->notice = cff_index_get_sid_string( cff, | |
| 344 dict->notice ); | |
| 345 font_info->full_name = cff_index_get_sid_string( cff, | |
| 346 dict->full_name ); | |
| 347 font_info->family_name = cff_index_get_sid_string( cff, | |
| 348 dict->family_name ); | |
| 349 font_info->weight = cff_index_get_sid_string( cff, | |
| 350 dict->weight ); | |
| 351 font_info->italic_angle = dict->italic_angle; | |
| 352 font_info->is_fixed_pitch = dict->is_fixed_pitch; | |
| 353 font_info->underline_position = (FT_Short)dict->underline_position; | |
| 354 font_info->underline_thickness = (FT_Short)dict->underline_thickness; | |
| 355 | |
| 356 cff->font_info = font_info; | |
| 357 } | |
| 358 | |
| 359 if ( cff ) | |
| 360 *afont_info = *cff->font_info; | |
| 361 | |
| 362 Fail: | |
| 363 return error; | |
| 364 } | |
| 365 | |
| 366 | |
| 367 FT_DEFINE_SERVICE_PSINFOREC( | |
| 368 cff_service_ps_info, | |
| 369 (PS_GetFontInfoFunc) cff_ps_get_font_info, | |
| 370 (PS_GetFontExtraFunc) NULL, | |
| 371 (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, | |
| 372 (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ | |
| 373 (PS_GetFontValueFunc) NULL /* not implemented */ | |
| 374 ) | |
| 375 | |
| 376 | |
| 377 /* | |
| 378 * POSTSCRIPT NAME SERVICE | |
| 379 * | |
| 380 */ | |
| 381 | |
| 382 static const char* | |
| 383 cff_get_ps_name( CFF_Face face ) | |
| 384 { | |
| 385 CFF_Font cff = (CFF_Font)face->extra.data; | |
| 386 | |
| 387 | |
| 388 return (const char*)cff->font_name; | |
| 389 } | |
| 390 | |
| 391 | |
| 392 FT_DEFINE_SERVICE_PSFONTNAMEREC( | |
| 393 cff_service_ps_name, | |
| 394 (FT_PsName_GetFunc)cff_get_ps_name | |
| 395 ) | |
| 396 | |
| 397 | |
| 398 /* | |
| 399 * TT CMAP INFO | |
| 400 * | |
| 401 * If the charmap is a synthetic Unicode encoding cmap or | |
| 402 * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO | |
| 403 * service defined in SFNT module. | |
| 404 * | |
| 405 * Otherwise call the service function in the sfnt module. | |
| 406 * | |
| 407 */ | |
| 408 static FT_Error | |
| 409 cff_get_cmap_info( FT_CharMap charmap, | |
| 410 TT_CMapInfo *cmap_info ) | |
| 411 { | |
| 412 FT_CMap cmap = FT_CMAP( charmap ); | |
| 413 FT_Error error = FT_Err_Ok; | |
| 414 | |
| 415 FT_Face face = FT_CMAP_FACE( cmap ); | |
| 416 FT_Library library = FT_FACE_LIBRARY( face ); | |
| 417 | |
| 418 | |
| 419 cmap_info->language = 0; | |
| 420 cmap_info->format = 0; | |
| 421 | |
| 422 if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && | |
| 423 cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) | |
| 424 { | |
| 425 FT_Module sfnt = FT_Get_Module( library, "sfnt" ); | |
| 426 FT_Service_TTCMaps service = | |
| 427 (FT_Service_TTCMaps)ft_module_get_service( sfnt, | |
| 428 FT_SERVICE_ID_TT_CMAP ); | |
| 429 | |
| 430 | |
| 431 if ( service && service->get_cmap_info ) | |
| 432 error = service->get_cmap_info( charmap, cmap_info ); | |
| 433 } | |
| 434 | |
| 435 return error; | |
| 436 } | |
| 437 | |
| 438 | |
| 439 FT_DEFINE_SERVICE_TTCMAPSREC( | |
| 440 cff_service_get_cmap_info, | |
| 441 (TT_CMap_Info_GetFunc)cff_get_cmap_info | |
| 442 ) | |
| 443 | |
| 444 | |
| 445 /* | |
| 446 * CID INFO SERVICE | |
| 447 * | |
| 448 */ | |
| 449 static FT_Error | |
| 450 cff_get_ros( CFF_Face face, | |
| 451 const char* *registry, | |
| 452 const char* *ordering, | |
| 453 FT_Int *supplement ) | |
| 454 { | |
| 455 FT_Error error = FT_Err_Ok; | |
| 456 CFF_Font cff = (CFF_Font)face->extra.data; | |
| 457 | |
| 458 | |
| 459 if ( cff ) | |
| 460 { | |
| 461 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
| 462 | |
| 463 | |
| 464 if ( dict->cid_registry == 0xFFFFU ) | |
| 465 { | |
| 466 error = FT_THROW( Invalid_Argument ); | |
| 467 goto Fail; | |
| 468 } | |
| 469 | |
| 470 if ( registry ) | |
| 471 { | |
| 472 if ( cff->registry == NULL ) | |
| 473 cff->registry = cff_index_get_sid_string( cff, | |
| 474 dict->cid_registry ); | |
| 475 *registry = cff->registry; | |
| 476 } | |
| 477 | |
| 478 if ( ordering ) | |
| 479 { | |
| 480 if ( cff->ordering == NULL ) | |
| 481 cff->ordering = cff_index_get_sid_string( cff, | |
| 482 dict->cid_ordering ); | |
| 483 *ordering = cff->ordering; | |
| 484 } | |
| 485 | |
| 486 /* | |
| 487 * XXX: According to Adobe TechNote #5176, the supplement in CFF | |
| 488 * can be a real number. We truncate it to fit public API | |
| 489 * since freetype-2.3.6. | |
| 490 */ | |
| 491 if ( supplement ) | |
| 492 { | |
| 493 if ( dict->cid_supplement < FT_INT_MIN || | |
| 494 dict->cid_supplement > FT_INT_MAX ) | |
| 495 FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", | |
| 496 dict->cid_supplement )); | |
| 497 *supplement = (FT_Int)dict->cid_supplement; | |
| 498 } | |
| 499 } | |
| 500 | |
| 501 Fail: | |
| 502 return error; | |
| 503 } | |
| 504 | |
| 505 | |
| 506 static FT_Error | |
| 507 cff_get_is_cid( CFF_Face face, | |
| 508 FT_Bool *is_cid ) | |
| 509 { | |
| 510 FT_Error error = FT_Err_Ok; | |
| 511 CFF_Font cff = (CFF_Font)face->extra.data; | |
| 512 | |
| 513 | |
| 514 *is_cid = 0; | |
| 515 | |
| 516 if ( cff ) | |
| 517 { | |
| 518 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
| 519 | |
| 520 | |
| 521 if ( dict->cid_registry != 0xFFFFU ) | |
| 522 *is_cid = 1; | |
| 523 } | |
| 524 | |
| 525 return error; | |
| 526 } | |
| 527 | |
| 528 | |
| 529 static FT_Error | |
| 530 cff_get_cid_from_glyph_index( CFF_Face face, | |
| 531 FT_UInt glyph_index, | |
| 532 FT_UInt *cid ) | |
| 533 { | |
| 534 FT_Error error = FT_Err_Ok; | |
| 535 CFF_Font cff; | |
| 536 | |
| 537 | |
| 538 cff = (CFF_Font)face->extra.data; | |
| 539 | |
| 540 if ( cff ) | |
| 541 { | |
| 542 FT_UInt c; | |
| 543 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
| 544 | |
| 545 | |
| 546 if ( dict->cid_registry == 0xFFFFU ) | |
| 547 { | |
| 548 error = FT_THROW( Invalid_Argument ); | |
| 549 goto Fail; | |
| 550 } | |
| 551 | |
| 552 if ( glyph_index > cff->num_glyphs ) | |
| 553 { | |
| 554 error = FT_THROW( Invalid_Argument ); | |
| 555 goto Fail; | |
| 556 } | |
| 557 | |
| 558 c = cff->charset.sids[glyph_index]; | |
| 559 | |
| 560 if ( cid ) | |
| 561 *cid = c; | |
| 562 } | |
| 563 | |
| 564 Fail: | |
| 565 return error; | |
| 566 } | |
| 567 | |
| 568 | |
| 569 FT_DEFINE_SERVICE_CIDREC( | |
| 570 cff_service_cid_info, | |
| 571 (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, | |
| 572 (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, | |
| 573 (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index | |
| 574 ) | |
| 575 | |
| 576 | |
| 577 /* | |
| 578 * PROPERTY SERVICE | |
| 579 * | |
| 580 */ | |
| 581 static FT_Error | |
| 582 cff_property_set( FT_Module module, /* CFF_Driver */ | |
| 583 const char* property_name, | |
| 584 const void* value ) | |
| 585 { | |
| 586 FT_Error error = FT_Err_Ok; | |
| 587 CFF_Driver driver = (CFF_Driver)module; | |
| 588 | |
| 589 | |
| 590 if ( !ft_strcmp( property_name, "hinting-engine" ) ) | |
| 591 { | |
| 592 FT_UInt* hinting_engine = (FT_UInt*)value; | |
| 593 | |
| 594 | |
| 595 #ifndef CFF_CONFIG_OPTION_OLD_ENGINE | |
| 596 if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) | |
| 597 error = FT_ERR( Unimplemented_Feature ); | |
| 598 else | |
| 599 #endif | |
| 600 driver->hinting_engine = *hinting_engine; | |
| 601 | |
| 602 return error; | |
| 603 } | |
| 604 else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) | |
| 605 { | |
| 606 FT_Bool* no_stem_darkening = (FT_Bool*)value; | |
| 607 | |
| 608 | |
| 609 driver->no_stem_darkening = *no_stem_darkening; | |
| 610 | |
| 611 return error; | |
| 612 } | |
| 613 | |
| 614 FT_TRACE0(( "cff_property_set: missing property `%s'\n", | |
| 615 property_name )); | |
| 616 return FT_THROW( Missing_Property ); | |
| 617 } | |
| 618 | |
| 619 | |
| 620 static FT_Error | |
| 621 cff_property_get( FT_Module module, /* CFF_Driver */ | |
| 622 const char* property_name, | |
| 623 const void* value ) | |
| 624 { | |
| 625 FT_Error error = FT_Err_Ok; | |
| 626 CFF_Driver driver = (CFF_Driver)module; | |
| 627 | |
| 628 FT_UInt hinting_engine = driver->hinting_engine; | |
| 629 FT_Bool no_stem_darkening = driver->no_stem_darkening; | |
| 630 | |
| 631 | |
| 632 if ( !ft_strcmp( property_name, "hinting-engine" ) ) | |
| 633 { | |
| 634 FT_UInt* val = (FT_UInt*)value; | |
| 635 | |
| 636 | |
| 637 *val = hinting_engine; | |
| 638 | |
| 639 return error; | |
| 640 } | |
| 641 else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) | |
| 642 { | |
| 643 FT_Bool* val = (FT_Bool*)value; | |
| 644 | |
| 645 | |
| 646 *val = no_stem_darkening; | |
| 647 | |
| 648 return error; | |
| 649 } | |
| 650 | |
| 651 FT_TRACE0(( "cff_property_get: missing property `%s'\n", | |
| 652 property_name )); | |
| 653 return FT_THROW( Missing_Property ); | |
| 654 } | |
| 655 | |
| 656 | |
| 657 FT_DEFINE_SERVICE_PROPERTIESREC( | |
| 658 cff_service_properties, | |
| 659 (FT_Properties_SetFunc)cff_property_set, | |
| 660 (FT_Properties_GetFunc)cff_property_get ) | |
| 661 | |
| 662 | |
| 663 /*************************************************************************/ | |
| 664 /*************************************************************************/ | |
| 665 /*************************************************************************/ | |
| 666 /**** ****/ | |
| 667 /**** ****/ | |
| 668 /**** D R I V E R I N T E R F A C E ****/ | |
| 669 /**** ****/ | |
| 670 /**** ****/ | |
| 671 /*************************************************************************/ | |
| 672 /*************************************************************************/ | |
| 673 /*************************************************************************/ | |
| 674 | |
| 675 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES | |
| 676 FT_DEFINE_SERVICEDESCREC7( | |
| 677 cff_services, | |
| 678 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, | |
| 679 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, | |
| 680 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, | |
| 681 FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, | |
| 682 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, | |
| 683 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, | |
| 684 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET | |
| 685 ) | |
| 686 #else | |
| 687 FT_DEFINE_SERVICEDESCREC6( | |
| 688 cff_services, | |
| 689 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, | |
| 690 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, | |
| 691 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, | |
| 692 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, | |
| 693 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, | |
| 694 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET | |
| 695 ) | |
| 696 #endif | |
| 697 | |
| 698 | |
| 699 FT_CALLBACK_DEF( FT_Module_Interface ) | |
| 700 cff_get_interface( FT_Module driver, /* CFF_Driver */ | |
| 701 const char* module_interface ) | |
| 702 { | |
| 703 FT_Library library; | |
| 704 FT_Module sfnt; | |
| 705 FT_Module_Interface result; | |
| 706 | |
| 707 | |
| 708 /* CFF_SERVICES_GET derefers `library' in PIC mode */ | |
| 709 #ifdef FT_CONFIG_OPTION_PIC | |
| 710 if ( !driver ) | |
| 711 return NULL; | |
| 712 library = driver->library; | |
| 713 if ( !library ) | |
| 714 return NULL; | |
| 715 #endif | |
| 716 | |
| 717 result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); | |
| 718 if ( result != NULL ) | |
| 719 return result; | |
| 720 | |
| 721 /* `driver' is not yet evaluated in non-PIC mode */ | |
| 722 #ifndef FT_CONFIG_OPTION_PIC | |
| 723 if ( !driver ) | |
| 724 return NULL; | |
| 725 library = driver->library; | |
| 726 if ( !library ) | |
| 727 return NULL; | |
| 728 #endif | |
| 729 | |
| 730 /* we pass our request to the `sfnt' module */ | |
| 731 sfnt = FT_Get_Module( library, "sfnt" ); | |
| 732 | |
| 733 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; | |
| 734 } | |
| 735 | |
| 736 | |
| 737 /* The FT_DriverInterface structure is defined in ftdriver.h. */ | |
| 738 | |
| 739 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS | |
| 740 #define CFF_SIZE_SELECT cff_size_select | |
| 741 #else | |
| 742 #define CFF_SIZE_SELECT 0 | |
| 743 #endif | |
| 744 | |
| 745 FT_DEFINE_DRIVER( | |
| 746 cff_driver_class, | |
| 747 | |
| 748 FT_MODULE_FONT_DRIVER | | |
| 749 FT_MODULE_DRIVER_SCALABLE | | |
| 750 FT_MODULE_DRIVER_HAS_HINTER, | |
| 751 | |
| 752 sizeof ( CFF_DriverRec ), | |
| 753 "cff", | |
| 754 0x10000L, | |
| 755 0x20000L, | |
| 756 | |
| 757 0, /* module-specific interface */ | |
| 758 | |
| 759 cff_driver_init, | |
| 760 cff_driver_done, | |
| 761 cff_get_interface, | |
| 762 | |
| 763 /* now the specific driver fields */ | |
| 764 sizeof ( TT_FaceRec ), | |
| 765 sizeof ( CFF_SizeRec ), | |
| 766 sizeof ( CFF_GlyphSlotRec ), | |
| 767 | |
| 768 cff_face_init, | |
| 769 cff_face_done, | |
| 770 cff_size_init, | |
| 771 cff_size_done, | |
| 772 cff_slot_init, | |
| 773 cff_slot_done, | |
| 774 | |
| 775 cff_glyph_load, | |
| 776 | |
| 777 cff_get_kerning, | |
| 778 0, /* FT_Face_AttachFunc */ | |
| 779 cff_get_advances, | |
| 780 | |
| 781 cff_size_request, | |
| 782 | |
| 783 CFF_SIZE_SELECT | |
| 784 ) | |
| 785 | |
| 786 | |
| 787 /* END */ | |
| OLD | NEW |