[PATCH v2 1/7] gdi32: Add a helper function to get the transform matrices.

Huw Davies huw at codeweavers.com
Wed Feb 6 03:42:05 CST 2019


On Wed, Jan 30, 2019 at 02:12:35AM +0900, Byeongsik Jeon wrote:
> Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
> ---
> Each helper function can be further refactored, but at this point,
> it has kept the existing code. In my personal git branch, I am modifying
> other issues, and these structural change seems appropriate.
> 
> I will send patches that actually fix metric problems separately.
> 
>  dlls/gdi32/freetype.c | 234 ++++++++++++++++++++++--------------------
>  1 file changed, 125 insertions(+), 109 deletions(-)
> 
> diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
> index c38108eece..a522bcaba6 100644
> --- a/dlls/gdi32/freetype.c
> +++ b/dlls/gdi32/freetype.c
> @@ -6588,6 +6588,129 @@ static inline FT_Vector normalize_vector(FT_Vector *vec)
>      return out;
>  }

This is a good opportunity to tidy up some of the code while we're
doing this.  I'll outline a few things below.


> +static BOOL get_transform_matrix( GdiFont *font, BOOL tategaki, const MAT2 *lpmat,

"get_transform_matrices" since it gets more than one.

Let's try to move away from having the word "tategaki" in the code, what this really
means is "vertical", so let's start by renaming this param to that.

Let's rename "lpmat" to "user_transform"

> +                                  FT_Matrix *transMat, FT_Matrix *transMatTategaki,
> +                                  FT_Matrix *transMatUnrotated )

Let's use a FT_Matrix matrices[3] array for these.  It'll obviously need changes to
the calling function too.  We'd define an enum (matrix_hori, matrix_vert, matrix_unrotated)
to index into the array.

> +{
> +    double widthRatio;

width_ratio

> +    BOOL needsTransform = FALSE;

needs_transform

> +
> +    /* Scaling factor */
> +    if (font->aveWidth)
> +    {
> +        TEXTMETRICW tm;
> +        get_text_metrics( font, &tm );
> +
> +        widthRatio = (double)font->aveWidth;
> +        widthRatio /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
> +    }
> +    else
> +        widthRatio = font->scale_y;
> +
> +    /* Scaling transform */
> +    if (widthRatio != 1.0 || font->scale_y != 1.0)
> +    {
> +        FT_Matrix scaleMat;
> +        scaleMat.xx = FT_FixedFromFloat( widthRatio );
> +        scaleMat.xy = 0;
> +        scaleMat.yx = 0;
> +        scaleMat.yy = FT_FixedFromFloat( font->scale_y );
> +
> +        pFT_Matrix_Multiply( &scaleMat, transMat );
> +        needsTransform = TRUE;
> +    }
> +
> +    /* Slant transform */
> +    if (font->fake_italic)
> +    {
> +        FT_Matrix slantMat;
> +        slantMat.xx = (1 << 16);
> +        slantMat.xy = (1 << 16) >> 2;
> +        slantMat.yx = 0;
> +        slantMat.yy = (1 << 16);
> +
> +        pFT_Matrix_Multiply( &slantMat, transMat );
> +        needsTransform = TRUE;
> +    }
> +
> +    /* Rotation transform */
> +    *transMatUnrotated = *transMat;
> +    *transMatTategaki = *transMat;
> +    if (font->orientation || tategaki)
> +    {
> +        FT_Matrix rotationMat;
> +        FT_Matrix taterotationMat;
> +        FT_Vector vecAngle;
> +        FT_Angle  angle;
> +
> +        double orient = font->orientation / 10.0;
> +        double tate_orient = 0.f;

"vert_orient" which should be initialed to orient so we don't need the else
block below.

> +
> +        if (tategaki)
> +            tate_orient = ((font->orientation + 900) % 3600) / 10.0;
> +        else
> +            tate_orient = font->orientation / 10.0;
> +
> +        if (orient)
> +        {
> +            angle = FT_FixedFromFloat( orient );
> +            pFT_Vector_Unit( &vecAngle, angle );
> +            rotationMat.xx =  vecAngle.x;
> +            rotationMat.xy = -vecAngle.y;
> +            rotationMat.yx = -rotationMat.xy;
> +            rotationMat.yy =  rotationMat.xx;
> +
> +            pFT_Matrix_Multiply( &rotationMat, transMat );
> +        }
> +
> +        if (tate_orient)
> +        {
> +            angle = FT_FixedFromFloat( tate_orient );
> +            pFT_Vector_Unit( &vecAngle, angle );
> +            taterotationMat.xx =  vecAngle.x;
> +            taterotationMat.xy = -vecAngle.y;
> +            taterotationMat.yx = -taterotationMat.xy;
> +            taterotationMat.yy =  taterotationMat.xx;
> +
> +            pFT_Matrix_Multiply( &taterotationMat, transMatTategaki );
> +        }
> +
> +        needsTransform = TRUE;
> +    }
> +
> +    /* World transform */
> +    if (!is_identity_FMAT2( &font->font_desc.matrix ))
> +    {
> +        FT_Matrix worldMat;
> +        worldMat.xx =  FT_FixedFromFloat( font->font_desc.matrix.eM11 );
> +        worldMat.xy = -FT_FixedFromFloat( font->font_desc.matrix.eM21 );
> +        worldMat.yx = -FT_FixedFromFloat( font->font_desc.matrix.eM12 );
> +        worldMat.yy =  FT_FixedFromFloat( font->font_desc.matrix.eM22 );
> +
> +        pFT_Matrix_Multiply( &worldMat, transMat );
> +        pFT_Matrix_Multiply( &worldMat, transMatUnrotated );
> +        pFT_Matrix_Multiply( &worldMat, transMatTategaki );

Using a matrices array, the above three lines can be written as a loop.

> +        needsTransform = TRUE;
> +    }
> +
> +    /* Extra transformation specified by caller */
> +    if (!is_identity_MAT2( lpmat ))
> +    {
> +        FT_Matrix extraMat;
> +        extraMat.xx = FT_FixedFromFIXED( lpmat->eM11 );
> +        extraMat.xy = FT_FixedFromFIXED( lpmat->eM21 );
> +        extraMat.yx = FT_FixedFromFIXED( lpmat->eM12 );
> +        extraMat.yy = FT_FixedFromFIXED( lpmat->eM22 );
> +
> +        pFT_Matrix_Multiply( &extraMat, transMat );
> +        pFT_Matrix_Multiply( &extraMat, transMatUnrotated );
> +        pFT_Matrix_Multiply( &extraMat, transMatTategaki );

As can these.

> +        needsTransform = TRUE;
> +    }
> +
> +    return needsTransform;
> +}
> +
>  static BOOL get_bold_glyph_outline(FT_GlyphSlot glyph, LONG ppem, FT_Glyph_Metrics *metrics)
>  {
>      FT_Error err;
> @@ -6946,9 +7069,7 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
>      INT left, right, top = 0, bottom = 0;
>      FT_Vector adv;
>      INT origin_x = 0, origin_y = 0;
> -    FT_Angle angle = 0;
>      FT_Int load_flags = get_load_flags(format);
> -    double widthRatio = 1.0;
>      FT_Matrix transMat = identityMat;
>      FT_Matrix transMatUnrotated;
>      FT_Matrix transMatTategaki;
> @@ -7008,113 +7129,8 @@ static DWORD get_glyph_outline(GdiFont *incoming_font, UINT glyph, UINT format,
>      if (!font->gm[original_index / GM_BLOCK_SIZE])
>          font->gm[original_index / GM_BLOCK_SIZE] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
>  
> -    /* Scaling factor */
> -    if (font->aveWidth)
> -    {
> -        TEXTMETRICW tm;
> -
> -        get_text_metrics(font, &tm);
> -
> -        widthRatio = (double)font->aveWidth;
> -        widthRatio /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
> -    }
> -    else
> -        widthRatio = font->scale_y;
> -
> -    /* Scaling transform */
> -    if (widthRatio != 1.0 || font->scale_y != 1.0)
> -    {
> -        FT_Matrix scaleMat;
> -        scaleMat.xx = FT_FixedFromFloat(widthRatio);
> -        scaleMat.xy = 0;
> -        scaleMat.yx = 0;
> -        scaleMat.yy = FT_FixedFromFloat(font->scale_y);
> -
> -        pFT_Matrix_Multiply(&scaleMat, &transMat);
> -        needsTransform = TRUE;
> -    }
> -
> -    /* Slant transform */
> -    if (font->fake_italic) {
> -        FT_Matrix slantMat;
> -        
> -        slantMat.xx = (1 << 16);
> -        slantMat.xy = ((1 << 16) >> 2);
> -        slantMat.yx = 0;
> -        slantMat.yy = (1 << 16);
> -        pFT_Matrix_Multiply(&slantMat, &transMat);
> -        needsTransform = TRUE;
> -    }
> -
> -    /* Rotation transform */
> -    transMatUnrotated = transMat;
> -    transMatTategaki = transMat;
> -    if(font->orientation || tategaki) {
> -        FT_Matrix rotationMat;
> -        FT_Matrix taterotationMat;
> -        FT_Vector vecAngle;
> -
> -        double orient = font->orientation / 10.0;
> -        double tate_orient = 0.f;
> -
> -        if (tategaki)
> -            tate_orient = ((font->orientation+900)%3600)/10.0;
> -        else
> -            tate_orient = font->orientation/10.0;
> -
> -        if (orient)
> -        {
> -            angle = FT_FixedFromFloat(orient);
> -            pFT_Vector_Unit(&vecAngle, angle);
> -            rotationMat.xx = vecAngle.x;
> -            rotationMat.xy = -vecAngle.y;
> -            rotationMat.yx = -rotationMat.xy;
> -            rotationMat.yy = rotationMat.xx;
> -
> -            pFT_Matrix_Multiply(&rotationMat, &transMat);
> -        }
> -
> -        if (tate_orient)
> -        {
> -            angle = FT_FixedFromFloat(tate_orient);
> -            pFT_Vector_Unit(&vecAngle, angle);
> -            taterotationMat.xx = vecAngle.x;
> -            taterotationMat.xy = -vecAngle.y;
> -            taterotationMat.yx = -taterotationMat.xy;
> -            taterotationMat.yy = taterotationMat.xx;
> -            pFT_Matrix_Multiply(&taterotationMat, &transMatTategaki);
> -        }
> -
> -        needsTransform = TRUE;
> -    }
> -
> -    /* World transform */
> -    if (!is_identity_FMAT2(&font->font_desc.matrix))
> -    {
> -        FT_Matrix worldMat;
> -        worldMat.xx = FT_FixedFromFloat(font->font_desc.matrix.eM11);
> -        worldMat.xy = -FT_FixedFromFloat(font->font_desc.matrix.eM21);
> -        worldMat.yx = -FT_FixedFromFloat(font->font_desc.matrix.eM12);
> -        worldMat.yy = FT_FixedFromFloat(font->font_desc.matrix.eM22);
> -        pFT_Matrix_Multiply(&worldMat, &transMat);
> -        pFT_Matrix_Multiply(&worldMat, &transMatUnrotated);
> -        pFT_Matrix_Multiply(&worldMat, &transMatTategaki);
> -        needsTransform = TRUE;
> -    }
> -
> -    /* Extra transformation specified by caller */
> -    if (!is_identity_MAT2(lpmat))
> -    {
> -        FT_Matrix extraMat;
> -        extraMat.xx = FT_FixedFromFIXED(lpmat->eM11);
> -        extraMat.xy = FT_FixedFromFIXED(lpmat->eM21);
> -        extraMat.yx = FT_FixedFromFIXED(lpmat->eM12);
> -        extraMat.yy = FT_FixedFromFIXED(lpmat->eM22);
> -        pFT_Matrix_Multiply(&extraMat, &transMat);
> -        pFT_Matrix_Multiply(&extraMat, &transMatUnrotated);
> -        pFT_Matrix_Multiply(&extraMat, &transMatTategaki);
> -        needsTransform = TRUE;
> -    }
> +    needsTransform = get_transform_matrix( font, tategaki, lpmat,
> +                                           &transMat, &transMatTategaki, &transMatUnrotated );
>  
>      vertical_metrics = (tategaki && FT_HAS_VERTICAL(ft_face));
>      /* there is a freetype bug where vertical metrics are only
> -- 
> 2.20.1
> 
> 
> 



More information about the wine-devel mailing list