void T1_AbsolutePath( T1_OUTLINE *rpath)
Once a path has been converted into an absolute path, it is
suitable for possibly nonlinear manipulation.14As an example of what can be done, have a look at figure .
void T1_ManipulatePath( T1_OUTLINE *path, void (*manipulate)(long *x,long *y, int type))
path
should be an absolute path as described above. Notice that
t1lib has no way to check whether the path is relative or absolute, this
is in the responsibility of the user. The second argument is a pointer to a
function that has a return type of void
and that expects three
arguments: two pointers to long
-values one integer type
.
T1_ManipulatePath()
works by iterating through all outline points of
path
and calling the function *manipulate()
for each outline
point. When the function *manipulate()
is called, x
and y
are pointers to the *manipulate()
can alter the outline
points arbitrarily. The type
-argument will be set to the segment type
by T1_ManipulatePath()
. As described earlier, the segment type can be
one of T1_PATHTYPE_MOVE
, T1_PATHTYPE_LINE
and
T1_PATHTYPE_BEZIER
. Of course, the function manipulate()
has to
be written by the user. To make it clear, we consider a function which
stretches an outline horizontally by 1.5. The code fragment for this could be:
. . . void h_stretch( long *x, long *y, int type) { double dx; dx=(double)*x; dx *=1.5; /* scale x coordinate by 1.5 */ *x=(long)dx; } . . . T1_OUTLINE *path=NULL; path=T1_GetStringOutline(FontID,(char *)SomeString, 0,0,T1_KERNING,20.0,NULL); T1_AbsolutePath( path); T1_ManipulatePath( path, &h_stretch); T1_RelativePath( path); glyph=T1_FillOutline( path, Modflag); . . .
As the example above already has shown, an absolute path, manipulated or not, must converted back to a relative path before it finally can be interpreted by the rasterizer. This conversion is done using
void T1_RelativePath( T1_OUTLINE *apath)
T1_AbsolutePath()
, t1lib cannot
check whether the path
specified is really absolute. The user has to
take care for this.
A few general comments about manipulating paths are appropriate. Although the
mechanism implemented by T1_ManipulatePath()
allows arbitrary
manipulation of path points, one must be very careful in doing so. Figure
exhibits some of the problems that may arise. A text
string aligned to a sine function is displayed.
a) ![]()
b)
c)
d)
e) |
Another completely independent topic is that, at the level where t1lib
provides outlines, their representation is strictly descriptive with respect
to points and their connections. There are no such things like
closepath
-segments which would take care that a path is really closed,
no matter what the transformation had been. This means, that identical points
have to be transformed to identical points
, no matter
where they appear in the outline. However,
if the transformation is done by by a function
as suggested,
this should never be a problem.
Finally, one should remember that all computations in the user function
manipulate()
have to be done in units of fractional pixels, rather than in
pixels. When designing a sine wave as in figure ,
this must be taken into account with respect to periodicity.