Commit be574d81 authored by David Turner's avatar David Turner
Browse files

integrated Yamano-Uchi changes to the base source code. However,

I've made a few modifications:

  - there is no new field named "driver" in "FT_SizeRec"

  - the new fields in "TT_SizeRec" are:

       strike_index   :: value 0xFFFF means "no sbit strike selected"
       strike_metrics :: the FT_Size_Metrics structure corresponding to
                         the currently selected strike

  - the code in "ttload.c" has been somewhat cleaned up too

thanks a lot, Y-U !!

- David
parent 9fe20e08
......@@ -877,16 +877,6 @@
/* to scale vertical distances expressed in font */
/* units to fractional (26.6) pixel coordinates. */
/* */
/* x_resolution :: The horizontal device resolution for this size */
/* object, expressed in integer dots per inches */
/* (dpi). As a convention, fixed font formats set */
/* this value to 72. */
/* */
/* y_resolution :: The vertical device resolution for this size */
/* object, expressed in integer dots per inches */
/* (dpi). As a convention, fixed font formats set */
/* this value to 72. */
/* */
/* ascender :: The ascender, expressed in 26.6 fixed point */
/* pixels. Always positive. */
/* */
......
......@@ -281,14 +281,18 @@
/* */
typedef
FT_Error (*TT_Load_SBit_Image_Func)( TT_Face face,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong strike_index,
FT_UInt glyph_index,
FT_UInt load_flags,
FT_Stream stream,
FT_Bitmap* map,
TT_SBit_Metrics* metrics );
typedef
FT_Error (*TT_Set_SBit_Strike_Func)( TT_Face face,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong* astrike_index );
/*************************************************************************/
/* */
......@@ -473,8 +477,10 @@
TT_Load_Table_Func load_kerning;
TT_Load_Table_Func load_gasp;
TT_Load_Table_Func load_pclt;
TT_Load_Table_Func load_pclt;
TT_Load_Table_Func load_bitmap_header;
TT_Set_SBit_Strike_Func set_sbit_strike;
/* see `ttsbit.h' */
TT_Load_Table_Func load_sbits;
TT_Load_SBit_Image_Func load_sbit_image;
......
......@@ -492,7 +492,7 @@
/* <Description> */
/* A structure used to hold the big metrics of a given glyph bitmap */
/* in a TrueType or OpenType font. These are usually found in the */
/* `EBDT' (Microsoft) or `bdat' (Apple) table. */
/* `EBDT' (Microsoft) or `bloc' (Apple) table. */
/* */
/* <Fields> */
/* height :: The glyph height in pixels. */
......@@ -700,7 +700,11 @@
/* */
/* index_ranges :: An array of glyph index ranges. */
/* */
/* color_ref :: Unused. A color reference? */
/* color_ref :: Unused. color_ref is put in for future */
/* enhancements, but these fields are already */
/* in use by other platforms (e.g. Newton). */
/* For details, please see */
/* http://fonts.apple.com/TTRefMan/RM06/Chap6bloc.html */
/* */
/* hori :: The line metrics for horizontal layouts. */
/* */
......@@ -718,6 +722,8 @@
/* and 8. */
/* */
/* flags :: Is this a vertical or horizontal strike? */
/* For details, please see */
/* http://fonts.apple.com/TTRefMan/RM06/Chap6bloc.html */
/* */
typedef struct TT_SBit_Strike_
{
......@@ -760,7 +766,6 @@
typedef struct TT_SBit_Component_
{
FT_UShort glyph_code;
FT_Char x_offset;
FT_Char y_offset;
......
......@@ -32,6 +32,7 @@
#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' )
#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' )
#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' )
#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' )
#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' )
#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' )
#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
......
......@@ -172,7 +172,11 @@
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* see `ttload.h` */
TT_Load_Bitmap_Header,
/* see `ttsbit.h' */
TT_Set_SBit_Strike,
TT_Load_SBit_Strikes,
TT_Load_SBit_Image,
TT_Free_SBit_Strikes,
......@@ -182,6 +186,8 @@
0,
0,
0,
0,
0,
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
......
......@@ -255,7 +255,9 @@
FT_Parameter* params )
{
FT_Error error;
FT_Bool missing_outline = 0;
FT_Bool has_outline;
FT_Bool is_apple_sbit;
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
FT_UNUSED( face_index );
......@@ -265,39 +267,63 @@
/* Load tables */
/* If you load SFNT wrapped sbit font files, it will fail if you */
/* want to read the `head', `hhea', and `vhea' tables. */
/* */
if ( LOAD_( header ) )
{
/* we now support two SFNT-based bitmapped font formats. */
/* they are recognized easily as they do not include a "glyf" */
/* table.. */
/* */
/* the first format comes from Apple, and uses a table named */
/* "bhed" instead of "head" to store the font header (using */
/* the same format). it also doesn't include horizontal and */
/* vertical metrics tables (i.e. "hhea" and "vhea" tables) */
/* */
/* the other format comes from Microsoft, and is used with */
/* WinCE / PocketPC. It's standard, except that it doesn't */
/* contain outlines.. */
/* */
/* do we have outlines in there ?? */
has_outline = (TT_LookUp_Table( face, TTAG_glyf ) != 0);
is_apple_sbit = 0;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
missing_outline = 1;
#else
goto Exit;
/*
* if this font doesn't contain outlines, we'll try to load
* a "bhed" table in it..
*/
if ( !has_outline )
is_apple_sbit = !LOAD_(bitmap_header);
#endif
}
/* load the font header ("head" table) if this isn't an Apple */
/* sbit font file.. */
if ( !is_apple_sbit && LOAD_(header) )
goto Exit;
/* load other tables */
if ( LOAD_( max_profile ) ||
LOAD_( charmaps ) ||
LOAD_( names ) ||
LOAD_( psnames ) )
goto Exit;
if ( /* load the `hhea' & `hmtx' tables at once */
( ( error = sfnt->load_metrics( face, stream, 0 ) ) != TT_Err_Ok ) ||
/* try to load the `vhea' & `vmtx' at once if present */
( ( error = sfnt->load_metrics( face, stream, 1 ) ) != TT_Err_Ok ) ||
LOAD_( os2 ) )
/* do not load the metrics headers and tables if this is an Apple */
/* sbit font file.. */
if ( !is_apple_sbit )
{
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
missing_outline = 1;
#else
goto Exit;
#endif
/* load the "hhea" and "hmtx" tables at once */
error = sfnt->load_metrics( face, stream, 0 );
if (error)
goto Exit;
/* try to load the "vhea" and "vmtx" tables at once */
error = sfnt->load_metrics( face, stream, 1 );
if (error)
goto Exit;
if ( LOAD_(os2) )
goto Exit;
}
/* the optional tables */
......@@ -307,11 +333,12 @@
/* embedded bitmap support. */
if ( sfnt->load_sbits && LOAD_( sbits ) )
{
if ( !( ( error == TT_Err_Table_Missing ) && /* missing SBit */
( missing_outline == 0 ) ) ) /* find outline */
/* return an error if this font file has no outlines */
if ( error == TT_Err_Table_Missing && has_outline )
error = 0;
else
goto Exit;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
if ( LOAD_( hdmx ) ||
......@@ -343,7 +370,7 @@
/* */
/* Compute face flags. */
/* */
if ( missing_outline == 0 )
if ( has_outline == TRUE )
flags = FT_FACE_FLAG_SCALABLE; /* scalable outlines */
flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */
......@@ -374,26 +401,23 @@
/* Compute style flags. */
/* */
flags = 0;
if ( missing_outline == 0 )
if ( has_outline == TRUE && face->os2.version != 0xFFFF )
{
if ( face->os2.version != 0xFFFF )
{
/* we have an OS/2 table; use the `fsSelection' field */
if ( face->os2.fsSelection & 1 )
flags |= FT_STYLE_FLAG_ITALIC;
/* we have an OS/2 table; use the `fsSelection' field */
if ( face->os2.fsSelection & 1 )
flags |= FT_STYLE_FLAG_ITALIC;
if ( face->os2.fsSelection & 32 )
flags |= FT_STYLE_FLAG_BOLD;
}
else
{
/* this is an old Mac font, use the header field */
if ( face->header.Mac_Style & 1 )
flags |= FT_STYLE_FLAG_BOLD;
if ( face->os2.fsSelection & 32 )
flags |= FT_STYLE_FLAG_BOLD;
}
else
{
/* this is an old Mac font, use the header field */
if ( face->header.Mac_Style & 1 )
flags |= FT_STYLE_FLAG_BOLD;
if ( face->header.Mac_Style & 2 )
flags |= FT_STYLE_FLAG_ITALIC;
}
if ( face->header.Mac_Style & 2 )
flags |= FT_STYLE_FLAG_ITALIC;
}
root->style_flags = flags;
......@@ -437,24 +461,27 @@
if ( face->num_sbit_strikes )
{
root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
#if 0
/* I don't know criteria whether layout is horizontal or vertical */
if ( missing_outline )
if ( has_outline.... )
{
...
root->face_flags |= FT_FACE_FLAG_VERTICAL;
}
#endif
root->num_fixed_sizes = face->num_sbit_strikes;
if ( ALLOC_ARRAY( root->available_sizes,
face->num_sbit_strikes,
FT_Bitmap_Size ) )
return error;
goto Exit;
for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
{
root->available_sizes[n].width =
face->sbit_strikes[n].x_ppem;
root->available_sizes[n].height =
face->sbit_strikes[n].y_ppem;
}
......@@ -464,15 +491,15 @@
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
{
root->num_fixed_sizes = 0;
root->available_sizes = 0;
root->num_fixed_sizes = 0;
root->available_sizes = 0;
}
/*********************************************************************/
/* */
/* Set up metrics. */
/* */
if ( missing_outline == 0 )
if ( has_outline == TRUE )
{
/* XXX What about if outline header is missing */
/* (e.g. sfnt wrapped outline)? */
......
......@@ -458,9 +458,10 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF
FT_Error TT_Load_Header( TT_Face face,
FT_Stream stream )
static
FT_Error TT_Load_Generic_Header( TT_Face face,
FT_Stream stream,
FT_ULong tag )
{
FT_Error error;
TT_Header* header;
......@@ -496,7 +497,7 @@
FT_TRACE2(( "Load_TT_Header: %08p\n", face ));
error = face->goto_table( face, TTAG_head, stream, 0 );
error = face->goto_table( face, tag, stream, 0 );
if ( error )
{
FT_TRACE0(( "Font Header is missing!\n" ));
......@@ -516,6 +517,21 @@
return error;
}
FT_LOCAL_DEF
FT_Error TT_Load_Header( TT_Face face,
FT_Stream stream )
{
return TT_Load_Generic_Header( face, stream, TTAG_head );
}
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
FT_LOCAL_DEF
FT_Error TT_Load_Bitmap_Header( TT_Face face,
FT_Stream stream )
{
return TT_Load_Generic_Header( face, stream, TTAG_bhed );
}
#endif
/*************************************************************************/
/* */
......
......@@ -120,6 +120,11 @@
FT_Error TT_Load_Gasp( TT_Face face,
FT_Stream stream );
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
FT_LOCAL
FT_Error TT_Load_Bitmap_Header( TT_Face face,
FT_Stream stream );
#endif
#ifdef __cplusplus
}
......
......@@ -627,6 +627,32 @@
face->num_sbit_strikes = 0;
}
FT_LOCAL_DEF
FT_Error TT_Set_SBit_Strike( TT_Face face,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong* astrike_index )
{
FT_Int i;
if ( x_ppem < 0 || x_ppem > 255 ||
y_ppem < 1 || y_ppem > 255 )
return TT_Err_Invalid_PPem;
for ( i = 0; i < face->num_sbit_strikes; i++ )
{
if ( ( face->sbit_strikes[i].y_ppem == y_ppem ) &&
( ( x_ppem == 0 ) ||
( face->sbit_strikes[i].x_ppem == x_ppem )))
{
*astrike_index = i;
return TT_Err_Ok;
}
}
return TT_Err_Invalid_PPem;
}
/*************************************************************************/
/* */
......@@ -736,13 +762,12 @@
/* */
/* <Description> */
/* Checks whether an embedded bitmap (an `sbit') exists for a given */
/* glyph, at given x and y ppems. */
/* glyph, at a given strike. */
/* */
/* <Input> */
/* face :: The target face object. */
/* glyph_index :: The glyph index. */
/* x_ppem :: The horizontal resolution in points per EM. */
/* y_ppem :: The vertical resolution in points per EM. */
/* strike_index :: The current strike index. */
/* */
/* <Output> */
/* arange :: The SBit range containing the glyph index. */
......@@ -756,37 +781,27 @@
static
FT_Error Find_SBit_Image( TT_Face face,
FT_UInt glyph_index,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong strike_index,
TT_SBit_Range** arange,
TT_SBit_Strike** astrike,
FT_ULong* aglyph_offset )
{
TT_SBit_Strike* strike = face->sbit_strikes;
TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes;
FT_Error error;
TT_SBit_Strike* strike;
if ( !strike )
if ( !face->sbit_strikes || ( face->num_sbit_strikes <= (FT_Int)strike_index ) )
goto Fail;
for ( ; strike < strike_limit; strike++ )
{
if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem )
{
FT_Error error;
strike = &face->sbit_strikes[strike_index];
error = Find_SBit_Range( glyph_index, strike,
arange, aglyph_offset );
if ( error )
goto Fail;
error = Find_SBit_Range( glyph_index, strike,
arange, aglyph_offset );
if ( error )
goto Fail;
*astrike = strike;
*astrike = strike;
return TT_Err_Ok;
}
}
return TT_Err_Ok;
Fail:
/* no embedded bitmap for this glyph in face */
......@@ -1353,9 +1368,7 @@
/* <Input> */
/* face :: The target face object. */
/* */
/* x_ppem :: The horizontal resolution in points per EM. */
/* */
/* y_ppem :: The vertical resolution in points per EM. */
/* strike_index :: The current strike index. */
/* */
/* glyph_index :: The current glyph index. */
/* */
......@@ -1378,8 +1391,7 @@
/* */
FT_LOCAL_DEF
FT_Error TT_Load_SBit_Image( TT_Face face,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong strike_index,
FT_UInt glyph_index,
FT_UInt load_flags,
FT_Stream stream,
......@@ -1395,7 +1407,7 @@
/* Check whether there is a glyph sbit for the current index */
error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem,
error = Find_SBit_Image( face, glyph_index, strike_index,
&range, &strike, &glyph_offset );
if ( error )
goto Exit;
......
......@@ -41,17 +41,24 @@
FT_Stream stream );
FT_LOCAL
void TT_Free_SBit_Strikes( TT_Face face );
void TT_Free_SBit_Strikes( TT_Face face );
FT_LOCAL
FT_Error TT_Set_SBit_Strike( TT_Face face,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong *astrike_index );
FT_LOCAL
FT_Error TT_Load_SBit_Image( TT_Face face,
FT_Int x_ppem,
FT_Int y_ppem,
FT_ULong strike_index,
FT_UInt glyph_index,
FT_UInt load_flags,
FT_Stream stream,
FT_Bitmap* map,
TT_SBit_Metrics* metrics );
FT_Bitmap *map,
TT_SBit_Metrics *metrics );
#ifdef __cplusplus
......
......@@ -225,6 +225,7 @@
}
size->ttmetrics.valid = FALSE;
size->strike_index = 0xFFFF;
return TT_Reset_Size( size );
}
......@@ -261,6 +262,7 @@
/* many things have been pre-computed by the base layer */
size->ttmetrics.valid = FALSE;
size->strike_index = 0xFFFF;
return TT_Reset_Size( size );
}
......
......@@ -1345,18 +1345,24 @@
glyph->num_subglyphs = 0;
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* try to load embedded bitmap if any */
/*
* try to load embedded bitmap if any
*
* XXX: The convention should be emphasized in
* the documents. Because some application
* developpers confuse.
*/
if ( size &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
sfnt->load_sbits )
size->strike_index != 0xFFFF &&
sfnt->load_sbits &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
{
TT_SBit_Metrics metrics;
error = sfnt->load_sbit_image( face,
size->root.metrics.x_ppem,
size->root.metrics.y_ppem,
size->strike_index,
glyph_index,
load_flags,
stream,
......
......@@ -453,7 +453,7 @@
size->ttmetrics.valid = FALSE;
return error;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#if defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER) || defined(TT_CONFIG_OPTION_EMBEDDED_BITMAPS)
Fail_Exec:
if ( !size->debug )
......@@ -535,8 +535,8 @@
/* <Input> */
/* size :: A handle to the target size object. */
/* */
FT_LOCAL
FT_Error TT_Reset_Size( TT_Size size )
static
FT_Error Reset_Outline_Size( TT_Size size )
{
TT_Face face;
FT_Error error = TT_Err_Ok;
......@@ -575,46 +575,6 @@
}
/* Compute root ascender, descender, test height, and max_advance */
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
if ( ( !( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) &&
( face->root.face_flags & FT_FACE_FLAG_FIXED_SIZES ) ) )
{
FT_Int i;
for ( i = 0; i < face->root.num_fixed_sizes; i++ )
{
if ( ( face->sbit_strikes[i].x_ppem == metrics->x_ppem ) &&
( face->sbit_strikes[i].y_ppem == metrics->y_ppem ) )
{
/*
* XXX: We now set horizontal metrics,
* but this is not valid if we use vertical layout style
*/
metrics->ascender =