1 /***************************************************************************/
5 /* CID-keyed Type1 Glyph Loader (body). */
7 /* Copyright 1996-2001 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 /***************************************************************************/
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_INTERNAL_STREAM_H
29 /*************************************************************************/
31 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
32 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
33 /* messages during execution. */
36 #define FT_COMPONENT trace_cidgload
39 FT_CALLBACK_DEF( FT_Error )
40 cid_load_glyph( T1_Decoder* decoder,
43 CID_Face face = (CID_Face)decoder->builder.face;
44 CID_Info* cid = &face->cid;
46 FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
48 FT_ULong off1, glyph_len;
49 FT_Stream stream = face->root.stream;
53 /* read the CID font dict index and charstring offset from the CIDMap */
54 if ( FILE_Seek( cid->data_offset + cid->cidmap_offset +
55 glyph_index * entry_len ) ||
56 ACCESS_Frame( 2 * entry_len ) )
59 p = (FT_Byte*)stream->cursor;
60 fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
61 off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
63 glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
67 /* now, if the glyph is not empty, set up the subrs array, and parse */
72 CID_Subrs* cid_subrs = face->subrs + fd_select;
74 FT_Memory memory = face->root.memory;
78 decoder->num_subrs = cid_subrs->num_subrs;
79 decoder->subrs = cid_subrs->code;
80 decoder->subrs_len = 0;
82 /* setup font matrix */
83 dict = cid->font_dicts + fd_select;
85 decoder->font_matrix = dict->font_matrix;
86 decoder->font_offset = dict->font_offset;
87 decoder->lenIV = dict->private_dict.lenIV;
89 /* the charstrings are encoded (stupid!) */
90 /* load the charstrings, then execute it */
92 if ( ALLOC( charstring, glyph_len ) )
95 if ( !FILE_Read_At( cid->data_offset + off1, charstring, glyph_len ) )
100 /* Adjustment for seed bytes. */
101 cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
103 /* Decrypt only if lenIV >= 0. */
104 if ( decoder->lenIV >= 0 )
105 cid_decrypt( charstring, glyph_len, 4330 );
107 error = decoder->funcs.parse_charstrings( decoder,
108 charstring + cs_offset,
109 glyph_len - cs_offset );
123 /*************************************************************************/
124 /*************************************************************************/
125 /*************************************************************************/
126 /********** *********/
127 /********** *********/
128 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
129 /********** *********/
130 /********** The following code is in charge of computing *********/
131 /********** the maximum advance width of the font. It *********/
132 /********** quickly processes each glyph charstring to *********/
133 /********** extract the value from either a `sbw' or `seac' *********/
134 /********** operator. *********/
135 /********** *********/
136 /*************************************************************************/
137 /*************************************************************************/
138 /*************************************************************************/
141 FT_LOCAL_DEF FT_Error
142 CID_Compute_Max_Advance( CID_Face face,
143 FT_Int* max_advance )
149 PSAux_Interface* psaux = (PSAux_Interface*)face->psaux;
154 /* Initialize load decoder */
155 error = psaux->t1_decoder_funcs->init( &decoder,
159 0, /* glyph names! XXX */
165 decoder.builder.metrics_only = 1;
166 decoder.builder.load_points = 0;
168 /* for each glyph, parse the glyph charstring and extract */
169 /* the advance width */
170 for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
173 /* now get load the unscaled outline */
174 error = cid_load_glyph( &decoder, glyph_index );
175 /* ignore the error if one occurred - skip to next glyph */
178 *max_advance = decoder.builder.advance.x;
187 /*************************************************************************/
188 /*************************************************************************/
189 /*************************************************************************/
190 /********** *********/
191 /********** *********/
192 /********** UNHINTED GLYPH LOADER *********/
193 /********** *********/
194 /********** The following code is in charge of loading a *********/
195 /********** single outline. It completely ignores hinting *********/
196 /********** and is used when FT_LOAD_NO_HINTING is set. *********/
197 /********** *********/
198 /*************************************************************************/
199 /*************************************************************************/
200 /*************************************************************************/
203 FT_LOCAL_DEF FT_Error
204 CID_Load_Glyph( CID_GlyphSlot glyph,
211 CID_Face face = (CID_Face)glyph->root.face;
214 PSAux_Interface* psaux = (PSAux_Interface*)face->psaux;
215 FT_Matrix font_matrix;
216 FT_Vector font_offset;
219 if ( load_flags & FT_LOAD_NO_RECURSE )
220 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
222 glyph->x_scale = size->root.metrics.x_scale;
223 glyph->y_scale = size->root.metrics.y_scale;
225 glyph->root.outline.n_points = 0;
226 glyph->root.outline.n_contours = 0;
228 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
229 ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
231 glyph->root.format = ft_glyph_format_outline;
234 error = psaux->t1_decoder_funcs->init( &decoder,
238 0, /* glyph names -- XXX */
242 /* set up the decoder */
243 decoder.builder.no_recurse = FT_BOOL(
244 ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
246 error = cid_load_glyph( &decoder, glyph_index );
248 font_matrix = decoder.font_matrix;
249 font_offset = decoder.font_offset;
251 /* save new glyph tables */
252 psaux->t1_decoder_funcs->done( &decoder );
255 /* now, set the metrics -- this is rather simple, as */
256 /* the left side bearing is the xMin, and the top side */
257 /* bearing the yMax */
260 glyph->root.outline.flags &= ft_outline_owner;
261 glyph->root.outline.flags |= ft_outline_reverse_fill;
263 /* for composite glyphs, return only left side bearing and */
265 if ( load_flags & FT_LOAD_NO_RECURSE )
267 FT_Slot_Internal internal = glyph->root.internal;
270 glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
271 glyph->root.metrics.horiAdvance = decoder.builder.advance.x;
273 internal->glyph_matrix = font_matrix;
274 internal->glyph_delta = font_offset;
275 internal->glyph_transformed = 1;
280 FT_Glyph_Metrics* metrics = &glyph->root.metrics;
283 /* copy the _unscaled_ advance width */
284 metrics->horiAdvance = decoder.builder.advance.x;
285 glyph->root.linearHoriAdvance = decoder.builder.advance.x;
286 glyph->root.internal->glyph_transformed = 0;
288 /* make up vertical metrics */
289 metrics->vertBearingX = 0;
290 metrics->vertBearingY = 0;
291 metrics->vertAdvance = 0;
293 glyph->root.linearVertAdvance = 0;
294 glyph->root.format = ft_glyph_format_outline;
296 if ( size && size->root.metrics.y_ppem < 24 )
297 glyph->root.outline.flags |= ft_outline_high_precision;
299 /* apply the font matrix */
300 FT_Outline_Transform( &glyph->root.outline, &font_matrix );
302 FT_Outline_Translate( &glyph->root.outline,
306 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
308 /* scale the outline and the metrics */
310 FT_Outline* cur = decoder.builder.base;
311 FT_Vector* vec = cur->points;
312 FT_Fixed x_scale = glyph->x_scale;
313 FT_Fixed y_scale = glyph->y_scale;
316 /* First of all, scale the points */
317 for ( n = cur->n_points; n > 0; n--, vec++ )
319 vec->x = FT_MulFix( vec->x, x_scale );
320 vec->y = FT_MulFix( vec->y, y_scale );
323 FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
325 /* Then scale the metrics */
326 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
327 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
329 metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
330 metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
333 /* compute the other metrics */
334 FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
336 /* grid fit the bounding box if necessary */
341 cbox.xMax = ( cbox.xMax + 63 ) & -64;
342 cbox.yMax = ( cbox.yMax + 63 ) & -64;
345 metrics->width = cbox.xMax - cbox.xMin;
346 metrics->height = cbox.yMax - cbox.yMin;
348 metrics->horiBearingX = cbox.xMin;
349 metrics->horiBearingY = cbox.yMax;