1 /***************************************************************************/
2 /* */
3 /* cffdrivr.c */
4 /* */
5 /* OpenType font driver implementation (body). */
6 /* */
7 /* Copyright 1996-2001 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
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. */
15 /* */
16 /***************************************************************************/
19 #include <ft2build.h>
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
26 #include "cffdrivr.h"
27 #include "cffgload.h"
28 #include "cffload.h"
30 #include "cfferrs.h"
33 /*************************************************************************/
34 /* */
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. */
38 /* */
39 #undef FT_COMPONENT
40 #define FT_COMPONENT trace_cffdriver
43 /*************************************************************************/
44 /*************************************************************************/
45 /*************************************************************************/
46 /**** ****/
47 /**** ****/
48 /**** F A C E S ****/
49 /**** ****/
50 /**** ****/
51 /*************************************************************************/
52 /*************************************************************************/
53 /*************************************************************************/
56 #undef PAIR_TAG
57 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
58 (FT_ULong)right )
61 /*************************************************************************/
62 /* */
63 /* <Function> */
64 /* Get_Kerning */
65 /* */
66 /* <Description> */
67 /* A driver method used to return the kerning vector between two */
68 /* glyphs of the same face. */
69 /* */
70 /* <Input> */
71 /* face :: A handle to the source face object. */
72 /* */
73 /* left_glyph :: The index of the left glyph in the kern pair. */
74 /* */
75 /* right_glyph :: The index of the right glyph in the kern pair. */
76 /* */
77 /* <Output> */
78 /* kerning :: The kerning vector. This is in font units for */
79 /* scalable formats, and in pixels for fixed-sizes */
80 /* formats. */
81 /* */
82 /* <Return> */
83 /* FreeType error code. 0 means success. */
84 /* */
85 /* <Note> */
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). */
90 /* */
91 /* They can be implemented by format-specific interfaces. */
92 /* */
93 static FT_Error
94 Get_Kerning( TT_Face face,
95 FT_UInt left_glyph,
96 FT_UInt right_glyph,
97 FT_Vector* kerning )
98 {
99 TT_Kern_0_Pair* pair;
102 if ( !face )
103 return CFF_Err_Invalid_Face_Handle;
105 kerning->x = 0;
106 kerning->y = 0;
108 if ( face->kern_pairs )
109 {
110 /* there are some kerning pairs in this font file! */
111 FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
112 FT_Long left, right;
115 left = 0;
116 right = face->num_kern_pairs - 1;
118 while ( left <= right )
119 {
120 FT_Int middle = left + ( ( right - left ) >> 1 );
121 FT_ULong cur_pair;
124 pair = face->kern_pairs + middle;
125 cur_pair = PAIR_TAG( pair->left, pair->right );
127 if ( cur_pair == search_tag )
128 goto Found;
130 if ( cur_pair < search_tag )
131 left = middle + 1;
132 else
133 right = middle - 1;
134 }
135 }
137 Exit:
138 return CFF_Err_Ok;
140 Found:
141 kerning->x = pair->value;
142 goto Exit;
143 }
146 #undef PAIR_TAG
149 /*************************************************************************/
150 /* */
151 /* <Function> */
152 /* Load_Glyph */
153 /* */
154 /* <Description> */
155 /* A driver method used to load a glyph within a given glyph slot. */
156 /* */
157 /* <Input> */
158 /* slot :: A handle to the target slot object where the glyph */
159 /* will be loaded. */
160 /* */
161 /* size :: A handle to the source face size at which the glyph */
162 /* must be scaled, loaded, etc. */
163 /* */
164 /* glyph_index :: The index of the glyph in the font file. */
165 /* */
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). */
171 /* */
172 /* <Return> */
173 /* FreeType error code. 0 means success. */
174 /* */
175 static FT_Error
176 Load_Glyph( CFF_GlyphSlot slot,
177 CFF_Size size,
178 FT_UShort glyph_index,
179 FT_UInt load_flags )
180 {
181 FT_Error error;
184 if ( !slot )
185 return CFF_Err_Invalid_Slot_Handle;
187 /* check whether we want a scaled outline or bitmap */
188 if ( !size )
189 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
191 if ( load_flags & FT_LOAD_NO_SCALE )
192 size = NULL;
194 /* reset the size object if necessary */
195 if ( size )
196 {
197 /* these two object must have the same parent */
198 if ( size->face != slot->root.face )
199 return CFF_Err_Invalid_Face_Handle;
200 }
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; */
208 return error;
209 }
212 /*************************************************************************/
213 /*************************************************************************/
214 /*************************************************************************/
215 /**** ****/
216 /**** ****/
217 /**** C H A R A C T E R M A P P I N G S ****/
218 /**** ****/
219 /**** ****/
220 /*************************************************************************/
221 /*************************************************************************/
222 /*************************************************************************/
224 static FT_Error
225 cff_get_glyph_name( CFF_Face face,
226 FT_UInt glyph_index,
227 FT_Pointer buffer,
228 FT_UInt buffer_max )
229 {
230 CFF_Font* font = (CFF_Font*)face->extra.data;
231 FT_Memory memory = FT_FACE_MEMORY(face);
232 FT_String* gname;
233 FT_UShort sid;
234 PSNames_Interface* psnames;
235 FT_Error error;
237 psnames = (PSNames_Interface*)FT_Get_Module_Interface(
238 face->root.driver->root.library, "psnames" );
240 if ( !psnames )
241 {
242 FT_ERROR(( "CFF_Init_Face:" ));
243 FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
244 FT_ERROR(( " " ));
245 FT_ERROR(( " without the `PSNames' module\n" ));
246 error = CFF_Err_Unknown_File_Format;
247 goto Exit;
248 }
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 )
257 {
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;
266 }
268 FREE ( gname );
269 error = CFF_Err_Ok;
271 Exit:
272 return error;
273 }
276 /*************************************************************************/
277 /* */
278 /* <Function> */
279 /* cff_get_char_index */
280 /* */
281 /* <Description> */
282 /* Uses a charmap to return a given character code's glyph index. */
283 /* */
284 /* <Input> */
285 /* charmap :: A handle to the source charmap object. */
286 /* charcode :: The character code. */
287 /* */
288 /* <Return> */
289 /* Glyph index. 0 means `undefined character code'. */
290 /* */
291 static FT_UInt
292 cff_get_char_index( TT_CharMap charmap,
293 FT_Long charcode )
294 {
295 FT_Error error;
296 CFF_Face face;
297 TT_CMapTable* cmap;
300 cmap = &charmap->cmap;
301 face = (CFF_Face)charmap->root.face;
303 /* Load table if needed */
304 if ( !cmap->loaded )
305 {
306 SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
309 error = sfnt->load_charmap( face, cmap, face->root.stream );
310 if ( error )
311 return 0;
313 cmap->loaded = TRUE;
314 }
316 return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 );
317 }
320 /*************************************************************************/
321 /* */
322 /* <Function> */
323 /* cff_get_name_index */
324 /* */
325 /* <Description> */
326 /* Uses the psnames module and the CFF font's charset to to return a */
327 /* a given glyph name's glyph index. */
328 /* */
329 /* <Input> */
330 /* face :: A handle to the source face object. */
331 /* */
332 /* glyph_name :: The glyph name. */
333 /* */
334 /* <Return> */
335 /* Glyph index. 0 means `undefined character code'. */
336 /* */
337 static FT_UInt
338 cff_get_name_index( CFF_Face face,
339 FT_String* glyph_name )
340 {
341 CFF_Font* cff;
342 CFF_Charset* charset;
343 PSNames_Interface* psnames;
344 FT_String* name;
345 FT_UShort sid;
346 FT_UInt i;
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++ )
356 {
357 sid = charset->sids[i];
359 if ( sid > 390 )
360 name = CFF_Get_Name( &cff->string_index, sid - 391 );
361 else
362 name = (FT_String *)psnames->adobe_std_strings( sid );
364 if ( !strcmp( glyph_name, name ) )
365 return i;
366 }
368 return 0;
369 }
372 /*************************************************************************/
373 /*************************************************************************/
374 /*************************************************************************/
375 /**** ****/
376 /**** ****/
377 /**** D R I V E R I N T E R F A C E ****/
378 /**** ****/
379 /**** ****/
380 /*************************************************************************/
381 /*************************************************************************/
382 /*************************************************************************/
384 static FT_Module_Interface
385 cff_get_interface( CFF_Driver driver,
386 const char* interface )
387 {
388 FT_Module sfnt;
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;
398 #endif
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;
404 }
407 /* The FT_DriverInterface structure is defined in ftdriver.h. */
409 FT_CALLBACK_TABLE_DEF
410 const FT_Driver_Class cff_driver_class =
411 {
412 /* begin with the FT_Module_Class fields */
413 {
414 ft_module_font_driver | ft_module_driver_scalable,
415 sizeof( CFF_DriverRec ),
416 "cff",
417 0x10000L,
418 0x20000L,
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,
425 },
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
448 };
451 #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
454 /*************************************************************************/
455 /* */
456 /* <Function> */
457 /* getDriverClass */
458 /* */
459 /* <Description> */
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. */
464 /* */
465 /* It shouldn't be implemented in a static build, as each driver must */
466 /* have the same function as an exported entry point. */
467 /* */
468 /* <Return> */
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. */
472 /* */
473 FT_EXPORT_DEF( const FT_Driver_Class* )
474 getDriverClass( void )
475 {
476 return &cff_driver_class;
477 }
480 #endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
483 /* END */