ref: 0142e6aff1f0836a7ec3902969491ab6ac7182aa
parent: f20a4d35278312801d75613b54e771a9223a26b4
author: Wu, Chia-I (吳佳一) <[email protected]>
date: Mon Aug 15 21:54:59 EDT 2005
* src/truetype/ttinterp.c, src/truetype/ttinterp.h: Remove original TT_Done_Context and rename TT_Destroy_Context to TT_Done_Context with slight changes. * src/truetype/ttobjs.h (tt_slot_init): New function. * src/truetype/ttobjs.c (tt_driver_init): Initialize execution context here. (tt_slot_init): New function to create extra points for the internal glyph loader. We then use it directly, instead of face's glyph loader, when loading glyph. * src/truetype/ttdriver.c: Use tt_slot_init for glyph slot initialization. (TT_Load_Glyph): Load flag dependencies are handled here. Return error if size is NULL. * src/truetype/ttgload.c: Heavy cleanup and refactor. (TT_Hint_Glyph): New funcion to hint a zone, prepared by caller. (TT_Process_Simple_Glyph): Use loader->pp's instead of recalculating. Use TT_Hint_Glyph. No need to save/restore loader->stream before/after TT_Vary_Get_Glyph_Deltas now. (TT_LOADER_SET_PP): New macro to calculate and set the four phantom points. (TT_Process_Composite_Component, TT_Process_Composite_Glyph, load_truetype_glyph): Refactor load_truetype_glyph into these three functions. Never set exec->glyphSize to 0. (close #13107) Forget glyph frame before calling TT_Process_Simple_Glyph. (TT_Load_Glyph, load_sbit_image, tt_loader_init): Refactor TT_Load_Glyph into these three functions. Set various fields of `glyph' here, instead of in load_truetype_glyph and compute_glyph_metrics.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2005-08-16 Chia I Wu <[email protected]>
+
+ * src/truetype/ttinterp.c, src/truetype/ttinterp.h: Remove original
+ TT_Done_Context and rename TT_Destroy_Context to TT_Done_Context with
+ slight changes.
+
+ * src/truetype/ttobjs.h (tt_slot_init): New function.
+
+ * src/truetype/ttobjs.c (tt_driver_init): Initialize execution context
+ here.
+ (tt_slot_init): New function to create extra points for the internal
+ glyph loader. We then use it directly, instead of face's glyph loader,
+ when loading glyph.
+
+ * src/truetype/ttdriver.c: Use tt_slot_init for glyph slot
+ initialization.
+ (TT_Load_Glyph): Load flag dependencies are handled here.
+ Return error if size is NULL.
+
+ * src/truetype/ttgload.c: Heavy cleanup and refactor.
+ (TT_Hint_Glyph): New funcion to hint a zone, prepared by caller.
+ (TT_Process_Simple_Glyph): Use loader->pp's instead of recalculating.
+ Use TT_Hint_Glyph.
+ No need to save/restore loader->stream before/after
+ TT_Vary_Get_Glyph_Deltas now.
+ (TT_LOADER_SET_PP): New macro to calculate and set the four phantom points.
+ (TT_Process_Composite_Component, TT_Process_Composite_Glyph,
+ load_truetype_glyph): Refactor load_truetype_glyph into these three functions.
+ Never set exec->glyphSize to 0. (close #13107)
+ Forget glyph frame before calling TT_Process_Simple_Glyph.
+ (TT_Load_Glyph, load_sbit_image, tt_loader_init): Refactor TT_Load_Glyph into
+ these three functions.
+ Set various fields of `glyph' here, instead of in load_truetype_glyph
+ and compute_glyph_metrics.
+
2005-08-08 Werner Lemberg <[email protected]>
* docs/INSTALL.ANY: Updated.
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -283,25 +283,14 @@
if ( !slot )
return TT_Err_Invalid_Slot_Handle;
- /* check whether we want a scaled outline or bitmap */
- if ( !size )
- load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
+ if ( !size || !size->ttmetrics.valid )
+ return TT_Err_Invalid_Size_Handle;
- if ( load_flags & FT_LOAD_NO_SCALE )
- size = NULL;
-
- /* reset the size object if necessary */
- if ( size )
+ if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
{
- /* these two object must have the same parent */
- if ( size->root.face != slot->face )
- return TT_Err_Invalid_Face_Handle;
-
- if ( !size->ttmetrics.valid )
- {
- if ( FT_SET_ERROR( tt_size_reset( size ) ) )
- return error;
- }
+ load_flags |= FT_LOAD_NO_HINTING |
+ FT_LOAD_NO_BITMAP |
+ FT_LOAD_NO_SCALE;
}
/* now load the glyph outline if necessary */
@@ -409,8 +398,8 @@
tt_face_done,
tt_size_init,
tt_size_done,
- 0, /* FT_Slot_InitFunc */
- 0, /* FT_Slot_DoneFunc */
+ tt_slot_init,
+ 0, /* FT_Slot_DoneFunc */
Set_Char_Sizes,
Set_Pixel_Sizes,
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -312,13 +312,6 @@
}
-#define cur_to_org( n, zone ) \
- FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) )
-
-#define org_to_cur( n, zone ) \
- FT_ARRAY_COPY( (zone)->cur, (zone)->org, (n) )
-
-
/*************************************************************************/
/* */
/* Translates an array of coordinates. */
@@ -342,21 +335,6 @@
}
- static void
- tt_prepare_zone( TT_GlyphZone zone,
- FT_GlyphLoad load,
- FT_UInt start_point,
- FT_UInt start_contour )
- {
- zone->n_points = (FT_UShort)( load->outline.n_points - start_point );
- zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour );
- zone->org = load->extra_points + start_point;
- zone->cur = load->outline.points + start_point;
- zone->tags = (FT_Byte*)load->outline.tags + start_point;
- zone->contours = (FT_UShort*)load->outline.contours + start_contour;
- }
-
-
#undef IS_HINTED
#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 )
@@ -439,7 +417,6 @@
FT_Int n_contours = load->n_contours;
FT_Outline* outline;
TT_Face face = (TT_Face)load->face;
- TT_GlyphSlot slot = (TT_GlyphSlot)load->glyph;
FT_UShort n_ins;
FT_Int n, n_points;
FT_Int byte_len = load->byte_len;
@@ -451,6 +428,11 @@
FT_Short *cont, *cont_limit;
+ /* check that we can add the contours to the glyph */
+ error = FT_GlyphLoader_CheckPoints( gloader, 0, n_contours );
+ if ( error )
+ goto Fail;
+
/* reading the contours' endpoints & number of points */
cont = gloader->current.outline.contours;
cont_limit = cont + n_contours;
@@ -467,6 +449,7 @@
if ( n_contours > 0 )
n_points = cont[-1] + 1;
+ /* note that we will add four phantom points later */
error = FT_GlyphLoader_CheckPoints( gloader, n_points + 4, 0 );
if ( error )
goto Fail;
@@ -479,8 +462,8 @@
goto Invalid_Outline;
/* reading the bytecode instructions */
- slot->control_len = 0;
- slot->control_data = 0;
+ load->glyph->control_len = 0;
+ load->glyph->control_data = 0;
n_ins = FT_GET_USHORT();
@@ -503,14 +486,12 @@
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- if ( ( load->load_flags &
- ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0 &&
- load->instructions )
+ if ( IS_HINTED( load->load_flags ) )
{
- slot->control_len = n_ins;
- slot->control_data = load->instructions;
+ load->glyph->control_len = n_ins;
+ load->glyph->control_data = load->exec->glyphIns;
- FT_MEM_COPY( load->instructions, stream->cursor, (FT_Long)n_ins );
+ FT_MEM_COPY( load->exec->glyphIns, stream->cursor, (FT_Long)n_ins );
}
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
@@ -723,6 +704,7 @@
gloader->current.num_subglyphs = num_subglyphs;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
{
/* we must undo the FT_FRAME_ENTER in order to point to the */
/* composite instructions, if we find some. */
@@ -731,6 +713,7 @@
loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
stream->cursor - stream->limit );
}
+
#endif
loader->byte_len = byte_len;
@@ -755,106 +738,156 @@
}
+ static void
+ tt_prepare_zone( TT_GlyphZone zone,
+ FT_GlyphLoad load,
+ FT_UInt start_point,
+ FT_UInt start_contour )
+ {
+ zone->n_points = (FT_UShort)( load->outline.n_points - start_point );
+ zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour );
+ zone->org = load->extra_points + start_point;
+ zone->cur = load->outline.points + start_point;
+ zone->tags = (FT_Byte*)load->outline.tags + start_point;
+ zone->contours = (FT_UShort*)load->outline.contours + start_contour;
+ }
+
+
/*************************************************************************/
/* */
/* <Function> */
- /* TT_Process_Simple_Glyph */
+ /* TT_Hint_Glyph */
/* */
/* <Description> */
- /* Once a simple glyph has been loaded, it needs to be processed. */
- /* Usually, this means scaling and hinting through bytecode */
- /* interpretation. */
+ /* Hint the glyph using the zone prepared by the caller. Note that */
+ /* the zone is supposed to include four phantom points. */
/* */
+#define cur_to_org( n, zone ) \
+ FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) )
static FT_Error
- TT_Process_Simple_Glyph( TT_Loader load,
- FT_Bool debug )
+ TT_Hint_Glyph( TT_Loader loader,
+ FT_Bool is_composite )
{
- FT_GlyphLoader gloader = load->gloader;
- FT_Outline* outline = &gloader->current.outline;
- FT_UInt n_points = outline->n_points;
+ TT_GlyphZone zone = &loader->zone;
+ FT_Pos origin;
+
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- FT_UInt n_ins;
-#endif
- TT_GlyphZone zone = &load->zone;
- FT_Error error = TT_Err_Ok;
- FT_UNUSED( debug ); /* used by truetype interpreter only */
+ FT_UInt n_ins;
+ n_ins = loader->glyph->control_len;
+
+#endif
+
+ origin = zone->cur[zone->n_points - 4].x;
+ origin = FT_PIX_ROUND( origin ) - origin;
+ if ( origin )
+ translate_array( zone->n_points, zone->cur, origin, 0 );
+
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- n_ins = load->glyph->control_len;
+
+ /* save original point positioin in org */
+ if ( n_ins > 0 )
+ cur_to_org( zone->n_points, zone );
+
#endif
- /* add shadow points */
+ /* round pp2 and pp4 */
+ zone->cur[zone->n_points - 3].x = FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
+ zone->cur[zone->n_points - 1].y = FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
- /* Add two horizontal shadow points at n and n+1. */
- /* We need the left side bearing and advance width. */
- /* Add two vertical shadow points at n+2 and n+3. */
- /* We need the top side bearing and advance height. */
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ if ( n_ins > 0 )
{
- FT_Vector* pp1;
- FT_Vector* pp2;
- FT_Vector* pp3;
- FT_Vector* pp4;
+ FT_Bool debug;
+ FT_Error error;
- /* pp1 = xMin - lsb */
- pp1 = outline->points + n_points;
- pp1->x = load->bbox.xMin - load->left_bearing;
- pp1->y = 0;
+ error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
+ loader->exec->glyphIns, n_ins );
+ if ( error )
+ return error;
- /* pp2 = pp1 + aw */
- pp2 = pp1 + 1;
- pp2->x = pp1->x + load->advance;
- pp2->y = 0;
+ loader->exec->is_composite = is_composite;
+ loader->exec->pts = *zone;
- /* pp3 = top side bearing */
- pp3 = pp1 + 2;
- pp3->x = 0;
- pp3->y = load->top_bearing + load->bbox.yMax;
+ debug = !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
+ ( (TT_Size)loader->size )->debug;
- /* pp4 = pp3 - ah */
- pp4 = pp1 + 3;
- pp4->x = 0;
- pp4->y = pp3->y - load->vadvance;
+ error = TT_Run_Context( loader->exec, debug );
+ if ( error && loader->exec->pedantic_hinting )
+ return error;
+ }
- outline->tags[n_points ] = 0;
- outline->tags[n_points + 1] = 0;
- outline->tags[n_points + 2] = 0;
- outline->tags[n_points + 3] = 0;
+#endif
+
+ /* save glyph phantom points */
+ if ( !loader->preserve_pps )
+ {
+ loader->pp1 = zone->cur[zone->n_points - 4];
+ loader->pp2 = zone->cur[zone->n_points - 3];
+ loader->pp3 = zone->cur[zone->n_points - 2];
+ loader->pp4 = zone->cur[zone->n_points - 1];
}
- /* Note that we return four more points that are not */
- /* part of the glyph outline. */
+ return TT_Err_Ok;
+ }
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Process_Simple_Glyph */
+ /* */
+ /* <Description> */
+ /* Once a simple glyph has been loaded, it needs to be processed. */
+ /* Usually, this means scaling and hinting through bytecode */
+ /* interpretation. */
+ /* */
+ static FT_Error
+ TT_Process_Simple_Glyph( TT_Loader loader )
+ {
+ FT_GlyphLoader gloader = loader->gloader;
+ FT_Error error = TT_Err_Ok;
+ FT_Outline* outline;
+ FT_UInt n_points;
+
+
+ outline = &gloader->current.outline;
+ n_points = outline->n_points;
+
+ /* set phantom points */
+
+ outline->points[n_points ] = loader->pp1;
+ outline->points[n_points + 1] = loader->pp2;
+ outline->points[n_points + 2] = loader->pp3;
+ outline->points[n_points + 3] = loader->pp4;
+
+ outline->tags[n_points ] = 0;
+ outline->tags[n_points + 1] = 0;
+ outline->tags[n_points + 2] = 0;
+ outline->tags[n_points + 3] = 0;
+
n_points += 4;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- if ( ((TT_Face)load->face)->doblend )
+ if ( ((TT_Face)loader->face)->doblend )
{
/* Deltas apply to the unscaled data. */
FT_Vector* deltas;
- FT_Memory memory = load->face->memory;
- FT_StreamRec saved_stream = *(load->stream);
+ FT_Memory memory = loader->face->memory;
FT_UInt i;
- /* TT_Vary_Get_Glyph_Deltas uses a frame, thus we have to save */
- /* (and restore) the current one */
- load->stream->cursor = 0;
- load->stream->limit = 0;
-
- error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(load->face),
- load->glyph_index,
+ error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
+ loader->glyph_index,
&deltas,
n_points );
-
- *(load->stream) = saved_stream;
-
if ( error )
- goto Exit;
+ return error;
for ( i = 0; i < n_points; ++i )
{
@@ -867,84 +900,290 @@
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
- /* set up zone for hinting */
- tt_prepare_zone( zone, &gloader->current, 0, 0 );
-
- /* eventually scale the glyph */
- if ( !( load->load_flags & FT_LOAD_NO_SCALE ) )
+ /* scale the glyph */
+ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
- FT_Vector* vec = zone->cur;
- FT_Vector* limit = vec + n_points;
- FT_Fixed x_scale = ((TT_Size)load->size)->metrics.x_scale;
- FT_Fixed y_scale = ((TT_Size)load->size)->metrics.y_scale;
+ FT_Vector* vec = outline->points;
+ FT_Vector* limit = outline->points + n_points;
+ FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale;
+ FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale;
- /* first scale the glyph points */
+
for ( ; vec < limit; vec++ )
{
vec->x = FT_MulFix( vec->x, x_scale );
vec->y = FT_MulFix( vec->y, y_scale );
}
+
+ loader->pp1 = outline->points[n_points - 4];
+ loader->pp2 = outline->points[n_points - 3];
+ loader->pp3 = outline->points[n_points - 2];
+ loader->pp4 = outline->points[n_points - 1];
}
- cur_to_org( n_points, zone );
+ if ( IS_HINTED( loader->load_flags ) )
+ {
+ tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
+ loader->zone.n_points += 4;
- /* eventually hint the glyph */
- if ( IS_HINTED( load->load_flags ) )
+ error = TT_Hint_Glyph( loader, 0 );
+ }
+
+ return error;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Process_Composite_Component */
+ /* */
+ /* <Description> */
+ /* Once a composite component has been loaded, it needs to be */
+ /* processed. Usually, this means transforming and translating. */
+ /* */
+ static FT_Error
+ TT_Process_Composite_Component( TT_Loader loader,
+ FT_SubGlyph subglyph,
+ FT_UInt start_point,
+ FT_UInt num_base_points )
+ {
+ FT_GlyphLoader gloader = loader->gloader;
+ FT_Vector* base_vec = gloader->base.outline.points;
+ FT_UInt num_points = gloader->base.outline.n_points;
+ FT_Bool have_scale;
+ FT_Pos x, y;
+
+
+ have_scale = ( subglyph->flags & ( WE_HAVE_A_SCALE |
+ WE_HAVE_AN_XY_SCALE |
+ WE_HAVE_A_2X2 ) );
+
+ /* perform the transform required for this subglyph */
+ if ( have_scale )
{
- FT_Pos x = zone->org[n_points-4].x;
+ FT_UInt i;
- x = FT_PIX_ROUND( x ) - x;
- translate_array( n_points, zone->org, x, 0 );
+ for ( i = num_base_points; i < num_points; i++ )
+ FT_Vector_Transform( base_vec + i, &subglyph->transform );
+ }
- org_to_cur( n_points, zone );
+ /* get offset */
+ if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
+ {
+ FT_UInt k = subglyph->arg1;
+ FT_UInt l = subglyph->arg2;
+ FT_Vector* p1;
+ FT_Vector* p2;
- zone->cur[n_points - 3].x = FT_PIX_ROUND( zone->cur[n_points - 3].x );
- zone->cur[n_points - 1].y = FT_PIX_ROUND( zone->cur[n_points - 1].y );
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ /* match l-th point of the newly loaded component to the k-th point of */
+ /* the previously loaded components. */
- /* now consider hinting */
- if ( n_ins > 0 )
+ /* change to the point numbers used by our outline */
+ k += start_point;
+ l += num_base_points;
+ if ( k >= (FT_UInt)num_base_points ||
+ l >= (FT_UInt)num_points )
{
- error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
- load->exec->glyphIns, n_ins );
- if ( error )
- goto Exit;
+ return TT_Err_Invalid_Composite;
+ }
- load->exec->is_composite = FALSE;
- load->exec->pts = *zone;
- load->exec->pts.n_points += 4;
+ p1 = gloader->base.outline.points + k;
+ p2 = gloader->base.outline.points + l;
- error = TT_Run_Context( load->exec, debug );
- if ( error && load->exec->pedantic_hinting )
- goto Exit;
+ x = p1->x - p2->x;
+ y = p1->y - p2->y;
+ }
+ else
+ {
+ x = subglyph->arg1;
+ y = subglyph->arg2;
- error = TT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */
+ if ( !x && !y )
+ return TT_Err_Ok;
+
+/* Use a default value dependent on */
+/* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */
+/* fonts which don't set the xxx_COMPONENT_OFFSET bit. */
+
+ if ( have_scale &&
+#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
+ !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
+#else
+ ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
+#endif
+ {
+#if 0
+
+/*************************************************************************/
+/* */
+/* This algorithm is what Apple documents. But it doesn't work. */
+/* */
+ int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
+ : -subglyph->transform.xx;
+ int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
+ : -subglyph->transform.yx;
+ int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
+ : -subglyph->transform.xy;
+ int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
+ : -subglyph->transform.yy;
+ int m = a > b ? a : b;
+ int n = c > d ? c : d;
+
+
+ if ( a - b <= 33 && a - b >= -33 )
+ m *= 2;
+ if ( c - d <= 33 && c - d >= -33 )
+ n *= 2;
+ x = FT_MulFix( x, m );
+ y = FT_MulFix( y, n );
+
+#else /* 0 */
+
+/*************************************************************************/
+/* */
+/* This algorithm is a guess and works much better than the above. */
+/* */
+ FT_Fixed mac_xscale = FT_SqrtFixed(
+ FT_MulFix( subglyph->transform.xx,
+ subglyph->transform.xx ) +
+ FT_MulFix( subglyph->transform.xy,
+ subglyph->transform.xy) );
+ FT_Fixed mac_yscale = FT_SqrtFixed(
+ FT_MulFix( subglyph->transform.yy,
+ subglyph->transform.yy ) +
+ FT_MulFix( subglyph->transform.yx,
+ subglyph->transform.yx ) );
+
+
+ x = FT_MulFix( x, mac_xscale );
+ y = FT_MulFix( y, mac_yscale );
+
+#endif /* 0 */
+
}
-#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
+ {
+ FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale;
+ FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale;
+
+ x = FT_MulFix( x, x_scale );
+ y = FT_MulFix( y, y_scale );
+
+ if ( subglyph->flags & ROUND_XY_TO_GRID )
+ {
+ x = FT_PIX_ROUND( x );
+ y = FT_PIX_ROUND( y );
+ }
+ }
}
- /* save glyph phantom points */
- if ( !load->preserve_pps )
+ if ( x || y )
+ translate_array( num_points - num_base_points,
+ base_vec + num_base_points,
+ x, y );
+
+ return TT_Err_Ok;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* TT_Process_Composite_Glyph */
+ /* */
+ /* <Description> */
+ /* This is slightly different from TT_Process_Simple_Glyph, in that */
+ /* it's sole purpose is to hint the glyph. Thus this function is */
+ /* only available when bytecode interpreter is enabled. */
+ /* */
+ static FT_Error
+ TT_Process_Composite_Glyph( TT_Loader loader,
+ FT_UInt start_point,
+ FT_UInt start_contour )
+ {
+ FT_Error error;
+ FT_Outline* outline;
+
+
+ outline = &loader->gloader->base.outline;
+
+ /* make room for phantom points */
+ error = FT_GlyphLoader_CheckPoints( loader->gloader, outline->n_points + 4, 0 );
+ if ( error )
+ return error;
+
+ outline->points[outline->n_points ] = loader->pp1;
+ outline->points[outline->n_points + 1] = loader->pp2;
+ outline->points[outline->n_points + 2] = loader->pp3;
+ outline->points[outline->n_points + 3] = loader->pp4;
+
+ outline->tags[outline->n_points ] = 0;
+ outline->tags[outline->n_points + 1] = 0;
+ outline->tags[outline->n_points + 2] = 0;
+ outline->tags[outline->n_points + 3] = 0;
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
{
- load->pp1 = zone->cur[n_points - 4];
- load->pp2 = zone->cur[n_points - 3];
- load->pp3 = zone->cur[n_points - 2];
- load->pp4 = zone->cur[n_points - 1];
+ FT_Stream stream = loader->stream;
+ FT_UShort n_ins;
+
+
+ /* TT_Load_Composite_Glyph only gives us the offset of instructions */
+ /* so we read them here */
+ if ( FT_STREAM_SEEK( loader->ins_pos ) ||
+ FT_READ_USHORT( n_ins ) )
+ return error;
+
+ FT_TRACE5(( " Instructions size = %d\n", n_ins ));
+
+ /* check it */
+ if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions )
+ {
+ FT_TRACE0(( "Too many instructions (%d)\n", n_ins ));
+
+ return TT_Err_Too_Many_Hints;
+ }
+ else if ( n_ins == 0 )
+ return TT_Err_Ok;
+
+ if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
+ return error;
+
+ loader->glyph->control_data = loader->exec->glyphIns;
+ loader->glyph->control_len = n_ins;
}
-#if defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) || \
- defined( TT_CONFIG_OPTION_GX_VAR_SUPPORT )
- Exit:
#endif
- return error;
+ tt_prepare_zone( &loader->zone, &loader->gloader->base, start_point, start_contour );
+ loader->zone.n_points += 4;
+
+ return TT_Hint_Glyph( loader, 1 );
}
+ /* Calculate the four phantom points. */
+ /* The first two stand for horizontal origin and advance. */
+ /* The last two stand for vertical origin and advance. */
+#define TT_LOADER_SET_PP( loader ) \
+ do { \
+ (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; \
+ (loader)->pp3.x = 0; \
+ (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax; \
+ (loader)->pp4.x = 0; \
+ (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \
+ } while ( 0 )
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -959,28 +1198,25 @@
FT_UInt glyph_index,
FT_UInt recurse_count )
{
-
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- FT_Stream stream = loader->stream;
-#endif
-
FT_Error error;
- TT_Face face = (TT_Face)loader->face;
- FT_ULong offset;
- FT_Int contours_count;
- FT_UInt num_points, count;
FT_Fixed x_scale, y_scale;
- FT_GlyphLoader gloader = loader->gloader;
+ FT_ULong offset;
+ TT_Face face = (TT_Face)loader->face;
+ FT_GlyphLoader gloader = loader->gloader;
FT_Bool opened_frame = 0;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+ FT_Vector* deltas = NULL;
+
+#endif
+
#ifdef FT_CONFIG_OPTION_INCREMENTAL
+
FT_StreamRec inc_stream;
FT_Data glyph_data;
FT_Bool glyph_data_loaded = 0;
-#endif
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- FT_Vector *deltas;
#endif
@@ -998,15 +1234,17 @@
}
loader->glyph_index = glyph_index;
- num_points = 0;
- x_scale = 0x10000L;
- y_scale = 0x10000L;
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
x_scale = ((TT_Size)loader->size)->metrics.x_scale;
y_scale = ((TT_Size)loader->size)->metrics.y_scale;
}
+ else
+ {
+ x_scale = 0x10000L;
+ y_scale = 0x10000L;
+ }
/* get metrics, horizontal and vertical */
{
@@ -1045,16 +1283,9 @@
goto Exit;
left_bearing = (FT_Short)metrics.bearing_x;
advance_width = (FT_UShort)metrics.advance;
- }
-
# if 0
- /* GWW: Do I do the same for vertical metrics ??? */
- if ( face->root.internal->incremental_interface &&
- face->root.internal->incremental_interface->funcs->get_glyph_metrics )
- {
- FT_Incremental_MetricsRec metrics;
-
+ /* GWW: Do I do the same for vertical metrics ??? */
metrics.bearing_x = 0;
metrics.bearing_y = top_bearing;
metrics.advance = advance_height;
@@ -1065,9 +1296,11 @@
goto Exit;
top_bearing = (FT_Short)metrics.bearing_y;
advance_height = (FT_UShort)metrics.advance;
- }
+
# endif
+ }
+
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
loader->left_bearing = left_bearing;
@@ -1082,16 +1315,15 @@
}
}
+ /* Set `offset' to the start of the glyph relative to the start of */
+ /* the 'glyf' table, and `byte_len' to the length of the glyph in */
+ /* bytes. */
+
#ifdef FT_CONFIG_OPTION_INCREMENTAL
- /* Set `offset' to the start of the glyph program relative to the */
- /* start of the 'glyf' table, and `count' to the length of the */
- /* glyph program in bytes. */
- /* */
/* If we are loading glyph data via the incremental interface, set */
/* the loader stream to a memory stream reading the data returned */
/* by the interface. */
-
if ( face->root.internal->incremental_interface )
{
error = face->root.internal->incremental_interface->funcs->get_glyph_data(
@@ -1102,7 +1334,7 @@
glyph_data_loaded = 1;
offset = 0;
- count = glyph_data.length;
+ byte_len = glyph_data.length;
FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
FT_Stream_OpenMemory( &inc_stream,
@@ -1114,23 +1346,21 @@
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
- offset = tt_face_get_location( face, glyph_index, &count );
+ offset = tt_face_get_location( face, glyph_index, (FT_UInt*)&loader->byte_len );
- if ( count == 0 )
+ if ( loader->byte_len == 0 )
{
- /* as described by Frederic Loyer, these are spaces, and */
- /* not the unknown glyph. */
+ /* as described by Frederic Loyer, these are spaces or */
+ /* the unknown glyph. */
loader->bbox.xMin = 0;
loader->bbox.xMax = 0;
loader->bbox.yMin = 0;
loader->bbox.yMax = 0;
- loader->pp1.x = 0;
- loader->pp2.x = loader->advance;
- loader->pp3.y = 0;
- loader->pp4.y = loader->pp3.y-loader->vadvance;
+ TT_LOADER_SET_PP( loader );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
if ( ((TT_Face)(loader->face))->doblend )
{
/* this must be done before scaling */
@@ -1149,31 +1379,24 @@
FT_FREE( deltas );
}
+
#endif
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
{
+ loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
+ loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
}
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
- if ( loader->exec )
- loader->exec->glyphSize = 0;
-
-#endif
-
error = TT_Err_Ok;
goto Exit;
}
- loader->byte_len = (FT_Int)count;
-
- offset = loader->glyf_offset + offset;
-
- /* access glyph frame */
- error = face->access_glyph_frame( loader, glyph_index, offset, count );
+ error = face->access_glyph_frame( loader, glyph_index,
+ loader->glyf_offset + offset,
+ loader->byte_len );
if ( error )
goto Exit;
@@ -1182,22 +1405,10 @@
/* read first glyph header */
error = face->read_glyph_header( loader );
if ( error )
- goto Fail;
+ goto Exit;
- contours_count = loader->n_contours;
+ TT_LOADER_SET_PP( loader );
- count -= 10;
-
- 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;
-
- loader->pp3.x = 0;
- loader->pp3.y = loader->top_bearing + loader->bbox.yMax;
- loader->pp4.x = 0;
- loader->pp4.y = loader->pp3.y - loader->vadvance;
-
/***********************************************************************/
/***********************************************************************/
/***********************************************************************/
@@ -1204,40 +1415,21 @@
/* if it is a simple glyph, load it */
- if ( contours_count >= 0 )
+ if ( loader->n_contours >= 0 )
{
- /* check that we can add the contours to the glyph */
- error = FT_GlyphLoader_CheckPoints( gloader, 0, contours_count );
- if ( error )
- goto Fail;
-
error = face->read_simple_glyph( loader );
if ( error )
- goto Fail;
+ goto Exit;
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ /* all data have been read */
+ face->forget_glyph_frame( loader );
+ opened_frame = 0;
- {
- TT_Size size = (TT_Size)loader->size;
-
-
- error = TT_Process_Simple_Glyph( loader,
- (FT_Bool)( size && size->debug ) );
- }
-
-#else
-
- error = TT_Process_Simple_Glyph( loader, 0 );
-
-#endif
-
+ error = TT_Process_Simple_Glyph( loader );
if ( error )
- goto Fail;
+ goto Exit;
FT_GlyphLoader_Add( gloader );
-
- /* Note: We could have put the simple loader source there */
- /* but the code is fat enough already :-) */
}
/***********************************************************************/
@@ -1245,29 +1437,25 @@
/***********************************************************************/
/* otherwise, load a composite! */
- else if ( contours_count == -1 )
+ else if ( loader->n_contours == -1 )
{
- TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph;
FT_UInt start_point;
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
-#endif
- /* for each subglyph, read composite header */
start_point = gloader->base.outline.n_points;
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
start_contour = gloader->base.outline.n_contours;
-#endif
+ /* for each subglyph, read composite header */
error = face->read_composite_glyph( loader );
if ( error )
- goto Fail;
+ goto Exit;
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+ /* store the offset of instructions */
ins_pos = loader->ins_pos;
-#endif
+
+ /* all data we need are read */
face->forget_glyph_frame( loader );
opened_frame = 0;
@@ -1290,7 +1478,6 @@
gloader->current.num_subglyphs + 4 )) != 0 )
goto Exit;
- /* Note: No subglyph reallocation here, our pointers are stable. */
subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
limit = gloader->current.num_subglyphs;
@@ -1327,13 +1514,9 @@
/* */
if ( loader->load_flags & FT_LOAD_NO_RECURSE )
{
- /* set up remaining glyph fields */
FT_GlyphLoader_Add( gloader );
+ loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
- glyph->num_subglyphs = gloader->base.num_subglyphs;
- glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
- glyph->subglyphs = gloader->base.subglyphs;
-
goto Exit;
}
@@ -1341,11 +1524,11 @@
/*********************************************************************/
/*********************************************************************/
- /* Now, read each subglyph independently. */
{
- FT_Int n, num_base_points, num_new_points;
+ FT_Int n, num_base_points;
FT_SubGlyph subglyph = 0;
+ FT_UInt num_points = start_point;
FT_UInt num_subglyphs = gloader->current.num_subglyphs;
FT_UInt num_base_subgs = gloader->base.num_subglyphs;
@@ -1352,10 +1535,10 @@
FT_GlyphLoader_Add( gloader );
+ /* read each subglyph independently */
for ( n = 0; n < (FT_Int)num_subglyphs; n++ )
{
- FT_Vector pp1, pp2, pp3, pp4;
- FT_Pos x, y;
+ FT_Vector pp[4];
/* Each time we call load_truetype_glyph in this loop, the */
@@ -1364,10 +1547,10 @@
/* pointer on each iteration. */
subglyph = gloader->base.subglyphs + num_base_subgs + n;
- pp1 = loader->pp1;
- pp2 = loader->pp2;
- pp3 = loader->pp3;
- pp4 = loader->pp4;
+ pp[0] = loader->pp1;
+ pp[1] = loader->pp2;
+ pp[2] = loader->pp3;
+ pp[3] = loader->pp4;
num_base_points = gloader->base.outline.n_points;
@@ -1374,289 +1557,55 @@
error = load_truetype_glyph( loader, subglyph->index,
recurse_count + 1 );
if ( error )
- goto Fail;
+ goto Exit;
/* restore subglyph pointer */
subglyph = gloader->base.subglyphs + num_base_subgs + n;
- if ( subglyph->flags & USE_MY_METRICS )
+ if ( !( subglyph->flags & USE_MY_METRICS ) )
{
- pp1 = loader->pp1;
- pp2 = loader->pp2;
- pp3 = loader->pp3;
- pp4 = loader->pp4;
+ loader->pp1 = pp[0];
+ loader->pp2 = pp[1];
+ loader->pp3 = pp[2];
+ loader->pp4 = pp[3];
}
- else
- {
- loader->pp1 = pp1;
- loader->pp2 = pp2;
- loader->pp3 = pp3;
- loader->pp4 = pp4;
- }
num_points = gloader->base.outline.n_points;
- num_new_points = num_points - num_base_points;
+ if ( num_points == num_base_points )
+ continue;
- /* now perform the transform required for this subglyph */
-
- if ( subglyph->flags & ( WE_HAVE_A_SCALE |
- WE_HAVE_AN_XY_SCALE |
- WE_HAVE_A_2X2 ) )
- {
- FT_Vector* cur = gloader->base.outline.points +
- num_base_points;
- FT_Vector* org = gloader->base.extra_points +
- num_base_points;
- FT_Vector* limit = cur + num_new_points;
-
-
- for ( ; cur < limit; cur++, org++ )
- {
- FT_Vector_Transform( cur, &subglyph->transform );
- FT_Vector_Transform( org, &subglyph->transform );
- }
- }
-
- /* apply offset */
-
- if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
- {
- FT_UInt k = subglyph->arg1;
- FT_UInt l = subglyph->arg2;
- FT_Vector* p1;
- FT_Vector* p2;
-
-
- if ( start_point + k >= (FT_UInt)num_base_points ||
- l >= (FT_UInt)num_new_points )
- {
- error = TT_Err_Invalid_Composite;
- goto Fail;
- }
-
- l += num_base_points;
-
- p1 = gloader->base.outline.points + start_point + k;
- p2 = gloader->base.outline.points + start_point + l;
-
- x = p1->x - p2->x;
- y = p1->y - p2->y;
- }
- else
- {
- x = subglyph->arg1;
- y = subglyph->arg2;
-
- /* Use a default value dependent on */
- /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */
- /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */
-
-#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
- if ( !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) &&
-#else
- if ( ( subglyph->flags & SCALED_COMPONENT_OFFSET ) &&
-#endif
- ( subglyph->flags & ( WE_HAVE_A_SCALE |
- WE_HAVE_AN_XY_SCALE |
- WE_HAVE_A_2X2 )) )
- {
-#if 0
-
- /*************************************************************************/
- /* */
- /* This algorithm is what Apple documents. But it doesn't work. */
- /* */
- int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
- : -subglyph->transform.xx;
- int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
- : -subglyph->transform.yx;
- int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
- : -subglyph->transform.xy;
- int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
- : -subglyph->transform.yy;
- int m = a > b ? a : b;
- int n = c > d ? c : d;
-
-
- if ( a - b <= 33 && a - b >= -33 )
- m *= 2;
- if ( c - d <= 33 && c - d >= -33 )
- n *= 2;
- x = FT_MulFix( x, m );
- y = FT_MulFix( y, n );
-
-#else /* 0 */
-
- /*************************************************************************/
- /* */
- /* This algorithm is a guess and works much better than the above. */
- /* */
- FT_Fixed mac_xscale = FT_SqrtFixed(
- FT_MulFix( subglyph->transform.xx,
- subglyph->transform.xx ) +
- FT_MulFix( subglyph->transform.xy,
- subglyph->transform.xy) );
- FT_Fixed mac_yscale = FT_SqrtFixed(
- FT_MulFix( subglyph->transform.yy,
- subglyph->transform.yy ) +
- FT_MulFix( subglyph->transform.yx,
- subglyph->transform.yx ) );
-
-
- x = FT_MulFix( x, mac_xscale );
- y = FT_MulFix( y, mac_yscale );
-#endif /* 0 */
-
- }
-
- if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
- {
- x = FT_MulFix( x, x_scale );
- y = FT_MulFix( y, y_scale );
-
- if ( subglyph->flags & ROUND_XY_TO_GRID )
- {
- x = FT_PIX_ROUND( x );
- y = FT_PIX_ROUND( y );
- }
- }
- }
-
- if ( x || y )
- {
- translate_array( num_new_points,
- gloader->base.outline.points + num_base_points,
- x, y );
-
- translate_array( num_new_points,
- gloader->base.extra_points + num_base_points,
- x, y );
- }
+ /* gloader->base.outline consists of three part: */
+ /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
+ /* */
+ /* (1): exist from the beginning */
+ /* (2): components that have been loaded so far */
+ /* (3): the newly loaded component */
+ TT_Process_Composite_Component( loader, subglyph, start_point,
+ num_base_points );
}
- /*******************************************************************/
- /*******************************************************************/
- /*******************************************************************/
- /* we have finished loading all sub-glyphs; now, look for */
- /* instructions for this composite! */
+ /* process the glyph */
+ loader->ins_pos = ins_pos;
+ if ( IS_HINTED( loader->load_flags ) &&
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- if ( num_subglyphs > 0 &&
- loader->exec &&
- ins_pos > 0 &&
- subglyph->flags & WE_HAVE_INSTR )
- {
- FT_UShort n_ins;
- TT_ExecContext exec = loader->exec;
- TT_GlyphZone pts;
- FT_Vector* pp1;
+ subglyph->flags & WE_HAVE_INSTR &&
+#endif
- /* read size of instructions */
- if ( FT_STREAM_SEEK( ins_pos ) ||
- FT_READ_USHORT( n_ins ) )
- goto Fail;
- FT_TRACE5(( " Instructions size = %d\n", n_ins ));
+ num_points > start_point )
+ TT_Process_Composite_Glyph( loader, start_point, start_contour );
- /* in some fonts? */
- if ( n_ins == 0xFFFFU )
- n_ins = 0;
-
- /* check it */
- if ( n_ins > face->max_profile.maxSizeOfInstructions )
- {
- FT_TRACE0(( "Too many instructions (%d) in composite glyph %ld\n",
- n_ins, subglyph->index ));
- error = TT_Err_Too_Many_Hints;
- goto Fail;
- }
-
- /* read the instructions */
- if ( FT_STREAM_READ( exec->glyphIns, n_ins ) )
- goto Fail;
-
- glyph->control_data = exec->glyphIns;
- glyph->control_len = n_ins;
-
- error = TT_Set_CodeRange( exec,
- tt_coderange_glyph,
- exec->glyphIns,
- n_ins );
- if ( error )
- goto Fail;
-
- error = FT_GlyphLoader_CheckPoints( gloader, num_points + 4, 0 );
- if ( error )
- goto Fail;
-
- /* prepare the execution context */
- tt_prepare_zone( &exec->pts, &gloader->base,
- start_point, start_contour );
- pts = &exec->pts;
-
- pts->n_points = (short)( num_points + 4 );
- pts->n_contours = gloader->base.outline.n_contours;
-
- /* add phantom points */
- pp1 = pts->cur + num_points;
- pp1[0] = loader->pp1;
- pp1[1] = loader->pp2;
- pp1[2] = loader->pp3;
- pp1[3] = loader->pp4;
-
- pts->tags[num_points ] = 0;
- pts->tags[num_points + 1] = 0;
- pts->tags[num_points + 2] = 0;
- pts->tags[num_points + 3] = 0;
-
- /* if hinting, round the phantom points */
- if ( IS_HINTED( loader->load_flags ) )
- {
- pp1[0].x = FT_PIX_ROUND( loader->pp1.x );
- pp1[1].x = FT_PIX_ROUND( loader->pp2.x );
- pp1[2].y = FT_PIX_ROUND( loader->pp3.y );
- pp1[3].y = FT_PIX_ROUND( loader->pp4.y );
- }
-
- {
- FT_UInt k;
-
-
- for ( k = 0; k < num_points; k++ )
- pts->tags[k] &= FT_CURVE_TAG_ON;
- }
-
- cur_to_org( num_points + 4, pts );
-
- /* now consider hinting */
- if ( IS_HINTED( loader->load_flags ) && n_ins > 0 )
- {
- exec->is_composite = TRUE;
- error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug );
- if ( error && exec->pedantic_hinting )
- goto Fail;
- }
-
- /* save glyph origin and advance points */
- loader->pp1 = pp1[0];
- loader->pp2 = pp1[1];
- loader->pp3 = pp1[2];
- loader->pp4 = pp1[3];
- }
-
-#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
-
}
- /* end of composite loading */
}
else
{
/* invalid composite count ( negative but not -1 ) */
error = TT_Err_Invalid_Outline;
- goto Fail;
+ goto Exit;
}
/***********************************************************************/
@@ -1663,17 +1612,18 @@
/***********************************************************************/
/***********************************************************************/
- Fail:
+ Exit:
+
if ( opened_frame )
face->forget_glyph_frame( loader );
- Exit:
-
#ifdef FT_CONFIG_OPTION_INCREMENTAL
+
if ( glyph_data_loaded )
face->root.internal->incremental_interface->funcs->free_glyph_data(
face->root.internal->incremental_interface->object,
&glyph_data );
+
#endif
return error;
@@ -1696,18 +1646,7 @@
y_scale = size->root.metrics.y_scale;
if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
- {
- glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
-
- /* copy outline to our glyph slot */
- FT_GlyphLoader_CopyPoints( glyph->internal->loader, loader->gloader );
- glyph->outline = glyph->internal->loader->base.outline;
-
- /* translate array so that (0,0) is the glyph's origin */
- FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 );
-
FT_Outline_Get_CBox( &glyph->outline, &bbox );
- }
else
bbox = loader->bbox;
@@ -1852,7 +1791,7 @@
}
/* adjust advance width to the value contained in the hdmx table */
- if ( !face->postscript.isFixedPitch && size &&
+ if ( !face->postscript.isFixedPitch &&
IS_HINTED( loader->load_flags ) )
{
FT_Byte* widthp = Get_Advance_WidthPtr( face,
@@ -1875,6 +1814,153 @@
}
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+ static FT_Error
+ load_sbit_image( TT_Size size,
+ TT_GlyphSlot glyph,
+ FT_UInt glyph_index,
+ FT_Int32 load_flags )
+ {
+ TT_Face face;
+ SFNT_Service sfnt;
+ FT_Stream stream;
+ FT_Error error;
+ TT_SBit_MetricsRec metrics;
+
+ face = (TT_Face)glyph->face;
+ sfnt = (SFNT_Service)face->sfnt;
+ stream = face->root.stream;
+
+ error = sfnt->load_sbit_image( face,
+ (FT_ULong)size->strike_index,
+ glyph_index,
+ (FT_Int)load_flags,
+ stream,
+ &glyph->bitmap,
+ &metrics );
+ if ( !error )
+ {
+ glyph->outline.n_points = 0;
+ glyph->outline.n_contours = 0;
+
+ glyph->metrics.width = (FT_Pos)metrics.width << 6;
+ glyph->metrics.height = (FT_Pos)metrics.height << 6;
+
+ glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
+ glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
+ glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
+
+ glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
+ glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
+ glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
+
+ glyph->format = FT_GLYPH_FORMAT_BITMAP;
+ if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
+ {
+ glyph->bitmap_left = metrics.vertBearingX;
+ glyph->bitmap_top = metrics.vertBearingY;
+ }
+ else
+ {
+ glyph->bitmap_left = metrics.horiBearingX;
+ glyph->bitmap_top = metrics.horiBearingY;
+ }
+ }
+
+ return error;
+ }
+#endif
+
+
+ static FT_Error
+ tt_loader_init( TT_Loader loader,
+ TT_Size size,
+ TT_GlyphSlot glyph,
+ FT_Int32 load_flags )
+ {
+ TT_Face face;
+ FT_Stream stream;
+
+
+ face = (TT_Face)glyph->face;
+ stream = face->root.stream;
+
+ FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
+ /* load execution context */
+ {
+ TT_ExecContext exec;
+
+
+ /* query new execution context */
+ exec = size->debug ? size->context
+ : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
+ if ( !exec )
+ return TT_Err_Could_Not_Find_Context;
+
+ TT_Load_Context( exec, face, size );
+
+ /* see if the cvt program has disabled hinting */
+ if ( exec->GS.instruct_control & 1 )
+ load_flags |= FT_LOAD_NO_HINTING;
+
+ /* load default graphics state - if needed */
+ if ( exec->GS.instruct_control & 2 )
+ exec->GS = tt_default_graphics_state;
+
+ exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
+ exec->grayscale =
+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_LOAD_TARGET_MONO );
+
+ loader->exec = exec;
+ loader->instructions = exec->glyphIns;
+ }
+
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
+ /* seek to the beginning of the glyph table. For Type 42 fonts */
+ /* the table might be accessed from a Postscript stream or something */
+ /* else... */
+
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+
+ if ( face->root.internal->incremental_interface )
+ loader->glyf_offset = 0;
+ else
+
+#endif
+
+ {
+ FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 );
+ if ( error )
+ {
+ FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
+ return error;
+ }
+ loader->glyf_offset = FT_STREAM_POS();
+ }
+
+ /* get face's glyph loader */
+ {
+ FT_GlyphLoader gloader = glyph->internal->loader;
+
+ FT_GlyphLoader_Rewind( gloader );
+ loader->gloader = gloader;
+ }
+
+ loader->load_flags = load_flags;
+
+ loader->face = (FT_Face)face;
+ loader->size = (FT_Size)size;
+ loader->glyph = (FT_GlyphSlot)glyph;
+ loader->stream = stream;
+
+ return TT_Err_Ok;
+ }
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -1908,7 +1994,6 @@
FT_UInt glyph_index,
FT_Int32 load_flags )
{
- SFNT_Service sfnt;
TT_Face face;
FT_Stream stream;
FT_Error error;
@@ -1916,21 +2001,9 @@
face = (TT_Face)glyph->face;
- sfnt = (SFNT_Service)face->sfnt;
stream = face->root.stream;
error = TT_Err_Ok;
- if ( !size || ( load_flags & FT_LOAD_NO_SCALE ) ||
- ( load_flags & FT_LOAD_NO_RECURSE ) )
- {
- size = NULL;
- load_flags |= FT_LOAD_NO_SCALE |
- FT_LOAD_NO_HINTING |
- FT_LOAD_NO_BITMAP;
- }
-
- glyph->num_subglyphs = 0;
-
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* try to load embedded bitmap if any */
@@ -1937,173 +2010,56 @@
/* */
/* XXX: The convention should be emphasized in */
/* the documents because it can be confusing. */
- if ( size &&
- size->strike_index != 0xFFFFU &&
- sfnt->load_sbits &&
+ if ( size->strike_index != 0xFFFFU &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
-
{
- TT_SBit_MetricsRec metrics;
-
-
- error = sfnt->load_sbit_image( face,
- (FT_ULong)size->strike_index,
- glyph_index,
- (FT_Int)load_flags,
- stream,
- &glyph->bitmap,
- &metrics );
+ error = load_sbit_image( size, glyph, glyph_index, load_flags );
if ( !error )
- {
- glyph->outline.n_points = 0;
- glyph->outline.n_contours = 0;
-
- glyph->metrics.width = (FT_Pos)metrics.width << 6;
- glyph->metrics.height = (FT_Pos)metrics.height << 6;
-
- glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
- glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
- glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
-
- glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
- glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
- glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
-
- glyph->format = FT_GLYPH_FORMAT_BITMAP;
- if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
- {
- glyph->bitmap_left = metrics.vertBearingX;
- glyph->bitmap_top = metrics.vertBearingY;
- }
- else
- {
- glyph->bitmap_left = metrics.horiBearingX;
- glyph->bitmap_top = metrics.horiBearingY;
- }
- return error;
- }
+ return TT_Err_Ok;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
- /* return immediately if we only want the embedded bitmaps */
if ( load_flags & FT_LOAD_SBITS_ONLY )
return TT_Err_Invalid_Argument;
- /* seek to the beginning of the glyph table. For Type 42 fonts */
- /* the table might be accessed from a Postscript stream or something */
- /* else... */
+ error = tt_loader_init( &loader, size, glyph, load_flags );
+ if ( error )
+ return error;
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ glyph->format = FT_GLYPH_FORMAT_OUTLINE;
+ glyph->num_subglyphs = 0;
+ glyph->outline.flags = 0;
- /* Don't look for the glyph table if this is an incremental font. */
- if ( !face->root.internal->incremental_interface )
-
-#endif
-
+ /* Main loading loop */
+ error = load_truetype_glyph( &loader, glyph_index, 0 );
+ if ( !error )
{
- error = face->goto_table( face, TTAG_glyf, stream, 0 );
- if ( error )
+ if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
{
- FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
- goto Exit;
+ glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
+ glyph->subglyphs = loader.gloader->base.subglyphs;
}
- }
+ else
+ {
+ glyph->outline = loader.gloader->base.outline;
+ glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
- FT_MEM_ZERO( &loader, sizeof ( loader ) );
+ /* translate array so that (0,0) is the glyph's origin */
+ if ( loader.pp1.x )
+ FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
+ }
- /* update the glyph zone bounds */
- {
- FT_GlyphLoader gloader = FT_FACE_DRIVER( face )->glyph_loader;
-
-
- loader.gloader = gloader;
-
- FT_GlyphLoader_Rewind( gloader );
-
- tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 );
- tt_prepare_zone( &loader.base, &gloader->base, 0, 0 );
+ compute_glyph_metrics( &loader, glyph_index );
}
-#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 );
- loader.instructions = loader.exec->glyphIns;
-
- /* load default graphics state - if needed */
- if ( size->GS.instruct_control & 2 )
- loader.exec->GS = tt_default_graphics_state;
-
- loader.exec->pedantic_hinting =
- FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
-
- loader.exec->grayscale =
- FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_LOAD_TARGET_MONO );
- }
-
-#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
-
- /* clear all outline flags, except the `owner' one */
- glyph->outline.flags = 0;
-
- /* let's initialize the rest of our loader now */
-
- loader.load_flags = load_flags;
-
- loader.face = (FT_Face)face;
- loader.size = (FT_Size)size;
- loader.glyph = (FT_GlyphSlot)glyph;
- loader.stream = stream;
-
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
-
- if ( face->root.internal->incremental_interface )
- loader.glyf_offset = 0;
- else
-
-#endif
-
- loader.glyf_offset = FT_STREAM_POS();
-
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
- /* if 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 /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
-
- /* Main loading loop */
- glyph->format = FT_GLYPH_FORMAT_OUTLINE;
- glyph->num_subglyphs = 0;
-
- error = load_truetype_glyph( &loader, glyph_index, 0 );
- if ( !error )
- compute_glyph_metrics( &loader, glyph_index );
-
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
- if ( !size || !size->debug )
- TT_Done_Context( loader.exec );
-
-#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
-
/* Set the `high precision' bit flag. */
/* This is _critical_ to get correct output for monochrome */
/* TrueType glyphs at all sizes using the bytecode interpreter. */
/* */
- if ( size && size->root.metrics.y_ppem < 24 )
+ if ( size->root.metrics.y_ppem < 24 )
glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
- Exit:
return error;
}
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -371,7 +371,7 @@
/*************************************************************************/
/* */
/* <Function> */
- /* TT_Destroy_Context */
+ /* TT_Done_Context */
/* */
/* <Description> */
/* Destroys a given context. */
@@ -388,9 +388,11 @@
/* Only the glyph loader and debugger should call this function. */
/* */
FT_LOCAL_DEF( FT_Error )
- TT_Destroy_Context( TT_ExecContext exec,
- FT_Memory memory )
+ TT_Done_Context( TT_ExecContext exec )
{
+ FT_Memory memory = exec->memory;
+
+
/* free composite load stack */
FT_FREE( exec->loadStack );
exec->loadSize = 0;
@@ -416,6 +418,7 @@
exec->face = NULL;
FT_FREE( exec );
+
return TT_Err_Ok;
}
@@ -431,8 +434,6 @@
/* <Input> */
/* memory :: A handle to the parent memory object. */
/* */
- /* face :: A handle to the source TrueType face object. */
- /* */
/* <InOut> */
/* exec :: A handle to the target execution context. */
/* */
@@ -441,14 +442,12 @@
/* */
static FT_Error
Init_Context( TT_ExecContext exec,
- TT_Face face,
FT_Memory memory )
{
FT_Error error;
- FT_TRACE1(( "Init_Context: new object at 0x%08p, parent = 0x%08p\n",
- exec, face ));
+ FT_TRACE1(( "Init_Context: new object at 0x%08p\n", exec ));
exec->memory = memory;
exec->callSize = 32;
@@ -469,7 +468,7 @@
exec->loadStack = NULL;
exec->glyphIns = NULL;
- exec->face = face;
+ exec->face = NULL;
exec->size = NULL;
return TT_Err_Ok;
@@ -477,7 +476,7 @@
Fail_Memory:
FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n",
(FT_Long)exec ));
- TT_Destroy_Context( exec, memory );
+ TT_Done_Context( exec );
return error;
}
@@ -770,18 +769,12 @@
/* documentation is in ttinterp.h */
FT_EXPORT_DEF( TT_ExecContext )
- TT_New_Context( TT_Face face )
+ TT_New_Context( TT_Driver driver )
{
- TT_Driver driver;
TT_ExecContext exec;
FT_Memory memory;
- if ( !face )
- return 0;
-
- driver = (TT_Driver)face->root.driver;
-
memory = driver->root.root.memory;
exec = driver->context;
@@ -795,7 +788,7 @@
goto Exit;
/* initialize it */
- error = Init_Context( exec, face, memory );
+ error = Init_Context( exec, memory );
if ( error )
goto Fail;
@@ -811,34 +804,6 @@
return 0;
}
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* TT_Done_Context */
- /* */
- /* <Description> */
- /* Discards an execution context. */
- /* */
- /* <Input> */
- /* exec :: A handle to the target execution context. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* Only the glyph loader and debugger should call this function. */
- /* */
- FT_LOCAL_DEF( FT_Error )
- TT_Done_Context( TT_ExecContext exec )
- {
- /* Nothing at all for now */
- FT_UNUSED( exec );
-
- return TT_Err_Ok;
- }
-
/*************************************************************************/
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -263,15 +263,10 @@
/* Only the glyph loader and debugger should call this function. */
/* */
FT_EXPORT( TT_ExecContext )
- TT_New_Context( TT_Face face );
+ TT_New_Context( TT_Driver driver );
-
FT_LOCAL( FT_Error )
TT_Done_Context( TT_ExecContext exec );
-
- FT_LOCAL( FT_Error )
- TT_Destroy_Context( TT_ExecContext exec,
- FT_Memory memory );
FT_LOCAL( FT_Error )
TT_Load_Context( TT_ExecContext exec,
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -348,7 +348,7 @@
if ( size->debug )
exec = size->context;
else
- exec = TT_New_Context( face );
+ exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
return TT_Err_Could_Not_Find_Context;
@@ -403,9 +403,6 @@
if ( !error )
TT_Save_Context( exec, size );
- if ( !size->debug )
- TT_Done_Context( exec );
-
return error;
}
@@ -436,7 +433,7 @@
if ( size->debug )
exec = size->context;
else
- exec = TT_New_Context( face );
+ exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
return TT_Err_Could_Not_Find_Context;
@@ -470,9 +467,6 @@
TT_Save_Context( exec, size );
- if ( !size->debug )
- TT_Done_Context( exec );
-
return error;
}
@@ -917,15 +911,24 @@
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
- tt_driver_init( FT_Module driver ) /* TT_Driver */
+ tt_driver_init( FT_Module ttdriver ) /* TT_Driver */
{
- FT_Error error;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
- /* set `extra' in glyph loader */
- error = FT_GlyphLoader_CreateExtra( FT_DRIVER( driver )->glyph_loader );
+ TT_Driver driver = (TT_Driver)ttdriver;
- return error;
+
+ if ( !TT_New_Context( driver ) )
+ return TT_Err_Could_Not_Find_Context;
+
+#else
+
+ FT_UNUSED( ttdriver );
+
+#endif
+
+ return TT_Err_Ok;
}
@@ -950,7 +953,7 @@
/* destroy the execution context */
if ( driver->context )
{
- TT_Destroy_Context( driver->context, driver->root.root.memory );
+ TT_Done_Context( driver->context );
driver->context = NULL;
}
#else
@@ -957,6 +960,27 @@
FT_UNUSED( ttdriver );
#endif
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* tt_slot_init */
+ /* */
+ /* <Description> */
+ /* Initializes a new slot object. */
+ /* */
+ /* <InOut> */
+ /* slot :: A handle to the slot object. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ FT_LOCAL_DEF( FT_Error )
+ tt_slot_init( FT_GlyphSlot slot )
+ {
+ return FT_GlyphLoader_CreateExtra( slot->internal->loader );
}
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -442,6 +442,14 @@
tt_driver_done( FT_Module ttdriver ); /* TT_Driver */
+ /*************************************************************************/
+ /* */
+ /* Slot functions */
+ /* */
+ FT_LOCAL( FT_Error )
+ tt_slot_init( FT_GlyphSlot slot );
+
+
FT_END_HEADER
#endif /* __TTOBJS_H__ */