freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] wl/freetype-ot-svg-from-scratch-new f529372a6 2/5: [truetype


From: Werner Lemberg
Subject: [freetype2] wl/freetype-ot-svg-from-scratch-new f529372a6 2/5: [truetype, cff] Add code to load SVG document.
Date: Wed, 19 Jan 2022 08:56:02 -0500 (EST)

branch: wl/freetype-ot-svg-from-scratch-new
commit f529372a6aa19ff6c4ef435f8617ad14025077aa
Author: Moazin Khatti <moazinkhatri@gmail.com>
Commit: Werner Lemberg <wl@gnu.org>

    [truetype, cff] Add code to load SVG document.
    
    * src/cff/cffgload.c (cff_slot_load): Add code to load SVG doc.
    * src/truetype/ttgload.c (TT_Load_Glyph): Add code to load SVG doc.
---
 src/cff/cffgload.c     | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/truetype/ttgload.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 97e8f9c1c..4d58c358b 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -346,6 +346,76 @@
     if ( load_flags & FT_LOAD_SBITS_ONLY )
       return FT_THROW( Invalid_Argument );
 
+#ifdef FT_CONFIG_OPTION_SVG
+    /* check for OT-SVG */
+    if ( ( load_flags & FT_LOAD_COLOR )     &&
+         ( (TT_Face)glyph->root.face )->svg )
+    {
+      /*
+       * We load the SVG document and try to grab the advances from the
+       * table.  For the bearings we rely on the presetting hook to do that.
+       */
+
+      FT_Short      dummy;
+      FT_UShort     advanceX;
+      FT_UShort     advanceY;
+      SFNT_Service  sfnt;
+
+
+      if ( size->root.metrics.x_ppem < 1 ||
+           size->root.metrics.y_ppem < 1 )
+      {
+        error = FT_THROW( Invalid_Size_Handle );
+        return error;
+      }
+
+      FT_TRACE3(( "Trying to load SVG glyph\n" ));
+
+      sfnt  = (SFNT_Service)((TT_Face)glyph->root.face)->sfnt;
+      error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
+      if ( !error )
+      {
+        FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
+
+        glyph->root.format = FT_GLYPH_FORMAT_SVG;
+
+        /*
+         * If the horizontal or vertical advances are not present in the
+         * table, this a problem with the font since the standard requires
+         * that they have it.  However, we are graceful and calculate the
+         * values by ourselves for the vertical case.
+         */
+        sfnt->get_metrics( face,
+                           FALSE,
+                           glyph_index,
+                           &dummy,
+                           &advanceX );
+        sfnt->get_metrics( face,
+                           TRUE,
+                           glyph_index,
+                           &dummy,
+                           &advanceY );
+
+        advanceX =
+          (FT_UShort)FT_MulDiv( advanceX,
+                                glyph->root.face->size->metrics.x_ppem,
+                                glyph->root.face->units_per_EM );
+        advanceY =
+          (FT_UShort)FT_MulDiv( advanceY,
+                                glyph->root.face->size->metrics.y_ppem,
+                                glyph->root.face->units_per_EM );
+
+        glyph->root.metrics.horiAdvance = advanceX << 6;
+        glyph->root.metrics.vertAdvance = advanceY << 6;
+
+        return error;
+      }
+
+      FT_TRACE3(( "Failed to load SVG glyph\n" ));
+    }
+
+#endif /* FT_CONFIG_OPTION_SVG */
+
     /* if we have a CID subfont, use its matrix (which has already */
     /* been multiplied with the root matrix)                       */
 
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 796811b39..6dbee7b7f 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2919,6 +2919,12 @@
       }
     }
 
+    if ( load_flags & FT_LOAD_SBITS_ONLY )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
     /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
@@ -2928,12 +2934,68 @@
       goto Exit;
     }
 
-    if ( load_flags & FT_LOAD_SBITS_ONLY )
+#ifdef FT_CONFIG_OPTION_SVG
+
+    /* check for OT-SVG */
+    if ( ( load_flags & FT_LOAD_COLOR ) && ( (TT_Face)glyph->face )->svg )
+    {
+      SFNT_Service  sfnt;
+
+      FT_Short   leftBearing;
+      FT_Short   topBearing;
+      FT_UShort  advanceX;
+      FT_UShort  advanceY;
+
+
+      FT_TRACE3(( "Trying to load SVG glyph\n" ));
+      sfnt = (SFNT_Service)( (TT_Face)glyph->face )->sfnt;
+
+      error = sfnt->load_svg_doc( glyph, glyph_index );
+      if ( !error )
+      {
+        TT_Face  face = (TT_Face)glyph->face;
+
+
+        FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
+
+        glyph->format = FT_GLYPH_FORMAT_SVG;
+
+        sfnt->get_metrics( face,
+                           FALSE,
+                           glyph_index,
+                           &leftBearing,
+                           &advanceX );
+        sfnt->get_metrics( face,
+                           TRUE,
+                           glyph_index,
+                           &topBearing,
+                           &advanceY );
+
+        advanceX = (FT_UShort)FT_MulDiv( advanceX,
+                                         glyph->face->size->metrics.x_ppem,
+                                         glyph->face->units_per_EM );
+        advanceY = (FT_UShort)FT_MulDiv( advanceY,
+                                         glyph->face->size->metrics.y_ppem,
+                                         glyph->face->units_per_EM );
+
+        glyph->metrics.horiAdvance = advanceX << 6;
+        glyph->metrics.vertAdvance = advanceY << 6;
+
+        return error;
+      }
+
+      FT_TRACE3(( "Failed to load SVG glyph\n" ));
+    }
+
+    /* return immediately if we only want SVG glyphs */
+    if ( load_flags & FT_LOAD_SVG_ONLY )
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
 
+#endif /* FT_CONFIG_OPTION_SVG */
+
     error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
     if ( error )
       goto Exit;



reply via email to

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