freetype-devel
[Top][All Lists]
Advanced

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

Re: [Devel] pixel size, hinting and scaling


From: David Turner
Subject: Re: [Devel] pixel size, hinting and scaling
Date: Fri, 17 Jan 2003 15:22:25 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.2a) Gecko/20020910

Graham Asher wrote:
David,

I think actually we are in agreement. You said "On the other hand, I'm
pretty certain that we still need to separate the transforms, and make the
distinction to the end user when this makes sense." My idea of having a
single function would do that implicitly: it would decompose the
transformation into scaling and the rest, and set the pixel sizes according
to the scaling only. I take your (implied) point, though, that it is easier
for the user sometimes to have two separate API functions. But that only
reinforces my original idea that there is a design flaw: if the transform
should not do any scaling, this should ideally be enforced by the API in
some way. At present the user is free to apply scaling by calling
FT_Set_Transform, and thus screw up the pixel sizes with respect to hinting.

But there are cases where the user wants to apply the additional scaling
intentionally (e.g. LCD rendering), so providing a way to do that is
convenient.. I really don't think it's a design flaw..

I can understand that you don't like that the function is named
FT_Set_Transfrom instead of FT_Set_Additional_Transform, but it's probably
a minor point. And we can provide "FT_Set_Device_Transform" to perform
what you want..

<<<<<<
Here's a proposed algorithm:

   let A be the matrix   | ax  bx  |
                         | ay  by  |

   then the scaling factors can be computed as:

      sx = sqrt( ax*ax + ay*ay )
      sy = ( ax*by - ay*bx ) / sx

   if sy > 0, we can write that A is equal to:

      | ax/sx  bx/sy  |  multiplied by | sx   0 |
      | ay/sx  by/sy  |                |  0  sy |

   if sy < 0, we can write that A is equal to:

      | ax/sx  -bx/sy  |  multiplied by | sx   0  |
      | ay/sx  -by/sy  |                |  0  -sy |


thanks - that's very useful and I think much more efficient than what I am
doing, which is so naive it's embarrassing ;-) I do it this way:

1. Use the matrix to rotate a vector that originally points in a known
direction (say, up).
2. From the vector, determine an angle by which to rotate the matrix in the
other direction. This removes rotation.
3. The scale factors are now elements 0 and 3 in the matrix. I can divide
the original matrix by them, thus separating
scaling from the rest.

I don't think it's embarassing, au contraire :-) it computes the same
scaling factors with higher accuracy and better speed, since its involves
less multiplications and divisions that my version. I have converted
yours to the FreeType trigonometric functions:

  {
    FT_Vector  v;
    FT_Fixed   sx, sy;
    FT_Angle   angle;

    v.x = matrix.xx;  // the result of applying the matrix
    v.y = matrix.yx;  // to the (1,0) vector

    FT_Vector_Polarize( &v1, &sx, &angle );  // compute sx & angle

    v.x = matrix.xy;  // the result of applying the matrix
    v.y = matrix.yy;  // to the (0,1) vector

    FT_Vector_Rotate( &v1, -angle );  // compute sy
    sy = v.y;
    if ( sy > 0 )
      sy = -sy;

    matrix2.xx = FT_DivFix( matrix.xx, sx );
    matrix2.yx = FT_DivFix( matrix.yx, sx );
    matrix2.xy = FT_DivFix( matrix.xy, sy );
    matrix2.yy = FT_DivFix( matrix.yy, sy );
  }

Due to the way FT_Vector_Rotate and FT_Vector_Polarize are
implemented, this should be significantly faster and more
stable than the previous code posted here...

You can tell from this that I gave up maths at age 15 at school, and never
really caught up.

don't worry, you seem to be doing pretty well already :-)

Regards,

- David Turner
- The FreeType Project  (www.freetype.org)




reply via email to

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