[Top][All Lists]
[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