1 /***************************************************************************/
5 /* High-level SFNT driver interface (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 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 ( !tag || !offset || !length )
121 return SFNT_Err_Invalid_Argument;
123 if ( idx >= face->num_tables )
124 return SFNT_Err_Table_Missing;
126 *tag = face->dir_tables[idx].Tag;
127 *offset = face->dir_tables[idx].Offset;
128 *length = face->dir_tables[idx].Length;
134 FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
135 (FT_SFNT_TableLoadFunc)tt_face_load_any,
136 (FT_SFNT_TableGetFunc) get_sfnt_table,
137 (FT_SFNT_TableInfoFunc)sfnt_table_info
141 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
149 sfnt_get_glyph_name( TT_Face face,
158 error = tt_face_get_ps_name( face, glyph_index, &gname );
160 FT_STRCPYN( buffer, gname, buffer_max );
167 sfnt_get_name_index( TT_Face face,
168 FT_String* glyph_name )
170 FT_Face root = &face->root;
171 FT_UInt i, max_gid = FT_UINT_MAX;
174 if ( root->num_glyphs < 0 )
176 else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
177 max_gid = ( FT_UInt ) root->num_glyphs;
179 FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
180 FT_UINT_MAX, root->num_glyphs ));
182 for ( i = 0; i < max_gid; i++ )
185 FT_Error error = tt_face_get_ps_name( face, i, &gname );
191 if ( !ft_strcmp( glyph_name, gname ) )
199 FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
200 (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name,
201 (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
204 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
208 * POSTSCRIPT NAME SERVICE
213 sfnt_get_ps_name( TT_Face face )
215 FT_Int n, found_win, found_apple;
216 const char* result = NULL;
219 /* shouldn't happen, but just in case to avoid memory leaks */
220 if ( face->postscript_name )
221 return face->postscript_name;
223 /* scan the name table to see whether we have a Postscript name here, */
224 /* either in Macintosh or Windows platform encodings */
228 for ( n = 0; n < face->num_names; n++ )
230 TT_NameEntryRec* name = face->name_table.names + n;
233 if ( name->nameID == 6 && name->stringLength > 0 )
235 if ( name->platformID == 3 &&
236 name->encodingID == 1 &&
237 name->languageID == 0x409 )
240 if ( name->platformID == 1 &&
241 name->encodingID == 0 &&
242 name->languageID == 0 )
247 if ( found_win != -1 )
249 FT_Memory memory = face->root.memory;
250 TT_NameEntryRec* name = face->name_table.names + found_win;
251 FT_UInt len = name->stringLength / 2;
252 FT_Error error = SFNT_Err_Ok;
257 if ( !FT_ALLOC( result, name->stringLength + 1 ) )
259 FT_Stream stream = face->name_table.stream;
260 FT_String* r = (FT_String*)result;
261 FT_Byte* p = (FT_Byte*)name->string;
264 if ( FT_STREAM_SEEK( name->stringOffset ) ||
265 FT_FRAME_ENTER( name->stringLength ) )
268 name->stringLength = 0;
269 name->stringOffset = 0;
270 FT_FREE( name->string );
275 p = (FT_Byte*)stream->cursor;
277 for ( ; len > 0; len--, p += 2 )
279 if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
289 if ( found_apple != -1 )
291 FT_Memory memory = face->root.memory;
292 TT_NameEntryRec* name = face->name_table.names + found_apple;
293 FT_UInt len = name->stringLength;
294 FT_Error error = SFNT_Err_Ok;
299 if ( !FT_ALLOC( result, len + 1 ) )
301 FT_Stream stream = face->name_table.stream;
304 if ( FT_STREAM_SEEK( name->stringOffset ) ||
305 FT_STREAM_READ( result, len ) )
307 name->stringOffset = 0;
308 name->stringLength = 0;
309 FT_FREE( name->string );
313 ((char*)result)[len] = '\0';
318 face->postscript_name = result;
322 FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
323 (FT_PsName_GetFunc)sfnt_get_ps_name
330 FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
331 (TT_CMap_Info_GetFunc)tt_get_cmap_info
335 #ifdef TT_CONFIG_OPTION_BDF
338 sfnt_get_charset_id( TT_Face face,
339 const char* *acharset_encoding,
340 const char* *acharset_registry )
342 BDF_PropertyRec encoding, registry;
346 /* XXX: I don't know whether this is correct, since
347 * tt_face_find_bdf_prop only returns something correct if we have
348 * previously selected a size that is listed in the BDF table.
349 * Should we change the BDF table format to include single offsets
350 * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
352 error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry );
355 error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
358 if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
359 encoding.type == BDF_PROPERTY_TYPE_ATOM )
361 *acharset_encoding = encoding.u.atom;
362 *acharset_registry = registry.u.atom;
365 error = FT_Err_Invalid_Argument;
373 FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
374 (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
375 (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop
378 #endif /* TT_CONFIG_OPTION_BDF */
385 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
386 FT_DEFINE_SERVICEDESCREC5(sfnt_services,
387 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
388 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
389 FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
390 FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
391 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
393 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
394 FT_DEFINE_SERVICEDESCREC4(sfnt_services,
395 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
396 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
397 FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
398 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
400 #elif defined TT_CONFIG_OPTION_BDF
401 FT_DEFINE_SERVICEDESCREC4(sfnt_services,
402 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
403 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
404 FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
405 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
408 FT_DEFINE_SERVICEDESCREC3(sfnt_services,
409 FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
410 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
411 FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
416 FT_CALLBACK_DEF( FT_Module_Interface )
417 sfnt_get_interface( FT_Module module,
418 const char* module_interface )
420 FT_Library library = module->library;
424 return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
428 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
430 FT_CALLBACK_DEF( FT_Error )
431 tt_face_load_sfnt_header_stub( TT_Face face,
438 FT_UNUSED( face_index );
441 return FT_Err_Unimplemented_Feature;
445 FT_CALLBACK_DEF( FT_Error )
446 tt_face_load_directory_stub( TT_Face face,
454 return FT_Err_Unimplemented_Feature;
458 FT_CALLBACK_DEF( FT_Error )
459 tt_face_load_hdmx_stub( TT_Face face,
465 return FT_Err_Unimplemented_Feature;
469 FT_CALLBACK_DEF( void )
470 tt_face_free_hdmx_stub( TT_Face face )
476 FT_CALLBACK_DEF( FT_Error )
477 tt_face_set_sbit_strike_stub( TT_Face face,
480 FT_ULong* astrike_index )
483 * We simply forge a FT_Size_Request and call the real function
484 * that does all the work.
486 * This stub might be called by libXfont in the X.Org Xserver,
487 * compiled against version 2.1.8 or newer.
490 FT_Size_RequestRec req;
493 req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
494 req.width = (FT_F26Dot6)x_ppem;
495 req.height = (FT_F26Dot6)y_ppem;
496 req.horiResolution = 0;
497 req.vertResolution = 0;
499 *astrike_index = 0x7FFFFFFFUL;
501 return tt_face_set_sbit_strike( face, &req, astrike_index );
505 FT_CALLBACK_DEF( FT_Error )
506 tt_face_load_sbit_stub( TT_Face face,
513 * This function was originally implemented to load the sbit table.
514 * However, it has been replaced by `tt_face_load_eblc', and this stub
515 * is only there for some rogue clients which would want to call it
516 * directly (which doesn't make much sense).
518 return FT_Err_Unimplemented_Feature;
522 FT_CALLBACK_DEF( void )
523 tt_face_free_sbit_stub( TT_Face face )
525 /* nothing to do in this stub */
530 FT_CALLBACK_DEF( FT_Error )
531 tt_face_load_charmap_stub( TT_Face face,
539 return FT_Err_Unimplemented_Feature;
543 FT_CALLBACK_DEF( FT_Error )
544 tt_face_free_charmap_stub( TT_Face face,
553 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
555 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
556 #define PUT_EMBEDDED_BITMAPS(a) a
558 #define PUT_EMBEDDED_BITMAPS(a) 0
560 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
561 #define PUT_PS_NAMES(a) a
563 #define PUT_PS_NAMES(a) 0
566 FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
576 tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
577 tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
589 tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
590 tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
597 PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
599 tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
600 tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
602 tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
603 tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
605 PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
607 tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
610 PUT_PS_NAMES(tt_face_get_ps_name),
611 PUT_PS_NAMES(tt_face_free_ps_names),
613 tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
614 tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
616 /* since version 2.1.8 */
620 /* since version 2.2 */
622 tt_face_load_font_dir,
625 /* see `ttsbit.h' and `sfnt.h' */
626 PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
627 PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
629 PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
630 PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
636 FT_DEFINE_MODULE(sfnt_module_class,
638 0, /* not a font driver or renderer */
639 sizeof( FT_ModuleRec ),
641 "sfnt", /* driver name */
642 0x10000L, /* driver version 1.0 */
643 0x20000L, /* driver requires FreeType 2.0 or higher */
645 (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */
647 (FT_Module_Constructor)0,
648 (FT_Module_Destructor) 0,
649 (FT_Module_Requester) sfnt_get_interface