Add vertical metrics support to OpenType CFF outlines. Based on a
patch from Mike Moening <MikeM@RetekSolutions.com> * src/cff/cffgload.c (cff_face_get_vertical_metrics): New function. (cff_slot_load): Use cff_face_get_vertical_metrics. * docs/CHANGES: Updated.
This commit is contained in:
parent
35bfc0f1b9
commit
cfc0cf2e78
28
ChangeLog
28
ChangeLog
|
@ -1,17 +1,29 @@
|
||||||
|
2005-11-17 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
Add vertical metrics support to OpenType CFF outlines. Based on a
|
||||||
|
patch from Mike Moening <MikeM@RetekSolutions.com>
|
||||||
|
|
||||||
|
* src/cff/cffgload.c (cff_face_get_vertical_metrics): New function.
|
||||||
|
(cff_slot_load): Use cff_face_get_vertical_metrics.
|
||||||
|
|
||||||
|
* docs/CHANGES: Updated.
|
||||||
|
|
||||||
2005-11-17 Chia-I Wu <b90201047@ntu.edu.tw>
|
2005-11-17 Chia-I Wu <b90201047@ntu.edu.tw>
|
||||||
|
|
||||||
* src/base/ftcalc.c (FT_MulTo64): Commented out.
|
* src/base/ftcalc.c (FT_MulTo64): Commented out.
|
||||||
|
|
||||||
* include/freetype/internal/ftcalc.h (FT_SqrtFixed), src/base/ftcalc.c
|
* include/freetype/internal/ftcalc.h (FT_SqrtFixed),
|
||||||
(FT_SqrtFixed), include/freetype/internal/ftdebug.h
|
src/base/ftcalc.c (FT_SqrtFixed),
|
||||||
|
include/freetype/internal/ftdebug.h (FT_Trace_Get_Count,
|
||||||
|
FT_Trace_Get_Name, FT_Message, FT_Panic), src/base/ftdebug.c
|
||||||
(FT_Trace_Get_Count, FT_Trace_Get_Name, FT_Message, FT_Panic),
|
(FT_Trace_Get_Count, FT_Trace_Get_Name, FT_Message, FT_Panic),
|
||||||
src/base/ftdebug.c (FT_Trace_Get_Count, FT_Trace_Get_Name, FT_Message,
|
include/freetype/internal/ftobjs.h (FT_New_Memory, FT_Done_Memory),
|
||||||
FT_Panic), include/freetype/internal/ftobjs.h (FT_New_Memory,
|
include/freetype/internal/ftstream.h (FT_Stream_Open),
|
||||||
FT_Done_Memory), include/freetype/internal/ftstream.h
|
src/base/ftsystem.c (FT_New_Memory, FT_Done_Memory, FT_Stream_Open):
|
||||||
(FT_Stream_Open), src/base/ftsystem.c (FT_New_Memory, FT_Done_Memory,
|
s/FT_EXPORT/FT_BASE/.
|
||||||
FT_Stream_Open): s/FT_EXPORT/FT_BASE/.
|
|
||||||
|
|
||||||
* builds/exports.mk: Manually add TT_New_Context to EXPORTS_LIST too.
|
* builds/exports.mk: Manually add TT_New_Context to EXPORTS_LIST
|
||||||
|
too.
|
||||||
|
|
||||||
2005-11-15 David Turner <david@freetype.org>
|
2005-11-15 David Turner <david@freetype.org>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ LATEST CHANGES BETWEEN 2.2.0 and 2.1.10
|
||||||
|
|
||||||
- The FT_HAS_KERNING macro always returned 0.
|
- The FT_HAS_KERNING macro always returned 0.
|
||||||
|
|
||||||
|
- CFF OpenType fonts didn't return correct vertical metrics for
|
||||||
|
glyphs with outlines.
|
||||||
|
|
||||||
II. IMPORTANT CHANGES
|
II. IMPORTANT CHANGES
|
||||||
|
|
||||||
- A new API `FT_TrueTypeGX_Validate' (in FT_GX_VALIDATE_H) has
|
- A new API `FT_TrueTypeGX_Validate' (in FT_GX_VALIDATE_H) has
|
||||||
|
|
|
@ -569,6 +569,117 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* <Function> */
|
||||||
|
/* cff_face_get_vertical_metrics */
|
||||||
|
/* */
|
||||||
|
/* <Description> */
|
||||||
|
/* Return the vertical metrics in font units for a given glyph. The */
|
||||||
|
/* metrics are the top side bearing and advance height. */
|
||||||
|
/* */
|
||||||
|
/* <Input> */
|
||||||
|
/* header :: A pointer to the vertical metrics structure. */
|
||||||
|
/* */
|
||||||
|
/* idx :: The glyph index. */
|
||||||
|
/* */
|
||||||
|
/* <Output> */
|
||||||
|
/* bearing :: The top side bearing. */
|
||||||
|
/* */
|
||||||
|
/* advance :: The advance height. */
|
||||||
|
/* */
|
||||||
|
/* <Note> */
|
||||||
|
/* Horizontal metric values are directly computed from the CFF data, */
|
||||||
|
/* bypassing the `hmtx' table completely. */
|
||||||
|
/* */
|
||||||
|
#ifdef FT_OPTIMIZE_MEMORY
|
||||||
|
|
||||||
|
static void
|
||||||
|
cff_face_get_vertical_metrics( TT_Face face,
|
||||||
|
FT_UInt idx,
|
||||||
|
FT_Short *abearing,
|
||||||
|
FT_UShort *aadvance )
|
||||||
|
{
|
||||||
|
TT_VertHeader* header;
|
||||||
|
FT_Byte* p;
|
||||||
|
FT_Byte* limit;
|
||||||
|
FT_UShort k;
|
||||||
|
|
||||||
|
|
||||||
|
header = &face->vertical;
|
||||||
|
p = face->vert_metrics;
|
||||||
|
limit = p + face->vert_metrics_size;
|
||||||
|
|
||||||
|
k = header->number_Of_VMetrics;
|
||||||
|
|
||||||
|
if ( k > 0 )
|
||||||
|
{
|
||||||
|
if ( idx < (FT_UInt)k )
|
||||||
|
{
|
||||||
|
p += 4 * idx;
|
||||||
|
if ( p + 4 > limit )
|
||||||
|
goto NoData;
|
||||||
|
|
||||||
|
*aadvance = FT_NEXT_USHORT( p );
|
||||||
|
*abearing = FT_NEXT_SHORT( p );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p += 4 * ( k - 1 );
|
||||||
|
if ( p + 4 > limit )
|
||||||
|
goto NoData;
|
||||||
|
|
||||||
|
*aadvance = FT_NEXT_USHORT( p );
|
||||||
|
p += 2 + 2 * ( idx - k );
|
||||||
|
if ( p + 2 > limit )
|
||||||
|
*abearing = 0;
|
||||||
|
else
|
||||||
|
*abearing = FT_PEEK_SHORT( p );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NoData:
|
||||||
|
*abearing = 0;
|
||||||
|
*aadvance = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !FT_OPTIMIZE_MEMORY */
|
||||||
|
|
||||||
|
static void
|
||||||
|
cff_face_get_vertical_metrics( TT_Face face,
|
||||||
|
FT_UInt idx,
|
||||||
|
FT_Short *abearing,
|
||||||
|
FT_UShort *aadvance )
|
||||||
|
{
|
||||||
|
TT_VertHeader* header = &face->vertical;
|
||||||
|
TT_LongMetrics longs_m;
|
||||||
|
FT_UShort k = header->number_Of_VMetrics;
|
||||||
|
|
||||||
|
|
||||||
|
if ( k == 0 )
|
||||||
|
{
|
||||||
|
*abearing = *aadvance = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( idx < (FT_UInt)k )
|
||||||
|
{
|
||||||
|
longs_m = (TT_LongMetrics)header->long_metrics + idx;
|
||||||
|
*abearing = longs_m->bearing;
|
||||||
|
*aadvance = longs_m->advance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*abearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k];
|
||||||
|
*aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !FT_OPTIMIZE_MEMORY */
|
||||||
|
|
||||||
|
|
||||||
static FT_Error
|
static FT_Error
|
||||||
cff_get_glyph_data( TT_Face face,
|
cff_get_glyph_data( TT_Face face,
|
||||||
FT_UInt glyph_index,
|
FT_UInt glyph_index,
|
||||||
|
@ -1299,7 +1410,7 @@
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
args = stack;
|
args = stack;
|
||||||
while (args < decoder->top )
|
while ( args < decoder->top )
|
||||||
{
|
{
|
||||||
if ( phase )
|
if ( phase )
|
||||||
x += args[0];
|
x += args[0];
|
||||||
|
@ -1425,7 +1536,7 @@
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
args = stack;
|
args = stack;
|
||||||
if (num_args < 4 || ( num_args % 4 ) > 1 )
|
if ( num_args < 4 || ( num_args % 4 ) > 1 )
|
||||||
goto Stack_Underflow;
|
goto Stack_Underflow;
|
||||||
|
|
||||||
if ( check_points( builder, ( num_args / 4 ) * 3 ) )
|
if ( check_points( builder, ( num_args / 4 ) * 3 ) )
|
||||||
|
@ -1772,7 +1883,8 @@
|
||||||
/* close hints recording session */
|
/* close hints recording session */
|
||||||
if ( hinter )
|
if ( hinter )
|
||||||
{
|
{
|
||||||
if (hinter->close( hinter->hints, builder->current->n_points ) )
|
if ( hinter->close( hinter->hints,
|
||||||
|
builder->current->n_points ) )
|
||||||
goto Syntax_Error;
|
goto Syntax_Error;
|
||||||
|
|
||||||
/* apply hints to the loaded glyph outline now */
|
/* apply hints to the loaded glyph outline now */
|
||||||
|
@ -2048,7 +2160,7 @@
|
||||||
|
|
||||||
case cff_op_ifelse:
|
case cff_op_ifelse:
|
||||||
{
|
{
|
||||||
FT_Fixed cond = (args[2] <= args[3]);
|
FT_Fixed cond = ( args[2] <= args[3] );
|
||||||
|
|
||||||
|
|
||||||
FT_TRACE4(( " ifelse" ));
|
FT_TRACE4(( " ifelse" ));
|
||||||
|
@ -2268,22 +2380,6 @@
|
||||||
#endif /* 0 */
|
#endif /* 0 */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
|
||||||
/*************************************************************************/
|
|
||||||
/*************************************************************************/
|
|
||||||
/********** *********/
|
|
||||||
/********** *********/
|
|
||||||
/********** UNHINTED GLYPH LOADER *********/
|
|
||||||
/********** *********/
|
|
||||||
/********** The following code is in charge of loading a *********/
|
|
||||||
/********** single outline. It completely ignores hinting *********/
|
|
||||||
/********** and is used when FT_LOAD_NO_HINTING is set. *********/
|
|
||||||
/********** *********/
|
|
||||||
/*************************************************************************/
|
|
||||||
/*************************************************************************/
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL_DEF( FT_Error )
|
FT_LOCAL_DEF( FT_Error )
|
||||||
cff_slot_load( CFF_GlyphSlot glyph,
|
cff_slot_load( CFF_GlyphSlot glyph,
|
||||||
CFF_Size size,
|
CFF_Size size,
|
||||||
|
@ -2515,8 +2611,26 @@
|
||||||
|
|
||||||
/* make up vertical ones */
|
/* make up vertical ones */
|
||||||
metrics->vertAdvance = 0;
|
metrics->vertAdvance = 0;
|
||||||
|
metrics->vertBearingX = 0;
|
||||||
|
metrics->vertBearingY = 0;
|
||||||
|
|
||||||
glyph->root.linearVertAdvance = 0;
|
glyph->root.linearVertAdvance = 0;
|
||||||
|
|
||||||
|
/* get the vertical metrics from the vtmx table if we have one */
|
||||||
|
if ( face->vertical_info &&
|
||||||
|
face->vertical.number_Of_VMetrics > 0 &&
|
||||||
|
face->vertical.long_metrics != 0 )
|
||||||
|
{
|
||||||
|
FT_Short vertBearingY = 0;
|
||||||
|
FT_UShort vertAdvance = 0;
|
||||||
|
|
||||||
|
|
||||||
|
cff_face_get_vertical_metrics( face, glyph_index,
|
||||||
|
&vertBearingY, &vertAdvance );
|
||||||
|
metrics->vertBearingY = vertBearingY;
|
||||||
|
metrics->vertAdvance = vertAdvance;
|
||||||
|
}
|
||||||
|
|
||||||
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
|
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
|
||||||
|
|
||||||
glyph->root.outline.flags = 0;
|
glyph->root.outline.flags = 0;
|
||||||
|
@ -2536,6 +2650,7 @@
|
||||||
advance.y = 0;
|
advance.y = 0;
|
||||||
FT_Vector_Transform( &advance, &font_matrix );
|
FT_Vector_Transform( &advance, &font_matrix );
|
||||||
metrics->horiAdvance = advance.x + font_offset.x;
|
metrics->horiAdvance = advance.x + font_offset.x;
|
||||||
|
|
||||||
advance.x = 0;
|
advance.x = 0;
|
||||||
advance.y = metrics->vertAdvance;
|
advance.y = metrics->vertAdvance;
|
||||||
FT_Vector_Transform( &advance, &font_matrix );
|
FT_Vector_Transform( &advance, &font_matrix );
|
||||||
|
@ -2560,8 +2675,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then scale the metrics */
|
/* Then scale the metrics */
|
||||||
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
|
||||||
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute the other metrics */
|
/* compute the other metrics */
|
||||||
|
@ -2573,10 +2688,6 @@
|
||||||
metrics->horiBearingX = cbox.xMin;
|
metrics->horiBearingX = cbox.xMin;
|
||||||
metrics->horiBearingY = cbox.yMax;
|
metrics->horiBearingY = cbox.yMax;
|
||||||
|
|
||||||
/* make up vertical ones */
|
|
||||||
metrics->vertBearingX = 0;
|
|
||||||
metrics->vertBearingY = 0;
|
|
||||||
|
|
||||||
if ( hinting )
|
if ( hinting )
|
||||||
ft_glyphslot_grid_fit_metrics( &glyph->root );
|
ft_glyphslot_grid_fit_metrics( &glyph->root );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue