blob: efca5ec3cb5f3e69faefa8d632fb5e59bf80678d [file] [log] [blame]
Werner Lemberge3c11d72000-06-16 06:49:56 +00001/***************************************************************************/
2/* */
3/* cidobjs.c */
4/* */
5/* CID objects manager (body). */
6/* */
7/* Copyright 1996-2000 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
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 Turner04aa8002000-06-01 03:27:48 +000026
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000027#include "ciderrs.h"
28
Werner Lemberge3c11d72000-06-16 06:49:56 +000029
30 /*************************************************************************/
31 /* */
32 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34 /* messages during execution. */
35 /* */
Werner Lemberg63408a12000-12-13 23:44:37 +000036#undef FT_COMPONENT
37#define FT_COMPONENT trace_cidobjs
David Turner04aa8002000-06-01 03:27:48 +000038
David Turner04aa8002000-06-01 03:27:48 +000039
Werner Lemberge3c11d72000-06-16 06:49:56 +000040 /*************************************************************************/
41 /* */
Werner Lemberge3c11d72000-06-16 06:49:56 +000042 /* FACE FUNCTIONS */
43 /* */
44 /*************************************************************************/
David Turner04aa8002000-06-01 03:27:48 +000045
David Turner04aa8002000-06-01 03:27:48 +000046
Werner Lemberge3c11d72000-06-16 06:49:56 +000047 /*************************************************************************/
48 /* */
49 /* <Function> */
50 /* CID_Done_Face */
51 /* */
52 /* <Description> */
53 /* Finalizes a given face object. */
54 /* */
55 /* <Input> */
56 /* face :: A pointer to the face object to destroy. */
57 /* */
David Turner76a5f622000-11-04 01:55:49 +000058 FT_LOCAL_DEF
Werner Lemberge3c11d72000-06-16 06:49:56 +000059 void CID_Done_Face( CID_Face face )
David Turner04aa8002000-06-01 03:27:48 +000060 {
61 FT_Memory memory;
62
Werner Lemberge3c11d72000-06-16 06:49:56 +000063
64 if ( face )
David Turner04aa8002000-06-01 03:27:48 +000065 {
Werner Lemberge3c11d72000-06-16 06:49:56 +000066 CID_Info* cid = &face->cid;
67 T1_FontInfo* info = &cid->font_info;
68
David Turner04aa8002000-06-01 03:27:48 +000069
70 memory = face->root.memory;
Werner Lemberge3c11d72000-06-16 06:49:56 +000071
David Turner04aa8002000-06-01 03:27:48 +000072 /* release FontInfo strings */
73 FREE( info->version );
74 FREE( info->notice );
75 FREE( info->full_name );
76 FREE( info->family_name );
77 FREE( info->weight );
Werner Lemberge3c11d72000-06-16 06:49:56 +000078
David Turner04aa8002000-06-01 03:27:48 +000079 /* release font dictionaries */
80 FREE( cid->font_dicts );
81 cid->num_dicts = 0;
Werner Lemberge3c11d72000-06-16 06:49:56 +000082
David Turner04aa8002000-06-01 03:27:48 +000083 /* release other strings */
84 FREE( cid->cid_font_name );
85 FREE( cid->registry );
86 FREE( cid->ordering );
Werner Lemberge3c11d72000-06-16 06:49:56 +000087
David Turner04aa8002000-06-01 03:27:48 +000088 face->root.family_name = 0;
89 face->root.style_name = 0;
90 }
91 }
92
David Turner04aa8002000-06-01 03:27:48 +000093
Werner Lemberge3c11d72000-06-16 06:49:56 +000094 /*************************************************************************/
95 /* */
96 /* <Function> */
97 /* CID_Init_Face */
98 /* */
99 /* <Description> */
100 /* Initializes a given CID face object. */
101 /* */
102 /* <Input> */
103 /* stream :: The source font stream. */
104 /* */
105 /* face_index :: The index of the font face in the resource. */
106 /* */
107 /* num_params :: Number of additional generic parameters. Ignored. */
108 /* */
109 /* params :: Additional generic parameters. Ignored. */
110 /* */
111 /* <InOut> */
112 /* face :: The newly built face object. */
113 /* */
114 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000115 /* FreeType error code. 0 means success. */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000116 /* */
David Turner76a5f622000-11-04 01:55:49 +0000117 FT_LOCAL_DEF
David Turnerf9b8dec2000-06-16 19:34:52 +0000118 FT_Error CID_Init_Face( FT_Stream stream,
Werner Lemberge3c11d72000-06-16 06:49:56 +0000119 CID_Face face,
David Turnerf9b8dec2000-06-16 19:34:52 +0000120 FT_Int face_index,
121 FT_Int num_params,
Werner Lemberge3c11d72000-06-16 06:49:56 +0000122 FT_Parameter* params )
David Turner04aa8002000-06-01 03:27:48 +0000123 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000124 FT_Error error;
David Turner04aa8002000-06-01 03:27:48 +0000125 PSNames_Interface* psnames;
David Turner34f1c2f2000-08-23 22:47:44 +0000126 PSAux_Interface* psaux;
David Turner04aa8002000-06-01 03:27:48 +0000127
David Turnerc6a92202000-07-04 18:12:13 +0000128 FT_UNUSED( num_params );
129 FT_UNUSED( params );
130 FT_UNUSED( face_index );
131 FT_UNUSED( stream );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000132
David Turner04aa8002000-06-01 03:27:48 +0000133
134 face->root.num_faces = 1;
135
136 psnames = (PSNames_Interface*)face->psnames;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000137 if ( !psnames )
David Turner04aa8002000-06-01 03:27:48 +0000138 {
Werner Lemberga929ba92000-06-25 06:47:11 +0000139 psnames = (PSNames_Interface*)FT_Get_Module_Interface(
140 FT_FACE_LIBRARY( face ), "psnames" );
David Turner04aa8002000-06-01 03:27:48 +0000141
David Turnerc3128612000-06-23 05:02:13 +0000142 face->psnames = psnames;
David Turner04aa8002000-06-01 03:27:48 +0000143 }
144
David Turner34f1c2f2000-08-23 22:47:44 +0000145 psaux = (PSAux_Interface*)face->psaux;
146 if ( !psaux )
147 {
148 psaux = (PSAux_Interface*)FT_Get_Module_Interface(
149 FT_FACE_LIBRARY( face ), "psaux" );
Werner Lemberge4b32a52000-10-31 20:42:18 +0000150
David Turner34f1c2f2000-08-23 22:47:44 +0000151 face->psaux = psaux;
152 }
153
Werner Lemberge3c11d72000-06-16 06:49:56 +0000154 /* open the tokenizer; this will also check the font format */
155 if ( FILE_Seek( 0 ) )
David Turner04aa8002000-06-01 03:27:48 +0000156 goto Exit;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000157
Werner Lemberge35cac62000-06-11 03:46:57 +0000158 error = CID_Open_Face( face );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000159 if ( error )
160 goto Exit;
David Turner04aa8002000-06-01 03:27:48 +0000161
162 /* if we just wanted to check the format, leave successfully now */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000163 if ( face_index < 0 )
David Turner04aa8002000-06-01 03:27:48 +0000164 goto Exit;
165
166 /* check the face index */
167 if ( face_index != 0 )
168 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000169 FT_ERROR(( "CID_Init_Face: invalid face index\n" ));
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000170 error = CID_Err_Invalid_Argument;
David Turner04aa8002000-06-01 03:27:48 +0000171 goto Exit;
172 }
173
174 /* Now, load the font program into the face object */
175 {
176 /* Init the face object fields */
177 /* Now set up root face fields */
178 {
179 FT_Face root = (FT_Face)&face->root;
180
Werner Lemberge3c11d72000-06-16 06:49:56 +0000181
David Turner04aa8002000-06-01 03:27:48 +0000182 root->num_glyphs = face->cid.cid_count;
183 root->num_charmaps = 0;
184
185 root->face_index = face_index;
186 root->face_flags = FT_FACE_FLAG_SCALABLE;
187
188 root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
189
190 if ( face->cid.font_info.is_fixed_pitch )
191 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
192
Werner Lembergac39ecd2000-06-30 22:24:36 +0000193 /* XXX: TODO: add kerning with .afm support */
David Turner04aa8002000-06-01 03:27:48 +0000194
Werner Lembergac39ecd2000-06-30 22:24:36 +0000195 /* get style name -- be careful, some broken fonts only */
196 /* have a /FontName dictionary entry! */
David Turner04aa8002000-06-01 03:27:48 +0000197 root->family_name = face->cid.font_info.family_name;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000198 if ( root->family_name )
David Turner04aa8002000-06-01 03:27:48 +0000199 {
200 char* full = face->cid.font_info.full_name;
201 char* family = root->family_name;
202
203 while ( *family && *full == *family )
204 {
205 family++;
206 full++;
207 }
208
Werner Lemberge3c11d72000-06-16 06:49:56 +0000209 root->style_name = ( *full == ' ' ) ? full + 1
Werner Lembergbd5ae402000-07-05 04:32:02 +0000210 : (char *)"Regular";
David Turner04aa8002000-06-01 03:27:48 +0000211 }
212 else
213 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000214 /* do we have a `/FontName'? */
215 if ( face->cid.cid_font_name )
David Turner04aa8002000-06-01 03:27:48 +0000216 {
217 root->family_name = face->cid.cid_font_name;
Werner Lemberge72c9fe2000-07-31 18:59:02 +0000218 root->style_name = (char *)"Regular";
David Turner04aa8002000-06-01 03:27:48 +0000219 }
220 }
221
222 /* no embedded bitmap support */
223 root->num_fixed_sizes = 0;
224 root->available_sizes = 0;
225
Werner Lemberg8eb03532001-06-19 23:03:41 +0000226 root->bbox = face->cid.font_bbox;
Tom Kacvinsky00169a32001-03-10 19:06:54 +0000227 if ( !root->units_per_EM )
228 root->units_per_EM = 1000;
229
Werner Lemberg8eb03532001-06-19 23:03:41 +0000230 root->ascender = (FT_Short)( face->cid.font_bbox.yMax >> 16 );
231 root->descender = (FT_Short)( face->cid.font_bbox.yMin >> 16 );
232 root->height = (FT_Short)(
233 ( ( root->ascender + root->descender ) * 12 ) / 10 );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000234
David Turner04aa8002000-06-01 03:27:48 +0000235
236#if 0
Werner Lemberge3c11d72000-06-16 06:49:56 +0000237
David Turner04aa8002000-06-01 03:27:48 +0000238 /* now compute the maximum advance width */
239
240 root->max_advance_width = face->type1.private_dict.standard_width[0];
241
242 /* compute max advance width for proportional fonts */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000243 if ( !face->type1.font_info.is_fixed_pitch )
David Turner04aa8002000-06-01 03:27:48 +0000244 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000245 FT_Int max_advance;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000246
David Turner04aa8002000-06-01 03:27:48 +0000247
David Turnera1be2dc2000-06-27 23:20:35 +0000248 error = CID_Compute_Max_Advance( face, &max_advance );
David Turner04aa8002000-06-01 03:27:48 +0000249
250 /* in case of error, keep the standard width */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000251 if ( !error )
David Turner04aa8002000-06-01 03:27:48 +0000252 root->max_advance_width = max_advance;
253 else
254 error = 0; /* clear error */
255 }
256
257 root->max_advance_height = root->height;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000258
259#endif /* 0 */
260
David Turner04aa8002000-06-01 03:27:48 +0000261 root->underline_position = face->cid.font_info.underline_position;
262 root->underline_thickness = face->cid.font_info.underline_thickness;
263
David Turner54e75742000-11-04 02:52:02 +0000264 root->internal->max_points = 0;
265 root->internal->max_contours = 0;
David Turner04aa8002000-06-01 03:27:48 +0000266 }
267 }
268
269#if 0
Werner Lemberge3c11d72000-06-16 06:49:56 +0000270
David Turner04aa8002000-06-01 03:27:48 +0000271 /* charmap support - synthetize unicode charmap when possible */
272 {
273 FT_Face root = &face->root;
274 FT_CharMap charmap = face->charmaprecs;
275
Werner Lemberge3c11d72000-06-16 06:49:56 +0000276
Werner Lembergac39ecd2000-06-30 22:24:36 +0000277 /* synthesize a Unicode charmap if there is support in the `psnames' */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000278 /* module */
279 if ( face->psnames )
David Turner04aa8002000-06-01 03:27:48 +0000280 {
281 PSNames_Interface* psnames = (PSNames_Interface*)face->psnames;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000282
283
284 if ( psnames->unicode_value )
David Turner04aa8002000-06-01 03:27:48 +0000285 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000286 error = psnames->build_unicodes(
287 root->memory,
288 face->type1.num_glyphs,
289 (const char**)face->type1.glyph_names,
290 &face->unicode_map );
291 if ( !error )
David Turner04aa8002000-06-01 03:27:48 +0000292 {
293 root->charmap = charmap;
294 charmap->face = (FT_Face)face;
295 charmap->encoding = ft_encoding_unicode;
296 charmap->platform_id = 3;
297 charmap->encoding_id = 1;
298 charmap++;
299 }
300
Werner Lemberge3c11d72000-06-16 06:49:56 +0000301 /* simply clear the error in case of failure (which really */
302 /* means that out of memory or no unicode glyph names) */
David Turner04aa8002000-06-01 03:27:48 +0000303 error = 0;
304 }
305 }
306
307 /* now, support either the standard, expert, or custom encodings */
308 charmap->face = (FT_Face)face;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000309 charmap->platform_id = 7; /* a new platform id for Adobe fonts? */
David Turner04aa8002000-06-01 03:27:48 +0000310
Werner Lemberge3c11d72000-06-16 06:49:56 +0000311 switch ( face->type1.encoding_type )
David Turner04aa8002000-06-01 03:27:48 +0000312 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000313 case t1_encoding_standard:
314 charmap->encoding = ft_encoding_adobe_standard;
315 charmap->encoding_id = 0;
316 break;
David Turner04aa8002000-06-01 03:27:48 +0000317
Werner Lemberge3c11d72000-06-16 06:49:56 +0000318 case t1_encoding_expert:
319 charmap->encoding = ft_encoding_adobe_expert;
320 charmap->encoding_id = 1;
321 break;
David Turner04aa8002000-06-01 03:27:48 +0000322
Werner Lemberge3c11d72000-06-16 06:49:56 +0000323 default:
324 charmap->encoding = ft_encoding_adobe_custom;
325 charmap->encoding_id = 2;
326 break;
David Turner04aa8002000-06-01 03:27:48 +0000327 }
328
Werner Lemberge3c11d72000-06-16 06:49:56 +0000329 root->charmaps = face->charmaps;
David Turner04aa8002000-06-01 03:27:48 +0000330 root->num_charmaps = charmap - face->charmaprecs + 1;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000331 face->charmaps[0] = &face->charmaprecs[0];
332 face->charmaps[1] = &face->charmaprecs[1];
David Turner04aa8002000-06-01 03:27:48 +0000333 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000334
335#endif /* 0 */
336
David Turner04aa8002000-06-01 03:27:48 +0000337 Exit:
338 return error;
339 }
340
341
Werner Lemberge3c11d72000-06-16 06:49:56 +0000342 /*************************************************************************/
343 /* */
344 /* <Function> */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000345 /* CID_Init_Driver */
346 /* */
347 /* <Description> */
348 /* Initializes a given CID driver object. */
349 /* */
350 /* <Input> */
351 /* driver :: A handle to the target driver object. */
352 /* */
353 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000354 /* FreeType error code. 0 means success. */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000355 /* */
David Turner76a5f622000-11-04 01:55:49 +0000356 FT_LOCAL_DEF
David Turnera1be2dc2000-06-27 23:20:35 +0000357 FT_Error CID_Init_Driver( CID_Driver driver )
David Turner04aa8002000-06-01 03:27:48 +0000358 {
David Turnerc6a92202000-07-04 18:12:13 +0000359 FT_UNUSED( driver );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000360
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000361 return CID_Err_Ok;
David Turner04aa8002000-06-01 03:27:48 +0000362 }
363
364
Werner Lemberge3c11d72000-06-16 06:49:56 +0000365 /*************************************************************************/
366 /* */
367 /* <Function> */
368 /* CID_Done_Driver */
369 /* */
370 /* <Description> */
371 /* Finalizes a given CID driver. */
372 /* */
373 /* <Input> */
374 /* driver :: A handle to the target CID driver. */
375 /* */
Werner Lemberg1429db62001-04-02 23:54:01 +0000376 FT_LOCAL_DEF
David Turnera1be2dc2000-06-27 23:20:35 +0000377 void CID_Done_Driver( CID_Driver driver )
David Turner04aa8002000-06-01 03:27:48 +0000378 {
David Turnerc6a92202000-07-04 18:12:13 +0000379 FT_UNUSED( driver );
David Turner04aa8002000-06-01 03:27:48 +0000380 }
381
382
383/* END */