Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/freetype/src/type1/t1gload.c
Line
Count
Source (jump to first uncovered line)
1
/****************************************************************************
2
 *
3
 * t1gload.c
4
 *
5
 *   Type 1 Glyph Loader (body).
6
 *
7
 * Copyright (C) 1996-2021 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 "t1gload.h"
20
#include <freetype/internal/ftcalc.h>
21
#include <freetype/internal/ftdebug.h>
22
#include <freetype/internal/ftstream.h>
23
#include <freetype/ftoutln.h>
24
#include <freetype/internal/psaux.h>
25
#include <freetype/internal/cfftypes.h>
26
#include <freetype/ftdriver.h>
27
28
#include "t1errors.h"
29
30
31
  /**************************************************************************
32
   *
33
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
34
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35
   * messages during execution.
36
   */
37
#undef  FT_COMPONENT
38
#define FT_COMPONENT  t1gload
39
40
41
  static FT_Error
42
  T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder,
43
                                      FT_UInt     glyph_index,
44
                                      FT_Data*    char_string,
45
                                      FT_Bool*    force_scaling )
46
0
  {
47
0
    T1_Face   face  = (T1_Face)decoder->builder.face;
48
0
    T1_Font   type1 = &face->type1;
49
0
    FT_Error  error = FT_Err_Ok;
50
51
0
    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
52
0
    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
53
0
    PS_Decoder              psdecoder;
54
55
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
56
0
    FT_Incremental_InterfaceRec *inc =
57
0
                      face->root.internal->incremental_interface;
58
0
#endif
59
60
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
61
    PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
62
#endif
63
64
65
0
    decoder->font_matrix = type1->font_matrix;
66
0
    decoder->font_offset = type1->font_offset;
67
68
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
69
70
    /* For incremental fonts get the character data using the */
71
    /* callback function.                                     */
72
0
    if ( inc )
73
0
      error = inc->funcs->get_glyph_data( inc->object,
74
0
                                          glyph_index, char_string );
75
0
    else
76
77
0
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
78
79
    /* For ordinary fonts get the character data stored in the face record. */
80
0
    {
81
0
      char_string->pointer = type1->charstrings[glyph_index];
82
0
      char_string->length  = (FT_Int)type1->charstrings_len[glyph_index];
83
0
    }
84
85
0
    if ( !error )
86
0
    {
87
      /* choose which renderer to use */
88
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
89
      if ( driver->hinting_engine == FT_HINTING_FREETYPE ||
90
           decoder->builder.metrics_only                 )
91
        error = decoder_funcs->parse_charstrings_old(
92
                  decoder,
93
                  (FT_Byte*)char_string->pointer,
94
                  (FT_UInt)char_string->length );
95
#else
96
0
      if ( decoder->builder.metrics_only )
97
0
        error = decoder_funcs->parse_metrics(
98
0
                  decoder,
99
0
                  (FT_Byte*)char_string->pointer,
100
0
                  (FT_UInt)char_string->length );
101
0
#endif
102
0
      else
103
0
      {
104
0
        CFF_SubFontRec  subfont;
105
106
107
0
        psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
108
109
0
        psaux->t1_make_subfont( FT_FACE( face ),
110
0
                                &face->type1.private_dict, &subfont );
111
0
        psdecoder.current_subfont = &subfont;
112
113
0
        error = decoder_funcs->parse_charstrings(
114
0
                  &psdecoder,
115
0
                  (FT_Byte*)char_string->pointer,
116
0
                  (FT_ULong)char_string->length );
117
118
        /* Adobe's engine uses 16.16 numbers everywhere;              */
119
        /* as a consequence, glyphs larger than 2000ppem get rejected */
120
0
        if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
121
0
        {
122
          /* this time, we retry unhinted and scale up the glyph later on */
123
          /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
124
          /* 0x400 for both `x_scale' and `y_scale' in this case)         */
125
0
          ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
126
127
0
          *force_scaling = TRUE;
128
129
0
          error = decoder_funcs->parse_charstrings(
130
0
                    &psdecoder,
131
0
                    (FT_Byte*)char_string->pointer,
132
0
                    (FT_ULong)char_string->length );
133
0
        }
134
0
      }
135
0
    }
136
137
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
138
139
    /* Incremental fonts can optionally override the metrics. */
140
0
    if ( !error && inc && inc->funcs->get_glyph_metrics )
141
0
    {
142
0
      FT_Incremental_MetricsRec  metrics;
143
144
145
0
      metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
146
0
      metrics.bearing_y = 0;
147
0
      metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
148
0
      metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
149
150
0
      error = inc->funcs->get_glyph_metrics( inc->object,
151
0
                                             glyph_index, FALSE, &metrics );
152
153
0
      decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
154
0
      decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
155
0
      decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
156
0
    }
157
158
0
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
159
160
0
    return error;
161
0
  }
162
163
164
  FT_CALLBACK_DEF( FT_Error )
165
  T1_Parse_Glyph( T1_Decoder  decoder,
166
                  FT_UInt     glyph_index )
167
0
  {
168
0
    FT_Data   glyph_data;
169
0
    FT_Bool   force_scaling = FALSE;
170
0
    FT_Error  error         = T1_Parse_Glyph_And_Get_Char_String(
171
0
                                decoder, glyph_index, &glyph_data,
172
0
                                &force_scaling );
173
174
175
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
176
177
0
    if ( !error )
178
0
    {
179
0
      T1_Face  face = (T1_Face)decoder->builder.face;
180
181
182
0
      if ( face->root.internal->incremental_interface )
183
0
        face->root.internal->incremental_interface->funcs->free_glyph_data(
184
0
          face->root.internal->incremental_interface->object,
185
0
          &glyph_data );
186
0
    }
187
188
0
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
189
190
0
    return error;
191
0
  }
192
193
194
  /*************************************************************************/
195
  /*************************************************************************/
196
  /*************************************************************************/
197
  /**********                                                      *********/
198
  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
199
  /**********                                                      *********/
200
  /**********    The following code is in charge of computing      *********/
201
  /**********    the maximum advance width of the font.  It        *********/
202
  /**********    quickly processes each glyph charstring to        *********/
203
  /**********    extract the value from either a `sbw' or `seac'   *********/
204
  /**********    operator.                                         *********/
205
  /**********                                                      *********/
206
  /*************************************************************************/
207
  /*************************************************************************/
208
  /*************************************************************************/
209
210
211
  FT_LOCAL_DEF( FT_Error )
212
  T1_Compute_Max_Advance( T1_Face  face,
213
                          FT_Pos*  max_advance )
214
0
  {
215
0
    FT_Error       error;
216
0
    T1_DecoderRec  decoder;
217
0
    FT_Int         glyph_index;
218
0
    T1_Font        type1 = &face->type1;
219
0
    PSAux_Service  psaux = (PSAux_Service)face->psaux;
220
221
222
0
    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
223
224
0
    *max_advance = 0;
225
226
    /* initialize load decoder */
227
0
    error = psaux->t1_decoder_funcs->init( &decoder,
228
0
                                           (FT_Face)face,
229
0
                                           0, /* size       */
230
0
                                           0, /* glyph slot */
231
0
                                           (FT_Byte**)type1->glyph_names,
232
0
                                           face->blend,
233
0
                                           0,
234
0
                                           FT_RENDER_MODE_NORMAL,
235
0
                                           T1_Parse_Glyph );
236
0
    if ( error )
237
0
      return error;
238
239
0
    decoder.builder.metrics_only = 1;
240
0
    decoder.builder.load_points  = 0;
241
242
0
    decoder.num_subrs     = type1->num_subrs;
243
0
    decoder.subrs         = type1->subrs;
244
0
    decoder.subrs_len     = type1->subrs_len;
245
0
    decoder.subrs_hash    = type1->subrs_hash;
246
247
0
    decoder.buildchar     = face->buildchar;
248
0
    decoder.len_buildchar = face->len_buildchar;
249
250
0
    *max_advance = 0;
251
252
0
    FT_TRACE6(( "T1_Compute_Max_Advance:\n" ));
253
254
    /* for each glyph, parse the glyph charstring and extract */
255
    /* the advance width                                      */
256
0
    for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
257
0
    {
258
      /* now get load the unscaled outline */
259
0
      (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index );
260
0
      if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
261
0
        *max_advance = decoder.builder.advance.x;
262
263
      /* ignore the error if one occurred - skip to next glyph */
264
0
    }
265
266
0
    FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n",
267
0
                *max_advance / 65536.0 ));
268
269
0
    psaux->t1_decoder_funcs->done( &decoder );
270
271
0
    return FT_Err_Ok;
272
0
  }
273
274
275
  FT_LOCAL_DEF( FT_Error )
276
  T1_Get_Advances( FT_Face    t1face,        /* T1_Face */
277
                   FT_UInt    first,
278
                   FT_UInt    count,
279
                   FT_Int32   load_flags,
280
                   FT_Fixed*  advances )
281
0
  {
282
0
    T1_Face        face  = (T1_Face)t1face;
283
0
    T1_DecoderRec  decoder;
284
0
    T1_Font        type1 = &face->type1;
285
0
    PSAux_Service  psaux = (PSAux_Service)face->psaux;
286
0
    FT_UInt        nn;
287
0
    FT_Error       error;
288
289
290
0
    FT_TRACE5(( "T1_Get_Advances:\n" ));
291
292
0
    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
293
0
    {
294
0
      for ( nn = 0; nn < count; nn++ )
295
0
      {
296
0
        advances[nn] = 0;
297
298
0
        FT_TRACE5(( "  idx %d: advance height 0 font units\n",
299
0
                    first + nn ));
300
0
      }
301
302
0
      return FT_Err_Ok;
303
0
    }
304
305
0
    error = psaux->t1_decoder_funcs->init( &decoder,
306
0
                                           (FT_Face)face,
307
0
                                           0, /* size       */
308
0
                                           0, /* glyph slot */
309
0
                                           (FT_Byte**)type1->glyph_names,
310
0
                                           face->blend,
311
0
                                           0,
312
0
                                           FT_RENDER_MODE_NORMAL,
313
0
                                           T1_Parse_Glyph );
314
0
    if ( error )
315
0
      return error;
316
317
0
    decoder.builder.metrics_only = 1;
318
0
    decoder.builder.load_points  = 0;
319
320
0
    decoder.num_subrs  = type1->num_subrs;
321
0
    decoder.subrs      = type1->subrs;
322
0
    decoder.subrs_len  = type1->subrs_len;
323
0
    decoder.subrs_hash = type1->subrs_hash;
324
325
0
    decoder.buildchar     = face->buildchar;
326
0
    decoder.len_buildchar = face->len_buildchar;
327
328
0
    for ( nn = 0; nn < count; nn++ )
329
0
    {
330
0
      error = T1_Parse_Glyph( &decoder, first + nn );
331
0
      if ( !error )
332
0
        advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
333
0
      else
334
0
        advances[nn] = 0;
335
336
0
      FT_TRACE5(( "  idx %d: advance width %ld font unit%s\n",
337
0
                  first + nn,
338
0
                  advances[nn],
339
0
                  advances[nn] == 1 ? "" : "s" ));
340
0
    }
341
342
0
    return FT_Err_Ok;
343
0
  }
344
345
346
  FT_LOCAL_DEF( FT_Error )
347
  T1_Load_Glyph( FT_GlyphSlot  t1glyph,          /* T1_GlyphSlot */
348
                 FT_Size       t1size,           /* T1_Size      */
349
                 FT_UInt       glyph_index,
350
                 FT_Int32      load_flags )
351
0
  {
352
0
    T1_GlyphSlot            glyph = (T1_GlyphSlot)t1glyph;
353
0
    FT_Error                error;
354
0
    T1_DecoderRec           decoder;
355
0
    T1_Face                 face = (T1_Face)t1glyph->face;
356
0
    FT_Bool                 hinting;
357
0
    FT_Bool                 scaled;
358
0
    FT_Bool                 force_scaling = FALSE;
359
0
    T1_Font                 type1         = &face->type1;
360
0
    PSAux_Service           psaux         = (PSAux_Service)face->psaux;
361
0
    const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
362
363
0
    FT_Matrix               font_matrix;
364
0
    FT_Vector               font_offset;
365
0
    FT_Data                 glyph_data;
366
0
    FT_Bool                 must_finish_decoder = FALSE;
367
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
368
0
    FT_Bool                 glyph_data_loaded = 0;
369
0
#endif
370
371
372
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
373
0
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
374
0
         !face->root.internal->incremental_interface   )
375
#else
376
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
377
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
378
0
    {
379
0
      error = FT_THROW( Invalid_Argument );
380
0
      goto Exit;
381
0
    }
382
383
0
    FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index ));
384
385
0
    FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
386
387
0
    if ( load_flags & FT_LOAD_NO_RECURSE )
388
0
      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
389
390
0
    if ( t1size )
391
0
    {
392
0
      glyph->x_scale = t1size->metrics.x_scale;
393
0
      glyph->y_scale = t1size->metrics.y_scale;
394
0
    }
395
0
    else
396
0
    {
397
0
      glyph->x_scale = 0x10000L;
398
0
      glyph->y_scale = 0x10000L;
399
0
    }
400
401
0
    t1glyph->outline.n_points   = 0;
402
0
    t1glyph->outline.n_contours = 0;
403
404
0
    hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) &&
405
0
                       !( load_flags & FT_LOAD_NO_HINTING ) );
406
0
    scaled  = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) );
407
408
0
    glyph->hint     = hinting;
409
0
    glyph->scaled   = scaled;
410
0
    t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
411
412
0
    error = decoder_funcs->init( &decoder,
413
0
                                 t1glyph->face,
414
0
                                 t1size,
415
0
                                 t1glyph,
416
0
                                 (FT_Byte**)type1->glyph_names,
417
0
                                 face->blend,
418
0
                                 hinting,
419
0
                                 FT_LOAD_TARGET_MODE( load_flags ),
420
0
                                 T1_Parse_Glyph );
421
0
    if ( error )
422
0
      goto Exit;
423
424
0
    must_finish_decoder = TRUE;
425
426
0
    decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
427
428
0
    decoder.num_subrs     = type1->num_subrs;
429
0
    decoder.subrs         = type1->subrs;
430
0
    decoder.subrs_len     = type1->subrs_len;
431
0
    decoder.subrs_hash    = type1->subrs_hash;
432
433
0
    decoder.buildchar     = face->buildchar;
434
0
    decoder.len_buildchar = face->len_buildchar;
435
436
    /* now load the unscaled outline */
437
0
    error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
438
0
                                                &glyph_data,
439
0
                                                &force_scaling );
440
0
    if ( error )
441
0
      goto Exit;
442
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
443
0
    glyph_data_loaded = 1;
444
0
#endif
445
446
0
    hinting     = glyph->hint;
447
0
    font_matrix = decoder.font_matrix;
448
0
    font_offset = decoder.font_offset;
449
450
    /* save new glyph tables */
451
0
    decoder_funcs->done( &decoder );
452
453
0
    must_finish_decoder = FALSE;
454
455
    /* now, set the metrics -- this is rather simple, as   */
456
    /* the left side bearing is the xMin, and the top side */
457
    /* bearing the yMax                                    */
458
0
    if ( !error )
459
0
    {
460
0
      t1glyph->outline.flags &= FT_OUTLINE_OWNER;
461
0
      t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
462
463
      /* for composite glyphs, return only left side bearing and */
464
      /* advance width                                           */
465
0
      if ( load_flags & FT_LOAD_NO_RECURSE )
466
0
      {
467
0
        FT_Slot_Internal  internal = t1glyph->internal;
468
469
470
0
        t1glyph->metrics.horiBearingX =
471
0
          FIXED_TO_INT( decoder.builder.left_bearing.x );
472
0
        t1glyph->metrics.horiAdvance  =
473
0
          FIXED_TO_INT( decoder.builder.advance.x );
474
475
0
        internal->glyph_matrix      = font_matrix;
476
0
        internal->glyph_delta       = font_offset;
477
0
        internal->glyph_transformed = 1;
478
0
      }
479
0
      else
480
0
      {
481
0
        FT_BBox            cbox;
482
0
        FT_Glyph_Metrics*  metrics = &t1glyph->metrics;
483
484
485
        /* copy the _unscaled_ advance width */
486
0
        metrics->horiAdvance =
487
0
          FIXED_TO_INT( decoder.builder.advance.x );
488
0
        t1glyph->linearHoriAdvance =
489
0
          FIXED_TO_INT( decoder.builder.advance.x );
490
0
        t1glyph->internal->glyph_transformed = 0;
491
492
0
        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
493
0
        {
494
          /* make up vertical ones */
495
0
          metrics->vertAdvance = ( face->type1.font_bbox.yMax -
496
0
                                   face->type1.font_bbox.yMin ) >> 16;
497
0
          t1glyph->linearVertAdvance = metrics->vertAdvance;
498
0
        }
499
0
        else
500
0
        {
501
0
          metrics->vertAdvance =
502
0
            FIXED_TO_INT( decoder.builder.advance.y );
503
0
          t1glyph->linearVertAdvance =
504
0
            FIXED_TO_INT( decoder.builder.advance.y );
505
0
        }
506
507
0
        t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
508
509
0
        if ( t1size && t1size->metrics.y_ppem < 24 )
510
0
          t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
511
512
0
#if 1
513
        /* apply the font matrix, if any */
514
0
        if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
515
0
             font_matrix.xy != 0        || font_matrix.yx != 0        )
516
0
        {
517
0
          FT_Outline_Transform( &t1glyph->outline, &font_matrix );
518
519
0
          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
520
0
                                            font_matrix.xx );
521
0
          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
522
0
                                            font_matrix.yy );
523
0
        }
524
525
0
        if ( font_offset.x || font_offset.y )
526
0
        {
527
0
          FT_Outline_Translate( &t1glyph->outline,
528
0
                                font_offset.x,
529
0
                                font_offset.y );
530
531
0
          metrics->horiAdvance += font_offset.x;
532
0
          metrics->vertAdvance += font_offset.y;
533
0
        }
534
0
#endif
535
536
0
        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
537
0
        {
538
          /* scale the outline and the metrics */
539
0
          FT_Int       n;
540
0
          FT_Outline*  cur = decoder.builder.base;
541
0
          FT_Vector*   vec = cur->points;
542
0
          FT_Fixed     x_scale = glyph->x_scale;
543
0
          FT_Fixed     y_scale = glyph->y_scale;
544
545
546
          /* First of all, scale the points, if we are not hinting */
547
0
          if ( !hinting || !decoder.builder.hints_funcs )
548
0
            for ( n = cur->n_points; n > 0; n--, vec++ )
549
0
            {
550
0
              vec->x = FT_MulFix( vec->x, x_scale );
551
0
              vec->y = FT_MulFix( vec->y, y_scale );
552
0
            }
553
554
          /* Then scale the metrics */
555
0
          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
556
0
          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
557
0
        }
558
559
        /* compute the other metrics */
560
0
        FT_Outline_Get_CBox( &t1glyph->outline, &cbox );
561
562
0
        metrics->width  = cbox.xMax - cbox.xMin;
563
0
        metrics->height = cbox.yMax - cbox.yMin;
564
565
0
        metrics->horiBearingX = cbox.xMin;
566
0
        metrics->horiBearingY = cbox.yMax;
567
568
0
        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
569
0
        {
570
          /* make up vertical ones */
571
0
          ft_synthesize_vertical_metrics( metrics,
572
0
                                          metrics->vertAdvance );
573
0
        }
574
0
      }
575
576
      /* Set control data to the glyph charstrings.  Note that this is */
577
      /* _not_ zero-terminated.                                        */
578
0
      t1glyph->control_data = (FT_Byte*)glyph_data.pointer;
579
0
      t1glyph->control_len  = glyph_data.length;
580
0
    }
581
582
583
0
  Exit:
584
585
0
#ifdef FT_CONFIG_OPTION_INCREMENTAL
586
0
    if ( glyph_data_loaded && face->root.internal->incremental_interface )
587
0
    {
588
0
      face->root.internal->incremental_interface->funcs->free_glyph_data(
589
0
        face->root.internal->incremental_interface->object,
590
0
        &glyph_data );
591
592
      /* Set the control data to null - it is no longer available if   */
593
      /* loaded incrementally.                                         */
594
0
      t1glyph->control_data = NULL;
595
0
      t1glyph->control_len  = 0;
596
0
    }
597
0
#endif
598
599
0
    if ( must_finish_decoder )
600
0
      decoder_funcs->done( &decoder );
601
602
0
    return error;
603
0
  }
604
605
606
/* END */