5172
|
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 */
|