freetype
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft] Determining pixel dimensions for bitmap


From: Werner LEMBERG
Subject: Re: [ft] Determining pixel dimensions for bitmap
Date: Fri, 07 Nov 2014 20:08:37 +0100 (CET)

> Sure, here you are.

Thanks.  There is a fundamental problem in your code: You are calling
`FT_Outline_Translate' with non-integer offset values, but you don't
recompute the bbox after this operation to get correct bitmap
dimensions.  It depends on your application whether non-integer offset
values are useful or not.

See attached code that fixes this.  If you execute it, you get much
less cases with a zero row or column.  An example is angle 29, and the
attached image shows the reason (with thick lines indicating pixel
borders): The covered area is to small to cause a non-zero gray value.


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


#define FLOOR(x) ((x) & ~63)
#define CEIL(x) FLOOR((x) + 63)


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;
  int xmin, ymin, xmax, ymax;
  int 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);
    FT_Outline_Translate(&outline, -bbox.xMin, -bbox.yMin);

    FT_Outline_Get_BBox(&outline, &bbox);

    xmin = FLOOR(bbox.xMin) >> 6;
    ymin = FLOOR(bbox.yMin) >> 6;
    xmax = CEIL(bbox.xMax) >> 6;
    ymax = CEIL(bbox.yMax) >> 6;

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

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

Attachment: ft-bbox-rotation-testx-1.pdf
Description: Adobe PDF document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]