summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoazin Khatti <moazinkhatri@gmail.com>2019-08-10 23:36:42 +0500
committerMoazin Khatti <moazinkhatri@gmail.com>2019-08-17 22:47:37 +0500
commit9df8c7dd27df66c79327babf7c011cc145c95563 (patch)
tree4ce4e44e977b7ffdc0256a31669e412c9a58512d
parent1d9364ca89a0adaf7866a3c0f9ae4624e035d5ce (diff)
downloadfreetype2-9df8c7dd27df66c79327babf7c011cc145c95563.tar.gz
Adds OT-SVG glyph support to FT Glyph Management API.
* include/freetype/ftglyph.h: Adds `FT_SvgGlyph' and `FT_SvgGlyphRec'. * src/base/ftglyph.c: Adds glyph class `ft_svg_glyph_class' and its methods. (FT_New_Glyph) Adds code to set the class of OT-SVG glyphs. (FT_Glyph_To_Bitmap) Adds code to free memory allocated for `FT_SVG_Document' in `dummy.other'.
-rw-r--r--include/freetype/ftglyph.h70
-rw-r--r--src/base/ftglyph.c167
2 files changed, 237 insertions, 0 deletions
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index fedab8491..b29751e04 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -225,6 +225,76 @@ 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_GlyphRec.
+ *
+ * @fields:
+ * root ::
+ * The root @FT_GlyphRec 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.
+ *
+ * metrics ::
+ * A metrics object storing the size information.
+ *
+ * units_per_EM ::
+ * The size of the EM square.
+ *
+ * start_glyph_id ::
+ * The starting glyph ID for the glyph range that this document has.
+ *
+ * end_glyph_id ::
+ * The ending glyph ID for the glyph range that this document has.
+ *
+ * @note:
+ * `metrics` and `units_per_EM` might look like repetitions since both
+ * fields are stored in face objects. However, the Glyph Management API
+ * requires an `FT_Glyph` to store all the information that completely
+ * describes a glyph. Outline glyphs are themselves scaled thus they
+ * don't need this information. However, SVG documents do. The field of
+ * `units_per_EM` is needed because the SVG is to be scaled in case its
+ * viewbox size differs from `units_per_EM`. For more info, refer to
+ * the section _Coordinate Systems and Glyph Metrics_ of the OpenType
+ * SVG specs.
+ */
+ typedef struct FT_SvgGlyphRec_
+ {
+ FT_GlyphRec root;
+ FT_Byte* svg_document;
+ FT_ULong svg_document_length;
+ FT_UInt glyph_index;
+ FT_Size_Metrics metrics;
+ FT_UShort units_per_EM;
+ FT_UShort start_glyph_id;
+ FT_UShort end_glyph_id;
+ /* 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 e6b132790..fa60ea1e7 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_OTSVG_H
/**************************************************************************
@@ -275,6 +276,157 @@
ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
)
+#ifdef FT_CONFIG_OPTION_SVG
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** FT_SvgGlyph support ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ FT_CALLBACK_DEF( FT_Error )
+ ft_svg_glyph_init( FT_Glyph svg_glyph,
+ FT_GlyphSlot slot )
+ {
+ FT_ULong doc_length;
+ FT_SVG_Document document;
+ FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = FT_GLYPH( glyph )->library->memory;
+
+
+ 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;
+ }
+
+ /* 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;
+ glyph->units_per_EM = document->units_per_EM;
+ glyph->start_glyph_id = document->start_glyph_id;
+ glyph->end_glyph_id = document->end_glyph_id;
+ /* 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;
+
+ /* 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;
+ }
+
+
+ target->glyph_index = source->glyph_index;
+ target->svg_document_length = source->svg_document_length;
+ target->metrics = source->metrics;
+ target->units_per_EM = source->units_per_EM;
+ target->start_glyph_id = source->start_glyph_id;
+ target->end_glyph_id = source->end_glyph_id;
+
+ /* 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;
+
+ document->svg_document = glyph->svg_document;
+ document->svg_document_length = glyph->svg_document_length;
+ document->metrics = glyph->metrics;
+ document->units_per_EM = glyph->units_per_EM;
+ document->start_glyph_id = glyph->start_glyph_id;
+ document->end_glyph_id = glyph->end_glyph_id;
+
+ slot->format = FT_GLYPH_FORMAT_SVG;
+ slot->glyph_index = glyph->glyph_index;
+ 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 */
+ )
+
+#endif
/*************************************************************************/
/*************************************************************************/
@@ -376,6 +528,12 @@
else if ( format == FT_GLYPH_FORMAT_OUTLINE )
clazz = &ft_outline_glyph_class;
+#ifdef FT_CONFIG_OPTION_SVG
+ /* if it is a SVG glyph */
+ else if ( format == FT_GLYPH_FORMAT_SVG )
+ clazz = &ft_svg_glyph_class;
+#endif
+
else
{
/* try to find a renderer that supports the glyph image format */
@@ -592,7 +750,16 @@
/* prepare dummy slot for rendering */
error = clazz->glyph_prepare( glyph, &dummy );
if ( !error )
+ {
error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
+#ifdef FT_CONFIG_OPTION_SVG
+ if ( clazz == &ft_svg_glyph_class )
+ {
+ FT_Memory memory = library->memory;
+ FT_FREE( dummy.other );
+ }
+#endif
+ }
#if 1
if ( !destroy && origin )