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