[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [Freetype] rendering a string, using outlines, in mono
From: |
Vincent Torri |
Subject: |
RE: [Freetype] rendering a string, using outlines, in mono |
Date: |
Mon, 18 Oct 2004 10:03:01 +0200 (MEST) |
Hello,
i go on investigating outlines in mono and i have a question about
vertical alignment in a horizontal layout. First, there's below a test
program which creates a .ppm of some the lower case letters
i draw them using their outlines. Line 173, i have increased
intentionnally pen.y by 1, to hightlight what i want to point out.
Looking at letters c, e, o and s in the ppm file, i assume that they
are correctly vertically aligned.
But, then, i think that letters f, h, i, k, l, m, n, r, t, v, w, x and
z should be on the same horizontal line, but they are at least 1 pixel
above.
More strange (for me): letters h, i, k and l are not 1 pixel above
letter c, but 2 pixels above. Another strange thing: letter a and b
(for example) are not on the same horizontal line.
so, is it normal (and what should i do to correct this) ? Does my program
do something wrong ?
thank you
Vincent TORRI
test program:
/* gcc -O2 -Wall -o test test.c `freetype-config --libs --cflags` */
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>
#include <freetype/ftoutln.h>
#include <freetype/ftbbox.h>
static FT_Library library; /* handle to library */
void
create_mono_ppm (char *filename, unsigned char *bitmap, int pitch, int
width, int height)
{
FILE *file;
unsigned int i, j, off;
unsigned char num, mask;
/* Open the ppm file */
file = fopen (filename, "w+b");
if (file == NULL)
{
printf ("The file can't be opened for writing\n");
return;
}
/* En-tete */
fprintf (file, "P3\n# colorbars.ppm\n%d %d\n256\n", width, height);
off = 0;
for (j = 0 ; j < height ; j++)
{
for (i=0 ; i<width ; i++)
{
unsigned char val;
num = i >> 3; /* num of the byte we are currently reading */
unsigned char byte = bitmap[off + num];
mask = 128 >> (i & 7);
val = ((byte & mask) == mask) * 255;
fprintf (file, "%d %d %d\n",
val, val, val);
}
off += pitch;
}
fclose (file);
}
void
GetTextBoundingBox (FT_Face face, char *str)
{
FT_UInt glyph_index;
FT_Bool use_kerning;
FT_UInt previous;
FT_Vector pos [100];
FT_Pos left[100];
FT_Pos top[100];
FT_Pos height[100];
FT_Vector pen;
FT_BBox bbox;
int n, l;
FT_Outline out;
FT_Outline my_outline[100];
pen.x = 0;
pen.y = 0;
l = strlen (str);
use_kerning = FT_HAS_KERNING (face);
previous = 0;
printf ("get outlines\n");
for (n=0 ; n<l ; n++)
{
glyph_index = FT_Get_Char_Index (face, str[n]);
if (use_kerning && previous && glyph_index)
{
FT_Vector delta;
FT_Get_Kerning (face, previous, glyph_index,
FT_KERNING_DEFAULT, &delta);
pen.x += delta.x >> 6;
}
FT_Load_Glyph (face, glyph_index, FT_LOAD_RENDER |
FT_LOAD_TARGET_MONO);
out = face->glyph->outline;
FT_Outline_New (face->glyph->library, out.n_points, out.n_contours,
&my_outline[n]);
FT_Outline_Copy (&out, &my_outline[n]);
height[n] = face->glyph->metrics.height >> 6;
left[n] = face->glyph->metrics.horiBearingX >> 6;
top[n] = (face->glyph->metrics.height -
face->glyph->metrics.horiBearingY) >> 6;
pos[n].x = pen.x;
pos[n].y = pen.y;
pen.x += face->glyph->advance.x >> 6;
previous = glyph_index;
}
printf ("compute bbox\n");
bbox.xMin = bbox.yMin = 32000;
bbox.xMax = bbox.yMax = -32000;
/* for each glyph image, compute its bounding box, */
/* translate it, and grow the string bbox */
for ( n = 0; n < l; n++ )
{
FT_BBox glyph_bbox;
FT_Outline_Get_CBox (&(my_outline[n]),
&glyph_bbox);
printf (" Outline Bbox %d: %ld %ld %ld %ld\n",n,
glyph_bbox.xMin >> 6, glyph_bbox.xMax >> 6,
glyph_bbox.yMin >> 6, glyph_bbox.yMax >> 6);
glyph_bbox.xMin = glyph_bbox.xMin >> 6;
glyph_bbox.xMax = glyph_bbox.xMax >> 6;
glyph_bbox.yMin = glyph_bbox.yMin >> 6;
glyph_bbox.yMax = glyph_bbox.yMax >> 6;
glyph_bbox.xMin += pos[n].x;
glyph_bbox.xMax += pos[n].x;
glyph_bbox.yMin += pos[n].y;
glyph_bbox.yMax += pos[n].y;
if (glyph_bbox.xMin < bbox.xMin)
bbox.xMin = glyph_bbox.xMin;
if (glyph_bbox.yMin < bbox.yMin)
bbox.yMin = glyph_bbox.yMin;
if (glyph_bbox.xMax > bbox.xMax)
bbox.xMax = glyph_bbox.xMax;
if (glyph_bbox.yMax > bbox.yMax)
bbox.yMax = glyph_bbox.yMax;
}
/* check that we really grew the string bbox */
if (bbox.xMin > bbox.xMax)
{
bbox.xMin = 0;
bbox.yMin = 0;
bbox.xMax = 0;
bbox.yMax = 0;
}
printf ("fill final bitmap\n");
FT_Bitmap bitmap_f;
bitmap_f.rows = bbox.yMax - bbox.yMin;
if (bitmap_f.rows > 32000)
bitmap_f.rows = 32000;
bitmap_f.width = bbox.xMax - bbox.xMin;
if (bitmap_f.width > 32000)
bitmap_f.width = 32000;
bitmap_f.pitch = ((bitmap_f.width + 7) >> 3);
bitmap_f.buffer = (unsigned char *)malloc (sizeof (unsigned char) *
bitmap_f.pitch*bitmap_f.rows);
bitmap_f.pixel_mode = FT_PIXEL_MODE_MONO;
printf ("box size : %d %d\n", bitmap_f.rows, bitmap_f.width);
/* Filling of final bitmap with 0 */
memset (bitmap_f.buffer,
0,
sizeof (unsigned char)*bitmap_f.pitch*bitmap_f.rows);
for ( n = 0; n < l; n++ )
{
FT_Vector pen;
pen.x = pos[n].x - left[0];
pen.y = pos[n].y + 1;
printf ("pos %c : %ld, %ld %ld %ld\n",str[n],
pen.x, pen.y, top[n], height[n]);
FT_Outline_Translate (&my_outline[n], pen.x << 6, pen.y << 6);
FT_Outline_Get_Bitmap (library,
&my_outline[n],
&bitmap_f);
FT_Outline_Translate (&my_outline[n], -pen.x << 6, -pen.y << 6);
FT_Outline_Done (library, &my_outline[n]);
}
create_mono_ppm ("AV.ppm",
bitmap_f.buffer, bitmap_f.pitch,
bitmap_f.width, bitmap_f.rows);
}
int
main (int argc, char *argv[])
{
FT_Face face; /* handle to face object */
FT_Error error;
FT_Init_FreeType (&library);
FT_New_Face (library, "/usr/share/fonts/ttf/vera/VeraBd.ttf", 0, &face);
error = FT_Set_Char_Size (face, /* handle to face object */
0, /* char_width in 1/64th of points */
16*64, /* char_height in 1/64th of points */
300, /* horizontal device resolution */
300); /* vertical device resolution */
/* Bounding Box et other... */
GetTextBoundingBox (face, "gabcdefhiklmnorstuvwxz");
return 1;
}
- [Freetype] rendering a string, using outlines, in mono, Vincent Torri, 2004/10/10
- RE: [Freetype] rendering a string, using outlines, in mono, Turner, David, 2004/10/13
- RE: [Freetype] rendering a string, using outlines, in mono, Turner, David, 2004/10/18