blob: dd611e2b0502b8680223cdbd2d5f132f2d4dc7f5 [file] [log] [blame]
Werner Lemberge3c11d72000-06-16 06:49:56 +00001/***************************************************************************/
2/* */
3/* cidobjs.c */
4/* */
5/* CID objects manager (body). */
6/* */
Werner Lemberg415235d2001-06-28 17:49:10 +00007/* Copyright 1996-2001 by */
Werner Lemberge3c11d72000-06-16 06:49:56 +00008/* 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
Werner Lembergcc069be2000-12-08 16:17:16 +000018
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_STREAM_H
David Turner8d3a4012001-03-20 11:14:24 +000022#include "cidgload.h"
23#include "cidload.h"
Werner Lembergcc069be2000-12-08 16:17:16 +000024#include FT_INTERNAL_POSTSCRIPT_NAMES_H
25#include FT_INTERNAL_POSTSCRIPT_AUX_H
David Turner85eb6692001-12-20 09:36:21 +000026#include FT_INTERNAL_POSTSCRIPT_HINTS_H
David Turner04aa8002000-06-01 03:27:48 +000027
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000028#include "ciderrs.h"
29
Werner Lemberge3c11d72000-06-16 06:49:56 +000030
31 /*************************************************************************/
32 /* */
33 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
34 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
35 /* messages during execution. */
36 /* */
Werner Lemberg63408a12000-12-13 23:44:37 +000037#undef FT_COMPONENT
38#define FT_COMPONENT trace_cidobjs
David Turner04aa8002000-06-01 03:27:48 +000039
David Turner04aa8002000-06-01 03:27:48 +000040
David Turner85eb6692001-12-20 09:36:21 +000041 /*************************************************************************/
42 /* */
43 /* SLOT FUNCTIONS */
44 /* */
45 /*************************************************************************/
46
David Turnerbc82f1b2002-03-01 02:26:22 +000047 FT_LOCAL_DEF( void )
David Turner85eb6692001-12-20 09:36:21 +000048 CID_GlyphSlot_Done( CID_GlyphSlot slot )
49 {
50 slot->root.internal->glyph_hints = 0;
51 }
52
53
David Turnerbc82f1b2002-03-01 02:26:22 +000054 FT_LOCAL_DEF( FT_Error )
Werner Lemberg0d9165e2002-03-07 21:59:59 +000055 CID_GlyphSlot_Init( CID_GlyphSlot slot )
Werner Lembergf41e71a2001-12-20 21:22:02 +000056 {
Werner Lemberg0d9165e2002-03-07 21:59:59 +000057 CID_Face face;
David Turner4e7eeee2002-02-28 16:10:29 +000058 PSHinter_Service pshinter;
Werner Lembergf41e71a2001-12-20 21:22:02 +000059
60
Werner Lemberg0d9165e2002-03-07 21:59:59 +000061 face = (CID_Face)slot->root.face;
62 pshinter = (PSHinter_Service)face->pshinter;
Werner Lembergf41e71a2001-12-20 21:22:02 +000063
64 if ( pshinter )
David Turner85eb6692001-12-20 09:36:21 +000065 {
66 FT_Module module;
Werner Lembergf41e71a2001-12-20 21:22:02 +000067
68
69 module = FT_Get_Module( slot->root.face->driver->root.library,
70 "pshinter" );
71 if ( module )
David Turner85eb6692001-12-20 09:36:21 +000072 {
73 T1_Hints_Funcs funcs;
Werner Lembergf41e71a2001-12-20 21:22:02 +000074
75
David Turner85eb6692001-12-20 09:36:21 +000076 funcs = pshinter->get_t1_funcs( module );
Werner Lembergf41e71a2001-12-20 21:22:02 +000077 slot->root.internal->glyph_hints = (void*)funcs;
David Turner85eb6692001-12-20 09:36:21 +000078 }
79 }
Werner Lembergf41e71a2001-12-20 21:22:02 +000080
David Turner85eb6692001-12-20 09:36:21 +000081 return 0;
82 }
Werner Lembergf41e71a2001-12-20 21:22:02 +000083
David Turner85eb6692001-12-20 09:36:21 +000084
85 /*************************************************************************/
86 /* */
87 /* SIZE FUNCTIONS */
88 /* */
89 /*************************************************************************/
90
91
92 static PSH_Globals_Funcs
93 CID_Size_Get_Globals_Funcs( CID_Size size )
94 {
Werner Lemberg0d9165e2002-03-07 21:59:59 +000095 CID_Face face = (CID_Face)size->root.face;
96 PSHinter_Service pshinter = (PSHinter_Service)face->pshinter;
97 FT_Module module;
Werner Lembergf41e71a2001-12-20 21:22:02 +000098
David Turner85eb6692001-12-20 09:36:21 +000099
100 module = FT_Get_Module( size->root.face->driver->root.library,
101 "pshinter" );
102 return ( module && pshinter && pshinter->get_globals_funcs )
103 ? pshinter->get_globals_funcs( module )
Werner Lembergf41e71a2001-12-20 21:22:02 +0000104 : 0;
David Turner85eb6692001-12-20 09:36:21 +0000105 }
106
107
David Turnerbc82f1b2002-03-01 02:26:22 +0000108 FT_LOCAL_DEF( void )
David Turner85eb6692001-12-20 09:36:21 +0000109 CID_Size_Done( CID_Size size )
110 {
111 if ( size->root.internal )
112 {
113 PSH_Globals_Funcs funcs;
Werner Lembergf41e71a2001-12-20 21:22:02 +0000114
David Turner85eb6692001-12-20 09:36:21 +0000115
116 funcs = CID_Size_Get_Globals_Funcs( size );
117 if ( funcs )
118 funcs->destroy( (PSH_Globals)size->root.internal );
119
120 size->root.internal = 0;
121 }
122 }
123
124
David Turnerbc82f1b2002-03-01 02:26:22 +0000125 FT_LOCAL_DEF( FT_Error )
David Turner85eb6692001-12-20 09:36:21 +0000126 CID_Size_Init( CID_Size size )
127 {
128 FT_Error error = 0;
129 PSH_Globals_Funcs funcs = CID_Size_Get_Globals_Funcs( size );
Werner Lembergf41e71a2001-12-20 21:22:02 +0000130
David Turner85eb6692001-12-20 09:36:21 +0000131
132 if ( funcs )
133 {
Werner Lembergf41e71a2001-12-20 21:22:02 +0000134 PSH_Globals globals;
135 CID_Face face = (CID_Face)size->root.face;
David Turner29644172002-02-28 18:59:37 +0000136 CID_FaceDict dict = face->cid.font_dicts + face->root.face_index;
137 PS_Private priv = &dict->private_dict;
Werner Lembergf41e71a2001-12-20 21:22:02 +0000138
David Turner85eb6692001-12-20 09:36:21 +0000139
140 error = funcs->create( size->root.face->memory, priv, &globals );
141 if ( !error )
142 size->root.internal = (FT_Size_Internal)(void*)globals;
143 }
Werner Lembergf41e71a2001-12-20 21:22:02 +0000144
David Turner85eb6692001-12-20 09:36:21 +0000145 return error;
146 }
147
148
David Turnerbc82f1b2002-03-01 02:26:22 +0000149 FT_LOCAL_DEF( FT_Error )
David Turner85eb6692001-12-20 09:36:21 +0000150 CID_Size_Reset( CID_Size size )
151 {
152 PSH_Globals_Funcs funcs = CID_Size_Get_Globals_Funcs( size );
153 FT_Error error = 0;
154
Werner Lembergf41e71a2001-12-20 21:22:02 +0000155
David Turner85eb6692001-12-20 09:36:21 +0000156 if ( funcs )
157 error = funcs->set_scale( (PSH_Globals)size->root.internal,
158 size->root.metrics.x_scale,
159 size->root.metrics.y_scale,
160 0, 0 );
Werner Lembergf41e71a2001-12-20 21:22:02 +0000161 return error;
David Turner85eb6692001-12-20 09:36:21 +0000162 }
163
164
165
166
Werner Lemberge3c11d72000-06-16 06:49:56 +0000167 /*************************************************************************/
168 /* */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000169 /* FACE FUNCTIONS */
170 /* */
171 /*************************************************************************/
David Turner04aa8002000-06-01 03:27:48 +0000172
David Turner04aa8002000-06-01 03:27:48 +0000173
Werner Lemberge3c11d72000-06-16 06:49:56 +0000174 /*************************************************************************/
175 /* */
176 /* <Function> */
David Turner85eb6692001-12-20 09:36:21 +0000177 /* CID_Face_Done */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000178 /* */
179 /* <Description> */
180 /* Finalizes a given face object. */
181 /* */
182 /* <Input> */
183 /* face :: A pointer to the face object to destroy. */
184 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000185 FT_LOCAL_DEF( void )
David Turner85eb6692001-12-20 09:36:21 +0000186 CID_Face_Done( CID_Face face )
David Turner04aa8002000-06-01 03:27:48 +0000187 {
188 FT_Memory memory;
189
Werner Lemberge3c11d72000-06-16 06:49:56 +0000190
191 if ( face )
David Turner04aa8002000-06-01 03:27:48 +0000192 {
David Turner29644172002-02-28 18:59:37 +0000193 CID_FaceInfo cid = &face->cid;
194 PS_FontInfo info = &cid->font_info;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000195
David Turner04aa8002000-06-01 03:27:48 +0000196
197 memory = face->root.memory;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000198
David Turner3a664fc2001-12-21 15:26:19 +0000199 /* release subrs */
200 if ( face->subrs )
201 {
202 FT_Int n;
203
Werner Lembergaf594e62001-12-22 14:38:40 +0000204
David Turner3a664fc2001-12-21 15:26:19 +0000205 for ( n = 0; n < cid->num_dicts; n++ )
206 {
David Turner29644172002-02-28 18:59:37 +0000207 CID_Subrs subr = face->subrs + n;
David Turner3a664fc2001-12-21 15:26:19 +0000208
Werner Lembergaf594e62001-12-22 14:38:40 +0000209
David Turner3a664fc2001-12-21 15:26:19 +0000210 if ( subr->code )
211 {
David Turnere459d742002-03-22 13:52:37 +0000212 FT_FREE( subr->code[0] );
213 FT_FREE( subr->code );
David Turner3a664fc2001-12-21 15:26:19 +0000214 }
215 }
216
David Turnere459d742002-03-22 13:52:37 +0000217 FT_FREE( face->subrs );
David Turner3a664fc2001-12-21 15:26:19 +0000218 }
219
David Turner04aa8002000-06-01 03:27:48 +0000220 /* release FontInfo strings */
David Turnere459d742002-03-22 13:52:37 +0000221 FT_FREE( info->version );
222 FT_FREE( info->notice );
223 FT_FREE( info->full_name );
224 FT_FREE( info->family_name );
225 FT_FREE( info->weight );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000226
David Turner04aa8002000-06-01 03:27:48 +0000227 /* release font dictionaries */
David Turnere459d742002-03-22 13:52:37 +0000228 FT_FREE( cid->font_dicts );
David Turner04aa8002000-06-01 03:27:48 +0000229 cid->num_dicts = 0;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000230
David Turner04aa8002000-06-01 03:27:48 +0000231 /* release other strings */
David Turnere459d742002-03-22 13:52:37 +0000232 FT_FREE( cid->cid_font_name );
233 FT_FREE( cid->registry );
234 FT_FREE( cid->ordering );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000235
David Turner04aa8002000-06-01 03:27:48 +0000236 face->root.family_name = 0;
237 face->root.style_name = 0;
238 }
239 }
240
David Turner04aa8002000-06-01 03:27:48 +0000241
Werner Lemberge3c11d72000-06-16 06:49:56 +0000242 /*************************************************************************/
243 /* */
244 /* <Function> */
David Turner85eb6692001-12-20 09:36:21 +0000245 /* CID_Face_Init */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000246 /* */
247 /* <Description> */
248 /* Initializes a given CID face object. */
249 /* */
250 /* <Input> */
251 /* stream :: The source font stream. */
252 /* */
253 /* face_index :: The index of the font face in the resource. */
254 /* */
255 /* num_params :: Number of additional generic parameters. Ignored. */
256 /* */
257 /* params :: Additional generic parameters. Ignored. */
258 /* */
259 /* <InOut> */
260 /* face :: The newly built face object. */
261 /* */
262 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000263 /* FreeType error code. 0 means success. */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000264 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000265 FT_LOCAL_DEF( FT_Error )
David Turner85eb6692001-12-20 09:36:21 +0000266 CID_Face_Init( FT_Stream stream,
Werner Lemberg93616ec2001-06-27 19:46:12 +0000267 CID_Face face,
268 FT_Int face_index,
269 FT_Int num_params,
270 FT_Parameter* params )
David Turner04aa8002000-06-01 03:27:48 +0000271 {
Werner Lembergf41e71a2001-12-20 21:22:02 +0000272 FT_Error error;
David Turner4e7eeee2002-02-28 16:10:29 +0000273 PSNames_Service psnames;
274 PSAux_Service psaux;
275 PSHinter_Service pshinter;
David Turner04aa8002000-06-01 03:27:48 +0000276
David Turnerc6a92202000-07-04 18:12:13 +0000277 FT_UNUSED( num_params );
278 FT_UNUSED( params );
279 FT_UNUSED( face_index );
280 FT_UNUSED( stream );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000281
David Turner04aa8002000-06-01 03:27:48 +0000282
283 face->root.num_faces = 1;
284
David Turner4e7eeee2002-02-28 16:10:29 +0000285 psnames = (PSNames_Service)face->psnames;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000286 if ( !psnames )
David Turner04aa8002000-06-01 03:27:48 +0000287 {
David Turner4e7eeee2002-02-28 16:10:29 +0000288 psnames = (PSNames_Service)FT_Get_Module_Interface(
Werner Lemberga929ba92000-06-25 06:47:11 +0000289 FT_FACE_LIBRARY( face ), "psnames" );
David Turner04aa8002000-06-01 03:27:48 +0000290
David Turnerc3128612000-06-23 05:02:13 +0000291 face->psnames = psnames;
David Turner04aa8002000-06-01 03:27:48 +0000292 }
293
David Turner4e7eeee2002-02-28 16:10:29 +0000294 psaux = (PSAux_Service)face->psaux;
David Turner34f1c2f2000-08-23 22:47:44 +0000295 if ( !psaux )
296 {
David Turner4e7eeee2002-02-28 16:10:29 +0000297 psaux = (PSAux_Service)FT_Get_Module_Interface(
Werner Lembergf41e71a2001-12-20 21:22:02 +0000298 FT_FACE_LIBRARY( face ), "psaux" );
Werner Lemberge4b32a52000-10-31 20:42:18 +0000299
David Turner34f1c2f2000-08-23 22:47:44 +0000300 face->psaux = psaux;
301 }
302
David Turner4e7eeee2002-02-28 16:10:29 +0000303 pshinter = (PSHinter_Service)face->pshinter;
David Turner85eb6692001-12-20 09:36:21 +0000304 if ( !pshinter )
305 {
David Turner4e7eeee2002-02-28 16:10:29 +0000306 pshinter = (PSHinter_Service)FT_Get_Module_Interface(
Werner Lembergf41e71a2001-12-20 21:22:02 +0000307 FT_FACE_LIBRARY( face ), "pshinter" );
David Turner85eb6692001-12-20 09:36:21 +0000308
309 face->pshinter = pshinter;
310 }
311
Werner Lemberge3c11d72000-06-16 06:49:56 +0000312 /* open the tokenizer; this will also check the font format */
David Turner7d3a2642002-03-20 10:49:31 +0000313 if ( FT_STREAM_SEEK( 0 ) )
David Turner04aa8002000-06-01 03:27:48 +0000314 goto Exit;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000315
Werner Lemberge35cac62000-06-11 03:46:57 +0000316 error = CID_Open_Face( face );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000317 if ( error )
318 goto Exit;
David Turner04aa8002000-06-01 03:27:48 +0000319
320 /* if we just wanted to check the format, leave successfully now */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000321 if ( face_index < 0 )
David Turner04aa8002000-06-01 03:27:48 +0000322 goto Exit;
323
324 /* check the face index */
325 if ( face_index != 0 )
326 {
David Turner85eb6692001-12-20 09:36:21 +0000327 FT_ERROR(( "CID_Face_Init: invalid face index\n" ));
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000328 error = CID_Err_Invalid_Argument;
David Turner04aa8002000-06-01 03:27:48 +0000329 goto Exit;
330 }
331
332 /* Now, load the font program into the face object */
333 {
334 /* Init the face object fields */
335 /* Now set up root face fields */
336 {
337 FT_Face root = (FT_Face)&face->root;
338
Werner Lemberge3c11d72000-06-16 06:49:56 +0000339
David Turner04aa8002000-06-01 03:27:48 +0000340 root->num_glyphs = face->cid.cid_count;
341 root->num_charmaps = 0;
342
343 root->face_index = face_index;
344 root->face_flags = FT_FACE_FLAG_SCALABLE;
345
346 root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
347
348 if ( face->cid.font_info.is_fixed_pitch )
349 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
350
Werner Lembergac39ecd2000-06-30 22:24:36 +0000351 /* XXX: TODO: add kerning with .afm support */
David Turner04aa8002000-06-01 03:27:48 +0000352
Werner Lembergac39ecd2000-06-30 22:24:36 +0000353 /* get style name -- be careful, some broken fonts only */
354 /* have a /FontName dictionary entry! */
David Turner04aa8002000-06-01 03:27:48 +0000355 root->family_name = face->cid.font_info.family_name;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000356 if ( root->family_name )
David Turner04aa8002000-06-01 03:27:48 +0000357 {
358 char* full = face->cid.font_info.full_name;
359 char* family = root->family_name;
360
361 while ( *family && *full == *family )
362 {
363 family++;
364 full++;
365 }
366
Werner Lemberge3c11d72000-06-16 06:49:56 +0000367 root->style_name = ( *full == ' ' ) ? full + 1
Werner Lembergbd5ae402000-07-05 04:32:02 +0000368 : (char *)"Regular";
David Turner04aa8002000-06-01 03:27:48 +0000369 }
370 else
371 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000372 /* do we have a `/FontName'? */
373 if ( face->cid.cid_font_name )
David Turner04aa8002000-06-01 03:27:48 +0000374 {
375 root->family_name = face->cid.cid_font_name;
Werner Lemberge72c9fe2000-07-31 18:59:02 +0000376 root->style_name = (char *)"Regular";
David Turner04aa8002000-06-01 03:27:48 +0000377 }
378 }
379
380 /* no embedded bitmap support */
381 root->num_fixed_sizes = 0;
382 root->available_sizes = 0;
383
David Turner7d0f0ba2002-03-05 15:55:28 +0000384 root->bbox.xMin = face->cid.font_bbox.xMin >> 16;
385 root->bbox.yMin = face->cid.font_bbox.yMin >> 16;
386 root->bbox.xMax = (face->cid.font_bbox.xMax + 0xFFFFU) >> 16;
387 root->bbox.yMax = (face->cid.font_bbox.yMax + 0xFFFFU) >> 16;
388
389
Tom Kacvinsky00169a32001-03-10 19:06:54 +0000390 if ( !root->units_per_EM )
391 root->units_per_EM = 1000;
392
David Turneracfea4d2002-03-06 12:38:15 +0000393 root->ascender = (FT_Short)( root->bbox.yMax );
394 root->descender = (FT_Short)( root->bbox.yMin );
Werner Lemberg8eb03532001-06-19 23:03:41 +0000395 root->height = (FT_Short)(
396 ( ( root->ascender + root->descender ) * 12 ) / 10 );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000397
David Turner04aa8002000-06-01 03:27:48 +0000398
David Turner04aa8002000-06-01 03:27:48 +0000399 root->underline_position = face->cid.font_info.underline_position;
400 root->underline_thickness = face->cid.font_info.underline_thickness;
401
David Turner54e75742000-11-04 02:52:02 +0000402 root->internal->max_points = 0;
403 root->internal->max_contours = 0;
David Turner04aa8002000-06-01 03:27:48 +0000404 }
405 }
406
David Turner04aa8002000-06-01 03:27:48 +0000407 Exit:
408 return error;
409 }
410
411
Werner Lemberge3c11d72000-06-16 06:49:56 +0000412 /*************************************************************************/
413 /* */
414 /* <Function> */
David Turner85eb6692001-12-20 09:36:21 +0000415 /* CID_Driver_Init */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000416 /* */
417 /* <Description> */
418 /* Initializes a given CID driver object. */
419 /* */
420 /* <Input> */
421 /* driver :: A handle to the target driver object. */
422 /* */
423 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000424 /* FreeType error code. 0 means success. */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000425 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000426 FT_LOCAL_DEF( FT_Error )
David Turner85eb6692001-12-20 09:36:21 +0000427 CID_Driver_Init( CID_Driver driver )
David Turner04aa8002000-06-01 03:27:48 +0000428 {
David Turnerc6a92202000-07-04 18:12:13 +0000429 FT_UNUSED( driver );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000430
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000431 return CID_Err_Ok;
David Turner04aa8002000-06-01 03:27:48 +0000432 }
433
434
Werner Lemberge3c11d72000-06-16 06:49:56 +0000435 /*************************************************************************/
436 /* */
437 /* <Function> */
David Turner85eb6692001-12-20 09:36:21 +0000438 /* CID_Driver_Done */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000439 /* */
440 /* <Description> */
441 /* Finalizes a given CID driver. */
442 /* */
443 /* <Input> */
444 /* driver :: A handle to the target CID driver. */
445 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000446 FT_LOCAL_DEF( void )
David Turner85eb6692001-12-20 09:36:21 +0000447 CID_Driver_Done( CID_Driver driver )
David Turner04aa8002000-06-01 03:27:48 +0000448 {
David Turnerc6a92202000-07-04 18:12:13 +0000449 FT_UNUSED( driver );
David Turner04aa8002000-06-01 03:27:48 +0000450 }
451
452
453/* END */