1 /***************************************************************************/
5 /* OpenType font driver implementation (body). */
7 /* Copyright 1996-2001 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_FREETYPE_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_STREAM_H
23 #include FT_INTERNAL_SFNT_H
24 #include FT_TRUETYPE_IDS_H
33 /*************************************************************************/
35 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
36 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
37 /* messages during execution. */
40 #define FT_COMPONENT trace_cffdriver
43 /*************************************************************************/
44 /*************************************************************************/
45 /*************************************************************************/
51 /*************************************************************************/
52 /*************************************************************************/
53 /*************************************************************************/
57 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
61 /*************************************************************************/
67 /* A driver method used to return the kerning vector between two */
68 /* glyphs of the same face. */
71 /* face :: A handle to the source face object. */
73 /* left_glyph :: The index of the left glyph in the kern pair. */
75 /* right_glyph :: The index of the right glyph in the kern pair. */
78 /* kerning :: The kerning vector. This is in font units for */
79 /* scalable formats, and in pixels for fixed-sizes */
83 /* FreeType error code. 0 means success. */
86 /* Only horizontal layouts (left-to-right & right-to-left) are */
87 /* supported by this function. Other layouts, or more sophisticated */
88 /* kernings, are out of scope of this method (the basic driver */
89 /* interface is meant to be simple). */
91 /* They can be implemented by format-specific interfaces. */
94 Get_Kerning( TT_Face face,
103 return CFF_Err_Invalid_Face_Handle;
108 if ( face->kern_pairs )
110 /* there are some kerning pairs in this font file! */
111 FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
116 right = face->num_kern_pairs - 1;
118 while ( left <= right )
120 FT_Int middle = left + ( ( right - left ) >> 1 );
124 pair = face->kern_pairs + middle;
125 cur_pair = PAIR_TAG( pair->left, pair->right );
127 if ( cur_pair == search_tag )
130 if ( cur_pair < search_tag )
141 kerning->x = pair->value;
149 /*************************************************************************/
155 /* A driver method used to load a glyph within a given glyph slot. */
158 /* slot :: A handle to the target slot object where the glyph */
159 /* will be loaded. */
161 /* size :: A handle to the source face size at which the glyph */
162 /* must be scaled, loaded, etc. */
164 /* glyph_index :: The index of the glyph in the font file. */
166 /* load_flags :: A flag indicating what to load for this glyph. The */
167 /* FTLOAD_??? constants can be used to control the */
168 /* glyph loading process (e.g., whether the outline */
169 /* should be scaled, whether to load bitmaps or not, */
170 /* whether to hint the outline, etc). */
173 /* FreeType error code. 0 means success. */
176 Load_Glyph( CFF_GlyphSlot slot,
178 FT_UShort glyph_index,
185 return CFF_Err_Invalid_Slot_Handle;
187 /* check whether we want a scaled outline or bitmap */
189 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
191 if ( load_flags & FT_LOAD_NO_SCALE )
194 /* reset the size object if necessary */
197 /* these two object must have the same parent */
198 if ( size->face != slot->root.face )
199 return CFF_Err_Invalid_Face_Handle;
202 /* now load the glyph outline if necessary */
203 error = CFF_Load_Glyph( slot, size, glyph_index, load_flags );
205 /* force drop-out mode to 2 - irrelevant now */
206 /* slot->outline.dropout_mode = 2; */
212 /*************************************************************************/
213 /*************************************************************************/
214 /*************************************************************************/
217 /**** C H A R A C T E R M A P P I N G S ****/
220 /*************************************************************************/
221 /*************************************************************************/
222 /*************************************************************************/
225 cff_get_glyph_name( CFF_Face face,
230 CFF_Font* font = (CFF_Font*)face->extra.data;
231 FT_Memory memory = FT_FACE_MEMORY(face);
234 PSNames_Interface* psnames;
237 psnames = (PSNames_Interface*)FT_Get_Module_Interface(
238 face->root.driver->root.library, "psnames" );
242 FT_ERROR(( "CFF_Init_Face:" ));
243 FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
245 FT_ERROR(( " without the `PSNames' module\n" ));
246 error = CFF_Err_Unknown_File_Format;
250 /* first, locate the sid in the charset table */
251 sid = font->charset.sids[glyph_index];
253 /* now, lookup the name itself */
254 gname = CFF_Get_String( &font->string_index, sid, psnames );
256 if ( buffer_max > 0 )
258 FT_UInt len = strlen( gname );
261 if ( len >= buffer_max )
262 len = buffer_max - 1;
264 MEM_Copy( buffer, gname, len );
265 ((FT_Byte*)buffer)[len] = 0;
276 /*************************************************************************/
279 /* cff_get_char_index */
282 /* Uses a charmap to return a given character code's glyph index. */
285 /* charmap :: A handle to the source charmap object. */
286 /* charcode :: The character code. */
289 /* Glyph index. 0 means `undefined character code'. */
292 cff_get_char_index( TT_CharMap charmap,
300 cmap = &charmap->cmap;
301 face = (CFF_Face)charmap->root.face;
303 /* Load table if needed */
306 SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
309 error = sfnt->load_charmap( face, cmap, face->root.stream );
316 return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 );
320 /*************************************************************************/
323 /* cff_get_name_index */
326 /* Uses the psnames module and the CFF font's charset to to return a */
327 /* a given glyph name's glyph index. */
330 /* face :: A handle to the source face object. */
332 /* glyph_name :: The glyph name. */
335 /* Glyph index. 0 means `undefined character code'. */
338 cff_get_name_index( CFF_Face face,
339 FT_String* glyph_name )
342 CFF_Charset* charset;
343 PSNames_Interface* psnames;
349 cff = face->extra.data;
350 charset = &cff->charset;
352 psnames = (PSNames_Interface*)FT_Get_Module_Interface(
353 face->root.driver->root.library, "psnames" );
355 for ( i = 0; i < cff->num_glyphs; i++ )
357 sid = charset->sids[i];
360 name = CFF_Get_Name( &cff->string_index, sid - 391 );
362 name = (FT_String *)psnames->adobe_std_strings( sid );
364 if ( !strcmp( glyph_name, name ) )
372 /*************************************************************************/
373 /*************************************************************************/
374 /*************************************************************************/
377 /**** D R I V E R I N T E R F A C E ****/
380 /*************************************************************************/
381 /*************************************************************************/
382 /*************************************************************************/
384 static FT_Module_Interface
385 cff_get_interface( CFF_Driver driver,
386 const char* interface )
390 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
392 if ( strcmp( (const char*)interface, "glyph_name" ) == 0 )
393 return (FT_Module_Interface)cff_get_glyph_name;
395 if ( strcmp( (const char*)interface, "name_index" ) == 0 )
396 return (FT_Module_Interface)cff_get_name_index;
400 /* we simply pass our request to the `sfnt' module */
401 sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
403 return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0;
407 /* The FT_DriverInterface structure is defined in ftdriver.h. */
409 FT_CALLBACK_TABLE_DEF
410 const FT_Driver_Class cff_driver_class =
412 /* begin with the FT_Module_Class fields */
414 ft_module_font_driver | ft_module_driver_scalable,
415 sizeof( CFF_DriverRec ),
420 0, /* module-specific interface */
422 (FT_Module_Constructor)CFF_Init_Driver,
423 (FT_Module_Destructor) CFF_Done_Driver,
424 (FT_Module_Requester) cff_get_interface,
427 /* now the specific driver fields */
428 sizeof( TT_FaceRec ),
429 sizeof( FT_SizeRec ),
430 sizeof( CFF_GlyphSlotRec ),
432 (FTDriver_initFace) CFF_Init_Face,
433 (FTDriver_doneFace) CFF_Done_Face,
434 (FTDriver_initSize) 0,
435 (FTDriver_doneSize) 0,
436 (FTDriver_initGlyphSlot)0,
437 (FTDriver_doneGlyphSlot)0,
439 (FTDriver_setCharSizes) 0,
440 (FTDriver_setPixelSizes)0,
442 (FTDriver_loadGlyph) Load_Glyph,
443 (FTDriver_getCharIndex) cff_get_char_index,
445 (FTDriver_getKerning) Get_Kerning,
446 (FTDriver_attachFile) 0,
447 (FTDriver_getAdvances) 0
451 #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
454 /*************************************************************************/
460 /* This function is used when compiling the TrueType driver as a */
461 /* shared library (`.DLL' or `.so'). It will be used by the */
462 /* high-level library of FreeType to retrieve the address of the */
463 /* driver's generic interface. */
465 /* It shouldn't be implemented in a static build, as each driver must */
466 /* have the same function as an exported entry point. */
469 /* The address of the TrueType's driver generic interface. The */
470 /* format-specific interface can then be retrieved through the method */
471 /* interface->get_format_interface. */
473 FT_EXPORT_DEF( const FT_Driver_Class* )
474 getDriverClass( void )
476 return &cff_driver_class;
480 #endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */