> > How can I get FreeType2 to draw only the outline of my FT_Outline
> > object with a fixed pixel stroke width?
>
> Have a look at the function `Render_Stroke' in the `ftview' demo
> program. It uses the FreeType stroker API.
I have successfully adapted the code from the FT_Glyph_Stroke() API
used in the example mentioned above to work without FT_Glyphs as I'm
not working with glyphs but with paths stored in FT_Stroker objects.
There is only one remaining problem now: I want to apply a transformation
matrix before letting FreeType draw the unfilled shape. This is of
course possible using FT_Outline_Transform() but the problem is that
FT_Outline_Transform() will also apply the transformation matrix to
the outline stroke size and I don't want that. For example, I set
an outline stroke size of 8 pixels like this:
FT_Stroker_Set(stroker, (int) ((double) 8.0 * 32.0),
FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
Now when applying the following transformation matrix, the outline
stroke size is reduced to 4 pixels on the y-axis:
m.xx = Float2Fixed(1.0);
m.xy = Float2Fixed(0.0);
m.yx = Float2Fixed(0.0);
m.yy = Float2Fixed(0.5);
But I don't want this! I want FreeType to use a constant outline stroke
size. The outline stroke size should always be the value that has been
set with FT_Stroker_Set(). Transformations shouldn't change the outline
stroke size. It should always be of size 8 pixels or whatever has been
set using FT_Stroker_Set().
Unfortunately, it is not possible to apply a transformation matrix to
an FT_Stroker AFAICS. If that was possible, I could first apply the
transformation matrix to the stroker and then export it into an FT_Outline.
This would probably leave the outline stroke size intact. But as of
now, I first have to export the path from the FT_Stroker object into
an FT_Outline, and then apply the matrix. This leads to the matrix
getting applied to the outline stroke size as well which I don't
want.
Is there any way around this?
I attach a small example source that shows the problem.
Marco#include <stdio.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_SYNTHESIS_H
#include FT_STROKER_H
static FT_Library freetype_library = NULL;
#define WIDTH 320
#define HEIGHT 240
// desired stroke thickness in pixels
#define STROKE_THICKNESS 8
#define setvector(pv, px, py) (pv).x = ((int) (px)) << 6; (pv).y = ((int) (py))
<< 6;
#define Float2Fixed(fl) ((FT_Fixed)((fl)*65536.0f))
int main(int argc, char *argv[])
{
FT_Stroker stroker;
FT_UInt points, contours;
FT_Outline outline;
FT_BBox bbox;
FT_Bitmap bm;
FT_Vector v;
FT_Matrix m;
int x, y, xmin, ymin, xmax, ymax, pixelwidth, pixelheight;
unsigned char *buf;
FT_Init_FreeType(&freetype_library);
FT_Stroker_New(freetype_library, &stroker);
FT_Stroker_Set(stroker, (int) ((double) STROKE_THICKNESS * 32.0),
FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
setvector(v, 0, 0);
FT_Stroker_BeginSubPath(stroker, &v, 1);
FT_Stroker_LineTo(stroker, &v);
setvector(v, 0, 0);
FT_Stroker_LineTo(stroker, &v);
setvector(v, 0, HEIGHT);
FT_Stroker_LineTo(stroker, &v);
setvector(v, WIDTH, HEIGHT);
FT_Stroker_LineTo(stroker, &v);
setvector(v, WIDTH, 0);
FT_Stroker_LineTo(stroker, &v);
setvector(v, 0, 0);
FT_Stroker_LineTo(stroker, &v);
FT_Stroker_EndSubPath(stroker);
FT_Stroker_GetBorderCounts(stroker, FT_STROKER_BORDER_LEFT, &points,
&contours);
memset(&outline, 0, sizeof(FT_Outline));
FT_Outline_New(freetype_library, 1024, 512, &outline);
outline.n_points = 0;
outline.n_contours = 0;
FT_Stroker_Export(stroker, &outline);
FT_Stroker_ParseOutline(stroker, &outline, 0);
FT_Stroker_GetCounts(stroker, &points, &contours);
FT_Stroker_Done(stroker);
// this transformation will reduce STROKE_THICKNESS on the y-axis to
STROKE_THICKNESS*0.5
// but I don't want this! STROKE_THICKNESS should always be the
constant value that has
// been set in FT_Stroker_Set() --- no matter which transformation
matrix has been applied!
m.xx = Float2Fixed(1.0);
m.xy = Float2Fixed(0.0);
m.yx = Float2Fixed(0.0);
m.yy = Float2Fixed(0.5);
FT_Outline_Transform(&outline, &m);
FT_Outline_Get_BBox(&outline, &bbox);
FT_Outline_Translate(&outline, -bbox.xMin, -bbox.yMin);
FT_Outline_Get_BBox(&outline, &bbox);
xmin = bbox.xMin >> 6;
ymin = bbox.yMin >> 6;
xmax = bbox.xMax >> 6;
ymax = bbox.yMax >> 6;
if(bbox.xMax & 0x3f) xmax++;
if(bbox.yMax & 0x3f) ymax++;
pixelwidth = xmax - xmin;
pixelheight = ymax - ymin;
buf = calloc(pixelwidth * pixelheight, 1);
memset(&bm, 0, sizeof(FT_Bitmap));
bm.rows = pixelheight;
bm.width = pixelwidth;
bm.pitch = pixelwidth;
bm.buffer = buf;
bm.num_grays = 256;
bm.pixel_mode = FT_PIXEL_MODE_GRAY;
FT_Outline_Get_Bitmap(freetype_library, &outline, &bm);
free(buf);
FT_Outline_Done(freetype_library, &outline);
FT_Done_FreeType(freetype_library);
return 0;
}
_______________________________________________
Freetype mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/freetype