Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3918 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  ttobjs.c                                                               */
4
/*                                                                         */
5
/*    Objects manager (body).                                              */
6
/*                                                                         */
7
/*  Copyright 1996-2013                                                    */
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 
20
#include FT_INTERNAL_DEBUG_H
21
#include FT_INTERNAL_STREAM_H
22
#include FT_TRUETYPE_TAGS_H
23
#include FT_INTERNAL_SFNT_H
24
#include FT_TRUETYPE_DRIVER_H
25
 
26
#include "ttgload.h"
27
#include "ttpload.h"
28
 
29
#include "tterrors.h"
30
 
31
#ifdef TT_USE_BYTECODE_INTERPRETER
32
#include "ttinterp.h"
33
#endif
34
 
35
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
36
#include FT_TRUETYPE_UNPATENTED_H
37
#endif
38
 
39
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
40
#include "ttgxvar.h"
41
#endif
42
 
43
  /*************************************************************************/
44
  /*                                                                       */
45
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
46
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
47
  /* messages during execution.                                            */
48
  /*                                                                       */
49
#undef  FT_COMPONENT
50
#define FT_COMPONENT  trace_ttobjs
51
 
52
 
53
#ifdef TT_USE_BYTECODE_INTERPRETER
54
 
55
  /*************************************************************************/
56
  /*                                                                       */
57
  /*                       GLYPH ZONE FUNCTIONS                            */
58
  /*                                                                       */
59
  /*************************************************************************/
60
 
61
 
62
  /*************************************************************************/
63
  /*                                                                       */
64
  /*                                                             */
65
  /*    tt_glyphzone_done                                                  */
66
  /*                                                                       */
67
  /*                                                          */
68
  /*    Deallocate a glyph zone.                                           */
69
  /*                                                                       */
70
  /*                                                                */
71
  /*    zone :: A pointer to the target glyph zone.                        */
72
  /*                                                                       */
73
  FT_LOCAL_DEF( void )
74
  tt_glyphzone_done( TT_GlyphZone  zone )
75
  {
76
    FT_Memory  memory = zone->memory;
77
 
78
 
79
    if ( memory )
80
    {
81
      FT_FREE( zone->contours );
82
      FT_FREE( zone->tags );
83
      FT_FREE( zone->cur );
84
      FT_FREE( zone->org );
85
      FT_FREE( zone->orus );
86
 
87
      zone->max_points   = zone->n_points   = 0;
88
      zone->max_contours = zone->n_contours = 0;
89
      zone->memory       = NULL;
90
    }
91
  }
92
 
93
 
94
  /*************************************************************************/
95
  /*                                                                       */
96
  /*                                                             */
97
  /*    tt_glyphzone_new                                                   */
98
  /*                                                                       */
99
  /*                                                          */
100
  /*    Allocate a new glyph zone.                                         */
101
  /*                                                                       */
102
  /*                                                                */
103
  /*    memory      :: A handle to the current memory object.              */
104
  /*                                                                       */
105
  /*    maxPoints   :: The capacity of glyph zone in points.               */
106
  /*                                                                       */
107
  /*    maxContours :: The capacity of glyph zone in contours.             */
108
  /*                                                                       */
109
  /*                                                               */
110
  /*    zone        :: A pointer to the target glyph zone record.          */
111
  /*                                                                       */
112
  /*                                                               */
113
  /*    FreeType error code.  0 means success.                             */
114
  /*                                                                       */
115
  FT_LOCAL_DEF( FT_Error )
116
  tt_glyphzone_new( FT_Memory     memory,
117
                    FT_UShort     maxPoints,
118
                    FT_Short      maxContours,
119
                    TT_GlyphZone  zone )
120
  {
121
    FT_Error  error;
122
 
123
 
124
    FT_MEM_ZERO( zone, sizeof ( *zone ) );
125
    zone->memory = memory;
126
 
127
    if ( FT_NEW_ARRAY( zone->org,      maxPoints   ) ||
128
         FT_NEW_ARRAY( zone->cur,      maxPoints   ) ||
129
         FT_NEW_ARRAY( zone->orus,     maxPoints   ) ||
130
         FT_NEW_ARRAY( zone->tags,     maxPoints   ) ||
131
         FT_NEW_ARRAY( zone->contours, maxContours ) )
132
    {
133
      tt_glyphzone_done( zone );
134
    }
135
    else
136
    {
137
      zone->max_points   = maxPoints;
138
      zone->max_contours = maxContours;
139
    }
140
 
141
    return error;
142
  }
143
#endif /* TT_USE_BYTECODE_INTERPRETER */
144
 
145
 
146
  /* Compare the face with a list of well-known `tricky' fonts. */
147
  /* This list shall be expanded as we find more of them.       */
148
 
149
  static FT_Bool
150
  tt_check_trickyness_family( FT_String*  name )
151
  {
152
 
153
#define TRICK_NAMES_MAX_CHARACTERS  16
154
#define TRICK_NAMES_COUNT            8
155
 
156
    static const char trick_names[TRICK_NAMES_COUNT]
157
                                 [TRICK_NAMES_MAX_CHARACTERS + 1] =
158
    {
159
      "DFKaiSho-SB",     /* dfkaisb.ttf */
160
      "DFKaiShu",
161
      "DFKai-SB",        /* kaiu.ttf */
162
      "HuaTianKaiTi?",   /* htkt2.ttf */
163
      "HuaTianSongTi?",  /* htst3.ttf */
164
      "MingLiU",         /* mingliu.ttf & mingliu.ttc */
165
      "PMingLiU",        /* mingliu.ttc */
166
      "MingLi43",        /* mingli.ttf */
167
    };
168
 
169
    int  nn;
170
 
171
 
172
    for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
173
      if ( ft_strstr( name, trick_names[nn] ) )
174
        return TRUE;
175
 
176
    return FALSE;
177
  }
178
 
179
 
180
  /* XXX: This function should be in the `sfnt' module. */
181
 
182
  /* Some PDF generators clear the checksums in the TrueType header table. */
183
  /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF     */
184
  /* Printer clears the entries for subsetted subtables.  We thus have to  */
185
  /* recalculate the checksums  where necessary.                           */
186
 
187
  static FT_UInt32
188
  tt_synth_sfnt_checksum( FT_Stream  stream,
189
                          FT_ULong   length )
190
  {
191
    FT_Error   error;
192
    FT_UInt32  checksum = 0;
193
    int        i;
194
 
195
 
196
    if ( FT_FRAME_ENTER( length ) )
197
      return 0;
198
 
199
    for ( ; length > 3; length -= 4 )
200
      checksum += (FT_UInt32)FT_GET_ULONG();
201
 
202
    for ( i = 3; length > 0; length --, i-- )
203
      checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) );
204
 
205
    FT_FRAME_EXIT();
206
 
207
    return checksum;
208
  }
209
 
210
 
211
  /* XXX: This function should be in the `sfnt' module. */
212
 
213
  static FT_ULong
214
  tt_get_sfnt_checksum( TT_Face    face,
215
                        FT_UShort  i )
216
  {
217
#if 0 /* if we believe the written value, use following part. */
218
    if ( face->dir_tables[i].CheckSum )
219
      return face->dir_tables[i].CheckSum;
220
#endif
221
 
222
    if ( !face->goto_table )
223
      return 0;
224
 
225
    if ( face->goto_table( face,
226
                           face->dir_tables[i].Tag,
227
                           face->root.stream,
228
                           NULL ) )
229
      return 0;
230
 
231
    return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,
232
                                             face->dir_tables[i].Length );
233
  }
234
 
235
 
236
  typedef struct tt_sfnt_id_rec_
237
  {
238
    FT_ULong  CheckSum;
239
    FT_ULong  Length;
240
 
241
  } tt_sfnt_id_rec;
242
 
243
 
244
  static FT_Bool
245
  tt_check_trickyness_sfnt_ids( TT_Face  face )
246
  {
247
#define TRICK_SFNT_IDS_PER_FACE   3
248
#define TRICK_SFNT_IDS_NUM_FACES  17
249
 
250
    static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
251
                                       [TRICK_SFNT_IDS_PER_FACE] = {
252
 
253
#define TRICK_SFNT_ID_cvt   0
254
#define TRICK_SFNT_ID_fpgm  1
255
#define TRICK_SFNT_ID_prep  2
256
 
257
      { /* MingLiU 1995 */
258
        { 0x05bcf058, 0x000002e4 }, /* cvt  */
259
        { 0x28233bf1, 0x000087c4 }, /* fpgm */
260
        { 0xa344a1ea, 0x000001e1 }  /* prep */
261
      },
262
      { /* MingLiU 1996- */
263
        { 0x05bcf058, 0x000002e4 }, /* cvt  */
264
        { 0x28233bf1, 0x000087c4 }, /* fpgm */
265
        { 0xa344a1eb, 0x000001e1 }  /* prep */
266
      },
267
      { /* DFKaiShu */
268
        { 0x11e5ead4, 0x00000350 }, /* cvt  */
269
        { 0x5a30ca3b, 0x00009063 }, /* fpgm */
270
        { 0x13a42602, 0x0000007e }  /* prep */
271
      },
272
      { /* HuaTianKaiTi */
273
        { 0xfffbfffc, 0x00000008 }, /* cvt  */
274
        { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */
275
        { 0x70020112, 0x00000008 }  /* prep */
276
      },
277
      { /* HuaTianSongTi */
278
        { 0xfffbfffc, 0x00000008 }, /* cvt  */
279
        { 0x0a5a0483, 0x00017c39 }, /* fpgm */
280
        { 0x70020112, 0x00000008 }  /* prep */
281
      },
282
      { /* NEC fadpop7.ttf */
283
        { 0x00000000, 0x00000000 }, /* cvt  */
284
        { 0x40c92555, 0x000000e5 }, /* fpgm */
285
        { 0xa39b58e3, 0x0000117c }  /* prep */
286
      },
287
      { /* NEC fadrei5.ttf */
288
        { 0x00000000, 0x00000000 }, /* cvt  */
289
        { 0x33c41652, 0x000000e5 }, /* fpgm */
290
        { 0x26d6c52a, 0x00000f6a }  /* prep */
291
      },
292
      { /* NEC fangot7.ttf */
293
        { 0x00000000, 0x00000000 }, /* cvt  */
294
        { 0x6db1651d, 0x0000019d }, /* fpgm */
295
        { 0x6c6e4b03, 0x00002492 }  /* prep */
296
      },
297
      { /* NEC fangyo5.ttf */
298
        { 0x00000000, 0x00000000 }, /* cvt  */
299
        { 0x40c92555, 0x000000e5 }, /* fpgm */
300
        { 0xde51fad0, 0x0000117c }  /* prep */
301
      },
302
      { /* NEC fankyo5.ttf */
303
        { 0x00000000, 0x00000000 }, /* cvt  */
304
        { 0x85e47664, 0x000000e5 }, /* fpgm */
305
        { 0xa6c62831, 0x00001caa }  /* prep */
306
      },
307
      { /* NEC fanrgo5.ttf */
308
        { 0x00000000, 0x00000000 }, /* cvt  */
309
        { 0x2d891cfd, 0x0000019d }, /* fpgm */
310
        { 0xa0604633, 0x00001de8 }  /* prep */
311
      },
312
      { /* NEC fangot5.ttc */
313
        { 0x00000000, 0x00000000 }, /* cvt  */
314
        { 0x40aa774c, 0x000001cb }, /* fpgm */
315
        { 0x9b5caa96, 0x00001f9a }  /* prep */
316
      },
317
      { /* NEC fanmin3.ttc */
318
        { 0x00000000, 0x00000000 }, /* cvt  */
319
        { 0x0d3de9cb, 0x00000141 }, /* fpgm */
320
        { 0xd4127766, 0x00002280 }  /* prep */
321
      },
322
      { /* NEC FA-Gothic, 1996 */
323
        { 0x00000000, 0x00000000 }, /* cvt  */
324
        { 0x4a692698, 0x000001f0 }, /* fpgm */
325
        { 0x340d4346, 0x00001fca }  /* prep */
326
      },
327
      { /* NEC FA-Minchou, 1996 */
328
        { 0x00000000, 0x00000000 }, /* cvt  */
329
        { 0xcd34c604, 0x00000166 }, /* fpgm */
330
        { 0x6cf31046, 0x000022b0 }  /* prep */
331
      },
332
      { /* NEC FA-RoundGothicB, 1996 */
333
        { 0x00000000, 0x00000000 }, /* cvt  */
334
        { 0x5da75315, 0x0000019d }, /* fpgm */
335
        { 0x40745a5f, 0x000022e0 }  /* prep */
336
      },
337
      { /* NEC FA-RoundGothicM, 1996 */
338
        { 0x00000000, 0x00000000 }, /* cvt  */
339
        { 0xf055fc48, 0x000001c2 }, /* fpgm */
340
        { 0x3900ded3, 0x00001e18 }  /* prep */
341
      }
342
    };
343
 
344
    FT_ULong   checksum;
345
    int        num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];
346
    FT_Bool    has_cvt, has_fpgm, has_prep;
347
    FT_UShort  i;
348
    int        j, k;
349
 
350
 
351
    FT_MEM_SET( num_matched_ids, 0,
352
                sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES );
353
    has_cvt  = FALSE;
354
    has_fpgm = FALSE;
355
    has_prep = FALSE;
356
 
357
    for ( i = 0; i < face->num_tables; i++ )
358
    {
359
      checksum = 0;
360
 
361
      switch( face->dir_tables[i].Tag )
362
      {
363
      case TTAG_cvt:
364
        k = TRICK_SFNT_ID_cvt;
365
        has_cvt  = TRUE;
366
        break;
367
 
368
      case TTAG_fpgm:
369
        k = TRICK_SFNT_ID_fpgm;
370
        has_fpgm = TRUE;
371
        break;
372
 
373
      case TTAG_prep:
374
        k = TRICK_SFNT_ID_prep;
375
        has_prep = TRUE;
376
        break;
377
 
378
      default:
379
        continue;
380
      }
381
 
382
      for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
383
        if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )
384
        {
385
          if ( !checksum )
386
            checksum = tt_get_sfnt_checksum( face, i );
387
 
388
          if ( sfnt_id[j][k].CheckSum == checksum )
389
            num_matched_ids[j]++;
390
 
391
          if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
392
            return TRUE;
393
        }
394
    }
395
 
396
    for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
397
    {
398
      if ( !has_cvt  && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
399
        num_matched_ids[j] ++;
400
      if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
401
        num_matched_ids[j] ++;
402
      if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
403
        num_matched_ids[j] ++;
404
      if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
405
        return TRUE;
406
    }
407
 
408
    return FALSE;
409
  }
410
 
411
 
412
  static FT_Bool
413
  tt_check_trickyness( FT_Face  face )
414
  {
415
    if ( !face )
416
      return FALSE;
417
 
418
    /* For first, check the face name for quick check. */
419
    if ( face->family_name                               &&
420
         tt_check_trickyness_family( face->family_name ) )
421
      return TRUE;
422
 
423
    /* Type42 fonts may lack `name' tables, we thus try to identify */
424
    /* tricky fonts by checking the checksums of Type42-persistent  */
425
    /* sfnt tables (`cvt', `fpgm', and `prep').                     */
426
    if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
427
      return TRUE;
428
 
429
    return FALSE;
430
  }
431
 
432
 
433
  /* Check whether `.notdef' is the only glyph in the `loca' table. */
434
  static FT_Bool
435
  tt_check_single_notdef( FT_Face  ttface )
436
  {
437
    FT_Bool   result = FALSE;
438
 
439
    TT_Face   face = (TT_Face)ttface;
440
    FT_UInt   asize;
441
    FT_ULong  i;
442
    FT_ULong  glyph_index = 0;
443
    FT_UInt   count       = 0;
444
 
445
 
446
    for( i = 0; i < face->num_locations; i++ )
447
    {
448
      tt_face_get_location( face, i, &asize );
449
      if ( asize > 0 )
450
      {
451
        count += 1;
452
        if ( count > 1 )
453
          break;
454
        glyph_index = i;
455
      }
456
    }
457
 
458
    /* Only have a single outline. */
459
    if ( count == 1 )
460
    {
461
      if ( glyph_index == 0 )
462
        result = TRUE;
463
      else
464
      {
465
        /* FIXME: Need to test glyphname == .notdef ? */
466
        FT_Error error;
467
        char buf[8];
468
 
469
 
470
        error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 );
471
        if ( !error                                            &&
472
             buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) )
473
          result = TRUE;
474
      }
475
    }
476
 
477
    return result;
478
  }
479
 
480
 
481
  /*************************************************************************/
482
  /*                                                                       */
483
  /*                                                             */
484
  /*    tt_face_init                                                       */
485
  /*                                                                       */
486
  /*                                                          */
487
  /*    Initialize a given TrueType face object.                           */
488
  /*                                                                       */
489
  /*                                                                */
490
  /*    stream     :: The source font stream.                              */
491
  /*                                                                       */
492
  /*    face_index :: The index of the font face in the resource.          */
493
  /*                                                                       */
494
  /*    num_params :: Number of additional generic parameters.  Ignored.   */
495
  /*                                                                       */
496
  /*    params     :: Additional generic parameters.  Ignored.             */
497
  /*                                                                       */
498
  /*                                                                */
499
  /*    face       :: The newly built face object.                         */
500
  /*                                                                       */
501
  /*                                                               */
502
  /*    FreeType error code.  0 means success.                             */
503
  /*                                                                       */
504
  FT_LOCAL_DEF( FT_Error )
505
  tt_face_init( FT_Stream      stream,
506
                FT_Face        ttface,      /* TT_Face */
507
                FT_Int         face_index,
508
                FT_Int         num_params,
509
                FT_Parameter*  params )
510
  {
511
    FT_Error      error;
512
    FT_Library    library;
513
    SFNT_Service  sfnt;
514
    TT_Face       face = (TT_Face)ttface;
515
 
516
 
517
    FT_TRACE2(( "TTF driver\n" ));
518
 
519
    library = ttface->driver->root.library;
520
 
521
    sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
522
    if ( !sfnt )
523
    {
524
      FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
525
      error = FT_THROW( Missing_Module );
526
      goto Exit;
527
    }
528
 
529
    /* create input stream from resource */
530
    if ( FT_STREAM_SEEK( 0 ) )
531
      goto Exit;
532
 
533
    /* check that we have a valid TrueType file */
534
    error = sfnt->init_face( stream, face, face_index, num_params, params );
535
    if ( error )
536
      goto Exit;
537
 
538
    /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
539
    /* The 0x00020000 tag is completely undocumented; some fonts from   */
540
    /* Arphic made for Chinese Windows 3.1 have this.                   */
541
    if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
542
         face->format_tag != 0x00020000L &&    /* CJK fonts for Win 3.1 */
543
         face->format_tag != TTAG_true   )     /* Mac fonts */
544
    {
545
      FT_TRACE2(( "  not a TTF font\n" ));
546
      goto Bad_Format;
547
    }
548
 
549
#ifdef TT_USE_BYTECODE_INTERPRETER
550
    ttface->face_flags |= FT_FACE_FLAG_HINTER;
551
#endif
552
 
553
    /* If we are performing a simple font format check, exit immediately. */
554
    if ( face_index < 0 )
555
      return FT_Err_Ok;
556
 
557
    /* Load font directory */
558
    error = sfnt->load_face( stream, face, face_index, num_params, params );
559
    if ( error )
560
      goto Exit;
561
 
562
    if ( tt_check_trickyness( ttface ) )
563
      ttface->face_flags |= FT_FACE_FLAG_TRICKY;
564
 
565
    error = tt_face_load_hdmx( face, stream );
566
    if ( error )
567
      goto Exit;
568
 
569
    if ( FT_IS_SCALABLE( ttface ) )
570
    {
571
 
572
#ifdef FT_CONFIG_OPTION_INCREMENTAL
573
 
574
      if ( !ttface->internal->incremental_interface )
575
        error = tt_face_load_loca( face, stream );
576
      if ( !error )
577
        error = tt_face_load_cvt( face, stream );
578
      if ( !error )
579
        error = tt_face_load_fpgm( face, stream );
580
      if ( !error )
581
        error = tt_face_load_prep( face, stream );
582
 
583
      /* Check the scalable flag based on `loca'. */
584
      if ( !ttface->internal->incremental_interface &&
585
           ttface->num_fixed_sizes                  &&
586
           face->glyph_locations                    &&
587
           tt_check_single_notdef( ttface )         )
588
      {
589
        FT_TRACE5(( "tt_face_init:"
590
                    " Only the `.notdef' glyph has an outline.\n"
591
                    "             "
592
                    " Resetting scalable flag to FALSE.\n" ));
593
 
594
        ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
595
      }
596
 
597
#else
598
 
599
      if ( !error )
600
        error = tt_face_load_loca( face, stream );
601
      if ( !error )
602
        error = tt_face_load_cvt( face, stream );
603
      if ( !error )
604
        error = tt_face_load_fpgm( face, stream );
605
      if ( !error )
606
        error = tt_face_load_prep( face, stream );
607
 
608
      /* Check the scalable flag based on `loca'. */
609
      if ( ttface->num_fixed_sizes          &&
610
           face->glyph_locations            &&
611
           tt_check_single_notdef( ttface ) )
612
      {
613
        FT_TRACE5(( "tt_face_init:"
614
                    " Only the `.notdef' glyph has an outline.\n"
615
                    "             "
616
                    " Resetting scalable flag to FALSE.\n" ));
617
 
618
        ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
619
      }
620
 
621
#endif
622
 
623
    }
624
 
625
#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING    ) && \
626
    !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
627
 
628
    {
629
      FT_Bool  unpatented_hinting;
630
      int      i;
631
 
632
 
633
      /* Determine whether unpatented hinting is to be used for this face. */
634
      unpatented_hinting = FT_BOOL
635
        ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
636
 
637
      for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
638
        if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
639
          unpatented_hinting = TRUE;
640
 
641
      if ( !unpatented_hinting )
642
        ttface->internal->ignore_unpatented_hinter = TRUE;
643
    }
644
 
645
#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
646
          !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
647
 
648
    /* initialize standard glyph loading routines */
649
    TT_Init_Glyph_Loading( face );
650
 
651
  Exit:
652
    return error;
653
 
654
  Bad_Format:
655
    error = FT_THROW( Unknown_File_Format );
656
    goto Exit;
657
  }
658
 
659
 
660
  /*************************************************************************/
661
  /*                                                                       */
662
  /*                                                             */
663
  /*    tt_face_done                                                       */
664
  /*                                                                       */
665
  /*                                                          */
666
  /*    Finalize a given face object.                                      */
667
  /*                                                                       */
668
  /*                                                                */
669
  /*    face :: A pointer to the face object to destroy.                   */
670
  /*                                                                       */
671
  FT_LOCAL_DEF( void )
672
  tt_face_done( FT_Face  ttface )           /* TT_Face */
673
  {
674
    TT_Face       face = (TT_Face)ttface;
675
    FT_Memory     memory;
676
    FT_Stream     stream;
677
    SFNT_Service  sfnt;
678
 
679
 
680
    if ( !face )
681
      return;
682
 
683
    memory = ttface->memory;
684
    stream = ttface->stream;
685
    sfnt   = (SFNT_Service)face->sfnt;
686
 
687
    /* for `extended TrueType formats' (i.e. compressed versions) */
688
    if ( face->extra.finalizer )
689
      face->extra.finalizer( face->extra.data );
690
 
691
    if ( sfnt )
692
      sfnt->done_face( face );
693
 
694
    /* freeing the locations table */
695
    tt_face_done_loca( face );
696
 
697
    tt_face_free_hdmx( face );
698
 
699
    /* freeing the CVT */
700
    FT_FREE( face->cvt );
701
    face->cvt_size = 0;
702
 
703
    /* freeing the programs */
704
    FT_FRAME_RELEASE( face->font_program );
705
    FT_FRAME_RELEASE( face->cvt_program );
706
    face->font_program_size = 0;
707
    face->cvt_program_size  = 0;
708
 
709
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
710
    tt_done_blend( memory, face->blend );
711
    face->blend = NULL;
712
#endif
713
  }
714
 
715
 
716
  /*************************************************************************/
717
  /*                                                                       */
718
  /*                           SIZE  FUNCTIONS                             */
719
  /*                                                                       */
720
  /*************************************************************************/
721
 
722
#ifdef TT_USE_BYTECODE_INTERPRETER
723
 
724
  /*************************************************************************/
725
  /*                                                                       */
726
  /*                                                             */
727
  /*    tt_size_run_fpgm                                                   */
728
  /*                                                                       */
729
  /*                                                          */
730
  /*    Run the font program.                                              */
731
  /*                                                                       */
732
  /*                                                                */
733
  /*    size     :: A handle to the size object.                           */
734
  /*                                                                       */
735
  /*    pedantic :: Set if bytecode execution should be pedantic.          */
736
  /*                                                                       */
737
  /*                                                               */
738
  /*    FreeType error code.  0 means success.                             */
739
  /*                                                                       */
740
  FT_LOCAL_DEF( FT_Error )
741
  tt_size_run_fpgm( TT_Size  size,
742
                    FT_Bool  pedantic )
743
  {
744
    TT_Face         face = (TT_Face)size->root.face;
745
    TT_ExecContext  exec;
746
    FT_Error        error;
747
 
748
 
749
    /* debugging instances have their own context */
750
    if ( size->debug )
751
      exec = size->context;
752
    else
753
      exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
754
 
755
    if ( !exec )
756
      return FT_THROW( Could_Not_Find_Context );
757
 
758
    TT_Load_Context( exec, face, size );
759
 
760
    exec->callTop = 0;
761
    exec->top     = 0;
762
 
763
    exec->period    = 64;
764
    exec->phase     = 0;
765
    exec->threshold = 0;
766
 
767
    exec->instruction_trap = FALSE;
768
    exec->F_dot_P          = 0x4000L;
769
 
770
    exec->pedantic_hinting = pedantic;
771
 
772
    {
773
      FT_Size_Metrics*  metrics    = &exec->metrics;
774
      TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;
775
 
776
 
777
      metrics->x_ppem   = 0;
778
      metrics->y_ppem   = 0;
779
      metrics->x_scale  = 0;
780
      metrics->y_scale  = 0;
781
 
782
      tt_metrics->ppem  = 0;
783
      tt_metrics->scale = 0;
784
      tt_metrics->ratio = 0x10000L;
785
    }
786
 
787
    /* allow font program execution */
788
    TT_Set_CodeRange( exec,
789
                      tt_coderange_font,
790
                      face->font_program,
791
                      face->font_program_size );
792
 
793
    /* disable CVT and glyph programs coderange */
794
    TT_Clear_CodeRange( exec, tt_coderange_cvt );
795
    TT_Clear_CodeRange( exec, tt_coderange_glyph );
796
 
797
    if ( face->font_program_size > 0 )
798
    {
799
      error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
800
 
801
      if ( !error )
802
      {
803
        FT_TRACE4(( "Executing `fpgm' table.\n" ));
804
 
805
        error = face->interpreter( exec );
806
      }
807
    }
808
    else
809
      error = FT_Err_Ok;
810
 
811
    if ( !error )
812
      TT_Save_Context( exec, size );
813
 
814
    return error;
815
  }
816
 
817
 
818
  /*************************************************************************/
819
  /*                                                                       */
820
  /*                                                             */
821
  /*    tt_size_run_prep                                                   */
822
  /*                                                                       */
823
  /*                                                          */
824
  /*    Run the control value program.                                     */
825
  /*                                                                       */
826
  /*                                                                */
827
  /*    size     :: A handle to the size object.                           */
828
  /*                                                                       */
829
  /*    pedantic :: Set if bytecode execution should be pedantic.          */
830
  /*                                                                       */
831
  /*                                                               */
832
  /*    FreeType error code.  0 means success.                             */
833
  /*                                                                       */
834
  FT_LOCAL_DEF( FT_Error )
835
  tt_size_run_prep( TT_Size  size,
836
                    FT_Bool  pedantic )
837
  {
838
    TT_Face         face = (TT_Face)size->root.face;
839
    TT_ExecContext  exec;
840
    FT_Error        error;
841
 
842
 
843
    /* debugging instances have their own context */
844
    if ( size->debug )
845
      exec = size->context;
846
    else
847
      exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
848
 
849
    if ( !exec )
850
      return FT_THROW( Could_Not_Find_Context );
851
 
852
    TT_Load_Context( exec, face, size );
853
 
854
    exec->callTop = 0;
855
    exec->top     = 0;
856
 
857
    exec->instruction_trap = FALSE;
858
 
859
    exec->pedantic_hinting = pedantic;
860
 
861
    TT_Set_CodeRange( exec,
862
                      tt_coderange_cvt,
863
                      face->cvt_program,
864
                      face->cvt_program_size );
865
 
866
    TT_Clear_CodeRange( exec, tt_coderange_glyph );
867
 
868
    if ( face->cvt_program_size > 0 )
869
    {
870
      error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
871
 
872
      if ( !error && !size->debug )
873
      {
874
        FT_TRACE4(( "Executing `prep' table.\n" ));
875
 
876
        error = face->interpreter( exec );
877
      }
878
    }
879
    else
880
      error = FT_Err_Ok;
881
 
882
    /* UNDOCUMENTED!  The MS rasterizer doesn't allow the following */
883
    /* graphics state variables to be modified by the CVT program.  */
884
 
885
    exec->GS.dualVector.x = 0x4000;
886
    exec->GS.dualVector.y = 0;
887
    exec->GS.projVector.x = 0x4000;
888
    exec->GS.projVector.y = 0x0;
889
    exec->GS.freeVector.x = 0x4000;
890
    exec->GS.freeVector.y = 0x0;
891
 
892
    exec->GS.rp0 = 0;
893
    exec->GS.rp1 = 0;
894
    exec->GS.rp2 = 0;
895
 
896
    exec->GS.gep0 = 1;
897
    exec->GS.gep1 = 1;
898
    exec->GS.gep2 = 1;
899
 
900
    exec->GS.loop = 1;
901
 
902
    /* save as default graphics state */
903
    size->GS = exec->GS;
904
 
905
    TT_Save_Context( exec, size );
906
 
907
    return error;
908
  }
909
 
910
#endif /* TT_USE_BYTECODE_INTERPRETER */
911
 
912
 
913
#ifdef TT_USE_BYTECODE_INTERPRETER
914
 
915
  static void
916
  tt_size_done_bytecode( FT_Size  ftsize )
917
  {
918
    TT_Size    size   = (TT_Size)ftsize;
919
    TT_Face    face   = (TT_Face)ftsize->face;
920
    FT_Memory  memory = face->root.memory;
921
 
922
 
923
    if ( size->debug )
924
    {
925
      /* the debug context must be deleted by the debugger itself */
926
      size->context = NULL;
927
      size->debug   = FALSE;
928
    }
929
 
930
    FT_FREE( size->cvt );
931
    size->cvt_size = 0;
932
 
933
    /* free storage area */
934
    FT_FREE( size->storage );
935
    size->storage_size = 0;
936
 
937
    /* twilight zone */
938
    tt_glyphzone_done( &size->twilight );
939
 
940
    FT_FREE( size->function_defs );
941
    FT_FREE( size->instruction_defs );
942
 
943
    size->num_function_defs    = 0;
944
    size->max_function_defs    = 0;
945
    size->num_instruction_defs = 0;
946
    size->max_instruction_defs = 0;
947
 
948
    size->max_func = 0;
949
    size->max_ins  = 0;
950
 
951
    size->bytecode_ready = 0;
952
    size->cvt_ready      = 0;
953
  }
954
 
955
 
956
  /* Initialize bytecode-related fields in the size object.       */
957
  /* We do this only if bytecode interpretation is really needed. */
958
  static FT_Error
959
  tt_size_init_bytecode( FT_Size  ftsize,
960
                         FT_Bool  pedantic )
961
  {
962
    FT_Error   error;
963
    TT_Size    size = (TT_Size)ftsize;
964
    TT_Face    face = (TT_Face)ftsize->face;
965
    FT_Memory  memory = face->root.memory;
966
    FT_Int     i;
967
 
968
    FT_UShort       n_twilight;
969
    TT_MaxProfile*  maxp = &face->max_profile;
970
 
971
 
972
    size->bytecode_ready = 1;
973
    size->cvt_ready      = 0;
974
 
975
    size->max_function_defs    = maxp->maxFunctionDefs;
976
    size->max_instruction_defs = maxp->maxInstructionDefs;
977
 
978
    size->num_function_defs    = 0;
979
    size->num_instruction_defs = 0;
980
 
981
    size->max_func = 0;
982
    size->max_ins  = 0;
983
 
984
    size->cvt_size     = face->cvt_size;
985
    size->storage_size = maxp->maxStorage;
986
 
987
    /* Set default metrics */
988
    {
989
      TT_Size_Metrics*  metrics = &size->ttmetrics;
990
 
991
 
992
      metrics->rotated   = FALSE;
993
      metrics->stretched = FALSE;
994
 
995
      /* set default compensation (all 0) */
996
      for ( i = 0; i < 4; i++ )
997
        metrics->compensations[i] = 0;
998
    }
999
 
1000
    /* allocate function defs, instruction defs, cvt, and storage area */
1001
    if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||
1002
         FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
1003
         FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
1004
         FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
1005
      goto Exit;
1006
 
1007
    /* reserve twilight zone */
1008
    n_twilight = maxp->maxTwilightPoints;
1009
 
1010
    /* there are 4 phantom points (do we need this?) */
1011
    n_twilight += 4;
1012
 
1013
    error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
1014
    if ( error )
1015
      goto Exit;
1016
 
1017
    size->twilight.n_points = n_twilight;
1018
 
1019
    size->GS = tt_default_graphics_state;
1020
 
1021
    /* set `face->interpreter' according to the debug hook present */
1022
    {
1023
      FT_Library  library = face->root.driver->root.library;
1024
 
1025
 
1026
      face->interpreter = (TT_Interpreter)
1027
                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
1028
      if ( !face->interpreter )
1029
        face->interpreter = (TT_Interpreter)TT_RunIns;
1030
    }
1031
 
1032
    /* Fine, now run the font program! */
1033
    error = tt_size_run_fpgm( size, pedantic );
1034
 
1035
  Exit:
1036
    if ( error )
1037
      tt_size_done_bytecode( ftsize );
1038
 
1039
    return error;
1040
  }
1041
 
1042
 
1043
  FT_LOCAL_DEF( FT_Error )
1044
  tt_size_ready_bytecode( TT_Size  size,
1045
                          FT_Bool  pedantic )
1046
  {
1047
    FT_Error  error = FT_Err_Ok;
1048
 
1049
 
1050
    if ( !size->bytecode_ready )
1051
    {
1052
      error = tt_size_init_bytecode( (FT_Size)size, pedantic );
1053
      if ( error )
1054
        goto Exit;
1055
    }
1056
 
1057
    /* rescale CVT when needed */
1058
    if ( !size->cvt_ready )
1059
    {
1060
      FT_UInt  i;
1061
      TT_Face  face = (TT_Face)size->root.face;
1062
 
1063
 
1064
      /* Scale the cvt values to the new ppem.          */
1065
      /* We use by default the y ppem to scale the CVT. */
1066
      for ( i = 0; i < size->cvt_size; i++ )
1067
        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
1068
 
1069
      /* all twilight points are originally zero */
1070
      for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
1071
      {
1072
        size->twilight.org[i].x = 0;
1073
        size->twilight.org[i].y = 0;
1074
        size->twilight.cur[i].x = 0;
1075
        size->twilight.cur[i].y = 0;
1076
      }
1077
 
1078
      /* clear storage area */
1079
      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
1080
        size->storage[i] = 0;
1081
 
1082
      size->GS = tt_default_graphics_state;
1083
 
1084
      error = tt_size_run_prep( size, pedantic );
1085
      if ( !error )
1086
        size->cvt_ready = 1;
1087
    }
1088
 
1089
  Exit:
1090
    return error;
1091
  }
1092
 
1093
#endif /* TT_USE_BYTECODE_INTERPRETER */
1094
 
1095
 
1096
  /*************************************************************************/
1097
  /*                                                                       */
1098
  /*                                                             */
1099
  /*    tt_size_init                                                       */
1100
  /*                                                                       */
1101
  /*                                                          */
1102
  /*    Initialize a new TrueType size object.                             */
1103
  /*                                                                       */
1104
  /*                                                                */
1105
  /*    size :: A handle to the size object.                               */
1106
  /*                                                                       */
1107
  /*                                                               */
1108
  /*    FreeType error code.  0 means success.                             */
1109
  /*                                                                       */
1110
  FT_LOCAL_DEF( FT_Error )
1111
  tt_size_init( FT_Size  ttsize )           /* TT_Size */
1112
  {
1113
    TT_Size   size  = (TT_Size)ttsize;
1114
    FT_Error  error = FT_Err_Ok;
1115
 
1116
#ifdef TT_USE_BYTECODE_INTERPRETER
1117
    size->bytecode_ready = 0;
1118
    size->cvt_ready      = 0;
1119
#endif
1120
 
1121
    size->ttmetrics.valid = FALSE;
1122
    size->strike_index    = 0xFFFFFFFFUL;
1123
 
1124
    return error;
1125
  }
1126
 
1127
 
1128
  /*************************************************************************/
1129
  /*                                                                       */
1130
  /*                                                             */
1131
  /*    tt_size_done                                                       */
1132
  /*                                                                       */
1133
  /*                                                          */
1134
  /*    The TrueType size object finalizer.                                */
1135
  /*                                                                       */
1136
  /*                                                                */
1137
  /*    size :: A handle to the target size object.                        */
1138
  /*                                                                       */
1139
  FT_LOCAL_DEF( void )
1140
  tt_size_done( FT_Size  ttsize )           /* TT_Size */
1141
  {
1142
    TT_Size  size = (TT_Size)ttsize;
1143
 
1144
 
1145
#ifdef TT_USE_BYTECODE_INTERPRETER
1146
    if ( size->bytecode_ready )
1147
      tt_size_done_bytecode( ttsize );
1148
#endif
1149
 
1150
    size->ttmetrics.valid = FALSE;
1151
  }
1152
 
1153
 
1154
  /*************************************************************************/
1155
  /*                                                                       */
1156
  /*                                                             */
1157
  /*    tt_size_reset                                                      */
1158
  /*                                                                       */
1159
  /*                                                          */
1160
  /*    Reset a TrueType size when resolutions and character dimensions    */
1161
  /*    have been changed.                                                 */
1162
  /*                                                                       */
1163
  /*                                                                */
1164
  /*    size :: A handle to the target size object.                        */
1165
  /*                                                                       */
1166
  FT_LOCAL_DEF( FT_Error )
1167
  tt_size_reset( TT_Size  size )
1168
  {
1169
    TT_Face           face;
1170
    FT_Error          error = FT_Err_Ok;
1171
    FT_Size_Metrics*  metrics;
1172
 
1173
 
1174
    size->ttmetrics.valid = FALSE;
1175
 
1176
    face = (TT_Face)size->root.face;
1177
 
1178
    metrics = &size->metrics;
1179
 
1180
    /* copy the result from base layer */
1181
    *metrics = size->root.metrics;
1182
 
1183
    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
1184
      return FT_THROW( Invalid_PPem );
1185
 
1186
    /* This bit flag, if set, indicates that the ppems must be       */
1187
    /* rounded to integers.  Nearly all TrueType fonts have this bit */
1188
    /* set, as hinting won't work really well otherwise.             */
1189
    /*                                                               */
1190
    if ( face->header.Flags & 8 )
1191
    {
1192
      metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
1193
                                    face->root.units_per_EM );
1194
      metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
1195
                                    face->root.units_per_EM );
1196
 
1197
      metrics->ascender =
1198
        FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
1199
      metrics->descender =
1200
        FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
1201
      metrics->height =
1202
        FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
1203
      metrics->max_advance =
1204
        FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
1205
                                 metrics->x_scale ) );
1206
    }
1207
 
1208
    /* compute new transformation */
1209
    if ( metrics->x_ppem >= metrics->y_ppem )
1210
    {
1211
      size->ttmetrics.scale   = metrics->x_scale;
1212
      size->ttmetrics.ppem    = metrics->x_ppem;
1213
      size->ttmetrics.x_ratio = 0x10000L;
1214
      size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem,
1215
                                           metrics->x_ppem );
1216
    }
1217
    else
1218
    {
1219
      size->ttmetrics.scale   = metrics->y_scale;
1220
      size->ttmetrics.ppem    = metrics->y_ppem;
1221
      size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem,
1222
                                           metrics->y_ppem );
1223
      size->ttmetrics.y_ratio = 0x10000L;
1224
    }
1225
 
1226
#ifdef TT_USE_BYTECODE_INTERPRETER
1227
    size->cvt_ready = 0;
1228
#endif /* TT_USE_BYTECODE_INTERPRETER */
1229
 
1230
    if ( !error )
1231
      size->ttmetrics.valid = TRUE;
1232
 
1233
    return error;
1234
  }
1235
 
1236
 
1237
  /*************************************************************************/
1238
  /*                                                                       */
1239
  /*                                                             */
1240
  /*    tt_driver_init                                                     */
1241
  /*                                                                       */
1242
  /*                                                          */
1243
  /*    Initialize a given TrueType driver object.                         */
1244
  /*                                                                       */
1245
  /*                                                                */
1246
  /*    driver :: A handle to the target driver object.                    */
1247
  /*                                                                       */
1248
  /*                                                               */
1249
  /*    FreeType error code.  0 means success.                             */
1250
  /*                                                                       */
1251
  FT_LOCAL_DEF( FT_Error )
1252
  tt_driver_init( FT_Module  ttdriver )     /* TT_Driver */
1253
  {
1254
 
1255
#ifdef TT_USE_BYTECODE_INTERPRETER
1256
 
1257
    TT_Driver  driver = (TT_Driver)ttdriver;
1258
 
1259
 
1260
    if ( !TT_New_Context( driver ) )
1261
      return FT_THROW( Could_Not_Find_Context );
1262
 
1263
#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1264
    driver->interpreter_version = TT_INTERPRETER_VERSION_38;
1265
#else
1266
    driver->interpreter_version = TT_INTERPRETER_VERSION_35;
1267
#endif
1268
 
1269
#else /* !TT_USE_BYTECODE_INTERPRETER */
1270
 
1271
    FT_UNUSED( ttdriver );
1272
 
1273
#endif /* !TT_USE_BYTECODE_INTERPRETER */
1274
 
1275
    return FT_Err_Ok;
1276
  }
1277
 
1278
 
1279
  /*************************************************************************/
1280
  /*                                                                       */
1281
  /*                                                             */
1282
  /*    tt_driver_done                                                     */
1283
  /*                                                                       */
1284
  /*                                                          */
1285
  /*    Finalize a given TrueType driver.                                  */
1286
  /*                                                                       */
1287
  /*                                                                */
1288
  /*    driver :: A handle to the target TrueType driver.                  */
1289
  /*                                                                       */
1290
  FT_LOCAL_DEF( void )
1291
  tt_driver_done( FT_Module  ttdriver )     /* TT_Driver */
1292
  {
1293
#ifdef TT_USE_BYTECODE_INTERPRETER
1294
    TT_Driver  driver = (TT_Driver)ttdriver;
1295
 
1296
 
1297
    /* destroy the execution context */
1298
    if ( driver->context )
1299
    {
1300
      TT_Done_Context( driver->context );
1301
      driver->context = NULL;
1302
    }
1303
#else
1304
    FT_UNUSED( ttdriver );
1305
#endif
1306
 
1307
  }
1308
 
1309
 
1310
  /*************************************************************************/
1311
  /*                                                                       */
1312
  /*                                                             */
1313
  /*    tt_slot_init                                                       */
1314
  /*                                                                       */
1315
  /*                                                          */
1316
  /*    Initialize a new slot object.                                      */
1317
  /*                                                                       */
1318
  /*                                                                */
1319
  /*    slot :: A handle to the slot object.                               */
1320
  /*                                                                       */
1321
  /*                                                               */
1322
  /*    FreeType error code.  0 means success.                             */
1323
  /*                                                                       */
1324
  FT_LOCAL_DEF( FT_Error )
1325
  tt_slot_init( FT_GlyphSlot  slot )
1326
  {
1327
    return FT_GlyphLoader_CreateExtra( slot->internal->loader );
1328
  }
1329
 
1330
 
1331
/* END */