:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / freetype / src / truetype / ttobjs.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ttobjs.c                                                               */
4 /*                                                                         */
5 /*    Objects manager (body).                                              */
6 /*                                                                         */
7 /*  Copyright 1996-2000 by                                                 */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17
18
19 #include <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftcalc.h>
21 #include <freetype/internal/ftstream.h>
22 #include <freetype/ttnameid.h>
23 #include <freetype/tttags.h>
24
25 #include <freetype/internal/sfnt.h>
26 #include <freetype/internal/psnames.h>
27
28
29 #ifdef FT_FLAT_COMPILE
30
31 #include "ttgload.h"
32 #include "ttpload.h"
33
34 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
35 #include "ttinterp.h"
36 #endif
37
38 #else /* FT_FLAT_COMPILE */
39
40 #include <freetype/src/truetype/ttgload.h>
41 #include <freetype/src/truetype/ttpload.h>
42
43 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
44 #include <freetype/src/truetype/ttinterp.h>
45 #endif
46
47 #endif /* FT_FLAT_COMPILE */
48
49
50 #include <freetype/internal/tterrors.h>
51
52
53
54   /*************************************************************************/
55   /*                                                                       */
56   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
57   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
58   /* messages during execution.                                            */
59   /*                                                                       */
60 #undef  FT_COMPONENT
61 #define FT_COMPONENT  trace_ttobjs
62
63
64   /*************************************************************************/
65   /*                                                                       */
66   /*                       GLYPH ZONE FUNCTIONS                            */
67   /*                                                                       */
68   /*************************************************************************/
69
70   /*************************************************************************/
71   /*                                                                       */
72   /* <Function>                                                            */
73   /*    TT_Done_GlyphZone                                                  */
74   /*                                                                       */
75   /* <Description>                                                         */
76   /*    Deallocates a glyph zone.                                          */
77   /*                                                                       */
78   /* <Input>                                                               */
79   /*    zone :: A pointer to the target glyph zone.                        */
80   /*                                                                       */
81   LOCAL_FUNC
82   void  TT_Done_GlyphZone( TT_GlyphZone*  zone )
83   {
84     FT_Memory  memory = zone->memory;
85
86
87     FREE( zone->contours );
88     FREE( zone->tags );
89     FREE( zone->cur );
90     FREE( zone->org );
91
92     zone->max_points   = zone->n_points   = 0;
93     zone->max_contours = zone->n_contours = 0;
94   }
95
96
97   /*************************************************************************/
98   /*                                                                       */
99   /* <Function>                                                            */
100   /*    TT_New_GlyphZone                                                   */
101   /*                                                                       */
102   /* <Description>                                                         */
103   /*    Allocates a new glyph zone.                                        */
104   /*                                                                       */
105   /* <Input>                                                               */
106   /*    memory      :: A handle to the current memory object.              */
107   /*                                                                       */
108   /*    maxPoints   :: The capacity of glyph zone in points.               */
109   /*                                                                       */
110   /*    maxContours :: The capacity of glyph zone in contours.             */
111   /*                                                                       */
112   /* <Output>                                                              */
113   /*    zone        :: A pointer to the target glyph zone record.          */
114   /*                                                                       */
115   /* <Return>                                                              */
116   /*    FreeType error code.  0 means success.                             */
117   /*                                                                       */
118   LOCAL_FUNC
119   FT_Error TT_New_GlyphZone( FT_Memory      memory,
120                              FT_UShort      maxPoints,
121                              FT_Short       maxContours,
122                              TT_GlyphZone*  zone )
123   {
124     FT_Error  error;
125
126
127     if ( maxPoints > 0 )
128       maxPoints += 2;
129
130     MEM_Set( zone, 0, sizeof ( *zone ) );
131     zone->memory = memory;
132
133     if ( ALLOC_ARRAY( zone->org,      maxPoints * 2, FT_F26Dot6 ) ||
134          ALLOC_ARRAY( zone->cur,      maxPoints * 2, FT_F26Dot6 ) ||
135          ALLOC_ARRAY( zone->tags,     maxPoints,     FT_Byte    ) ||
136          ALLOC_ARRAY( zone->contours, maxContours,   FT_UShort  ) )
137     {
138       TT_Done_GlyphZone( zone );
139     }
140
141     return error;
142   }
143
144
145   /*************************************************************************/
146   /*                                                                       */
147   /* <Function>                                                            */
148   /*    TT_Init_Face                                                       */
149   /*                                                                       */
150   /* <Description>                                                         */
151   /*    Initializes a given TrueType face object.                          */
152   /*                                                                       */
153   /* <Input>                                                               */
154   /*    stream     :: The source font stream.                              */
155   /*                                                                       */
156   /*    face_index :: The index of the font face in the resource.          */
157   /*                                                                       */
158   /*    num_params :: Number of additional generic parameters.  Ignored.   */
159   /*                                                                       */
160   /*    params     :: Additional generic parameters.  Ignored.             */
161   /*                                                                       */
162   /* <InOut>                                                               */
163   /*    face       :: The newly built face object.                         */
164   /*                                                                       */
165   /* <Return>                                                              */
166   /*    FreeType error code.  0 means success.                             */
167   /*                                                                       */
168   LOCAL_DEF
169   FT_Error  TT_Init_Face( FT_Stream      stream,
170                           TT_Face        face,
171                           FT_Int         face_index,
172                           FT_Int         num_params,
173                           FT_Parameter*  params )
174   {
175     FT_Error         error;
176     FT_Library       library;
177     SFNT_Interface*  sfnt;
178
179
180     library = face->root.driver->root.library;
181     sfnt    = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" );
182     if ( !sfnt )
183       goto Bad_Format;
184
185     /* create input stream from resource */
186     if ( FILE_Seek( 0 ) )
187       goto Exit;
188
189     /* check that we have a valid TrueType file */
190     error = sfnt->init_face( stream, face, face_index, num_params, params );
191     if ( error )
192       goto Exit;
193
194     /* We must also be able to accept Mac/GX fonts, as well as OT ones */
195     if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
196          face->format_tag != TTAG_true   )     /* Mac fonts */
197     {
198       FT_TRACE2(( "[not a valid TTF font]\n" ));
199       goto Bad_Format;
200     }
201
202     /* If we are performing a simple font format check, exit immediately */
203     if ( face_index < 0 )
204       return TT_Err_Ok;
205
206     /* Load font directory */
207     error = sfnt->load_face( stream, face, face_index, num_params, params );
208     if ( error )
209       goto Exit;
210
211     error = TT_Load_Locations( face, stream ) ||
212             TT_Load_CVT      ( face, stream ) ||
213             TT_Load_Programs ( face, stream );
214
215     /* initialize standard glyph loading routines */
216     TT_Init_Glyph_Loading( face );
217
218   Exit:
219     return error;
220
221   Bad_Format:
222     error = FT_Err_Unknown_File_Format;
223     goto Exit;
224   }
225
226
227   /*************************************************************************/
228   /*                                                                       */
229   /* <Function>                                                            */
230   /*    TT_Done_Face                                                       */
231   /*                                                                       */
232   /* <Description>                                                         */
233   /*    Finalizes a given face object.                                     */
234   /*                                                                       */
235   /* <Input>                                                               */
236   /*    face :: A pointer to the face object to destroy.                   */
237   /*                                                                       */
238   LOCAL_DEF
239   void  TT_Done_Face( TT_Face  face )
240   {
241     FT_Memory  memory = face->root.memory;
242     FT_Stream  stream = face->root.stream;
243
244     SFNT_Interface*  sfnt = (SFNT_Interface*)face->sfnt;
245
246
247     /* for `extended TrueType formats' (i.e. compressed versions) */
248     if ( face->extra.finalizer )
249       face->extra.finalizer( face->extra.data );
250
251     if ( sfnt )
252       sfnt->done_face( face );
253
254     /* freeing the locations table */
255     FREE( face->glyph_locations );
256     face->num_locations = 0;
257
258     /* freeing the CVT */
259     FREE( face->cvt );
260     face->cvt_size = 0;
261
262     /* freeing the programs */
263     RELEASE_Frame( face->font_program );
264     RELEASE_Frame( face->cvt_program );
265     face->font_program_size = 0;
266     face->cvt_program_size  = 0;
267   }
268
269
270   /*************************************************************************/
271   /*                                                                       */
272   /*                           SIZE  FUNCTIONS                             */
273   /*                                                                       */
274   /*************************************************************************/
275
276
277   /*************************************************************************/
278   /*                                                                       */
279   /* <Function>                                                            */
280   /*    TT_Init_Size                                                       */
281   /*                                                                       */
282   /* <Description>                                                         */
283   /*    Initializes a new TrueType size object.                            */
284   /*                                                                       */
285   /* <InOut>                                                               */
286   /*    size :: A handle to the size object.                               */
287   /*                                                                       */
288   /* <Return>                                                              */
289   /*    FreeType error code.  0 means success.                             */
290   /*                                                                       */
291   LOCAL_DEF
292   FT_Error  TT_Init_Size( TT_Size  size )
293   {
294     FT_Error  error = TT_Err_Ok;
295
296
297 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
298
299     TT_Face    face   = (TT_Face)size->root.face;
300     FT_Memory  memory = face->root.memory;
301     FT_Int     i;
302
303     TT_ExecContext  exec;
304     FT_UShort       n_twilight;
305     TT_MaxProfile*  maxp = &face->max_profile;
306
307
308     size->ttmetrics.valid = FALSE;
309
310     size->max_function_defs    = maxp->maxFunctionDefs;
311     size->max_instruction_defs = maxp->maxInstructionDefs;
312
313     size->num_function_defs    = 0;
314     size->num_instruction_defs = 0;
315
316     size->max_func = 0;
317     size->max_ins  = 0;
318
319     size->cvt_size     = face->cvt_size;
320     size->storage_size = maxp->maxStorage;
321
322     /* Set default metrics */
323     {
324       FT_Size_Metrics*  metrics  = &size->root.metrics;
325       TT_Size_Metrics*  metrics2 = &size->ttmetrics;
326
327
328       metrics->x_ppem = 0;
329       metrics->y_ppem = 0;
330
331       metrics2->rotated   = FALSE;
332       metrics2->stretched = FALSE;
333
334       /* set default compensation (all 0) */
335       for ( i = 0; i < 4; i++ )
336         metrics2->compensations[i] = 0;
337     }
338
339     /* allocate function defs, instruction defs, cvt, and storage area */
340     if ( ALLOC_ARRAY( size->function_defs,
341                       size->max_function_defs,
342                       TT_DefRecord )                ||
343
344          ALLOC_ARRAY( size->instruction_defs,
345                       size->max_instruction_defs,
346                       TT_DefRecord )                ||
347
348          ALLOC_ARRAY( size->cvt,
349                       size->cvt_size, FT_Long )     ||
350
351          ALLOC_ARRAY( size->storage,
352                       size->storage_size, FT_Long ) )
353
354       goto Fail_Memory;
355
356     /* reserve twilight zone */
357     n_twilight = maxp->maxTwilightPoints;
358     error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
359     if ( error )
360       goto Fail_Memory;
361
362     size->twilight.n_points = n_twilight;
363
364     /* set `face->interpreter' according to the debug hook present */
365     {
366       FT_Library  library = face->root.driver->root.library;
367
368
369       face->interpreter = (TT_Interpreter)
370                             library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
371       if ( !face->interpreter )
372         face->interpreter = (TT_Interpreter)TT_RunIns;
373     }
374
375     /* Fine, now execute the font program! */
376     exec = size->context;
377     /* size objects used during debugging have their own context */
378     if ( !size->debug )
379       exec = TT_New_Context( face );
380
381     if ( !exec )
382     {
383       error = TT_Err_Could_Not_Find_Context;
384       goto Fail_Memory;
385     }
386
387     size->GS = tt_default_graphics_state;
388     TT_Load_Context( exec, face, size );
389
390     exec->callTop   = 0;
391     exec->top       = 0;
392
393     exec->period    = 64;
394     exec->phase     = 0;
395     exec->threshold = 0;
396
397     {
398       FT_Size_Metrics*  metrics    = &exec->metrics;
399       TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;
400
401
402       metrics->x_ppem   = 0;
403       metrics->y_ppem   = 0;
404       metrics->x_scale  = 0;
405       metrics->y_scale  = 0;
406
407       tt_metrics->ppem  = 0;
408       tt_metrics->scale = 0;
409       tt_metrics->ratio = 0x10000L;
410     }
411
412     exec->instruction_trap = FALSE;
413
414     exec->cvtSize = size->cvt_size;
415     exec->cvt     = size->cvt;
416
417     exec->F_dot_P = 0x10000L;
418
419     /* allow font program execution */
420     TT_Set_CodeRange( exec,
421                       tt_coderange_font,
422                       face->font_program,
423                       face->font_program_size );
424
425     /* disable CVT and glyph programs coderange */
426     TT_Clear_CodeRange( exec, tt_coderange_cvt );
427     TT_Clear_CodeRange( exec, tt_coderange_glyph );
428
429     if ( face->font_program_size > 0 )
430     {
431       error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
432       if ( !error )
433         error = face->interpreter( exec );
434
435       if ( error )
436         goto Fail_Exec;
437     }
438     else
439       error = TT_Err_Ok;
440
441     TT_Save_Context( exec, size );
442
443     if ( !size->debug )
444       TT_Done_Context( exec );
445
446 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
447
448     size->ttmetrics.valid = FALSE;
449     return error;
450
451 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
452
453   Fail_Exec:
454     if ( !size->debug )
455       TT_Done_Context( exec );
456
457   Fail_Memory:
458
459 #endif
460
461     TT_Done_Size( size );
462     return error;
463   }
464
465
466   /*************************************************************************/
467   /*                                                                       */
468   /* <Function>                                                            */
469   /*    TT_Done_Size                                                       */
470   /*                                                                       */
471   /* <Description>                                                         */
472   /*    The TrueType size object finalizer.                                */
473   /*                                                                       */
474   /* <Input>                                                               */
475   /*    size :: A handle to the target size object.                        */
476   /*                                                                       */
477   LOCAL_FUNC
478   void  TT_Done_Size( TT_Size  size )
479   {
480
481 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
482
483     FT_Memory  memory = size->root.face->memory;
484
485
486     if ( size->debug )
487     {
488       /* the debug context must be deleted by the debugger itself */
489       size->context = NULL;
490       size->debug   = FALSE;
491     }
492
493     FREE( size->cvt );
494     size->cvt_size = 0;
495
496     /* free storage area */
497     FREE( size->storage );
498     size->storage_size = 0;
499
500     /* twilight zone */
501     TT_Done_GlyphZone( &size->twilight );
502
503     FREE( size->function_defs );
504     FREE( size->instruction_defs );
505
506     size->num_function_defs    = 0;
507     size->max_function_defs    = 0;
508     size->num_instruction_defs = 0;
509     size->max_instruction_defs = 0;
510
511     size->max_func = 0;
512     size->max_ins  = 0;
513
514 #endif
515
516     size->ttmetrics.valid = FALSE;
517   }
518
519
520   /*************************************************************************/
521   /*                                                                       */
522   /* <Function>                                                            */
523   /*    TT_Reset_Size                                                      */
524   /*                                                                       */
525   /* <Description>                                                         */
526   /*    Resets a TrueType size when resolutions and character dimensions   */
527   /*    have been changed.                                                 */
528   /*                                                                       */
529   /* <Input>                                                               */
530   /*    size :: A handle to the target size object.                        */
531   /*                                                                       */
532   LOCAL_DEF
533   FT_Error  TT_Reset_Size( TT_Size  size )
534   {
535     TT_Face   face;
536     FT_Error  error = TT_Err_Ok;
537
538     FT_Size_Metrics*  metrics;
539
540
541     if ( size->ttmetrics.valid )
542       return TT_Err_Ok;
543
544     face = (TT_Face)size->root.face;
545
546     metrics = &size->root.metrics;
547
548     if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
549       return TT_Err_Invalid_PPem;
550
551     /* compute new transformation */
552     if ( metrics->x_ppem >= metrics->y_ppem )
553     {
554       size->ttmetrics.scale   = metrics->x_scale;
555       size->ttmetrics.ppem    = metrics->x_ppem;
556       size->ttmetrics.x_ratio = 0x10000L;
557       size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
558                                            0x10000L,
559                                            metrics->x_ppem );
560     }
561     else
562     {
563       size->ttmetrics.scale   = metrics->y_scale;
564       size->ttmetrics.ppem    = metrics->y_ppem;
565       size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
566                                            0x10000L,
567                                            metrics->y_ppem );
568       size->ttmetrics.y_ratio = 0x10000L;
569     }
570
571     /* Compute root ascender, descender, test height, and max_advance */
572     metrics->ascender    = ( FT_MulFix( face->root.ascender,
573                                           metrics->y_scale ) + 32 ) & -64;
574     metrics->descender   = ( FT_MulFix( face->root.descender,
575                                           metrics->y_scale ) + 32 ) & -64;
576     metrics->height      = ( FT_MulFix( face->root.height,
577                                           metrics->y_scale ) + 32 ) & -64;
578     metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
579                                           metrics->x_scale ) + 32 ) & -64;
580
581 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
582
583     {
584       TT_ExecContext  exec;
585       FT_UInt         i, j;
586
587
588       /* Scale the cvt values to the new ppem.          */
589       /* We use by default the y ppem to scale the CVT. */
590       for ( i = 0; i < size->cvt_size; i++ )
591         size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
592
593       /* All twilight points are originally zero */
594       for ( j = 0; j < size->twilight.n_points; j++ )
595       {
596         size->twilight.org[j].x = 0;
597         size->twilight.org[j].y = 0;
598         size->twilight.cur[j].x = 0;
599         size->twilight.cur[j].y = 0;
600       }
601
602       /* clear storage area */
603       for ( i = 0; i < size->storage_size; i++ )
604         size->storage[i] = 0;
605
606       size->GS = tt_default_graphics_state;
607
608       /* get execution context and run prep program */
609       if ( size->debug )
610         exec = size->context;
611       else
612         exec = TT_New_Context( face );
613       /* debugging instances have their own context */
614
615       if ( !exec )
616         return TT_Err_Could_Not_Find_Context;
617
618       TT_Load_Context( exec, face, size );
619
620       TT_Set_CodeRange( exec,
621                         tt_coderange_cvt,
622                         face->cvt_program,
623                         face->cvt_program_size );
624
625       TT_Clear_CodeRange( exec, tt_coderange_glyph );
626
627       exec->instruction_trap = FALSE;
628
629       exec->top     = 0;
630       exec->callTop = 0;
631
632       if ( face->cvt_program_size > 0 )
633       {
634         error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
635         if ( error )
636           goto End;
637
638         if ( !size->debug )
639           error = face->interpreter( exec );
640       }
641       else
642         error = TT_Err_Ok;
643
644       size->GS = exec->GS;
645       /* save default graphics state */
646
647     End:
648       TT_Save_Context( exec, size );
649
650       if ( !size->debug )
651         TT_Done_Context( exec );
652       /* debugging instances keep their context */
653     }
654
655 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
656
657     if ( !error )
658       size->ttmetrics.valid = TRUE;
659
660     return error;
661   }
662
663
664   /*************************************************************************/
665   /*                                                                       */
666   /* <Function>                                                            */
667   /*    TT_Init_Driver                                                     */
668   /*                                                                       */
669   /* <Description>                                                         */
670   /*    Initializes a given TrueType driver object.                        */
671   /*                                                                       */
672   /* <Input>                                                               */
673   /*    driver :: A handle to the target driver object.                    */
674   /*                                                                       */
675   /* <Return>                                                              */
676   /*    FreeType error code.  0 means success.                             */
677   /*                                                                       */
678   LOCAL_FUNC
679   FT_Error  TT_Init_Driver( TT_Driver  driver )
680   {
681     FT_Error  error;
682
683
684     /* set `extra' in glyph loader */
685     error = FT_GlyphLoader_Create_Extra( FT_DRIVER( driver )->glyph_loader );
686
687     /* init extension registry if needed */
688
689 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
690     if ( !error )
691       return TT_Init_Extensions( driver );
692 #endif
693
694     return error;
695   }
696
697
698   /*************************************************************************/
699   /*                                                                       */
700   /* <Function>                                                            */
701   /*    TT_Done_Driver                                                     */
702   /*                                                                       */
703   /* <Description>                                                         */
704   /*    Finalizes a given TrueType driver.                                 */
705   /*                                                                       */
706   /* <Input>                                                               */
707   /*    driver :: A handle to the target TrueType driver.                  */
708   /*                                                                       */
709   LOCAL_FUNC
710   void  TT_Done_Driver( TT_Driver  driver )
711   {
712     /* destroy extensions registry if needed */
713
714 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
715
716     TT_Done_Extensions( driver );
717
718 #endif
719
720 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
721
722     /* destroy the execution context */
723     if ( driver->context )
724     {
725       TT_Destroy_Context( driver->context, driver->root.root.memory );
726       driver->context = NULL;
727     }
728
729 #endif
730
731   }
732
733
734 /* END */