void *alloc_image_data(size_t, size_t);
int init_font(Font *, FT_Face, const Range *, unsigned, bool);
int init_glyphs(Font *, FT_Face, const Range *, bool);
+int copy_bitmap(const FT_Bitmap *, Image *);
int render_grid(Font *, unsigned, unsigned, unsigned, bool, bool);
int render_packed(Font *, unsigned, unsigned, bool);
int save_defs(const char *, const Font *);
free(font.glyphs);
free(font.kerning);
free(font.image.data);
+ free(ranges);
FT_Done_Face(face);
FT_Done_FreeType(freetype);
unsigned i, j;
unsigned size = 0;
- font->ascent = (face->size->metrics.ascender+63)>>6;
- font->descent = (face->size->metrics.descender+63)>>6;
+ font->ascent = (face->size->metrics.ascender+63)/64;
+ font->descent = (face->size->metrics.descender-63)/64;
if(verbose>=1)
{
{
unsigned n;
FT_Bitmap *bmp = &face->glyph->bitmap;
- unsigned x, y;
int flags = 0;
Glyph *glyph;
printf(": glyph %u, size %dx%d\n", n, bmp->width, bmp->rows);
}
- if(bmp->pixel_mode!=FT_PIXEL_MODE_GRAY)
+ if(bmp->pixel_mode!=FT_PIXEL_MODE_GRAY && bmp->pixel_mode!=FT_PIXEL_MODE_MONO)
{
- fprintf(stderr, "Warning: Glyph %u skipped, not grayscale\n", n);
+ fprintf(stderr, "Warning: Glyph %u skipped, incompatible pixel mode\n", n);
continue;
}
glyph = &font->glyphs[font->n_glyphs++];
glyph->index = n;
glyph->code = i;
- glyph->image.w = bmp->width;
- glyph->image.h = bmp->rows;
- glyph->image.data = (char *)malloc(bmp->width*bmp->rows);
- if(!glyph->image.data)
- {
- fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", bmp->width*bmp->rows);
- return -1;
- }
glyph->offset_x = face->glyph->bitmap_left;
glyph->offset_y = face->glyph->bitmap_top-bmp->rows;
glyph->advance = (int)(face->glyph->advance.x+32)/64;
/* Copy the glyph image since FreeType uses a global buffer, which would
be overwritten by the next glyph. Negative pitch means the scanlines
start from the bottom. */
- if(bmp->pitch<0)
+ if(copy_bitmap(bmp, &glyph->image))
+ return -1;
+ }
+
+ return 0;
+}
+
+int copy_bitmap(const FT_Bitmap *bmp, Image *image)
+{
+ unsigned x, y;
+ unsigned char *src;
+ char *dst;
+
+ image->w = bmp->width;
+ image->h = bmp->rows;
+ if(!image->w || !image->h)
+ {
+ image->data = NULL;
+ return 0;
+ }
+
+ image->data = (char *)malloc(image->w*image->h);
+ if(!image->data)
+ {
+ fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", image->w*image->h);
+ return -1;
+ }
+
+ if(bmp->pitch<0)
+ src = bmp->buffer+(bmp->rows-1)*-bmp->pitch;
+ else
+ src = bmp->buffer;
+ dst = image->data;
+
+ for(y=0; y<bmp->rows; ++y)
+ {
+ if(bmp->pixel_mode==FT_PIXEL_MODE_MONO)
{
- for(y=0; y<bmp->rows; ++y) for(x=0; x<bmp->width; ++x)
- glyph->image.data[x+(glyph->image.h-1-y)*glyph->image.w] = bmp->buffer[x-y*bmp->pitch];
+ for(x=0; x<bmp->width; ++x)
+ dst[x] = ((src[x/8]&(0x80>>(x%8))) ? 0xFF : 0x00);
}
else
{
- for(y=0; y<bmp->rows; ++y) for(x=0; x<bmp->width; ++x)
- glyph->image.data[x+y*glyph->image.w] = bmp->buffer[x+y*bmp->pitch];
+ for(x=0; x<bmp->width; ++x)
+ dst[x] = src[x];
}
+
+ src += bmp->pitch;
+ dst += image->w;
}
return 0;