freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] GSoC-2019-moazin 864ea56 16/18: Adds support for SVG glyphs


From: Moazin Khatti
Subject: [freetype2] GSoC-2019-moazin 864ea56 16/18: Adds support for SVG glyphs to Glyph Management API.
Date: Sun, 23 Jun 2019 02:32:14 -0400 (EDT)

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

    Adds support for SVG glyphs to Glyph Management API.
---
 include/freetype/ftglyph.h |  46 +++++++++++++
 src/base/ftglyph.c         | 156 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 202 insertions(+)

diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index fedab84..004a234 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -225,6 +225,52 @@ FT_BEGIN_HEADER
 
   /**************************************************************************
    *
+   * @type:
+   *   FT_SvgGlyph
+   *
+   * @description:
+   *   A handle to an object used to model an SVG glyph image.  This is a
+   *   sub-class of @FT_Glyph, and a pointer to @FT_SvgGlyphRec.
+   */
+  typedef struct FT_SvgGlyphRec_*  FT_SvgGlyph;
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   FT_SvgGlyphRec
+   *
+   * @description:
+   *   A structure used for SVG glyph images.  This really is a 'sub-class'
+   *   of @FT_OutlineGlyphRec.
+   *
+   * @fields:
+   *   root ::
+   *     The root @FT_OutlineGlyphRec fields.
+   *
+   *   svg_document ::
+   *     A pointer to the SVG document.
+   *
+   *   svg_document_length ::
+   *     The length of the svg_document.
+   *
+   *   glyph_index ::
+   *     The index of the glyph to be rendered. I think it's necessary
+   *     because one document can contain multiple glyphs.
+   *
+   */
+  typedef struct  FT_SvgGlyphRec_
+  {
+    FT_OutlineGlyphRec  root;
+    FT_Byte*            svg_document;
+    FT_ULong            svg_document_length;
+    FT_UInt             glyph_index;
+    FT_Size_Metrics     metrics;
+    /* TODO: (OT-SVG) Maybe put a transformation matrix here */
+  } FT_SvgGlyphRec;
+
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_New_Glyph
    *
diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index e6b1327..19a170c 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -35,6 +35,7 @@
 #include FT_OUTLINE_H
 #include FT_BITMAP_H
 #include FT_INTERNAL_OBJECTS_H
+#include FT_SVG_RENDERER_H
 
 
   /**************************************************************************
@@ -275,6 +276,157 @@
     ft_outline_glyph_prepare    /* FT_Glyph_PrepareFunc    glyph_prepare   */
   )
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****   FT_SvgGlyph support                                           ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  ft_svg_glyph_init( FT_Glyph      svg_glyph,
+                     FT_GlyphSlot  slot )
+  {
+    FT_SvgGlyph   glyph   = (FT_SvgGlyph)svg_glyph;
+    FT_Error      error   = FT_Err_Ok;
+    FT_Memory     memory  =  FT_GLYPH( glyph )->library->memory;
+    FT_ULong      doc_length;
+
+    FT_SVG_Document  document;
+
+    if ( slot->format != FT_GLYPH_FORMAT_SVG )
+    {
+      error = FT_THROW( Invalid_Glyph_Format );
+      goto Exit;
+    }
+
+    if ( slot->other == NULL )
+    {
+      error = FT_THROW( Invalid_Slot_Handle );
+      goto Exit;
+    }
+
+    document = (FT_SVG_Document)slot->other;
+
+    if ( document->svg_document_length == 0 )
+    {
+      error = FT_THROW( Invalid_Slot_Handle );
+      goto Exit;
+    }
+
+    slot->format = FT_GLYPH_FORMAT_OUTLINE;
+    /* let's init the parent first */
+    ft_outline_glyph_class.glyph_init( svg_glyph, slot );
+    slot->format = FT_GLYPH_FORMAT_SVG;
+
+    /* allocate a new document */
+    doc_length = document->svg_document_length;
+    glyph->svg_document        = memory->alloc( memory, doc_length );
+    glyph->svg_document_length = doc_length;
+    glyph->glyph_index         = slot->glyph_index;
+    glyph->metrics             = document->metrics;
+
+    /* copy the document into glyph */
+    FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
+
+  Exit:
+    return error;
+  }
+
+
+  FT_CALLBACK_DEF( void )
+  ft_svg_glyph_done( FT_Glyph  svg_glyph )
+  {
+    FT_SvgGlyph  glyph  = (FT_SvgGlyph)svg_glyph;
+    FT_Memory    memory = svg_glyph->library->memory;
+
+    /* free the parent first */
+    ft_outline_glyph_class.glyph_done( svg_glyph );
+
+    /* just free the memory */
+    memory->free( memory, glyph->svg_document );
+  }
+
+  FT_CALLBACK_DEF( FT_Error )
+  ft_svg_glyph_copy( FT_Glyph  svg_source,
+                     FT_Glyph  svg_target )
+  {
+    FT_SvgGlyph  source  = (FT_SvgGlyph)svg_source;
+    FT_SvgGlyph  target  = (FT_SvgGlyph)svg_target;
+    FT_Error     error   = FT_Err_Ok;
+    FT_Memory    memory  = FT_GLYPH( source )->library->memory;
+
+    if ( svg_source->format != FT_GLYPH_FORMAT_SVG )
+    {
+      error = FT_THROW( Invalid_Glyph_Format );
+      return error;
+    }
+
+    if ( source->svg_document_length == 0 )
+    {
+      error = FT_THROW( Invalid_Slot_Handle );
+      return error;
+    }
+
+    /* copy the parent first */
+    ft_outline_glyph_class.glyph_copy( svg_source, svg_target );
+
+    target->glyph_index         = source->glyph_index;
+    target->svg_document_length = source->svg_document_length;
+    target->metrics             = source->metrics;
+
+    /* allocate space for the svg document */
+    target->svg_document = memory->alloc( memory, target->svg_document_length 
);
+
+    /* copy the stuff */
+    FT_MEM_COPY( target->svg_document, source->svg_document, 
target->svg_document_length );
+
+    return error;
+  }
+
+  FT_CALLBACK_DEF( FT_Error )
+  ft_svg_glyph_prepare( FT_Glyph     svg_glyph,
+                        FT_GlyphSlot slot )
+  {
+    FT_SvgGlyph   glyph  = (FT_SvgGlyph)svg_glyph;
+    FT_Error      error  = FT_Err_Ok;
+    FT_Memory     memory = svg_glyph->library->memory;
+
+    FT_SVG_Document  document;
+
+    if ( FT_NEW( document ) )
+      return error;
+
+    /* call the parent and prepare it */
+    ft_outline_glyph_class.glyph_prepare( svg_glyph, slot );
+    slot->format = FT_GLYPH_FORMAT_SVG;
+
+    document->svg_document        = glyph->svg_document;
+    document->svg_document_length = glyph->svg_document_length;
+    document->metrics             = glyph->metrics;
+    slot->format = FT_GLYPH_FORMAT_SVG;
+
+    slot->other = document;
+    return error;
+  }
+
+  FT_DEFINE_GLYPH(
+    ft_svg_glyph_class,
+
+    sizeof ( FT_SvgGlyphRec ),
+    FT_GLYPH_FORMAT_SVG,
+
+    ft_svg_glyph_init,      /* FT_Glyph_InitFunc       glyph_init      */
+    ft_svg_glyph_done,      /* FT_Glyph_DoneFunc       glyph_done      */
+    ft_svg_glyph_copy,      /* FT_Glyph_CopyFunc       glyph_copy      */
+    NULL,                   /* FT_Glyph_TransformFunc  glyph_transform */
+    NULL,                   /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
+    ft_svg_glyph_prepare    /* FT_Glyph_PrepareFunc    glyph_prepare   */
+  )
+
+
 
   /*************************************************************************/
   /*************************************************************************/
@@ -376,6 +528,10 @@
     else if ( format == FT_GLYPH_FORMAT_OUTLINE )
       clazz = &ft_outline_glyph_class;
 
+    /* if it is a SVG glyph */
+    else if ( format == FT_GLYPH_FORMAT_SVG )
+      clazz = &ft_svg_glyph_class;
+
     else
     {
       /* try to find a renderer that supports the glyph image format */



reply via email to

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