~reviczky/luatex/texlive-bin-git

« back to all changes in this revision

Viewing changes to libs/freetype2/freetype-2.5.3/src/autofit/afloader.c

  • Committer: Adam Reviczky
  • Date: 2015-04-26 22:40:47 UTC
  • Revision ID: adam.reviczky@kclalumni.net-20150426224047-i2p26n3wqphupq6z
TeX Live 2015 import (rev. 37052)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************/
2
 
/*                                                                         */
3
 
/*  afloader.c                                                             */
4
 
/*                                                                         */
5
 
/*    Auto-fitter glyph loading routines (body).                           */
6
 
/*                                                                         */
7
 
/*  Copyright 2003-2009, 2011-2014 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 "afglobal.h"
20
 
#include "afloader.h"
21
 
#include "afhints.h"
22
 
#include "aferrors.h"
23
 
#include "afmodule.h"
24
 
#include "afpic.h"
25
 
 
26
 
 
27
 
  /* Initialize glyph loader. */
28
 
 
29
 
  FT_LOCAL_DEF( FT_Error )
30
 
  af_loader_init( AF_Module  module )
31
 
  {
32
 
    AF_Loader  loader = module->loader;
33
 
    FT_Memory  memory = module->root.library->memory;
34
 
 
35
 
 
36
 
    FT_ZERO( loader );
37
 
 
38
 
    af_glyph_hints_init( &loader->hints, memory );
39
 
#ifdef FT_DEBUG_AUTOFIT
40
 
    _af_debug_hints = &loader->hints;
41
 
#endif
42
 
    return FT_GlyphLoader_New( memory, &loader->gloader );
43
 
  }
44
 
 
45
 
 
46
 
  /* Reset glyph loader and compute globals if necessary. */
47
 
 
48
 
  FT_LOCAL_DEF( FT_Error )
49
 
  af_loader_reset( AF_Module  module,
50
 
                   FT_Face    face )
51
 
  {
52
 
    FT_Error   error  = FT_Err_Ok;
53
 
    AF_Loader  loader = module->loader;
54
 
 
55
 
 
56
 
    loader->face    = face;
57
 
    loader->globals = (AF_FaceGlobals)face->autohint.data;
58
 
 
59
 
    FT_GlyphLoader_Rewind( loader->gloader );
60
 
 
61
 
    if ( loader->globals == NULL )
62
 
    {
63
 
      error = af_face_globals_new( face, &loader->globals, module );
64
 
      if ( !error )
65
 
      {
66
 
        face->autohint.data =
67
 
          (FT_Pointer)loader->globals;
68
 
        face->autohint.finalizer =
69
 
          (FT_Generic_Finalizer)af_face_globals_free;
70
 
      }
71
 
    }
72
 
 
73
 
    return error;
74
 
  }
75
 
 
76
 
 
77
 
  /* Finalize glyph loader. */
78
 
 
79
 
  FT_LOCAL_DEF( void )
80
 
  af_loader_done( AF_Module  module )
81
 
  {
82
 
    AF_Loader  loader = module->loader;
83
 
 
84
 
 
85
 
    af_glyph_hints_done( &loader->hints );
86
 
 
87
 
    loader->face    = NULL;
88
 
    loader->globals = NULL;
89
 
 
90
 
#ifdef FT_DEBUG_AUTOFIT
91
 
    _af_debug_hints = NULL;
92
 
#endif
93
 
    FT_GlyphLoader_Done( loader->gloader );
94
 
    loader->gloader = NULL;
95
 
  }
96
 
 
97
 
 
98
 
  /* Load a single glyph component.  This routine calls itself */
99
 
  /* recursively, if necessary, and does the main work of      */
100
 
  /* `af_loader_load_glyph.'                                   */
101
 
 
102
 
  static FT_Error
103
 
  af_loader_load_g( AF_Loader  loader,
104
 
                    AF_Scaler  scaler,
105
 
                    FT_UInt    glyph_index,
106
 
                    FT_Int32   load_flags,
107
 
                    FT_UInt    depth )
108
 
  {
109
 
    FT_Error          error;
110
 
    FT_Face           face     = loader->face;
111
 
    FT_GlyphLoader    gloader  = loader->gloader;
112
 
    AF_StyleMetrics   metrics  = loader->metrics;
113
 
    AF_GlyphHints     hints    = &loader->hints;
114
 
    FT_GlyphSlot      slot     = face->glyph;
115
 
    FT_Slot_Internal  internal = slot->internal;
116
 
    FT_Int32          flags;
117
 
 
118
 
 
119
 
    flags = load_flags | FT_LOAD_LINEAR_DESIGN;
120
 
    error = FT_Load_Glyph( face, glyph_index, flags );
121
 
    if ( error )
122
 
      goto Exit;
123
 
 
124
 
    loader->transformed = internal->glyph_transformed;
125
 
    if ( loader->transformed )
126
 
    {
127
 
      FT_Matrix  inverse;
128
 
 
129
 
 
130
 
      loader->trans_matrix = internal->glyph_matrix;
131
 
      loader->trans_delta  = internal->glyph_delta;
132
 
 
133
 
      inverse = loader->trans_matrix;
134
 
      FT_Matrix_Invert( &inverse );
135
 
      FT_Vector_Transform( &loader->trans_delta, &inverse );
136
 
    }
137
 
 
138
 
    switch ( slot->format )
139
 
    {
140
 
    case FT_GLYPH_FORMAT_OUTLINE:
141
 
      /* translate the loaded glyph when an internal transform is needed */
142
 
      if ( loader->transformed )
143
 
        FT_Outline_Translate( &slot->outline,
144
 
                              loader->trans_delta.x,
145
 
                              loader->trans_delta.y );
146
 
 
147
 
      /* copy the outline points in the loader's current                */
148
 
      /* extra points which are used to keep original glyph coordinates */
149
 
      error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
150
 
                                           slot->outline.n_points + 4,
151
 
                                           slot->outline.n_contours );
152
 
      if ( error )
153
 
        goto Exit;
154
 
 
155
 
      FT_ARRAY_COPY( gloader->current.outline.points,
156
 
                     slot->outline.points,
157
 
                     slot->outline.n_points );
158
 
 
159
 
      FT_ARRAY_COPY( gloader->current.outline.contours,
160
 
                     slot->outline.contours,
161
 
                     slot->outline.n_contours );
162
 
 
163
 
      FT_ARRAY_COPY( gloader->current.outline.tags,
164
 
                     slot->outline.tags,
165
 
                     slot->outline.n_points );
166
 
 
167
 
      gloader->current.outline.n_points   = slot->outline.n_points;
168
 
      gloader->current.outline.n_contours = slot->outline.n_contours;
169
 
 
170
 
      /* compute original horizontal phantom points (and ignore */
171
 
      /* vertical ones)                                         */
172
 
      loader->pp1.x = hints->x_delta;
173
 
      loader->pp1.y = hints->y_delta;
174
 
      loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
175
 
                                 hints->x_scale ) + hints->x_delta;
176
 
      loader->pp2.y = hints->y_delta;
177
 
 
178
 
      /* be sure to check for spacing glyphs */
179
 
      if ( slot->outline.n_points == 0 )
180
 
        goto Hint_Metrics;
181
 
 
182
 
      /* now load the slot image into the auto-outline and run the */
183
 
      /* automatic hinting process                                 */
184
 
      {
185
 
#ifdef FT_CONFIG_OPTION_PIC
186
 
        AF_FaceGlobals         globals = loader->globals;
187
 
#endif
188
 
        AF_StyleClass          style_class = metrics->style_class;
189
 
        AF_WritingSystemClass  writing_system_class =
190
 
          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
191
 
 
192
 
 
193
 
        if ( writing_system_class->style_hints_apply )
194
 
          writing_system_class->style_hints_apply( hints,
195
 
                                                   &gloader->current.outline,
196
 
                                                   metrics );
197
 
      }
198
 
 
199
 
      /* we now need to adjust the metrics according to the change in */
200
 
      /* width/positioning that occurred during the hinting process   */
201
 
      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
202
 
      {
203
 
        FT_Pos        old_rsb, old_lsb, new_lsb;
204
 
        FT_Pos        pp1x_uh, pp2x_uh;
205
 
        AF_AxisHints  axis  = &hints->axis[AF_DIMENSION_HORZ];
206
 
        AF_Edge       edge1 = axis->edges;         /* leftmost edge  */
207
 
        AF_Edge       edge2 = edge1 +
208
 
                              axis->num_edges - 1; /* rightmost edge */
209
 
 
210
 
 
211
 
        if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
212
 
        {
213
 
          old_rsb = loader->pp2.x - edge2->opos;
214
 
          old_lsb = edge1->opos;
215
 
          new_lsb = edge1->pos;
216
 
 
217
 
          /* remember unhinted values to later account */
218
 
          /* for rounding errors                       */
219
 
 
220
 
          pp1x_uh = new_lsb    - old_lsb;
221
 
          pp2x_uh = edge2->pos + old_rsb;
222
 
 
223
 
          /* prefer too much space over too little space */
224
 
          /* for very small sizes                        */
225
 
 
226
 
          if ( old_lsb < 24 )
227
 
            pp1x_uh -= 8;
228
 
 
229
 
          if ( old_rsb < 24 )
230
 
            pp2x_uh += 8;
231
 
 
232
 
          loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
233
 
          loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
234
 
 
235
 
          if ( loader->pp1.x >= new_lsb && old_lsb > 0 )
236
 
            loader->pp1.x -= 64;
237
 
 
238
 
          if ( loader->pp2.x <= edge2->pos && old_rsb > 0 )
239
 
            loader->pp2.x += 64;
240
 
 
241
 
          slot->lsb_delta = loader->pp1.x - pp1x_uh;
242
 
          slot->rsb_delta = loader->pp2.x - pp2x_uh;
243
 
        }
244
 
        else
245
 
        {
246
 
          FT_Pos  pp1x = loader->pp1.x;
247
 
          FT_Pos  pp2x = loader->pp2.x;
248
 
 
249
 
 
250
 
          loader->pp1.x = FT_PIX_ROUND( pp1x );
251
 
          loader->pp2.x = FT_PIX_ROUND( pp2x );
252
 
 
253
 
          slot->lsb_delta = loader->pp1.x - pp1x;
254
 
          slot->rsb_delta = loader->pp2.x - pp2x;
255
 
        }
256
 
      }
257
 
      else
258
 
      {
259
 
        FT_Pos  pp1x = loader->pp1.x;
260
 
        FT_Pos  pp2x = loader->pp2.x;
261
 
 
262
 
 
263
 
        loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
264
 
        loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
265
 
 
266
 
        slot->lsb_delta = loader->pp1.x - pp1x;
267
 
        slot->rsb_delta = loader->pp2.x - pp2x;
268
 
      }
269
 
 
270
 
      /* good, we simply add the glyph to our loader's base */
271
 
      FT_GlyphLoader_Add( gloader );
272
 
      break;
273
 
 
274
 
    case FT_GLYPH_FORMAT_COMPOSITE:
275
 
      {
276
 
        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;
277
 
        FT_UInt      num_base_subgs, start_point;
278
 
        FT_SubGlyph  subglyph;
279
 
 
280
 
 
281
 
        start_point = gloader->base.outline.n_points;
282
 
 
283
 
        /* first of all, copy the subglyph descriptors in the glyph loader */
284
 
        error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
285
 
        if ( error )
286
 
          goto Exit;
287
 
 
288
 
        FT_ARRAY_COPY( gloader->current.subglyphs,
289
 
                       slot->subglyphs,
290
 
                       num_subglyphs );
291
 
 
292
 
        gloader->current.num_subglyphs = num_subglyphs;
293
 
        num_base_subgs                 = gloader->base.num_subglyphs;
294
 
 
295
 
        /* now read each subglyph independently */
296
 
        for ( nn = 0; nn < num_subglyphs; nn++ )
297
 
        {
298
 
          FT_Vector  pp1, pp2;
299
 
          FT_Pos     x, y;
300
 
          FT_UInt    num_points, num_new_points, num_base_points;
301
 
 
302
 
 
303
 
          /* gloader.current.subglyphs can change during glyph loading due */
304
 
          /* to re-allocation -- we must recompute the current subglyph on */
305
 
          /* each iteration                                                */
306
 
          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
307
 
 
308
 
          pp1 = loader->pp1;
309
 
          pp2 = loader->pp2;
310
 
 
311
 
          num_base_points = gloader->base.outline.n_points;
312
 
 
313
 
          error = af_loader_load_g( loader, scaler, subglyph->index,
314
 
                                    load_flags, depth + 1 );
315
 
          if ( error )
316
 
            goto Exit;
317
 
 
318
 
          /* recompute subglyph pointer */
319
 
          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
320
 
 
321
 
          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) )
322
 
          {
323
 
            loader->pp1 = pp1;
324
 
            loader->pp2 = pp2;
325
 
          }
326
 
 
327
 
          num_points     = gloader->base.outline.n_points;
328
 
          num_new_points = num_points - num_base_points;
329
 
 
330
 
          /* now perform the transformation required for this subglyph */
331
 
 
332
 
          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |
333
 
                                   FT_SUBGLYPH_FLAG_XY_SCALE |
334
 
                                   FT_SUBGLYPH_FLAG_2X2      ) )
335
 
          {
336
 
            FT_Vector*  cur   = gloader->base.outline.points +
337
 
                                num_base_points;
338
 
            FT_Vector*  limit = cur + num_new_points;
339
 
 
340
 
 
341
 
            for ( ; cur < limit; cur++ )
342
 
              FT_Vector_Transform( cur, &subglyph->transform );
343
 
          }
344
 
 
345
 
          /* apply offset */
346
 
 
347
 
          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
348
 
          {
349
 
            FT_Int      k = subglyph->arg1;
350
 
            FT_UInt     l = subglyph->arg2;
351
 
            FT_Vector*  p1;
352
 
            FT_Vector*  p2;
353
 
 
354
 
 
355
 
            if ( start_point + k >= num_base_points         ||
356
 
                               l >= (FT_UInt)num_new_points )
357
 
            {
358
 
              error = FT_THROW( Invalid_Composite );
359
 
              goto Exit;
360
 
            }
361
 
 
362
 
            l += num_base_points;
363
 
 
364
 
            /* for now, only use the current point coordinates; */
365
 
            /* we eventually may consider another approach      */
366
 
            p1 = gloader->base.outline.points + start_point + k;
367
 
            p2 = gloader->base.outline.points + start_point + l;
368
 
 
369
 
            x = p1->x - p2->x;
370
 
            y = p1->y - p2->y;
371
 
          }
372
 
          else
373
 
          {
374
 
            x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
375
 
            y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
376
 
 
377
 
            x = FT_PIX_ROUND( x );
378
 
            y = FT_PIX_ROUND( y );
379
 
          }
380
 
 
381
 
          {
382
 
            FT_Outline  dummy = gloader->base.outline;
383
 
 
384
 
 
385
 
            dummy.points  += num_base_points;
386
 
            dummy.n_points = (short)num_new_points;
387
 
 
388
 
            FT_Outline_Translate( &dummy, x, y );
389
 
          }
390
 
        }
391
 
      }
392
 
      break;
393
 
 
394
 
    default:
395
 
      /* we don't support other formats (yet?) */
396
 
      error = FT_THROW( Unimplemented_Feature );
397
 
    }
398
 
 
399
 
  Hint_Metrics:
400
 
    if ( depth == 0 )
401
 
    {
402
 
      FT_BBox    bbox;
403
 
      FT_Vector  vvector;
404
 
 
405
 
 
406
 
      vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;
407
 
      vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;
408
 
      vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale );
409
 
      vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale );
410
 
 
411
 
      /* transform the hinted outline if needed */
412
 
      if ( loader->transformed )
413
 
      {
414
 
        FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
415
 
        FT_Vector_Transform( &vvector, &loader->trans_matrix );
416
 
      }
417
 
#if 1
418
 
      /* we must translate our final outline by -pp1.x and compute */
419
 
      /* the new metrics                                           */
420
 
      if ( loader->pp1.x )
421
 
        FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
422
 
#endif
423
 
      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
424
 
 
425
 
      bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
426
 
      bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
427
 
      bbox.xMax = FT_PIX_CEIL(  bbox.xMax );
428
 
      bbox.yMax = FT_PIX_CEIL(  bbox.yMax );
429
 
 
430
 
      slot->metrics.width        = bbox.xMax - bbox.xMin;
431
 
      slot->metrics.height       = bbox.yMax - bbox.yMin;
432
 
      slot->metrics.horiBearingX = bbox.xMin;
433
 
      slot->metrics.horiBearingY = bbox.yMax;
434
 
 
435
 
      slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x );
436
 
      slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );
437
 
 
438
 
      /* for mono-width fonts (like Andale, Courier, etc.) we need */
439
 
      /* to keep the original rounded advance width; ditto for     */
440
 
      /* digits if all have the same advance width                 */
441
 
#if 0
442
 
      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
443
 
        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
444
 
      else
445
 
        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
446
 
                                               x_scale );
447
 
#else
448
 
      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT                      &&
449
 
           ( FT_IS_FIXED_WIDTH( slot->face )                              ||
450
 
             ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
451
 
               metrics->digits_have_same_width                          ) ) )
452
 
      {
453
 
        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
454
 
                                               metrics->scaler.x_scale );
455
 
 
456
 
        /* Set delta values to 0.  Otherwise code that uses them is */
457
 
        /* going to ruin the fixed advance width.                   */
458
 
        slot->lsb_delta = 0;
459
 
        slot->rsb_delta = 0;
460
 
      }
461
 
      else
462
 
      {
463
 
        /* non-spacing glyphs must stay as-is */
464
 
        if ( slot->metrics.horiAdvance )
465
 
          slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
466
 
      }
467
 
#endif
468
 
 
469
 
      slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
470
 
                                             metrics->scaler.y_scale );
471
 
 
472
 
      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
473
 
      slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
474
 
 
475
 
      /* now copy outline into glyph slot */
476
 
      FT_GlyphLoader_Rewind( internal->loader );
477
 
      error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
478
 
      if ( error )
479
 
        goto Exit;
480
 
 
481
 
      /* reassign all outline fields except flags to protect them */
482
 
      slot->outline.n_contours = internal->loader->base.outline.n_contours;
483
 
      slot->outline.n_points   = internal->loader->base.outline.n_points;
484
 
      slot->outline.points     = internal->loader->base.outline.points;
485
 
      slot->outline.tags       = internal->loader->base.outline.tags;
486
 
      slot->outline.contours   = internal->loader->base.outline.contours;
487
 
 
488
 
      slot->format  = FT_GLYPH_FORMAT_OUTLINE;
489
 
    }
490
 
 
491
 
  Exit:
492
 
    return error;
493
 
  }
494
 
 
495
 
 
496
 
  /* Load a glyph. */
497
 
 
498
 
  FT_LOCAL_DEF( FT_Error )
499
 
  af_loader_load_glyph( AF_Module  module,
500
 
                        FT_Face    face,
501
 
                        FT_UInt    gindex,
502
 
                        FT_Int32   load_flags )
503
 
  {
504
 
    FT_Error      error;
505
 
    FT_Size       size   = face->size;
506
 
    AF_Loader     loader = module->loader;
507
 
    AF_ScalerRec  scaler;
508
 
 
509
 
 
510
 
    if ( !size )
511
 
      return FT_THROW( Invalid_Argument );
512
 
 
513
 
    FT_ZERO( &scaler );
514
 
 
515
 
    scaler.face    = face;
516
 
    scaler.x_scale = size->metrics.x_scale;
517
 
    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
518
 
    scaler.y_scale = size->metrics.y_scale;
519
 
    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
520
 
 
521
 
    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
522
 
    scaler.flags       = 0;  /* XXX: fix this */
523
 
 
524
 
    error = af_loader_reset( module, face );
525
 
    if ( !error )
526
 
    {
527
 
      AF_StyleMetrics  metrics;
528
 
      FT_UInt          options = AF_STYLE_NONE_DFLT;
529
 
 
530
 
 
531
 
#ifdef FT_OPTION_AUTOFIT2
532
 
      /* XXX: undocumented hook to activate the latin2 writing system */
533
 
      if ( load_flags & ( 1UL << 20 ) )
534
 
        options = AF_STYLE_LTN2_DFLT;
535
 
#endif
536
 
 
537
 
      error = af_face_globals_get_metrics( loader->globals, gindex,
538
 
                                           options, &metrics );
539
 
      if ( !error )
540
 
      {
541
 
#ifdef FT_CONFIG_OPTION_PIC
542
 
        AF_FaceGlobals         globals = loader->globals;
543
 
#endif
544
 
        AF_StyleClass          style_class = metrics->style_class;
545
 
        AF_WritingSystemClass  writing_system_class =
546
 
          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
547
 
 
548
 
 
549
 
        loader->metrics = metrics;
550
 
 
551
 
        if ( writing_system_class->style_metrics_scale )
552
 
          writing_system_class->style_metrics_scale( metrics, &scaler );
553
 
        else
554
 
          metrics->scaler = scaler;
555
 
 
556
 
        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
557
 
        load_flags &= ~FT_LOAD_RENDER;
558
 
 
559
 
        if ( writing_system_class->style_hints_init )
560
 
        {
561
 
          error = writing_system_class->style_hints_init( &loader->hints,
562
 
                                                          metrics );
563
 
          if ( error )
564
 
            goto Exit;
565
 
        }
566
 
 
567
 
        error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
568
 
      }
569
 
    }
570
 
  Exit:
571
 
    return error;
572
 
  }
573
 
 
574
 
 
575
 
/* END */