From c492bf3f0acf995611e31a583646ac31411ec6e6 Mon Sep 17 00:00:00 2001 From: Moazin Khatti Date: Sat, 17 Aug 2019 16:09:28 +0500 Subject: [PATCH] Handle cascaded transformations correctly. We use homogeneous coordinates to properly calculate an equivalent transformation correctly. --- src/base/ftglyph.c | 48 +++++++++++++++++++++++++++++++++++----------- src/svg/ftsvg.c | 47 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index 300c05baa..f59f404d1 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -392,25 +392,51 @@ FT_CALLBACK_DEF( void ) ft_svg_glyph_transform( FT_Glyph svg_glyph, - const FT_Matrix* matrix, - const FT_Vector* delta ) + const FT_Matrix* _matrix, + const FT_Vector* _delta ) { FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph; - if ( matrix ) + 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 ) { - FT_Matrix a, b; - a = glyph->transform; - b = *matrix; - FT_Matrix_Multiply( &b, &a ); - glyph->transform = a; + tmp_matrix.xx = 0x10000; + tmp_matrix.xy = 0; + tmp_matrix.yx = 0; + tmp_matrix.yy = 0x10000; + matrix = &tmp_matrix; } - if ( delta ) + if ( !delta ) { - glyph->delta.x = ADD_LONG( glyph->delta.x, delta->x ); - glyph->delta.y = ADD_LONG( glyph->delta.y, delta->y ); + 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 ) diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c index 2ba0a17ee..a438be34c 100644 --- a/src/svg/ftsvg.c +++ b/src/svg/ftsvg.c @@ -190,26 +190,51 @@ static FT_Error ft_svg_transform( FT_Renderer renderer, FT_GlyphSlot slot, - const FT_Matrix* matrix, - const FT_Vector* delta ) + const FT_Matrix* _matrix, + const FT_Vector* _delta ) { FT_SVG_Document doc = (FT_SVG_Document)slot->other; - if ( matrix ) + 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 ) { - FT_Matrix a, b; - a = doc->transform; - b = *matrix; - FT_Matrix_Multiply( &b, &a ); - doc->transform = a; + tmp_matrix.xx = 0x10000; + tmp_matrix.xy = 0; + tmp_matrix.yx = 0; + tmp_matrix.yy = 0x10000; + matrix = &tmp_matrix; } - if ( delta ) + if ( !delta ) { - doc->delta.x = ADD_LONG( doc->delta.x, delta->x ); - doc->delta.y = ADD_LONG( doc->delta.y, delta->y ); + 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; }