source: trunk/poppler/freetype2/src/cid/cidgload.c @ 251

Last change on this file since 251 was 251, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.5

File size: 15.6 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  cidgload.c                                                             */
4/*                                                                         */
5/*    CID-keyed Type1 Glyph Loader (body).                                 */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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 "cidload.h"
21#include "cidgload.h"
22#include FT_INTERNAL_DEBUG_H
23#include FT_INTERNAL_STREAM_H
24#include FT_OUTLINE_H
25
26#include "ciderrs.h"
27
28
29  /*************************************************************************/
30  /*                                                                       */
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.                                            */
34  /*                                                                       */
35#undef  FT_COMPONENT
36#define FT_COMPONENT  trace_cidgload
37
38
39  FT_CALLBACK_DEF( FT_Error )
40  cid_load_glyph( T1_Decoder  decoder,
41                  FT_UInt     glyph_index )
42  {
43    CID_Face       face = (CID_Face)decoder->builder.face;
44    CID_FaceInfo   cid  = &face->cid;
45    FT_Byte*       p;
46    FT_UInt        fd_select;
47    FT_Stream      stream       = face->cid_stream;
48    FT_Error       error        = CID_Err_Ok;
49    FT_Byte*       charstring   = 0;
50    FT_Memory      memory       = face->root.memory;
51    FT_ULong       glyph_length = 0;
52    PSAux_Service  psaux        = (PSAux_Service)face->psaux;
53
54
55#ifdef FT_CONFIG_OPTION_INCREMENTAL
56
57    /* For incremental fonts get the character data using */
58    /* the callback function.                             */
59    if ( face->root.internal->incremental_interface )
60    {
61      FT_Data  glyph_data;
62
63
64      error = face->root.internal->incremental_interface->funcs->get_glyph_data(
65                face->root.internal->incremental_interface->object,
66                glyph_index,
67                &glyph_data );
68      if ( error )
69        goto Exit;
70
71      p         = (FT_Byte*)glyph_data.pointer;
72      fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
73
74      if ( glyph_data.length != 0 )
75      {
76        glyph_length = glyph_data.length - cid->fd_bytes;
77        (void)FT_ALLOC( charstring, glyph_length );
78        if ( !error )
79          ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes,
80                     glyph_length );
81      }
82
83      face->root.internal->incremental_interface->funcs->free_glyph_data(
84                face->root.internal->incremental_interface->object,
85                &glyph_data );
86
87      if ( error )
88        goto Exit;
89    }
90
91    else
92
93#endif /* FT_CONFIG_OPTION_INCREMENTAL */
94
95    /* For ordinary fonts read the CID font dictionary index */
96    /* and charstring offset from the CIDMap.                */
97    {
98      FT_UInt   entry_len = cid->fd_bytes + cid->gd_bytes;
99      FT_ULong  off1;
100
101
102      if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
103                           glyph_index * entry_len )               ||
104           FT_FRAME_ENTER( 2 * entry_len )                         )
105        goto Exit;
106
107      p            = (FT_Byte*)stream->cursor;
108      fd_select    = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
109      off1         = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
110      p           += cid->fd_bytes;
111      glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
112      FT_FRAME_EXIT();
113
114      if ( fd_select >= (FT_UInt)cid->num_dicts )
115      {
116        error = CID_Err_Invalid_Offset;
117        goto Exit;
118      }
119      if ( glyph_length == 0 )
120        goto Exit;
121      if ( FT_ALLOC( charstring, glyph_length ) )
122        goto Exit;
123      if ( FT_STREAM_READ_AT( cid->data_offset + off1,
124                              charstring, glyph_length ) )
125        goto Exit;
126    }
127
128    /* Now set up the subrs array and parse the charstrings. */
129    {
130      CID_FaceDict  dict;
131      CID_Subrs     cid_subrs = face->subrs + fd_select;
132      FT_Int        cs_offset;
133
134
135      /* Set up subrs */
136      decoder->num_subrs = cid_subrs->num_subrs;
137      decoder->subrs     = cid_subrs->code;
138      decoder->subrs_len = 0;
139
140      /* Set up font matrix */
141      dict                 = cid->font_dicts + fd_select;
142
143      decoder->font_matrix = dict->font_matrix;
144      decoder->font_offset = dict->font_offset;
145      decoder->lenIV       = dict->private_dict.lenIV;
146
147      /* Decode the charstring. */
148
149      /* Adjustment for seed bytes. */
150      cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
151
152      /* Decrypt only if lenIV >= 0. */
153      if ( decoder->lenIV >= 0 )
154        psaux->t1_decrypt( charstring, glyph_length, 4330 );
155
156      error = decoder->funcs.parse_charstrings(
157                decoder, charstring + cs_offset,
158                (FT_Int)glyph_length - cs_offset );
159    }
160
161    FT_FREE( charstring );
162
163#ifdef FT_CONFIG_OPTION_INCREMENTAL
164
165    /* Incremental fonts can optionally override the metrics. */
166    if ( !error                                                              &&
167         face->root.internal->incremental_interface                          &&
168         face->root.internal->incremental_interface->funcs->get_glyph_metrics )
169    {
170      FT_Incremental_MetricsRec  metrics;
171
172
173      metrics.bearing_x = decoder->builder.left_bearing.x;
174      metrics.bearing_y = decoder->builder.left_bearing.y;
175      metrics.advance   = decoder->builder.advance.x;
176      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
177                face->root.internal->incremental_interface->object,
178                glyph_index, FALSE, &metrics );
179      decoder->builder.left_bearing.x = metrics.bearing_x;
180      decoder->builder.left_bearing.y = metrics.bearing_y;
181      decoder->builder.advance.x      = metrics.advance;
182      decoder->builder.advance.y      = 0;
183    }
184
185#endif /* FT_CONFIG_OPTION_INCREMENTAL */
186
187  Exit:
188    return error;
189  }
190
191
192#if 0
193
194
195  /*************************************************************************/
196  /*************************************************************************/
197  /*************************************************************************/
198  /**********                                                      *********/
199  /**********                                                      *********/
200  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
201  /**********                                                      *********/
202  /**********    The following code is in charge of computing      *********/
203  /**********    the maximum advance width of the font.  It        *********/
204  /**********    quickly processes each glyph charstring to        *********/
205  /**********    extract the value from either a `sbw' or `seac'   *********/
206  /**********    operator.                                         *********/
207  /**********                                                      *********/
208  /*************************************************************************/
209  /*************************************************************************/
210  /*************************************************************************/
211
212
213  FT_LOCAL_DEF( FT_Error )
214  cid_face_compute_max_advance( CID_Face  face,
215                                FT_Int*   max_advance )
216  {
217    FT_Error       error;
218    T1_DecoderRec  decoder;
219    FT_Int         glyph_index;
220
221    PSAux_Service  psaux = (PSAux_Service)face->psaux;
222
223
224    *max_advance = 0;
225
226    /* Initialize load decoder */
227    error = psaux->t1_decoder_funcs->init( &decoder,
228                                           (FT_Face)face,
229                                           0, /* size       */
230                                           0, /* glyph slot */
231                                           0, /* glyph names! XXX */
232                                           0, /* blend == 0 */
233                                           0, /* hinting == 0 */
234                                           cid_load_glyph );
235    if ( error )
236      return error;
237
238    /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
239    /*       if we ever support CID-keyed multiple master fonts     */
240
241    decoder.builder.metrics_only = 1;
242    decoder.builder.load_points  = 0;
243
244    /* for each glyph, parse the glyph charstring and extract */
245    /* the advance width                                      */
246    for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
247          glyph_index++ )
248    {
249      /* now get load the unscaled outline */
250      error = cid_load_glyph( &decoder, glyph_index );
251      /* ignore the error if one occurred - skip to next glyph */
252    }
253
254    *max_advance = decoder.builder.advance.x;
255
256    psaux->t1_decoder_funcs->done( &decoder );
257
258    return CID_Err_Ok;
259  }
260
261
262#endif /* 0 */
263
264
265  FT_LOCAL_DEF( FT_Error )
266  cid_slot_load_glyph( FT_GlyphSlot  cidglyph,      /* CID_GlyphSlot */
267                       FT_Size       cidsize,       /* CID_Size      */
268                       FT_UInt       glyph_index,
269                       FT_Int32      load_flags )
270  {
271    CID_GlyphSlot  glyph = (CID_GlyphSlot)cidglyph;
272    CID_Size       size  = (CID_Size)cidsize;
273    FT_Error       error;
274    T1_DecoderRec  decoder;
275    CID_Face       face = (CID_Face)cidglyph->face;
276    FT_Bool        hinting;
277
278    PSAux_Service  psaux = (PSAux_Service)face->psaux;
279    FT_Matrix      font_matrix;
280    FT_Vector      font_offset;
281
282
283    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
284    {
285      error = CID_Err_Invalid_Argument;
286      goto Exit;
287    }
288
289    if ( load_flags & FT_LOAD_NO_RECURSE )
290      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
291
292    glyph->x_scale = cidsize->metrics.x_scale;
293    glyph->y_scale = cidsize->metrics.y_scale;
294
295    cidglyph->outline.n_points   = 0;
296    cidglyph->outline.n_contours = 0;
297
298    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
299                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
300
301    cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
302
303    error = psaux->t1_decoder_funcs->init( &decoder,
304                                           cidglyph->face,
305                                           cidsize,
306                                           cidglyph,
307                                           0, /* glyph names -- XXX */
308                                           0, /* blend == 0 */
309                                           hinting,
310                                           FT_LOAD_TARGET_MODE( load_flags ),
311                                           cid_load_glyph );
312    if ( error )
313      goto Exit;
314
315    /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
316    /*       if we ever support CID-keyed multiple master fonts     */
317
318    /* set up the decoder */
319    decoder.builder.no_recurse = FT_BOOL(
320      ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
321
322    error = cid_load_glyph( &decoder, glyph_index );
323    if ( error )
324      goto Exit;
325
326    font_matrix = decoder.font_matrix;
327    font_offset = decoder.font_offset;
328
329    /* save new glyph tables */
330    psaux->t1_decoder_funcs->done( &decoder );
331
332    /* now set the metrics -- this is rather simple, as    */
333    /* the left side bearing is the xMin, and the top side */
334    /* bearing the yMax                                    */
335    cidglyph->outline.flags &= FT_OUTLINE_OWNER;
336    cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
337
338    /* for composite glyphs, return only left side bearing and */
339    /* advance width                                           */
340    if ( load_flags & FT_LOAD_NO_RECURSE )
341    {
342      FT_Slot_Internal  internal = cidglyph->internal;
343
344
345      cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
346      cidglyph->metrics.horiAdvance  = decoder.builder.advance.x;
347
348      internal->glyph_matrix      = font_matrix;
349      internal->glyph_delta       = font_offset;
350      internal->glyph_transformed = 1;
351    }
352    else
353    {
354      FT_BBox            cbox;
355      FT_Glyph_Metrics*  metrics = &cidglyph->metrics;
356      FT_Vector          advance;
357
358
359      /* copy the _unscaled_ advance width */
360      metrics->horiAdvance                  = decoder.builder.advance.x;
361      cidglyph->linearHoriAdvance           = decoder.builder.advance.x;
362      cidglyph->internal->glyph_transformed = 0;
363
364      /* make up vertical ones */
365      metrics->vertAdvance        = ( face->cid.font_bbox.yMax -
366                                      face->cid.font_bbox.yMin ) >> 16;
367      cidglyph->linearVertAdvance = metrics->vertAdvance;
368
369      cidglyph->format            = FT_GLYPH_FORMAT_OUTLINE;
370
371      if ( size && cidsize->metrics.y_ppem < 24 )
372        cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
373
374      /* apply the font matrix */
375      FT_Outline_Transform( &cidglyph->outline, &font_matrix );
376
377      FT_Outline_Translate( &cidglyph->outline,
378                            font_offset.x,
379                            font_offset.y );
380
381      advance.x = metrics->horiAdvance;
382      advance.y = 0;
383      FT_Vector_Transform( &advance, &font_matrix );
384      metrics->horiAdvance = advance.x + font_offset.x;
385
386      advance.x = 0;
387      advance.y = metrics->vertAdvance;
388      FT_Vector_Transform( &advance, &font_matrix );
389      metrics->vertAdvance = advance.y + font_offset.y;
390
391      if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
392      {
393        /* scale the outline and the metrics */
394        FT_Int       n;
395        FT_Outline*  cur = decoder.builder.base;
396        FT_Vector*   vec = cur->points;
397        FT_Fixed     x_scale = glyph->x_scale;
398        FT_Fixed     y_scale = glyph->y_scale;
399
400
401        /* First of all, scale the points */
402        if ( !hinting || !decoder.builder.hints_funcs )
403          for ( n = cur->n_points; n > 0; n--, vec++ )
404          {
405            vec->x = FT_MulFix( vec->x, x_scale );
406            vec->y = FT_MulFix( vec->y, y_scale );
407          }
408
409        /* Then scale the metrics */
410        metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
411        metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
412      }
413
414      /* compute the other metrics */
415      FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
416
417      metrics->width  = cbox.xMax - cbox.xMin;
418      metrics->height = cbox.yMax - cbox.yMin;
419
420      metrics->horiBearingX = cbox.xMin;
421      metrics->horiBearingY = cbox.yMax;
422
423      /* make up vertical ones */
424      ft_synthesize_vertical_metrics( metrics,
425                                      metrics->vertAdvance );
426    }
427
428  Exit:
429    return error;
430  }
431
432
433/* END */
Note: See TracBrowser for help on using the repository browser.