Add vertical phantom points.
* include/freetype/internal/tttypes.h (TT_LoaderRec): Add `top_bearing', `vadvance', `pp3, and `pp4'. * src/autofit/afloader.c (af_loader_load_g): Handle two more points. * src/autohint/ahhint.c (ah_hinter_load): Handle two more points. * src/truetype/ttgload.c (Get_VMetrics): New function. (TT_Load_Simple_Glyph, TT_Process_Simple_Glyph): Handle two more points. (load_truetype_glyph): Use Get_VMetrics. Handle two more points. (compute_glyph_metrics): Thanks to vertical phantom points we now can always compute `advance_height' and `top_bearing'. * src/truetype/ttobjs.h (TT_SubglyphRec): Add vertical phantom points. * src/autohint/ahglyph.c (ah_outline_load): Fix allocation of `news'. Converting some files to Unix end-of-line convention.
This commit is contained in:
parent
60e0a4d5db
commit
8bb07e6386
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
|||
2004-13-26 George Williams <gww@silcom.com>
|
||||
|
||||
Add vertical phantom points.
|
||||
|
||||
* include/freetype/internal/tttypes.h (TT_LoaderRec): Add
|
||||
`top_bearing', `vadvance', `pp3, and `pp4'.
|
||||
|
||||
* src/autofit/afloader.c (af_loader_load_g): Handle two more points.
|
||||
|
||||
* src/autohint/ahhint.c (ah_hinter_load): Handle two more points.
|
||||
* src/truetype/ttgload.c (Get_VMetrics): New function.
|
||||
(TT_Load_Simple_Glyph, TT_Process_Simple_Glyph): Handle two more
|
||||
points.
|
||||
(load_truetype_glyph): Use Get_VMetrics.
|
||||
Handle two more points.
|
||||
(compute_glyph_metrics): Thanks to vertical phantom points we now
|
||||
can always compute `advance_height' and `top_bearing'.
|
||||
* src/truetype/ttobjs.h (TT_SubglyphRec): Add vertical phantom
|
||||
points.
|
||||
|
||||
|
||||
* src/autohint/ahglyph.c (ah_outline_load): Fix allocation of
|
||||
`news'.
|
||||
|
||||
2004-03-21 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/bdf/bdfdrivr.c (BDF_Glyph_Load): Fix left side bearing.
|
||||
|
|
|
@ -1342,11 +1342,15 @@ FT_BEGIN_HEADER
|
|||
FT_BBox bbox;
|
||||
FT_Int left_bearing;
|
||||
FT_Int advance;
|
||||
FT_Int top_bearing;
|
||||
FT_Int vadvance;
|
||||
FT_Int linear;
|
||||
FT_Bool linear_def;
|
||||
FT_Bool preserve_pps;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp2;
|
||||
FT_Vector pp3;
|
||||
FT_Vector pp4;
|
||||
|
||||
FT_ULong glyf_offset;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
/* copy the outline points in the loader's current */
|
||||
/* extra points which is used to keep original glyph coordinates */
|
||||
error = FT_GlyphLoader_CheckPoints( gloader,
|
||||
slot->outline.n_points + 2,
|
||||
slot->outline.n_points + 4,
|
||||
slot->outline.n_contours );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
@ -144,7 +144,8 @@
|
|||
gloader->current.outline.n_points = slot->outline.n_points;
|
||||
gloader->current.outline.n_contours = slot->outline.n_contours;
|
||||
|
||||
/* compute original phantom points */
|
||||
/* compute original horizontal phantom points (and ignore */
|
||||
/* vertical ones) */
|
||||
loader->pp1.x = hints->x_delta;
|
||||
loader->pp1.y = hints->y_delta;
|
||||
loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
|
||||
|
|
|
@ -18,6 +18,7 @@ FT_BEGIN_HEADER
|
|||
FT_Vector trans_delta;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp2;
|
||||
/* we don't handle vertical phantom points */
|
||||
|
||||
} AF_LoaderRec, *AF_Loader;
|
||||
|
||||
|
|
|
@ -435,7 +435,7 @@
|
|||
/* */
|
||||
if ( num_points + 2 > outline->max_points )
|
||||
{
|
||||
FT_Int news = FT_PAD_CEIL( num_points, 8 );
|
||||
FT_Int news = FT_PAD_CEIL( num_points + 2, 8 );
|
||||
FT_Int max = outline->max_points;
|
||||
|
||||
|
||||
|
|
|
@ -1489,7 +1489,7 @@
|
|||
|
||||
/* copy the outline points in the loader's current */
|
||||
/* extra points which is used to keep original glyph coordinates */
|
||||
error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
|
||||
error = ah_loader_check_points( gloader, slot->outline.n_points + 4,
|
||||
slot->outline.n_contours );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
@ -1506,7 +1506,7 @@
|
|||
gloader->current.outline.n_points = slot->outline.n_points;
|
||||
gloader->current.outline.n_contours = slot->outline.n_contours;
|
||||
|
||||
/* compute original phantom points */
|
||||
/* compute original horizontal phantom points, ignoring vertical ones */
|
||||
hinter->pp1.x = 0;
|
||||
hinter->pp1.y = 0;
|
||||
hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale );
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/* General types and definitions for the auto-hint module */
|
||||
/* (specification only). */
|
||||
/* */
|
||||
/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */
|
||||
/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
|
@ -492,8 +492,9 @@ FT_BEGIN_HEADER
|
|||
AH_Outline glyph;
|
||||
|
||||
AH_Loader loader;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp1; /* horizontal phantom points */
|
||||
FT_Vector pp2;
|
||||
/* we ignore vertical phantom points */
|
||||
|
||||
FT_Bool transformed;
|
||||
FT_Vector trans_delta;
|
||||
|
|
|
@ -162,6 +162,57 @@
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Returns the vertical metrics in font units for a given glyph. */
|
||||
/* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */
|
||||
/* table, typoAscender/Descender from the `OS/2' table would be used */
|
||||
/* instead, and if there were no `OS/2' table, use ascender/descender */
|
||||
/* from the `hhea' table. But that is not what Microsoft's rasterizer */
|
||||
/* apparently does: It uses the ppem value as the advance height, and */
|
||||
/* sets the top side bearing to be zero. */
|
||||
/* */
|
||||
/* The monospace `check' is probably not meaningful here, but we leave */
|
||||
/* it in for a consistent interface. */
|
||||
/* */
|
||||
static void
|
||||
Get_VMetrics( TT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_Bool check,
|
||||
FT_Short* tsb,
|
||||
FT_UShort* ah )
|
||||
{
|
||||
FT_UNUSED( check );
|
||||
|
||||
if ( face->vertical_info )
|
||||
TT_Get_Metrics( (TT_HoriHeader *)&face->vertical, idx, tsb, ah );
|
||||
|
||||
#if 1 /* Emperically determined, at variance with what MS said */
|
||||
|
||||
else
|
||||
{
|
||||
*tsb = 0;
|
||||
*ah = face->root.units_per_EM;
|
||||
}
|
||||
|
||||
#else /* This is what MS said to do. It isn't what they do, however. */
|
||||
|
||||
else if ( face->os2.version != 0xFFFFU )
|
||||
{
|
||||
*tsb = face->os2.sTypoAscender;
|
||||
*ah = face->os2.sTypoAscender - face->os2.sTypoDescender;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tsb = face->horizontal.Ascender;
|
||||
*ah = face->horizontal.Ascender - face->horizontal.Descender;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define cur_to_org( n, zone ) \
|
||||
FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) )
|
||||
|
||||
|
@ -317,7 +368,7 @@
|
|||
if ( n_contours > 0 )
|
||||
n_points = cont[-1] + 1;
|
||||
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 );
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, n_points + 4, 0 );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
|
@ -635,12 +686,16 @@
|
|||
|
||||
/* add shadow points */
|
||||
|
||||
/* Now add the two shadow points at n and n + 1. */
|
||||
/* 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. */
|
||||
|
||||
{
|
||||
FT_Vector* pp1;
|
||||
FT_Vector* pp2;
|
||||
FT_Vector* pp3;
|
||||
FT_Vector* pp4;
|
||||
|
||||
|
||||
/* pp1 = xMin - lsb */
|
||||
|
@ -653,14 +708,26 @@
|
|||
pp2->x = pp1->x + load->advance;
|
||||
pp2->y = 0;
|
||||
|
||||
/* pp3 = top side bearing */
|
||||
pp3 = pp1 + 2;
|
||||
pp3->x = 0;
|
||||
pp3->y = load->top_bearing + load->bbox.yMax;
|
||||
|
||||
/* pp4 = pp3 - ah */
|
||||
pp4 = pp1 + 3;
|
||||
pp4->x = 0;
|
||||
pp4->y = pp3->y - load->vadvance;
|
||||
|
||||
outline->tags[n_points ] = 0;
|
||||
outline->tags[n_points + 1] = 0;
|
||||
outline->tags[n_points + 2] = 0;
|
||||
outline->tags[n_points + 3] = 0;
|
||||
}
|
||||
|
||||
/* Note that we return two more points that are not */
|
||||
/* part of the glyph outline. */
|
||||
|
||||
n_points += 2;
|
||||
n_points += 4;
|
||||
|
||||
/* set up zone for hinting */
|
||||
tt_prepare_zone( zone, &gloader->current, 0, 0 );
|
||||
|
@ -687,15 +754,18 @@
|
|||
/* eventually hint the glyph */
|
||||
if ( IS_HINTED( load->load_flags ) )
|
||||
{
|
||||
FT_Pos x = zone->org[n_points-2].x;
|
||||
FT_Pos x = zone->org[n_points-4].x;
|
||||
FT_Pos y = zone->org[n_points-2].y;
|
||||
|
||||
|
||||
x = FT_PIX_ROUND( x ) - x;
|
||||
translate_array( n_points, zone->org, x, 0 );
|
||||
y = FT_PIX_ROUND( y ) - y;
|
||||
translate_array( n_points, zone->org, x, y );
|
||||
|
||||
org_to_cur( n_points, zone );
|
||||
|
||||
zone->cur[n_points - 1].x = FT_PIX_ROUND( zone->cur[n_points - 1].x );
|
||||
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
|
||||
|
||||
|
@ -711,7 +781,7 @@
|
|||
load->exec->pedantic_hinting = (FT_Bool)( load->load_flags &
|
||||
FT_LOAD_PEDANTIC );
|
||||
load->exec->pts = *zone;
|
||||
load->exec->pts.n_points += 2;
|
||||
load->exec->pts.n_points += 4;
|
||||
|
||||
error = TT_Run_Context( load->exec, debug );
|
||||
if ( error && load->exec->pedantic_hinting )
|
||||
|
@ -727,8 +797,10 @@
|
|||
/* save glyph phantom points */
|
||||
if ( !load->preserve_pps )
|
||||
{
|
||||
load->pp1 = zone->cur[n_points - 2];
|
||||
load->pp2 = zone->cur[n_points - 1];
|
||||
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];
|
||||
}
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
@ -797,16 +869,22 @@
|
|||
y_scale = loader->size->metrics.y_scale;
|
||||
}
|
||||
|
||||
/* get horizontal metrics */
|
||||
/* get metrics, horizontal and vertical */
|
||||
{
|
||||
FT_Short left_bearing = 0;
|
||||
FT_UShort advance_width = 0;
|
||||
FT_Short left_bearing = 0, top_bearing = 0;
|
||||
FT_UShort advance_width = 0, advance_height = 0;
|
||||
|
||||
|
||||
Get_HMetrics( face, glyph_index,
|
||||
(FT_Bool)!( loader->load_flags &
|
||||
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
|
||||
&left_bearing,
|
||||
&advance_width );
|
||||
Get_VMetrics( face, glyph_index,
|
||||
(FT_Bool)!( loader->load_flags &
|
||||
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
|
||||
&top_bearing,
|
||||
&advance_height );
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
|
@ -830,10 +908,33 @@
|
|||
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;
|
||||
|
||||
|
||||
metrics.bearing_x = 0;
|
||||
metrics.bearing_y = top_bearing;
|
||||
metrics.advance = advance_height;
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, TRUE, &metrics );
|
||||
if ( error )
|
||||
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;
|
||||
loader->advance = advance_width;
|
||||
loader->top_bearing = top_bearing;
|
||||
loader->vadvance = advance_height;
|
||||
|
||||
if ( !loader->linear_def )
|
||||
{
|
||||
|
@ -893,9 +994,14 @@
|
|||
|
||||
loader->pp1.x = 0;
|
||||
loader->pp2.x = loader->advance;
|
||||
loader->pp3.y = 0;
|
||||
loader->pp4.y = loader->pp3.y-loader->vadvance;
|
||||
|
||||
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
||||
{
|
||||
loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
|
||||
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
|
||||
}
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
|
@ -933,10 +1039,17 @@
|
|||
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;
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -1045,7 +1158,7 @@
|
|||
|
||||
for ( n = 0; n < (FT_Int)num_subglyphs; n++ )
|
||||
{
|
||||
FT_Vector pp1, pp2;
|
||||
FT_Vector pp1, pp2, pp3, pp4;
|
||||
FT_Pos x, y;
|
||||
|
||||
|
||||
|
@ -1057,6 +1170,8 @@
|
|||
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
pp3 = loader->pp3;
|
||||
pp4 = loader->pp4;
|
||||
|
||||
num_base_points = gloader->base.outline.n_points;
|
||||
|
||||
|
@ -1072,11 +1187,15 @@
|
|||
{
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
pp3 = loader->pp3;
|
||||
pp4 = loader->pp4;
|
||||
}
|
||||
else
|
||||
{
|
||||
loader->pp1 = pp1;
|
||||
loader->pp2 = pp2;
|
||||
loader->pp3 = pp3;
|
||||
loader->pp4 = pp4;
|
||||
}
|
||||
|
||||
num_points = gloader->base.outline.n_points;
|
||||
|
@ -1273,7 +1392,7 @@
|
|||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, num_points + 2, 0 );
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, num_points + 4, 0 );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
|
@ -1282,22 +1401,28 @@
|
|||
start_point, start_contour );
|
||||
pts = &exec->pts;
|
||||
|
||||
pts->n_points = (short)(num_points + 2);
|
||||
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 );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1308,7 +1433,7 @@
|
|||
pts->tags[k] &= FT_CURVE_TAG_ON;
|
||||
}
|
||||
|
||||
cur_to_org( num_points + 2, pts );
|
||||
cur_to_org( num_points + 4, pts );
|
||||
|
||||
/* now consider hinting */
|
||||
if ( IS_HINTED( loader->load_flags ) && n_ins > 0 )
|
||||
|
@ -1324,6 +1449,8 @@
|
|||
/* 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 */
|
||||
|
@ -1443,13 +1570,9 @@
|
|||
if ( face->vertical_info &&
|
||||
face->vertical.number_Of_VMetrics > 0 )
|
||||
{
|
||||
/* Don't assume that both the vertical header and vertical */
|
||||
/* metrics are present in the same font :-) */
|
||||
advance_height = loader->pp4.y - loader->pp3.y;
|
||||
top_bearing = loader->pp3.y - bbox.yMax;
|
||||
|
||||
TT_Get_Metrics( (TT_HoriHeader*)&face->vertical,
|
||||
glyph_index,
|
||||
&top_bearing,
|
||||
&advance_height );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1465,6 +1588,12 @@
|
|||
/* here with: */
|
||||
/* ascender - descender + linegap */
|
||||
/* */
|
||||
/* NOTE3: This is different from what MS's rasterizer */
|
||||
/* appears to do when getting default values */
|
||||
/* for the vertical phantom points. We leave */
|
||||
/* the old code untouched, but relying on */
|
||||
/* phantom points alone might be reasonable */
|
||||
/* (i.e., removing the `if' above). */
|
||||
if ( face->os2.version != 0xFFFFU )
|
||||
{
|
||||
top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 );
|
||||
|
@ -1507,6 +1636,8 @@
|
|||
advance_height = (FT_UShort)metrics.advance;
|
||||
}
|
||||
|
||||
/* GWW: Do vertical metrics get loaded incrementally too? */
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
/* We must adjust the top_bearing value from the bounding box given */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* */
|
||||
/* Objects manager (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
|
@ -216,7 +216,8 @@ FT_BEGIN_HEADER
|
|||
|
||||
TT_Transform transform; /* transformation matrix */
|
||||
|
||||
FT_Vector pp1, pp2; /* phantom points */
|
||||
FT_Vector pp1, pp2; /* phantom points (horizontal) */
|
||||
FT_Vector pp3, pp4; /* phantom points (vertical) */
|
||||
|
||||
} TT_SubGlyphRec, *TT_SubGlyph_Stack;
|
||||
|
||||
|
|
Loading…
Reference in New Issue