1 /***************************************************************************/
5 /* High-level SFNT driver interface (body). */
7 /* Copyright 1996-2007, 2009-2014 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
54 /*************************************************************************/
56 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
57 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
58 /* messages during execution. */
61 #define FT_COMPONENT trace_sfdriver
70 get_sfnt_table( TT_Face face
,
79 table
= &face
->header
;
83 table
= &face
->horizontal
;
87 table
= face
->vertical_info
? &face
->vertical
: NULL
;
91 table
= face
->os2
.version
== 0xFFFFU
? NULL
: &face
->os2
;
95 table
= &face
->postscript
;
99 table
= &face
->max_profile
;
103 table
= face
->pclt
.Version
? &face
->pclt
: NULL
;
115 sfnt_table_info( TT_Face face
,
121 if ( !offset
|| !length
)
122 return FT_THROW( Invalid_Argument
);
125 *length
= face
->num_tables
;
128 if ( idx
>= face
->num_tables
)
129 return FT_THROW( Table_Missing
);
131 *tag
= face
->dir_tables
[idx
].Tag
;
132 *offset
= face
->dir_tables
[idx
].Offset
;
133 *length
= face
->dir_tables
[idx
].Length
;
140 FT_DEFINE_SERVICE_SFNT_TABLEREC(
141 sfnt_service_sfnt_table
,
142 (FT_SFNT_TableLoadFunc
)tt_face_load_any
,
143 (FT_SFNT_TableGetFunc
) get_sfnt_table
,
144 (FT_SFNT_TableInfoFunc
)sfnt_table_info
)
147 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
155 sfnt_get_glyph_name( TT_Face face
,
164 error
= tt_face_get_ps_name( face
, glyph_index
, &gname
);
166 FT_STRCPYN( buffer
, gname
, buffer_max
);
173 sfnt_get_name_index( TT_Face face
,
174 FT_String
* glyph_name
)
176 FT_Face root
= &face
->root
;
178 FT_UInt i
, max_gid
= FT_UINT_MAX
;
181 if ( root
->num_glyphs
< 0 )
183 else if ( (FT_ULong
)root
->num_glyphs
< FT_UINT_MAX
)
184 max_gid
= (FT_UInt
)root
->num_glyphs
;
186 FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
187 FT_UINT_MAX
, root
->num_glyphs
));
189 for ( i
= 0; i
< max_gid
; i
++ )
192 FT_Error error
= tt_face_get_ps_name( face
, i
, &gname
);
198 if ( !ft_strcmp( glyph_name
, gname
) )
206 FT_DEFINE_SERVICE_GLYPHDICTREC(
207 sfnt_service_glyph_dict
,
208 (FT_GlyphDict_GetNameFunc
) sfnt_get_glyph_name
,
209 (FT_GlyphDict_NameIndexFunc
)sfnt_get_name_index
)
212 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
216 * POSTSCRIPT NAME SERVICE
221 sfnt_get_ps_name( TT_Face face
)
223 FT_Int n
, found_win
, found_apple
;
224 const char* result
= NULL
;
227 /* shouldn't happen, but just in case to avoid memory leaks */
228 if ( face
->postscript_name
)
229 return face
->postscript_name
;
231 /* scan the name table to see whether we have a Postscript name here, */
232 /* either in Macintosh or Windows platform encodings */
236 for ( n
= 0; n
< face
->num_names
; n
++ )
238 TT_NameEntryRec
* name
= face
->name_table
.names
+ n
;
241 if ( name
->nameID
== 6 && name
->stringLength
> 0 )
243 if ( name
->platformID
== 3 &&
244 name
->encodingID
== 1 &&
245 name
->languageID
== 0x409 )
248 if ( name
->platformID
== 1 &&
249 name
->encodingID
== 0 &&
250 name
->languageID
== 0 )
255 if ( found_win
!= -1 )
257 FT_Memory memory
= face
->root
.memory
;
258 TT_NameEntryRec
* name
= face
->name_table
.names
+ found_win
;
259 FT_UInt len
= name
->stringLength
/ 2;
260 FT_Error error
= FT_Err_Ok
;
265 if ( !FT_ALLOC( result
, name
->stringLength
+ 1 ) )
267 FT_Stream stream
= face
->name_table
.stream
;
268 FT_String
* r
= (FT_String
*)result
;
272 if ( FT_STREAM_SEEK( name
->stringOffset
) ||
273 FT_FRAME_ENTER( name
->stringLength
) )
276 name
->stringLength
= 0;
277 name
->stringOffset
= 0;
278 FT_FREE( name
->string
);
283 p
= (FT_Byte
*)stream
->cursor
;
285 for ( ; len
> 0; len
--, p
+= 2 )
287 if ( p
[0] == 0 && p
[1] >= 32 && p
[1] < 128 )
297 if ( found_apple
!= -1 )
299 FT_Memory memory
= face
->root
.memory
;
300 TT_NameEntryRec
* name
= face
->name_table
.names
+ found_apple
;
301 FT_UInt len
= name
->stringLength
;
302 FT_Error error
= FT_Err_Ok
;
307 if ( !FT_ALLOC( result
, len
+ 1 ) )
309 FT_Stream stream
= face
->name_table
.stream
;
312 if ( FT_STREAM_SEEK( name
->stringOffset
) ||
313 FT_STREAM_READ( result
, len
) )
315 name
->stringOffset
= 0;
316 name
->stringLength
= 0;
317 FT_FREE( name
->string
);
321 ((char*)result
)[len
] = '\0';
326 face
->postscript_name
= result
;
331 FT_DEFINE_SERVICE_PSFONTNAMEREC(
332 sfnt_service_ps_name
,
333 (FT_PsName_GetFunc
)sfnt_get_ps_name
)
339 FT_DEFINE_SERVICE_TTCMAPSREC(
340 tt_service_get_cmap_info
,
341 (TT_CMap_Info_GetFunc
)tt_get_cmap_info
)
344 #ifdef TT_CONFIG_OPTION_BDF
347 sfnt_get_charset_id( TT_Face face
,
348 const char* *acharset_encoding
,
349 const char* *acharset_registry
)
351 BDF_PropertyRec encoding
, registry
;
355 /* XXX: I don't know whether this is correct, since
356 * tt_face_find_bdf_prop only returns something correct if we have
357 * previously selected a size that is listed in the BDF table.
358 * Should we change the BDF table format to include single offsets
359 * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
361 error
= tt_face_find_bdf_prop( face
, "CHARSET_REGISTRY", ®istry
);
364 error
= tt_face_find_bdf_prop( face
, "CHARSET_ENCODING", &encoding
);
367 if ( registry
.type
== BDF_PROPERTY_TYPE_ATOM
&&
368 encoding
.type
== BDF_PROPERTY_TYPE_ATOM
)
370 *acharset_encoding
= encoding
.u
.atom
;
371 *acharset_registry
= registry
.u
.atom
;
374 error
= FT_THROW( Invalid_Argument
);
382 FT_DEFINE_SERVICE_BDFRec(
384 (FT_BDF_GetCharsetIdFunc
)sfnt_get_charset_id
,
385 (FT_BDF_GetPropertyFunc
) tt_face_find_bdf_prop
)
388 #endif /* TT_CONFIG_OPTION_BDF */
395 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
396 FT_DEFINE_SERVICEDESCREC5(
398 FT_SERVICE_ID_SFNT_TABLE
, &SFNT_SERVICE_SFNT_TABLE_GET
,
399 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME
, &SFNT_SERVICE_PS_NAME_GET
,
400 FT_SERVICE_ID_GLYPH_DICT
, &SFNT_SERVICE_GLYPH_DICT_GET
,
401 FT_SERVICE_ID_BDF
, &SFNT_SERVICE_BDF_GET
,
402 FT_SERVICE_ID_TT_CMAP
, &TT_SERVICE_CMAP_INFO_GET
)
403 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
404 FT_DEFINE_SERVICEDESCREC4(
406 FT_SERVICE_ID_SFNT_TABLE
, &SFNT_SERVICE_SFNT_TABLE_GET
,
407 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME
, &SFNT_SERVICE_PS_NAME_GET
,
408 FT_SERVICE_ID_GLYPH_DICT
, &SFNT_SERVICE_GLYPH_DICT_GET
,
409 FT_SERVICE_ID_TT_CMAP
, &TT_SERVICE_CMAP_INFO_GET
)
410 #elif defined TT_CONFIG_OPTION_BDF
411 FT_DEFINE_SERVICEDESCREC4(
413 FT_SERVICE_ID_SFNT_TABLE
, &SFNT_SERVICE_SFNT_TABLE_GET
,
414 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME
, &SFNT_SERVICE_PS_NAME_GET
,
415 FT_SERVICE_ID_BDF
, &SFNT_SERVICE_BDF_GET
,
416 FT_SERVICE_ID_TT_CMAP
, &TT_SERVICE_CMAP_INFO_GET
)
418 FT_DEFINE_SERVICEDESCREC3(
420 FT_SERVICE_ID_SFNT_TABLE
, &SFNT_SERVICE_SFNT_TABLE_GET
,
421 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME
, &SFNT_SERVICE_PS_NAME_GET
,
422 FT_SERVICE_ID_TT_CMAP
, &TT_SERVICE_CMAP_INFO_GET
)
426 FT_CALLBACK_DEF( FT_Module_Interface
)
427 sfnt_get_interface( FT_Module module
,
428 const char* module_interface
)
430 /* SFNT_SERVICES_GET dereferences `library' in PIC mode */
431 #ifdef FT_CONFIG_OPTION_PIC
437 library
= module
->library
;
444 return ft_service_list_lookup( SFNT_SERVICES_GET
, module_interface
);
448 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
449 #define PUT_EMBEDDED_BITMAPS( a ) a
451 #define PUT_EMBEDDED_BITMAPS( a ) NULL
454 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
455 #define PUT_PS_NAMES( a ) a
457 #define PUT_PS_NAMES( a ) NULL
460 FT_DEFINE_SFNT_INTERFACE(
486 PUT_EMBEDDED_BITMAPS( tt_face_load_bhed
),
488 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image
),
491 PUT_PS_NAMES( tt_face_get_ps_name
),
492 PUT_PS_NAMES( tt_face_free_ps_names
),
494 /* since version 2.1.8 */
497 /* since version 2.2 */
498 tt_face_load_font_dir
,
501 /* see `ttsbit.h' and `sfnt.h' */
502 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit
),
503 PUT_EMBEDDED_BITMAPS( tt_face_free_sbit
),
505 PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike
),
506 PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics
),
515 0, /* not a font driver or renderer */
516 sizeof ( FT_ModuleRec
),
518 "sfnt", /* driver name */
519 0x10000L
, /* driver version 1.0 */
520 0x20000L
, /* driver requires FreeType 2.0 or higher */
522 (const void*)&SFNT_INTERFACE_GET
, /* module specific interface */
524 (FT_Module_Constructor
)0,
525 (FT_Module_Destructor
) 0,
526 (FT_Module_Requester
) sfnt_get_interface
)