Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencffdrivr.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* cffdrivr.c */ 00004 /* */ 00005 /* OpenType font driver implementation (body). */ 00006 /* */ 00007 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ 00008 /* 2010 by */ 00009 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00010 /* */ 00011 /* This file is part of the FreeType project, and may only be used, */ 00012 /* modified, and distributed under the terms of the FreeType project */ 00013 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00014 /* this file you indicate that you have read the license and */ 00015 /* understand and accept it fully. */ 00016 /* */ 00017 /***************************************************************************/ 00018 00019 00020 #include <ft2build.h> 00021 #include FT_FREETYPE_H 00022 #include FT_INTERNAL_DEBUG_H 00023 #include FT_INTERNAL_STREAM_H 00024 #include FT_INTERNAL_SFNT_H 00025 #include FT_SERVICE_CID_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 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00046 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00047 /* messages during execution. */ 00048 /* */ 00049 #undef FT_COMPONENT 00050 #define FT_COMPONENT trace_cffdriver 00051 00052 00053 /*************************************************************************/ 00054 /*************************************************************************/ 00055 /*************************************************************************/ 00056 /**** ****/ 00057 /**** ****/ 00058 /**** F A C E S ****/ 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 /* <Function> */ 00074 /* cff_get_kerning */ 00075 /* */ 00076 /* <Description> */ 00077 /* A driver method used to return the kerning vector between two */ 00078 /* glyphs of the same face. */ 00079 /* */ 00080 /* <Input> */ 00081 /* face :: A handle to the source face object. */ 00082 /* */ 00083 /* left_glyph :: The index of the left glyph in the kern pair. */ 00084 /* */ 00085 /* right_glyph :: The index of the right glyph in the kern pair. */ 00086 /* */ 00087 /* <Output> */ 00088 /* kerning :: The kerning vector. This is in font units for */ 00089 /* scalable formats, and in pixels for fixed-sizes */ 00090 /* formats. */ 00091 /* */ 00092 /* <Return> */ 00093 /* FreeType error code. 0 means success. */ 00094 /* */ 00095 /* <Note> */ 00096 /* Only horizontal layouts (left-to-right & right-to-left) are */ 00097 /* supported by this function. Other layouts, or more sophisticated */ 00098 /* kernings, are out of scope of this method (the basic driver */ 00099 /* interface is meant to be simple). */ 00100 /* */ 00101 /* They can be implemented by format-specific interfaces. */ 00102 /* */ 00103 FT_CALLBACK_DEF( FT_Error ) 00104 cff_get_kerning( FT_Face ttface, /* TT_Face */ 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 /* <Function> */ 00129 /* Load_Glyph */ 00130 /* */ 00131 /* <Description> */ 00132 /* A driver method used to load a glyph within a given glyph slot. */ 00133 /* */ 00134 /* <Input> */ 00135 /* slot :: A handle to the target slot object where the glyph */ 00136 /* will be loaded. */ 00137 /* */ 00138 /* size :: A handle to the source face size at which the glyph */ 00139 /* must be scaled, loaded, etc. */ 00140 /* */ 00141 /* glyph_index :: The index of the glyph in the font file. */ 00142 /* */ 00143 /* load_flags :: A flag indicating what to load for this glyph. The */ 00144 /* FT_LOAD_??? constants can be used to control the */ 00145 /* glyph loading process (e.g., whether the outline */ 00146 /* should be scaled, whether to load bitmaps or not, */ 00147 /* whether to hint the outline, etc). */ 00148 /* */ 00149 /* <Return> */ 00150 /* FreeType error code. 0 means success. */ 00151 /* */ 00152 FT_CALLBACK_DEF( FT_Error ) 00153 Load_Glyph( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ 00154 FT_Size cffsize, /* CFF_Size */ 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 /* check whether we want a scaled outline or bitmap */ 00167 if ( !size ) 00168 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 00169 00170 /* reset the size object if necessary */ 00171 if ( load_flags & FT_LOAD_NO_SCALE ) 00172 size = NULL; 00173 00174 if ( size ) 00175 { 00176 /* these two objects must have the same parent */ 00177 if ( cffsize->face != cffslot->face ) 00178 return CFF_Err_Invalid_Face_Handle; 00179 } 00180 00181 /* now load the glyph outline if necessary */ 00182 error = cff_slot_load( slot, size, glyph_index, load_flags ); 00183 00184 /* force drop-out mode to 2 - irrelevant now */ 00185 /* slot->outline.dropout_mode = 2; */ 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 * GLYPH DICT SERVICE 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_String* gname; 00233 FT_UShort sid; 00234 FT_Error error; 00235 00236 00237 if ( !font->psnames ) 00238 { 00239 FT_ERROR(( "cff_get_glyph_name:" 00240 " cannot get glyph name from CFF & CEF fonts\n" 00241 " " 00242 " without the `PSNames' module\n" )); 00243 error = CFF_Err_Unknown_File_Format; 00244 goto Exit; 00245 } 00246 00247 /* first, locate the sid in the charset table */ 00248 sid = font->charset.sids[glyph_index]; 00249 00250 /* now, lookup the name itself */ 00251 gname = cff_index_get_sid_string( font, sid ); 00252 00253 if ( gname ) 00254 FT_STRCPYN( buffer, gname, buffer_max ); 00255 00256 error = CFF_Err_Ok; 00257 00258 Exit: 00259 return error; 00260 } 00261 00262 00263 static FT_UInt 00264 cff_get_name_index( CFF_Face face, 00265 FT_String* glyph_name ) 00266 { 00267 CFF_Font cff; 00268 CFF_Charset charset; 00269 FT_Service_PsCMaps psnames; 00270 FT_String* name; 00271 FT_UShort sid; 00272 FT_UInt i; 00273 00274 00275 cff = (CFF_FontRec *)face->extra.data; 00276 charset = &cff->charset; 00277 00278 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 00279 if ( !psnames ) 00280 return 0; 00281 00282 for ( i = 0; i < cff->num_glyphs; i++ ) 00283 { 00284 sid = charset->sids[i]; 00285 00286 if ( sid > 390 ) 00287 name = cff_index_get_string( cff, sid - 391 ); 00288 else 00289 name = (FT_String *)psnames->adobe_std_strings( sid ); 00290 00291 if ( !name ) 00292 continue; 00293 00294 if ( !ft_strcmp( glyph_name, name ) ) 00295 return i; 00296 } 00297 00298 return 0; 00299 } 00300 00301 00302 FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict, 00303 (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, 00304 (FT_GlyphDict_NameIndexFunc)cff_get_name_index 00305 ) 00306 00307 00308 /* 00309 * POSTSCRIPT INFO SERVICE 00310 * 00311 */ 00312 00313 static FT_Int 00314 cff_ps_has_glyph_names( FT_Face face ) 00315 { 00316 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; 00317 } 00318 00319 00320 static FT_Error 00321 cff_ps_get_font_info( CFF_Face face, 00322 PS_FontInfoRec* afont_info ) 00323 { 00324 CFF_Font cff = (CFF_Font)face->extra.data; 00325 FT_Error error = CFF_Err_Ok; 00326 00327 00328 if ( cff && cff->font_info == NULL ) 00329 { 00330 CFF_FontRecDict dict = &cff->top_font.font_dict; 00331 PS_FontInfoRec *font_info; 00332 FT_Memory memory = face->root.memory; 00333 00334 00335 if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) 00336 goto Fail; 00337 00338 font_info->version = cff_index_get_sid_string( cff, 00339 dict->version ); 00340 font_info->notice = cff_index_get_sid_string( cff, 00341 dict->notice ); 00342 font_info->full_name = cff_index_get_sid_string( cff, 00343 dict->full_name ); 00344 font_info->family_name = cff_index_get_sid_string( cff, 00345 dict->family_name ); 00346 font_info->weight = cff_index_get_sid_string( cff, 00347 dict->weight ); 00348 font_info->italic_angle = dict->italic_angle; 00349 font_info->is_fixed_pitch = dict->is_fixed_pitch; 00350 font_info->underline_position = (FT_Short)dict->underline_position; 00351 font_info->underline_thickness = (FT_Short)dict->underline_thickness; 00352 00353 cff->font_info = font_info; 00354 } 00355 00356 if ( cff ) 00357 *afont_info = *cff->font_info; 00358 00359 Fail: 00360 return error; 00361 } 00362 00363 00364 FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info, 00365 (PS_GetFontInfoFunc) cff_ps_get_font_info, 00366 (PS_GetFontExtraFunc) NULL, 00367 (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, 00368 (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ 00369 ) 00370 00371 00372 /* 00373 * POSTSCRIPT NAME SERVICE 00374 * 00375 */ 00376 00377 static const char* 00378 cff_get_ps_name( CFF_Face face ) 00379 { 00380 CFF_Font cff = (CFF_Font)face->extra.data; 00381 00382 00383 return (const char*)cff->font_name; 00384 } 00385 00386 00387 FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name, 00388 (FT_PsName_GetFunc)cff_get_ps_name 00389 ) 00390 00391 00392 /* 00393 * TT CMAP INFO 00394 * 00395 * If the charmap is a synthetic Unicode encoding cmap or 00396 * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO 00397 * service defined in SFNT module. 00398 * 00399 * Otherwise call the service function in the sfnt module. 00400 * 00401 */ 00402 static FT_Error 00403 cff_get_cmap_info( FT_CharMap charmap, 00404 TT_CMapInfo *cmap_info ) 00405 { 00406 FT_CMap cmap = FT_CMAP( charmap ); 00407 FT_Error error = CFF_Err_Ok; 00408 FT_Face face = FT_CMAP_FACE( cmap ); 00409 FT_Library library = FT_FACE_LIBRARY( face ); 00410 00411 00412 cmap_info->language = 0; 00413 cmap_info->format = 0; 00414 00415 if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET && 00416 cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET ) 00417 { 00418 FT_Module sfnt = FT_Get_Module( library, "sfnt" ); 00419 FT_Service_TTCMaps service = 00420 (FT_Service_TTCMaps)ft_module_get_service( sfnt, 00421 FT_SERVICE_ID_TT_CMAP ); 00422 00423 00424 if ( service && service->get_cmap_info ) 00425 error = service->get_cmap_info( charmap, cmap_info ); 00426 } 00427 00428 return error; 00429 } 00430 00431 00432 FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info, 00433 (TT_CMap_Info_GetFunc)cff_get_cmap_info 00434 ) 00435 00436 00437 /* 00438 * CID INFO SERVICE 00439 * 00440 */ 00441 static FT_Error 00442 cff_get_ros( CFF_Face face, 00443 const char* *registry, 00444 const char* *ordering, 00445 FT_Int *supplement ) 00446 { 00447 FT_Error error = CFF_Err_Ok; 00448 CFF_Font cff = (CFF_Font)face->extra.data; 00449 00450 00451 if ( cff ) 00452 { 00453 CFF_FontRecDict dict = &cff->top_font.font_dict; 00454 00455 00456 if ( dict->cid_registry == 0xFFFFU ) 00457 { 00458 error = CFF_Err_Invalid_Argument; 00459 goto Fail; 00460 } 00461 00462 if ( registry ) 00463 { 00464 if ( cff->registry == NULL ) 00465 cff->registry = cff_index_get_sid_string( cff, 00466 dict->cid_registry ); 00467 *registry = cff->registry; 00468 } 00469 00470 if ( ordering ) 00471 { 00472 if ( cff->ordering == NULL ) 00473 cff->ordering = cff_index_get_sid_string( cff, 00474 dict->cid_ordering ); 00475 *ordering = cff->ordering; 00476 } 00477 00478 /* 00479 * XXX: According to Adobe TechNote #5176, the supplement in CFF 00480 * can be a real number. We truncate it to fit public API 00481 * since freetype-2.3.6. 00482 */ 00483 if ( supplement ) 00484 { 00485 if ( dict->cid_supplement < FT_INT_MIN || 00486 dict->cid_supplement > FT_INT_MAX ) 00487 FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", 00488 dict->cid_supplement )); 00489 *supplement = (FT_Int)dict->cid_supplement; 00490 } 00491 } 00492 00493 Fail: 00494 return error; 00495 } 00496 00497 00498 static FT_Error 00499 cff_get_is_cid( CFF_Face face, 00500 FT_Bool *is_cid ) 00501 { 00502 FT_Error error = CFF_Err_Ok; 00503 CFF_Font cff = (CFF_Font)face->extra.data; 00504 00505 00506 *is_cid = 0; 00507 00508 if ( cff ) 00509 { 00510 CFF_FontRecDict dict = &cff->top_font.font_dict; 00511 00512 00513 if ( dict->cid_registry != 0xFFFFU ) 00514 *is_cid = 1; 00515 } 00516 00517 return error; 00518 } 00519 00520 00521 static FT_Error 00522 cff_get_cid_from_glyph_index( CFF_Face face, 00523 FT_UInt glyph_index, 00524 FT_UInt *cid ) 00525 { 00526 FT_Error error = CFF_Err_Ok; 00527 CFF_Font cff; 00528 00529 00530 cff = (CFF_Font)face->extra.data; 00531 00532 if ( cff ) 00533 { 00534 FT_UInt c; 00535 CFF_FontRecDict dict = &cff->top_font.font_dict; 00536 00537 00538 if ( dict->cid_registry == 0xFFFFU ) 00539 { 00540 error = CFF_Err_Invalid_Argument; 00541 goto Fail; 00542 } 00543 00544 if ( glyph_index > cff->num_glyphs ) 00545 { 00546 error = CFF_Err_Invalid_Argument; 00547 goto Fail; 00548 } 00549 00550 c = cff->charset.sids[glyph_index]; 00551 00552 if ( cid ) 00553 *cid = c; 00554 } 00555 00556 Fail: 00557 return error; 00558 } 00559 00560 00561 FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info, 00562 (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, 00563 (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, 00564 (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index 00565 ) 00566 00567 00568 /*************************************************************************/ 00569 /*************************************************************************/ 00570 /*************************************************************************/ 00571 /**** ****/ 00572 /**** ****/ 00573 /**** D R I V E R I N T E R F A C E ****/ 00574 /**** ****/ 00575 /**** ****/ 00576 /*************************************************************************/ 00577 /*************************************************************************/ 00578 /*************************************************************************/ 00579 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES 00580 FT_DEFINE_SERVICEDESCREC6(cff_services, 00581 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, 00582 FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, 00583 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, 00584 FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET, 00585 FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, 00586 FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET 00587 ) 00588 #else 00589 FT_DEFINE_SERVICEDESCREC5(cff_services, 00590 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, 00591 FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET, 00592 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET, 00593 FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET, 00594 FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET 00595 ) 00596 #endif 00597 00598 FT_CALLBACK_DEF( FT_Module_Interface ) 00599 cff_get_interface( FT_Module driver, /* CFF_Driver */ 00600 const char* module_interface ) 00601 { 00602 FT_Module sfnt; 00603 FT_Module_Interface result; 00604 00605 00606 result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface ); 00607 if ( result != NULL ) 00608 return result; 00609 00610 if ( !driver ) 00611 return NULL; 00612 00613 /* we pass our request to the `sfnt' module */ 00614 sfnt = FT_Get_Module( driver->library, "sfnt" ); 00615 00616 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; 00617 } 00618 00619 00620 /* The FT_DriverInterface structure is defined in ftdriver.h. */ 00621 00622 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 00623 #define CFF_SIZE_SELECT cff_size_select 00624 #else 00625 #define CFF_SIZE_SELECT 0 00626 #endif 00627 00628 FT_DEFINE_DRIVER(cff_driver_class, 00629 FT_MODULE_FONT_DRIVER | 00630 FT_MODULE_DRIVER_SCALABLE | 00631 FT_MODULE_DRIVER_HAS_HINTER, 00632 00633 sizeof( CFF_DriverRec ), 00634 "cff", 00635 0x10000L, 00636 0x20000L, 00637 00638 0, /* module-specific interface */ 00639 00640 cff_driver_init, 00641 cff_driver_done, 00642 cff_get_interface, 00643 00644 /* now the specific driver fields */ 00645 sizeof( TT_FaceRec ), 00646 sizeof( CFF_SizeRec ), 00647 sizeof( CFF_GlyphSlotRec ), 00648 00649 cff_face_init, 00650 cff_face_done, 00651 cff_size_init, 00652 cff_size_done, 00653 cff_slot_init, 00654 cff_slot_done, 00655 00656 ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ 00657 ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ 00658 00659 Load_Glyph, 00660 00661 cff_get_kerning, 00662 0, /* FT_Face_AttachFunc */ 00663 cff_get_advances, /* FT_Face_GetAdvancesFunc */ 00664 00665 cff_size_request, 00666 00667 CFF_SIZE_SELECT 00668 ) 00669 00670 00671 /* END */ Generated on Sat May 26 2012 04:32:40 for ReactOS by
1.7.6.1
|