Commit 1df35d94c79dea3f981bd2907dd979973c8199dc

John Tytgat 2017-10-04T22:46:36

[cff] Add support for `FSType'. * include/freetype/internal/cfftypes.h (CFF_FontRec): Add `font_extra' entry. * src/cff/cffdrivr.c (cff_ps_get_font_extra): New function to retrieve FSType info from the embedded PostScript data. (cff_service_ps_info): Register function. * src/cff/cffload.c (cff_font_done): Free `font_extra'.

diff --git a/ChangeLog b/ChangeLog
index dac2e7d..b30c3b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2017-10-04  John Tytgat  <John.Tytgat@esko.com>
+
+	[cff] Add support for `FSType'.
+
+	* include/freetype/internal/cfftypes.h (CFF_FontRec): Add
+	`font_extra' entry.
+
+	* src/cff/cffdrivr.c (cff_ps_get_font_extra): New function to
+	retrieve FSType info from the embedded PostScript data.
+	(cff_service_ps_info): Register function.
+
+	* src/cff/cffload.c (cff_font_done): Free `font_extra'.
+
 2017-09-30  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	Signedness fixes in bitmap presetting.
diff --git a/include/freetype/internal/cfftypes.h b/include/freetype/internal/cfftypes.h
index d6de1f3..0b9dbdf 100644
--- a/include/freetype/internal/cfftypes.h
+++ b/include/freetype/internal/cfftypes.h
@@ -27,6 +27,7 @@
 #include FT_INTERNAL_SERVICE_H
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
+#include FT_INTERNAL_TYPE1_TYPES_H
 
 
 FT_BEGIN_HEADER
@@ -397,6 +398,9 @@ FT_BEGIN_HEADER
     /* since version 2.7.1 */
     CFF_VStoreRec    vstore;        /* parsed vstore structure */
 
+    /* since version 2.8.2 */
+    PS_FontExtraRec*  font_extra;
+
   } CFF_FontRec;
 
 
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 340de9c..e761409 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -496,11 +496,91 @@
   }
 
 
+  static FT_Error
+  cff_ps_get_font_extra( CFF_Face          face,
+                         PS_FontExtraRec*  afont_extra )
+  {
+    CFF_Font  cff   = (CFF_Font)face->extra.data;
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( cff && cff->font_extra == NULL )
+    {
+      CFF_FontRecDict   dict       = &cff->top_font.font_dict;
+      PS_FontExtraRec*  font_extra = NULL;
+      FT_Memory         memory     = face->root.memory;
+      FT_String*        embedded_postscript;
+
+
+      if ( FT_ALLOC( font_extra, sizeof ( *font_extra ) ) )
+        goto Fail;
+
+      font_extra->fs_type = 0u;
+
+      embedded_postscript = cff_index_get_sid_string(
+                              cff,
+                              dict->embedded_postscript );
+      if ( embedded_postscript )
+      {
+        FT_String*  start_fstype;
+        FT_String*  start_def;
+
+
+        /* Identify the XYZ integer in `/FSType XYZ def' substring. */
+        if ( ( start_fstype = ft_strstr( embedded_postscript,
+                                         "/FSType" ) ) != NULL    &&
+             ( start_def = ft_strstr( start_fstype +
+                                        sizeof ( "/FSType" ) - 1,
+                                      "def" ) ) != NULL           )
+        {
+          FT_String*  s;
+
+
+          for ( s = start_fstype + sizeof ( "/FSType" ) - 1;
+                s != start_def;
+                s++ )
+          {
+            if ( *s >= '0' && *s <= '9' )
+            {
+              FT_UShort  prev_fs_type;
+
+
+              prev_fs_type        = font_extra->fs_type;
+              font_extra->fs_type = 10 * font_extra->fs_type + *s - '0';
+              if ( font_extra->fs_type < prev_fs_type )
+              {
+                /* Overflow - ignore the FSType value.  */
+                font_extra->fs_type = 0U;
+                break;
+              }
+            }
+            else if ( *s != ' ' && *s != '\n' && *s != '\r' )
+            {
+              /* Non-whitespace character between `/FSType' and next `def' */
+              /* - ignore the FSType value.                                */
+              font_extra->fs_type = 0U;
+              break;
+            }
+          }
+        }
+      }
+
+      cff->font_extra = font_extra;
+    }
+
+    if ( cff )
+      *afont_extra = *cff->font_extra;
+
+  Fail:
+    return error;
+  }
+
+
   FT_DEFINE_SERVICE_PSINFOREC(
     cff_service_ps_info,
 
     (PS_GetFontInfoFunc)   cff_ps_get_font_info,    /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  NULL,                    /* ps_get_font_extra   */
+    (PS_GetFontExtraFunc)  cff_ps_get_font_extra,   /* ps_get_font_extra   */
     (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,  /* ps_has_glyph_names  */
     /* unsupported with CFF fonts */
     (PS_GetFontPrivateFunc)NULL,                    /* ps_get_font_private */
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 0875ead..0f0c839 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -2539,6 +2539,8 @@
       font->cf2_instance.finalizer( font->cf2_instance.data );
       FT_FREE( font->cf2_instance.data );
     }
+
+    FT_FREE( font->font_extra );
   }