1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  t1gload.c                                                              */
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*    Type 1 Glyph Loader (body).                                          */
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  Copyright 1996-2006, 2008-2010, 2013 by                                */
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  This file is part of the FreeType project, and may only be used,       */
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  modified, and distributed under the terms of the FreeType project      */
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  this file you indicate that you have read the license and              */
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  understand and accept it fully.                                        */
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h"
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "t1gload.h"
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftcalc.h"
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h"
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h"
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftoutln.h"
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/psaux.h"
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "t1errors.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* messages during execution.                                            */
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef  FT_COMPONENT
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT  trace_t1gload
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********                                                      *********/
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********                                                      *********/
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********    The following code is in charge of computing      *********/
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********    the maximum advance width of the font.  It        *********/
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********    quickly processes each glyph charstring to        *********/
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********    extract the value from either a `sbw' or `seac'   *********/
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********    operator.                                         *********/
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /**********                                                      *********/
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Error )
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder,
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FT_UInt     glyph_index,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FT_Data*    char_string )
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Face   face  = (T1_Face)decoder->builder.face;
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Font   type1 = &face->type1;
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Incremental_InterfaceRec *inc =
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      face->root.internal->incremental_interface;
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder->font_matrix = type1->font_matrix;
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder->font_offset = type1->font_offset;
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* For incremental fonts get the character data using the */
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* callback function.                                     */
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( inc )
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = inc->funcs->get_glyph_data( inc->object,
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                          glyph_index, char_string );
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* For ordinary fonts get the character data stored in the face record. */
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      char_string->pointer = type1->charstrings[glyph_index];
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      char_string->length  = (FT_Int)type1->charstrings_len[glyph_index];
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !error )
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = decoder->funcs.parse_charstrings(
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                decoder, (FT_Byte*)char_string->pointer,
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                char_string->length );
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* Incremental fonts can optionally override the metrics. */
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !error && inc && inc->funcs->get_glyph_metrics )
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Incremental_MetricsRec  metrics;
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      metrics.bearing_y = 0;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = inc->funcs->get_glyph_metrics( inc->object,
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                             glyph_index, FALSE, &metrics );
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_CALLBACK_DEF( FT_Error )
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  T1_Parse_Glyph( T1_Decoder  decoder,
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_UInt     glyph_index )
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Data   glyph_data;
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = T1_Parse_Glyph_And_Get_Char_String(
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        decoder, glyph_index, &glyph_data );
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !error )
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      T1_Face  face = (T1_Face)decoder->builder.face;
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( face->root.internal->incremental_interface )
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        face->root.internal->incremental_interface->funcs->free_glyph_data(
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          face->root.internal->incremental_interface->object,
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          &glyph_data );
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Error )
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  T1_Compute_Max_Advance( T1_Face  face,
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          FT_Pos*  max_advance )
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error       error;
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_DecoderRec  decoder;
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Int         glyph_index;
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Font        type1 = &face->type1;
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    PSAux_Service  psaux = (PSAux_Service)face->psaux;
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *max_advance = 0;
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* initialize load decoder */
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = psaux->t1_decoder_funcs->init( &decoder,
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           (FT_Face)face,
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           0, /* size       */
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           0, /* glyph slot */
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           (FT_Byte**)type1->glyph_names,
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           face->blend,
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           0,
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           FT_RENDER_MODE_NORMAL,
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           T1_Parse_Glyph );
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( error )
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.builder.metrics_only = 1;
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.builder.load_points  = 0;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.num_subrs     = type1->num_subrs;
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.subrs         = type1->subrs;
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.subrs_len     = type1->subrs_len;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.buildchar     = face->buildchar;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.len_buildchar = face->len_buildchar;
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *max_advance = 0;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* for each glyph, parse the glyph charstring and extract */
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* the advance width                                      */
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* now get load the unscaled outline */
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = T1_Parse_Glyph( &decoder, glyph_index );
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *max_advance = decoder.builder.advance.x;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* ignore the error if one occurred - skip to next glyph */
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    psaux->t1_decoder_funcs->done( &decoder );
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Error )
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  T1_Get_Advances( FT_Face    t1face,        /* T1_Face */
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_UInt    first,
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_UInt    count,
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_Int32   load_flags,
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_Fixed*  advances )
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Face        face  = (T1_Face)t1face;
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_DecoderRec  decoder;
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Font        type1 = &face->type1;
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    PSAux_Service  psaux = (PSAux_Service)face->psaux;
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt        nn;
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error       error;
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      for ( nn = 0; nn < count; nn++ )
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advances[nn] = 0;
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return FT_Err_Ok;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = psaux->t1_decoder_funcs->init( &decoder,
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           (FT_Face)face,
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           0, /* size       */
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           0, /* glyph slot */
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           (FT_Byte**)type1->glyph_names,
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           face->blend,
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           0,
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           FT_RENDER_MODE_NORMAL,
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                           T1_Parse_Glyph );
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( error )
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.builder.metrics_only = 1;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.builder.load_points  = 0;
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.num_subrs = type1->num_subrs;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.subrs     = type1->subrs;
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.subrs_len = type1->subrs_len;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.buildchar     = face->buildchar;
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.len_buildchar = face->len_buildchar;
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( nn = 0; nn < count; nn++ )
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = T1_Parse_Glyph( &decoder, first + nn );
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( !error )
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      else
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advances[nn] = 0;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_LOCAL_DEF( FT_Error )
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  T1_Load_Glyph( FT_GlyphSlot  t1glyph,          /* T1_GlyphSlot */
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 FT_Size       t1size,           /* T1_Size      */
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 FT_UInt       glyph_index,
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 FT_Int32      load_flags )
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_GlyphSlot            glyph = (T1_GlyphSlot)t1glyph;
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error                error;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_DecoderRec           decoder;
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Face                 face = (T1_Face)t1glyph->face;
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool                 hinting;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T1_Font                 type1         = &face->type1;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Matrix               font_matrix;
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Vector               font_offset;
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Data                 glyph_data;
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool                 must_finish_decoder = FALSE;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool                 glyph_data_loaded = 0;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         !face->root.internal->incremental_interface   )
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_CONFIG_OPTION_INCREMENTAL */
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Invalid_Argument );
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( load_flags & FT_LOAD_NO_RECURSE )
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( t1size )
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      glyph->x_scale = t1size->metrics.x_scale;
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      glyph->y_scale = t1size->metrics.y_scale;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      glyph->x_scale = 0x10000L;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      glyph->y_scale = 0x10000L;
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t1glyph->outline.n_points   = 0;
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t1glyph->outline.n_contours = 0;
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = decoder_funcs->init( &decoder,
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 t1glyph->face,
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 t1size,
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 t1glyph,
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 (FT_Byte**)type1->glyph_names,
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 face->blend,
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FT_BOOL( hinting ),
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FT_LOAD_TARGET_MODE( load_flags ),
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 T1_Parse_Glyph );
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( error )
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    must_finish_decoder = TRUE;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.builder.no_recurse = FT_BOOL(
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.num_subrs     = type1->num_subrs;
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.subrs         = type1->subrs;
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.subrs_len     = type1->subrs_len;
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.buildchar     = face->buildchar;
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder.len_buildchar = face->len_buildchar;
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* now load the unscaled outline */
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                &glyph_data );
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( error )
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    glyph_data_loaded = 1;
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    font_matrix = decoder.font_matrix;
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    font_offset = decoder.font_offset;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* save new glyph tables */
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    decoder_funcs->done( &decoder );
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    must_finish_decoder = FALSE;
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* now, set the metrics -- this is rather simple, as   */
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* the left side bearing is the xMin, and the top side */
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* bearing the yMax                                    */
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !error )
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      t1glyph->outline.flags &= FT_OUTLINE_OWNER;
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* for composite glyphs, return only left side bearing and */
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* advance width                                           */
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( load_flags & FT_LOAD_NO_RECURSE )
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Slot_Internal  internal = t1glyph->internal;
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t1glyph->metrics.horiBearingX =
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FIXED_TO_INT( decoder.builder.left_bearing.x );
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t1glyph->metrics.horiAdvance  =
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FIXED_TO_INT( decoder.builder.advance.x );
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        internal->glyph_matrix      = font_matrix;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        internal->glyph_delta       = font_offset;
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        internal->glyph_transformed = 1;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      else
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_BBox            cbox;
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Glyph_Metrics*  metrics = &t1glyph->metrics;
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Vector          advance;
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        /* copy the _unscaled_ advance width */
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->horiAdvance =
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FIXED_TO_INT( decoder.builder.advance.x );
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t1glyph->linearHoriAdvance =
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FIXED_TO_INT( decoder.builder.advance.x );
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t1glyph->internal->glyph_transformed = 0;
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          /* make up vertical ones */
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          metrics->vertAdvance = ( face->type1.font_bbox.yMax -
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   face->type1.font_bbox.yMin ) >> 16;
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          t1glyph->linearVertAdvance = metrics->vertAdvance;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          metrics->vertAdvance =
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FIXED_TO_INT( decoder.builder.advance.y );
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          t1glyph->linearVertAdvance =
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FIXED_TO_INT( decoder.builder.advance.y );
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( t1size && t1size->metrics.y_ppem < 24 )
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 1
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        /* apply the font matrix, if any */
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx ||
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             font_matrix.xy != 0        || font_matrix.yx != 0              )
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Outline_Transform( &t1glyph->outline, &font_matrix );
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( font_offset.x || font_offset.y )
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Outline_Translate( &t1glyph->outline,
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                font_offset.x,
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                font_offset.y );
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advance.x = metrics->horiAdvance;
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advance.y = 0;
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Vector_Transform( &advance, &font_matrix );
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->horiAdvance = advance.x + font_offset.x;
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advance.x = 0;
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        advance.y = metrics->vertAdvance;
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Vector_Transform( &advance, &font_matrix );
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->vertAdvance = advance.y + font_offset.y;
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          /* scale the outline and the metrics */
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Int       n;
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Outline*  cur = decoder.builder.base;
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Vector*   vec = cur->points;
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Fixed     x_scale = glyph->x_scale;
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_Fixed     y_scale = glyph->y_scale;
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          /* First of all, scale the points, if we are not hinting */
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          if ( !hinting || ! decoder.builder.hints_funcs )
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for ( n = cur->n_points; n > 0; n--, vec++ )
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            {
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              vec->x = FT_MulFix( vec->x, x_scale );
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              vec->y = FT_MulFix( vec->y, y_scale );
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          /* Then scale the metrics */
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        /* compute the other metrics */
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FT_Outline_Get_CBox( &t1glyph->outline, &cbox );
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->width  = cbox.xMax - cbox.xMin;
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->height = cbox.yMax - cbox.yMin;
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->horiBearingX = cbox.xMin;
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        metrics->horiBearingY = cbox.yMax;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          /* make up vertical ones */
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          ft_synthesize_vertical_metrics( metrics,
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                          metrics->vertAdvance );
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* Set control data to the glyph charstrings.  Note that this is */
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* _not_ zero-terminated.                                        */
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      t1glyph->control_data = (FT_Byte*)glyph_data.pointer;
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      t1glyph->control_len  = glyph_data.length;
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Exit:
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_INCREMENTAL
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( glyph_data_loaded && face->root.internal->incremental_interface )
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      face->root.internal->incremental_interface->funcs->free_glyph_data(
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        face->root.internal->incremental_interface->object,
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &glyph_data );
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* Set the control data to null - it is no longer available if   */
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* loaded incrementally.                                         */
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      t1glyph->control_data = 0;
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      t1glyph->control_len  = 0;
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( must_finish_decoder )
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      decoder_funcs->done( &decoder );
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */
518