> > 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

Reply via email to