[woff2] Support `hmtx' reconstruction when `glyf' is untransformed. `reconstruct_hmtx' requires `info->x_mins' and `info->num_glyphs' to reconstruct the hmtx table. In case glyf is not transformed, we call `get_x_mins' which does the necessary work. * src/sfnt/sfwoff2.c (get_x_mins): New function. (reconstruct_font): Call get_x_mins.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
diff --git a/ChangeLog b/ChangeLog
index 1a3e190..771deea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2019-08-27 Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>
+ [woff2] Support `hmtx' reconstruction when `glyf' is untransformed.
+
+ `reconstruct_hmtx' requires `info->x_mins' and `info->num_glyphs' to
+ reconstruct the hmtx table. In case glyf is not transformed, we
+ call `get_x_mins' which does the necessary work.
+
+ * src/sfnt/sfwoff2.c (get_x_mins): New function.
+ (reconstruct_font): Call get_x_mins.
+
+2019-08-27 Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>
+
[sfnt] Support `face->num_faces' for WOFF2 fonts.
Set correct value of `face->num_faces' for WOFF2 fonts. This is
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
index cbdaa8b..d9268d9 100644
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -1170,7 +1170,92 @@
}
- /* XXX What if hmtx is transformed but glyf is not? */
+ /* Get `x_mins' for untransformed glyf table. */
+ static FT_Error
+ get_x_mins( FT_Stream stream,
+ WOFF2_Table* tables,
+ FT_UShort num_tables,
+ WOFF2_Info info,
+ FT_Memory memory )
+ {
+ FT_UShort num_glyphs;
+ FT_UShort index_format;
+ FT_ULong glyf_offset;
+ FT_UShort glyf_offset_short;
+ FT_ULong loca_offset;
+ FT_Int i;
+ FT_Error error = FT_Err_Ok;
+ FT_ULong offset_size;
+
+ const WOFF2_Table glyf_table = find_table( tables, num_tables,
+ TTAG_glyf );
+ const WOFF2_Table loca_table = find_table( tables, num_tables,
+ TTAG_loca );
+ const WOFF2_Table maxp_table = find_table( tables, num_tables,
+ TTAG_maxp );
+ const WOFF2_Table head_table = find_table( tables, num_tables,
+ TTAG_head );
+
+ /* Read `numGlyphs' from maxp table. */
+ if ( FT_STREAM_SEEK( maxp_table->src_offset ) && FT_STREAM_SKIP( 8 ) )
+ return error;
+
+ if( FT_READ_USHORT( num_glyphs ) )
+ return error;
+
+ info->num_glyphs = num_glyphs;
+
+ FT_TRACE2(( "num_glyphs = %d", num_glyphs ));
+
+ /* Read `indexToLocFormat' from head table. */
+ if( FT_STREAM_SEEK( head_table->src_offset ) && FT_STREAM_SKIP( 50 ) )
+ return error;
+
+ if( FT_READ_USHORT( index_format ) )
+ return error;
+
+ offset_size = index_format ? 4 : 2;
+
+ /* Create x_mins array. */
+ if( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
+ return error;
+
+ loca_offset = loca_table->src_offset;
+
+ for( i = 0; i < num_glyphs; ++i )
+ {
+ if( FT_STREAM_SEEK( loca_offset ) )
+ return error;
+
+ loca_offset += offset_size;
+
+ if( index_format )
+ {
+ if( FT_READ_ULONG( glyf_offset ) )
+ return error;
+ }
+ else
+ {
+ if( FT_READ_USHORT( glyf_offset_short ) )
+ return error;
+
+ glyf_offset = (FT_ULong)( glyf_offset_short );
+ glyf_offset = glyf_offset << 1;
+ }
+
+ glyf_offset += glyf_table->src_offset;
+
+ if( FT_STREAM_SEEK( glyf_offset ) && FT_STREAM_SKIP( 2 ) )
+ return error;
+
+ if( FT_READ_USHORT( info->x_mins[i] ) )
+ return error;
+ }
+
+ return error;
+ }
+
+
static FT_Error
reconstruct_hmtx( FT_Stream stream,
FT_ULong transformed_size,
@@ -1450,11 +1535,11 @@
}
else if( table.Tag == TTAG_hmtx )
{
+ /* If glyf is not transformed and hmtx is, handle separately. */
if( !is_glyf_xform )
{
- FT_ERROR(( "hmtx is transformed but glyf is not.\n" ));
- error = FT_THROW( Unimplemented_Feature );
- goto Fail;
+ if( get_x_mins(stream, indices, num_tables, info, memory) )
+ return FT_THROW( Invalid_Table );
}
table.dst_offset = dest_offset;
if( reconstruct_hmtx( stream, table.src_length, info->num_glyphs,