ref: 5367e0ca016bc79096cb3b57217fc1326dc3b997
parent: bb7668d7c30e16ef1d6442c4aa2b694fadd15295
author: Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>
date: Sun Aug 4 21:53:00 EDT 2019
[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 variable `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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
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
+ 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 variable `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.
+
+2019-08-27 Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>
+
[woff2] Improve memory and error handling.
Free up memory after use, and improve error handling.
--- 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;
@@ -706,6 +714,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;
}
--- 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 */
--- a/src/sfnt/sfwoff2.h
+++ b/src/sfnt/sfwoff2.h
@@ -64,7 +64,8 @@
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