freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] Autohinter only works for unrotated text


From: Graham Asher
Subject: Re: [ft-devel] Autohinter only works for unrotated text
Date: Wed, 27 May 2009 21:26:36 +0100
User-agent: Thunderbird 2.0.0.21 (Windows/20090302)

When I coded this up for a private project a while ago I took a simpler approach: I used the matrix to convert the point (1,0) to a new point. If the new point is (x,0), (0,x), (-x,0) or (0,-x) for any x we have a rotation by a multiple of 90 degrees, neglecting any slant; the slant is ignored because we are transforming a vector along the baseline, and that's what we're interested in.

This system worked perfectly.

Graham


James Cloos wrote:
"Werner" == Werner LEMBERG <address@hidden> writes:

Werner> Maybe there is a volunteer which wants to make the autohinter
Werner> support text rotated by 90°, 180°, and 270°?

The first question, then, is:  what are the contraints on a matrix which
prove that it is a rotation by in integer multiple of 90° followed by a
“simple slant”?

Quoting the PDF ref:

,----
| Rotations are produced by [ cos θ sin θ −sin θ cos θ 0 0 ]
| Skew is specified by      [     1 tan α  tan β     1 0 0 ],
| which skews the x axis by an angle α and the y axis by … β.
`----

And, of course we know that:

,----
|   θ   cos   sin
|   0    1     0
|  90    0     1
| 180   -1     0
| 270    0    -1
`----

Freetype currently checks for:

,----
| face->internal->transform_matrix.yy > 0  &&
| face->internal->transform_matrix.yx == 0 `----

I assume that freetype labels the matix as either:
(both forms are seen in the literature)

⎡xx xy 0⎤      ⎡xx xy tx⎤
⎢yx yy 0⎥  or  ⎢yx yy ty⎥
⎣tx ty 1⎦      ⎣ 0  0  1⎦

then skew (alone) has xx=1, xy=tan α, yx=tan β and yy=1
and rotation by a multiple of 90° (alone) has xx, xy,
yx, yy all ∈ {-1, 0, 1} with xx ≡ yy ∧ xy ≡ −yx.

Checking for yy > 0 seems to attempt to confirm that the matrix is not
degenerate, and yx == 0 is a check that there is no skew to the y axis.

The second question is: what does freetype want to permit as a
grid-fittable transform?  Some possibilites include scale+rotate+slant,
scale+slant+rotate, rotate+scale+slant, rotate+slant+scale, slant+scale+
rotate and slant+rotate+scale.

I used a hp50g emulator with symbolic matrices to get the results of
multiplying identity, scaling, skewing and rotating matrices.

For scale+slant+rotate we have xx=Sx×(cos(θ)−sin(θ)×tan(α)),
xy=Sx×(sin(θ)+cos(θ)×tan(α)), yx=Sy×(cos(θ)−sin(θ)) and
yy=Sy×(cos(θ)+sin(θ)).)

(At least if the math is supposed to be I×Sc×Sl×R and not R×Sl×Sc×I,
where I is the Identity matrix.  I can’t remember now whether the new
matrix is supposed to be appended or prepended....  If they are supposed
to be prepended, they are xx=Sx×cos(θ), xy=Sy×(sin(θ)+tan(α)×cos(θ)),
yx=−(Sx×sin(θ)) and yy=Sy×(cos(θ)−tan(α)×sin(θ)).)

(For the following tables, c=cos(θ), s=sin(θ), t=tan(α), x=Sx and y=Sy.)

The append case is:

   0 deg      90 deg     180 deg     270 deg
----------  ----------  ----------  ----------
  x   tx     -tx   x      -x -tx      tx  -x
  y    y      -y   y      -y  -y       y  -y

And the prepend case is then:

   0 deg      90 deg     180 deg     270 deg
----------  ----------  ----------  ----------
  x   ty       0   y      -x -ty       0  -y
  0    y      -x -ty       0  -y       x  ty

So, unless I screwed up when transcribing, the prepend case is clearly
the correct one.

We want x, y and t to all be >0.  So, it seems we want one of these
possibilities:

( yx == 0 && ( ( xx > 0 && xy > 0 && yy > 0 ) ||
               ( xx < 0 && xy < 0 && yy < 0 ) ) ) ||
( xx == 0 && ( ( xy > 0 && yx < 0 && yy < 0 ) ||
               ( xy < 0 && yx > 0 && yy > 0 ) ) )

In other words, if yx==0 then the other three must all have the same
sign and if xx==0 then yx and yy must share a sign and xy must have the
opposite sign.

Does anyone want to confirm my math?

Note that even if the check is changed to the above, the autofitter may
need more work to correctly handle rotations; it may need to do the
equivilent of un-rotating, fitting and then rotating the pixmap.

Rotating the autofix pixmaps just might prove faster than auto-fitting
with a rotation matrix.

-JimC






reply via email to

[Prev in Thread] Current Thread [Next in Thread]