contrib/OWB: add correct SDL dependency, fix compilers used
[AROS-Contrib.git] / freetype1 / lib / ttobjs.c
blob9ce11013ae8ebc821d23f68cdbcd8d921fbf456c
1 /*******************************************************************
3 * ttobjs.c 1.0
5 * Objects manager.
7 * Copyright 1996-1999 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
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.
16 ******************************************************************/
18 #include "ttobjs.h"
19 #include "ttfile.h"
20 #include "ttcalc.h"
21 #include "ttmemory.h"
22 #include "ttload.h"
23 #include "ttinterp.h"
24 #include "ttdebug.h"
27 /* Add extensions definition */
28 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
29 #include "ttextend.h"
30 #endif
32 /* Required by tracing mode */
33 #undef TT_COMPONENT
34 #define TT_COMPONENT trace_objs
36 /*******************************************************************
38 * Function : New_Context
40 * Description : Creates a new execution context for a given
41 * face object.
43 ******************************************************************/
45 LOCAL_FUNC
46 PExecution_Context New_Context( PFace face )
48 PEngine_Instance engine;
49 PExecution_Context exec;
52 if ( !face )
53 return NULL;
55 engine = face->engine;
56 CACHE_New( engine->objs_exec_cache, exec, face );
57 return exec;
61 /*******************************************************************
63 * Function : Done_Context
65 * Description : Discards an execution context.
67 ******************************************************************/
69 LOCAL_FUNC
70 TT_Error Done_Context( PExecution_Context exec )
72 PEngine_Instance engine;
75 if ( !exec )
76 return TT_Err_Ok;
78 engine = exec->face->engine;
79 return CACHE_Done( engine->objs_exec_cache, exec );
83 #if 0
85 /*******************************************************************
87 * Function : New_Instance
89 * Description : Creates a new instance for a given face object.
91 ******************************************************************/
93 LOCAL_FUNC
94 PInstance New_Instance( PFace face )
96 PInstance ins;
99 if ( !face )
100 return NULL;
102 CACHE_New( &face->instances, ins, face );
104 return ins;
108 /*******************************************************************
110 * Function : Done_Instance
112 * Description : Discards an instance.
114 ******************************************************************/
116 LOCAL_FUNC
117 TT_Error Done_Instance( PInstance instance )
119 return CACHE_Done( &instance->owner->instances, instance );
122 #endif
125 /*******************************************************************
127 * GLYPH ZONE FUNCTIONS *
130 *******************************************************************/
132 /*******************************************************************
134 * Function : New_Glyph_Zone
136 * Description : Allocates a new glyph zone
138 * Input : pts pointer to the target glyph zone record
139 * maxPoints capacity of glyph zone in points
140 * maxContours capacity of glyph zone in contours
142 * Return : Error code.
144 *****************************************************************/
146 static
147 TT_Error New_Glyph_Zone( PGlyph_Zone pts,
148 UShort maxPoints,
149 UShort maxContours )
151 TT_Error error;
154 if ( ALLOC( pts->org, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) ||
155 ALLOC( pts->cur, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) ||
156 ALLOC( pts->touch, maxPoints * sizeof ( Byte ) ) ||
157 ALLOC( pts->contours, maxContours * sizeof ( Short ) ) )
158 return error;
160 return TT_Err_Ok;
164 /*******************************************************************
166 * Function : Done_Glyph_Zone
168 * Description : Deallocates a glyph zone
170 * Input : pts pointer to the target glyph zone record
172 * Return : Error code.
174 *****************************************************************/
176 static
177 TT_Error Done_Glyph_Zone( PGlyph_Zone pts )
179 FREE( pts->contours );
180 FREE( pts->touch );
181 FREE( pts->cur );
182 FREE( pts->org );
184 return TT_Err_Ok;
189 /*******************************************************************
191 * CODERANGE FUNCTIONS *
193 *******************************************************************/
195 /*******************************************************************
197 * Function : Goto_CodeRange
199 * Description : Switch to a new code range (updates Code and IP).
201 * Input : exec target execution context
202 * range new execution code range
203 * IP new IP in new code range
205 * Output : SUCCESS on success. FAILURE on error (no code range).
207 *****************************************************************/
209 LOCAL_FUNC
210 TT_Error Goto_CodeRange( PExecution_Context exec,
211 Int range,
212 ULong IP )
214 PCodeRange cr;
217 if ( range < 1 || range > 3 )
218 return TT_Err_Bad_Argument;
220 cr = &exec->codeRangeTable[range - 1];
222 if ( cr->Base == NULL )
223 return TT_Err_Invalid_CodeRange;
225 /* NOTE: Because the last instruction of a program may be a CALL */
226 /* which will return to the first byte *after* the code */
227 /* range, we test for IP <= Size, instead of IP < Size. */
229 if ( IP > cr->Size )
230 return TT_Err_Code_Overflow;
232 exec->code = cr->Base;
233 exec->codeSize = cr->Size;
234 exec->IP = IP;
235 exec->curRange = range;
237 return TT_Err_Ok;
241 #if 0
243 /*******************************************************************
245 * Function : Get_CodeRange
247 * Description : Returns a pointer to a given code range. Should
248 * be used only by the debugger. Returns NULL if
249 * 'range' is out of current bounds.
251 * Input : exec target execution context
252 * range new execution code range
254 * Output : Pointer to the code range record. NULL on failure.
256 *****************************************************************/
258 LOCAL_FUNC
259 PCodeRange Get_CodeRange( PExecution_Context exec, Int range )
261 if ( range < 1 || range > 3 )
262 return NULL;
263 else /* arrays start with 1 in Pascal, and with 0 in C */
264 return &exec->codeRangeTable[range - 1];
267 #endif
270 /*******************************************************************
272 * Function : Set_CodeRange
274 * Description : Sets a code range.
276 * Input : exec target execution context
277 * range code range index
278 * base new code base
279 * length range size in bytes
281 * Output : SUCCESS on success. FAILURE on error.
283 *****************************************************************/
285 LOCAL_FUNC
286 TT_Error Set_CodeRange( PExecution_Context exec,
287 Int range,
288 void* base,
289 ULong length )
291 if ( range < 1 || range > 3 )
292 return TT_Err_Bad_Argument;
294 exec->codeRangeTable[range - 1].Base = (Byte*)base;
295 exec->codeRangeTable[range - 1].Size = length;
297 return TT_Err_Ok;
301 /*******************************************************************
303 * Function : Clear_CodeRange
305 * Description : Clears a code range.
307 * Input : exec target execution context
308 * range code range index
310 * Output : SUCCESS on success. FAILURE on error.
312 * Note : Does not set the Error variable.
314 *****************************************************************/
316 LOCAL_FUNC
317 TT_Error Clear_CodeRange( PExecution_Context exec, Int range )
319 if ( range < 1 || range > 3 )
320 return TT_Err_Bad_Argument;
322 exec->codeRangeTable[range - 1].Base = NULL;
323 exec->codeRangeTable[range - 1].Size = 0;
325 return TT_Err_Ok;
330 /*******************************************************************
332 * EXECUTION CONTEXT ROUTINES *
334 *******************************************************************/
336 /*******************************************************************
338 * Function : Context_Destroy
340 *****************************************************************/
342 LOCAL_FUNC
343 TT_Error Context_Destroy( void* _context )
345 PExecution_Context exec = (PExecution_Context)_context;
347 if ( !exec )
348 return TT_Err_Ok;
350 /* free composite load stack */
351 FREE( exec->loadStack );
352 exec->loadSize = 0;
354 /* points zone */
355 Done_Glyph_Zone( &exec->pts );
356 exec->maxPoints = 0;
357 exec->maxContours = 0;
359 /* free stack */
360 FREE( exec->stack );
361 exec->stackSize = 0;
363 /* free call stack */
364 FREE( exec->callStack );
365 exec->callSize = 0;
366 exec->callTop = 0;
368 /* free glyph code range */
369 FREE( exec->glyphIns );
370 exec->glyphSize = 0;
372 exec->instance = NULL;
373 exec->face = NULL;
375 return TT_Err_Ok;
379 /*******************************************************************
381 * Function : Context_Create
383 *****************************************************************/
385 LOCAL_FUNC
386 TT_Error Context_Create( void* _context, void* _face )
388 PExecution_Context exec = (PExecution_Context)_context;
390 PFace face = (PFace)_face;
391 TT_Error error;
394 /* XXX : We don't reserve arrays anymore, this is done automatically */
395 /* during a "Context_Load".. */
397 exec->callSize = 32;
398 if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TCallRecord ) )
399 goto Fail_Memory;
401 /* all values in the context are set to 0 already, but this is */
402 /* here as a remainder */
403 exec->maxPoints = 0;
404 exec->maxContours = 0;
406 exec->stackSize = 0;
407 exec->loadSize = 0;
408 exec->glyphSize = 0;
410 exec->stack = NULL;
411 exec->loadStack = NULL;
412 exec->glyphIns = NULL;
414 exec->face = face;
415 exec->instance = NULL;
417 return TT_Err_Ok;
419 Fail_Memory:
420 Context_Destroy( exec );
421 return error;
425 /*******************************************************************
427 * Function : Context_Load
429 *****************************************************************/
431 /****************************************************************/
432 /* */
433 /* Update_Max : Reallocate a buffer if it needs to */
434 /* */
435 /* input: size address of buffer's current size */
436 /* expressed in elements */
437 /* */
438 /* multiplier size in bytes of each element in the */
439 /* buffer */
440 /* */
441 /* buff address of the buffer base pointer */
442 /* */
443 /* new_max new capacity (size) of the buffer */
445 static
446 TT_Error Update_Max( ULong* size,
447 ULong multiplier,
448 void** buff,
449 ULong new_max )
451 TT_Error error;
453 if ( *size < new_max )
455 FREE( *buff );
456 if ( ALLOC( *buff, new_max * multiplier ) )
457 return error;
458 *size = new_max;
460 return TT_Err_Ok;
464 /****************************************************************/
465 /* */
466 /* Update_Zone: Reallocate a zone if it needs to */
467 /* */
468 /* input: zone address of the target zone */
469 /* */
470 /* maxPoints address of the zone's current capacity */
471 /* in points */
472 /* */
473 /* maxContours address of the zone's current capacity */
474 /* in contours */
475 /* */
476 /* newPoints new capacity in points */
477 /* */
478 /* newContours new capacity in contours */
479 /* */
481 static
482 TT_Error Update_Zone( PGlyph_Zone zone,
483 UShort* maxPoints,
484 UShort* maxContours,
485 UShort newPoints,
486 UShort newContours )
488 if ( *maxPoints < newPoints || *maxContours < newContours )
490 TT_Error error;
493 Done_Glyph_Zone( zone );
495 error = New_Glyph_Zone( zone, newPoints, newContours );
496 if ( error )
497 return error;
499 *maxPoints = newPoints;
500 *maxContours = newContours;
502 return TT_Err_Ok;
506 LOCAL_FUNC
507 TT_Error Context_Load( PExecution_Context exec,
508 PFace face,
509 PInstance ins )
511 Int i;
512 TMaxProfile* maxp;
513 TT_Error error;
515 exec->face = face;
516 maxp = &face->maxProfile;
518 exec->instance = ins;
520 if ( ins )
522 exec->numFDefs = ins->numFDefs;
523 exec->numIDefs = ins->numIDefs;
524 exec->maxFDefs = ins->maxFDefs;
525 exec->maxIDefs = ins->maxIDefs;
526 exec->FDefs = ins->FDefs;
527 exec->IDefs = ins->IDefs;
528 exec->metrics = ins->metrics;
530 exec->maxFunc = ins->maxFunc;
531 exec->maxIns = ins->maxIns;
533 for ( i = 0; i < MAX_CODE_RANGES; i++ )
534 exec->codeRangeTable[i] = ins->codeRangeTable[i];
536 /* set graphics state */
537 exec->GS = ins->GS;
539 exec->cvtSize = ins->cvtSize;
540 exec->cvt = ins->cvt;
542 exec->storeSize = ins->storeSize;
543 exec->storage = ins->storage;
545 exec->twilight = ins->twilight;
548 error = Update_Max( &exec->loadSize,
549 sizeof ( TSubglyph_Record ),
550 (void**)&exec->loadStack,
551 face->maxComponents + 1 );
552 if ( error )
553 return error;
555 error = Update_Max( &exec->stackSize,
556 sizeof ( TT_F26Dot6 ),
557 (void**)&exec->stack,
558 maxp->maxStackElements + 32 );
559 /* XXX : We reserve a little more elements on the stack to deal safely */
560 /* with broken fonts like arialbs, courbs, timesbs... */
561 if ( error )
562 return error;
564 error = Update_Max( &exec->glyphSize,
565 sizeof ( Byte ),
566 (void**)&exec->glyphIns,
567 maxp->maxSizeOfInstructions );
568 if ( error )
569 return error;
571 error = Update_Zone( &exec->pts,
572 &exec->maxPoints,
573 &exec->maxContours,
574 exec->face->maxPoints + 2,
575 exec->face->maxContours );
576 /* XXX : We reserve two positions for the phantom points! */
577 if ( error )
578 return error;
580 exec->pts.n_points = 0;
581 exec->pts.n_contours = 0;
583 exec->instruction_trap = FALSE;
585 return TT_Err_Ok;
589 /*******************************************************************
591 * Function : Context_Save
593 *****************************************************************/
595 LOCAL_FUNC
596 TT_Error Context_Save( PExecution_Context exec,
597 PInstance ins )
599 Int i;
601 /* XXXX : Will probably disappear soon with all the coderange */
602 /* management, which is now rather obsolete. */
604 ins->numFDefs = exec->numFDefs;
605 ins->numIDefs = exec->numIDefs;
606 ins->maxFunc = exec->maxFunc;
607 ins->maxIns = exec->maxIns;
609 for ( i = 0; i < MAX_CODE_RANGES; i++ )
610 ins->codeRangeTable[i] = exec->codeRangeTable[i];
612 return TT_Err_Ok;
616 /*******************************************************************
618 * Function : Context_Run
620 *****************************************************************/
622 LOCAL_FUNC
623 TT_Error Context_Run( PExecution_Context exec,
624 Bool debug )
626 TT_Error error;
629 if ( (error = Goto_CodeRange( exec,
630 TT_CodeRange_Glyph, 0 )) != TT_Err_Ok )
631 return error;
633 exec->zp0 = exec->pts;
634 exec->zp1 = exec->pts;
635 exec->zp2 = exec->pts;
637 exec->GS.gep0 = 1;
638 exec->GS.gep1 = 1;
639 exec->GS.gep2 = 1;
641 exec->GS.projVector.x = 0x4000;
642 exec->GS.projVector.y = 0x0000;
644 exec->GS.freeVector = exec->GS.projVector;
645 exec->GS.dualVector = exec->GS.projVector;
647 exec->GS.round_state = 1;
648 exec->GS.loop = 1;
650 /* some glyphs leave something on the stack. so we clean it */
651 /* before a new execution. */
652 exec->top = 0;
653 exec->callTop = 0;
655 if ( !debug )
656 return RunIns( exec );
657 else
658 return TT_Err_Ok;
662 LOCAL_FUNC
663 const TGraphicsState Default_GraphicsState =
665 0, 0, 0,
666 { 0x4000, 0 },
667 { 0x4000, 0 },
668 { 0x4000, 0 },
669 1, 64, 1,
670 TRUE, 68, 0, 0, 9, 3,
671 0, FALSE, 2, 1, 1, 1
676 /*******************************************************************
678 * INSTANCE FUNCTIONS *
681 *******************************************************************/
683 /*******************************************************************
685 * Function : Instance_Destroy
687 * Description :
689 * Input : _instance the instance object to destroy
691 * Output : error code.
693 ******************************************************************/
695 LOCAL_FUNC
696 TT_Error Instance_Destroy( void* _instance )
698 PInstance ins = (PInstance)_instance;
701 if ( !_instance )
702 return TT_Err_Ok;
704 if ( ins->debug )
706 /* the debug context must be deleted by the debugger itself */
707 ins->context = NULL;
708 ins->debug = FALSE;
711 FREE( ins->cvt );
712 ins->cvtSize = 0;
714 /* free storage area */
715 FREE( ins->storage );
716 ins->storeSize = 0;
718 /* twilight zone */
719 Done_Glyph_Zone( &ins->twilight );
721 FREE( ins->FDefs );
722 FREE( ins->IDefs );
723 ins->numFDefs = 0;
724 ins->numIDefs = 0;
725 ins->maxFDefs = 0;
726 ins->maxIDefs = 0;
727 ins->maxFunc = -1;
728 ins->maxIns = -1;
730 ins->owner = NULL;
731 ins->valid = FALSE;
733 return TT_Err_Ok;
737 /*******************************************************************
739 * Function : Instance_Create
741 * Description :
743 * Input : _instance instance record to initialize
744 * _face parent face object
746 * Output : Error code. All partially built subtables are
747 * released on error.
749 ******************************************************************/
751 LOCAL_FUNC
752 TT_Error Instance_Create( void* _instance,
753 void* _face )
755 PInstance ins = (PInstance)_instance;
756 PFace face = (PFace)_face;
757 TT_Error error;
758 Int i;
759 UShort n_twilight;
761 PMaxProfile maxp = &face->maxProfile;
764 ins->owner = face;
765 ins->valid = FALSE;
767 ins->maxFDefs = maxp->maxFunctionDefs;
768 ins->maxIDefs = maxp->maxInstructionDefs;
769 ins->cvtSize = face->cvtSize;
770 ins->storeSize = maxp->maxStorage;
772 /* Set default metrics */
774 PIns_Metrics metrics = &ins->metrics;
777 metrics->pointSize = 10 * 64; /* default pointsize = 10pts */
779 metrics->x_resolution = 96; /* default resolution = 96dpi */
780 metrics->y_resolution = 96;
782 metrics->x_ppem = 0;
783 metrics->y_ppem = 0;
785 metrics->rotated = FALSE;
786 metrics->stretched = FALSE;
788 /* set default compensation ( all 0 ) */
789 for ( i = 0; i < 4; i++ )
790 metrics->compensations[i] = 0;
793 /* allocate function defs, instruction defs, cvt and storage area */
794 if ( ALLOC_ARRAY( ins->FDefs, ins->maxFDefs, TDefRecord ) ||
795 ALLOC_ARRAY( ins->IDefs, ins->maxIDefs, TDefRecord ) ||
796 ALLOC_ARRAY( ins->cvt, ins->cvtSize, Long ) ||
797 ALLOC_ARRAY( ins->storage, ins->storeSize, Long ) )
798 goto Fail_Memory;
800 /* reserve twilight zone */
801 n_twilight = maxp->maxTwilightPoints;
802 error = New_Glyph_Zone( &ins->twilight, n_twilight, 0 );
803 if (error)
804 goto Fail_Memory;
806 ins->twilight.n_points = n_twilight;
808 return TT_Err_Ok;
810 Fail_Memory:
811 Instance_Destroy( ins );
812 return error;
816 /*******************************************************************
818 * Function : Instance_Init
820 * Description : Initialize a fresh new instance.
821 * Executes the font program if any is found.
823 * Input : _instance the instance object to destroy
825 * Output : Error code.
827 ******************************************************************/
829 LOCAL_FUNC
830 TT_Error Instance_Init( PInstance ins )
832 PExecution_Context exec;
834 TT_Error error;
835 PFace face = ins->owner;
838 if ( ins->debug )
839 exec = ins->context;
840 else
841 exec = New_Context( face );
842 /* debugging instances have their own context */
844 if ( !exec )
845 return TT_Err_Could_Not_Find_Context;
847 ins->GS = Default_GraphicsState;
849 ins->numFDefs = 0;
850 ins->numIDefs = 0;
851 ins->maxFunc = -1;
852 ins->maxIns = -1;
854 Context_Load( exec, face, ins );
856 exec->callTop = 0;
857 exec->top = 0;
859 exec->period = 64;
860 exec->phase = 0;
861 exec->threshold = 0;
864 PIns_Metrics metrics = &exec->metrics;
867 metrics->x_ppem = 0;
868 metrics->y_ppem = 0;
869 metrics->pointSize = 0;
870 metrics->x_scale1 = 0;
871 metrics->x_scale2 = 1;
872 metrics->y_scale1 = 0;
873 metrics->y_scale2 = 1;
875 metrics->ppem = 0;
876 metrics->scale1 = 0;
877 metrics->scale2 = 1;
878 metrics->ratio = 1L << 16;
881 exec->instruction_trap = FALSE;
883 exec->cvtSize = ins->cvtSize;
884 exec->cvt = ins->cvt;
886 exec->F_dot_P = 0x10000;
888 /* allow font program execution */
889 Set_CodeRange( exec,
890 TT_CodeRange_Font,
891 face->fontProgram,
892 face->fontPgmSize );
894 /* disable CVT and glyph programs coderange */
895 Clear_CodeRange( exec, TT_CodeRange_Cvt );
896 Clear_CodeRange( exec, TT_CodeRange_Glyph );
898 if ( face->fontPgmSize > 0 )
900 error = Goto_CodeRange( exec, TT_CodeRange_Font, 0 );
901 if ( error )
902 goto Fin;
904 error = RunIns( exec );
906 else
907 error = TT_Err_Ok;
909 Fin:
910 Context_Save( exec, ins );
912 if ( !ins->debug )
913 Done_Context( exec );
914 /* debugging instances keep their context */
916 ins->valid = FALSE;
918 return error;
922 /*******************************************************************
924 * Function : Instance_Reset
926 * Description : Resets an instance to a new pointsize/transform.
927 * Executes the cvt program if any is found.
929 * Input : _instance the instance object to destroy
931 * Output : Error code.
933 ******************************************************************/
935 LOCAL_FUNC
936 TT_Error Instance_Reset( PInstance ins )
938 PExecution_Context exec;
940 TT_Error error;
941 ULong i;
942 UShort j;
943 PFace face;
946 if ( !ins )
947 return TT_Err_Invalid_Instance_Handle;
949 if ( ins->valid )
950 return TT_Err_Ok;
952 face = ins->owner;
954 if ( ins->metrics.x_ppem < 1 ||
955 ins->metrics.y_ppem < 1 )
956 return TT_Err_Invalid_PPem;
958 /* compute new transformation */
959 if ( ins->metrics.x_ppem >= ins->metrics.y_ppem )
961 ins->metrics.scale1 = ins->metrics.x_scale1;
962 ins->metrics.scale2 = ins->metrics.x_scale2;
963 ins->metrics.ppem = ins->metrics.x_ppem;
964 ins->metrics.x_ratio = 1L << 16;
965 ins->metrics.y_ratio = TT_MulDiv( ins->metrics.y_ppem,
966 0x10000,
967 ins->metrics.x_ppem );
969 else
971 ins->metrics.scale1 = ins->metrics.y_scale1;
972 ins->metrics.scale2 = ins->metrics.y_scale2;
973 ins->metrics.ppem = ins->metrics.y_ppem;
974 ins->metrics.x_ratio = TT_MulDiv( ins->metrics.x_ppem,
975 0x10000,
976 ins->metrics.y_ppem );
977 ins->metrics.y_ratio = 1L << 16;
980 /* Scale the cvt values to the new ppem. */
981 /* We use by default the y ppem to scale the CVT. */
983 for ( i = 0; i < ins->cvtSize; i++ )
984 ins->cvt[i] = TT_MulDiv( face->cvt[i],
985 ins->metrics.scale1,
986 ins->metrics.scale2 );
988 /* All twilight points are originally zero */
989 for ( j = 0; j < ins->twilight.n_points; j++ )
991 ins->twilight.org[j].x = 0;
992 ins->twilight.org[j].y = 0;
993 ins->twilight.cur[j].x = 0;
994 ins->twilight.cur[j].y = 0;
997 /* clear storage area */
998 for ( i = 0; i < ins->storeSize; i++ )
999 ins->storage[i] = 0;
1001 ins->GS = Default_GraphicsState;
1003 /* get execution context and run prep program */
1005 if ( ins->debug )
1006 exec = ins->context;
1007 else
1008 exec = New_Context(face);
1009 /* debugging instances have their own context */
1011 if ( !exec )
1012 return TT_Err_Could_Not_Find_Context;
1014 Context_Load( exec, face, ins );
1016 Set_CodeRange( exec,
1017 TT_CodeRange_Cvt,
1018 face->cvtProgram,
1019 face->cvtPgmSize );
1021 Clear_CodeRange( exec, TT_CodeRange_Glyph );
1023 exec->instruction_trap = FALSE;
1025 exec->top = 0;
1026 exec->callTop = 0;
1028 if ( face->cvtPgmSize > 0 )
1030 error = Goto_CodeRange( exec, TT_CodeRange_Cvt, 0 );
1031 if ( error )
1032 goto Fin;
1034 if ( !ins->debug )
1035 error = RunIns( exec );
1037 else
1038 error = TT_Err_Ok;
1040 ins->GS = exec->GS;
1041 /* save default graphics state */
1043 Fin:
1044 Context_Save( exec, ins );
1046 if ( !ins->debug )
1047 Done_Context( exec );
1048 /* debugging instances keep their context */
1050 if ( !error )
1051 ins->valid = TRUE;
1053 return error;
1058 /*******************************************************************
1060 * FACE FUNCTIONS *
1063 *******************************************************************/
1065 /*******************************************************************
1067 * Function : Face_Destroy
1069 * Description : The face object destructor.
1071 * Input : _face typeless pointer to the face object to destroy
1073 * Output : Error code.
1075 ******************************************************************/
1077 LOCAL_FUNC
1078 TT_Error Face_Destroy( void* _face )
1080 PFace face = (PFace)_face;
1081 UShort n;
1084 if ( !face )
1085 return TT_Err_Ok;
1087 /* well, we assume that no other thread is using the face */
1088 /* at this moment, but one is never sure enough. */
1089 MUTEX_Lock( face->lock );
1091 /* first of all, destroys the cached sub-objects */
1092 Cache_Destroy( &face->instances );
1093 Cache_Destroy( &face->glyphs );
1095 /* destroy the extensions */
1096 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
1097 Extension_Destroy( face );
1098 #endif
1100 /* freeing the collection table */
1101 FREE( face->ttcHeader.TableDirectory );
1102 face->ttcHeader.DirCount = 0;
1104 /* freeing table directory */
1105 FREE( face->dirTables );
1106 face->numTables = 0;
1108 /* freeing the locations table */
1109 FREE( face->glyphLocations );
1110 face->numLocations = 0;
1112 /* freeing the character mapping tables */
1113 for ( n = 0; n < face->numCMaps; n++ )
1114 CharMap_Free( face->cMaps + n );
1116 FREE( face->cMaps );
1117 face->numCMaps = 0;
1119 /* freeing the CVT */
1120 FREE( face->cvt );
1121 face->cvtSize = 0;
1123 /* freeing the horizontal metrics */
1124 FREE( face->horizontalHeader.long_metrics );
1125 FREE( face->horizontalHeader.short_metrics );
1127 /* freeing the vertical ones, if any */
1128 if (face->verticalInfo)
1130 FREE( face->verticalHeader.long_metrics );
1131 FREE( face->verticalHeader.short_metrics );
1132 face->verticalInfo = 0;
1135 /* freeing the programs */
1136 FREE( face->fontProgram );
1137 FREE( face->cvtProgram );
1138 face->fontPgmSize = 0;
1139 face->cvtPgmSize = 0;
1141 /* freeing the gasp table */
1142 FREE( face->gasp.gaspRanges );
1143 face->gasp.numRanges = 0;
1145 /* freeing the name table */
1146 Free_TrueType_Names( face );
1148 /* freeing the hdmx table */
1149 Free_TrueType_Hdmx( face );
1151 /* TT_Close_Stream( &face->stream ); -- this is performed by the API */
1153 /* destroy the mutex */
1154 MUTEX_Destroy(face->lock);
1156 return TT_Err_Ok;
1160 /*******************************************************************
1162 * Function : Face_Create
1164 * Description : The face object constructor.
1166 * Input : _face face record to build
1167 * _input input stream where to load font data
1169 * Output : Error code.
1171 * NOTE : The input stream is kept in the face object. The
1172 * caller shouldn't destroy it after calling Face_Create().
1174 ******************************************************************/
1176 #undef LOAD_
1177 #define LOAD_( table ) \
1178 (error = Load_TrueType_##table (face)) != TT_Err_Ok
1181 LOCAL_FUNC
1182 TT_Error Face_Create( void* _face,
1183 void* _input )
1185 PEngine_Instance engine;
1187 TFont_Input* input = (TFont_Input*)_input;
1188 PFace face = (PFace)_face;
1189 TT_Error error;
1192 face->stream = input->stream;
1193 face->engine = input->engine;
1195 engine = face->engine;
1197 MUTEX_Create( face->lock );
1199 Cache_Create( engine,
1200 engine->objs_instance_class,
1201 &face->instances,
1202 &face->lock );
1204 Cache_Create( engine,
1205 engine->objs_glyph_class,
1206 &face->glyphs,
1207 &face->lock );
1209 /* Load collection directory if present, then font directory */
1211 error = Load_TrueType_Directory( face, input->fontIndex );
1212 if ( error )
1213 goto Fail;
1215 /* Load tables */
1217 if ( LOAD_( Header ) ||
1218 LOAD_( MaxProfile ) ||
1219 LOAD_( Locations ) ||
1221 (error = Load_TrueType_Metrics_Header( face, 0 )) != TT_Err_Ok ||
1222 /* load the 'hhea' & 'hmtx' tables at once */
1224 LOAD_( CMap ) ||
1225 LOAD_( CVT ) ||
1226 LOAD_( Programs ) ||
1227 LOAD_( Gasp ) ||
1228 LOAD_( Names ) ||
1229 LOAD_( OS2 ) ||
1230 LOAD_( PostScript ) ||
1232 (error = Load_TrueType_Metrics_Header( face, 1 )) != TT_Err_Ok ||
1233 /* try to load the 'vhea' & 'vmtx' at once if present */
1235 LOAD_( Hdmx ) )
1237 goto Fail;
1239 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
1240 if ( ( error = Extension_Create( face ) ) != TT_Err_Ok )
1241 return error;
1242 #endif
1244 return TT_Err_Ok;
1246 Fail :
1247 Face_Destroy( face );
1248 return error;
1251 #undef LOAD_
1254 /*******************************************************************
1256 * Function : Glyph_Destroy
1258 * Description : The glyph object destructor.
1260 * Input : _glyph typeless pointer to the glyph record to destroy
1262 * Output : Error code.
1264 ******************************************************************/
1266 LOCAL_FUNC
1267 TT_Error Glyph_Destroy( void* _glyph )
1269 PGlyph glyph = (PGlyph)_glyph;
1272 if ( !glyph )
1273 return TT_Err_Ok;
1275 glyph->outline.owner = TRUE;
1276 return TT_Done_Outline( &glyph->outline );
1280 /*******************************************************************
1282 * Function : Glyph_Create
1284 * Description : The glyph object constructor.
1286 * Input : _glyph glyph record to build.
1287 * _face the glyph's parent face.
1289 * Output : Error code.
1291 ******************************************************************/
1293 LOCAL_FUNC
1294 TT_Error Glyph_Create( void* _glyph,
1295 void* _face )
1297 PFace face = (PFace)_face;
1298 PGlyph glyph = (PGlyph)_glyph;
1301 if ( !face )
1302 return TT_Err_Invalid_Face_Handle;
1304 if ( !glyph )
1305 return TT_Err_Invalid_Glyph_Handle;
1307 glyph->face = face;
1309 /* XXX: Don't forget the space for the 2 phantom points */
1310 return TT_New_Outline( glyph->face->maxPoints + 2,
1311 glyph->face->maxContours,
1312 &glyph->outline );
1316 /*******************************************************************
1318 * Function : Scale_X
1320 * Description : scale an horizontal distance from font
1321 * units to 26.6 pixels
1323 * Input : metrics pointer to metrics
1324 * x value to scale
1326 * Output : scaled value
1328 ******************************************************************/
1330 LOCAL_FUNC
1331 TT_Pos Scale_X( PIns_Metrics metrics, TT_Pos x )
1333 return TT_MulDiv( x, metrics->x_scale1, metrics->x_scale2 );
1337 /*******************************************************************
1339 * Function : Scale_Y
1341 * Description : scale a vertical distance from font
1342 * units to 26.6 pixels
1344 * Input : metrics pointer to metrics
1345 * y value to scale
1347 * Output : scaled value
1349 ******************************************************************/
1351 LOCAL_FUNC
1352 TT_Pos Scale_Y( PIns_Metrics metrics, TT_Pos y )
1354 return TT_MulDiv( y, metrics->y_scale1, metrics->y_scale2 );
1358 /*******************************************************************
1360 * Function : TTObjs_Init
1362 * Description : The TTObjs component initializer. Creates the
1363 * object cache classes, as well as the face record
1364 * cache.
1366 * Input : engine engine instance
1368 * Output : Error code.
1370 ******************************************************************/
1372 static
1373 const TCache_Class objs_face_class =
1375 sizeof ( TFace ),
1377 Face_Create,
1378 Face_Destroy,
1379 NULL,
1380 NULL
1383 static
1384 const TCache_Class objs_instance_class =
1386 sizeof ( TInstance ),
1388 Instance_Create,
1389 Instance_Destroy,
1390 NULL,
1391 NULL
1394 /* Note that we use a cache size of 1 for the execution context. */
1395 /* This is to avoid re-creating a new context each time we */
1396 /* change one instance's attribute (resolution and/or char sizes) */
1397 /* or when we load a glyph. */
1399 static
1400 const TCache_Class objs_exec_class =
1402 sizeof ( TExecution_Context ),
1404 Context_Create,
1405 Context_Destroy,
1406 NULL,
1407 NULL
1410 static
1411 const TCache_Class objs_glyph_class =
1413 sizeof ( TGlyph ),
1415 Glyph_Create,
1416 Glyph_Destroy,
1417 NULL,
1418 NULL
1422 LOCAL_FUNC
1423 TT_Error TTObjs_Init( PEngine_Instance engine )
1425 PCache face_cache, exec_cache;
1426 TT_Error error;
1429 face_cache = 0;
1430 exec_cache = 0;
1432 if ( ALLOC( face_cache, sizeof ( TCache ) ) ||
1433 ALLOC( exec_cache, sizeof ( TCache ) ) )
1434 goto Fail;
1436 /* create face cache */
1437 error = Cache_Create( engine, (PCache_Class)&objs_face_class,
1438 face_cache, &engine->lock );
1439 if ( error )
1440 goto Fail;
1442 engine->objs_face_cache = face_cache;
1444 error = Cache_Create( engine, (PCache_Class)&objs_exec_class,
1445 exec_cache, &engine->lock );
1446 if ( error )
1447 goto Fail;
1449 engine->objs_exec_cache = exec_cache;
1451 engine->objs_face_class = (PCache_Class)&objs_face_class;
1452 engine->objs_instance_class = (PCache_Class)&objs_instance_class;
1453 engine->objs_execution_class = (PCache_Class)&objs_exec_class;
1454 engine->objs_glyph_class = (PCache_Class)&objs_glyph_class;
1456 goto Exit;
1458 Fail:
1459 FREE( face_cache );
1460 FREE( exec_cache );
1462 Exit:
1463 return error;
1467 /*******************************************************************
1469 * Function : TTObjs_Done
1471 * Description : The TTObjs component finalizer.
1473 * Input : engine engine instance
1475 * Output : Error code.
1477 ******************************************************************/
1479 LOCAL_FUNC
1480 TT_Error TTObjs_Done( PEngine_Instance engine )
1482 /* destroy all active faces and contexts before releasing the */
1483 /* caches */
1484 Cache_Destroy( (TCache*)engine->objs_exec_cache );
1485 Cache_Destroy( (TCache*)engine->objs_face_cache );
1487 /* Now frees caches and cache classes */
1488 FREE( engine->objs_exec_cache );
1489 FREE( engine->objs_face_cache );
1491 return TT_Err_Ok;
1495 /* END */