> > This calculation gives me an exact fit only if I don't apply any
> > rotation to the shape using FT_Outline_Transform(). As soon as I
> > apply a transformation matrix on my FT_Outline, it happens very
> > often that either the very first row is empty or the very last
> > column is empty.
>
> Could you provide a compilable sample code that exhibits your problem?
Sure, here you are. I tried to make it as simple as possible. The code draws
a 320x240 filled rectangle applying a transformation matrix that rotates
the rectangle from 0 to 359 degrees.
You can see that the first row or the last column is empty very often.
Here are some excerpts from the debug output:
...
*** NOW CHECKING ROTATION ANGLE: 4
--> EMPTY ROW: 0
*** NOW CHECKING ROTATION ANGLE: 5
--> EMPTY ROW: 0
*** NOW CHECKING ROTATION ANGLE: 6
*** NOW CHECKING ROTATION ANGLE: 7
*** NOW CHECKING ROTATION ANGLE: 8
*** NOW CHECKING ROTATION ANGLE: 9
--> EMPTY ROW: 0
*** NOW CHECKING ROTATION ANGLE: 10
--> EMPTY ROW: 0
*** NOW CHECKING ROTATION ANGLE: 11
--> EMPTY ROW: 0
....
*** NOW CHECKING ROTATION ANGLE: 94
--> EMPTY COLUMN: 262
*** NOW CHECKING ROTATION ANGLE: 95
--> EMPTY COLUMN: 267
*** NOW CHECKING ROTATION ANGLE: 96
*** NOW CHECKING ROTATION ANGLE: 97
*** NOW CHECKING ROTATION ANGLE: 98
*** NOW CHECKING ROTATION ANGLE: 99
--> EMPTY COLUMN: 288
*** NOW CHECKING ROTATION ANGLE: 100
--> EMPTY COLUMN: 292
*** NOW CHECKING ROTATION ANGLE: 101
--> EMPTY COLUMN: 297
....
Tested with freetype 2.5.3.
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
#define setvector(pv, px, py) (pv).x = ((int) (px)) << 6; (pv).y = ((int) (py))
<< 6;
#define Float2Fixed(fl) ((FT_Fixed)((fl)*65536.0f))
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
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;
int k, x, y, xmin, ymin, xmax, ymax, pixelwidth, pixelheight;
unsigned char *buf, *ptr;
FT_Init_FreeType(&freetype_library);
for(k = 0; k < 360; k++) {
FT_Stroker_New(freetype_library, &stroker);
setvector(v, 0, 0);
FT_Stroker_BeginSubPath(stroker, &v, 0);
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_Done(stroker);
if(1) {
double angle = (double) (360 - k) * (M_PI / (double)
180);
FT_Matrix m;
m.xx = Float2Fixed(cos(angle));
m.xy = Float2Fixed(-sin(angle));
m.yx = Float2Fixed(sin(angle));
m.yy = Float2Fixed(cos(angle));
FT_Outline_Transform(&outline, &m);
}
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);
FT_Outline_Translate(&outline, -bbox.xMin, -bbox.yMin);
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);
printf("*** NOW CHECKING ROTATION ANGLE: %d\n", k);
ptr = buf;
for(y = 0; y < bm.rows; y++) {
int ok = 0;
for(x = 0; x < bm.width; x++) {
if(ptr[x]) {
ok = 1;
break;
}
}
if(!ok) printf("--> EMPTY ROW: %d\n", y);
ptr += bm.pitch;
}
ptr = buf;
for(x = 0; x < bm.width; x++) {
int ok = 0;
ptr = buf + x;
for(y = 0; y < bm.rows; y++) {
if(*ptr) {
ok = 1;
break;
}
ptr += bm.pitch;
}
if(!ok) printf("--> EMPTY COLUMN: %d\n", x);
}
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