ref: ed7f62aca5eab9d808daf0879607779bd2670173
parent: 7024ca1a37b7753e5c0de13330cb34fdbf28fb18
author: David Turner <[email protected]>
date: Tue Mar 28 06:19:28 EST 2000
support for FT_LOAD_NO_RECURSE needed by the auto-hinter
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -474,7 +474,7 @@
TT_ULong ins_offset;
/* check glyph index */
- index = (TT_UInt)glyph_index;
+ index = glyph_index;
if ( index >= (TT_UInt)face->root.num_glyphs )
{
error = TT_Err_Invalid_Glyph_Index;
@@ -698,10 +698,40 @@
/* composite instructions, if we find some .. */
/* we will process them later.. */
ins_offset = FILE_Pos() + stream->cursor - stream->limit;
- FORGET_Frame();
}
#endif
+ FORGET_Frame();
+ /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
+ /* "as is" in the glyph slot (the client application will be */
+ /* responsible for interpreting this data..) */
+ if ( loader->load_flags & FT_LOAD_NO_RECURSE )
+ {
+ FT_GlyphSlot glyph = loader->glyph;
+
+ /* reallocate subglyph array if necessary */
+ if (glyph->max_subglyphs < num_subglyphs)
+ {
+ FT_Memory memory = loader->face->root.memory;
+
+ if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
+ num_subglyphs, FT_SubGlyph ) )
+ goto Fail;
+
+ glyph->max_subglyphs = num_subglyphs;
+ }
+
+ /* copy subglyph array */
+ MEM_Copy( glyph->subglyphs, subglyphs,
+ num_subglyphs*sizeof(FT_SubGlyph));
+
+ /* set up remaining glyph fields */
+ glyph->num_subglyphs = num_subglyphs;
+ glyph->format = ft_glyph_format_composite;
+ goto Load_End;
+ }
+
+
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
@@ -954,6 +984,7 @@
y_scale = size->root.metrics.y_scale;
}
+ if ( glyph->format != ft_glyph_format_composite )
{
TT_UInt u;
for ( u = 0; u < num_points + 2; u++ )
@@ -964,30 +995,31 @@
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;
-
- /* glyph->outline.second_pass = TRUE; */
- glyph->outline.flags &= ~ft_outline_single_pass;
+ /* glyph->outline.second_pass = TRUE; */
+ glyph->outline.flags &= ~ft_outline_single_pass;
+ glyph->outline.n_points = num_points;
+ glyph->outline.n_contours = num_contours;
+
+ /* translate array so that (0,0) is the glyph's origin */
+ translate_array( (TT_UShort)(num_points + 2),
+ glyph->outline.points,
+ -loader->pp1.x,
+ 0 );
+
+ FT_Outline_Get_CBox( &glyph->outline, &bbox );
- /* translate array so that (0,0) is the glyph's origin */
- translate_array( (TT_UShort)(num_points + 2),
- glyph->outline.points,
- -loader->pp1.x,
- 0 );
-
- FT_Outline_Get_CBox( &glyph->outline, &bbox );
-
- if ( IS_HINTED(loader->load_flags) )
- {
- /* grid-fit the bounding box */
- bbox.xMin &= -64;
- bbox.yMin &= -64;
- bbox.xMax = (bbox.xMax + 63) & -64;
- bbox.yMax = (bbox.yMax + 63) & -64;
+ if ( IS_HINTED(loader->load_flags) )
+ {
+ /* grid-fit the bounding box */
+ bbox.xMin &= -64;
+ bbox.yMin &= -64;
+ bbox.xMax = (bbox.xMax + 63) & -64;
+ bbox.yMax = (bbox.yMax + 63) & -64;
+ }
}
+ else
+ bbox = loader->bbox;
/* get the device-independent scaled horizontal metrics */
/* take care of fixed-pitch fonts... */
@@ -1141,7 +1173,6 @@
glyph->metrics.width = bbox.xMax - bbox.xMin;
glyph->metrics.height = bbox.yMax - bbox.yMin;
- glyph->format = ft_glyph_format_outline;
}
@@ -1174,8 +1205,9 @@
stream = face->root.stream;
memory = face->root.memory;
error = 0;
-
- if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+
+ if ( !size || (load_flags & FT_LOAD_NO_SCALE) ||
+ (load_flags & FT_LOAD_NO_RECURSE ))
{
size = NULL;
load_flags |= FT_LOAD_NO_SCALE |
@@ -1183,6 +1215,8 @@
FT_LOAD_NO_BITMAP;
}
+ glyph->num_subglyphs = 0;
+
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/*********************************************************************/
/* Try to load embedded bitmap if any */
@@ -1245,6 +1279,9 @@
goto Exit;
}
loader.base = *zone;
+
+ loader.zone.n_points = 0;
+ loader.zone.n_contours = 0;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if ( size )
@@ -1289,6 +1326,7 @@
#endif
/* Main loading loop */
+ glyph->format = ft_glyph_format_outline;
error = load_truetype_glyph( &loader, glyph_index );
if (!error)
compute_glyph_metrics( &loader, glyph_index );
@@ -1301,30 +1339,6 @@
Exit:
return error;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -255,7 +255,7 @@
cur->n_points = 0;
cur->n_contours = 0;
cur->points = base->points + base->n_points;
- cur->tags = base->tags + base->n_points;
+ cur->tags = base->tags + base->n_points;
cur->contours = base->contours + base->n_contours;
error = T1_Parse_CharStrings( decoder,
@@ -268,48 +268,88 @@
n_base_points = cur->n_points;
- /* save the left bearing and width of the base character */
- /* as they will be erased by the next load.. */
- left_bearing = decoder->builder.left_bearing;
- advance = decoder->builder.advance;
+ if ( decoder->builder.no_recurse )
+ {
+ /* if we're trying to load a composite glyph, do not load the */
+ /* accent character and return the array of subglyphs.. */
+ FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
+ FT_SubGlyph* subg;
- decoder->builder.left_bearing.x = 0;
- decoder->builder.left_bearing.y = 0;
+ /* reallocate subglyph array if necessary */
+ if (glyph->max_subglyphs < 2)
+ {
+ FT_Memory memory = decoder->builder.face->root.memory;
+
+ if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
+ 2, FT_SubGlyph ) )
+ return error;
+
+ glyph->max_subglyphs = 2;
+ }
- /* Now load "achar" on top of */
- /* the base outline */
- /* */
- cur->n_points = 0;
- cur->n_contours = 0;
- cur->points = base->points + base->n_points;
- cur->tags = base->tags + base->n_points;
- cur->contours = base->contours + base->n_contours;
+ subg = glyph->subglyphs;
+
+ /* subglyph 0 = base character */
+ subg->index = bchar_index;
+ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
+ FT_SUBGLYPH_FLAG_USE_MY_METRICS;
+ subg->arg1 = 0;
+ subg->arg2 = 0;
+ subg++;
+
+ /* subglyph 1 = accent character */
+ subg->index = achar_index;
+ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
+ subg->arg1 = adx - asb;
+ subg->arg2 = ady;
- error = T1_Parse_CharStrings( decoder,
- type1->charstrings [achar_index],
- type1->charstrings_len[achar_index],
- type1->num_subrs,
- type1->subrs,
- type1->subrs_len );
- if (error) return error;
-
- /* adjust contours in accented character outline */
+ /* set up remaining glyph fields */
+ glyph->num_subglyphs = 2;
+ glyph->format = ft_glyph_format_composite;
+ }
+ else
{
- T1_Int n;
-
- for ( n = 0; n < cur->n_contours; n++ )
- cur->contours[n] += n_base_points;
+ /* save the left bearing and width of the base character */
+ /* as they will be erased by the next load.. */
+ left_bearing = decoder->builder.left_bearing;
+ advance = decoder->builder.advance;
+
+ decoder->builder.left_bearing.x = 0;
+ decoder->builder.left_bearing.y = 0;
+
+ /* Now load "achar" on top of */
+ /* the base outline */
+ /* */
+ cur->n_points = 0;
+ cur->n_contours = 0;
+ cur->points = base->points + base->n_points;
+ cur->tags = base->tags + base->n_points;
+ cur->contours = base->contours + base->n_contours;
+
+ error = T1_Parse_CharStrings( decoder,
+ type1->charstrings [achar_index],
+ type1->charstrings_len[achar_index],
+ type1->num_subrs,
+ type1->subrs,
+ type1->subrs_len );
+ if (error) return error;
+
+ /* adjust contours in accented character outline */
+ {
+ T1_Int n;
+
+ for ( n = 0; n < cur->n_contours; n++ )
+ cur->contours[n] += n_base_points;
+ }
+
+ /* restore the left side bearing and */
+ /* advance width of the base character */
+ decoder->builder.left_bearing = left_bearing;
+ decoder->builder.advance = advance;
+
+ /* Finally, move the accent */
+ FT_Outline_Translate( cur, adx - asb, ady );
}
-
- /* restore the left side bearing and */
- /* advance width of the base character */
- decoder->builder.left_bearing = left_bearing;
- decoder->builder.advance = advance;
-
- /* Finally, move the accent */
- FT_Outline_Translate( cur, adx - asb, ady );
-
- (void)asb; /* ignore this parameter */
return T1_Err_Ok;
}
@@ -1416,6 +1456,9 @@
T1_Bool hinting;
T1_Font* type1 = &face->type1;
+ if (load_flags & FT_LOAD_NO_RECURSE)
+ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
+
glyph->x_scale = size->root.metrics.x_scale;
glyph->y_scale = size->root.metrics.y_scale;
@@ -1470,6 +1513,7 @@
&gload_builder_interface );
decoder.builder.pass = 1;
+ decoder.builder.no_recurse = 0;
error = T1_Parse_CharStrings( &decoder,
type1->charstrings [glyph_index],
@@ -1483,6 +1527,7 @@
}
else
#endif
+
{
T1_Init_Decoder( &decoder, &gload_hinter_interface );
@@ -1489,6 +1534,8 @@
T1_Init_Builder( &decoder.builder, face, size, glyph,
&gload_builder_interface );
+ decoder.builder.no_recurse = !!(load_flags & FT_LOAD_NO_RECURSE);
+
/* now load the unscaled outline */
error = T1_Parse_CharStrings( &decoder,
type1->charstrings [glyph_index],
@@ -1507,82 +1554,92 @@
/* bearing the yMax.. */
if (!error)
{
- FT_BBox cbox;
- FT_Glyph_Metrics* metrics = &glyph->root.metrics;
-
- FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
-
- /* grid fit the bounding box if necessary */
- if (hinting)
+ /* for composite glyphs, return only the left side bearing and the */
+ /* advance width.. */
+ if ( load_flags & FT_LOAD_NO_RECURSE )
{
- cbox.xMin &= -64;
- cbox.yMin &= -64;
- cbox.xMax = ( cbox.xMax+63 ) & -64;
- cbox.yMax = ( cbox.yMax+63 ) & -64;
+ glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
+ glyph->root.metrics.horiAdvance = decoder.builder.advance.x;
}
-
- metrics->width = cbox.xMax - cbox.xMin;
- metrics->height = cbox.yMax - cbox.yMin;
-
- metrics->horiBearingX = cbox.xMin;
- metrics->horiBearingY = cbox.yMax;
-
- /* copy the _unscaled_ advance width */
- metrics->horiAdvance = decoder.builder.advance.x;
-
- /* make up vertical metrics */
- metrics->vertBearingX = 0;
- metrics->vertBearingY = 0;
- metrics->vertAdvance = 0;
-
- glyph->root.format = ft_glyph_format_outline;
-
- glyph->root.outline.flags &= ft_outline_owner;
-
- if ( size->root.metrics.y_ppem < 24 )
- glyph->root.outline.flags |= ft_outline_high_precision;
-
- /*
- glyph->root.outline.second_pass = TRUE;
- glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
- glyph->root.outline.dropout_mode = 2;
- */
-
- if ( hinting )
+ else
{
- /* adjust the advance width */
- /* XXX : TODO : consider stem hints grid-fit */
- metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
- glyph->x_scale );
- }
- else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
- {
- /* scale the outline and the metrics */
- T1_Int n;
- FT_Outline* cur = &decoder.builder.base;
- T1_Vector* vec = cur->points;
- T1_Fixed x_scale = glyph->x_scale;
- T1_Fixed y_scale = glyph->y_scale;
-
- /* First of all, scale the points */
- for ( n = cur->n_points; n > 0; n--, vec++ )
+ FT_BBox cbox;
+ FT_Glyph_Metrics* metrics = &glyph->root.metrics;
+
+ FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
+
+ /* grid fit the bounding box if necessary */
+ if (hinting)
{
- vec->x = FT_MulFix( vec->x, x_scale );
- vec->y = FT_MulFix( vec->y, y_scale );
+ cbox.xMin &= -64;
+ cbox.yMin &= -64;
+ cbox.xMax = ( cbox.xMax+63 ) & -64;
+ cbox.yMax = ( cbox.yMax+63 ) & -64;
}
-
- /* Then scale the metrics */
- metrics->width = FT_MulFix( metrics->width, x_scale );
- metrics->height = FT_MulFix( metrics->height, y_scale );
-
- metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale );
- metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale );
- metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
-
- metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
- metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
- metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale );
-
+
+ metrics->width = cbox.xMax - cbox.xMin;
+ metrics->height = cbox.yMax - cbox.yMin;
+
+ metrics->horiBearingX = cbox.xMin;
+ metrics->horiBearingY = cbox.yMax;
+
+ /* copy the _unscaled_ advance width */
+ metrics->horiAdvance = decoder.builder.advance.x;
+
+ /* make up vertical metrics */
+ metrics->vertBearingX = 0;
+ metrics->vertBearingY = 0;
+ metrics->vertAdvance = 0;
+
+ glyph->root.format = ft_glyph_format_outline;
+
+ glyph->root.outline.flags &= ft_outline_owner;
+
+ if ( size->root.metrics.y_ppem < 24 )
+ glyph->root.outline.flags |= ft_outline_high_precision;
+
+ /*
+ glyph->root.outline.second_pass = TRUE;
+ glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+ glyph->root.outline.dropout_mode = 2;
+ */
+
+ if ( hinting )
+ {
+ /* adjust the advance width */
+ /* XXX : TODO : consider stem hints grid-fit */
+ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
+ glyph->x_scale );
+ }
+ else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
+ {
+ /* scale the outline and the metrics */
+ T1_Int n;
+ FT_Outline* cur = &decoder.builder.base;
+ T1_Vector* vec = cur->points;
+ T1_Fixed x_scale = glyph->x_scale;
+ T1_Fixed y_scale = glyph->y_scale;
+
+ /* First of all, scale the points */
+ for ( n = cur->n_points; n > 0; n--, vec++ )
+ {
+ vec->x = FT_MulFix( vec->x, x_scale );
+ vec->y = FT_MulFix( vec->y, y_scale );
+ }
+
+ /* Then scale the metrics */
+ metrics->width = FT_MulFix( metrics->width, x_scale );
+ metrics->height = FT_MulFix( metrics->height, y_scale );
+
+ metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale );
+ metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale );
+ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
+
+ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
+ metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
+ metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale );
+
+ }
}
}
--- a/src/type1/t1gload.h
+++ b/src/type1/t1gload.h
@@ -159,6 +159,7 @@
T1_Vector left_bearing;
T1_Vector advance;
+ T1_Bool no_recurse;
T1_BBox bbox; /* bounding box */
T1_Bool path_begun;
--- a/src/type1z/t1gload.c
+++ b/src/type1z/t1gload.c
@@ -475,50 +475,90 @@
n_base_points = cur->n_points;
- /* save the left bearing and width of the base character */
- /* as they will be erase by the next load.. */
- left_bearing = decoder->builder.left_bearing;
- advance = decoder->builder.advance;
+ if ( decoder->builder.no_recurse )
+ {
+ /* if we're trying to load a composite glyph, do not load the */
+ /* accent character and return the array of subglyphs.. */
+ FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
+ FT_SubGlyph* subg;
- decoder->builder.left_bearing.x = 0;
- decoder->builder.left_bearing.y = 0;
+ /* reallocate subglyph array if necessary */
+ if (glyph->max_subglyphs < 2)
+ {
+ FT_Memory memory = decoder->builder.face->root.memory;
+
+ if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
+ 2, FT_SubGlyph ) )
+ return error;
+
+ glyph->max_subglyphs = 2;
+ }
- /* Now load "achar" on top of */
- /* the base outline */
- /* */
- cur->n_points = 0;
- cur->n_contours = 0;
- cur->points = base->points + base->n_points;
- cur->tags = base->tags + base->n_points;
- cur->contours = base->contours + base->n_contours;
+ subg = glyph->subglyphs;
+
+ /* subglyph 0 = base character */
+ subg->index = bchar_index;
+ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
+ FT_SUBGLYPH_FLAG_USE_MY_METRICS;
+ subg->arg1 = 0;
+ subg->arg2 = 0;
+ subg++;
+
+ /* subglyph 1 = accent character */
+ subg->index = achar_index;
+ subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
+ subg->arg1 = adx - asb;
+ subg->arg2 = ady;
- error = T1_Parse_CharStrings( decoder,
- type1->charstrings [achar_index],
- type1->charstrings_len[achar_index],
- type1->num_subrs,
- type1->subrs,
- type1->subrs_len );
- if (error) return error;
-
- /* adjust contours in accented character outline */
- if (decoder->builder.load_points)
+ /* set up remaining glyph fields */
+ glyph->num_subglyphs = 2;
+ glyph->format = ft_glyph_format_composite;
+ }
+ else
{
- T1_Int n;
-
- for ( n = 0; n < cur->n_contours; n++ )
- cur->contours[n] += n_base_points;
+ /* save the left bearing and width of the base character */
+ /* as they will be erase by the next load.. */
+ left_bearing = decoder->builder.left_bearing;
+ advance = decoder->builder.advance;
+
+ decoder->builder.left_bearing.x = 0;
+ decoder->builder.left_bearing.y = 0;
+
+ /* Now load "achar" on top of */
+ /* the base outline */
+ /* */
+ cur->n_points = 0;
+ cur->n_contours = 0;
+ cur->points = base->points + base->n_points;
+ cur->tags = base->tags + base->n_points;
+ cur->contours = base->contours + base->n_contours;
+
+ error = T1_Parse_CharStrings( decoder,
+ type1->charstrings [achar_index],
+ type1->charstrings_len[achar_index],
+ type1->num_subrs,
+ type1->subrs,
+ type1->subrs_len );
+ if (error) return error;
+
+ /* adjust contours in accented character outline */
+ if (decoder->builder.load_points)
+ {
+ T1_Int n;
+
+ for ( n = 0; n < cur->n_contours; n++ )
+ cur->contours[n] += n_base_points;
+ }
+
+ /* restore the left side bearing and */
+ /* advance width of the base character */
+ decoder->builder.left_bearing = left_bearing;
+ decoder->builder.advance = advance;
+
+ /* Finally, move the accent */
+ if (decoder->builder.load_points)
+ FT_Outline_Translate( cur, adx - asb, ady );
}
-
- /* restore the left side bearing and */
- /* advance width of the base character */
- decoder->builder.left_bearing = left_bearing;
- decoder->builder.advance = advance;
-
- /* Finally, move the accent */
- if (decoder->builder.load_points)
- FT_Outline_Translate( cur, adx - asb, ady );
-
- (void)asb; /* ignore this parameter */
return T1_Err_Ok;
}
@@ -1213,6 +1253,9 @@
T1_Bool hinting;
T1_Font* type1 = &face->type1;
+ if (load_flags & FT_LOAD_NO_RECURSE)
+ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
+
glyph->x_scale = size->root.metrics.x_scale;
glyph->y_scale = size->root.metrics.y_scale;
@@ -1228,6 +1271,8 @@
T1_Init_Decoder( &decoder );
T1_Init_Builder( &decoder.builder, face, size, glyph );
+ decoder.builder.no_recurse = !!(load_flags & FT_LOAD_NO_RECURSE);
+
/* now load the unscaled outline */
error = T1_Parse_CharStrings( &decoder,
type1->charstrings [glyph_index],
@@ -1245,72 +1290,82 @@
/* bearing the yMax.. */
if (!error)
{
- FT_BBox cbox;
- FT_Glyph_Metrics* metrics = &glyph->root.metrics;
-
- FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
-
- /* grid fit the bounding box if necessary */
- if (hinting)
+ /* for composite glyphs, return only the left side bearing and the */
+ /* advance width.. */
+ if ( load_flags & FT_LOAD_NO_RECURSE )
{
- cbox.xMin &= -64;
- cbox.yMin &= -64;
- cbox.xMax = ( cbox.xMax+63 ) & -64;
- cbox.yMax = ( cbox.yMax+63 ) & -64;
+ glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
+ glyph->root.metrics.horiAdvance = decoder.builder.advance.x;
}
-
- metrics->width = cbox.xMax - cbox.xMin;
- metrics->height = cbox.yMax - cbox.yMin;
-
- metrics->horiBearingX = cbox.xMin;
- metrics->horiBearingY = cbox.yMax;
-
- /* copy the _unscaled_ advance width */
- metrics->horiAdvance = decoder.builder.advance.x;
-
- /* make up vertical metrics */
- metrics->vertBearingX = 0;
- metrics->vertBearingY = 0;
- metrics->vertAdvance = 0;
-
- glyph->root.format = ft_glyph_format_outline;
-
- glyph->root.outline.flags &= ft_outline_owner;
- if ( size->root.metrics.y_ppem < 24 )
- glyph->root.outline.flags |= ft_outline_high_precision;
- /*
- glyph->root.outline.second_pass = TRUE;
- glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
- glyph->root.outline.dropout_mode = 2;
- */
-
- if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
+ else
{
- /* scale the outline and the metrics */
- T1_Int n;
- FT_Outline* cur = &decoder.builder.base;
- T1_Vector* vec = cur->points;
- T1_Fixed x_scale = glyph->x_scale;
- T1_Fixed y_scale = glyph->y_scale;
-
- /* First of all, scale the points */
- for ( n = cur->n_points; n > 0; n--, vec++ )
+ FT_BBox cbox;
+ FT_Glyph_Metrics* metrics = &glyph->root.metrics;
+
+ FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
+
+ /* grid fit the bounding box if necessary */
+ if (hinting)
{
- vec->x = FT_MulFix( vec->x, x_scale );
- vec->y = FT_MulFix( vec->y, y_scale );
+ cbox.xMin &= -64;
+ cbox.yMin &= -64;
+ cbox.xMax = ( cbox.xMax+63 ) & -64;
+ cbox.yMax = ( cbox.yMax+63 ) & -64;
}
-
- /* Then scale the metrics */
- metrics->width = FT_MulFix( metrics->width, x_scale );
- metrics->height = FT_MulFix( metrics->height, y_scale );
-
- metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale );
- metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale );
- metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
-
- metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
- metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
- metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale );
+
+ metrics->width = cbox.xMax - cbox.xMin;
+ metrics->height = cbox.yMax - cbox.yMin;
+
+ metrics->horiBearingX = cbox.xMin;
+ metrics->horiBearingY = cbox.yMax;
+
+ /* copy the _unscaled_ advance width */
+ metrics->horiAdvance = decoder.builder.advance.x;
+
+ /* make up vertical metrics */
+ metrics->vertBearingX = 0;
+ metrics->vertBearingY = 0;
+ metrics->vertAdvance = 0;
+
+ glyph->root.format = ft_glyph_format_outline;
+
+ glyph->root.outline.flags &= ft_outline_owner;
+ if ( size->root.metrics.y_ppem < 24 )
+ glyph->root.outline.flags |= ft_outline_high_precision;
+ /*
+ glyph->root.outline.second_pass = TRUE;
+ glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+ glyph->root.outline.dropout_mode = 2;
+ */
+
+ if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
+ {
+ /* scale the outline and the metrics */
+ T1_Int n;
+ FT_Outline* cur = &decoder.builder.base;
+ T1_Vector* vec = cur->points;
+ T1_Fixed x_scale = glyph->x_scale;
+ T1_Fixed y_scale = glyph->y_scale;
+
+ /* First of all, scale the points */
+ for ( n = cur->n_points; n > 0; n--, vec++ )
+ {
+ vec->x = FT_MulFix( vec->x, x_scale );
+ vec->y = FT_MulFix( vec->y, y_scale );
+ }
+
+ /* Then scale the metrics */
+ metrics->width = FT_MulFix( metrics->width, x_scale );
+ metrics->height = FT_MulFix( metrics->height, y_scale );
+
+ metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale );
+ metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale );
+ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
+
+ metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
+ metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
+ metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale );
+ }
}
}
return error;
--- a/src/type1z/t1gload.h
+++ b/src/type1z/t1gload.h
@@ -107,6 +107,7 @@
T1_BBox bbox; /* bounding box */
T1_Bool path_begun;
T1_Bool load_points;
+ T1_Bool no_recurse;
T1_Error error; /* only used for memory errors */
T1_Bool metrics_only;