[woff2] Write SFNT Offset table.

* src/sfnt/sfwoff2.c (WRITE_USHORT, WRITE_ULONG): New macros.
(compare_tags): New function.
(woff2_open_font): Implement it.
This commit is contained in:
Nikhil Ramakrishnan 2019-06-24 01:07:18 +05:30 committed by Werner Lemberg
parent e09fe4cc79
commit 76c64f6ba1
2 changed files with 129 additions and 1 deletions

View File

@ -1,3 +1,11 @@
2019-08-27 Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>
[woff2] Write SFNT Offset table.
* src/sfnt/sfwoff2.c (WRITE_USHORT, WRITE_ULONG): New macros.
(compare_tags): New function.
(woff2_open_font): Implement it.
2019-08-27 Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>
* src/sfnt/sfwoff2.c: #undef macros.

View File

@ -34,9 +34,49 @@
#define READ_255USHORT( var ) Read255UShort( stream, &var )
#define READ_BASE128( var ) ReadBase128( stream, &var )
#define ROUND4( var ) ( var + 3 ) & ~3
#define WRITE_USHORT( p, v ) \
do \
{ \
*(p)++ = (FT_Byte)( (v) >> 8 ); \
*(p)++ = (FT_Byte)( (v) >> 0 ); \
\
} while ( 0 )
#define WRITE_ULONG( p, v ) \
do \
{ \
*(p)++ = (FT_Byte)( (v) >> 24 ); \
*(p)++ = (FT_Byte)( (v) >> 16 ); \
*(p)++ = (FT_Byte)( (v) >> 8 ); \
*(p)++ = (FT_Byte)( (v) >> 0 ); \
\
} while ( 0 )
FT_CALLBACK_DEF( int )
compare_tags( const void* a,
const void* b )
{
WOFF2_Table table1 = *(WOFF2_Table*)a;
WOFF2_Table table2 = *(WOFF2_Table*)b;
FT_ULong tag1 = table1->Tag;
FT_ULong tag2 = table2->Tag;
if ( tag1 > tag2 )
return 1;
else if ( tag1 < tag2 )
return -1;
else
return 0;
}
static FT_Error
Read255UShort( FT_Stream stream,
@ -183,6 +223,10 @@
FT_UInt64 first_table_offset;
FT_UInt64 file_offset;
FT_Byte* sfnt = NULL;
FT_Stream sfnt_stream = NULL;
FT_Byte* sfnt_header;
static const FT_Frame_Field woff2_header_fields[] =
{
#undef FT_STRUCTURE
@ -211,6 +255,9 @@
FT_ASSERT( stream == face->root.stream );
FT_ASSERT( FT_STREAM_POS() == 0 );
/* DEBUG - Remove later. */
FT_TRACE2(( "Face index = %ld\n", face->root.face_index ));
/* Read WOFF2 Header. */
if ( FT_STREAM_READ_FIELDS( woff2_header_fields, &woff2 ) )
return error;
@ -408,7 +455,7 @@
return FT_THROW( Invalid_Table );
/* DEBUG - Remove later */
else
FT_TRACE2(( "Glyf and loca are valid.\n" ));
FT_TRACE2(( "glyf and loca are valid.\n" ));
}
}
/* Collection directory reading complete. */
@ -444,11 +491,82 @@
if( file_offset != ( ROUND4( woff2.length ) ) )
return FT_THROW( Invalid_Table );
/* Redirect a TTC to exit for now. */
if( woff2.header_version )
{
FT_TRACE2(( "Reading TTC fonts not supported yet.\n" ));
error = FT_THROW( Unimplemented_Feature );
goto Exit;
}
/* Write sfnt header. */
if ( FT_ALLOC( sfnt, 12 + woff2.num_tables * 16UL ) ||
FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
{
FT_UInt searchRange, entrySelector, rangeShift, x;
/* DEBUG - Remove later */
FT_TRACE2(( "Writing SFNT offset table.\n" ));
x = woff2.num_tables;
entrySelector = 0;
while ( x )
{
x >>= 1;
entrySelector += 1;
}
entrySelector--;
searchRange = ( 1 << entrySelector ) * 16;
rangeShift = ( woff2.num_tables * 16 ) - searchRange;
WRITE_ULONG ( sfnt_header, woff2.flavor );
WRITE_USHORT( sfnt_header, woff2.num_tables );
WRITE_USHORT( sfnt_header, searchRange );
WRITE_USHORT( sfnt_header, entrySelector );
WRITE_USHORT( sfnt_header, rangeShift );
}
/* Sort tables by tag. */
ft_qsort( indices,
woff2.num_tables,
sizeof ( WOFF2_Table ),
compare_tags );
/* DEBUG - Remove later */
FT_TRACE2(( "Sorted table indices: \n" ));
for( nn = 0; nn < woff2.num_tables; ++nn )
{
WOFF2_Table table = indices[nn];
/* DEBUG - Remove later */
FT_TRACE2(( " Index %d", nn ));
FT_TRACE2(( " %c%c%c%c\n",
(FT_Char)( table->Tag >> 24 ),
(FT_Char)( table->Tag >> 16 ),
(FT_Char)( table->Tag >> 8 ),
(FT_Char)( table->Tag )));
}
error = FT_THROW( Unimplemented_Feature );
/* DEBUG - Remove later */
FT_TRACE2(( "Reached end without errors.\n" ));
goto Exit;
Exit:
FT_FREE( tables );
FT_FREE( indices );
if( error )
{
FT_FREE( sfnt );
FT_Stream_Close( sfnt_stream );
FT_FREE( sfnt_stream );
}
return error;
}
@ -456,6 +574,8 @@
#undef READ_255USHORT
#undef READ_BASE128
#undef ROUND4
#undef WRITE_USHORT
#undef WRITE_ULONG
/* END */