ref: 9a2b3b6d55f0266550770f95626de677c00e7282
parent: 35222ff7bb7000298af514e7693af5f1ff1c8417
author: Wu, Chia-I (吳佳一) <[email protected]>
date: Tue Feb 14 03:37:03 EST 2006
* src/sfnt/ttmtx.c (tt_face_load_hhea, tt_face_load_hmtx): Simply return error if table is missing. Check table length in non-FT_OPTIMIZE_MEMORY'ed `tt_face_load_hmtx'. * src/sfnt/sfobjs.c (sfnt_load_face): Take care of missing metrics tables. The last change makes Mac bitmap-only font not load and this fixes it. * src/truetype/ttgload.c (load_truetype_glyph): Fix compilation error when FT_CONFIG_OPTION_INCREMENTAL is defined.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2006-02-14 Chia-I Wu <[email protected]>
+
+ * src/sfnt/ttmtx.c (tt_face_load_hhea, tt_face_load_hmtx): Simply
+ return error if table is missing.
+ Check table length in non-FT_OPTIMIZE_MEMORY'ed `tt_face_load_hmtx'.
+
+ * src/sfnt/sfobjs.c (sfnt_load_face): Take care of missing metrics
+ tables. The last change makes Mac bitmap-only font not load and this
+ fixes it.
+
+ * src/truetype/ttgload.c (load_truetype_glyph): Fix compilation error
+ when FT_CONFIG_OPTION_INCREMENTAL is defined.
+
2006-02-13 Chia-I Wu <[email protected]>
Clean up the SFNT_Interface. In this final pass, `load_hmtx' is
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -560,16 +560,54 @@
/* sbit font file */
if ( !is_apple_sbit )
{
- /* load the `hhea' and `hmtx' tables at once */
- error = sfnt->load_hhea( face, stream, 0 ) ||
- sfnt->load_hmtx( face, stream, 0 );
+ /* load the `hhea' and `hmtx' tables */
+ error = sfnt->load_hhea( face, stream, 0 );
+ if ( !error )
+ {
+ error = sfnt->load_hmtx( face, stream, 0 );
+
+ if ( error == SFNT_Err_Table_Missing )
+ {
+ error = SFNT_Err_Hmtx_Table_Missing;
+
+#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;
+ }
+#endif
+ }
+ }
+ else if ( error == SFNT_Err_Table_Missing )
+ {
+ /* No `hhea' table necessary for SFNT Mac fonts. */
+ if ( face->format_tag == TTAG_true )
+ {
+ FT_TRACE2(( "This is an SFNT Mac font.\n"));
+ error = SFNT_Err_Ok;
+ }
+ else
+ error = SFNT_Err_Horiz_Header_Missing;
+ }
+
if ( error )
goto Exit;
- /* try to load the `vhea' and `vmtx' tables at once */
- error = sfnt->load_hhea( face, stream, 1 ) ||
- sfnt->load_hmtx( face, stream, 1 );
- if ( error )
+ /* try to load the `vhea' and `vmtx' tables */
+ error = sfnt->load_hhea( face, stream, 1 );
+ if ( !error )
+ {
+ error = sfnt->load_hmtx( face, stream, 1 );
+ if ( !error )
+ face->vertical_info = 1;
+ }
+
+ if ( error && error != SFNT_Err_Table_Missing )
goto Exit;
if ( LOAD_( os2 ) )
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -66,65 +66,40 @@
FT_ULong* ptable_size;
- FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical"
- : "Horizontal",
- face ));
+ FT_TRACE2(( "%cmtx ", vertical ? 'v' : 'h' ));
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;
- }
+ goto Fail;
+
+ ptable = &face->vert_metrics;
+ ptable_size = &face->vert_metrics_size;
}
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
+ goto Fail;
- FT_ERROR(( " no horizontal metrics in file!\n" ));
- error = SFNT_Err_Hmtx_Table_Missing;
- goto Exit;
- }
+ ptable = &face->horz_metrics;
+ ptable_size = &face->horz_metrics_size;
}
if ( FT_FRAME_EXTRACT( table_size, *ptable ) )
- goto Exit;
+ goto Fail;
*ptable_size = table_size;
+
+ return SFNT_Err_Ok;
- Exit:
+ Fail:
+ if ( error == SFNT_Err_Table_Missing )
+ FT_TRACE2(( "missing\n" ));
+ else
+ FT_TRACE2(( "failed\n" ));
+
return error;
}
@@ -145,31 +120,26 @@
TT_ShortMetrics** shorts;
- FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical"
- : "Horizontal",
- face ));
+ FT_TRACE2(( "%cmtx ", vertical ? 'v' : 'h' ));
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;
+
+ goto Fail;
}
num_longs = face->vertical.number_Of_VMetrics;
+ if ( num_longs > table_len / 4 )
+ {
+ num_longs = table_len / 4;
+ face->vertical.number_Of_VMetrics = num_longs;
+ }
+
longs = (TT_LongMetrics *)&face->vertical.long_metrics;
shorts = (TT_ShortMetrics**)&face->vertical.short_metrics;
}
@@ -178,26 +148,18 @@
error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
if ( error )
{
+ face->horizontal.number_Of_HMetrics = 0;
-#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;
+ goto Fail;
}
num_longs = face->horizontal.number_Of_HMetrics;
+ if ( num_longs > table_len / 4 )
+ {
+ num_longs = table_len / 4;
+ face->horizontal.number_Of_HMetrics = num_longs;
+ }
+
longs = (TT_LongMetrics *)&face->horizontal.long_metrics;
shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics;
}
@@ -209,9 +171,8 @@
if ( num_shorts < 0 )
{
- FT_ERROR(( "TT_Load_%s_Metrics: more metrics than glyphs!\n",
- vertical ? "Vertical"
- : "Horizontal" ));
+ FT_ERROR(( "%cmtx: more metrics than glyphs!\n",
+ vertical ? 'v' : 'h' ));
/* Adobe simply ignores this problem. So we shall do the same. */
#if 0
@@ -225,10 +186,10 @@
if ( FT_QNEW_ARRAY( *longs, num_longs ) ||
FT_QNEW_ARRAY( *shorts, num_shorts ) )
- goto Exit;
+ goto Fail;
if ( FT_FRAME_ENTER( table_len ) )
- goto Exit;
+ goto Fail;
{
TT_LongMetrics cur = *longs;
@@ -270,7 +231,14 @@
FT_TRACE2(( "loaded\n" ));
- Exit:
+ return SFNT_Err_Ok;
+
+ Fail:
+ if ( error == SFNT_Err_Table_Missing )
+ FT_TRACE2(( "missing\n" ));
+ else
+ FT_TRACE2(( "failed\n" ));
+
return error;
}
@@ -330,48 +298,27 @@
};
- FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " ));
+ FT_TRACE2(( "%chea ", vertical ? 'v' : 'h' ));
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;
- }
+ goto Fail;
- 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;
+ goto Fail;
- /* 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;
+ goto Fail;
header->long_metrics = NULL;
header->short_metrics = NULL;
@@ -380,7 +327,12 @@
return SFNT_Err_Ok;
- Exit:
+ Fail:
+ if ( error == SFNT_Err_Table_Missing )
+ FT_TRACE2(( "missing\n" ));
+ else
+ FT_TRACE2(( "failed\n" ));
+
return error;
}
@@ -388,7 +340,7 @@
/*************************************************************************/
/* */
/* <Function> */
- /* tt_face_get_metrics */
+ /* tt_face_get_metrics */
/* */
/* <Description> */
/* Returns the horizontal or vertical metrics in font units for a */
@@ -490,7 +442,7 @@
FT_UShort k = header->number_Of_HMetrics;
- if ( k == 0 )
+ if ( k == 0 || k >= (FT_UInt)face->max_profile.numGlyphs )
{
*abearing = *aadvance = 0;
return SFNT_Err_Ok;
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1158,7 +1158,7 @@
glyph_data_loaded = 1;
offset = 0;
- byte_len = glyph_data.length;
+ loader->byte_len = glyph_data.length;
FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
FT_Stream_OpenMemory( &inc_stream,