Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / modules / freetype2 / src / cff / cffdrivr.c
blob6c3ff989fb0796cedc2e80f3da060deefb2cdc89
1 /***************************************************************************/
2 /* */
3 /* cffdrivr.c */
4 /* */
5 /* OpenType font driver implementation (body). */
6 /* */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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_SERVICE_CID_H
26 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
27 #include FT_SERVICE_POSTSCRIPT_INFO_H
28 #include FT_SERVICE_POSTSCRIPT_NAME_H
29 #include FT_SERVICE_TT_CMAP_H
31 #include "cffdrivr.h"
32 #include "cffgload.h"
33 #include "cffload.h"
34 #include "cffcmap.h"
36 #include "cfferrs.h"
38 #include FT_SERVICE_XFREE86_NAME_H
39 #include FT_SERVICE_GLYPH_DICT_H
42 /*************************************************************************/
43 /* */
44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
46 /* messages during execution. */
47 /* */
48 #undef FT_COMPONENT
49 #define FT_COMPONENT trace_cffdriver
52 /*************************************************************************/
53 /*************************************************************************/
54 /*************************************************************************/
55 /**** ****/
56 /**** ****/
57 /**** F A C E S ****/
58 /**** ****/
59 /**** ****/
60 /*************************************************************************/
61 /*************************************************************************/
62 /*************************************************************************/
65 #undef PAIR_TAG
66 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
67 (FT_ULong)right )
70 /*************************************************************************/
71 /* */
72 /* <Function> */
73 /* cff_get_kerning */
74 /* */
75 /* <Description> */
76 /* A driver method used to return the kerning vector between two */
77 /* glyphs of the same face. */
78 /* */
79 /* <Input> */
80 /* face :: A handle to the source face object. */
81 /* */
82 /* left_glyph :: The index of the left glyph in the kern pair. */
83 /* */
84 /* right_glyph :: The index of the right glyph in the kern pair. */
85 /* */
86 /* <Output> */
87 /* kerning :: The kerning vector. This is in font units for */
88 /* scalable formats, and in pixels for fixed-sizes */
89 /* formats. */
90 /* */
91 /* <Return> */
92 /* FreeType error code. 0 means success. */
93 /* */
94 /* <Note> */
95 /* Only horizontal layouts (left-to-right & right-to-left) are */
96 /* supported by this function. Other layouts, or more sophisticated */
97 /* kernings, are out of scope of this method (the basic driver */
98 /* interface is meant to be simple). */
99 /* */
100 /* They can be implemented by format-specific interfaces. */
101 /* */
102 FT_CALLBACK_DEF( FT_Error )
103 cff_get_kerning( FT_Face ttface, /* TT_Face */
104 FT_UInt left_glyph,
105 FT_UInt right_glyph,
106 FT_Vector* kerning )
108 TT_Face face = (TT_Face)ttface;
109 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
112 kerning->x = 0;
113 kerning->y = 0;
115 if ( sfnt )
116 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
118 return CFF_Err_Ok;
122 #undef PAIR_TAG
125 /*************************************************************************/
126 /* */
127 /* <Function> */
128 /* Load_Glyph */
129 /* */
130 /* <Description> */
131 /* A driver method used to load a glyph within a given glyph slot. */
132 /* */
133 /* <Input> */
134 /* slot :: A handle to the target slot object where the glyph */
135 /* will be loaded. */
136 /* */
137 /* size :: A handle to the source face size at which the glyph */
138 /* must be scaled, loaded, etc. */
139 /* */
140 /* glyph_index :: The index of the glyph in the font file. */
141 /* */
142 /* load_flags :: A flag indicating what to load for this glyph. The */
143 /* FT_LOAD_??? constants can be used to control the */
144 /* glyph loading process (e.g., whether the outline */
145 /* should be scaled, whether to load bitmaps or not, */
146 /* whether to hint the outline, etc). */
147 /* */
148 /* <Return> */
149 /* FreeType error code. 0 means success. */
150 /* */
151 FT_CALLBACK_DEF( FT_Error )
152 Load_Glyph( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */
153 FT_Size cffsize, /* CFF_Size */
154 FT_UInt glyph_index,
155 FT_Int32 load_flags )
157 FT_Error error;
158 CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot;
159 CFF_Size size = (CFF_Size)cffsize;
162 if ( !slot )
163 return CFF_Err_Invalid_Slot_Handle;
165 /* check whether we want a scaled outline or bitmap */
166 if ( !size )
167 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
169 /* reset the size object if necessary */
170 if ( load_flags & FT_LOAD_NO_SCALE )
171 size = NULL;
173 if ( size )
175 /* these two objects must have the same parent */
176 if ( cffsize->face != cffslot->face )
177 return CFF_Err_Invalid_Face_Handle;
180 /* now load the glyph outline if necessary */
181 error = cff_slot_load( slot, size, glyph_index, load_flags );
183 /* force drop-out mode to 2 - irrelevant now */
184 /* slot->outline.dropout_mode = 2; */
186 return error;
191 * GLYPH DICT SERVICE
195 static FT_Error
196 cff_get_glyph_name( CFF_Face face,
197 FT_UInt glyph_index,
198 FT_Pointer buffer,
199 FT_UInt buffer_max )
201 CFF_Font font = (CFF_Font)face->extra.data;
202 FT_Memory memory = FT_FACE_MEMORY( face );
203 FT_String* gname;
204 FT_UShort sid;
205 FT_Service_PsCMaps psnames;
206 FT_Error error;
209 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
210 if ( !psnames )
212 FT_ERROR(( "cff_get_glyph_name:" ));
213 FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" ));
214 FT_ERROR(( " " ));
215 FT_ERROR(( " without the `PSNames' module\n" ));
216 error = CFF_Err_Unknown_File_Format;
217 goto Exit;
220 /* first, locate the sid in the charset table */
221 sid = font->charset.sids[glyph_index];
223 /* now, lookup the name itself */
224 gname = cff_index_get_sid_string( &font->string_index, sid, psnames );
226 if ( gname )
227 FT_STRCPYN( buffer, gname, buffer_max );
229 FT_FREE( gname );
230 error = CFF_Err_Ok;
232 Exit:
233 return error;
237 static FT_UInt
238 cff_get_name_index( CFF_Face face,
239 FT_String* glyph_name )
241 CFF_Font cff;
242 CFF_Charset charset;
243 FT_Service_PsCMaps psnames;
244 FT_Memory memory = FT_FACE_MEMORY( face );
245 FT_String* name;
246 FT_UShort sid;
247 FT_UInt i;
248 FT_Int result;
251 cff = (CFF_FontRec *)face->extra.data;
252 charset = &cff->charset;
254 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
255 if ( !psnames )
256 return 0;
258 for ( i = 0; i < cff->num_glyphs; i++ )
260 sid = charset->sids[i];
262 if ( sid > 390 )
263 name = cff_index_get_name( &cff->string_index, sid - 391 );
264 else
265 name = (FT_String *)psnames->adobe_std_strings( sid );
267 if ( !name )
268 continue;
270 result = ft_strcmp( glyph_name, name );
272 if ( sid > 390 )
273 FT_FREE( name );
275 if ( !result )
276 return i;
279 return 0;
283 static const FT_Service_GlyphDictRec cff_service_glyph_dict =
285 (FT_GlyphDict_GetNameFunc) cff_get_glyph_name,
286 (FT_GlyphDict_NameIndexFunc)cff_get_name_index,
291 * POSTSCRIPT INFO SERVICE
295 static FT_Int
296 cff_ps_has_glyph_names( FT_Face face )
298 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
302 static FT_Error
303 cff_ps_get_font_info( CFF_Face face,
304 PS_FontInfoRec* afont_info )
306 CFF_Font cff = (CFF_Font)face->extra.data;
307 FT_Error error = FT_Err_Ok;
310 if ( cff && cff->font_info == NULL )
312 CFF_FontRecDict dict = &cff->top_font.font_dict;
313 PS_FontInfoRec *font_info;
314 FT_Memory memory = face->root.memory;
315 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
318 if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
319 goto Fail;
321 font_info->version = cff_index_get_sid_string( &cff->string_index,
322 dict->version,
323 psnames );
324 font_info->notice = cff_index_get_sid_string( &cff->string_index,
325 dict->notice,
326 psnames );
327 font_info->full_name = cff_index_get_sid_string( &cff->string_index,
328 dict->full_name,
329 psnames );
330 font_info->family_name = cff_index_get_sid_string( &cff->string_index,
331 dict->family_name,
332 psnames );
333 font_info->weight = cff_index_get_sid_string( &cff->string_index,
334 dict->weight,
335 psnames );
336 font_info->italic_angle = dict->italic_angle;
337 font_info->is_fixed_pitch = dict->is_fixed_pitch;
338 font_info->underline_position = (FT_Short)dict->underline_position;
339 font_info->underline_thickness = (FT_Short)dict->underline_thickness;
341 cff->font_info = font_info;
344 *afont_info = *cff->font_info;
346 Fail:
347 return error;
351 static const FT_Service_PsInfoRec cff_service_ps_info =
353 (PS_GetFontInfoFunc) cff_ps_get_font_info,
354 (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
355 (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
360 * POSTSCRIPT NAME SERVICE
364 static const char*
365 cff_get_ps_name( CFF_Face face )
367 CFF_Font cff = (CFF_Font)face->extra.data;
370 return (const char*)cff->font_name;
374 static const FT_Service_PsFontNameRec cff_service_ps_name =
376 (FT_PsName_GetFunc)cff_get_ps_name
381 * TT CMAP INFO
383 * If the charmap is a synthetic Unicode encoding cmap or
384 * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
385 * service defined in SFNT module.
387 * Otherwise call the service function in the sfnt module.
390 static FT_Error
391 cff_get_cmap_info( FT_CharMap charmap,
392 TT_CMapInfo *cmap_info )
394 FT_CMap cmap = FT_CMAP( charmap );
395 FT_Error error = CFF_Err_Ok;
398 cmap_info->language = 0;
400 if ( cmap->clazz != &cff_cmap_encoding_class_rec &&
401 cmap->clazz != &cff_cmap_unicode_class_rec )
403 FT_Face face = FT_CMAP_FACE( cmap );
404 FT_Library library = FT_FACE_LIBRARY( face );
405 FT_Module sfnt = FT_Get_Module( library, "sfnt" );
406 FT_Service_TTCMaps service =
407 (FT_Service_TTCMaps)ft_module_get_service( sfnt,
408 FT_SERVICE_ID_TT_CMAP );
411 if ( service && service->get_cmap_info )
412 error = service->get_cmap_info( charmap, cmap_info );
415 return error;
419 static const FT_Service_TTCMapsRec cff_service_get_cmap_info =
421 (TT_CMap_Info_GetFunc)cff_get_cmap_info
426 * CID INFO SERVICE
429 static FT_Error
430 cff_get_ros( CFF_Face face,
431 const char* *registry,
432 const char* *ordering,
433 FT_Int *supplement )
435 FT_Error error = CFF_Err_Ok;
436 CFF_Font cff = (CFF_Font)face->extra.data;
439 if ( cff )
441 CFF_FontRecDict dict = &cff->top_font.font_dict;
442 FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
445 if ( dict->cid_registry == 0xFFFFU )
447 error = CFF_Err_Invalid_Argument;
448 goto Fail;
451 if ( registry )
453 if ( cff->registry == NULL )
454 cff->registry = cff_index_get_sid_string( &cff->string_index,
455 dict->cid_registry,
456 psnames );
457 *registry = cff->registry;
460 if ( ordering )
462 if ( cff->ordering == NULL )
463 cff->ordering = cff_index_get_sid_string( &cff->string_index,
464 dict->cid_ordering,
465 psnames );
466 *ordering = cff->ordering;
469 if ( supplement )
470 *supplement = dict->cid_supplement;
473 Fail:
474 return error;
478 static const FT_Service_CIDRec cff_service_cid_info =
480 (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros
484 /*************************************************************************/
485 /*************************************************************************/
486 /*************************************************************************/
487 /**** ****/
488 /**** ****/
489 /**** D R I V E R I N T E R F A C E ****/
490 /**** ****/
491 /**** ****/
492 /*************************************************************************/
493 /*************************************************************************/
494 /*************************************************************************/
496 static const FT_ServiceDescRec cff_services[] =
498 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF },
499 { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info },
500 { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name },
501 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
502 { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict },
503 #endif
504 { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info },
505 { FT_SERVICE_ID_CID, &cff_service_cid_info },
506 { NULL, NULL }
510 FT_CALLBACK_DEF( FT_Module_Interface )
511 cff_get_interface( FT_Module driver, /* CFF_Driver */
512 const char* module_interface )
514 FT_Module sfnt;
515 FT_Module_Interface result;
518 result = ft_service_list_lookup( cff_services, module_interface );
519 if ( result != NULL )
520 return result;
522 /* we pass our request to the `sfnt' module */
523 sfnt = FT_Get_Module( driver->library, "sfnt" );
525 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
529 /* The FT_DriverInterface structure is defined in ftdriver.h. */
531 FT_CALLBACK_TABLE_DEF
532 const FT_Driver_ClassRec cff_driver_class =
534 /* begin with the FT_Module_Class fields */
536 FT_MODULE_FONT_DRIVER |
537 FT_MODULE_DRIVER_SCALABLE |
538 FT_MODULE_DRIVER_HAS_HINTER,
540 sizeof( CFF_DriverRec ),
541 "cff",
542 0x10000L,
543 0x20000L,
545 0, /* module-specific interface */
547 cff_driver_init,
548 cff_driver_done,
549 cff_get_interface,
552 /* now the specific driver fields */
553 sizeof( TT_FaceRec ),
554 sizeof( CFF_SizeRec ),
555 sizeof( CFF_GlyphSlotRec ),
557 cff_face_init,
558 cff_face_done,
559 cff_size_init,
560 cff_size_done,
561 cff_slot_init,
562 cff_slot_done,
564 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
565 ft_stub_set_char_sizes,
566 ft_stub_set_pixel_sizes,
567 #endif
569 Load_Glyph,
571 cff_get_kerning,
572 0, /* FT_Face_AttachFunc */
573 0, /* FT_Face_GetAdvancesFunc */
575 cff_size_request,
577 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
578 cff_size_select
579 #else
580 0 /* FT_Size_SelectFunc */
581 #endif
585 /* END */