freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] GSoC-2019-nikhil b25c352: [sfnt] Support `face->num_faces' f


From: Nikhil Ramakrishnan
Subject: [freetype2] GSoC-2019-nikhil b25c352: [sfnt] Support `face->num_faces' for WOFF2 fonts.
Date: Sun, 4 Aug 2019 16:32:55 -0400 (EDT)

branch: GSoC-2019-nikhil
commit b25c352ed4719c4b81a23978a69e7762ba2ca037
Author: Nikhil Ramakrishnan <address@hidden>
Commit: Nikhil Ramakrishnan <address@hidden>

    [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.
---
 src/sfnt/sfobjs.c  | 20 ++++++++++++++++----
 src/sfnt/sfwoff2.c | 34 ++++++++++++++++++++++++++++------
 src/sfnt/sfwoff2.h |  3 ++-
 3 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 7fe25ac..f6da955 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 cda2b59..cbdaa8b 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 b4f1ac5..b1d46ad 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]