Fix text rotation problem in GM_ADVANCED graphics mode caused by incorrect implementation of GetTextExtentPointW().

Ralf Habacker ralf.habacker at freenet.de
Wed Oct 9 06:48:01 CDT 2013


On 01.10.2013 12:40, Alexandre Julliard wrote:
> Ralf Habacker <ralf at habacker.de> writes:
>
>> On 01.10.2013 12:12, Alexandre Julliard wrote:
>>> Ralf Habacker <ralf.habacker at freenet.de> writes:
>>>
>>>> With other patches i have been told to implement such stuff in the dib
>>>> driver. Unfortunally this do not works in this case, because in the top
>>>> level function it looks like having driver specific stuff using display
>>>> coordinates.
>>> It would still most likely have to be in the driver,
>> which is freetype_GetTextExtentExPoint() ?
>>
>>>  though maybe the driver would not be calling that exact entry point.
>> not sure i understand right:
>>
>> GetTextExtentExPointW() calls get_char_positions(), which runs
>> dev->funcs->pGetTextExtentExPoint(), which is mapped to
>> freetype_GetTextExtentExPoint(), which is in the driver. Which entry
>> point your are refering else ?
> The various text rendering entry points in the graphics drivers.
You mean there are more affected places ?
>
>>> In any case, you can't change the DC transform like this 
>> then a real solution requires to move the transformation to logical
>> coordinates stuff in BOOL GetTextExtentExPointW() to
>> freetype_GetTextExtentExPoint() and to manipulate the related matrixes
>> in freetype_GetTextExtentExPoint() directly wen using GM_ADVANCED ?
> No, I don't think so. The transform is only used to determine the font
> scaling factor.
the recent implementation of get_glyph_outline() uses in GM_ADVANCED
mode a scale which depends somehow on the rotation angle.

I got better results with saving the "use GM_ADVANCED case" in
font->font_desc.advanced_graphics_mode and the following hunks for
freetype.c

@@ -6426,10 +6426,24 @@ static DWORD get_glyph_outline(GdiFont
*incoming_font, UINT glyph, UINT format,
         worldMat.xy = -FTFixedFromFloat(font->font_desc.matrix.eM21);
         worldMat.yx = -FTFixedFromFloat(font->font_desc.matrix.eM12);
         worldMat.yy = FTFixedFromFloat(font->font_desc.matrix.eM22);
         pFT_Matrix_Multiply(&worldMat, &transMat);
-        pFT_Matrix_Multiply(&worldMat, &transMatUnrotated);
         pFT_Matrix_Multiply(&worldMat, &transMatTategaki);
-        needsTransform = TRUE;
+        if (font->font_desc.advanced_graphics_mode) {
+            worldMat.xx =
FTFixedFromFloat(1.0/font->font_desc.matrix.eM11);
+            worldMat.xy = -FTFixedFromFloat(font->font_desc.matrix.eM21);
+            worldMat.yx = -FTFixedFromFloat(font->font_desc.matrix.eM12);
+            worldMat.yy =
FTFixedFromFloat(1.0/font->font_desc.matrix.eM22);
+        }
+        else {
+            worldMat = identityMat;
+        }
+
+        pFT_Matrix_Multiply(&worldMat, &transMatUnrotated);
+       needsTransform = TRUE;
     }

and

@@ -6571,35 +6590,50 @@ static DWORD get_glyph_outline(GdiFont
*incoming_font, UINT glyph, UINT format,
             origin_y = top;
         }
 
+        if (font->font_desc.advanced_graphics_mode)
+            pFT_Vector_Transform(&vec, &transMatUnrotated);
+        else
+            pFT_Vector_Transform(&vec, &transMat);
+

which works except for using 90° and 270° world transformations angles.
Transforming back the list of character width in the top level function
GetTextExtentExPointW(). The transformation is done with

static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
{
    double floatWidth;

    floatWidth = (double)width * dc->xformVport2World.eM11;
    /* Round to integers */
    return GDI_ROUND(floatWidth);
}

dc->xformVport2World.eM11 is zero in the mentioned angles, so it will
always return zero, which means at now the submitted patch is the only
working solution.

>From what i can see an alternative would require to move the device to
logical back transformation into get_glyph_outline() and to refactor all
function get_glyph_outline()  is called from.

Regards
Ralf




More information about the wine-devel mailing list