freetype-devel
[Top][All Lists]
Advanced

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

Re: [ft-devel] Strange behavior of freetype2 function FT_Outline_Decompo


From: Werner LEMBERG
Subject: Re: [ft-devel] Strange behavior of freetype2 function FT_Outline_Decompose()
Date: Tue, 16 Dec 2008 09:10:46 +0100 (CET)

> 1) FT_Outline_Decompose() does not walk through all the Outline
> contour-points one-by-one and call the emitters.
> 
> By printing out the to_points passed to the emitters by
> FT_Outline_Decompose(), we noticed that there are gaps.  The
> decomposition begins with a consecutive sequence followed with
> sequences of skipping by one point or more. There isn't any obvious
> correlation with the type of corresponding emitters (line_to(),
> conic_to() or cubic_to())

This is rather easy to explain: TrueType allows that on-curve spline
points can be omitted under certain assumptions.  In the attached
image, there are on-curve points between points 9 and 10 and points 20
and 21.

Consider this example, taken from the letter `m' in FreeMono.ttf,
version 1.126:

   point  coordinates  flag
  --------------------------
     0     (129,576)    on
     1     (129,497)    on
     2     (157,540)    off
                          -> unnumbered on-curve point in the middle
                             between points 2 and 3
     3     (212,576)    off
     4     (248,576)    on
     5     (320,576)    off
     6     (372,491)    on
     7     (435,576)    off
     8     (501,576)    on
     9     (551,576)    off
                          -> unnumbered on-curve point in the middle
                             between points 9 and 10
    10     (641,492)    off
    11     (641,434)    on


Note that I've used

  #define CHAR_WIDTH_DEFAULT_SIZE 20*64
  #define CHAR_HEIGHT_DEFAULT_SIZE 20*64

in outline_decompose.c to get a reasonable glyph size of 20ppem --
1ppem, as used in your example, is too small, even for testing
purposes.

Using the above table, it is rather easy to see that the following
points are passed to the various callback functions:

      callback   `to' point
     -----------------------
      move_to         0
      line_to         1
      conic_to    computed
      conic_to        4
      conic_to        6
      conic_to        8
      conic_to    computed
      conic_to       11

> 2) When closing the decomposition of a contour, the coordinates of the
> to_point passed to the emitter is not transformed.

Well, this is your own fault :-) Look at your function
is_a_contour_end_point:

  int
  is_a_contour_end_point(FT_Outline outline,
                         FT_Vector* to,
                         FT_Pos delta,
                         int shift)
  {
    ...

    to->x = (to->x + delta) >> shift;
    to->y = (to->y + delta) >> shift;
    ...
  }

In other words, you modify the `to' vector, and you shouldn't do this.
Everything's fine if you copy the `to' vector locally before
transforming it back.

BTW, this error would have been easily detected if you had strictly
followed the definitions in ftimage.h.  For example, the function
signature of the `move to' emitter is

  typedef int
  (*FT_Outline_MoveToFunc)( const FT_Vector*  to,
                            void*             user );

while you declare it as

  int
  move_to( FT_Vector* to,
           void* payload )

which drops the `const' qualifier.

> 3) We also observed that most decomposition ended with a call to an
> emitter from the end-point of a contour to its first-point
> (to_point) to close the decomposition. Occasionally, we will see a
> decomposition ending with a call to an emitter (usually a line_to(),
> sometime a conic_to()) not from the last point of the contour, but
> from the contour-point before the last one, to the first point of
> that contour.

This is the same `problem' as issue 1 because of unnumbered on-curve
points.


    Werner

PNG image


reply via email to

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