Clean up the SFNT_Interface. Table loading functions are now named
after the tables' tags; `hdmx' is TrueType-specific and thus the code is moved to the truetype module; `get_metrics' is moved here from the truetype module so that the code can be shared with the cff module. This pass involves no real changes. That is, the code is moved verbatim mostly. The only exception is the return value of `tt_face_get_metrics'. * include/freetype/internal/sfnt.h, src/sfnt/rules.mk, src/sfnt/sfdriver.c, src/sfnt/sfnt.c, src/sfnt/sfobjs.c, src/sfnt/ttload.c, src/sfnt/ttload.h, src/sfnt/ttsbit.c, src/sfnt/ttsbit.h, src/sfnt/ttsbit0.c: Clean up the SFNT_Interface. * src/sfnt/ttmtx.c, src/sfnt/ttmtx.h: Metrics-related tables' loading and parsing code is moved here. Move `tt_face_get_metrics' here from the truetype module. The return value is changed from `void' to `FT_Error'. * include/freetype/internal/fttrace.h: New trace: ttmtx. * src/truetype/ttpload.c, src/truetype/ttpload.h: `hdmx' loading and parsing code is moved here. New function `tt_face_load_prep' splitted from `tt_face_load_fpgm'. `tt_face_load_fpgm' returns `FT_Err_Ok' if `fpgm' doesn't exist. * src/cff/cffgload.c, src/cff/cffobjs.c: Update. * src/truetype/ttgload.c, src/truetype/ttobjs.c: Update.
This commit is contained in:
parent
d39fda2b55
commit
f5aa47beb0
32
ChangeLog
32
ChangeLog
@ -1,3 +1,35 @@
|
||||
2006-02-13 Chia-I Wu <b90201047@ntu.edu.tw>
|
||||
|
||||
Clean up the SFNT_Interface. Table loading functions are now named
|
||||
after the tables' tags; `hdmx' is TrueType-specific and thus the code
|
||||
is moved to the truetype module; `get_metrics' is moved here from the
|
||||
truetype module so that the code can be shared with the cff module.
|
||||
|
||||
This pass involves no real changes. That is, the code is moved
|
||||
verbatim mostly. The only exception is the return value of
|
||||
`tt_face_get_metrics'.
|
||||
|
||||
* include/freetype/internal/sfnt.h, src/sfnt/rules.mk,
|
||||
src/sfnt/sfdriver.c, src/sfnt/sfnt.c, src/sfnt/sfobjs.c,
|
||||
src/sfnt/ttload.c, src/sfnt/ttload.h, src/sfnt/ttsbit.c,
|
||||
src/sfnt/ttsbit.h, src/sfnt/ttsbit0.c: Clean up the SFNT_Interface.
|
||||
|
||||
* src/sfnt/ttmtx.c, src/sfnt/ttmtx.h: Metrics-related tables' loading
|
||||
and parsing code is moved here.
|
||||
Move `tt_face_get_metrics' here from the truetype module. The return
|
||||
value is changed from `void' to `FT_Error'.
|
||||
|
||||
* include/freetype/internal/fttrace.h: New trace: ttmtx.
|
||||
|
||||
* src/truetype/ttpload.c, src/truetype/ttpload.h: `hdmx' loading and
|
||||
parsing code is moved here.
|
||||
New function `tt_face_load_prep' splitted from `tt_face_load_fpgm'.
|
||||
`tt_face_load_fpgm' returns `FT_Err_Ok' if `fpgm' doesn't exist.
|
||||
|
||||
* src/cff/cffgload.c, src/cff/cffobjs.c: Update.
|
||||
|
||||
* src/truetype/ttgload.c, src/truetype/ttobjs.c: Update.
|
||||
|
||||
2006-02-11 Chia-I Wu <b90201047@ntu.edu.tw>
|
||||
|
||||
* src/autofit/afcjk.c (af_cjk_metrics_init): Fix a stupid bug...
|
||||
|
@ -45,6 +45,7 @@ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */
|
||||
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
|
||||
FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */
|
||||
FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */
|
||||
FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */
|
||||
FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */
|
||||
FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */
|
||||
|
||||
|
@ -442,6 +442,31 @@ FT_BEGIN_HEADER
|
||||
/* TT_Load_Metrics_Func */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Load a metrics table, which is a table comes with a horizontal */
|
||||
/* and a vertical version. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
/* stream :: The input stream. */
|
||||
/* */
|
||||
/* vertical :: A boolean flag. If set, load the vertical one. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
typedef FT_Error
|
||||
(*TT_Load_Metrics_Func)( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <FuncType> */
|
||||
/* TT_Get_Metrics_Func */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Load the horizontal or vertical header in a face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
@ -455,9 +480,11 @@ FT_BEGIN_HEADER
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
typedef FT_Error
|
||||
(*TT_Load_Metrics_Func)( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical );
|
||||
(*TT_Get_Metrics_Func)( TT_Face face,
|
||||
FT_Bool vertical,
|
||||
FT_UInt gindex,
|
||||
FT_Short* abearing,
|
||||
FT_UShort* aadvance );
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
@ -548,39 +575,38 @@ FT_BEGIN_HEADER
|
||||
|
||||
/* these functions are called by `load_face' but they can also */
|
||||
/* be called from external modules, if there is a need to do so */
|
||||
TT_Load_Table_Func load_header;
|
||||
TT_Load_Metrics_Func load_metrics;
|
||||
TT_Load_Table_Func load_charmaps;
|
||||
TT_Load_Table_Func load_max_profile;
|
||||
TT_Load_Table_Func load_head;
|
||||
TT_Load_Metrics_Func load_hhea;
|
||||
TT_Load_Table_Func load_cmap;
|
||||
TT_Load_Table_Func load_maxp;
|
||||
TT_Load_Table_Func load_os2;
|
||||
TT_Load_Table_Func load_psnames;
|
||||
|
||||
TT_Load_Table_Func load_names;
|
||||
TT_Free_Table_Func free_names;
|
||||
TT_Load_Table_Func load_post;
|
||||
TT_Load_Table_Func load_name;
|
||||
TT_Free_Table_Func free_name;
|
||||
|
||||
/* optional tables */
|
||||
TT_Load_Table_Func load_hdmx;
|
||||
TT_Free_Table_Func free_hdmx;
|
||||
|
||||
TT_Load_Table_Func load_kerning;
|
||||
TT_Load_Table_Func load_kern;
|
||||
TT_Load_Table_Func load_gasp;
|
||||
TT_Load_Table_Func load_pclt;
|
||||
|
||||
/* see `ttload.h' */
|
||||
TT_Load_Table_Func load_bitmap_header;
|
||||
TT_Load_Table_Func load_bhed;
|
||||
|
||||
/* see `ttsbit.h' */
|
||||
TT_Load_Table_Func load_eblc;
|
||||
TT_Free_Table_Func free_eblc;
|
||||
|
||||
TT_Set_SBit_Strike_Func set_sbit_strike;
|
||||
TT_Load_Strike_Metrics_Func load_strike_metrics;
|
||||
TT_Load_Table_Func load_sbits;
|
||||
TT_Find_SBit_Image_Func find_sbit_image;
|
||||
TT_Load_SBit_Metrics_Func load_sbit_metrics;
|
||||
TT_Load_SBit_Image_Func load_sbit_image;
|
||||
TT_Free_Table_Func free_sbits;
|
||||
|
||||
/* see `ttkern.h' */
|
||||
TT_Face_GetKerningFunc get_kerning;
|
||||
|
||||
TT_Get_Metrics_Func get_metrics;
|
||||
|
||||
/* see `ttpost.h' */
|
||||
TT_Get_PS_Name_Func get_psname;
|
||||
TT_Free_Table_Func free_psnames;
|
||||
|
@ -569,117 +569,6 @@
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <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
|
||||
cff_get_glyph_data( TT_Face face,
|
||||
FT_UInt glyph_index,
|
||||
@ -2421,7 +2310,7 @@
|
||||
|
||||
|
||||
if ( size->strike_index != 0xFFFFFFFFUL &&
|
||||
sfnt->load_sbits &&
|
||||
sfnt->load_eblc &&
|
||||
( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
|
||||
{
|
||||
TT_SBit_MetricsRec metrics;
|
||||
@ -2621,8 +2510,10 @@
|
||||
FT_UShort vertAdvance = 0;
|
||||
|
||||
|
||||
cff_face_get_vertical_metrics( face, glyph_index,
|
||||
&vertBearingY, &vertAdvance );
|
||||
( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
||||
glyph_index,
|
||||
&vertBearingY,
|
||||
&vertAdvance );
|
||||
metrics->vertBearingY = vertBearingY;
|
||||
metrics->vertAdvance = vertAdvance;
|
||||
}
|
||||
|
@ -380,7 +380,7 @@
|
||||
else
|
||||
{
|
||||
/* load the `cmap' table explicitly */
|
||||
error = sfnt->load_charmaps( face, stream );
|
||||
error = sfnt->load_cmap( face, stream );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
|
@ -26,6 +26,7 @@ SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR))
|
||||
# SFNT driver sources (i.e., C files)
|
||||
#
|
||||
SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \
|
||||
$(SFNT_DIR)/ttmtx.c \
|
||||
$(SFNT_DIR)/ttcmap.c \
|
||||
$(SFNT_DIR)/ttsbit.c \
|
||||
$(SFNT_DIR)/ttpost.c \
|
||||
|
@ -389,18 +389,15 @@
|
||||
tt_face_load_sfnt_header,
|
||||
tt_face_load_directory,
|
||||
|
||||
tt_face_load_header,
|
||||
tt_face_load_metrics_header,
|
||||
tt_face_load_head,
|
||||
tt_face_load_hhea,
|
||||
tt_face_load_cmap,
|
||||
tt_face_load_max_profile,
|
||||
tt_face_load_maxp,
|
||||
tt_face_load_os2,
|
||||
tt_face_load_postscript,
|
||||
tt_face_load_post,
|
||||
|
||||
tt_face_load_names,
|
||||
tt_face_free_names,
|
||||
|
||||
tt_face_load_hdmx,
|
||||
tt_face_free_hdmx,
|
||||
tt_face_load_name,
|
||||
tt_face_free_name,
|
||||
|
||||
tt_face_load_kern,
|
||||
tt_face_load_gasp,
|
||||
@ -409,12 +406,15 @@
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||
|
||||
/* see `ttload.h' */
|
||||
tt_face_load_bitmap_header,
|
||||
tt_face_load_bhed,
|
||||
|
||||
|
||||
/* see `ttsbit.h' and `sfnt.h' */
|
||||
tt_face_load_eblc,
|
||||
tt_face_free_eblc,
|
||||
|
||||
tt_face_set_sbit_strike,
|
||||
tt_face_load_strike_metrics,
|
||||
tt_face_load_sbit_strikes,
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
0,
|
||||
0,
|
||||
@ -423,7 +423,6 @@
|
||||
tt_load_sbit_metrics,
|
||||
#endif
|
||||
tt_face_load_sbit_image,
|
||||
tt_face_free_sbit_strikes,
|
||||
|
||||
#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||
|
||||
@ -440,6 +439,8 @@
|
||||
/* see `ttkern.h' */
|
||||
tt_face_get_kerning,
|
||||
|
||||
tt_face_get_metrics,
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
|
||||
|
||||
/* see `ttpost.h' */
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <ft2build.h>
|
||||
#include "ttload.c"
|
||||
#include "ttmtx.c"
|
||||
#include "ttcmap.c"
|
||||
#include "ttkern.c"
|
||||
#include "sfobjs.c"
|
||||
|
@ -457,36 +457,36 @@
|
||||
/* if this font doesn't contain outlines, we try to load */
|
||||
/* a `bhed' table */
|
||||
if ( !has_outline )
|
||||
is_apple_sbit = FT_BOOL( !LOAD_( bitmap_header ) );
|
||||
is_apple_sbit = FT_BOOL( !LOAD_( bhed ) );
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||
|
||||
/* load the font header (`head' table) if this isn't an Apple */
|
||||
/* sbit font file */
|
||||
if ( !is_apple_sbit && LOAD_( header ) )
|
||||
if ( !is_apple_sbit && LOAD_( head ) )
|
||||
goto Exit;
|
||||
|
||||
/* the following tables are often not present in embedded TrueType */
|
||||
/* fonts within PDF documents, so don't check for them. */
|
||||
(void)LOAD_( max_profile );
|
||||
(void)LOAD_( charmaps );
|
||||
(void)LOAD_( maxp );
|
||||
(void)LOAD_( cmap );
|
||||
|
||||
/* the following tables are optional in PCL fonts -- */
|
||||
/* don't check for errors */
|
||||
(void)LOAD_( names );
|
||||
psnames_error = LOAD_( psnames );
|
||||
(void)LOAD_( name );
|
||||
psnames_error = LOAD_( post );
|
||||
|
||||
/* do not load the metrics headers and tables if this is an Apple */
|
||||
/* sbit font file */
|
||||
if ( !is_apple_sbit )
|
||||
{
|
||||
/* load the `hhea' and `hmtx' tables at once */
|
||||
error = sfnt->load_metrics( face, stream, 0 );
|
||||
error = sfnt->load_hhea( face, stream, 0 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* try to load the `vhea' and `vmtx' tables at once */
|
||||
error = sfnt->load_metrics( face, stream, 1 );
|
||||
error = sfnt->load_hhea( face, stream, 1 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
@ -499,7 +499,7 @@
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||
|
||||
/* embedded bitmap support. */
|
||||
if ( sfnt->load_sbits && LOAD_( sbits ) )
|
||||
if ( sfnt->load_eblc && LOAD_( eblc ) )
|
||||
{
|
||||
/* return an error if this font file has no outlines */
|
||||
if ( error == SFNT_Err_Table_Missing && has_outline )
|
||||
@ -510,13 +510,12 @@
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||
|
||||
if ( LOAD_( hdmx ) ||
|
||||
LOAD_( pclt ) )
|
||||
if ( LOAD_( pclt ) )
|
||||
goto Exit;
|
||||
|
||||
/* consider the kerning and gasp tables as optional */
|
||||
(void)LOAD_( gasp );
|
||||
(void)LOAD_( kerning );
|
||||
(void)LOAD_( kern );
|
||||
|
||||
error = SFNT_Err_Ok;
|
||||
|
||||
@ -755,8 +754,8 @@
|
||||
sfnt->free_psnames( face );
|
||||
|
||||
/* destroy the embedded bitmaps table if it is loaded */
|
||||
if ( sfnt->free_sbits )
|
||||
sfnt->free_sbits( face );
|
||||
if ( sfnt->free_eblc )
|
||||
sfnt->free_eblc( face );
|
||||
}
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BDF
|
||||
@ -813,10 +812,7 @@
|
||||
face->gasp.numRanges = 0;
|
||||
|
||||
/* freeing the name table */
|
||||
sfnt->free_names( face );
|
||||
|
||||
/* freeing the hdmx table */
|
||||
sfnt->free_hdmx( face );
|
||||
sfnt->free_name( face );
|
||||
|
||||
/* freeing family and style name */
|
||||
FT_FREE( face->root.family_name );
|
||||
|
@ -657,8 +657,8 @@
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_header( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_head( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
return tt_face_load_generic_header( face, stream, TTAG_head );
|
||||
}
|
||||
@ -667,8 +667,8 @@
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_bitmap_header( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_bhed( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
return tt_face_load_generic_header( face, stream, TTAG_bhed );
|
||||
}
|
||||
@ -693,8 +693,8 @@
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_max_profile( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_maxp( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
TT_MaxProfile* maxProfile = &face->max_profile;
|
||||
@ -798,358 +798,6 @@
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* tt_face_load_metrics */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Loads the horizontal or vertical metrics table into a face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
/* stream :: The input stream. */
|
||||
/* */
|
||||
/* vertical :: A boolean flag. If set, load vertical metrics. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
|
||||
static FT_Error
|
||||
tt_face_load_metrics( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_ULong table_size;
|
||||
FT_Byte** ptable;
|
||||
FT_ULong* ptable_size;
|
||||
|
||||
|
||||
FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical"
|
||||
: "Horizontal",
|
||||
face ));
|
||||
|
||||
if ( vertical )
|
||||
{
|
||||
ptable = &face->vert_metrics;
|
||||
ptable_size = &face->vert_metrics_size;
|
||||
|
||||
/* The table is optional, quit silently if it wasn't found. */
|
||||
/* */
|
||||
/* XXX: Some fonts have a valid vertical header with a non-null */
|
||||
/* `number_of_VMetrics' fields, but no corresponding `vmtx' */
|
||||
/* table to get the metrics from (e.g. mingliu). */
|
||||
/* */
|
||||
/* For safety, we set the field to 0! */
|
||||
/* */
|
||||
error = face->goto_table( face, TTAG_vmtx, stream, &table_size );
|
||||
if ( error )
|
||||
{
|
||||
/* Set number_Of_VMetrics to 0! */
|
||||
FT_TRACE2(( " no vertical header in file.\n" ));
|
||||
error = SFNT_Err_Ok;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptable = &face->horz_metrics;
|
||||
ptable_size = &face->horz_metrics_size;
|
||||
|
||||
error = face->goto_table( face, TTAG_hmtx, stream, &table_size );
|
||||
if ( error )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
/* If this is an incrementally loaded font and there are */
|
||||
/* overriding metrics, tolerate a missing `hmtx' table. */
|
||||
if ( face->root.internal->incremental_interface &&
|
||||
face->root.internal->incremental_interface->funcs->
|
||||
get_glyph_metrics )
|
||||
{
|
||||
face->horizontal.number_Of_HMetrics = 0;
|
||||
error = SFNT_Err_Ok;
|
||||
goto Exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
FT_ERROR(( " no horizontal metrics in file!\n" ));
|
||||
error = SFNT_Err_Hmtx_Table_Missing;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( FT_FRAME_EXTRACT( table_size, *ptable ) )
|
||||
goto Exit;
|
||||
|
||||
*ptable_size = table_size;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#else /* !OPTIMIZE_MEMORY */
|
||||
|
||||
static FT_Error
|
||||
tt_face_load_metrics( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
FT_ULong table_len;
|
||||
FT_Long num_shorts, num_longs, num_shorts_checked;
|
||||
|
||||
TT_LongMetrics * longs;
|
||||
TT_ShortMetrics** shorts;
|
||||
|
||||
|
||||
FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical"
|
||||
: "Horizontal",
|
||||
face ));
|
||||
|
||||
if ( vertical )
|
||||
{
|
||||
/* The table is optional, quit silently if it wasn't found. */
|
||||
/* */
|
||||
/* XXX: Some fonts have a valid vertical header with a non-null */
|
||||
/* `number_of_VMetrics' fields, but no corresponding `vmtx' */
|
||||
/* table to get the metrics from (e.g. mingliu). */
|
||||
/* */
|
||||
/* For safety, we set the field to 0! */
|
||||
/* */
|
||||
error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
|
||||
if ( error )
|
||||
{
|
||||
/* Set number_Of_VMetrics to 0! */
|
||||
FT_TRACE2(( " no vertical header in file.\n" ));
|
||||
face->vertical.number_Of_VMetrics = 0;
|
||||
error = SFNT_Err_Ok;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
num_longs = face->vertical.number_Of_VMetrics;
|
||||
longs = (TT_LongMetrics *)&face->vertical.long_metrics;
|
||||
shorts = (TT_ShortMetrics**)&face->vertical.short_metrics;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
|
||||
if ( error )
|
||||
{
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
/* If this is an incrementally loaded font and there are */
|
||||
/* overriding metrics, tolerate a missing `hmtx' table. */
|
||||
if ( face->root.internal->incremental_interface &&
|
||||
face->root.internal->incremental_interface->funcs->
|
||||
get_glyph_metrics )
|
||||
{
|
||||
face->horizontal.number_Of_HMetrics = 0;
|
||||
error = SFNT_Err_Ok;
|
||||
goto Exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
FT_ERROR(( " no horizontal metrics in file!\n" ));
|
||||
error = SFNT_Err_Hmtx_Table_Missing;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
num_longs = face->horizontal.number_Of_HMetrics;
|
||||
longs = (TT_LongMetrics *)&face->horizontal.long_metrics;
|
||||
shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics;
|
||||
}
|
||||
|
||||
/* never trust derived values */
|
||||
|
||||
num_shorts = face->max_profile.numGlyphs - num_longs;
|
||||
num_shorts_checked = ( table_len - num_longs * 4L ) / 2;
|
||||
|
||||
if ( num_shorts < 0 )
|
||||
{
|
||||
FT_ERROR(( "TT_Load_%s_Metrics: more metrics than glyphs!\n",
|
||||
vertical ? "Vertical"
|
||||
: "Horizontal" ));
|
||||
|
||||
/* Adobe simply ignores this problem. So we shall do the same. */
|
||||
#if 0
|
||||
error = vertical ? SFNT_Err_Invalid_Vert_Metrics
|
||||
: SFNT_Err_Invalid_Horiz_Metrics;
|
||||
goto Exit;
|
||||
#else
|
||||
num_shorts = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( FT_QNEW_ARRAY( *longs, num_longs ) ||
|
||||
FT_QNEW_ARRAY( *shorts, num_shorts ) )
|
||||
goto Exit;
|
||||
|
||||
if ( FT_FRAME_ENTER( table_len ) )
|
||||
goto Exit;
|
||||
|
||||
{
|
||||
TT_LongMetrics cur = *longs;
|
||||
TT_LongMetrics limit = cur + num_longs;
|
||||
|
||||
|
||||
for ( ; cur < limit; cur++ )
|
||||
{
|
||||
cur->advance = FT_GET_USHORT();
|
||||
cur->bearing = FT_GET_SHORT();
|
||||
}
|
||||
}
|
||||
|
||||
/* do we have an inconsistent number of metric values? */
|
||||
{
|
||||
TT_ShortMetrics* cur = *shorts;
|
||||
TT_ShortMetrics* limit = cur +
|
||||
FT_MIN( num_shorts, num_shorts_checked );
|
||||
|
||||
|
||||
for ( ; cur < limit; cur++ )
|
||||
*cur = FT_GET_SHORT();
|
||||
|
||||
/* We fill up the missing left side bearings with the */
|
||||
/* last valid value. Since this will occur for buggy CJK */
|
||||
/* fonts usually only, nothing serious will happen. */
|
||||
if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
|
||||
{
|
||||
FT_Short val = (*shorts)[num_shorts_checked - 1];
|
||||
|
||||
|
||||
limit = *shorts + num_shorts;
|
||||
for ( ; cur < limit; cur++ )
|
||||
*cur = val;
|
||||
}
|
||||
}
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
FT_TRACE2(( "loaded\n" ));
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif /* !FT_OPTIMIZE_METRICS */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* tt_face_load_metrics_header */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Loads the horizontal or vertical header in a face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
/* stream :: The input stream. */
|
||||
/* */
|
||||
/* vertical :: A boolean flag. If set, load vertical metrics. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_metrics_header( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical )
|
||||
{
|
||||
FT_Error error;
|
||||
TT_HoriHeader* header;
|
||||
|
||||
const FT_Frame_Field metrics_header_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE TT_HoriHeader
|
||||
|
||||
FT_FRAME_START( 36 ),
|
||||
FT_FRAME_ULONG ( Version ),
|
||||
FT_FRAME_SHORT ( Ascender ),
|
||||
FT_FRAME_SHORT ( Descender ),
|
||||
FT_FRAME_SHORT ( Line_Gap ),
|
||||
FT_FRAME_USHORT( advance_Width_Max ),
|
||||
FT_FRAME_SHORT ( min_Left_Side_Bearing ),
|
||||
FT_FRAME_SHORT ( min_Right_Side_Bearing ),
|
||||
FT_FRAME_SHORT ( xMax_Extent ),
|
||||
FT_FRAME_SHORT ( caret_Slope_Rise ),
|
||||
FT_FRAME_SHORT ( caret_Slope_Run ),
|
||||
FT_FRAME_SHORT ( caret_Offset ),
|
||||
FT_FRAME_SHORT ( Reserved[0] ),
|
||||
FT_FRAME_SHORT ( Reserved[1] ),
|
||||
FT_FRAME_SHORT ( Reserved[2] ),
|
||||
FT_FRAME_SHORT ( Reserved[3] ),
|
||||
FT_FRAME_SHORT ( metric_Data_Format ),
|
||||
FT_FRAME_USHORT( number_Of_HMetrics ),
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
|
||||
FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " ));
|
||||
|
||||
if ( vertical )
|
||||
{
|
||||
face->vertical_info = 0;
|
||||
|
||||
/* The vertical header table is optional, so return quietly if */
|
||||
/* we don't find it. */
|
||||
error = face->goto_table( face, TTAG_vhea, stream, 0 );
|
||||
if ( error )
|
||||
{
|
||||
error = SFNT_Err_Ok;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
face->vertical_info = 1;
|
||||
header = (TT_HoriHeader*)&face->vertical;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The horizontal header is mandatory for most fonts; return */
|
||||
/* an error if we don't find it. */
|
||||
error = face->goto_table( face, TTAG_hhea, stream, 0 );
|
||||
if ( error )
|
||||
{
|
||||
error = SFNT_Err_Horiz_Header_Missing;
|
||||
|
||||
/* No `hhea' table necessary for SFNT Mac fonts. */
|
||||
if ( face->format_tag == TTAG_true )
|
||||
{
|
||||
FT_TRACE2(( "missing. This is an SFNT Mac font.\n"));
|
||||
error = SFNT_Err_Ok;
|
||||
}
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
header = &face->horizontal;
|
||||
}
|
||||
|
||||
if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )
|
||||
goto Exit;
|
||||
|
||||
header->long_metrics = NULL;
|
||||
header->short_metrics = NULL;
|
||||
|
||||
FT_TRACE2(( "loaded\n" ));
|
||||
|
||||
/* Now try to load the corresponding metrics */
|
||||
|
||||
error = tt_face_load_metrics( face, stream, vertical );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -1167,8 +815,8 @@
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_names( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_name( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
@ -1306,7 +954,7 @@
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_names( TT_Face face )
|
||||
tt_face_free_name( TT_Face face )
|
||||
{
|
||||
FT_Memory memory = face->root.driver->root.memory;
|
||||
TT_NameTable table = &face->name_table;
|
||||
@ -1539,8 +1187,8 @@
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_postscript( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_post( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
TT_Postscript* post = &face->postscript;
|
||||
@ -1719,187 +1367,4 @@
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* tt_face_load_hdmx */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Loads the horizontal device metrics table. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
/* stream :: A handle to the input stream. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_hdmx( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
FT_UInt version, nn, num_records;
|
||||
FT_ULong table_size, record_size;
|
||||
FT_Byte* p;
|
||||
FT_Byte* limit;
|
||||
|
||||
|
||||
/* this table is optional */
|
||||
error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
|
||||
if ( error || table_size < 8 )
|
||||
return SFNT_Err_Ok;
|
||||
|
||||
if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
|
||||
goto Exit;
|
||||
|
||||
p = face->hdmx_table;
|
||||
limit = p + table_size;
|
||||
|
||||
version = FT_NEXT_USHORT( p );
|
||||
num_records = FT_NEXT_USHORT( p );
|
||||
record_size = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( version != 0 || num_records > 255 || record_size > 0x40000 )
|
||||
{
|
||||
error = SFNT_Err_Invalid_File_Format;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
|
||||
goto Fail;
|
||||
|
||||
for ( nn = 0; nn < num_records; nn++ )
|
||||
{
|
||||
if ( p + record_size > limit )
|
||||
break;
|
||||
|
||||
face->hdmx_record_sizes[nn] = p[0];
|
||||
p += record_size;
|
||||
}
|
||||
|
||||
face->hdmx_record_count = nn;
|
||||
face->hdmx_table_size = table_size;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
FT_FRAME_RELEASE( face->hdmx_table );
|
||||
face->hdmx_table_size = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_hdmx( TT_Face face )
|
||||
{
|
||||
FT_Stream stream = face->root.stream;
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FT_FREE( face->hdmx_record_sizes );
|
||||
FT_FRAME_RELEASE( face->hdmx_table );
|
||||
}
|
||||
|
||||
#else /* !FT_OPTIMIZE_MEMORY */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_hdmx( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
TT_Hdmx hdmx = &face->hdmx;
|
||||
FT_Short num_records;
|
||||
FT_Long num_glyphs;
|
||||
FT_Long record_size;
|
||||
|
||||
|
||||
hdmx->version = 0;
|
||||
hdmx->num_records = 0;
|
||||
hdmx->records = 0;
|
||||
|
||||
/* this table is optional */
|
||||
error = face->goto_table( face, TTAG_hdmx, stream, 0 );
|
||||
if ( error )
|
||||
return SFNT_Err_Ok;
|
||||
|
||||
if ( FT_FRAME_ENTER( 8L ) )
|
||||
goto Exit;
|
||||
|
||||
hdmx->version = FT_GET_USHORT();
|
||||
num_records = FT_GET_SHORT();
|
||||
record_size = FT_GET_LONG();
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
if ( record_size < 0 || num_records < 0 )
|
||||
return SFNT_Err_Invalid_File_Format;
|
||||
|
||||
/* Only recognize format 0 */
|
||||
if ( hdmx->version != 0 )
|
||||
goto Exit;
|
||||
|
||||
/* we can't use FT_QNEW_ARRAY here; otherwise tt_face_free_hdmx */
|
||||
/* could fail during deallocation */
|
||||
if ( FT_NEW_ARRAY( hdmx->records, num_records ) )
|
||||
goto Exit;
|
||||
|
||||
hdmx->num_records = num_records;
|
||||
num_glyphs = face->root.num_glyphs;
|
||||
record_size -= num_glyphs + 2;
|
||||
|
||||
{
|
||||
TT_HdmxEntry cur = hdmx->records;
|
||||
TT_HdmxEntry limit = cur + hdmx->num_records;
|
||||
|
||||
|
||||
for ( ; cur < limit; cur++ )
|
||||
{
|
||||
/* read record */
|
||||
if ( FT_READ_BYTE( cur->ppem ) ||
|
||||
FT_READ_BYTE( cur->max_width ) )
|
||||
goto Exit;
|
||||
|
||||
if ( FT_QALLOC( cur->widths, num_glyphs ) ||
|
||||
FT_STREAM_READ( cur->widths, num_glyphs ) )
|
||||
goto Exit;
|
||||
|
||||
/* skip padding bytes */
|
||||
if ( record_size > 0 && FT_STREAM_SKIP( record_size ) )
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_hdmx( TT_Face face )
|
||||
{
|
||||
if ( face )
|
||||
{
|
||||
FT_Int n;
|
||||
FT_Memory memory = face->root.driver->root.memory;
|
||||
|
||||
|
||||
for ( n = 0; n < face->hdmx.num_records; n++ )
|
||||
FT_FREE( face->hdmx.records[n].widths );
|
||||
|
||||
FT_FREE( face->hdmx.records );
|
||||
face->hdmx.num_records = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !OPTIMIZE_MEMORY */
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -60,14 +60,8 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_header( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_metrics_header( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical );
|
||||
tt_face_load_head( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
@ -76,13 +70,13 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_max_profile( TT_Face face,
|
||||
FT_Stream stream );
|
||||
tt_face_load_maxp( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_names( TT_Face face,
|
||||
FT_Stream stream );
|
||||
tt_face_load_name( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
@ -91,24 +85,16 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_postscript( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_hdmx( TT_Face face,
|
||||
tt_face_load_post( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_pclt( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
FT_LOCAL( void )
|
||||
tt_face_free_names( TT_Face face );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
tt_face_free_hdmx ( TT_Face face );
|
||||
tt_face_free_name( TT_Face face );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
@ -118,8 +104,8 @@ FT_BEGIN_HEADER
|
||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_bitmap_header( TT_Face face,
|
||||
FT_Stream stream );
|
||||
tt_face_load_bhed( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||
|
||||
|
1038
src/sfnt/ttmtx.c
Normal file
1038
src/sfnt/ttmtx.c
Normal file
File diff suppressed because it is too large
Load Diff
98
src/sfnt/ttmtx.h
Normal file
98
src/sfnt/ttmtx.h
Normal file
@ -0,0 +1,98 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ttmtx.h */
|
||||
/* */
|
||||
/* Load the metrics tables common to TTF and OTF fonts (specification). */
|
||||
/* */
|
||||
/* Copyright 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
/* modified, and distributed under the terms of the FreeType project */
|
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __TTMTX_H__
|
||||
#define __TTMTX_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_TRUETYPE_TYPES_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_hhea( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_get_metrics( TT_Face face,
|
||||
FT_Bool vertical,
|
||||
FT_UInt gindex,
|
||||
FT_Short* abearing,
|
||||
FT_UShort* aadvance );
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __TTMTX_H__ */
|
||||
|
||||
|
||||
/* END */
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ttmtx.h */
|
||||
/* */
|
||||
/* Load the metrics tables common to TTF and OTF fonts (specification). */
|
||||
/* */
|
||||
/* Copyright 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
/* modified, and distributed under the terms of the FreeType project */
|
||||
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||
/* this file you indicate that you have read the license and */
|
||||
/* understand and accept it fully. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
#ifndef __TTMTX_H__
|
||||
#define __TTMTX_H__
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_INTERNAL_TRUETYPE_TYPES_H
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_hhea( TT_Face face,
|
||||
FT_Stream stream,
|
||||
FT_Bool vertical );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_get_metrics( TT_Face face,
|
||||
FT_Bool vertical,
|
||||
FT_UInt gindex,
|
||||
FT_Short* abearing,
|
||||
FT_UShort* aadvance );
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __TTMTX_H__ */
|
||||
|
||||
|
||||
/* END */
|
@ -406,8 +406,8 @@
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_sbit_strikes( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_eblc( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
FT_Memory memory = stream->memory;
|
||||
@ -635,7 +635,7 @@
|
||||
/* face :: The target face object. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_sbit_strikes( TT_Face face )
|
||||
tt_face_free_eblc( TT_Face face )
|
||||
{
|
||||
FT_Memory memory = face->root.memory;
|
||||
TT_SBit_Strike strike = face->sbit_strikes;
|
||||
|
@ -28,11 +28,11 @@ FT_BEGIN_HEADER
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_sbit_strikes( TT_Face face,
|
||||
FT_Stream stream );
|
||||
tt_face_load_eblc( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
FT_LOCAL( void )
|
||||
tt_face_free_sbit_strikes( TT_Face face );
|
||||
tt_face_free_eblc( TT_Face face );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
|
@ -86,8 +86,8 @@
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_sbit_strikes( TT_Face face,
|
||||
FT_Stream stream )
|
||||
tt_face_load_eblc( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error = SFNT_Err_Ok;
|
||||
FT_Fixed version;
|
||||
@ -197,7 +197,7 @@
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_sbit_strikes( TT_Face face )
|
||||
tt_face_free_eblc( TT_Face face )
|
||||
{
|
||||
FT_Stream stream = face->root.stream;
|
||||
|
||||
|
@ -63,131 +63,6 @@
|
||||
#define UNSCALED_COMPONENT_OFFSET 0x1000
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* tt_face_get_metrics */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Returns the horizontal or vertical metrics in font units for a */
|
||||
/* given glyph. The metrics are the left side bearing (resp. top */
|
||||
/* side bearing) and advance width (resp. advance height). */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* header :: A pointer to either the horizontal or vertical metrics */
|
||||
/* structure. */
|
||||
/* */
|
||||
/* idx :: The glyph index. */
|
||||
/* */
|
||||
/* <Output> */
|
||||
/* bearing :: The bearing, either left side or top side. */
|
||||
/* */
|
||||
/* advance :: The advance width resp. advance height. */
|
||||
/* */
|
||||
/* <Note> */
|
||||
/* This function will much probably move to another component in the */
|
||||
/* near future, but I haven't decided which yet. */
|
||||
/* */
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
|
||||
static void
|
||||
tt_face_get_metrics( TT_Face face,
|
||||
FT_Bool vertical,
|
||||
FT_UInt idx,
|
||||
FT_Short *abearing,
|
||||
FT_UShort *aadvance )
|
||||
{
|
||||
TT_HoriHeader* header;
|
||||
FT_Byte* p;
|
||||
FT_Byte* limit;
|
||||
FT_UShort k;
|
||||
|
||||
|
||||
if ( vertical )
|
||||
{
|
||||
header = (TT_HoriHeader*)&face->vertical;
|
||||
p = face->vert_metrics;
|
||||
limit = p + face->vert_metrics_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
header = &face->horizontal;
|
||||
p = face->horz_metrics;
|
||||
limit = p + face->horz_metrics_size;
|
||||
}
|
||||
|
||||
k = header->number_Of_HMetrics;
|
||||
|
||||
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
|
||||
tt_face_get_metrics( TT_Face face,
|
||||
FT_Bool vertical,
|
||||
FT_UInt idx,
|
||||
FT_Short *abearing,
|
||||
FT_UShort *aadvance )
|
||||
{
|
||||
TT_HoriHeader* header = vertical ? (TT_HoriHeader*)&face->vertical
|
||||
: &face->horizontal;
|
||||
TT_LongMetrics longs_m;
|
||||
FT_UShort k = header->number_Of_HMetrics;
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Returns the horizontal metrics in font units for a given glyph. If */
|
||||
@ -201,57 +76,13 @@
|
||||
FT_Short* lsb,
|
||||
FT_UShort* aw )
|
||||
{
|
||||
tt_face_get_metrics( face, 0, idx, lsb, aw );
|
||||
( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
|
||||
|
||||
if ( check && face->postscript.isFixedPitch )
|
||||
*aw = face->horizontal.advance_Width_Max;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Returns the advance width table for a given pixel size if it is found */
|
||||
/* in the font's `hdmx' table (if any). */
|
||||
/* */
|
||||
static FT_Byte*
|
||||
Get_Advance_WidthPtr( TT_Face face,
|
||||
FT_Int ppem,
|
||||
FT_UInt gindex )
|
||||
{
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
|
||||
FT_UInt nn;
|
||||
FT_Byte* result = NULL;
|
||||
FT_ULong record_size = face->hdmx_record_size;
|
||||
FT_Byte* record = face->hdmx_table + 8;
|
||||
|
||||
|
||||
for ( nn = 0; nn < face->hdmx_record_count; nn++ )
|
||||
if ( face->hdmx_record_sizes[nn] == ppem )
|
||||
{
|
||||
gindex += 2;
|
||||
if ( gindex < record_size )
|
||||
result = record + gindex;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
#else
|
||||
|
||||
FT_UShort n;
|
||||
|
||||
|
||||
for ( n = 0; n < face->hdmx.num_records; n++ )
|
||||
if ( face->hdmx.records[n].ppem == ppem )
|
||||
return &face->hdmx.records[n].widths[gindex];
|
||||
|
||||
return NULL;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Returns the vertical metrics in font units for a given glyph. */
|
||||
@ -275,7 +106,7 @@
|
||||
FT_UNUSED( check );
|
||||
|
||||
if ( face->vertical_info )
|
||||
tt_face_get_metrics( face, 1, idx, tsb, ah );
|
||||
( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
|
||||
|
||||
#if 1 /* Emperically determined, at variance with what MS said */
|
||||
|
||||
@ -1769,11 +1600,13 @@
|
||||
if ( !face->postscript.isFixedPitch &&
|
||||
IS_HINTED( loader->load_flags ) )
|
||||
{
|
||||
FT_Byte* widthp = Get_Advance_WidthPtr( face,
|
||||
size->root.metrics.x_ppem,
|
||||
glyph_index );
|
||||
FT_Byte* widthp;
|
||||
|
||||
|
||||
widthp = tt_face_get_device_metrics( face,
|
||||
size->root.metrics.x_ppem,
|
||||
glyph_index );
|
||||
|
||||
if ( widthp )
|
||||
glyph->metrics.horiAdvance = *widthp << 6;
|
||||
}
|
||||
|
@ -216,6 +216,10 @@
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
error = tt_face_load_hdmx( face, stream );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
|
||||
{
|
||||
|
||||
@ -224,18 +228,17 @@
|
||||
if ( !face->root.internal->incremental_interface )
|
||||
error = tt_face_load_loca( face, stream );
|
||||
if ( !error )
|
||||
{
|
||||
error = tt_face_load_cvt( face, stream );
|
||||
if ( !error )
|
||||
error = tt_face_load_fpgm( face, stream );
|
||||
}
|
||||
error = tt_face_load_cvt( face, stream ) ||
|
||||
tt_face_load_fpgm( face, stream ) ||
|
||||
tt_face_load_prep( face, stream );
|
||||
|
||||
#else
|
||||
|
||||
if ( !error )
|
||||
error = tt_face_load_loca( face, stream ) ||
|
||||
tt_face_load_cvt( face, stream ) ||
|
||||
tt_face_load_fpgm( face, stream );
|
||||
tt_face_load_fpgm( face, stream ) ||
|
||||
tt_face_load_prep( face, stream );
|
||||
|
||||
#endif
|
||||
|
||||
@ -301,6 +304,8 @@
|
||||
/* freeing the locations table */
|
||||
tt_face_done_loca( face );
|
||||
|
||||
tt_face_free_hdmx( face );
|
||||
|
||||
/* freeing the CVT */
|
||||
FT_FREE( face->cvt );
|
||||
face->cvt_size = 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* */
|
||||
/* ttpload.c */
|
||||
/* */
|
||||
/* TrueType glyph data/program tables loader (body). */
|
||||
/* TrueType-specific tables loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
@ -400,7 +400,7 @@
|
||||
/* tt_face_load_fpgm */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Loads the font program and the cvt program. */
|
||||
/* Loads the font program. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* face :: A handle to the target face object. */
|
||||
@ -429,6 +429,7 @@
|
||||
{
|
||||
face->font_program = NULL;
|
||||
face->font_program_size = 0;
|
||||
error = TT_Err_Ok;
|
||||
|
||||
FT_TRACE2(( "is missing!\n" ));
|
||||
}
|
||||
@ -441,6 +442,47 @@
|
||||
FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
|
||||
FT_UNUSED( face );
|
||||
FT_UNUSED( stream );
|
||||
|
||||
return TT_Err_Ok;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* tt_face_load_prep */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Loads the cvt program. */
|
||||
/* */
|
||||
/* <InOut> */
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* stream :: A handle to the input stream. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_prep( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
FT_Error error;
|
||||
FT_ULong table_len;
|
||||
|
||||
|
||||
FT_TRACE2(( "Prep program " ));
|
||||
|
||||
error = face->goto_table( face, TTAG_prep, stream, &table_len );
|
||||
@ -475,4 +517,230 @@
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* tt_face_load_hdmx */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Loads the `hdmx' table into the face object. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* face :: A handle to the target face object. */
|
||||
/* */
|
||||
/* stream :: A handle to the input stream. */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* FreeType error code. 0 means success. */
|
||||
/* */
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_hdmx( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
FT_UInt version, nn, num_records;
|
||||
FT_ULong table_size, record_size;
|
||||
FT_Byte* p;
|
||||
FT_Byte* limit;
|
||||
|
||||
|
||||
/* this table is optional */
|
||||
error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
|
||||
if ( error || table_size < 8 )
|
||||
return TT_Err_Ok;
|
||||
|
||||
if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
|
||||
goto Exit;
|
||||
|
||||
p = face->hdmx_table;
|
||||
limit = p + table_size;
|
||||
|
||||
version = FT_NEXT_USHORT( p );
|
||||
num_records = FT_NEXT_USHORT( p );
|
||||
record_size = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( version != 0 || num_records > 255 || record_size > 0x40000 )
|
||||
{
|
||||
error = TT_Err_Invalid_File_Format;
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
|
||||
goto Fail;
|
||||
|
||||
for ( nn = 0; nn < num_records; nn++ )
|
||||
{
|
||||
if ( p + record_size > limit )
|
||||
break;
|
||||
|
||||
face->hdmx_record_sizes[nn] = p[0];
|
||||
p += record_size;
|
||||
}
|
||||
|
||||
face->hdmx_record_count = nn;
|
||||
face->hdmx_table_size = table_size;
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
|
||||
Fail:
|
||||
FT_FRAME_RELEASE( face->hdmx_table );
|
||||
face->hdmx_table_size = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_hdmx( TT_Face face )
|
||||
{
|
||||
FT_Stream stream = face->root.stream;
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FT_FREE( face->hdmx_record_sizes );
|
||||
FT_FRAME_RELEASE( face->hdmx_table );
|
||||
}
|
||||
|
||||
#else /* !FT_OPTIMIZE_MEMORY */
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_face_load_hdmx( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
|
||||
TT_Hdmx hdmx = &face->hdmx;
|
||||
FT_Short num_records;
|
||||
FT_Long num_glyphs;
|
||||
FT_Long record_size;
|
||||
|
||||
|
||||
hdmx->version = 0;
|
||||
hdmx->num_records = 0;
|
||||
hdmx->records = 0;
|
||||
|
||||
/* this table is optional */
|
||||
error = face->goto_table( face, TTAG_hdmx, stream, 0 );
|
||||
if ( error )
|
||||
return TT_Err_Ok;
|
||||
|
||||
if ( FT_FRAME_ENTER( 8L ) )
|
||||
goto Exit;
|
||||
|
||||
hdmx->version = FT_GET_USHORT();
|
||||
num_records = FT_GET_SHORT();
|
||||
record_size = FT_GET_LONG();
|
||||
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
if ( record_size < 0 || num_records < 0 )
|
||||
return TT_Err_Invalid_File_Format;
|
||||
|
||||
/* Only recognize format 0 */
|
||||
if ( hdmx->version != 0 )
|
||||
goto Exit;
|
||||
|
||||
/* we can't use FT_QNEW_ARRAY here; otherwise tt_face_free_hdmx */
|
||||
/* could fail during deallocation */
|
||||
if ( FT_NEW_ARRAY( hdmx->records, num_records ) )
|
||||
goto Exit;
|
||||
|
||||
hdmx->num_records = num_records;
|
||||
num_glyphs = face->root.num_glyphs;
|
||||
record_size -= num_glyphs + 2;
|
||||
|
||||
{
|
||||
TT_HdmxEntry cur = hdmx->records;
|
||||
TT_HdmxEntry limit = cur + hdmx->num_records;
|
||||
|
||||
|
||||
for ( ; cur < limit; cur++ )
|
||||
{
|
||||
/* read record */
|
||||
if ( FT_READ_BYTE( cur->ppem ) ||
|
||||
FT_READ_BYTE( cur->max_width ) )
|
||||
goto Exit;
|
||||
|
||||
if ( FT_QALLOC( cur->widths, num_glyphs ) ||
|
||||
FT_STREAM_READ( cur->widths, num_glyphs ) )
|
||||
goto Exit;
|
||||
|
||||
/* skip padding bytes */
|
||||
if ( record_size > 0 && FT_STREAM_SKIP( record_size ) )
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
tt_face_free_hdmx( TT_Face face )
|
||||
{
|
||||
if ( face )
|
||||
{
|
||||
FT_Int n;
|
||||
FT_Memory memory = face->root.driver->root.memory;
|
||||
|
||||
|
||||
for ( n = 0; n < face->hdmx.num_records; n++ )
|
||||
FT_FREE( face->hdmx.records[n].widths );
|
||||
|
||||
FT_FREE( face->hdmx.records );
|
||||
face->hdmx.num_records = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !OPTIMIZE_MEMORY */
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Returns the advance width table for a given pixel size if it is found */
|
||||
/* in the font's `hdmx' table (if any). */
|
||||
/* */
|
||||
FT_LOCAL_DEF( FT_Byte* )
|
||||
tt_face_get_device_metrics( TT_Face face,
|
||||
FT_Byte ppem,
|
||||
FT_UInt gindex )
|
||||
{
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
|
||||
FT_UInt nn;
|
||||
FT_Byte* result = NULL;
|
||||
FT_ULong record_size = face->hdmx_record_size;
|
||||
FT_Byte* record = face->hdmx_table + 8;
|
||||
|
||||
|
||||
for ( nn = 0; nn < face->hdmx_record_count; nn++ )
|
||||
if ( face->hdmx_record_sizes[nn] == ppem )
|
||||
{
|
||||
gindex += 2;
|
||||
if ( gindex < record_size )
|
||||
result = record + gindex;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
#else
|
||||
|
||||
FT_UShort n;
|
||||
|
||||
|
||||
for ( n = 0; n < face->hdmx.num_records; n++ )
|
||||
if ( face->hdmx.records[n].ppem == ppem )
|
||||
return &face->hdmx.records[n].widths[gindex];
|
||||
|
||||
return NULL;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
|
@ -2,9 +2,9 @@
|
||||
/* */
|
||||
/* ttpload.h */
|
||||
/* */
|
||||
/* TrueType glyph data/program tables loader (specification). */
|
||||
/* TrueType-specific tables loader (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2005 by */
|
||||
/* Copyright 1996-2001, 2002, 2005, 2006 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -48,6 +48,25 @@ FT_BEGIN_HEADER
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_prep( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_face_load_hdmx( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
tt_face_free_hdmx( TT_Face face );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Byte* )
|
||||
tt_face_get_device_metrics( TT_Face face,
|
||||
FT_Byte ppem,
|
||||
FT_UInt gindex );
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __TTPLOAD_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user