summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-08-05 01:53:00 +0530
committerNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-08-05 01:53:00 +0530
commitb25c352ed4719c4b81a23978a69e7762ba2ca037 (patch)
treee9744b75ffd17f661b142251f5a61ad2a00ebd41
parentaf7d2967d5165839915a84c19c327c0336e57b56 (diff)
downloadfreetype2-b25c352ed4719c4b81a23978a69e7762ba2ca037.tar.gz
[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.
-rw-r--r--src/sfnt/sfobjs.c20
-rw-r--r--src/sfnt/sfwoff2.c34
-rw-r--r--src/sfnt/sfwoff2.h3
3 files changed, 46 insertions, 11 deletions
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 7fe25ace7..f6da955ba 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -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;
}
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
index cda2b59a0..cbdaa8bf8 100644
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -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 */
diff --git a/src/sfnt/sfwoff2.h b/src/sfnt/sfwoff2.h
index b4f1ac594..b1d46ad0d 100644
--- a/src/sfnt/sfwoff2.h
+++ b/src/sfnt/sfwoff2.h
@@ -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