|
1 /***************************************************************************/ |
|
2 /* */ |
|
3 /* cidobjs.c */ |
|
4 /* */ |
|
5 /* CID objects manager (body). */ |
|
6 /* */ |
|
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 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 /***************************************************************************/ |
|
17 |
|
18 |
|
19 #include <ft2build.h> |
|
20 #include FT_INTERNAL_DEBUG_H |
|
21 #include FT_INTERNAL_STREAM_H |
|
22 |
|
23 #include "cidgload.h" |
|
24 #include "cidload.h" |
|
25 |
|
26 #include FT_SERVICE_POSTSCRIPT_CMAPS_H |
|
27 #include FT_INTERNAL_POSTSCRIPT_AUX_H |
|
28 #include FT_INTERNAL_POSTSCRIPT_HINTS_H |
|
29 |
|
30 #include "ciderrs.h" |
|
31 |
|
32 |
|
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_cidobjs |
|
41 |
|
42 |
|
43 /*************************************************************************/ |
|
44 /* */ |
|
45 /* SLOT FUNCTIONS */ |
|
46 /* */ |
|
47 /*************************************************************************/ |
|
48 |
|
49 FT_LOCAL_DEF( void ) |
|
50 cid_slot_done( FT_GlyphSlot slot ) |
|
51 { |
|
52 slot->internal->glyph_hints = 0; |
|
53 } |
|
54 |
|
55 |
|
56 FT_LOCAL_DEF( FT_Error ) |
|
57 cid_slot_init( FT_GlyphSlot slot ) |
|
58 { |
|
59 CID_Face face; |
|
60 PSHinter_Service pshinter; |
|
61 |
|
62 |
|
63 face = (CID_Face)slot->face; |
|
64 pshinter = (PSHinter_Service)face->pshinter; |
|
65 |
|
66 if ( pshinter ) |
|
67 { |
|
68 FT_Module module; |
|
69 |
|
70 |
|
71 module = FT_Get_Module( slot->face->driver->root.library, |
|
72 "pshinter" ); |
|
73 if ( module ) |
|
74 { |
|
75 T1_Hints_Funcs funcs; |
|
76 |
|
77 |
|
78 funcs = pshinter->get_t1_funcs( module ); |
|
79 slot->internal->glyph_hints = (void*)funcs; |
|
80 } |
|
81 } |
|
82 |
|
83 return 0; |
|
84 } |
|
85 |
|
86 |
|
87 /*************************************************************************/ |
|
88 /* */ |
|
89 /* SIZE FUNCTIONS */ |
|
90 /* */ |
|
91 /*************************************************************************/ |
|
92 |
|
93 |
|
94 static PSH_Globals_Funcs |
|
95 cid_size_get_globals_funcs( CID_Size size ) |
|
96 { |
|
97 CID_Face face = (CID_Face)size->root.face; |
|
98 PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; |
|
99 FT_Module module; |
|
100 |
|
101 |
|
102 module = FT_Get_Module( size->root.face->driver->root.library, |
|
103 "pshinter" ); |
|
104 return ( module && pshinter && pshinter->get_globals_funcs ) |
|
105 ? pshinter->get_globals_funcs( module ) |
|
106 : 0; |
|
107 } |
|
108 |
|
109 |
|
110 FT_LOCAL_DEF( void ) |
|
111 cid_size_done( FT_Size cidsize ) /* CID_Size */ |
|
112 { |
|
113 CID_Size size = (CID_Size)cidsize; |
|
114 |
|
115 |
|
116 if ( cidsize->internal ) |
|
117 { |
|
118 PSH_Globals_Funcs funcs; |
|
119 |
|
120 |
|
121 funcs = cid_size_get_globals_funcs( size ); |
|
122 if ( funcs ) |
|
123 funcs->destroy( (PSH_Globals)cidsize->internal ); |
|
124 |
|
125 cidsize->internal = 0; |
|
126 } |
|
127 } |
|
128 |
|
129 |
|
130 FT_LOCAL_DEF( FT_Error ) |
|
131 cid_size_init( FT_Size cidsize ) /* CID_Size */ |
|
132 { |
|
133 CID_Size size = (CID_Size)cidsize; |
|
134 FT_Error error = CID_Err_Ok; |
|
135 PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); |
|
136 |
|
137 |
|
138 if ( funcs ) |
|
139 { |
|
140 PSH_Globals globals; |
|
141 CID_Face face = (CID_Face)cidsize->face; |
|
142 CID_FaceDict dict = face->cid.font_dicts + face->root.face_index; |
|
143 PS_Private priv = &dict->private_dict; |
|
144 |
|
145 |
|
146 error = funcs->create( cidsize->face->memory, priv, &globals ); |
|
147 if ( !error ) |
|
148 cidsize->internal = (FT_Size_Internal)(void*)globals; |
|
149 } |
|
150 |
|
151 return error; |
|
152 } |
|
153 |
|
154 |
|
155 FT_LOCAL( FT_Error ) |
|
156 cid_size_request( FT_Size size, |
|
157 FT_Size_Request req ) |
|
158 { |
|
159 PSH_Globals_Funcs funcs; |
|
160 |
|
161 |
|
162 FT_Request_Metrics( size->face, req ); |
|
163 |
|
164 funcs = cid_size_get_globals_funcs( (CID_Size)size ); |
|
165 |
|
166 if ( funcs ) |
|
167 funcs->set_scale( (PSH_Globals)size->internal, |
|
168 size->metrics.x_scale, |
|
169 size->metrics.y_scale, |
|
170 0, 0 ); |
|
171 |
|
172 return CID_Err_Ok; |
|
173 } |
|
174 |
|
175 |
|
176 /*************************************************************************/ |
|
177 /* */ |
|
178 /* FACE FUNCTIONS */ |
|
179 /* */ |
|
180 /*************************************************************************/ |
|
181 |
|
182 /*************************************************************************/ |
|
183 /* */ |
|
184 /* <Function> */ |
|
185 /* cid_face_done */ |
|
186 /* */ |
|
187 /* <Description> */ |
|
188 /* Finalizes a given face object. */ |
|
189 /* */ |
|
190 /* <Input> */ |
|
191 /* face :: A pointer to the face object to destroy. */ |
|
192 /* */ |
|
193 FT_LOCAL_DEF( void ) |
|
194 cid_face_done( FT_Face cidface ) /* CID_Face */ |
|
195 { |
|
196 CID_Face face = (CID_Face)cidface; |
|
197 FT_Memory memory; |
|
198 CID_FaceInfo cid; |
|
199 PS_FontInfo info; |
|
200 |
|
201 |
|
202 if ( !face ) |
|
203 return; |
|
204 |
|
205 cid = &face->cid; |
|
206 info = &cid->font_info; |
|
207 memory = cidface->memory; |
|
208 |
|
209 /* release subrs */ |
|
210 if ( face->subrs ) |
|
211 { |
|
212 FT_Int n; |
|
213 |
|
214 |
|
215 for ( n = 0; n < cid->num_dicts; n++ ) |
|
216 { |
|
217 CID_Subrs subr = face->subrs + n; |
|
218 |
|
219 |
|
220 if ( subr->code ) |
|
221 { |
|
222 FT_FREE( subr->code[0] ); |
|
223 FT_FREE( subr->code ); |
|
224 } |
|
225 } |
|
226 |
|
227 FT_FREE( face->subrs ); |
|
228 } |
|
229 |
|
230 /* release FontInfo strings */ |
|
231 FT_FREE( info->version ); |
|
232 FT_FREE( info->notice ); |
|
233 FT_FREE( info->full_name ); |
|
234 FT_FREE( info->family_name ); |
|
235 FT_FREE( info->weight ); |
|
236 |
|
237 /* release font dictionaries */ |
|
238 FT_FREE( cid->font_dicts ); |
|
239 cid->num_dicts = 0; |
|
240 |
|
241 /* release other strings */ |
|
242 FT_FREE( cid->cid_font_name ); |
|
243 FT_FREE( cid->registry ); |
|
244 FT_FREE( cid->ordering ); |
|
245 |
|
246 cidface->family_name = 0; |
|
247 cidface->style_name = 0; |
|
248 |
|
249 FT_FREE( face->binary_data ); |
|
250 FT_FREE( face->cid_stream ); |
|
251 } |
|
252 |
|
253 |
|
254 /*************************************************************************/ |
|
255 /* */ |
|
256 /* <Function> */ |
|
257 /* cid_face_init */ |
|
258 /* */ |
|
259 /* <Description> */ |
|
260 /* Initializes a given CID face object. */ |
|
261 /* */ |
|
262 /* <Input> */ |
|
263 /* stream :: The source font stream. */ |
|
264 /* */ |
|
265 /* face_index :: The index of the font face in the resource. */ |
|
266 /* */ |
|
267 /* num_params :: Number of additional generic parameters. Ignored. */ |
|
268 /* */ |
|
269 /* params :: Additional generic parameters. Ignored. */ |
|
270 /* */ |
|
271 /* <InOut> */ |
|
272 /* face :: The newly built face object. */ |
|
273 /* */ |
|
274 /* <Return> */ |
|
275 /* FreeType error code. 0 means success. */ |
|
276 /* */ |
|
277 FT_LOCAL_DEF( FT_Error ) |
|
278 cid_face_init( FT_Stream stream, |
|
279 FT_Face cidface, /* CID_Face */ |
|
280 FT_Int face_index, |
|
281 FT_Int num_params, |
|
282 FT_Parameter* params ) |
|
283 { |
|
284 CID_Face face = (CID_Face)cidface; |
|
285 FT_Error error; |
|
286 PSAux_Service psaux; |
|
287 PSHinter_Service pshinter; |
|
288 |
|
289 FT_UNUSED( num_params ); |
|
290 FT_UNUSED( params ); |
|
291 FT_UNUSED( stream ); |
|
292 |
|
293 |
|
294 cidface->num_faces = 1; |
|
295 |
|
296 psaux = (PSAux_Service)face->psaux; |
|
297 if ( !psaux ) |
|
298 { |
|
299 psaux = (PSAux_Service)FT_Get_Module_Interface( |
|
300 FT_FACE_LIBRARY( face ), "psaux" ); |
|
301 |
|
302 face->psaux = psaux; |
|
303 } |
|
304 |
|
305 pshinter = (PSHinter_Service)face->pshinter; |
|
306 if ( !pshinter ) |
|
307 { |
|
308 pshinter = (PSHinter_Service)FT_Get_Module_Interface( |
|
309 FT_FACE_LIBRARY( face ), "pshinter" ); |
|
310 |
|
311 face->pshinter = pshinter; |
|
312 } |
|
313 |
|
314 /* open the tokenizer; this will also check the font format */ |
|
315 if ( FT_STREAM_SEEK( 0 ) ) |
|
316 goto Exit; |
|
317 |
|
318 error = cid_face_open( face, face_index ); |
|
319 if ( error ) |
|
320 goto Exit; |
|
321 |
|
322 /* if we just wanted to check the format, leave successfully now */ |
|
323 if ( face_index < 0 ) |
|
324 goto Exit; |
|
325 |
|
326 /* check the face index */ |
|
327 /* XXX: handle CID fonts with more than a single face */ |
|
328 if ( face_index != 0 ) |
|
329 { |
|
330 FT_ERROR(( "cid_face_init: invalid face index\n" )); |
|
331 error = CID_Err_Invalid_Argument; |
|
332 goto Exit; |
|
333 } |
|
334 |
|
335 /* now load the font program into the face object */ |
|
336 |
|
337 /* initialize the face object fields */ |
|
338 |
|
339 /* set up root face fields */ |
|
340 { |
|
341 CID_FaceInfo cid = &face->cid; |
|
342 PS_FontInfo info = &cid->font_info; |
|
343 |
|
344 |
|
345 cidface->num_glyphs = cid->cid_count; |
|
346 cidface->num_charmaps = 0; |
|
347 |
|
348 cidface->face_index = face_index; |
|
349 cidface->face_flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ |
|
350 FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ |
|
351 FT_FACE_FLAG_HINTER; /* has native hinter */ |
|
352 |
|
353 if ( info->is_fixed_pitch ) |
|
354 cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; |
|
355 |
|
356 /* XXX: TODO: add kerning with .afm support */ |
|
357 |
|
358 /* get style name -- be careful, some broken fonts only */ |
|
359 /* have a /FontName dictionary entry! */ |
|
360 cidface->family_name = info->family_name; |
|
361 /* assume "Regular" style if we don't know better */ |
|
362 cidface->style_name = (char *)"Regular"; |
|
363 if ( cidface->family_name ) |
|
364 { |
|
365 char* full = info->full_name; |
|
366 char* family = cidface->family_name; |
|
367 |
|
368 |
|
369 if ( full ) |
|
370 { |
|
371 while ( *full ) |
|
372 { |
|
373 if ( *full == *family ) |
|
374 { |
|
375 family++; |
|
376 full++; |
|
377 } |
|
378 else |
|
379 { |
|
380 if ( *full == ' ' || *full == '-' ) |
|
381 full++; |
|
382 else if ( *family == ' ' || *family == '-' ) |
|
383 family++; |
|
384 else |
|
385 { |
|
386 if ( !*family ) |
|
387 cidface->style_name = full; |
|
388 break; |
|
389 } |
|
390 } |
|
391 } |
|
392 } |
|
393 } |
|
394 else |
|
395 { |
|
396 /* do we have a `/FontName'? */ |
|
397 if ( cid->cid_font_name ) |
|
398 cidface->family_name = cid->cid_font_name; |
|
399 } |
|
400 |
|
401 /* compute style flags */ |
|
402 cidface->style_flags = 0; |
|
403 if ( info->italic_angle ) |
|
404 cidface->style_flags |= FT_STYLE_FLAG_ITALIC; |
|
405 if ( info->weight ) |
|
406 { |
|
407 if ( !ft_strcmp( info->weight, "Bold" ) || |
|
408 !ft_strcmp( info->weight, "Black" ) ) |
|
409 cidface->style_flags |= FT_STYLE_FLAG_BOLD; |
|
410 } |
|
411 |
|
412 /* no embedded bitmap support */ |
|
413 cidface->num_fixed_sizes = 0; |
|
414 cidface->available_sizes = 0; |
|
415 |
|
416 cidface->bbox.xMin = cid->font_bbox.xMin >> 16; |
|
417 cidface->bbox.yMin = cid->font_bbox.yMin >> 16; |
|
418 /* no `U' suffix here to 0xFFFF! */ |
|
419 cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16; |
|
420 cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16; |
|
421 |
|
422 if ( !cidface->units_per_EM ) |
|
423 cidface->units_per_EM = 1000; |
|
424 |
|
425 cidface->ascender = (FT_Short)( cidface->bbox.yMax ); |
|
426 cidface->descender = (FT_Short)( cidface->bbox.yMin ); |
|
427 |
|
428 cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 ); |
|
429 if ( cidface->height < cidface->ascender - cidface->descender ) |
|
430 cidface->height = (FT_Short)( cidface->ascender - cidface->descender ); |
|
431 |
|
432 cidface->underline_position = (FT_Short)info->underline_position; |
|
433 cidface->underline_thickness = (FT_Short)info->underline_thickness; |
|
434 } |
|
435 |
|
436 Exit: |
|
437 return error; |
|
438 } |
|
439 |
|
440 |
|
441 /*************************************************************************/ |
|
442 /* */ |
|
443 /* <Function> */ |
|
444 /* cid_driver_init */ |
|
445 /* */ |
|
446 /* <Description> */ |
|
447 /* Initializes a given CID driver object. */ |
|
448 /* */ |
|
449 /* <Input> */ |
|
450 /* driver :: A handle to the target driver object. */ |
|
451 /* */ |
|
452 /* <Return> */ |
|
453 /* FreeType error code. 0 means success. */ |
|
454 /* */ |
|
455 FT_LOCAL_DEF( FT_Error ) |
|
456 cid_driver_init( FT_Module driver ) |
|
457 { |
|
458 FT_UNUSED( driver ); |
|
459 |
|
460 return CID_Err_Ok; |
|
461 } |
|
462 |
|
463 |
|
464 /*************************************************************************/ |
|
465 /* */ |
|
466 /* <Function> */ |
|
467 /* cid_driver_done */ |
|
468 /* */ |
|
469 /* <Description> */ |
|
470 /* Finalizes a given CID driver. */ |
|
471 /* */ |
|
472 /* <Input> */ |
|
473 /* driver :: A handle to the target CID driver. */ |
|
474 /* */ |
|
475 FT_LOCAL_DEF( void ) |
|
476 cid_driver_done( FT_Module driver ) |
|
477 { |
|
478 FT_UNUSED( driver ); |
|
479 } |
|
480 |
|
481 |
|
482 /* END */ |