[Webkit-unassigned] [Bug 50619] [GTK] Glyphs in vertical text tests are rotated 90 degrees clockwise

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Thu Oct 3 10:07:56 PDT 2013


https://bugs.webkit.org/show_bug.cgi?id=50619





--- Comment #38 from Simon Pena <simon.pena at samsung.com>  2013-10-03 10:06:49 PST ---
(From update of attachment 212584)
View in context: https://bugs.webkit.org/attachment.cgi?id=212584&action=review

Thanks a lot for your time preparing the diagram! I thought about it, and I proposed an alternative that maybe feels a bit easier to understand.

>>> Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp:323
>>> +        cairo_matrix_translate(&fontMatrix, 0.0, 1.0);
>> 
>> Could you explain why this makes the translation in the y-axis, while in FontPlatformData::setOrientation you translate in the x-axis?
> 
> Sure. Here is my understanding, please correct me if I'm wrong.
> In the Cairo coordinate system, glyphs are drawn in the quadrant where x and y are positive. For example, in the figure (a) below, the glyph is drawn in quadrant 4.
> Assuming texts are rotated 90 degrees in the user space because the text orientation is vertical, then the coordinates are rotated as in (b) and the glyph is located at quadrant 1.
> So the idea behind the fix is to keep the glyph in quadrant 1 (b) but rotated anti-clockwise 90 degrees. Therefore, rotation angle = -90 degrees, and translation = (0,1). Where (0,1) means a translation of font size towards y-axis. Assuming the system is scaled by font size.
> 
> (a) HORIZONTAL ORIENTATION   (b) VERTICAL ORIENTATION
>           |                            |
>        3  |  4                      2  |  3
>           |     x                y     |
>      ----------->                <-----------
>           |                            |
>        2  |  1                      1  |  4
>           |                            |
>           v y                          v x
> 
>     Translation: (0,0)           Translation: (0,1)
>     Rotation: 0                  Rotation: -90 degrees
> 
>      | 1  0  0 |               | 1  0  0 |   | 1  0  0 |   | 0 -1  0 |   | 0 -1  0 |
>      | 0  1  0 |               | 0  1  0 | x | 0  1  0 | x | 1  0  0 | = | 1  0  0 |
>      | 0  0  1 |               | 0  0  1 |   | 0  1  1 |   | 0  0  1 |   | 1  0  1 |
>   Horizontal Matrix            Horizontal    Translation    Rotation      Vertical
>      (Identity)                  Matrix        Matrix        Matrix        Matrix
> 
> Where translation matrix = |  cos  sin  0 |   cos - cosine of the rotation angle
>                            | -sin  cos  0 |   sin - sine of the rotation angle
>                            |  tx   ty   1 |
> 
>          rotation matrix = |  1    0    0 |   tx,ty - translation in x and y,
>                            |  0    1    0 |           respectively
>                            |  tx   ty   1 |
> 
> At FontPlatformData::setOrientation(), there are two situations:
> 
> 1) From vertical orientation to horizontal orientation
> When changing the orientation from vertical to horizontal, the coordinate system changes from (c) to (d) below, and the glyph is located in quadrant 1.
> So this time, we want to keep the glyph in quadrant 1 (d) but rotated clockwise 90 degrees.
> Therefore, rotation angle = 90 degrees and translation = (-1,0). The peculiar Cairo coordinate system is the reason why translation is done in x-axis and not in y-axis as in (b).
> The resulting rotation angle and translation in (d) should be the same as in (a).
> 
> (c) VERTICAL ORIENTATION     (d) HORIZONTAL ORIENTATION
>           |                            |
>        2  |  3                      3  |  4
>     y     |                            |     x
>     <-----------                  ----------->
>           |                            |
>        1  |  4                      2  |  1
>           |                            |
>           v x                          v y
> 
>     Translation: (0,1)           Translation: (-1,0)
>     Rotation: -90 degrees        Rotation: 90 degrees
> 
>      | 0 -1  0 |               | 0 -1  0 |   | 1  0  0 |   | 0  1  0 |   | 1  0  0 |
>      | 1  0  0 |               | 1  0  0 | x | 0  1  0 | x |-1  0  0 | = | 0  1  0 |
>      | 1  0  1 |               | 1  0  1 |   |-1  0  1 |   | 0  0  1 |   | 0  0  1 |
>       Vertical                  Vertical     Translation    Rotation     Horizontal
>        Matrix                    Matrix        Matrix        Matrix        Matrix
> 
> 2) From horizontal orientation to vertical orientation
> This is the same case as in (a) to (b).
> I realised this last case is incorrect in my patch, which incorrectly translates in the x-axis. This case is not currently used in the code and that explains why this bug wasn't spotted before.
> I will fix it.

If we start from a Horizontal matrix H and we want to get to the Vertical matrix V, we are doing it like:

V = H · R · T

So, if we want to go back to the original Horizontal matrix, we should be able to do

H · (R · T) · (R · T)^(-1) = V · (R · T)^(-1)

So

H = V · T^(-1) · R^(-1)

In the case of the rotation matrix, if we invert it, we get to a Rotation matrix of M_PI_2: the opposite to the previous angle. Then, when we invert the translation matrix, it turns out that we are translating back (0, -1): the opposite amount of the previous translation.

When going from horizontal to vertical, we do

cairo_matrix_rotate(&fontMatrix, -M_PI_2);
cairo_matrix_translate(&fontMatrix, 0.0, 1.0);

so we would, when going from vertical to horizontal, do

cairo_matrix_translate(&fontMatrix, 0.0, -1.0);
cairo_matrix_rotate(&fontMatrix, M_PI_2);

It could be that keeping the order you suggest is also fine, but I think it feels more natural to think about inverting the matrices for going back.

>>> Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp:363
>>> +    uint32_t tag = (table >> 24) | ((table >> 8) & 0xff00) | ((table & 0xff00) << 8) | ((table & 0xff) << 24);
>> 
>> I am not sure, but maybe you could try to use http://www.freetype.org/freetype2/docs/reference/ft2-basic_types.html#FT_MAKE_TAG for this, and it would increase readability.
> 
> Nice one :) That line can be simplified a bit:
> 
> uint32_t tag = FT_MAKE_TAG(table & 0xff,  table & 0xff00, table & 0xff0000, table & 0xff000000);

Cool! I think it's more readable!

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the webkit-unassigned mailing list