1 /***************************************************************************/
5 /* CID objects manager (body). */
7 /* Copyright 1996-2018 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_STREAM_H
26 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
27 #include FT_INTERNAL_POSTSCRIPT_AUX_H
28 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
34 /*************************************************************************/
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. */
41 #define FT_COMPONENT trace_cidobjs
44 /*************************************************************************/
48 /*************************************************************************/
51 cid_slot_done( FT_GlyphSlot slot
)
53 slot
->internal
->glyph_hints
= NULL
;
57 FT_LOCAL_DEF( FT_Error
)
58 cid_slot_init( FT_GlyphSlot slot
)
61 PSHinter_Service pshinter
;
64 face
= (CID_Face
)slot
->face
;
65 pshinter
= (PSHinter_Service
)face
->pshinter
;
72 module
= FT_Get_Module( slot
->face
->driver
->root
.library
,
79 funcs
= pshinter
->get_t1_funcs( module
);
80 slot
->internal
->glyph_hints
= (void*)funcs
;
88 /*************************************************************************/
92 /*************************************************************************/
95 static PSH_Globals_Funcs
96 cid_size_get_globals_funcs( CID_Size size
)
98 CID_Face face
= (CID_Face
)size
->root
.face
;
99 PSHinter_Service pshinter
= (PSHinter_Service
)face
->pshinter
;
103 module
= FT_Get_Module( size
->root
.face
->driver
->root
.library
,
105 return ( module
&& pshinter
&& pshinter
->get_globals_funcs
)
106 ? pshinter
->get_globals_funcs( module
)
112 cid_size_done( FT_Size cidsize
) /* CID_Size */
114 CID_Size size
= (CID_Size
)cidsize
;
117 if ( cidsize
->internal
->module_data
)
119 PSH_Globals_Funcs funcs
;
122 funcs
= cid_size_get_globals_funcs( size
);
124 funcs
->destroy( (PSH_Globals
)cidsize
->internal
->module_data
);
126 cidsize
->internal
->module_data
= NULL
;
131 FT_LOCAL_DEF( FT_Error
)
132 cid_size_init( FT_Size cidsize
) /* CID_Size */
134 CID_Size size
= (CID_Size
)cidsize
;
135 FT_Error error
= FT_Err_Ok
;
136 PSH_Globals_Funcs funcs
= cid_size_get_globals_funcs( size
);
142 CID_Face face
= (CID_Face
)cidsize
->face
;
143 CID_FaceDict dict
= face
->cid
.font_dicts
+ face
->root
.face_index
;
144 PS_Private priv
= &dict
->private_dict
;
147 error
= funcs
->create( cidsize
->face
->memory
, priv
, &globals
);
149 cidsize
->internal
->module_data
= globals
;
157 cid_size_request( FT_Size size
,
158 FT_Size_Request req
)
160 PSH_Globals_Funcs funcs
;
163 FT_Request_Metrics( size
->face
, req
);
165 funcs
= cid_size_get_globals_funcs( (CID_Size
)size
);
168 funcs
->set_scale( (PSH_Globals
)size
->internal
->module_data
,
169 size
->metrics
.x_scale
,
170 size
->metrics
.y_scale
,
177 /*************************************************************************/
181 /*************************************************************************/
183 /*************************************************************************/
189 /* Finalizes a given face object. */
192 /* face :: A pointer to the face object to destroy. */
195 cid_face_done( FT_Face cidface
) /* CID_Face */
197 CID_Face face
= (CID_Face
)cidface
;
207 info
= &cid
->font_info
;
208 memory
= cidface
->memory
;
216 for ( n
= 0; n
< cid
->num_dicts
; n
++ )
218 CID_Subrs subr
= face
->subrs
+ n
;
223 FT_FREE( subr
->code
[0] );
224 FT_FREE( subr
->code
);
228 FT_FREE( face
->subrs
);
231 /* release FontInfo strings */
232 FT_FREE( info
->version
);
233 FT_FREE( info
->notice
);
234 FT_FREE( info
->full_name
);
235 FT_FREE( info
->family_name
);
236 FT_FREE( info
->weight
);
238 /* release font dictionaries */
239 FT_FREE( cid
->font_dicts
);
242 /* release other strings */
243 FT_FREE( cid
->cid_font_name
);
244 FT_FREE( cid
->registry
);
245 FT_FREE( cid
->ordering
);
247 cidface
->family_name
= NULL
;
248 cidface
->style_name
= NULL
;
250 FT_FREE( face
->binary_data
);
251 FT_FREE( face
->cid_stream
);
255 /*************************************************************************/
261 /* Initializes a given CID face object. */
264 /* stream :: The source font stream. */
266 /* face_index :: The index of the font face in the resource. */
268 /* num_params :: Number of additional generic parameters. Ignored. */
270 /* params :: Additional generic parameters. Ignored. */
273 /* face :: The newly built face object. */
276 /* FreeType error code. 0 means success. */
278 FT_LOCAL_DEF( FT_Error
)
279 cid_face_init( FT_Stream stream
,
280 FT_Face cidface
, /* CID_Face */
283 FT_Parameter
* params
)
285 CID_Face face
= (CID_Face
)cidface
;
288 PSHinter_Service pshinter
;
290 FT_UNUSED( num_params
);
295 cidface
->num_faces
= 1;
297 psaux
= (PSAux_Service
)face
->psaux
;
300 psaux
= (PSAux_Service
)FT_Get_Module_Interface(
301 FT_FACE_LIBRARY( face
), "psaux" );
305 FT_ERROR(( "cid_face_init: cannot access `psaux' module\n" ));
306 error
= FT_THROW( Missing_Module
);
313 pshinter
= (PSHinter_Service
)face
->pshinter
;
316 pshinter
= (PSHinter_Service
)FT_Get_Module_Interface(
317 FT_FACE_LIBRARY( face
), "pshinter" );
319 face
->pshinter
= pshinter
;
322 FT_TRACE2(( "CID driver\n" ));
324 /* open the tokenizer; this will also check the font format */
325 if ( FT_STREAM_SEEK( 0 ) )
328 error
= cid_face_open( face
, face_index
);
332 /* if we just wanted to check the format, leave successfully now */
333 if ( face_index
< 0 )
336 /* check the face index */
337 /* XXX: handle CID fonts with more than a single face */
338 if ( ( face_index
& 0xFFFF ) != 0 )
340 FT_ERROR(( "cid_face_init: invalid face index\n" ));
341 error
= FT_THROW( Invalid_Argument
);
345 /* now load the font program into the face object */
347 /* initialize the face object fields */
349 /* set up root face fields */
351 CID_FaceInfo cid
= &face
->cid
;
352 PS_FontInfo info
= &cid
->font_info
;
355 cidface
->num_glyphs
= (FT_Long
)cid
->cid_count
;
356 cidface
->num_charmaps
= 0;
358 cidface
->face_index
= face_index
& 0xFFFF;
360 cidface
->face_flags
|= FT_FACE_FLAG_SCALABLE
| /* scalable outlines */
361 FT_FACE_FLAG_HORIZONTAL
| /* horizontal data */
362 FT_FACE_FLAG_HINTER
; /* has native hinter */
364 if ( info
->is_fixed_pitch
)
365 cidface
->face_flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
367 /* XXX: TODO: add kerning with .afm support */
369 /* get style name -- be careful, some broken fonts only */
370 /* have a /FontName dictionary entry! */
371 cidface
->family_name
= info
->family_name
;
372 /* assume "Regular" style if we don't know better */
373 cidface
->style_name
= (char *)"Regular";
374 if ( cidface
->family_name
)
376 char* full
= info
->full_name
;
377 char* family
= cidface
->family_name
;
384 if ( *full
== *family
)
391 if ( *full
== ' ' || *full
== '-' )
393 else if ( *family
== ' ' || *family
== '-' )
398 cidface
->style_name
= full
;
407 /* do we have a `/FontName'? */
408 if ( cid
->cid_font_name
)
409 cidface
->family_name
= cid
->cid_font_name
;
412 /* compute style flags */
413 cidface
->style_flags
= 0;
414 if ( info
->italic_angle
)
415 cidface
->style_flags
|= FT_STYLE_FLAG_ITALIC
;
418 if ( !ft_strcmp( info
->weight
, "Bold" ) ||
419 !ft_strcmp( info
->weight
, "Black" ) )
420 cidface
->style_flags
|= FT_STYLE_FLAG_BOLD
;
423 /* no embedded bitmap support */
424 cidface
->num_fixed_sizes
= 0;
425 cidface
->available_sizes
= NULL
;
427 cidface
->bbox
.xMin
= cid
->font_bbox
.xMin
>> 16;
428 cidface
->bbox
.yMin
= cid
->font_bbox
.yMin
>> 16;
429 /* no `U' suffix here to 0xFFFF! */
430 cidface
->bbox
.xMax
= ( cid
->font_bbox
.xMax
+ 0xFFFF ) >> 16;
431 cidface
->bbox
.yMax
= ( cid
->font_bbox
.yMax
+ 0xFFFF ) >> 16;
433 if ( !cidface
->units_per_EM
)
434 cidface
->units_per_EM
= 1000;
436 cidface
->ascender
= (FT_Short
)( cidface
->bbox
.yMax
);
437 cidface
->descender
= (FT_Short
)( cidface
->bbox
.yMin
);
439 cidface
->height
= (FT_Short
)( ( cidface
->units_per_EM
* 12 ) / 10 );
440 if ( cidface
->height
< cidface
->ascender
- cidface
->descender
)
441 cidface
->height
= (FT_Short
)( cidface
->ascender
- cidface
->descender
);
443 cidface
->underline_position
= (FT_Short
)info
->underline_position
;
444 cidface
->underline_thickness
= (FT_Short
)info
->underline_thickness
;
452 /*************************************************************************/
455 /* cid_driver_init */
458 /* Initializes a given CID driver object. */
461 /* driver :: A handle to the target driver object. */
464 /* FreeType error code. 0 means success. */
466 FT_LOCAL_DEF( FT_Error
)
467 cid_driver_init( FT_Module module
)
469 PS_Driver driver
= (PS_Driver
)module
;
474 /* set default property values, cf. `ftt1drv.h' */
475 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
476 driver
->hinting_engine
= FT_HINTING_FREETYPE
;
478 driver
->hinting_engine
= FT_HINTING_ADOBE
;
481 driver
->no_stem_darkening
= TRUE
;
483 driver
->darken_params
[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1
;
484 driver
->darken_params
[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1
;
485 driver
->darken_params
[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2
;
486 driver
->darken_params
[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2
;
487 driver
->darken_params
[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3
;
488 driver
->darken_params
[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3
;
489 driver
->darken_params
[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4
;
490 driver
->darken_params
[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4
;
492 /* compute random seed from some memory addresses */
493 seed
= (FT_UInt32
)( (FT_Offset
)(char*)&seed
^
494 (FT_Offset
)(char*)&module
^
495 (FT_Offset
)(char*)module
->memory
);
496 seed
= seed
^ ( seed
>> 10 ) ^ ( seed
>> 20 );
498 driver
->random_seed
= (FT_Int32
)seed
;
499 if ( driver
->random_seed
< 0 )
500 driver
->random_seed
= -driver
->random_seed
;
501 else if ( driver
->random_seed
== 0 )
502 driver
->random_seed
= 123456789;
508 /*************************************************************************/
511 /* cid_driver_done */
514 /* Finalizes a given CID driver. */
517 /* driver :: A handle to the target CID driver. */
520 cid_driver_done( FT_Module driver
)