40#define FT_COMPONENT cidgload
54 FT_LOCAL_DEF( FT_Error )
55 cid_compute_fd_and_offsets( CID_Face face,
57 FT_ULong* fd_select_p,
61 FT_Error error = FT_Err_Ok;
63 CID_FaceInfo cid = &face->cid;
64 FT_Stream stream = face->cid_stream;
65 FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
68 FT_Bool need_frame_exit = 0;
69 FT_ULong fd_select, off1, off2;
75 if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
76 glyph_index * entry_len ) ||
77 FT_FRAME_ENTER( 2 * entry_len ) )
82 p = (FT_Byte*)stream->cursor;
83 fd_select = cid_get_offset( &p, cid->fd_bytes );
84 off1 = cid_get_offset( &p, cid->gd_bytes );
87 off2 = cid_get_offset( &p, cid->gd_bytes );
90 *fd_select_p = fd_select;
96 if ( fd_select >= cid->num_dicts )
103 if ( ( cid->fd_bytes == 1 && fd_select == 0xFFU ) ||
104 ( cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
106 FT_TRACE1((
"cid_load_glyph: fail for glyph index %u:\n",
108 FT_TRACE1((
" FD number %lu is the maximum\n",
110 FT_TRACE1((
" integer fitting into %u byte%s\n",
111 cid->fd_bytes, cid->fd_bytes == 1 ?
"" :
"s" ));
115 FT_TRACE0((
"cid_load_glyph: fail for glyph index %u:\n",
117 FT_TRACE0((
" FD number %lu is larger\n",
119 FT_TRACE0((
" than number of dictionaries (%u)\n",
123 error = FT_THROW( Invalid_Offset );
126 else if ( off2 > stream->size )
128 FT_TRACE0((
"cid_load_glyph: fail for glyph index %u:\n",
130 FT_TRACE0((
" end of the glyph data\n" ));
131 FT_TRACE0((
" is beyond the data stream\n" ));
133 error = FT_THROW( Invalid_Offset );
136 else if ( off1 > off2 )
138 FT_TRACE0((
"cid_load_glyph: fail for glyph index %u:\n",
140 FT_TRACE0((
" the end position of glyph data\n" ));
141 FT_TRACE0((
" is set before the start position\n" ));
143 error = FT_THROW( Invalid_Offset );
147 if ( need_frame_exit )
154 FT_CALLBACK_DEF( FT_Error )
155 cid_load_glyph( T1_Decoder decoder,
156 FT_UInt glyph_index )
158 CID_Face face = (CID_Face)decoder->builder.face;
159 CID_FaceInfo cid = &face->cid;
162 FT_Stream stream = face->cid_stream;
163 FT_Error error = FT_Err_Ok;
164 FT_Byte* charstring = NULL;
165 FT_Memory memory = face->root.memory;
166 FT_ULong glyph_length = 0;
167 PSAux_Service psaux = (PSAux_Service)face->psaux;
169 FT_Bool force_scaling = FALSE;
171#ifdef FT_CONFIG_OPTION_INCREMENTAL
172 FT_Incremental_InterfaceRec *inc =
173 face->root.internal->incremental_interface;
177 FT_TRACE1((
"cid_load_glyph: glyph index %u\n", glyph_index ));
179#ifdef FT_CONFIG_OPTION_INCREMENTAL
188 error = inc->funcs->get_glyph_data( inc->object,
189 glyph_index, &glyph_data );
190 if ( error || glyph_data.length < cid->fd_bytes )
193 p = (FT_Byte*)glyph_data.pointer;
194 fd_select = cid_get_offset( &p, cid->fd_bytes );
196 glyph_length = glyph_data.length - cid->fd_bytes;
198 if ( !FT_QALLOC( charstring, glyph_length ) )
199 FT_MEM_COPY( charstring, glyph_data.pointer + cid->fd_bytes,
202 inc->funcs->free_glyph_data( inc->object, &glyph_data );
215 error = cid_compute_fd_and_offsets( face, glyph_index,
216 &fd_select, &off1, &off2 );
220 glyph_length = off2 - off1;
222 if ( glyph_length == 0 ||
223 FT_QALLOC( charstring, glyph_length ) ||
224 FT_STREAM_READ_AT( cid->data_offset + off1,
225 charstring, glyph_length ) )
232 CID_Subrs cid_subrs = face->subrs + fd_select;
237 decoder->num_subrs = cid_subrs->num_subrs;
238 decoder->subrs = cid_subrs->code;
239 decoder->subrs_len = 0;
240 decoder->subrs_hash = NULL;
243 dict = cid->font_dicts + fd_select;
245 decoder->font_matrix = dict->font_matrix;
246 decoder->font_offset = dict->font_offset;
247 decoder->lenIV = dict->private_dict.lenIV;
252 cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0;
253 if ( cs_offset > glyph_length )
255 FT_TRACE0((
"cid_load_glyph: fail for glyph_index=%u,"
256 " offset to the charstring is beyond glyph length\n",
258 error = FT_THROW( Invalid_Offset );
263 if ( decoder->lenIV >= 0 )
264 psaux->t1_decrypt( charstring, glyph_length, 4330 );
267#ifdef T1_CONFIG_OPTION_OLD_ENGINE
268 if ( ( (PS_Driver)FT_FACE_DRIVER( face ) )->hinting_engine ==
269 FT_HINTING_FREETYPE ||
270 decoder->builder.metrics_only )
271 error = psaux->t1_decoder_funcs->parse_charstrings_old(
273 charstring + cs_offset,
274 glyph_length - cs_offset );
276 if ( decoder->builder.metrics_only )
277 error = psaux->t1_decoder_funcs->parse_metrics(
279 charstring + cs_offset,
280 glyph_length - cs_offset );
284 PS_Decoder psdecoder;
285 CFF_SubFontRec subfont;
288 psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
290 psaux->t1_make_subfont( FT_FACE( face ),
293 psdecoder.current_subfont = &subfont;
295 error = psaux->t1_decoder_funcs->parse_charstrings(
297 charstring + cs_offset,
298 glyph_length - cs_offset );
302 if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
307 ((CID_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
309 force_scaling = TRUE;
311 error = psaux->t1_decoder_funcs->parse_charstrings(
313 charstring + cs_offset,
314 glyph_length - cs_offset );
319#ifdef FT_CONFIG_OPTION_INCREMENTAL
322 if ( !error && inc && inc->funcs->get_glyph_metrics )
324 FT_Incremental_MetricsRec metrics;
327 metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
328 metrics.bearing_y = 0;
329 metrics.advance = FIXED_TO_INT( decoder->builder.advance.x );
330 metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
332 error = inc->funcs->get_glyph_metrics( inc->object,
333 glyph_index, FALSE, &metrics );
335 decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
336 decoder->builder.advance.x = INT_TO_FIXED( metrics.advance );
337 decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v );
343 FT_FREE( charstring );
345 ((CID_GlyphSlot)decoder->builder.glyph)->scaled = force_scaling;
372 FT_LOCAL_DEF( FT_Error )
373 cid_face_compute_max_advance( CID_Face face,
374 FT_Int* max_advance )
377 T1_DecoderRec decoder;
380 PSAux_Service psaux = (PSAux_Service)face->psaux;
386 error = psaux->t1_decoder_funcs->init( &decoder,
400 decoder.builder.metrics_only = 1;
401 decoder.builder.load_points = 0;
405 for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
409 error = cid_load_glyph( &decoder, glyph_index );
413 *max_advance = FIXED_TO_INT( decoder.builder.advance.x );
415 psaux->t1_decoder_funcs->done( &decoder );
424 FT_LOCAL_DEF( FT_Error )
425 cid_slot_load_glyph( FT_GlyphSlot cidglyph,
428 FT_Int32 load_flags )
430 CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph;
432 T1_DecoderRec decoder;
433 CID_Face face = (CID_Face)cidglyph->face;
437 PSAux_Service psaux = (PSAux_Service)face->psaux;
438 FT_Matrix font_matrix;
439 FT_Vector font_offset;
440 FT_Bool must_finish_decoder = FALSE;
443 if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
445 error = FT_THROW( Invalid_Argument );
449 if ( load_flags & FT_LOAD_NO_RECURSE )
450 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
452 glyph->x_scale = cidsize->metrics.x_scale;
453 glyph->y_scale = cidsize->metrics.y_scale;
455 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
456 ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
457 scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
459 glyph->hint = hinting;
460 glyph->scaled = scaled;
462 error = psaux->t1_decoder_funcs->init( &decoder,
469 FT_LOAD_TARGET_MODE( load_flags ),
477 must_finish_decoder = TRUE;
480 decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
482 error = cid_load_glyph( &decoder, glyph_index );
487 hinting = glyph->hint;
488 scaled = glyph->scaled;
490 font_matrix = decoder.font_matrix;
491 font_offset = decoder.font_offset;
494 psaux->t1_decoder_funcs->done( &decoder );
496 must_finish_decoder = FALSE;
502 if ( load_flags & FT_LOAD_NO_RECURSE )
504 FT_Slot_Internal internal = cidglyph->internal;
507 cidglyph->metrics.horiBearingX =
508 FIXED_TO_INT( decoder.builder.left_bearing.x );
509 cidglyph->metrics.horiAdvance =
510 FIXED_TO_INT( decoder.builder.advance.x );
512 internal->glyph_matrix = font_matrix;
513 internal->glyph_delta = font_offset;
514 internal->glyph_transformed = 1;
519 FT_Glyph_Metrics* metrics = &cidglyph->metrics;
522 cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
524 cidglyph->outline.flags &= FT_OUTLINE_OWNER;
525 cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
526 if ( cidsize->metrics.y_ppem < 24 )
527 cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
530 metrics->horiAdvance =
531 FIXED_TO_INT( decoder.builder.advance.x );
532 cidglyph->linearHoriAdvance =
533 FIXED_TO_INT( decoder.builder.advance.x );
534 cidglyph->internal->glyph_transformed = 0;
537 metrics->vertAdvance = ( face->cid.font_bbox.yMax -
538 face->cid.font_bbox.yMin ) >> 16;
539 cidglyph->linearVertAdvance = metrics->vertAdvance;
542 if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
543 font_matrix.xy != 0 || font_matrix.yx != 0 )
545 FT_Outline_Transform( &cidglyph->outline, &font_matrix );
547 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
549 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
553 if ( font_offset.x || font_offset.y )
555 FT_Outline_Translate( &cidglyph->outline,
559 metrics->horiAdvance += font_offset.x;
560 metrics->vertAdvance += font_offset.y;
563 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || scaled )
567 FT_Outline* cur = decoder.builder.base;
568 FT_Vector* vec = cur->points;
569 FT_Fixed x_scale = glyph->x_scale;
570 FT_Fixed y_scale = glyph->y_scale;
574 if ( !hinting || !decoder.builder.hints_funcs )
575 for ( n = cur->n_points; n > 0; n--, vec++ )
577 vec->x = FT_MulFix( vec->x, x_scale );
578 vec->y = FT_MulFix( vec->y, y_scale );
582 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
583 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
587 FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
589 metrics->width = cbox.xMax - cbox.xMin;
590 metrics->height = cbox.yMax - cbox.yMin;
592 metrics->horiBearingX = cbox.xMin;
593 metrics->horiBearingY = cbox.yMax;
595 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
598 ft_synthesize_vertical_metrics( metrics,
599 metrics->vertAdvance );
605 if ( must_finish_decoder )
606 psaux->t1_decoder_funcs->done( &decoder );