freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] GSoC-2019-moazin 2bd80f2 05/18: Very crude way to handle SVG


From: Moazin Khatti
Subject: [freetype2] GSoC-2019-moazin 2bd80f2 05/18: Very crude way to handle SVG data with only TTF outlined OT fonts. Gonna revert soon.
Date: Sun, 23 Jun 2019 02:32:12 -0400 (EDT)

branch: GSoC-2019-moazin
commit 2bd80f205106a701301bbb0376ef6ac2caca2e10
Author: Moazin Khatti <address@hidden>
Commit: Moazin Khatti <address@hidden>

    Very crude way to handle SVG data with only TTF outlined OT fonts. Gonna 
revert soon.
---
 include/freetype/internal/sfnt.h    |  13 ++++-
 include/freetype/internal/tttypes.h |  30 +++++++++-
 src/sfnt/sfdriver.c                 |   5 +-
 src/sfnt/ttsvg.c                    | 111 +++++++++++++++++++++++++++++++++++-
 src/sfnt/ttsvg.h                    |   4 ++
 src/truetype/ttgload.c              |  76 ++++++++++++++----------
 src/truetype/ttobjs.h               |  15 -----
 7 files changed, 202 insertions(+), 52 deletions(-)

diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 94f5122..996cae8 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -312,6 +312,12 @@ FT_BEGIN_HEADER
                               TT_SBit_MetricsRec  *ametrics );
 
 
+  /* OT-SVG to be documented later */
+  typedef FT_Error
+  (*TT_Load_Svg_Doc_Func)( FT_GlyphSlot  glyph,
+                           FT_UInt       glyph_index );
+
+
   /**************************************************************************
    *
    * @functype:
@@ -781,6 +787,7 @@ FT_BEGIN_HEADER
     /* Open Type SVG Support */
     TT_Load_Table_Func           load_svg;
     TT_Free_Table_Func           free_svg;
+    TT_Load_Svg_Doc_Func         load_svg_doc;
   } SFNT_Interface;
 
 
@@ -829,7 +836,8 @@ FT_BEGIN_HEADER
           get_name_,                     \
           get_name_id_,                  \
           load_svg_,                     \
-          free_svg_    )                 \
+          free_svg_,                     \
+          load_svg_doc_ )                \
   static const SFNT_Interface  class_ =  \
   {                                      \
     goto_table_,                         \
@@ -871,7 +879,8 @@ FT_BEGIN_HEADER
     get_name_,                           \
     get_name_id_,                        \
     load_svg_,                           \
-    free_svg_                            \
+    free_svg_,                           \
+    load_svg_doc_                        \
   };
 
 
diff --git a/include/freetype/internal/tttypes.h 
b/include/freetype/internal/tttypes.h
index 42a921f..9ec8a1c 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -967,8 +967,8 @@ FT_BEGIN_HEADER
    * This structure/class is defined here because it is common to the
    * following formats: TTF, OpenType-TT, and OpenType-CFF.
    *
-   * Note, however, that the classes TT_Size and TT_GlyphSlot are not shared
-   * between font drivers, and are thus defined in `ttobjs.h`.
+   * Note, however, that the classes TT_Size and `TT_GlyphSlot'(not anymore),
+   * are not shared between font drivers, and are thus defined in `ttobjs.h`.
    *
    */
 
@@ -988,6 +988,32 @@ FT_BEGIN_HEADER
    */
   typedef struct TT_FaceRec_*  TT_Face;
 
+  /**************************************************************************
+   *
+   * @Type:
+   *   TT_GlyphSlotRec_
+   *
+   * @Description:
+   *   A glyph slot that inherits from FT_GlyphSlotRec_ but adds more fields
+   *
+   */
+  typedef struct TT_GlyphSlotRec_ 
+  {
+    FT_GlyphSlotRec   root;
+    FT_Byte*          svg_document;
+    FT_ULong          svg_document_length;
+  } TT_GlyphSlotRec;
+
+  /**************************************************************************
+   *
+   * @Type:
+   *   TT_GlyphSlot
+   *
+   * @Description:
+   *   A handle to a TrueType glyph slot object.
+   */
+  typedef struct TT_GlyphSlotRec_*  TT_GlyphSlot;
+
 
   /* a function type used for the truetype bytecode interpreter hooks */
   typedef FT_Error
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 11148b2..cff8ad6 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -1297,8 +1297,9 @@
 
     tt_face_get_name,       /* TT_Get_Name_Func        get_name        */
     sfnt_get_name_id,       /* TT_Get_Name_ID_Func     get_name_id     */
-    tt_face_load_svg,       /* TT_Load_Table_Func      load_svg       */
-    tt_face_free_svg        /* TT_Free_Table_Func      free_svg       */
+    tt_face_load_svg,       /* TT_Load_Table_Func      load_svg        */
+    tt_face_free_svg,       /* TT_Free_Table_Func      free_svg        */
+    tt_face_load_svg_doc
   )
 
 
diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
index 0ebe162..27e8296 100644
--- a/src/sfnt/ttsvg.c
+++ b/src/sfnt/ttsvg.c
@@ -1,6 +1,6 @@
 /****************************************************************************
  *
- * ttsvg.h
+ * ttsvg.c
  *
  *   OpenType SVG Color (specification).
  *
@@ -27,6 +27,7 @@
 #include <ft2build.h>
 #include FT_INTERNAL_STREAM_H
 #include FT_TRUETYPE_TAGS_H
+#include FT_GZIP_H
 
 
 #include "ttsvg.h"
@@ -113,3 +114,111 @@
       FT_FREE( svg );
     }   
   }
+
+  FT_Error
+  find_doc( FT_Byte*   stream,
+            FT_UShort  num_entries,
+            FT_UInt    glyph_index,
+            FT_ULong   *doc_offset,
+            FT_ULong   *doc_length  )
+  {
+    FT_Error   error;
+    FT_UShort  start_glyph_id;
+    FT_UShort  end_glyph_id;
+    FT_ULong   cur_doc_offset;
+    FT_ULong   cur_doc_length;
+
+    FT_Bool    found = FALSE;
+    FT_UInt    i     = 0;
+
+    /* For now it's linear search, later convert to binary search */
+    for ( i = 0; i < num_entries; i++)
+    {
+      start_glyph_id = FT_NEXT_USHORT( stream );
+      end_glyph_id   = FT_NEXT_USHORT( stream );
+      cur_doc_offset = FT_NEXT_ULONG( stream );
+      cur_doc_length = FT_NEXT_ULONG( stream );
+      
+      if ( ( glyph_index >= start_glyph_id) && 
+           ( glyph_index <= end_glyph_id  ) )
+      {
+        found = TRUE;
+        *doc_offset = cur_doc_offset;
+        *doc_length = cur_doc_length;
+        break;
+      }
+    }
+    if ( found != TRUE )
+      error = FT_THROW( Invalid_Glyph_Index );
+    else
+      error = FT_Err_Ok;
+    return error;
+  }
+
+  FT_LOCAL_DEF(FT_Error)
+  tt_face_load_svg_doc( FT_GlyphSlot  glyph_,
+                        FT_UInt       glyph_index )
+  {
+
+    TT_GlyphSlot glyph = (TT_GlyphSlot) glyph_;
+
+    /* TODO: properly clean stuff here on errors */
+
+    FT_Byte*   doc_list;             /* Pointer to the Svg Document List */ 
+    FT_UShort  num_entries;          /* Total no of entires in doc list  */
+
+    FT_ULong   doc_offset;
+    FT_ULong   doc_length;
+
+    FT_ULong   uncomp_size;
+    FT_Byte*   uncomp_buffer;
+
+    FT_Bool    is_gzip_encoded = FALSE;
+
+    FT_Error   error  = FT_Err_Ok;
+    TT_Face    face   = (TT_Face)glyph->root.face;   
+    FT_Memory  memory = face->root.memory;
+    Svg*       svg    = face->svg;
+
+    /* handle svg being 0x0 situation here */
+    doc_list     = svg->svg_doc_list;
+    num_entries  = FT_NEXT_USHORT( doc_list );
+    
+    error = find_doc( doc_list, num_entries, glyph_index, 
+                                &doc_offset, &doc_length );
+    if ( error != FT_Err_Ok )
+      return error;
+
+    doc_list = svg->svg_doc_list;   /* Reset to so we can use it again */
+    doc_list = (FT_Byte*)( doc_list + doc_offset );
+    
+    if( ( doc_list[0] == 0x1F ) && ( doc_list[1] == 0x8B )
+                                && ( doc_list[2] == 0x08 ) )
+    {
+      is_gzip_encoded = TRUE;
+      uncomp_size = (FT_ULong)doc_list[doc_length - 1] << 24 |
+                    (FT_ULong)doc_list[doc_length - 2] << 16 |
+                    (FT_ULong)doc_list[doc_length - 3] << 8  |
+                    (FT_ULong)doc_list[doc_length - 4];
+      
+      /* TODO: memory allocated here needs to be freed somewhere */
+      uncomp_buffer = (FT_Byte*) memory->alloc(memory, uncomp_size);
+      error = FT_Gzip_Uncompress( memory, uncomp_buffer, &uncomp_size,
+                                          doc_list,      doc_length  );
+      if ( error != FT_Err_Ok )
+      {
+        error = FT_THROW( Invalid_Table );
+        return error;
+      }
+
+      glyph->svg_document        = uncomp_buffer;
+      glyph->svg_document_length = uncomp_size;
+      return FT_Err_Ok;
+    } 
+
+    glyph->svg_document        = doc_list;
+    glyph->svg_document_length = doc_length;
+    return FT_Err_Ok;
+  }
+
+  
diff --git a/src/sfnt/ttsvg.h b/src/sfnt/ttsvg.h
index 1c6413b..186d4c8 100644
--- a/src/sfnt/ttsvg.h
+++ b/src/sfnt/ttsvg.h
@@ -29,6 +29,10 @@ FT_BEGIN_HEADER
   FT_LOCAL( void )
   tt_face_free_svg( TT_Face    face );
 
+  FT_LOCAL(FT_Error)
+  tt_face_load_svg_doc( FT_GlyphSlot  glyph,
+                        FT_UInt       glyph_index );
+
 FT_END_HEADER
 
 #endif /* __TTSVG_H__ */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index a046840..6b2bb69 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2204,7 +2204,8 @@
 
     FT_BBox       bbox;
     FT_Fixed      y_scale;
-    TT_GlyphSlot  glyph = loader->glyph;
+    TT_GlyphSlot  glyph_ = (TT_GlyphSlot)loader->glyph;
+    FT_GlyphSlot  glyph = (FT_GlyphSlot)glyph_;
     TT_Size       size  = loader->size;
 
 
@@ -2392,7 +2393,7 @@
     TT_SBit_MetricsRec  sbit_metrics;
 
 
-    face   = (TT_Face)glyph->face;
+    face   = (TT_Face)(glyph->root.face);
     sfnt   = (SFNT_Service)face->sfnt;
     stream = face->root.stream;
 
@@ -2401,35 +2402,35 @@
                                    glyph_index,
                                    (FT_UInt)load_flags,
                                    stream,
-                                   &glyph->bitmap,
+                                   &(glyph->root.bitmap),
                                    &sbit_metrics );
     if ( !error )
     {
-      glyph->outline.n_points   = 0;
-      glyph->outline.n_contours = 0;
+      (glyph->root).outline.n_points   = 0;
+      (glyph->root).outline.n_contours = 0;
 
-      glyph->metrics.width  = (FT_Pos)sbit_metrics.width  * 64;
-      glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64;
+      (glyph->root).metrics.width  = (FT_Pos)sbit_metrics.width  * 64;
+      (glyph->root).metrics.height = (FT_Pos)sbit_metrics.height * 64;
 
-      glyph->metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64;
-      glyph->metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64;
-      glyph->metrics.horiAdvance  = (FT_Pos)sbit_metrics.horiAdvance  * 64;
+      (glyph->root).metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 
64;
+      (glyph->root).metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 
64;
+      (glyph->root).metrics.horiAdvance  = (FT_Pos)sbit_metrics.horiAdvance  * 
64;
 
-      glyph->metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64;
-      glyph->metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64;
-      glyph->metrics.vertAdvance  = (FT_Pos)sbit_metrics.vertAdvance  * 64;
+      (glyph->root).metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 
64;
+      (glyph->root).metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 
64;
+      (glyph->root).metrics.vertAdvance  = (FT_Pos)sbit_metrics.vertAdvance  * 
64;
 
-      glyph->format = FT_GLYPH_FORMAT_BITMAP;
+      (glyph->root).format = FT_GLYPH_FORMAT_BITMAP;
 
       if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
       {
-        glyph->bitmap_left = sbit_metrics.vertBearingX;
-        glyph->bitmap_top  = sbit_metrics.vertBearingY;
+        (glyph->root).bitmap_left = sbit_metrics.vertBearingX;
+        (glyph->root).bitmap_top  = sbit_metrics.vertBearingY;
       }
       else
       {
-        glyph->bitmap_left = sbit_metrics.horiBearingX;
-        glyph->bitmap_top  = sbit_metrics.horiBearingY;
+        (glyph->root).bitmap_left = sbit_metrics.horiBearingX;
+        (glyph->root).bitmap_top  = sbit_metrics.horiBearingY;
       }
     }
 
@@ -2438,6 +2439,22 @@
 
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
+  static FT_Error
+  load_svg_glyph( TT_GlyphSlot glyph,
+                  FT_ULong     glyph_index ) 
+  {
+    FT_Error      error;
+    TT_Face       face;
+    SFNT_Service  sfnt;
+    FT_Byte*      doc_list;
+
+    face = (TT_Face)(glyph->root).face;
+    sfnt = (SFNT_Service)face->sfnt;
+    
+    error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
+    return error;
+  }
+
 
   static FT_Error
   tt_loader_init( TT_Loader     loader,
@@ -2454,12 +2471,12 @@
     FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
 #if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
     defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
+    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)(glyph->root).face 
);
 #endif
 #endif
 
 
-    face   = (TT_Face)glyph->face;
+    face   = (TT_Face)(glyph->root.face);
     stream = face->root.stream;
 
     FT_ZERO( loader );
@@ -2711,7 +2728,7 @@
     /* get face's glyph loader */
     if ( !glyf_table_only )
     {
-      FT_GlyphLoader  gloader = glyph->internal->loader;
+      FT_GlyphLoader  gloader = (glyph->root).internal->loader;
 
 
       FT_GlyphLoader_Rewind( gloader );
@@ -2775,13 +2792,13 @@
    */
   FT_LOCAL_DEF( FT_Error )
   TT_Load_Glyph( TT_Size       size,
-                 TT_GlyphSlot  glyph,
+                 TT_GlyphSlot  glyph_,
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
   {
     FT_Error      error;
     TT_LoaderRec  loader;
-
+    FT_GlyphSlot  glyph = (FT_GlyphSlot)glyph_;
 
     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
 
@@ -2796,7 +2813,7 @@
       FT_Fixed  y_scale = size->root.metrics.y_scale;
 
 
-      error = load_sbit_image( size, glyph, glyph_index, load_flags );
+      error = load_sbit_image( size, glyph_, glyph_index, load_flags );
       if ( FT_ERR_EQ( error, Missing_Bitmap ) )
       {
         /* the bitmap strike is incomplete and misses the requested glyph; */
@@ -2863,7 +2880,7 @@
         if ( FT_IS_SCALABLE( glyph->face ) )
         {
           /* for the bbox we need the header only */
-          (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
+          (void)tt_loader_init( &loader, size, glyph_, load_flags, TRUE );
           (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
           tt_loader_done( &loader );
           glyph->linearHoriAdvance = loader.linear;
@@ -2885,11 +2902,10 @@
 
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
-    /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
-    if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
+    /* OT-SVG part here */
+    if ( ( load_flags & FT_LOAD_COLOR ) && ( ((TT_Face)glyph->face)->svg ) )
     {
-      error = FT_THROW( Invalid_Size_Handle );
-      goto Exit;
+      error = load_svg_glyph( glyph_, glyph_index );
     }
 
     if ( load_flags & FT_LOAD_SBITS_ONLY )
@@ -2898,7 +2914,7 @@
       goto Exit;
     }
 
-    error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
+    error = tt_loader_init( &loader, size, glyph_, load_flags, FALSE );
     if ( error )
       goto Exit;
 
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 9fc654d..d131a9a 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -41,21 +41,6 @@ FT_BEGIN_HEADER
 
   /**************************************************************************
    *
-   * @Type:
-   *   TT_GlyphSlot
-   *
-   * @Description:
-   *   A handle to a TrueType glyph slot object.
-   *
-   * @Note:
-   *   This is a direct typedef of FT_GlyphSlot, as there is nothing
-   *   specific about the TrueType glyph slot.
-   */
-  typedef FT_GlyphSlot  TT_GlyphSlot;
-
-
-  /**************************************************************************
-   *
    * @Struct:
    *   TT_GraphicsState
    *



reply via email to

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