ref: 8f43c714a5a74c63c2a6242392790510ac487f80
parent: 0360168a4d0decdeb2f9dfde9a3be887dcea3892
author: David Turner <[email protected]>
date: Wed Feb 2 07:16:19 EST 2000
A major refresh of the TrueType driver : - some #ifdefs were included in order to _not_ compile support for the bytecode interpreter when FT_CONFIG_OPTION_BYTECODE_INTERPRETER is not defined in "ttconfig.h" - the glyph loader has been seriously re-designed. It is now smaller, simpler and should load composites a bit faster - works with the TrueType debugger
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -44,7 +44,9 @@
#include <ttdriver.c> /* driver interface */
#include <ttpload.c> /* tables loader */
#include <ttgload.c> /* glyph loader */
-#include <ttinterp.c> /* bytecode interpreter */
#include <ttobjs.c> /* object manager */
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#include <ttinterp.c> /* bytecode interpreter */
+#endif
/* END */
--- a/src/truetype/ttconfig.h
+++ b/src/truetype/ttconfig.h
@@ -30,6 +30,17 @@
/*************************************************************************/
/* */
+ /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */
+ /* a bytecode interpreter in the TrueType driver. Note that there are */
+ /* important patent issues related to the use of the interpreter. */
+ /* */
+ /* By undefining this, you'll only compile the code necessary to load */
+ /* TrueType glyphs without hinting.. */
+ /* */
+#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
+ /*************************************************************************/
+ /* */
/* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */
/* bytecode interpreter with a huge switch statement, rather than a */
/* call table. This results in smaller and faster code for a number of */
@@ -46,7 +57,7 @@
/* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */
/* embedded bitmaps in the TrueType/OpenType driver. */
/* */
-#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#undef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/*************************************************************************/
@@ -55,8 +66,10 @@
/* load and enumerate the glyph Postscript names in a TrueType or */
/* OpenType file. */
/* */
-#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+#undef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+ /* The maximum number of sub-glyphs in a TrueType composite glyph */
+#define TT_MAX_SUBGLYPHS 32
#define TT_USE_FIXED
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -683,7 +683,7 @@
EXPORT_FUNC
FT_DriverInterface* getDriverInterface( void )
{
- return &truetype_driver_interface;
+ return &tt_driver_interface;
}
#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -26,114 +26,9 @@
#include <ttnameid.h>
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TTDriver_getFontData */
- /* */
- /* <Description> */
- /* Returns either a single font table or the whole font file into */
- /* caller's memory. This function mimics the GetFontData() API */
- /* function found in Windows. */
- /* */
- /* <Input> */
- /* face :: A handle to the source TrueType face object. */
- /* */
- /* tag :: A 32-bit integer used to name the table you want to */
- /* read. Use the macro MAKE_TT_TAG (defined in freetype.h) */
- /* to create one. Use the value 0 if you want to access */
- /* the whole file instead. */
- /* */
- /* offset :: The offset from the start of the table or file from */
- /* which you want to read bytes. */
- /* */
- /* buffer :: The address of the target/read buffer where data will be */
- /* copied. */
- /* */
- /* <InOut> */
- /* length :: The length in bytes of the data to read. If it is set */
- /* to 0 when this function is called, it will return */
- /* immediately, setting the value of `length' to the */
- /* requested table's size (or the whole font file if the */
- /* tag is 0). It is thus possible to allocate and read an */
- /* arbitrary table in two successive calls. */
- /* <Return> */
- /* TrueType error code. 0 means success. */
- /* */
- typedef TT_Error (*TTDriver_getFontData)( TT_Face face,
- TT_ULong tag,
- TT_ULong offset,
- void* buffer,
- TT_Long* length );
-
-
- /*************************************************************************/
- /* */
- /* <FuncType> */
- /* TTDriver_getFaceWidths */
- /* */
- /* <Description> */
- /* Returns the widths and/or heights of a given range of glyph from */
- /* a face. */
- /* */
- /* <Input> */
- /* face :: A handle to the source FreeType face object. */
- /* */
- /* first_glyph :: The first glyph in the range. */
- /* */
- /* last_glyph :: The last glyph in the range. */
- /* */
- /* <Output> */
- /* widths :: The address of the table receiving the widths */
- /* expressed in font units (UShorts). Set this */
- /* parameter to NULL if you're not interested in these */
- /* values. */
- /* */
- /* heights :: The address of the table receiving the heights */
- /* expressed in font units (UShorts). Set this */
- /* parameter to NULL if you're not interested in these */
- /* values. */
- /* */
- /* <Return> */
- /* Error code. 0 means success. */
- /* */
- typedef TT_Error (*TTDriver_getFaceWidths)( TT_Face face,
- TT_UShort first_glyph,
- TT_UShort last_glyph,
- TT_UShort* widths,
- TT_UShort* heights );
-
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* TT_DriverInterface */
- /* */
- /* <Description> */
- /* The TrueType-specific interface of this driver. Note that some of */
- /* the methods defined here are optional, as they're only used for */
- /* for specific tasks of the driver. */
- /* */
- /* <Fields> */
- /* get_font_data :: See the declaration of TTDriver_getFontData(). */
- /* get_face_widths :: See the declaration of */
- /* TTDriver_getFaceWidths(). */
- /* */
- typedef struct TT_DriverInterface_
- {
- TTDriver_getFontData get_font_data;
- TTDriver_getFaceWidths get_face_widths;
-
- } TT_DriverInterface;
-
-
EXPORT_DEF
- const FT_DriverInterface tt_driver_interface;
+ const FT_DriverInterface ttz_driver_interface;
-
- EXPORT_DEF
- const TT_DriverInterface tt_format_interface;
#endif /* TTDRIVER_H */
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -25,9 +25,11 @@
#include <ttgload.h>
#include <tttags.h>
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#include <ttinterp.h>
+#endif
-
/* required for the tracing mode */
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttgload
@@ -49,41 +51,15 @@
#define USE_MY_METRICS 0x200
-#undef SCALE_X
-#define SCALE_X( distance ) FT_MulFix( distance, exec->metrics.x_scale )
-#undef SCALE_Y
-#define SCALE_Y( distance ) FT_MulFix( distance, exec->metrics.y_scale )
-
-
/*************************************************************************/
- /* */
- /* <Function> */
- /* TT_Get_Metrics */
- /* */
- /* <Description> */
/* Returns the horizontal or vertical metrics in font units for a */
/* given glyph. The metrics are the left side bearing (resp. top */
/* side bearing) and advance width (resp. advance height). */
/* */
- /* <Input> */
- /* header :: A pointer to either the horizontal or vertical metrics */
- /* structure. */
- /* */
- /* index :: The glyph index. */
- /* */
- /* <Output> */
- /* bearing :: The bearing, either left side or top side. */
- /* */
- /* advance :: The advance width resp. advance height. */
- /* */
- /* <Note> */
- /* This function will much probably move to another component in the */
- /* near future, but I haven't decided which yet. */
- /* */
LOCAL_FUNC
void TT_Get_Metrics( TT_HoriHeader* header,
- TT_UShort index,
+ TT_UInt index,
TT_Short* bearing,
TT_UShort* advance )
{
@@ -106,30 +82,13 @@
/*************************************************************************/
- /* */
- /* <Function> */
- /* Get_HMetrics */
- /* */
- /* <Description> */
/* Returns the horizontal metrics in font units for a given glyph. */
/* If `check' is true, take care of monospaced fonts by returning the */
/* advance width maximum. */
/* */
- /* <Input> */
- /* face :: A handle to the target source face. */
- /* */
- /* index :: The glyph index. */
- /* */
- /* check :: If set, handle monospaced fonts. */
- /* */
- /* <Output> */
- /* lsb :: The left side bearing. */
- /* */
- /* aw :: The advance width. */
- /* */
static
void Get_HMetrics( TT_Face face,
- TT_UShort index,
+ TT_UInt index,
TT_Bool check,
TT_Short* lsb,
TT_UShort* aw )
@@ -142,22 +101,9 @@
/*************************************************************************/
- /* */
- /* <Function> */
- /* Get_Advance_Widths */
- /* */
- /* <Description> */
/* Returns the advance width table for a given pixel size if it is */
/* found in the font's `hdmx' table (if any). */
/* */
- /* <Input> */
- /* face :: A handle to the target source face. */
- /* */
- /* ppem :: The pixel size. */
- /* */
- /* <Return> */
- /* A pointer to the advance with table. NULL if it doesn't exist. */
- /* */
static
TT_Byte* Get_Advance_Widths( TT_Face face,
TT_UShort ppem )
@@ -181,32 +127,16 @@
/*************************************************************************/
- /* */
- /* <Function> */
- /* translate_array */
- /* */
- /* <Description> */
/* Translates an array of coordinates. */
/* */
- /* <Input> */
- /* n :: The number of points to translate. */
- /* */
- /* delta_x :: The horizontal coordinate of the shift vector. */
- /* */
- /* delta_y :: The vertical coordinate of the shift vector. */
- /* */
- /* <InOut> */
- /* coords :: The vector array to translate. */
- /* */
static
- void translate_array( TT_UShort n,
+ void translate_array( TT_UInt n,
TT_Vector* coords,
TT_Pos delta_x,
TT_Pos delta_y )
{
- TT_UShort k;
+ TT_UInt k;
-
if ( delta_x )
for ( k = 0; k < n; k++ )
coords[k].x += delta_x;
@@ -217,29 +147,18 @@
}
+
/*************************************************************************/
- /* */
- /* <Function> */
- /* mount_zone */
- /* */
- /* <Description> */
/* Mounts one glyph zone on top of another. This is needed to */
/* assemble composite glyphs. */
/* */
- /* <Input> */
- /* source :: The source glyph zone. */
- /* */
- /* <Output> */
- /* target :: The target glyph zone. */
- /* */
static
void mount_zone( TT_GlyphZone* source,
TT_GlyphZone* target )
{
- TT_UShort np;
- TT_Short nc;
+ TT_UInt np;
+ TT_Int nc;
-
np = source->n_points;
nc = source->n_contours;
@@ -254,6 +173,9 @@
}
+#undef IS_HINTED
+#define IS_HINTED(flags) ((flags & FT_LOAD_NO_HINTING) == 0)
+
/*************************************************************************/
/* */
/* <Function> */
@@ -265,35 +187,23 @@
/* glyphs elements will be loaded with routine. */
/* */
static
- TT_Error Load_Simple_Glyph( TT_ExecContext exec,
- FT_Stream stream,
- TT_ULong byte_count,
- TT_Short n_contours,
- TT_Short left_contours,
- TT_UShort left_points,
- TT_UInt load_flags,
- TT_SubGlyphRec* subg,
- TT_Bool debug )
+ TT_Error Load_Simple( TT_Loader* load,
+ TT_UInt byte_count,
+ TT_Int n_contours,
+ TT_Bool debug )
{
TT_Error error;
- TT_GlyphZone* pts;
- TT_Short k;
- TT_UShort j;
- TT_UShort n_points, n_ins;
- TT_Face face;
- TT_Byte* flag;
- TT_Vector* vec;
- TT_F26Dot6 x, y;
+ FT_Stream stream = load->stream;
+ TT_GlyphZone* zone = &load->zone;
+ TT_Face face = load->face;
- TT_Vector *pp1, *pp2;
+ TT_UShort n_ins;
+ TT_Int n, n_points;
-
- face = exec->face;
-
/*********************************************************************/
/* simple check */
- if ( n_contours > left_contours )
+ if ( n_contours > load->left_contours )
{
FT_TRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n",
subg->index,
@@ -303,9 +213,8 @@
}
/* preparing the execution context */
- mount_zone( &subg->zone, &exec->pts );
+ mount_zone( &load->base, zone );
-
/*********************************************************************/
/* reading the contours endpoints */
@@ -312,12 +221,12 @@
if ( ACCESS_Frame( byte_count ) )
return error;
- for ( k = 0; k < n_contours; k++ )
- exec->pts.contours[k] = GET_UShort();
+ for ( n = 0; n < n_contours; n++ )
+ zone->contours[n] = GET_UShort();
n_points = 0;
if ( n_contours > 0 )
- n_points = exec->pts.contours[n_contours - 1] + 1;
+ n_points = zone->contours[n_contours - 1] + 1;
/*********************************************************************/
@@ -325,7 +234,7 @@
n_ins = GET_UShort();
- if ( n_points > left_points )
+ if ( n_points > load->left_points )
{
FT_TRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index ));
error = TT_Err_Too_Many_Points;
@@ -347,34 +256,32 @@
error = TT_Err_Too_Many_Ins;
goto Fail;
}
- MEM_Copy( exec->glyphIns, stream->cursor, n_ins );
- stream->cursor += n_ins;
- error = TT_Set_CodeRange( exec, tt_coderange_glyph,
- exec->glyphIns, n_ins );
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ MEM_Copy( load->exec->glyphIns, stream->cursor, n_ins );
+
+ error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
+ load->exec->glyphIns, n_ins );
if (error) goto Fail;
+#endif
+ stream->cursor += n_ins;
/*********************************************************************/
/* reading the point flags */
-
- j = 0;
- flag = exec->pts.touch;
- while ( j < n_points )
- {
- TT_Byte c, cnt;
-
- flag[j] = c = GET_Byte();
- j++;
-
- if ( c & 8 )
+ {
+ TT_Byte* flag = load->zone.touch;
+ TT_Byte* limit = flag + n_points;
+ TT_Byte c, count;
+
+ for (; flag < limit; flag++)
{
- cnt = GET_Byte();
- while( cnt > 0 )
+ *flag = c = GET_Byte();
+ if ( c & 8 )
{
- flag[j++] = c;
- cnt--;
+ for ( count = GET_Byte(); count > 0; count-- )
+ *++flag = c;
}
}
}
@@ -382,49 +289,53 @@
/*********************************************************************/
/* reading the X coordinates */
- x = 0;
- vec = exec->pts.org;
-
- for ( j = 0; j < n_points; j++ )
{
- if ( flag[j] & 2 )
+ TT_Vector* vec = zone->org;
+ TT_Vector* limit = vec + n_points;
+ TT_Byte* flag = zone->touch;
+ TT_Pos x = 0;
+
+ for ( ; vec < limit; vec++, flag++ )
{
- if ( flag[j] & 16 )
- x += GET_Byte();
- else
- x -= GET_Byte();
+ TT_Pos y = 0;
+
+ if ( *flag & 2 )
+ {
+ y = GET_Byte();
+ if ((*flag & 16) == 0) y = -y;
+ }
+ else if ((*flag & 16) == 0)
+ y = GET_Short();
+
+ x += y;
+ vec->x = x;
}
- else
- {
- if ( (flag[j] & 16) == 0 )
- x += GET_Short();
- }
-
- vec[j].x = x;
}
-
/*********************************************************************/
/* reading the YX coordinates */
-
- y = 0;
- for ( j = 0; j < n_points; j++ )
{
- if ( flag[j] & 4 )
+ TT_Vector* vec = zone->org;
+ TT_Vector* limit = vec + n_points;
+ TT_Byte* flag = zone->touch;
+ TT_Pos x = 0;
+
+ for ( ; vec < limit; vec++, flag++ )
{
- if ( flag[j] & 32 )
- y += GET_Byte();
- else
- y -= GET_Byte();
+ TT_Pos y = 0;
+
+ if ( *flag & 4 )
+ {
+ y = GET_Byte();
+ if ((*flag & 32) == 0) y = -y;
+ }
+ else if ((*flag & 32) == 0)
+ y = GET_Short();
+
+ x += y;
+ vec->y = x;
}
- else
- {
- if ( (flag[j] & 32) == 0 )
- y += GET_Short();
- }
-
- vec[j].y = y;
}
FORGET_Frame();
@@ -435,79 +346,93 @@
/* Now add the two shadow points at n and n + 1. */
/* We need the left side bearing and advance width. */
- /* pp1 = xMin - lsb */
- pp1 = vec + n_points;
- pp1->x = subg->bbox.xMin - subg->left_bearing;
- pp1->y = 0;
-
- /* pp2 = pp1 + aw */
- pp2 = pp1 + 1;
- pp2->x = pp1->x + subg->advance;
- pp2->y = 0;
+ {
+ TT_Vector* pp1;
+ TT_Vector* pp2;
+
+ /* pp1 = xMin - lsb */
+ pp1 = zone->org + n_points;
+ pp1->x = load->bbox.xMin - load->left_bearing;
+ pp1->y = 0;
+
+ /* pp2 = pp1 + aw */
+ pp2 = pp1 + 1;
+ pp2->x = pp1->x + load->advance;
+ pp2->y = 0;
- /* clear the touch flags */
- for ( j = 0; j < n_points; j++ )
- exec->pts.touch[j] &= FT_Curve_Tag_On;
+ /* clear the touch flags */
+ for ( n = 0; n < n_points; n++ )
+ zone->touch[n] &= FT_Curve_Tag_On;
- exec->pts.touch[n_points ] = 0;
- exec->pts.touch[n_points + 1] = 0;
-
+ zone->touch[n_points ] = 0;
+ zone->touch[n_points + 1] = 0;
+ }
/* Note that we return two more points that are not */
/* part of the glyph outline. */
- n_points += 2;
+ zone->n_points = n_points;
+ zone->n_contours = n_contours;
+ n_points += 2;
+ /*******************************************/
/* now eventually scale and hint the glyph */
- pts = &exec->pts;
- pts->n_points = n_points;
- pts->n_contours = n_contours;
-
- if (load_flags & FT_LOAD_NO_SCALE)
+ if (load->load_flags & FT_LOAD_NO_SCALE)
{
/* no scaling, just copy the orig arrays into the cur ones */
- org_to_cur( n_points, pts );
+ org_to_cur( n_points, zone );
}
else
{
+ TT_Vector* vec = zone->org;
+ TT_Vector* limit = vec + n_points;
+ TT_Fixed x_scale = load->size->root.metrics.x_scale;
+ TT_Fixed y_scale = load->size->root.metrics.y_scale;
+
/* first scale the glyph points */
- for ( j = 0; j < n_points; j++ )
+ for (; vec < limit; vec++)
{
- pts->org[j].x = SCALE_X( pts->org[j].x );
- pts->org[j].y = SCALE_Y( pts->org[j].y );
+ vec->x = FT_MulFix( vec->x, x_scale );
+ vec->y = FT_MulFix( vec->y, y_scale );
}
/* if hinting, round pp1, and shift the glyph accordingly */
- if ( subg->is_hinted )
+ if ( !IS_HINTED(load->load_flags) )
{
- x = pts->org[n_points - 2].x;
+ org_to_cur( n_points, zone );
+ }
+ else
+ {
+ TT_Pos x = zone->org[n_points-2].x;
x = ((x + 32) & -64) - x;
- translate_array( n_points, pts->org, x, 0 );
+ translate_array( n_points, zone->org, x, 0 );
- org_to_cur( n_points, pts );
+ org_to_cur( n_points, zone );
- pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64;
+ zone->cur[n_points-1].x = (zone->cur[n_points-1].x + 32) & -64;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
/* now consider hinting */
if ( n_ins > 0 )
{
- exec->is_composite = FALSE;
- exec->pedantic_hinting = load_flags & FT_LOAD_PEDANTIC;
+ load->exec->is_composite = FALSE;
+ load->exec->pedantic_hinting = (TT_Bool)(load->load_flags & FT_LOAD_PEDANTIC);
+ load->exec->pts = *zone;
+ load->exec->pts.n_points += 2;
- error = TT_Run_Context( exec, debug );
- if ( error && exec->pedantic_hinting )
+ error = TT_Run_Context( load->exec, debug );
+ if ( error && load->exec->pedantic_hinting )
return error;
}
+#endif
}
- else
- org_to_cur( n_points, pts );
}
/* save glyph phantom points */
- if ( !subg->preserve_pps )
+ if ( !load->preserve_pps )
{
- subg->pp1 = pts->cur[n_points - 2];
- subg->pp2 = pts->cur[n_points - 1];
+ load->pp1 = zone->cur[n_points - 2];
+ load->pp2 = zone->cur[n_points - 1];
}
return TT_Err_Ok;
@@ -518,683 +443,304 @@
}
+
+
+
+
/*************************************************************************/
/* */
/* <Function> */
- /* Load_Composite_End */
+ /* load_truetype_glyph */
/* */
/* <Description> */
- /* Finalizes the loading process of a composite glyph element. This */
- /* function is used for the `Load_End' state of TT_Load_Glyph(). */
+ /* Loads a given truetype glyph. Handles composites and uses a */
+ /* TT_Loader object.. */
/* */
static
- TT_Error Load_Composite_End( TT_UShort n_points,
- TT_Short n_contours,
- TT_ExecContext exec,
- TT_SubGlyphRec* subg,
- FT_Stream stream,
- TT_UInt load_flags,
- TT_Bool debug )
+ TT_Error load_truetype_glyph( TT_Loader* loader,
+ TT_UInt glyph_index )
{
- TT_Error error;
-
- TT_UShort k, n_ins;
- TT_GlyphZone* pts;
-
- if ( subg->is_hinted &&
- subg->element_flag & WE_HAVE_INSTR )
+ FT_Stream stream = loader->stream;
+ TT_Error error;
+ TT_Face face = loader->face;
+ TT_ULong offset;
+ FT_SubGlyph subglyphs[ TT_MAX_SUBGLYPHS ];
+ TT_Int num_subglyphs = 0, contours_count;
+ TT_UInt index, num_points, num_contours, count;
+ TT_Fixed x_scale, y_scale;
+ TT_ULong ins_offset;
+
+ /* check glyph index */
+ index = (TT_UInt)glyph_index;
+ if ( index >= (TT_UInt)face->root.num_glyphs )
{
- if ( READ_UShort( n_ins ) ) /* read size of instructions */
- return error;
-
- FT_TRACE4(( "Instructions size = %d\n", n_ins ));
-
- if ( n_ins > exec->face->max_profile.maxSizeOfInstructions )
- {
- FT_TRACE0(( "Too many instructions in composite glyph %ld\n",
- subg->index ));
- return TT_Err_Too_Many_Ins;
- }
-
- if ( FILE_Read( exec->glyphIns, n_ins ) )
- return error;
-
- error = TT_Set_CodeRange( exec,
- tt_coderange_glyph,
- exec->glyphIns,
- n_ins );
- if ( error )
- return error;
+ error = TT_Err_Invalid_Glyph_Index;
+ goto Fail;
}
- else
- n_ins = 0;
-
- /* prepare the execution context */
- n_points += 2;
- exec->pts = subg->zone;
- pts = &exec->pts;
-
- pts->n_points = n_points;
- pts->n_contours = n_contours;
-
- /* add phantom points */
- pts->cur[n_points - 2] = subg->pp1;
- pts->cur[n_points - 1] = subg->pp2;
-
- pts->touch[n_points - 1] = 0;
- pts->touch[n_points - 2] = 0;
-
- /* if hinting, round the phantom points */
- if ( subg->is_hinted )
+ num_contours = 0;
+ num_points = 0;
+ ins_offset = 0;
+
+ x_scale = 0x10000;
+ y_scale = 0x10000;
{
- pts->cur[n_points - 2].x = ((subg->pp1.x + 32) & -64);
- pts->cur[n_points - 1].x = ((subg->pp2.x + 32) & -64);
+ x_scale = loader->size->root.metrics.x_scale;
+ y_scale = loader->size->root.metrics.y_scale;
}
- for ( k = 0; k < n_points; k++ )
- pts->touch[k] &= FT_Curve_Tag_On;
-
- cur_to_org( n_points, pts );
-
- /* now consider hinting */
- if ( subg->is_hinted && n_ins > 0 )
+ /* get horizontal metrics */
{
- exec->is_composite = TRUE;
- exec->pedantic_hinting = load_flags & FT_LOAD_PEDANTIC;
+ TT_Short left_bearing;
+ TT_UShort advance_width;
- error = TT_Run_Context( exec, debug );
- if ( error && exec->pedantic_hinting )
- return error;
+ Get_HMetrics( face, index, TRUE,
+ &left_bearing,
+ &advance_width );
+
+ loader->left_bearing = left_bearing;
+ loader->advance = advance_width;
}
- /* save glyph origin and advance points */
- subg->pp1 = pts->cur[n_points - 2];
- subg->pp2 = pts->cur[n_points - 1];
+ /* load glyph header */
+ offset = face->glyph_locations[index];
+ count = 0;
+ if (index < (TT_UInt)face->num_locations-1)
+ count = face->glyph_locations[index+1] - offset;
+
- return TT_Err_Ok;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Init_Glyph_Component */
- /* */
- /* <Description> */
- /* Initializes a glyph component for further processing. */
- /* */
- static
- void Init_Glyph_Component( TT_SubGlyphRec* element,
- TT_SubGlyphRec* original,
- TT_ExecContext exec )
- {
- element->index = -1;
- element->is_scaled = FALSE;
- element->is_hinted = FALSE;
-
- if ( original )
- mount_zone( &original->zone, &element->zone );
- else
- element->zone = exec->pts;
-
- element->zone.n_contours = 0;
- element->zone.n_points = 0;
-
- element->arg1 = 0;
- element->arg2 = 0;
-
- element->element_flag = 0;
- element->preserve_pps = FALSE;
-
- element->transform.xx = 0x10000;
- element->transform.xy = 0;
- element->transform.yx = 0;
- element->transform.yy = 0x10000;
-
- element->transform.ox = 0;
- element->transform.oy = 0;
-
- element->left_bearing = 0;
- element->advance = 0;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* TT_Load_Glyph */
- /* */
- /* <Description> */
- /* A function used to load a single glyph within a given glyph slot, */
- /* for a given size. */
- /* */
- /* <Input> */
- /* glyph :: A handle to a target slot object where the glyph */
- /* will be loaded. */
- /* */
- /* size :: A handle to the source face size at which the glyph */
- /* must be scaled/loaded. */
- /* */
- /* glyph_index :: The index of the glyph in the font file. */
- /* */
- /* load_flags :: A flag indicating what to load for this glyph. The */
- /* FT_LOAD_XXX constants can be used to control the */
- /* glyph loading process (e.g., whether the outline */
- /* should be scaled, whether to load bitmaps or not, */
- /* whether to hint the outline, etc). */
- /* <Output> */
- /* result :: A set of bit flags indicating the type of data that */
- /* was loaded in the glyph slot (outline or bitmap, */
- /* etc). */
- /* */
- /* You can set this field to 0 if you don't want this */
- /* information. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- LOCAL_FUNC
- TT_Error TT_Load_Glyph( TT_Size size,
- TT_GlyphSlot glyph,
- TT_UShort glyph_index,
- TT_UInt load_flags )
- {
- typedef enum TPhases_
+ if (count == 0)
{
- Load_Exit,
- Load_Glyph,
- Load_Header,
- Load_Simple,
- Load_Composite,
- Load_End
+ /* as described by Frederic Loyer, these are spaces, and */
+ /* not the unknown glyph. */
+ loader->bbox.xMin = 0;
+ loader->bbox.xMax = 0;
+ loader->bbox.yMin = 0;
+ loader->bbox.yMax = 0;
- } TPhases;
+ loader->pp1.x = 0;
+ loader->pp2.x = loader->advance;
- TT_Error error = 0;
- FT_Stream stream;
+ if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 )
+ loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
- TT_Face face;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ loader->exec->glyphSize = 0;
+#endif
+ goto Load_End;
+ }
- TT_UShort num_points;
- TT_Short num_contours;
- TT_UShort left_points;
- TT_Short left_contours;
+ offset = loader->glyf_offset + offset;
- TT_ULong load_top;
- TT_Long k, l;
- TT_Int new_flags;
- TT_UShort index;
- TT_UShort u;
- TT_Long count;
+ /* read first glyph header */
+ if ( FILE_Seek( offset ) || ACCESS_Frame( 10L ) )
+ goto Fail;
- TT_Long glyph_offset, offset;
+ contours_count = GET_Short();
- TT_F26Dot6 x, y, nx, ny;
+ loader->bbox.xMin = GET_Short();
+ loader->bbox.yMin = GET_Short();
+ loader->bbox.xMax = GET_Short();
+ loader->bbox.yMax = GET_Short();
- TT_Fixed xx, xy, yx, yy;
- TT_BBox bbox;
+ FORGET_Frame();
- TT_ExecContext exec;
+ FT_TRACE6(( "Glyph %ld\n", index ));
+ FT_TRACE6(( " # of contours : %d\n", num_contours ));
+ FT_TRACE6(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
+ loader->bbox.xMax ));
+ FT_TRACE6(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
+ loader->bbox.yMax ));
+ FT_TRACE6(( "-" ));
- TT_SubGlyphRec *subglyph, *subglyph2;
+ count -= 10;
- TT_GlyphZone base_pts;
-
- TPhases phase;
- TT_Byte* widths;
- TT_Int num_elem_points;
-
- SFNT_Interface* sfnt;
-
- /* first of all, check arguments */
- if ( !glyph )
- return TT_Err_Invalid_Glyph_Handle;
-
- face = (TT_Face)glyph->face;
- if ( !face )
- return TT_Err_Invalid_Glyph_Handle;
-
- sfnt = (SFNT_Interface*)face->sfnt;
- stream = face->root.stream;
- count = 0;
-
- if ( glyph_index >= face->root.num_glyphs )
- return TT_Err_Invalid_Glyph_Index;
-
- if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+ if ( contours_count > loader->left_contours )
{
- size = NULL;
- load_flags |= FT_LOAD_NO_SCALE |
- FT_LOAD_NO_HINTING |
- FT_LOAD_NO_BITMAP;
+ FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
+ error = TT_Err_Too_Many_Contours;
+ goto Fail;
}
- /* Try to load embedded bitmap if any */
- if ( size && (load_flags & FT_LOAD_NO_BITMAP) == 0 && sfnt->load_sbits )
+ loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
+ loader->pp1.y = 0;
+ loader->pp2.x = loader->pp1.x + loader->advance;
+ loader->pp2.y = 0;
+
+ if ((loader->load_flags & FT_LOAD_NO_SCALE)==0)
{
- TT_SBit_Metrics metrics;
-
- error = sfnt->load_sbit_image( face,
- size->root.metrics.x_ppem,
- size->root.metrics.y_ppem,
- glyph_index,
- stream,
- &glyph->bitmap,
- &metrics );
- if ( !error )
- {
- glyph->outline.n_points = 0;
- glyph->outline.n_contours = 0;
-
- glyph->metrics.width = (TT_Pos)metrics.width << 6;
- glyph->metrics.height = (TT_Pos)metrics.height << 6;
-
- glyph->metrics.horiBearingX = (TT_Pos)metrics.horiBearingX << 6;
- glyph->metrics.horiBearingY = (TT_Pos)metrics.horiBearingY << 6;
- glyph->metrics.horiAdvance = (TT_Pos)metrics.horiAdvance << 6;
-
- glyph->metrics.vertBearingX = (TT_Pos)metrics.vertBearingX << 6;
- glyph->metrics.vertBearingY = (TT_Pos)metrics.vertBearingY << 6;
- glyph->metrics.vertAdvance = (TT_Pos)metrics.vertAdvance << 6;
-
- glyph->format = ft_glyph_format_bitmap;
- return error;
- }
+ loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
+ loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
}
- if ( load_flags & FT_LOAD_NO_OUTLINE )
- return ( error ? error : TT_Err_Unavailable_Bitmap );
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
- error = face->goto_table( face, TTAG_glyf, stream, 0 );
- if (error)
+ /**********************************************************************/
+ /* if it is a simple glyph, load it */
+ if (contours_count >= 0)
{
- FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
- return error;
- }
+ TT_UInt num_base_points;
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ error = Load_Simple( loader,
+ count,
+ contours_count,
+ (TT_Bool)( loader->size &&
+ loader->size->debug ) );
+#else
+ error = Load_Simple( loader, count, contours_count, 0 );
+#endif
+ if ( error )
+ goto Fail;
- glyph_offset = FILE_Pos();
+ /* Note: We could have put the simple loader source there */
+ /* but the code is fat enough already :-) */
+ num_points = loader->zone.n_points;
+ num_contours = loader->zone.n_contours;
+
+ num_base_points = loader->base.n_points;
+ {
+ TT_UInt k;
+ for ( k = 0; k < num_contours; k++ )
+ loader->zone.contours[k] += num_base_points;
+ }
- /* query new execution context */
+ loader->base.n_points += num_points;
+ loader->base.n_contours += num_contours;
- if ( size && size->debug )
- exec = size->context;
- else
- exec = TT_New_Context( face );
+ loader->zone.n_points = 0;
+ loader->zone.n_contours = 0;
- if ( !exec )
- return TT_Err_Could_Not_Find_Context;
-
- TT_Load_Context( exec, face, size );
-
- if ( size )
- {
- /* load default graphics state - if needed */
- if ( size->GS.instruct_control & 2 )
- exec->GS = tt_default_graphics_state;
-
- glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+ loader->left_points -= num_points;
+ loader->left_contours -= num_contours;
}
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
- /* save its critical pointers, as they'll be modified during load */
- base_pts = exec->pts;
-
- /* init variables */
- left_points = face->root.max_points; /* remove phantom points */
- left_contours = face->root.max_contours;
-
- num_points = 0;
- num_contours = 0;
-
- load_top = 0;
- subglyph = exec->loadStack;
-
- Init_Glyph_Component( subglyph, NULL, exec );
-
- subglyph->index = glyph_index;
- subglyph->is_hinted = !(load_flags & FT_LOAD_NO_HINTING);
-
- /* when the cvt program has disabled hinting, the argument */
- /* is ignored. */
- if ( size && (size->GS.instruct_control & 1) )
- subglyph->is_hinted = FALSE;
-
- /* Main loading loop */
-
- phase = Load_Glyph;
- index = 0;
-
- while ( phase != Load_Exit )
+ /************************************************************************/
+ else /* otherwise, load a composite !! */
{
- subglyph = exec->loadStack + load_top;
-
- switch ( phase )
+ /* for each subglyph, read composite header */
+ FT_SubGlyph* subglyph = subglyphs;
+
+ if (ACCESS_Frame(count)) goto Fail;
+
+ num_subglyphs = 0;
+ do
{
-
- /************************************************************/
- /* */
- /* Load_Glyph state */
- /* */
- /* reading a glyph's generic data, checking whether the */
- /* glyph is cached already (not implemented yet) */
- /* */
- /* exit states: Load_Header and Load_End */
- /* */
- case Load_Glyph:
- /* check glyph index and table */
-
- index = (TT_UInt)subglyph->index;
- if ( index >= face->root.num_glyphs )
- {
- error = TT_Err_Invalid_Glyph_Index;
- goto Fail;
- }
-
- /* get horizontal metrics */
- {
- TT_Short left_bearing;
- TT_UShort advance_width;
-
- Get_HMetrics( face, index, TRUE,
- &left_bearing,
- &advance_width );
-
- subglyph->left_bearing = left_bearing;
- subglyph->advance = advance_width;
- }
-
- phase = Load_Header;
-
- /************************************************************/
- /* */
- /* Load_Header state */
- /* */
- /* reading a glyph's generic header to determine whether */
- /* it is a simple or composite glyph */
- /* */
- /* exit states: Load_Simple and Load_Composite */
- /* */
- case Load_Header:
- /* load glyph */
-
- offset = face->glyph_locations[index];
- count = 0;
- if (index < face->num_locations-1)
- count = face->glyph_locations[index+1] - offset;
-
- if (count == 0)
- {
- /* as described by Frederic Loyer, these are spaces, and */
- /* not the unknown glyph. */
-
- num_contours = 0;
- num_points = 0;
-
- subglyph->bbox.xMin = 0;
- subglyph->bbox.xMax = 0;
- subglyph->bbox.yMin = 0;
- subglyph->bbox.yMax = 0;
-
- subglyph->pp1.x = 0;
- subglyph->pp2.x = subglyph->advance;
-
- if ( !(load_flags & FT_LOAD_NO_SCALE) )
- subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
-
- exec->glyphSize = 0;
- phase = Load_End;
- break;
- }
-
- offset = glyph_offset + offset;
-
- /* read first glyph header */
- if ( FILE_Seek( offset ) ||
- ACCESS_Frame( 10L ) )
- goto Fail_File;
-
- num_contours = GET_Short();
-
- subglyph->bbox.xMin = GET_Short();
- subglyph->bbox.yMin = GET_Short();
- subglyph->bbox.xMax = GET_Short();
- subglyph->bbox.yMax = GET_Short();
-
- FORGET_Frame();
-
- FT_TRACE6(( "Glyph %ld\n", index ));
- FT_TRACE6(( " # of contours : %d\n", num_contours ));
- FT_TRACE6(( " xMin: %4d xMax: %4d\n",
- subglyph->bbox.xMin,
- subglyph->bbox.xMax ));
- FT_TRACE6(( " yMin: %4d yMax: %4d\n",
- subglyph->bbox.yMin,
- subglyph->bbox.yMax ));
- FT_TRACE6(( "-" ));
-
- count -= 10;
-
- if ( num_contours > left_contours )
- {
- FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
- error = TT_Err_Too_Many_Contours;
- goto Fail;
- }
-
- subglyph->pp1.x = subglyph->bbox.xMin - subglyph->left_bearing;
- subglyph->pp1.y = 0;
- subglyph->pp2.x = subglyph->pp1.x + subglyph->advance;
- if (!(load_flags & FT_LOAD_NO_SCALE))
- {
- subglyph->pp1.x = SCALE_X( subglyph->pp1.x );
- subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
- }
-
- /* is it a simple glyph ? */
- if ( num_contours < 0 )
- {
- phase = Load_Composite;
- break;
- }
-
- phase = Load_Simple;
+ TT_Fixed xx, xy, yy, yx;
- /************************************************************/
- /* */
- /* Load_Simple state */
- /* */
- /* reading a simple glyph (num_contours must be set to */
- /* the glyph's number of contours.) */
- /* */
- /* exit state: Load_End */
- /* */
- case Load_Simple:
- new_flags = load_flags;
+ subglyph->arg1 = subglyph->arg2 = 0;
+
+ subglyph->flags = GET_UShort();
+ subglyph->index = GET_UShort();
- /* disable hinting when scaling */
- if ( !subglyph->is_hinted )
- new_flags |= FT_LOAD_NO_HINTING;
-
- error = Load_Simple_Glyph( exec,
- stream,
- count,
- num_contours,
- left_contours,
- left_points,
- new_flags,
- subglyph,
- (TT_Bool)(size && size->debug &&
- load_top == 0) );
- if ( error )
- goto Fail;
-
- /* Note: We could have put the simple loader source there */
- /* but the code is fat enough already :-) */
-
- num_points = exec->pts.n_points - 2;
-
- phase = Load_End;
- break;
-
- /************************************************************/
- /* */
- /* Load_Composite state */
- /* */
- /* reading a composite glyph header and pushing a new */
- /* load element on the stack. */
- /* */
- /* exit state: Load_Glyph */
- /* */
- case Load_Composite:
-
- /* create a new element on the stack */
- load_top++;
-
- if ( load_top > face->max_components )
+ /* read arguments */
+ if (subglyph->flags & ARGS_ARE_WORDS)
{
- error = TT_Err_Invalid_Composite;
- goto Fail;
+ subglyph->arg1 = GET_Short();
+ subglyph->arg2 = GET_Short();
}
-
- subglyph2 = exec->loadStack + load_top;
-
- Init_Glyph_Component( subglyph2, subglyph, NULL );
- subglyph2->is_hinted = subglyph->is_hinted;
-
- /* now read composite header */
-
- if ( ACCESS_Frame( 4L ) )
- goto Fail_File;
-
- subglyph->element_flag = new_flags = GET_UShort();
-
- subglyph2->index = GET_UShort();
-
- FORGET_Frame();
-
- k = 1+1;
-
- if ( new_flags & ARGS_ARE_WORDS )
- k *= 2;
-
- if ( new_flags & WE_HAVE_A_SCALE )
- k += 2;
-
- else if ( new_flags & WE_HAVE_AN_XY_SCALE )
- k += 4;
-
- else if ( new_flags & WE_HAVE_A_2X2 )
- k += 8;
-
- if ( ACCESS_Frame( k ) )
- goto Fail_File;
-
- if ( new_flags & ARGS_ARE_WORDS )
- {
- k = GET_Short();
- l = GET_Short();
- }
else
{
- k = GET_Char();
- l = GET_Char();
+ subglyph->arg1 = GET_Char();
+ subglyph->arg2 = GET_Char();
}
-
- subglyph->arg1 = k;
- subglyph->arg2 = l;
-
- if ( new_flags & ARGS_ARE_XY_VALUES )
+
+ /* read transform */
+ xx = yy = 0x10000;
+ xy = yx = 0;
+
+ if (subglyph->flags & WE_HAVE_A_SCALE)
{
- subglyph->transform.ox = k;
- subglyph->transform.oy = l;
- }
-
- xx = 0x10000;
- xy = 0;
- yx = 0;
- yy = 0x10000;
-
- if ( new_flags & WE_HAVE_A_SCALE )
- {
xx = (TT_Fixed)GET_Short() << 2;
yy = xx;
- subglyph2->is_scaled = TRUE;
}
- else if ( new_flags & WE_HAVE_AN_XY_SCALE )
+ else if (subglyph->flags & WE_HAVE_AN_XY_SCALE)
{
xx = (TT_Fixed)GET_Short() << 2;
yy = (TT_Fixed)GET_Short() << 2;
- subglyph2->is_scaled = TRUE;
}
- else if ( new_flags & WE_HAVE_A_2X2 )
+ else if (subglyph->flags & WE_HAVE_A_2X2)
{
xx = (TT_Fixed)GET_Short() << 2;
xy = (TT_Fixed)GET_Short() << 2;
yx = (TT_Fixed)GET_Short() << 2;
yy = (TT_Fixed)GET_Short() << 2;
- subglyph2->is_scaled = TRUE;
}
-
- FORGET_Frame();
-
+
subglyph->transform.xx = xx;
subglyph->transform.xy = xy;
subglyph->transform.yx = yx;
subglyph->transform.yy = yy;
+
+ subglyph++;
+ num_subglyphs++;
+ if (num_subglyphs >= TT_MAX_SUBGLYPHS)
+ break;
+ }
+ while (subglyph[-1].flags & MORE_COMPONENTS);
- k = FT_MulFix( xx, yy ) - FT_MulFix( xy, yx );
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ {
+ /* we must undo the ACCESS_Frame in order to point to the */
+ /* composite instructions, if we find some .. */
+ /* we will process them later.. */
+ ins_offset = FILE_Pos() + stream->cursor - stream->limit;
+ FORGET_Frame();
+ }
+#endif
- /* disable hinting in case of scaling/slanting */
- if ( ABS( k ) != 0x10000 )
- subglyph2->is_hinted = FALSE;
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
- subglyph->file_offset = FILE_Pos();
-
- phase = Load_Glyph;
- break;
-
- /************************************************************/
- /* */
- /* Load_End state */
- /* */
- /* after loading a glyph, apply transformation and offset */
- /* where necessary, pop element and continue or stop */
- /* process. */
- /* */
- /* exit states: Load_Composite and Load_Exit */
- /* */
- case Load_End:
- if ( load_top > 0 )
+ /*********************************************************************/
+ /* Now, read each subglyph independently.. */
+ {
+ TT_Int n, num_base_points, num_new_points;
+
+ subglyph = subglyphs;
+ for ( n = 0; n < num_subglyphs; n++, subglyph++ )
{
- subglyph2 = subglyph;
+ TT_Vector pp1, pp2;
+ TT_Pos x, y;
+
+ pp1 = loader->pp1;
+ pp2 = loader->pp2;
- load_top--;
- subglyph = exec->loadStack + load_top;
-
- /* check advance width and left side bearing */
-
- if ( !subglyph->preserve_pps &&
- subglyph->element_flag & USE_MY_METRICS )
+ num_base_points = loader->base.n_points;
+
+ error = load_truetype_glyph( loader, subglyph->index );
+ if ((subglyph->flags & USE_MY_METRICS) == 0)
{
- subglyph->left_bearing = subglyph2->left_bearing;
- subglyph->advance = subglyph2->advance;
-
- subglyph->pp1 = subglyph2->pp1;
- subglyph->pp2 = subglyph2->pp2;
-
- subglyph->preserve_pps = TRUE;
+ loader->pp1 = pp1;
+ loader->pp2 = pp2;
}
-
- /* apply scale */
-
- if ( subglyph2->is_scaled )
+
+ num_points = loader->base.n_points;
+ num_contours = loader->base.n_contours;
+
+ num_new_points = num_points - num_base_points;
+
+ /********************************************************/
+ /* now perform the transform required for this subglyph */
+
+ if ( subglyph->flags & ( WE_HAVE_A_SCALE |
+ WE_HAVE_AN_XY_SCALE |
+ WE_HAVE_A_2X2 ) )
{
- TT_Vector* cur = subglyph2->zone.cur;
- TT_Vector* org = subglyph2->zone.org;
+ TT_Vector* cur = loader->zone.cur;
+ TT_Vector* org = loader->zone.org;
+ TT_Vector* limit = cur + num_new_points;
-
- for ( u = 0; u < num_points; u++ )
+ for ( ; cur < limit; cur++, org++ )
{
+ TT_Pos nx, ny;
+
nx = FT_MulFix( cur->x, subglyph->transform.xx ) +
FT_MulFix( cur->y, subglyph->transform.yx );
@@ -1212,55 +758,39 @@
org->x = nx;
org->y = ny;
-
- cur++;
- org++;
}
}
- /* adjust counts */
-
- num_elem_points = subglyph->zone.n_points;
-
- for ( k = 0; k < num_contours; k++ )
- subglyph2->zone.contours[k] += num_elem_points;
-
- subglyph->zone.n_points += num_points;
- subglyph->zone.n_contours += num_contours;
-
- left_points -= num_points;
- left_contours -= num_contours;
-
/* apply offset */
- if ( !(subglyph->element_flag & ARGS_ARE_XY_VALUES) )
+ if ( !(subglyph->flags & ARGS_ARE_XY_VALUES) )
{
- k = subglyph->arg1;
- l = subglyph->arg2;
+ TT_Int k = subglyph->arg1;
+ TT_UInt l = subglyph->arg2;
- if ( k >= num_elem_points ||
- l >= num_points )
+ if ( k >= num_base_points ||
+ l >= (TT_UInt)num_new_points )
{
error = TT_Err_Invalid_Composite;
goto Fail;
}
- l += num_elem_points;
+ l += num_base_points;
- x = subglyph->zone.cur[k].x - subglyph->zone.cur[l].x;
- y = subglyph->zone.cur[k].y - subglyph->zone.cur[l].y;
+ x = loader->base.cur[k].x - loader->base.cur[l].x;
+ y = loader->base.cur[k].y - loader->base.cur[l].y;
}
else
{
- x = subglyph->transform.ox;
- y = subglyph->transform.oy;
+ x = subglyph->arg1;
+ y = subglyph->arg2;
- if (!(load_flags & FT_LOAD_NO_SCALE))
+ if (!(loader->load_flags & FT_LOAD_NO_SCALE))
{
- x = SCALE_X( x );
- y = SCALE_Y( y );
+ x = FT_MulFix( x, x_scale );
+ y = FT_MulFix( y, y_scale );
- if ( subglyph->element_flag & ROUND_XY_TO_GRID )
+ if ( subglyph->flags & ROUND_XY_TO_GRID )
{
x = (x + 32) & -64;
y = (y + 32) & -64;
@@ -1268,58 +798,157 @@
}
}
- translate_array( num_points, subglyph2->zone.cur, x, y );
+ translate_array( num_new_points, loader->zone.cur, x, y );
+ cur_to_org( num_new_points, &loader->zone );
+ }
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
- cur_to_org( num_points, &subglyph2->zone );
+ /* we have finished loading all sub-glyphs, now, look for */
+ /* instructions for this composite !! */
- num_points = subglyph->zone.n_points;
- num_contours = subglyph->zone.n_contours;
-
- /* check for last component */
-
- if ( FILE_Seek( subglyph->file_offset ) )
- goto Fail_File;
-
- if ( subglyph->element_flag & MORE_COMPONENTS )
- phase = Load_Composite;
- else
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ subglyph--;
+ if (num_subglyphs > 0 && subglyph->flags & WE_HAVE_INSTR)
+ {
+ TT_UShort n_ins;
+ TT_ExecContext exec = loader->exec;
+ TT_UInt n_points = loader->base.n_points;
+ TT_GlyphZone* pts;
+ TT_Vector* pp1;
+
+ /* read size of instructions */
+ if ( FILE_Seek( ins_offset ) ||
+ READ_UShort(n_ins) ) goto Fail;
+ FT_TRACE4(( "Instructions size = %d\n", n_ins ));
+
+ /* check it */
+ if ( n_ins > face->max_profile.maxSizeOfInstructions )
{
- error = Load_Composite_End( num_points,
- num_contours,
- exec,
- subglyph,
- stream,
- load_flags,
- (TT_Bool)(size && size->debug &&
- load_top == 0) );
- if ( error )
+ FT_TRACE0(( "Too many instructions in composite glyph %ld\n",
+ subglyph->index ));
+ return TT_Err_Too_Many_Ins;
+ }
+
+ /* read the instructions */
+ if ( FILE_Read( exec->glyphIns, n_ins ) )
+ goto Fail;
+
+ error = TT_Set_CodeRange( exec,
+ tt_coderange_glyph,
+ exec->glyphIns,
+ n_ins );
+ if ( error ) goto Fail;
+
+ /* prepare the execution context */
+ exec->pts = loader->base;
+ pts = &exec->pts;
+
+ pts->n_points = num_points + 2;
+ pts->n_contours = num_contours;
+
+ /* add phantom points */
+ pp1 = pts->cur + num_points;
+ pp1[0] = loader->pp1;
+ pp1[1] = loader->pp2;
+
+ pts->touch[num_points - 1] = 0;
+ pts->touch[num_points - 2] = 0;
+
+ /* if hinting, round the phantom points */
+ if ( IS_HINTED(loader->load_flags) )
+ {
+ pp1[0].x = ((loader->pp1.x + 32) & -64);
+ pp1[1].x = ((loader->pp2.x + 32) & -64);
+ }
+
+ {
+ TT_UInt k;
+ for ( k = 0; k < n_points; k++ )
+ pts->touch[k] &= FT_Curve_Tag_On;
+ }
+
+ cur_to_org( n_points, pts );
+
+ /* now consider hinting */
+ if ( IS_HINTED(loader->load_flags) && n_ins > 0 )
+ {
+ exec->is_composite = TRUE;
+ exec->pedantic_hinting =
+ (TT_Bool)(loader->load_flags & FT_LOAD_PEDANTIC);
+
+ error = TT_Run_Context( exec, loader->size->debug );
+ if ( error && exec->pedantic_hinting )
goto Fail;
-
- phase = Load_End;
}
+
+ /* save glyph origin and advance points */
+ loader->pp1 = pp1[0];
+ loader->pp2 = pp1[1];
}
- else
- phase = Load_Exit;
-
- break;
-
- case Load_Exit:
- break;
+#endif
+
}
}
- /* finally, copy the points arrays to the glyph object */
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
- exec->pts = base_pts;
+ Load_End:
+ error = TT_Err_Ok;
- for ( u = 0; u < num_points + 2; u++ )
+ Fail:
+ return error;
+ }
+
+
+
+
+
+ static
+ void compute_glyph_metrics( TT_Loader* loader,
+ TT_UInt glyph_index )
+ {
+ TT_UInt num_points = loader->base.n_points;
+ TT_UInt num_contours = loader->base.n_contours;
+ TT_BBox bbox;
+ TT_Face face = loader->face;
+ TT_Fixed x_scale, y_scale;
+ TT_GlyphSlot glyph = loader->glyph;
+ TT_Size size = loader->size;
+
+ /* when a simple glyph was loaded, the value of */
+ /* "base.n_points" and "base.n_contours" is 0, we must */
+ /* take those in the "zone" instead.. */
+ if ( num_points == 0 && num_contours == 0 )
{
- glyph->outline.points[u] = exec->pts.cur[u];
- glyph->outline.flags [u] = exec->pts.touch[u];
+ num_points = loader->zone.n_points;
+ num_contours = loader->zone.n_contours;
}
+
+ x_scale = 0x10000;
+ y_scale = 0x10000;
+ if ( (loader->load_flags & FT_LOAD_NO_SCALE) == 0)
+ {
+ x_scale = size->root.metrics.x_scale;
+ y_scale = size->root.metrics.y_scale;
+ }
+
+ {
+ TT_UInt u;
+ for ( u = 0; u < num_points + 2; u++ )
+ {
+ glyph->outline.points[u] = loader->base.cur[u];
+ glyph->outline.flags [u] = loader->base.touch[u];
+ }
- for ( k = 0; k < num_contours; k++ )
- glyph->outline.contours[k] = exec->pts.contours[k];
+ for ( u = 0; u < num_contours; u++ )
+ glyph->outline.contours[u] = loader->base.contours[u];
+ }
glyph->outline.n_points = num_points;
glyph->outline.n_contours = num_contours;
@@ -1328,12 +957,12 @@
/* translate array so that (0,0) is the glyph's origin */
translate_array( (TT_UShort)(num_points + 2),
glyph->outline.points,
- -subglyph->pp1.x,
+ -loader->pp1.x,
0 );
FT_Get_Outline_CBox( &glyph->outline, &bbox );
- if ( subglyph->is_hinted )
+ if ( IS_HINTED(loader->load_flags) )
{
/* grid-fit the bounding box */
bbox.xMin &= -64;
@@ -1348,17 +977,16 @@
TT_Pos left_bearing;
TT_Pos advance;
+ left_bearing = loader->left_bearing;
+ advance = loader->advance;
- left_bearing = subglyph->left_bearing;
- advance = subglyph->advance;
-
if ( face->postscript.isFixedPitch )
advance = face->horizontal.advance_Width_Max;
- if ( !(load_flags & FT_LOAD_NO_SCALE) )
+ if ( !(loader->load_flags & FT_LOAD_NO_SCALE) )
{
- left_bearing = SCALE_X( left_bearing );
- advance = SCALE_X( advance );
+ left_bearing = FT_MulFix( left_bearing, x_scale );
+ advance = FT_MulFix( advance, x_scale );
}
glyph->metrics2.horiBearingX = left_bearing;
@@ -1367,7 +995,7 @@
glyph->metrics.horiBearingX = bbox.xMin;
glyph->metrics.horiBearingY = bbox.yMax;
- glyph->metrics.horiAdvance = subglyph->pp2.x - subglyph->pp1.x;
+ glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
/* Now take care of vertical metrics. In the case where there is */
/* no vertical information within the font (relatively common), make */
@@ -1430,16 +1058,17 @@
TT_Get_Outline_BBox() */
/* scale the metrics */
- if ( !(load_flags & FT_LOAD_NO_SCALE) )
+ if ( !(loader->load_flags & FT_LOAD_NO_SCALE) )
{
- Top = SCALE_Y( top_bearing );
- top = SCALE_Y( top_bearing + subglyph->bbox.yMax ) - bbox.yMax;
- advance = SCALE_Y( advance_height );
+ Top = FT_MulFix( top_bearing, y_scale );
+ top = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale )
+ - bbox.yMax;
+ advance = FT_MulFix( advance_height, y_scale );
}
else
{
Top = top_bearing;
- top = top_bearing + subglyph->bbox.yMax - bbox.yMax;
+ top = top_bearing + loader->bbox.yMax - bbox.yMax;
advance = advance_height;
}
@@ -1452,7 +1081,7 @@
left = ( bbox.xMin - bbox.xMax ) / 2;
/* grid-fit them if necessary */
- if ( subglyph->is_hinted )
+ if ( IS_HINTED(loader->load_flags) )
{
left &= -64;
top = (top + 63) & -64;
@@ -1465,16 +1094,20 @@
}
/* Adjust advance width to the value contained in the hdmx table. */
- if ( !exec->face->postscript.isFixedPitch && size &&
- subglyph->is_hinted )
+ if ( !face->postscript.isFixedPitch && size &&
+ IS_HINTED(loader->load_flags) )
{
- widths = Get_Advance_Widths( exec->face,
- exec->size->root.metrics.x_ppem );
+ TT_Byte* widths = Get_Advance_Widths( face,
+ size->root.metrics.x_ppem );
if ( widths )
glyph->metrics.horiAdvance = widths[glyph_index] << 6;
}
- glyph->outline.dropout_mode = (TT_Char)exec->GS.scan_type;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ glyph->outline.dropout_mode = (TT_Char)loader->exec->GS.scan_type;
+#else
+ glyph->outline.dropout_mode = 2;
+#endif
/* set glyph dimensions */
glyph->metrics.width = bbox.xMax - bbox.xMin;
@@ -1481,20 +1114,178 @@
glyph->metrics.height = bbox.yMax - bbox.yMin;
glyph->format = ft_glyph_format_outline;
+ }
- error = TT_Err_Ok;
- Fail_File:
- Fail:
- /* reset the execution context */
- exec->pts = base_pts;
+
+
+
+
+
+
+
+
+ LOCAL_FUNC
+ TT_Error TT_Load_Glyph( TT_Size size,
+ TT_GlyphSlot glyph,
+ TT_UShort glyph_index,
+ TT_UInt load_flags )
+ {
+ SFNT_Interface* sfnt;
+ TT_Face face;
+ FT_Stream stream;
+ FT_Memory memory;
+ TT_Error error;
+ TT_Loader loader;
+
+ face = (TT_Face)glyph->face;
+ sfnt = (SFNT_Interface*)face->sfnt;
+ stream = face->root.stream;
+ memory = face->root.memory;
+ error = 0;
+
+ if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+ {
+ size = NULL;
+ load_flags |= FT_LOAD_NO_SCALE |
+ FT_LOAD_NO_HINTING |
+ FT_LOAD_NO_BITMAP;
+ }
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+ /*********************************************************************/
+ /* Try to load embedded bitmap if any */
+ if ( size && (load_flags & FT_LOAD_NO_BITMAP) == 0 && sfnt->load_sbits )
+ {
+ TT_SBit_Metrics metrics;
+
+ error = sfnt->load_sbit_image( face,
+ size->root.metrics.x_ppem,
+ size->root.metrics.y_ppem,
+ glyph_index,
+ stream,
+ &glyph->bitmap,
+ &metrics );
+ if ( !error )
+ {
+ glyph->outline.n_points = 0;
+ glyph->outline.n_contours = 0;
+
+ glyph->metrics.width = (TT_Pos)metrics.width << 6;
+ glyph->metrics.height = (TT_Pos)metrics.height << 6;
+
+ glyph->metrics.horiBearingX = (TT_Pos)metrics.horiBearingX << 6;
+ glyph->metrics.horiBearingY = (TT_Pos)metrics.horiBearingY << 6;
+ glyph->metrics.horiAdvance = (TT_Pos)metrics.horiAdvance << 6;
+
+ glyph->metrics.vertBearingX = (TT_Pos)metrics.vertBearingX << 6;
+ glyph->metrics.vertBearingY = (TT_Pos)metrics.vertBearingY << 6;
+ glyph->metrics.vertAdvance = (TT_Pos)metrics.vertAdvance << 6;
+
+ glyph->format = ft_glyph_format_bitmap;
+ return error;
+ }
+ }
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+
+ if ( load_flags & FT_LOAD_NO_OUTLINE )
+ return ( error ? error : TT_Err_Unavailable_Bitmap );
+
+ /* seek to the beginning of the glyph table. For Type 43 fonts */
+ /* the table might be accessed from a Postscript stream or something */
+ /* else... */
+ error = face->goto_table( face, TTAG_glyf, stream, 0 );
+ if (error)
+ {
+ FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
+ return error;
+ }
+
+ MEM_Set( &loader, 0, sizeof(loader) );
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ if ( size )
+ {
+ /* query new execution context */
+ loader.exec = size->debug ? size->context : TT_New_Context(face);
+ if ( !loader.exec )
+ return TT_Err_Could_Not_Find_Context;
+
+ TT_Load_Context( loader.exec, face, size );
+
+ /* load default graphics state - if needed */
+ if ( size->GS.instruct_control & 2 )
+ loader.exec->GS = tt_default_graphics_state;
+ }
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
+ if (size)
+ glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+
+ /************************************************************************/
+ /* let's initialise our loader now */
+ error = TT_New_GlyphZone( memory, &loader.base,
+ face->root.max_points, face->root.max_contours );
+ if (error) return error;
+
+ loader.left_points = face->root.max_points;
+ loader.left_contours = face->root.max_contours;
+ loader.load_flags = load_flags;
+
+ loader.face = face;
+ loader.size = size;
+ loader.glyph = glyph;
+ loader.stream = stream;
+
+ loader.glyf_offset = FILE_Pos();
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ /* when the cvt program has disabled hinting, the argument */
+ /* is ignored. */
+ if ( size && (size->GS.instruct_control & 1) )
+ loader.load_flags |= FT_LOAD_NO_HINTING;
+#endif
+
+ /* Main loading loop */
+ error = load_truetype_glyph( &loader, glyph_index );
+ if (!error)
+ compute_glyph_metrics( &loader, glyph_index );
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if ( !size || !size->debug )
- TT_Done_Context( exec );
+ TT_Done_Context( loader.exec );
+#endif
+ TT_Done_GlyphZone( memory, &loader.base );
return error;
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* END */
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -21,11 +21,48 @@
#include <ttobjs.h>
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#include <ttinterp.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
+ typedef struct TT_Loader_
+ {
+ TT_Face face;
+ TT_Size size;
+ TT_GlyphSlot glyph;
+ TT_ULong load_flags;
+
+ FT_Stream stream;
+ TT_Int byte_len;
+ TT_Int left_points;
+ TT_Int left_contours;
+
+ TT_BBox bbox;
+ TT_Int left_bearing;
+ TT_Int advance;
+ TT_Bool preserve_pps;
+ TT_Vector pp1;
+ TT_Vector pp2;
+
+ TT_ULong glyf_offset;
+
+ /* the zone where we load our glyphs */
+ TT_GlyphZone base;
+ TT_GlyphZone zone;
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ TT_ExecContext exec;
+ TT_Byte* instructions;
+#endif
+
+ } TT_Loader;
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -53,7 +90,7 @@
/* */
LOCAL_DEF
void TT_Get_Metrics( TT_HoriHeader* header,
- TT_UShort index,
+ TT_UInt index,
TT_Short* bearing,
TT_UShort* advance );
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -21,13 +21,18 @@
#include <ftcalc.h>
#include <ftstream.h>
#include <ttnameid.h>
+#include <tttags.h>
#include <sfnt.h>
+#include <ttobjs.h>
#include <ttpload.h>
-#include <ttinterp.h>
#include <tterrors.h>
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#include <ttinterp.h>
+#endif
+
/* required by tracing mode */
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttobjs
@@ -442,14 +447,16 @@
LOCAL_DEF
TT_Error TT_Init_Size( TT_Size size )
{
+ TT_Error error = 0;
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
TT_Face face = (TT_Face)size->root.face;
FT_Memory memory = face->root.memory;
- TT_Error error;
TT_Int i;
- TT_UShort n_twilight;
- TT_MaxProfile* maxp = &face->max_profile;
TT_ExecContext exec;
+ TT_UShort n_twilight;
+ TT_MaxProfile* maxp = &face->max_profile;
size->ttmetrics.valid = FALSE;
@@ -587,14 +594,19 @@
if ( !size->debug )
TT_Done_Context( exec );
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
size->ttmetrics.valid = FALSE;
return error;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Fail_Exec:
if ( !size->debug )
TT_Done_Context( exec );
Fail_Memory:
+#endif
+
TT_Done_Size( size );
return error;
}
@@ -614,9 +626,9 @@
LOCAL_FUNC
void TT_Done_Size( TT_Size size )
{
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_Memory memory = size->root.face->memory;
-
if ( size->debug )
{
/* the debug context must be deleted by the debugger itself */
@@ -643,6 +655,7 @@
size->max_func = 0;
size->max_ins = 0;
+#endif
size->ttmetrics.valid = FALSE;
}
@@ -663,10 +676,8 @@
LOCAL_DEF
TT_Error TT_Reset_Size( TT_Size size )
{
- TT_ExecContext exec;
- TT_Error error;
- TT_UShort i, j;
- TT_Face face;
+ TT_Face face;
+ TT_Error error = TT_Err_Ok;
FT_Size_Metrics* metrics;
@@ -713,73 +724,80 @@
metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
metrics->x_scale ) + 32 ) & -64;
- /* 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 );
-
- /* All twilight points are originally zero */
- for ( j = 0; j < size->twilight.n_points; j++ )
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
{
- size->twilight.org[j].x = 0;
- size->twilight.org[j].y = 0;
- size->twilight.cur[j].x = 0;
- size->twilight.cur[j].y = 0;
- }
-
- /* clear storage area */
- for ( i = 0; i < size->storage_size; i++ )
- size->storage[i] = 0;
-
- size->GS = tt_default_graphics_state;
-
- /* 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 */
-
- if ( !exec )
- return TT_Err_Could_Not_Find_Context;
-
- TT_Load_Context( exec, face, size );
-
- TT_Set_CodeRange( exec,
- tt_coderange_cvt,
- face->cvt_program,
- face->cvt_program_size );
-
- TT_Clear_CodeRange( exec, tt_coderange_glyph );
-
- exec->instruction_trap = FALSE;
-
- exec->top = 0;
- exec->callTop = 0;
-
- if ( face->cvt_program_size > 0 )
- {
- error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
- if ( error )
- goto Fin;
-
+ TT_ExecContext exec;
+ TT_UInt i, j;
+
+ /* 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 );
+
+ /* All twilight points are originally zero */
+ for ( j = 0; j < size->twilight.n_points; j++ )
+ {
+ size->twilight.org[j].x = 0;
+ size->twilight.org[j].y = 0;
+ size->twilight.cur[j].x = 0;
+ size->twilight.cur[j].y = 0;
+ }
+
+ /* clear storage area */
+ for ( i = 0; i < size->storage_size; i++ )
+ size->storage[i] = 0;
+
+ size->GS = tt_default_graphics_state;
+
+ /* 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 */
+
+ if ( !exec )
+ return TT_Err_Could_Not_Find_Context;
+
+ TT_Load_Context( exec, face, size );
+
+ TT_Set_CodeRange( exec,
+ tt_coderange_cvt,
+ face->cvt_program,
+ face->cvt_program_size );
+
+ TT_Clear_CodeRange( exec, tt_coderange_glyph );
+
+ exec->instruction_trap = FALSE;
+
+ exec->top = 0;
+ exec->callTop = 0;
+
+ if ( face->cvt_program_size > 0 )
+ {
+ error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+ if ( error )
+ goto Fin;
+
+ if ( !size->debug )
+ error = face->interpreter( exec );
+ }
+ else
+ error = TT_Err_Ok;
+
+ size->GS = exec->GS;
+ /* save default graphics state */
+
+ Fin:
+ TT_Save_Context( exec, size );
+
if ( !size->debug )
- error = face->interpreter( exec );
+ TT_Done_Context( exec );
+ /* debugging instances keep their context */
}
- else
- error = TT_Err_Ok;
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
- size->GS = exec->GS;
- /* save default graphics state */
-
- Fin:
- TT_Save_Context( exec, size );
-
- if ( !size->debug )
- TT_Done_Context( exec );
- /* debugging instances keep their context */
-
if ( !error )
size->ttmetrics.valid = TRUE;
@@ -888,6 +906,7 @@
TT_Done_Extensions( driver );
#endif
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
/* destroy the execution context */
if ( driver->context )
{
@@ -894,6 +913,7 @@
TT_Destroy_Context( driver->context, driver->root.memory );
driver->context = NULL;
}
+#endif
}
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -330,6 +330,7 @@
TT_Size_Metrics ttmetrics;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
TT_UInt num_function_defs; /* number of function definitions */
TT_UInt max_function_defs;
TT_DefArray function_defs; /* table of function definitions */
@@ -361,6 +362,8 @@
TT_Bool debug;
TT_ExecContext context;
+
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
} TT_SizeRec;