Adds support for SVG glyphs to Glyph Management API.

This commit is contained in:
Moazin Khatti 2019-06-22 22:54:38 +05:00
parent 61b1f0b73c
commit 6bf9ade45c
2 changed files with 202 additions and 0 deletions

View File

@ -223,6 +223,52 @@ FT_BEGIN_HEADER
} FT_OutlineGlyphRec;
/**************************************************************************
*
* @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:

View File

@ -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 */