Adds transformation support for OT-SVG glyphs.
* include/freetype/ftglyph.h: Adds `transform' and `delta' fields to `FT_SvgGlyphRed'. * include/freetype/otsvg.h: Adds `transform' and `delta' fields to `FT_SVG_Document'. * src/base/ftglyph.c: Creates method `ft_svg_glyph_transform' and modifies existing functions for the new fields. * src/sfnt/ttsvg.c: (tt_face_load_svg_doc) Set `transform' to unity and `delta' to zero by default. * src/svg/ftsvg.c: Adds `ft_svg_transform'.
This commit is contained in:
parent
9df8c7dd27
commit
503977f55c
|
@ -268,6 +268,12 @@ FT_BEGIN_HEADER
|
||||||
* end_glyph_id ::
|
* end_glyph_id ::
|
||||||
* The ending glyph ID for the glyph range that this document has.
|
* The ending glyph ID for the glyph range that this document has.
|
||||||
*
|
*
|
||||||
|
* transform ::
|
||||||
|
* Transformation matrix to apply on the glyph while rendering.
|
||||||
|
*
|
||||||
|
* delta ::
|
||||||
|
* Translation to apply on the glyph while rendering.
|
||||||
|
*
|
||||||
* @note:
|
* @note:
|
||||||
* `metrics` and `units_per_EM` might look like repetitions since both
|
* `metrics` and `units_per_EM` might look like repetitions since both
|
||||||
* fields are stored in face objects. However, the Glyph Management API
|
* fields are stored in face objects. However, the Glyph Management API
|
||||||
|
@ -289,7 +295,8 @@ FT_BEGIN_HEADER
|
||||||
FT_UShort units_per_EM;
|
FT_UShort units_per_EM;
|
||||||
FT_UShort start_glyph_id;
|
FT_UShort start_glyph_id;
|
||||||
FT_UShort end_glyph_id;
|
FT_UShort end_glyph_id;
|
||||||
/* TODO: (OT-SVG) Maybe put a transformation matrix here */
|
FT_Matrix transform;
|
||||||
|
FT_Vector delta;
|
||||||
} FT_SvgGlyphRec;
|
} FT_SvgGlyphRec;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,12 @@ FT_BEGIN_HEADER
|
||||||
* end_glyph_id ::
|
* end_glyph_id ::
|
||||||
* The ending glyph ID for the glyph range that this document has.
|
* The ending glyph ID for the glyph range that this document has.
|
||||||
*
|
*
|
||||||
|
* transform ::
|
||||||
|
* Transformation matrix to apply on the glyph while rendering.
|
||||||
|
*
|
||||||
|
* delta ::
|
||||||
|
* Translation to apply on the glyph while rendering.
|
||||||
|
*
|
||||||
* @note:
|
* @note:
|
||||||
* `metrics` and `units_per_EM` might look like repetitions since both
|
* `metrics` and `units_per_EM` might look like repetitions since both
|
||||||
* fields are stored in face object, but they are not; When the slot is
|
* fields are stored in face object, but they are not; When the slot is
|
||||||
|
@ -165,6 +171,8 @@ FT_BEGIN_HEADER
|
||||||
FT_UShort units_per_EM;
|
FT_UShort units_per_EM;
|
||||||
FT_UShort start_glyph_id;
|
FT_UShort start_glyph_id;
|
||||||
FT_UShort end_glyph_id;
|
FT_UShort end_glyph_id;
|
||||||
|
FT_Matrix transform;
|
||||||
|
FT_Vector delta;
|
||||||
} FT_SVG_DocumentRec;
|
} FT_SVG_DocumentRec;
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
|
|
@ -326,6 +326,8 @@
|
||||||
glyph->units_per_EM = document->units_per_EM;
|
glyph->units_per_EM = document->units_per_EM;
|
||||||
glyph->start_glyph_id = document->start_glyph_id;
|
glyph->start_glyph_id = document->start_glyph_id;
|
||||||
glyph->end_glyph_id = document->end_glyph_id;
|
glyph->end_glyph_id = document->end_glyph_id;
|
||||||
|
glyph->transform = document->transform;
|
||||||
|
glyph->delta = document->delta;
|
||||||
/* copy the document into glyph */
|
/* copy the document into glyph */
|
||||||
FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
|
FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
|
||||||
|
|
||||||
|
@ -372,6 +374,8 @@
|
||||||
target->units_per_EM = source->units_per_EM;
|
target->units_per_EM = source->units_per_EM;
|
||||||
target->start_glyph_id = source->start_glyph_id;
|
target->start_glyph_id = source->start_glyph_id;
|
||||||
target->end_glyph_id = source->end_glyph_id;
|
target->end_glyph_id = source->end_glyph_id;
|
||||||
|
target->transform = source->transform;
|
||||||
|
target->delta = source->delta;
|
||||||
|
|
||||||
/* allocate space for the svg document */
|
/* allocate space for the svg document */
|
||||||
target->svg_document = memory->alloc( memory,
|
target->svg_document = memory->alloc( memory,
|
||||||
|
@ -385,6 +389,55 @@
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_CALLBACK_DEF( void )
|
||||||
|
ft_svg_glyph_transform( FT_Glyph svg_glyph,
|
||||||
|
const FT_Matrix* _matrix,
|
||||||
|
const FT_Vector* _delta )
|
||||||
|
{
|
||||||
|
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
|
||||||
|
|
||||||
|
FT_Matrix* matrix = _matrix;
|
||||||
|
FT_Vector* delta = _delta;
|
||||||
|
|
||||||
|
FT_Matrix tmp_matrix;
|
||||||
|
FT_Vector tmp_delta;
|
||||||
|
FT_Matrix a, b;
|
||||||
|
FT_Pos x, y;
|
||||||
|
|
||||||
|
if ( !matrix )
|
||||||
|
{
|
||||||
|
tmp_matrix.xx = 0x10000;
|
||||||
|
tmp_matrix.xy = 0;
|
||||||
|
tmp_matrix.yx = 0;
|
||||||
|
tmp_matrix.yy = 0x10000;
|
||||||
|
matrix = &tmp_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !delta )
|
||||||
|
{
|
||||||
|
tmp_delta.x = 0;
|
||||||
|
tmp_delta.y = 0;
|
||||||
|
delta = &tmp_delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = glyph->transform;
|
||||||
|
b = *matrix;
|
||||||
|
FT_Matrix_Multiply( &b, &a );
|
||||||
|
|
||||||
|
x = ADD_LONG(ADD_LONG(
|
||||||
|
FT_MulFix(matrix->xx, glyph->delta.x),
|
||||||
|
FT_MulFix(matrix->xy, glyph->delta.y)),
|
||||||
|
delta->x);
|
||||||
|
y = ADD_LONG(ADD_LONG(
|
||||||
|
FT_MulFix(matrix->yx, glyph->delta.x),
|
||||||
|
FT_MulFix(matrix->yy, glyph->delta.y)),
|
||||||
|
delta->y);
|
||||||
|
glyph->delta.x = x;
|
||||||
|
glyph->delta.y = y;
|
||||||
|
|
||||||
|
glyph->transform = a;
|
||||||
|
}
|
||||||
|
|
||||||
FT_CALLBACK_DEF( FT_Error )
|
FT_CALLBACK_DEF( FT_Error )
|
||||||
ft_svg_glyph_prepare( FT_Glyph svg_glyph,
|
ft_svg_glyph_prepare( FT_Glyph svg_glyph,
|
||||||
FT_GlyphSlot slot )
|
FT_GlyphSlot slot )
|
||||||
|
@ -404,6 +457,8 @@
|
||||||
document->units_per_EM = glyph->units_per_EM;
|
document->units_per_EM = glyph->units_per_EM;
|
||||||
document->start_glyph_id = glyph->start_glyph_id;
|
document->start_glyph_id = glyph->start_glyph_id;
|
||||||
document->end_glyph_id = glyph->end_glyph_id;
|
document->end_glyph_id = glyph->end_glyph_id;
|
||||||
|
document->transform = glyph->transform;
|
||||||
|
document->delta = glyph->delta;
|
||||||
|
|
||||||
slot->format = FT_GLYPH_FORMAT_SVG;
|
slot->format = FT_GLYPH_FORMAT_SVG;
|
||||||
slot->glyph_index = glyph->glyph_index;
|
slot->glyph_index = glyph->glyph_index;
|
||||||
|
@ -421,7 +476,7 @@
|
||||||
ft_svg_glyph_init, /* FT_Glyph_InitFunc glyph_init */
|
ft_svg_glyph_init, /* FT_Glyph_InitFunc glyph_init */
|
||||||
ft_svg_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
|
ft_svg_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
|
||||||
ft_svg_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
|
ft_svg_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
|
||||||
NULL, /* FT_Glyph_TransformFunc glyph_transform */
|
ft_svg_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */
|
||||||
NULL, /* FT_Glyph_GetBBoxFunc glyph_bbox */
|
NULL, /* FT_Glyph_GetBBoxFunc glyph_bbox */
|
||||||
ft_svg_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
|
ft_svg_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
|
||||||
)
|
)
|
||||||
|
|
|
@ -318,6 +318,13 @@
|
||||||
svg_document->start_glyph_id = start_glyph_id;
|
svg_document->start_glyph_id = start_glyph_id;
|
||||||
svg_document->end_glyph_id = end_glyph_id;
|
svg_document->end_glyph_id = end_glyph_id;
|
||||||
|
|
||||||
|
svg_document->transform.xx = 0x10000;
|
||||||
|
svg_document->transform.xy = 0;
|
||||||
|
svg_document->transform.yx = 0;
|
||||||
|
svg_document->transform.yy = 0x10000;
|
||||||
|
svg_document->delta.x = 0;
|
||||||
|
svg_document->delta.y = 0;
|
||||||
|
|
||||||
FT_TRACE5(( "start_glyph_id: %d\n", start_glyph_id ));
|
FT_TRACE5(( "start_glyph_id: %d\n", start_glyph_id ));
|
||||||
FT_TRACE5(( "end_glyph_id: %d\n", end_glyph_id ));
|
FT_TRACE5(( "end_glyph_id: %d\n", end_glyph_id ));
|
||||||
FT_TRACE5(( "svg_document:\n%.*s\n", doc_length, doc_list ));
|
FT_TRACE5(( "svg_document:\n%.*s\n", doc_length, doc_list ));
|
||||||
|
|
|
@ -175,6 +175,57 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FT_Error
|
||||||
|
ft_svg_transform( FT_Renderer renderer,
|
||||||
|
FT_GlyphSlot slot,
|
||||||
|
const FT_Matrix* _matrix,
|
||||||
|
const FT_Vector* _delta )
|
||||||
|
{
|
||||||
|
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
|
||||||
|
|
||||||
|
FT_Matrix* matrix = _matrix;
|
||||||
|
FT_Vector* delta = _delta;
|
||||||
|
FT_Matrix tmp_matrix;
|
||||||
|
FT_Vector tmp_delta;
|
||||||
|
FT_Matrix a, b;
|
||||||
|
FT_Pos x, y;
|
||||||
|
|
||||||
|
if ( !matrix )
|
||||||
|
{
|
||||||
|
tmp_matrix.xx = 0x10000;
|
||||||
|
tmp_matrix.xy = 0;
|
||||||
|
tmp_matrix.yx = 0;
|
||||||
|
tmp_matrix.yy = 0x10000;
|
||||||
|
matrix = &tmp_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !delta )
|
||||||
|
{
|
||||||
|
tmp_delta.x = 0;
|
||||||
|
tmp_delta.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = doc->transform;
|
||||||
|
b = *matrix;
|
||||||
|
FT_Matrix_Multiply( &b, &a );
|
||||||
|
|
||||||
|
|
||||||
|
x = ADD_LONG(ADD_LONG(
|
||||||
|
FT_MulFix(matrix->xx, doc->delta.x),
|
||||||
|
FT_MulFix(matrix->xy, doc->delta.y)),
|
||||||
|
delta->x);
|
||||||
|
y = ADD_LONG(ADD_LONG(
|
||||||
|
FT_MulFix(matrix->yx, doc->delta.x),
|
||||||
|
FT_MulFix(matrix->yy, doc->delta.y)),
|
||||||
|
delta->y);
|
||||||
|
doc->delta.x = x;
|
||||||
|
doc->delta.y = y;
|
||||||
|
|
||||||
|
doc->transform = a;
|
||||||
|
|
||||||
|
return FT_Err_Ok;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FT_CONFIG_OPTION_SVG
|
#ifdef FT_CONFIG_OPTION_SVG
|
||||||
|
@ -201,7 +252,7 @@
|
||||||
PUT_SVG_MODULE( ft_svg_get_interface ), /* get_interface */
|
PUT_SVG_MODULE( ft_svg_get_interface ), /* get_interface */
|
||||||
SVG_GLYPH_FORMAT,
|
SVG_GLYPH_FORMAT,
|
||||||
(FT_Renderer_RenderFunc)PUT_SVG_MODULE( ft_svg_render ),
|
(FT_Renderer_RenderFunc)PUT_SVG_MODULE( ft_svg_render ),
|
||||||
NULL,
|
(FT_Renderer_TransformFunc)PUT_SVG_MODULE( ft_svg_transform ),
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
|
|
Loading…
Reference in New Issue