[sfnt] Support `face->num_faces' for WOFF2 fonts.

Set correct value of `face->num_faces' for WOFF2 fonts. This is being
handled separately because we only load the tables for the requested
font face in `woff2_open_font' and create a single-face sfnt stream.

The full discussion is at:

  https://lists.gnu.org/archive/html/freetype-devel/2019-08/msg00000.html

* src/sfnt/sfobjs.c (sfnt_open_font): Add parameter `woff2_num_faces'.
(sfnt_init_face): Introduce var `woff2_num_faces', and change
`face->root.num_faces' if `woff2_num_faces' is set.

* src/sfnt/sfwoff2.c (woff2_open_font): Validate requested face index
and handle negative face indices.

* src/sfnt/sfwoff2.h (woff2_open_font): Add parameter `num_faces' to
declaration.
This commit is contained in:
Nikhil Ramakrishnan 2019-08-05 01:53:00 +05:30
parent af7d2967d5
commit b25c352ed4
3 changed files with 46 additions and 11 deletions

View File

@ -343,7 +343,8 @@
static FT_Error
sfnt_open_font( FT_Stream stream,
TT_Face face,
FT_Int* face_instance_index )
FT_Int* face_instance_index,
FT_Long* woff2_num_faces )
{
FT_Memory memory = stream->memory;
FT_Error error;
@ -394,7 +395,10 @@
if ( FT_STREAM_SEEK( offset ) )
return error;
error = woff2_open_font( stream, face, face_instance_index );
error = woff2_open_font( stream,
face,
face_instance_index,
woff2_num_faces );
if ( error )
return error;
@ -479,9 +483,10 @@
FT_Parameter* params )
{
FT_Error error;
FT_Library library = face->root.driver->root.library;
FT_Library library = face->root.driver->root.library;
SFNT_Service sfnt;
FT_Int face_index;
FT_Long woff2_num_faces = 0;
/* for now, parameters are unused */
@ -532,7 +537,10 @@
FT_TRACE2(( "SFNT driver\n" ));
error = sfnt_open_font( stream, face, &face_instance_index );
error = sfnt_open_font( stream,
face,
&face_instance_index,
&woff2_num_faces );
if ( error )
return error;
@ -707,6 +715,10 @@
face->root.num_faces = face->ttc_header.count;
face->root.face_index = face_instance_index;
/* `num_faces' for a WOFF2 needs to be handled separately. */
if( woff2_num_faces )
face->root.num_faces = woff2_num_faces;
return error;
}

View File

@ -1535,11 +1535,12 @@
FT_LOCAL_DEF( FT_Error )
woff2_open_font( FT_Stream stream,
TT_Face face,
FT_Int* face_instance_index )
FT_Int* face_instance_index,
FT_Long* num_faces )
{
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
FT_Int face_index = *face_instance_index;
FT_Int face_index;
WOFF2_HeaderRec woff2;
WOFF2_InfoRec info;
@ -1594,6 +1595,7 @@
FT_ASSERT( stream == face->root.stream );
FT_ASSERT( FT_STREAM_POS() == 0 );
face_index = FT_ABS( *face_instance_index ) & 0xFFFF;
/* DEBUG - Remove later. */
FT_TRACE2(( "Face index = %ld\n", face_index ));
@ -1734,6 +1736,7 @@
FT_TRACE2(( "Table directory successfully parsed.\n" ));
/* Check for and read collection directory. */
woff2.num_fonts = 1;
woff2.header_version = 0;
if( woff2.flavor == TTAG_ttcf ){
FT_TRACE2(( "Font is a TTC, reading collection directory.\n" ));
@ -1848,12 +1851,28 @@
goto Exit;
}
/* Validate requested face index. */
*num_faces = woff2.num_fonts;
/* value -(N+1) requests information on index N */
if ( *face_instance_index < 0 )
face_index--;
if( face_index >= woff2.num_fonts )
{
if ( *face_instance_index >= 0 )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
}
else
face_index = 0;
}
/* Only retain tables of the requested face in a TTC. */
/* TODO Check whether it is OK for rest of the code to be unaware of the
fact that we're working with a TTC. */
if( woff2.header_version )
{
WOFF2_TtcFont ttc_font = woff2.ttc_fonts + face_index;
/* Create a temporary array. */
if( FT_NEW_ARRAY( temp_indices,
ttc_font->num_tables ) )
@ -1989,8 +2008,11 @@
face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
/* Set face_index to 0. */
*face_instance_index = 0;
/* Set face_index. */
if( *face_instance_index < 0 )
*face_instance_index = -1;
else
*face_instance_index = 0;
/* error = FT_THROW( Unimplemented_Feature ); */
/* DEBUG - Remove later */

View File

@ -64,7 +64,8 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
woff2_open_font( FT_Stream stream,
TT_Face face,
FT_Int* face_index );
FT_Int* face_index,
FT_Long* num_faces );
FT_END_HEADER