forked from minhngoc25a/freetype2
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'.
This commit is contained in:
parent
1d9364ca89
commit
9df8c7dd27
|
@ -223,6 +223,76 @@ 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_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:
|
||||
|
|
|
@ -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 )
|
||||
|
|
Loading…
Reference in New Issue