1 /***************************************************************************/
5 /* High-level SFNT driver interface (body). */
7 /* Copyright 1996-2007, 2009-2011 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_SFNT_H
22 #include FT_INTERNAL_OBJECTS_H
31 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
35 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
39 #ifdef TT_CONFIG_OPTION_BDF
41 #include FT_SERVICE_BDF_H
48 #include FT_SERVICE_GLYPH_DICT_H
49 #include FT_SERVICE_POSTSCRIPT_NAME_H
50 #include FT_SERVICE_SFNT_H
51 #include FT_SERVICE_TT_CMAP_H
53 /*************************************************************************/
55 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
56 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
57 /* messages during execution. */
60 #define FT_COMPONENT trace_sfdriver
69 get_sfnt_table( TT_Face face,
78 table = &face->header;
82 table = &face->horizontal;
86 table = face->vertical_info ? &face->vertical : 0;
90 table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
94 table = &face->postscript;
98 table = &face->max_profile;
102 table = face->pclt.Version ? &face->pclt : 0;
114 sfnt_table_info( TT_Face face,
120 if ( !offset || !length )
121 return SFNT_Err_Invalid_Argument;
124 *length = face->num_tables;
127 if ( idx >= face->num_tables )
128 return SFNT_Err_Table_Missing;
130 *tag = face->dir_tables[idx].Tag;
131 *offset = face->dir_tables[idx].Offset;
132 *length = face->dir_tables[idx].Length;
139 FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
140 (FT_SFNT_TableLoadFunc)tt_face_load_any,
141 (FT_SFNT_TableGetFunc) get_sfnt_table,
142 (FT_SFNT_TableInfoFunc)sfnt_table_info
146 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
154 sfnt_get_glyph_name( TT_Face face,
163 error = tt_face_get_ps_name( face, glyph_index, &gname );
165 FT_STRCPYN( buffer, gname, buffer_max );
172 sfnt_get_name_index( TT_Face face,
173 FT_String* glyph_name )
175 FT_Face root = &face->root;
176 FT_UInt i, max_gid = FT_UINT_MAX;
179 if ( root->num_glyphs < 0 )
181 else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
182 max_gid = ( FT_UInt ) root->num_glyphs;
184 FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
185 FT_UINT_MAX, root->num_glyphs ));
187 for ( i = 0; i < max_gid; i++ )
190 FT_Error error = tt_face_get_ps_name( face, i, &gname );
196 if ( !ft_strcmp( glyph_name, gname ) )
204 FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
205 (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name,
206 (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
209 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
213 * POSTSCRIPT NAME SERVICE
218 sfnt_get_ps_name( TT_Face face )
220 FT_Int n, found_win, found_apple;
221 const char* result = NULL;
224 /* shouldn't happen, but just in case to avoid memory leaks */
225 if ( face->postscript_name )
226 return face->postscript_name;
228 /* scan the name table to see whether we have a Postscript name here, */
229 /* either in Macintosh or Windows platform encodings */
233 for ( n = 0; n < face->num_names; n++ )
235 TT_NameEntryRec* name = face->name_table.names + n;
238 if ( name->nameID == 6 && name->stringLength > 0 )
240 if ( name->platformID == 3 &&
241 name->encodingID == 1 &&
242 name->languageID == 0x409 )
245 if ( name->platformID == 1 &&
246 name->encodingID == 0 &&
247 name->languageID == 0 )
252 if ( found_win != -1 )
254 FT_Memory memory = face->root.memory;
255 TT_NameEntryRec* name = face->name_table.names + found_win;
256 FT_UInt len = name->stringLength / 2;
257 FT_Error error = SFNT_Err_Ok;
262 if ( !FT_ALLOC( result, name->stringLength + 1 ) )
264 FT_Stream stream = face->name_table.stream;
265 FT_String* r = (FT_String*)result;
266 FT_Byte* p = (FT_Byte*)name->string;
269 if ( FT_STREAM_SEEK( name->stringOffset ) ||
270 FT_FRAME_ENTER( name->stringLength ) )
273 name->stringLength = 0;
274 name->stringOffset = 0;
275 FT_FREE( name->string );
280 p = (FT_Byte*)stream->cursor;
282 for ( ; len > 0; len--, p += 2 )
284 if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
294 if ( found_apple != -1 )
296 FT_Memory memory = face->root.memory;
297 TT_NameEntryRec* name = face->name_table.names + found_apple;
298 FT_UInt len = name->stringLength;
299 FT_Error error = SFNT_Err_Ok;
304 if ( !FT_ALLOC( result, len + 1 ) )
306 FT_Stream stream = face->name_table.stream;
309 if ( FT_STREAM_SEEK( name->stringOffset ) ||
310 FT_STREAM_READ( result, len ) )
312 name->stringOffset = 0;
313 name->stringLength = 0;
314 FT_FREE( name->string );
318 ((char*)result)[len] = '\0';
323 face->postscript_name = result;
327 FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
328 (FT_PsName_GetFunc)sfnt_get_ps_name
335 FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
336 (TT_CMap_Info_GetFunc)tt_get_cmap_info
340 #ifdef TT_CONFIG_OPTION_BDF
343 sfnt_get_charset_id( TT_Face face,
344 const char* *acharset_encoding,
345 const char* *acharset_registry )
347 BDF_PropertyRec encoding, registry;
351 /* XXX: I don't know whether this is correct, since
352 * tt_face_find_bdf_prop only returns something correct if we have
353 * previously selected a size that is listed in the BDF table.
354 * Should we change the BDF table format to include single offsets
355 * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
357 error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry );
360 error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
363 if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
364 encoding.type == BDF_PROPERTY_TYPE_ATOM )
366 *acharset_encoding = encoding.u.atom;
367 *acharset_registry = registry.u.atom;
370 error = SFNT_Err_Invalid_Argument;
378 FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
379 (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
380 (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop
383 #endif /* TT_CONFIG_OPTION_BDF */
390 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
391 FT_DEFINE_SERVICEDESCREC5(sfnt_services,
392 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
393 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
394 FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
395 FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
396 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
398 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
399 FT_DEFINE_SERVICEDESCREC4(sfnt_services,
400 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
401 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
402 FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
403 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
405 #elif defined TT_CONFIG_OPTION_BDF
406 FT_DEFINE_SERVICEDESCREC4(sfnt_services,
407 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
408 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
409 FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
410 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
413 FT_DEFINE_SERVICEDESCREC3(sfnt_services,
414 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
415 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
416 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
421 FT_CALLBACK_DEF( FT_Module_Interface )
422 sfnt_get_interface( FT_Module module,
423 const char* module_interface )
425 /* FT_SFNT_SERVICES_GET derefers `library' in PIC mode */
426 #ifdef FT_CONFIG_OPTION_PIC
432 library = module->library;
438 return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
442 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
444 FT_CALLBACK_DEF( FT_Error )
445 tt_face_load_sfnt_header_stub( TT_Face face,
452 FT_UNUSED( face_index );
455 return SFNT_Err_Unimplemented_Feature;
459 FT_CALLBACK_DEF( FT_Error )
460 tt_face_load_directory_stub( TT_Face face,
468 return SFNT_Err_Unimplemented_Feature;
472 FT_CALLBACK_DEF( FT_Error )
473 tt_face_load_hdmx_stub( TT_Face face,
479 return SFNT_Err_Unimplemented_Feature;
483 FT_CALLBACK_DEF( void )
484 tt_face_free_hdmx_stub( TT_Face face )
490 FT_CALLBACK_DEF( FT_Error )
491 tt_face_set_sbit_strike_stub( TT_Face face,
494 FT_ULong* astrike_index )
497 * We simply forge a FT_Size_Request and call the real function
498 * that does all the work.
500 * This stub might be called by libXfont in the X.Org Xserver,
501 * compiled against version 2.1.8 or newer.
504 FT_Size_RequestRec req;
507 req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
508 req.width = (FT_F26Dot6)x_ppem;
509 req.height = (FT_F26Dot6)y_ppem;
510 req.horiResolution = 0;
511 req.vertResolution = 0;
513 *astrike_index = 0x7FFFFFFFUL;
515 return tt_face_set_sbit_strike( face, &req, astrike_index );
519 FT_CALLBACK_DEF( FT_Error )
520 tt_face_load_sbit_stub( TT_Face face,
527 * This function was originally implemented to load the sbit table.
528 * However, it has been replaced by `tt_face_load_eblc', and this stub
529 * is only there for some rogue clients which would want to call it
530 * directly (which doesn't make much sense).
532 return SFNT_Err_Unimplemented_Feature;
536 FT_CALLBACK_DEF( void )
537 tt_face_free_sbit_stub( TT_Face face )
539 /* nothing to do in this stub */
544 FT_CALLBACK_DEF( FT_Error )
545 tt_face_load_charmap_stub( TT_Face face,
553 return SFNT_Err_Unimplemented_Feature;
557 FT_CALLBACK_DEF( FT_Error )
558 tt_face_free_charmap_stub( TT_Face face,
567 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
569 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
570 #define PUT_EMBEDDED_BITMAPS(a) a
572 #define PUT_EMBEDDED_BITMAPS(a) 0
574 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
575 #define PUT_PS_NAMES(a) a
577 #define PUT_PS_NAMES(a) 0
580 FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
590 tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
591 tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
603 tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
604 tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
611 PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
613 tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
614 tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
616 tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
617 tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
619 PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
621 tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
624 PUT_PS_NAMES(tt_face_get_ps_name),
625 PUT_PS_NAMES(tt_face_free_ps_names),
627 tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
628 tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
630 /* since version 2.1.8 */
634 /* since version 2.2 */
636 tt_face_load_font_dir,
639 /* see `ttsbit.h' and `sfnt.h' */
640 PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
641 PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
643 PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
644 PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
650 FT_DEFINE_MODULE(sfnt_module_class,
652 0, /* not a font driver or renderer */
653 sizeof ( FT_ModuleRec ),
655 "sfnt", /* driver name */
656 0x10000L, /* driver version 1.0 */
657 0x20000L, /* driver requires FreeType 2.0 or higher */
659 (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */
661 (FT_Module_Constructor)0,
662 (FT_Module_Destructor) 0,
663 (FT_Module_Requester) sfnt_get_interface