Bringing apdf from vendor into main branch.
[AROS-Contrib.git] / apdf / freetype2 / cff / cffdrivr.c
blob7a0c0df20a5202602ee3f8c78b79279455efeb8b
1 /***************************************************************************/
2 /* */
3 /* cffdrivr.c */
4 /* */
5 /* OpenType font driver implementation (body). */
6 /* */
7 /* Copyright 1996-2001, 2002 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
25 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
27 #include "cffdrivr.h"
28 #include "cffgload.h"
29 #include "cffload.h"
31 #include "cfferrs.h"
34 /*************************************************************************/
35 /* */
36 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
37 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
38 /* messages during execution. */
39 /* */
40 #undef FT_COMPONENT
41 #define FT_COMPONENT trace_cffdriver
44 /*************************************************************************/
45 /*************************************************************************/
46 /*************************************************************************/
47 /**** ****/
48 /**** ****/
49 /**** F A C E S ****/
50 /**** ****/
51 /**** ****/
52 /*************************************************************************/
53 /*************************************************************************/
54 /*************************************************************************/
57 #undef PAIR_TAG
58 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
59 (FT_ULong)right )
62 /*************************************************************************/
63 /* */
64 /* <Function> */
65 /* Get_Kerning */
66 /* */
67 /* <Description> */
68 /* A driver method used to return the kerning vector between two */
69 /* glyphs of the same face. */
70 /* */
71 /* <Input> */
72 /* face :: A handle to the source face object. */
73 /* */
74 /* left_glyph :: The index of the left glyph in the kern pair. */
75 /* */
76 /* right_glyph :: The index of the right glyph in the kern pair. */
77 /* */
78 /* <Output> */
79 /* kerning :: The kerning vector. This is in font units for */
80 /* scalable formats, and in pixels for fixed-sizes */
81 /* formats. */
82 /* */
83 /* <Return> */
84 /* FreeType error code. 0 means success. */
85 /* */
86 /* <Note> */
87 /* Only horizontal layouts (left-to-right & right-to-left) are */
88 /* supported by this function. Other layouts, or more sophisticated */
89 /* kernings, are out of scope of this method (the basic driver */
90 /* interface is meant to be simple). */
91 /* */
92 /* They can be implemented by format-specific interfaces. */
93 /* */
94 static FT_Error
95 Get_Kerning( TT_Face face,
96 FT_UInt left_glyph,
97 FT_UInt right_glyph,
98 FT_Vector* kerning )
100 TT_Kern0_Pair pair;
103 if ( !face )
104 return CFF_Err_Invalid_Face_Handle;
106 kerning->x = 0;
107 kerning->y = 0;
109 if ( face->kern_pairs )
111 /* there are some kerning pairs in this font file! */
112 FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph );
113 FT_Long left, right;
116 left = 0;
117 right = face->num_kern_pairs - 1;
119 while ( left <= right )
121 FT_Int middle = left + ( ( right - left ) >> 1 );
122 FT_ULong cur_pair;
125 pair = face->kern_pairs + middle;
126 cur_pair = PAIR_TAG( pair->left, pair->right );
128 if ( cur_pair == search_tag )
129 goto Found;
131 if ( cur_pair < search_tag )
132 left = middle + 1;
133 else
134 right = middle - 1;
138 Exit:
139 return CFF_Err_Ok;
141 Found:
142 kerning->x = pair->value;
143 goto Exit;
147 #undef PAIR_TAG
150 /*************************************************************************/
151 /* */
152 /* <Function> */
153 /* Load_Glyph */
154 /* */
155 /* <Description> */
156 /* A driver method used to load a glyph within a given glyph slot. */
157 /* */
158 /* <Input> */
159 /* slot :: A handle to the target slot object where the glyph */
160 /* will be loaded. */
161 /* */
162 /* size :: A handle to the source face size at which the glyph */
163 /* must be scaled, loaded, etc. */
164 /* */
165 /* glyph_index :: The index of the glyph in the font file. */
166 /* */
167 /* load_flags :: A flag indicating what to load for this glyph. The */
168 /* FTLOAD_??? constants can be used to control the */
169 /* glyph loading process (e.g., whether the outline */
170 /* should be scaled, whether to load bitmaps or not, */
171 /* whether to hint the outline, etc). */
172 /* */
173 /* <Return> */
174 /* FreeType error code. 0 means success. */
175 /* */
176 static FT_Error
177 Load_Glyph( CFF_GlyphSlot slot,
178 CFF_Size size,
179 FT_UShort glyph_index,
180 FT_UInt load_flags )
182 FT_Error error;
185 if ( !slot )
186 return CFF_Err_Invalid_Slot_Handle;
188 /* check whether we want a scaled outline or bitmap */
189 if ( !size )
190 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
192 if ( load_flags & FT_LOAD_NO_SCALE )
193 size = NULL;
195 /* reset the size object if necessary */
196 if ( size )
198 /* these two object must have the same parent */
199 if ( size->face != slot->root.face )
200 return CFF_Err_Invalid_Face_Handle;
203 /* now load the glyph outline if necessary */
204 error = CFF_Load_Glyph( slot, size, glyph_index, load_flags );
206 /* force drop-out mode to 2 - irrelevant now */
207 /* slot->outline.dropout_mode = 2; */
209 return error;
213 /*************************************************************************/
214 /*************************************************************************/
215 /*************************************************************************/
216 /**** ****/
217 /**** ****/
218 /**** C H A R A C T E R M A P P I N G S ****/
219 /**** ****/
220 /**** ****/
221 /*************************************************************************/
222 /*************************************************************************/
223 /*************************************************************************/
225 static FT_Error
226 cff_get_glyph_name( CFF_Face face,
227 FT_UInt glyph_index,
228 FT_Pointer buffer,
229 FT_UInt buffer_max )
231 CFF_Font font = (CFF_Font)face->extra.data;
232 FT_Memory memory = FT_FACE_MEMORY( face );
233 FT_String* gname;
234 FT_UShort sid;
235 PSNames_Service psnames;
236 FT_Error error;
239 psnames = (PSNames_Service)FT_Get_Module_Interface(
240 face->root.driver->root.library, "psnames" );
242 if ( !psnames )
244 FT_ERROR(( "cff_get_glyph_name:" ));
245 FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
246 FT_ERROR(( " " ));
247 FT_ERROR(( " without the `PSNames' module\n" ));
248 error = CFF_Err_Unknown_File_Format;
249 goto Exit;
252 /* first, locate the sid in the charset table */
253 sid = font->charset.sids[glyph_index];
255 /* now, lookup the name itself */
256 gname = CFF_Get_String( &font->string_index, sid, psnames );
258 if ( buffer_max > 0 )
260 FT_UInt len = ft_strlen( gname );
263 if ( len >= buffer_max )
264 len = buffer_max - 1;
266 FT_MEM_COPY( buffer, gname, len );
267 ((FT_Byte*)buffer)[len] = 0;
270 FT_FREE ( gname );
271 error = CFF_Err_Ok;
273 Exit:
274 return error;
278 /*************************************************************************/
279 /* */
280 /* <Function> */
281 /* cff_get_char_index */
282 /* */
283 /* <Description> */
284 /* Uses a charmap to return a given character code's glyph index. */
285 /* */
286 /* <Input> */
287 /* charmap :: A handle to the source charmap object. */
288 /* charcode :: The character code. */
289 /* */
290 /* <Return> */
291 /* Glyph index. 0 means `undefined character code'. */
292 /* */
293 static FT_UInt
294 cff_get_char_index( TT_CharMap charmap,
295 FT_Long charcode )
297 FT_Error error;
298 CFF_Face face;
299 TT_CMapTable cmap;
302 cmap = &charmap->cmap;
303 face = (CFF_Face)charmap->root.face;
305 /* Load table if needed */
306 if ( !cmap->loaded )
308 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
311 error = sfnt->load_charmap( face, cmap, face->root.stream );
312 if ( error )
313 return 0;
315 cmap->loaded = TRUE;
318 return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 );
322 /*************************************************************************/
323 /* */
324 /* <Function> */
325 /* cff_get_next_char */
326 /* */
327 /* <Description> */
328 /* Uses a charmap to return the next encoded charcode. */
329 /* */
330 /* <Input> */
331 /* charmap :: A handle to the source charmap object. */
332 /* charcode :: The character code. */
333 /* */
334 /* <Return> */
335 /* Char code. 0 means `no encoded chars above the given one'. */
336 /* */
337 static FT_Long
338 cff_get_next_char( TT_CharMap charmap,
339 FT_Long charcode )
341 FT_Error error;
342 CFF_Face face;
343 TT_CMapTable cmap;
346 cmap = &charmap->cmap;
347 face = (CFF_Face)charmap->root.face;
349 /* Load table if needed */
350 if ( !cmap->loaded )
352 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
355 error = sfnt->load_charmap( face, cmap, face->root.stream );
356 if ( error )
357 return 0;
359 cmap->loaded = TRUE;
362 return ( cmap->get_next_char ? cmap->get_next_char( cmap, charcode )
363 : 0 );
367 /*************************************************************************/
368 /* */
369 /* <Function> */
370 /* cff_get_name_index */
371 /* */
372 /* <Description> */
373 /* Uses the psnames module and the CFF font's charset to to return a */
374 /* a given glyph name's glyph index. */
375 /* */
376 /* <Input> */
377 /* face :: A handle to the source face object. */
378 /* */
379 /* glyph_name :: The glyph name. */
380 /* */
381 /* <Return> */
382 /* Glyph index. 0 means `undefined character code'. */
383 /* */
384 static FT_UInt
385 cff_get_name_index( CFF_Face face,
386 FT_String* glyph_name )
388 CFF_Font cff;
389 CFF_Charset charset;
390 PSNames_Service psnames;
391 FT_Memory memory = FT_FACE_MEMORY( face );
392 FT_String* name;
393 FT_UShort sid;
394 FT_UInt i;
395 FT_Int result;
398 cff = (CFF_FontRec *)face->extra.data;
399 charset = &cff->charset;
401 psnames = (PSNames_Service)FT_Get_Module_Interface(
402 face->root.driver->root.library, "psnames" );
404 for ( i = 0; i < cff->num_glyphs; i++ )
406 sid = charset->sids[i];
408 if ( sid > 390 )
409 name = CFF_Get_Name( &cff->string_index, sid - 391 );
410 else
411 name = (FT_String *)psnames->adobe_std_strings( sid );
413 result = ft_strcmp( glyph_name, name );
415 if ( sid > 390 )
416 FT_FREE( name );
418 if ( !result )
419 return i;
422 return 0;
426 /*************************************************************************/
427 /*************************************************************************/
428 /*************************************************************************/
429 /**** ****/
430 /**** ****/
431 /**** D R I V E R I N T E R F A C E ****/
432 /**** ****/
433 /**** ****/
434 /*************************************************************************/
435 /*************************************************************************/
436 /*************************************************************************/
438 static FT_Module_Interface
439 cff_get_interface( CFF_Driver driver,
440 const char* module_interface )
442 FT_Module sfnt;
445 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
447 if ( ft_strcmp( (const char*)module_interface, "glyph_name" ) == 0 )
448 return (FT_Module_Interface)cff_get_glyph_name;
450 if ( ft_strcmp( (const char*)module_interface, "name_index" ) == 0 )
451 return (FT_Module_Interface)cff_get_name_index;
453 #endif
455 /* we simply pass our request to the `sfnt' module */
456 sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
458 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
462 /* The FT_DriverInterface structure is defined in ftdriver.h. */
464 FT_CALLBACK_TABLE_DEF
465 const FT_Driver_ClassRec cff_driver_class =
467 /* begin with the FT_Module_Class fields */
469 ft_module_font_driver |
470 ft_module_driver_scalable |
471 ft_module_driver_has_hinter,
473 sizeof( CFF_DriverRec ),
474 "cff",
475 0x10000L,
476 0x20000L,
478 0, /* module-specific interface */
480 (FT_Module_Constructor)CFF_Driver_Init,
481 (FT_Module_Destructor) CFF_Driver_Done,
482 (FT_Module_Requester) cff_get_interface,
485 /* now the specific driver fields */
486 sizeof( TT_FaceRec ),
487 sizeof( FT_SizeRec ),
488 sizeof( CFF_GlyphSlotRec ),
490 (FT_Face_InitFunc) CFF_Face_Init,
491 (FT_Face_DoneFunc) CFF_Face_Done,
492 (FT_Size_InitFunc) CFF_Size_Init,
493 (FT_Size_DoneFunc) CFF_Size_Done,
494 (FT_Slot_InitFunc) CFF_GlyphSlot_Init,
495 (FT_Slot_DoneFunc) CFF_GlyphSlot_Done,
497 (FT_Size_ResetPointsFunc) CFF_Size_Reset,
498 (FT_Size_ResetPixelsFunc) CFF_Size_Reset,
500 (FT_Slot_LoadFunc) Load_Glyph,
501 (FT_CharMap_CharIndexFunc)cff_get_char_index,
503 (FT_Face_GetKerningFunc) Get_Kerning,
504 (FT_Face_AttachFunc) 0,
505 (FT_Face_GetAdvancesFunc) 0,
507 (FT_CharMap_CharNextFunc) cff_get_next_char
511 /* END */