ttobjs.c 30.2 KB
Newer Older
David Turner's avatar
David Turner committed
1
2
3
4
5
6
/***************************************************************************/
/*                                                                         */
/*  ttobjs.c                                                               */
/*                                                                         */
/*    Objects manager (body).                                              */
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
7
/*  Copyright 1996-2001, 2002 by                                           */
David Turner's avatar
David Turner committed
8
9
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
10
11
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
David Turner's avatar
David Turner committed
12
13
14
15
16
17
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
18

19
20
21
22
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
23
#include FT_TRUETYPE_IDS_H
24
25
26
27
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_POSTSCRIPT_NAMES_H

28
29
#include "ttgload.h"
#include "ttpload.h"
Werner Lemberg's avatar
   
Werner Lemberg committed
30

31
32
#include "tterrors.h"

33
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
34
#include "ttinterp.h"
35
36
#endif

Werner Lemberg's avatar
   
Werner Lemberg committed
37
38
39
40
41
42
43

  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  /* messages during execution.                                            */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
44
45
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_ttobjs
David Turner's avatar
David Turner committed
46
47


Werner Lemberg's avatar
   
Werner Lemberg committed
48
49
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
50
51
52
53
54
55
  /*************************************************************************/
  /*                                                                       */
  /*                       GLYPH ZONE FUNCTIONS                            */
  /*                                                                       */
  /*************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
56

57
58
59
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
60
  /*    tt_glyphzone_done                                                  */
61
62
63
64
65
66
67
  /*                                                                       */
  /* <Description>                                                         */
  /*    Deallocates a glyph zone.                                          */
  /*                                                                       */
  /* <Input>                                                               */
  /*    zone :: A pointer to the target glyph zone.                        */
  /*                                                                       */
68
  FT_LOCAL_DEF( void )
69
  tt_glyphzone_done( TT_GlyphZone  zone )
70
71
72
  {
    FT_Memory  memory = zone->memory;

Werner Lemberg's avatar
   
Werner Lemberg committed
73

74
75
76
77
    FT_FREE( zone->contours );
    FT_FREE( zone->tags );
    FT_FREE( zone->cur );
    FT_FREE( zone->org );
78
79
80
81
82
83
84
85
86

    zone->max_points   = zone->n_points   = 0;
    zone->max_contours = zone->n_contours = 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
87
  /*    tt_glyphzone_new                                                   */
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  /*                                                                       */
  /* <Description>                                                         */
  /*    Allocates a new glyph zone.                                        */
  /*                                                                       */
  /* <Input>                                                               */
  /*    memory      :: A handle to the current memory object.              */
  /*                                                                       */
  /*    maxPoints   :: The capacity of glyph zone in points.               */
  /*                                                                       */
  /*    maxContours :: The capacity of glyph zone in contours.             */
  /*                                                                       */
  /* <Output>                                                              */
  /*    zone        :: A pointer to the target glyph zone record.          */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
105
  FT_LOCAL_DEF( FT_Error )
106
  tt_glyphzone_new( FT_Memory     memory,
Werner Lemberg's avatar
   
Werner Lemberg committed
107
108
109
                    FT_UShort     maxPoints,
                    FT_Short      maxContours,
                    TT_GlyphZone  zone )
110
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
111
112
    FT_Error  error;

113
114
115
116

    if ( maxPoints > 0 )
      maxPoints += 2;

Werner Lemberg's avatar
   
Werner Lemberg committed
117
    FT_MEM_ZERO( zone, sizeof ( *zone ) );
118
119
    zone->memory = memory;

120
121
122
123
    if ( FT_NEW_ARRAY( zone->org,      maxPoints * 2 ) ||
         FT_NEW_ARRAY( zone->cur,      maxPoints * 2 ) ||
         FT_NEW_ARRAY( zone->tags,     maxPoints     ) ||
         FT_NEW_ARRAY( zone->contours, maxContours   ) )
124
    {
125
      tt_glyphzone_done( zone );
126
127
128
129
    }

    return error;
  }
Werner Lemberg's avatar
   
Werner Lemberg committed
130
131
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

132

David Turner's avatar
David Turner committed
133
134
135
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
136
  /*    tt_face_init                                                       */
David Turner's avatar
David Turner committed
137
138
139
140
141
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType face object.                          */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
142
143
  /*    stream     :: The source font stream.                              */
  /*                                                                       */
David Turner's avatar
David Turner committed
144
  /*    face_index :: The index of the font face in the resource.          */
Werner Lemberg's avatar
   
Werner Lemberg committed
145
146
147
148
149
150
  /*                                                                       */
  /*    num_params :: Number of additional generic parameters.  Ignored.   */
  /*                                                                       */
  /*    params     :: Additional generic parameters.  Ignored.             */
  /*                                                                       */
  /* <InOut>                                                               */
David Turner's avatar
David Turner committed
151
152
153
  /*    face       :: The newly built face object.                         */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
154
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
155
  /*                                                                       */
156
  FT_LOCAL_DEF( FT_Error )
157
  tt_face_init( FT_Stream      stream,
Werner Lemberg's avatar
   
Werner Lemberg committed
158
159
160
161
                TT_Face        face,
                FT_Int         face_index,
                FT_Int         num_params,
                FT_Parameter*  params )
David Turner's avatar
David Turner committed
162
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
163
164
    FT_Error      error;
    FT_Library    library;
165
    SFNT_Service  sfnt;
Werner Lemberg's avatar
   
Werner Lemberg committed
166

Werner Lemberg's avatar
   
Werner Lemberg committed
167

David Turner's avatar
David Turner committed
168
    library = face->root.driver->root.library;
169
    sfnt    = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
Werner Lemberg's avatar
   
Werner Lemberg committed
170
171
    if ( !sfnt )
      goto Bad_Format;
172

David Turner's avatar
David Turner committed
173
    /* create input stream from resource */
174
    if ( FT_STREAM_SEEK( 0 ) )
David Turner's avatar
David Turner committed
175
176
      goto Exit;

177
    /* check that we have a valid TrueType file */
178
    error = sfnt->init_face( stream, face, face_index, num_params, params );
Werner Lemberg's avatar
   
Werner Lemberg committed
179
180
    if ( error )
      goto Exit;
181

182
    /* We must also be able to accept Mac/GX fonts, as well as OT ones */
Werner Lemberg's avatar
   
Werner Lemberg committed
183
184
    if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
         face->format_tag != TTAG_true   )     /* Mac fonts */
185
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
186
      FT_TRACE2(( "[not a valid TTF font]\n" ));
187
      goto Bad_Format;
188
189
    }

Werner Lemberg's avatar
   
Werner Lemberg committed
190
    /* If we are performing a simple font format check, exit immediately */
David Turner's avatar
David Turner committed
191
192
193
    if ( face_index < 0 )
      return TT_Err_Ok;

194
195
    /* Load font directory */
    error = sfnt->load_face( stream, face, face_index, num_params, params );
Werner Lemberg's avatar
   
Werner Lemberg committed
196
197
    if ( error )
      goto Exit;
David Turner's avatar
David Turner committed
198

Werner Lemberg's avatar
   
Werner Lemberg committed
199
    if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
200
      {
Werner Lemberg's avatar
   
Werner Lemberg committed
201

202
#ifdef FT_CONFIG_OPTION_INCREMENTAL
Werner Lemberg's avatar
   
Werner Lemberg committed
203

204
        if ( !face->root.internal->incremental_interface )
205
          error = tt_face_load_loca( face, stream );
206
        if ( !error )
207
208
          error = tt_face_load_cvt      ( face, stream ) ||
                  tt_face_load_fpgm ( face, stream );
Werner Lemberg's avatar
   
Werner Lemberg committed
209

210
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
211

212
        if ( !error )
213
214
215
          error = tt_face_load_loca( face, stream ) ||
                  tt_face_load_cvt      ( face, stream ) ||
                  tt_face_load_fpgm ( face, stream );
Werner Lemberg's avatar
   
Werner Lemberg committed
216

217
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
218

219
      }
Werner Lemberg's avatar
   
Werner Lemberg committed
220

Werner Lemberg's avatar
   
Werner Lemberg committed
221
    /* initialize standard glyph loading routines */
222
223
    TT_Init_Glyph_Loading( face );

David Turner's avatar
David Turner committed
224
225
  Exit:
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
226

227
  Bad_Format:
Werner Lemberg's avatar
Werner Lemberg committed
228
    error = TT_Err_Unknown_File_Format;
229
    goto Exit;
David Turner's avatar
David Turner committed
230
231
232
233
234
235
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
236
  /*    tt_face_done                                                       */
David Turner's avatar
David Turner committed
237
238
239
240
241
242
243
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given face object.                                     */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face :: A pointer to the face object to destroy.                   */
  /*                                                                       */
244
  FT_LOCAL_DEF( void )
245
  tt_face_done( TT_Face  face )
David Turner's avatar
David Turner committed
246
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
247
248
    FT_Memory     memory = face->root.memory;
    FT_Stream     stream = face->root.stream;
David Turner's avatar
David Turner committed
249

Werner Lemberg's avatar
   
Werner Lemberg committed
250
    SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
251

Werner Lemberg's avatar
   
Werner Lemberg committed
252

Werner Lemberg's avatar
   
Werner Lemberg committed
253
254
    /* for `extended TrueType formats' (i.e. compressed versions) */
    if ( face->extra.finalizer )
255
      face->extra.finalizer( face->extra.data );
Werner Lemberg's avatar
   
Werner Lemberg committed
256
257
258

    if ( sfnt )
      sfnt->done_face( face );
David Turner's avatar
David Turner committed
259
260

    /* freeing the locations table */
261
    FT_FREE( face->glyph_locations );
David Turner's avatar
David Turner committed
262
263
264
    face->num_locations = 0;

    /* freeing the CVT */
265
    FT_FREE( face->cvt );
David Turner's avatar
David Turner committed
266
267
268
    face->cvt_size = 0;

    /* freeing the programs */
269
270
    FT_FRAME_RELEASE( face->font_program );
    FT_FRAME_RELEASE( face->cvt_program );
David Turner's avatar
David Turner committed
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    face->font_program_size = 0;
    face->cvt_program_size  = 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /*                           SIZE  FUNCTIONS                             */
  /*                                                                       */
  /*************************************************************************/


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
286
  /*    tt_size_init                                                       */
David Turner's avatar
David Turner committed
287
288
289
290
291
292
293
294
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a new TrueType size object.                            */
  /*                                                                       */
  /* <InOut>                                                               */
  /*    size :: A handle to the size object.                               */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
295
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
296
  /*                                                                       */
297
  FT_LOCAL_DEF( FT_Error )
298
  tt_size_init( TT_Size  size )
David Turner's avatar
David Turner committed
299
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
300
301
    FT_Error  error = TT_Err_Ok;

302

303
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
304

David Turner's avatar
David Turner committed
305
306
    TT_Face    face   = (TT_Face)size->root.face;
    FT_Memory  memory = face->root.memory;
307
    FT_Int     i;
David Turner's avatar
David Turner committed
308
309

    TT_ExecContext  exec;
310
    FT_UShort       n_twilight;
311
    TT_MaxProfile*  maxp = &face->max_profile;
David Turner's avatar
David Turner committed
312

Werner Lemberg's avatar
   
Werner Lemberg committed
313

David Turner's avatar
David Turner committed
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
    size->ttmetrics.valid = FALSE;

    size->max_function_defs    = maxp->maxFunctionDefs;
    size->max_instruction_defs = maxp->maxInstructionDefs;

    size->num_function_defs    = 0;
    size->num_instruction_defs = 0;

    size->max_func = 0;
    size->max_ins  = 0;

    size->cvt_size     = face->cvt_size;
    size->storage_size = maxp->maxStorage;

    /* Set default metrics */
    {
      FT_Size_Metrics*  metrics  = &size->root.metrics;
      TT_Size_Metrics*  metrics2 = &size->ttmetrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
333

David Turner's avatar
David Turner committed
334
335
336
337
338
339
340
341
342
343
344
      metrics->x_ppem = 0;
      metrics->y_ppem = 0;

      metrics2->rotated   = FALSE;
      metrics2->stretched = FALSE;

      /* set default compensation (all 0) */
      for ( i = 0; i < 4; i++ )
        metrics2->compensations[i] = 0;
    }

Werner Lemberg's avatar
   
Werner Lemberg committed
345
    /* allocate function defs, instruction defs, cvt, and storage area */
Werner Lemberg's avatar
   
Werner Lemberg committed
346
    if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||
347
         FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
Werner Lemberg's avatar
   
Werner Lemberg committed
348
349
         FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
         FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
David Turner's avatar
David Turner committed
350
351
352
353
354

      goto Fail_Memory;

    /* reserve twilight zone */
    n_twilight = maxp->maxTwilightPoints;
355
    error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
David Turner's avatar
David Turner committed
356
357
358
359
360
361
362
    if ( error )
      goto Fail_Memory;

    size->twilight.n_points = n_twilight;

    /* set `face->interpreter' according to the debug hook present */
    {
David Turner's avatar
David Turner committed
363
      FT_Library  library = face->root.driver->root.library;
364

Werner Lemberg's avatar
   
Werner Lemberg committed
365

David Turner's avatar
David Turner committed
366
      face->interpreter = (TT_Interpreter)
Werner Lemberg's avatar
   
Werner Lemberg committed
367
368
                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
      if ( !face->interpreter )
David Turner's avatar
David Turner committed
369
370
371
372
373
374
        face->interpreter = (TT_Interpreter)TT_RunIns;
    }

    /* Fine, now execute the font program! */
    exec = size->context;
    /* size objects used during debugging have their own context */
Werner Lemberg's avatar
   
Werner Lemberg committed
375
376
    if ( !size->debug )
      exec = TT_New_Context( face );
David Turner's avatar
David Turner committed
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

    if ( !exec )
    {
      error = TT_Err_Could_Not_Find_Context;
      goto Fail_Memory;
    }

    size->GS = tt_default_graphics_state;
    TT_Load_Context( exec, face, size );

    exec->callTop   = 0;
    exec->top       = 0;

    exec->period    = 64;
    exec->phase     = 0;
    exec->threshold = 0;

    {
      FT_Size_Metrics*  metrics    = &exec->metrics;
      TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;


Werner Lemberg's avatar
   
Werner Lemberg committed
399
400
401
402
      metrics->x_ppem   = 0;
      metrics->y_ppem   = 0;
      metrics->x_scale  = 0;
      metrics->y_scale  = 0;
David Turner's avatar
David Turner committed
403

Werner Lemberg's avatar
   
Werner Lemberg committed
404
405
406
      tt_metrics->ppem  = 0;
      tt_metrics->scale = 0;
      tt_metrics->ratio = 0x10000L;
David Turner's avatar
David Turner committed
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    }

    exec->instruction_trap = FALSE;

    exec->cvtSize = size->cvt_size;
    exec->cvt     = size->cvt;

    exec->F_dot_P = 0x10000L;

    /* allow font program execution */
    TT_Set_CodeRange( exec,
                      tt_coderange_font,
                      face->font_program,
                      face->font_program_size );

    /* disable CVT and glyph programs coderange */
    TT_Clear_CodeRange( exec, tt_coderange_cvt );
    TT_Clear_CodeRange( exec, tt_coderange_glyph );

    if ( face->font_program_size > 0 )
    {
      error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
      if ( !error )
        error = face->interpreter( exec );

      if ( error )
        goto Fail_Exec;
    }
    else
      error = TT_Err_Ok;

    TT_Save_Context( exec, size );

    if ( !size->debug )
      TT_Done_Context( exec );

443
444
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
445
446
447
    size->ttmetrics.valid = FALSE;
    return error;

448
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
449

David Turner's avatar
David Turner committed
450
451
452
453
454
  Fail_Exec:
    if ( !size->debug )
      TT_Done_Context( exec );

  Fail_Memory:
Werner Lemberg's avatar
   
Werner Lemberg committed
455

456
    tt_size_done( size );
David Turner's avatar
David Turner committed
457
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
458
459
460

#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
461
462
463
464
465
466
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
467
  /*    tt_size_done                                                       */
David Turner's avatar
David Turner committed
468
469
470
471
472
473
474
  /*                                                                       */
  /* <Description>                                                         */
  /*    The TrueType size object finalizer.                                */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
475
  FT_LOCAL_DEF( void )
476
  tt_size_done( TT_Size  size )
David Turner's avatar
David Turner committed
477
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
478

479
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
480

David Turner's avatar
David Turner committed
481
482
    FT_Memory  memory = size->root.face->memory;

Werner Lemberg's avatar
   
Werner Lemberg committed
483

David Turner's avatar
David Turner committed
484
485
486
487
488
489
490
    if ( size->debug )
    {
      /* the debug context must be deleted by the debugger itself */
      size->context = NULL;
      size->debug   = FALSE;
    }

491
    FT_FREE( size->cvt );
David Turner's avatar
David Turner committed
492
493
494
    size->cvt_size = 0;

    /* free storage area */
495
    FT_FREE( size->storage );
David Turner's avatar
David Turner committed
496
497
498
    size->storage_size = 0;

    /* twilight zone */
499
    tt_glyphzone_done( &size->twilight );
David Turner's avatar
David Turner committed
500

501
502
    FT_FREE( size->function_defs );
    FT_FREE( size->instruction_defs );
Werner Lemberg's avatar
   
Werner Lemberg committed
503

David Turner's avatar
David Turner committed
504
505
506
507
508
509
510
    size->num_function_defs    = 0;
    size->max_function_defs    = 0;
    size->num_instruction_defs = 0;
    size->max_instruction_defs = 0;

    size->max_func = 0;
    size->max_ins  = 0;
Werner Lemberg's avatar
   
Werner Lemberg committed
511

512
#endif
David Turner's avatar
David Turner committed
513
514
515
516
517
518
519
520

    size->ttmetrics.valid = FALSE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
521
  /*    Reset_Outline_Size                                                 */
David Turner's avatar
David Turner committed
522
523
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
524
525
  /*    Resets a TrueType outline size when resolutions and character      */
  /*    dimensions have been changed.                                      */
David Turner's avatar
David Turner committed
526
527
528
529
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
530
531
  static FT_Error
  Reset_Outline_Size( TT_Size  size )
David Turner's avatar
David Turner committed
532
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
533
534
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;
David Turner's avatar
David Turner committed
535
536
537

    FT_Size_Metrics*  metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
538

David Turner's avatar
David Turner committed
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
    if ( size->ttmetrics.valid )
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;

    metrics = &size->root.metrics;

    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
      return TT_Err_Invalid_PPem;

    /* compute new transformation */
    if ( metrics->x_ppem >= metrics->y_ppem )
    {
      size->ttmetrics.scale   = metrics->x_scale;
      size->ttmetrics.ppem    = metrics->x_ppem;
Werner Lemberg's avatar
   
Werner Lemberg committed
554
      size->ttmetrics.x_ratio = 0x10000L;
David Turner's avatar
David Turner committed
555
556
557
558
559
560
561
562
563
564
565
      size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
                                           0x10000L,
                                           metrics->x_ppem );
    }
    else
    {
      size->ttmetrics.scale   = metrics->y_scale;
      size->ttmetrics.ppem    = metrics->y_ppem;
      size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
                                           0x10000L,
                                           metrics->y_ppem );
Werner Lemberg's avatar
   
Werner Lemberg committed
566
      size->ttmetrics.y_ratio = 0x10000L;
David Turner's avatar
David Turner committed
567
568
569
    }

    /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg's avatar
   
Werner Lemberg committed
570
571
572
573
574
575
576
577
    metrics->ascender    = ( FT_MulFix( face->root.ascender,
                                        metrics->y_scale ) + 32 ) & -64;
    metrics->descender   = ( FT_MulFix( face->root.descender,
                                        metrics->y_scale ) + 32 ) & -64;
    metrics->height      = ( FT_MulFix( face->root.height,
                                        metrics->y_scale ) + 32 ) & -64;
    metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
                                        metrics->x_scale ) + 32 ) & -64;
David Turner's avatar
David Turner committed
578

579
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
580
    /* set to `invalid' by default */
Werner Lemberg's avatar
   
Werner Lemberg committed
581
    size->strike_index = 0xFFFFU;
582
583
#endif

584
585
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
586
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
587
588
      TT_ExecContext  exec;
      FT_UInt         i, j;
589

Werner Lemberg's avatar
   
Werner Lemberg committed
590

591
592
593
594
      /* Scale the cvt values to the new ppem.          */
      /* We use by default the y ppem to scale the CVT. */
      for ( i = 0; i < size->cvt_size; i++ )
        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
595

596
      /* All twilight points are originally zero */
597
      for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ )
598
599
600
601
602
603
      {
        size->twilight.org[j].x = 0;
        size->twilight.org[j].y = 0;
        size->twilight.cur[j].x = 0;
        size->twilight.cur[j].y = 0;
      }
604

605
      /* clear storage area */
606
      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
607
        size->storage[i] = 0;
608

609
      size->GS = tt_default_graphics_state;
610

611
612
613
614
615
616
      /* get execution context and run prep program */
      if ( size->debug )
        exec = size->context;
      else
        exec = TT_New_Context( face );
      /* debugging instances have their own context */
617

618
619
      if ( !exec )
        return TT_Err_Could_Not_Find_Context;
620

621
      TT_Load_Context( exec, face, size );
622

623
624
625
626
      TT_Set_CodeRange( exec,
                        tt_coderange_cvt,
                        face->cvt_program,
                        face->cvt_program_size );
627

628
      TT_Clear_CodeRange( exec, tt_coderange_glyph );
629

630
      exec->instruction_trap = FALSE;
631

632
633
      exec->top     = 0;
      exec->callTop = 0;
634

635
636
637
638
      if ( face->cvt_program_size > 0 )
      {
        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
        if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
639
          goto End;
640

641
642
643
644
645
        if ( !size->debug )
          error = face->interpreter( exec );
      }
      else
        error = TT_Err_Ok;
646

647
648
      size->GS = exec->GS;
      /* save default graphics state */
649

Werner Lemberg's avatar
   
Werner Lemberg committed
650
    End:
651
      TT_Save_Context( exec, size );
652

David Turner's avatar
David Turner committed
653
      if ( !size->debug )
654
655
        TT_Done_Context( exec );
      /* debugging instances keep their context */
David Turner's avatar
David Turner committed
656
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
657

658
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turner's avatar
David Turner committed
659
660
661
662
663
664
665

    if ( !error )
      size->ttmetrics.valid = TRUE;

    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
666

667
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
668
669
670
671
672
673
674
675
676
677
678
679
680

  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Reset_SBit_Size                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Resets a TrueType sbit size when resolutions and character         */
  /*    dimensions have been changed.                                      */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
681
682
  static FT_Error
  Reset_SBit_Size( TT_Size  size )
683
684
685
686
687
688
689
  {
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;

    FT_ULong          strike_index;
    FT_Size_Metrics*  metrics;
    FT_Size_Metrics*  sbit_metrics;
Werner Lemberg's avatar
   
Werner Lemberg committed
690
    SFNT_Service      sfnt;
691

Werner Lemberg's avatar
   
Werner Lemberg committed
692

693
694
    metrics = &size->root.metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
695
    if ( size->strike_index != 0xFFFFU )
696
697
698
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;
699
    sfnt = (SFNT_Service)face->sfnt;
700
701
702
703

    sbit_metrics = &size->strike_metrics;

    error = sfnt->set_sbit_strike(face,
Werner Lemberg's avatar
   
Werner Lemberg committed
704
705
                                  metrics->x_ppem, metrics->y_ppem,
                                  &strike_index);
706

Werner Lemberg's avatar
   
Werner Lemberg committed
707
    if ( !error )
708
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
709
      TT_SBit_Strike  strike = face->sbit_strikes + strike_index;
Werner Lemberg's avatar
   
Werner Lemberg committed
710
711


Werner Lemberg's avatar
   
Werner Lemberg committed
712
713
      sbit_metrics->x_ppem      = metrics->x_ppem;
      sbit_metrics->y_ppem      = metrics->y_ppem;
714
715
716
717
718
#if 0
      /*
       * sbit_metrics->?_scale
       * are not used now.
       */
Werner Lemberg's avatar
   
Werner Lemberg committed
719
720
      sbit_metrics->x_scale     = 1 << 16;
      sbit_metrics->y_scale     = 1 << 16;
721
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
722

Werner Lemberg's avatar
   
Werner Lemberg committed
723
724
      sbit_metrics->ascender    = strike->hori.ascender << 6;
      sbit_metrics->descender   = strike->hori.descender << 6;
Werner Lemberg's avatar
   
Werner Lemberg committed
725

726
      /* XXX: Is this correct? */
Werner Lemberg's avatar
   
Werner Lemberg committed
727
728
      sbit_metrics->height      = sbit_metrics->ascender -
                                  sbit_metrics->descender;
Werner Lemberg's avatar
   
Werner Lemberg committed
729

730
731
732
733
734
735
736
737
738
      /* XXX: Is this correct? */
      sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
                                    strike->hori.max_width     +
                                    strike->hori.min_advance_SB ) << 6;

      size->strike_index = strike_index;
    }
    else
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
739
      size->strike_index = 0xFFFFU;
Werner Lemberg's avatar
   
Werner Lemberg committed
740

741
742
743
744
745
746
747
748
749
750
      sbit_metrics->x_ppem      = 0;
      sbit_metrics->y_ppem      = 0;
      sbit_metrics->ascender    = 0;
      sbit_metrics->descender   = 0;
      sbit_metrics->height      = 0;
      sbit_metrics->max_advance = 0;
    }

    return error;
  }
Werner Lemberg's avatar
   
Werner Lemberg committed
751

752
753
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

Werner Lemberg's avatar
   
Werner Lemberg committed
754

755
756
757
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
758
  /*    tt_size_reset                                                      */
759
760
761
762
763
764
765
766
  /*                                                                       */
  /* <Description>                                                         */
  /*    Resets a TrueType size when resolutions and character dimensions   */
  /*    have been changed.                                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
767
  FT_LOCAL_DEF( FT_Error )
768
  tt_size_reset( TT_Size  size )
769
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
770
    FT_Face   face;
771
772
    FT_Error  error = TT_Err_Ok;

Werner Lemberg's avatar
   
Werner Lemberg committed
773

774
775
776
777
778
    face = size->root.face;

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
    {
      if ( !size->ttmetrics.valid )
Werner Lemberg's avatar
   
Werner Lemberg committed
779
        error = Reset_Outline_Size( size );
780
781

      if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
782
        return error;
783
784
785
    }

#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
786

787
788
    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
789
      if ( size->strike_index == 0xFFFFU )
790
791
        error = Reset_SBit_Size( size );

Werner Lemberg's avatar
   
Werner Lemberg committed
792
      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
793
        size->root.metrics = size->strike_metrics;
794
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
795
796
797
798

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
799
800
801
802
      return TT_Err_Ok;
    else
      return error;
  }
David Turner's avatar
David Turner committed
803

Werner Lemberg's avatar
   
Werner Lemberg committed
804

David Turner's avatar
David Turner committed
805
806
807
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
808
  /*    tt_driver_init                                                     */
David Turner's avatar
David Turner committed
809
810
811
812
813
814
815
816
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType driver object.                        */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target driver object.                    */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
817
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
818
  /*                                                                       */
819
  FT_LOCAL_DEF( FT_Error )
820
  tt_driver_init( TT_Driver  driver )
David Turner's avatar
David Turner committed
821
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
822
    FT_Error  error;
Werner Lemberg's avatar
   
Werner Lemberg committed
823

Werner Lemberg's avatar
   
Werner Lemberg committed
824
825

    /* set `extra' in glyph loader */
David Turner's avatar
David Turner committed
826
    error = FT_GlyphLoader_CreateExtra( FT_DRIVER( driver )->glyph_loader );
Werner Lemberg's avatar
   
Werner Lemberg committed
827

David Turner's avatar
David Turner committed
828
    return error;
David Turner's avatar
David Turner committed
829
830
831
832
833
834
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
835
  /*    tt_driver_done                                                     */
David Turner's avatar
David Turner committed
836
837
838
839
840
841
842
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given TrueType driver.                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target TrueType driver.                  */
  /*                                                                       */
843
  FT_LOCAL_DEF( void )
844
  tt_driver_done( TT_Driver  driver )
David Turner's avatar
David Turner committed
845
  {
846
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
847

David Turner's avatar
David Turner committed
848
849
850
    /* destroy the execution context */
    if ( driver->context )
    {
David Turner's avatar
David Turner committed
851
      TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turner's avatar
David Turner committed
852
853
      driver->context = NULL;
    }
854
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
855
    FT_UNUSED( driver );
856
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
857

David Turner's avatar
David Turner committed
858
859
860
861
  }


/* END */