X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=ttf2png.c;h=e890e33643084f7784c8d23e280555c425e8fec4;hb=2bd053c9c2207a7c0afa2defee10568fde2e7c50;hp=e39c328c2a2b3a7dc90eb726d3de7be6dedd1d51;hpb=3ea6caa46577f716fa0e5cb46574469c44ee74ed;p=ttf2png.git diff --git a/ttf2png.c b/ttf2png.c index e39c328..e890e33 100644 --- a/ttf2png.c +++ b/ttf2png.c @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA typedef struct sImage { unsigned w, h; - char *data; + unsigned char *data; } Image; typedef struct sGlyph @@ -80,6 +80,7 @@ unsigned round_to_pot(unsigned); 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 *); @@ -264,6 +265,7 @@ int main(int argc, char **argv) free(font.glyphs); free(font.kerning); free(font.image.data); + free(ranges); FT_Done_Face(face); FT_Done_FreeType(freetype); @@ -500,8 +502,8 @@ int init_font(Font *font, FT_Face face, const Range *ranges, unsigned n_ranges, 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) { @@ -541,7 +543,7 @@ int init_font(Font *font, FT_Face face, const Range *ranges, unsigned n_ranges, kern = &font->kerning[font->n_kerning++]; kern->left_code = font->glyphs[i].code; kern->right_code = font->glyphs[j].code; - kern->distance = kerning.x/64; + kern->distance = (kerning.x+32)/64; } } @@ -560,7 +562,6 @@ int init_glyphs(Font *font, FT_Face face, const Range *range, bool autohinter) { unsigned n; FT_Bitmap *bmp = &face->glyph->bitmap; - unsigned x, y; int flags = 0; Glyph *glyph; @@ -594,9 +595,9 @@ int init_glyphs(Font *font, FT_Face face, const Range *range, bool autohinter) 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; } @@ -609,14 +610,6 @@ int init_glyphs(Font *font, FT_Face face, const Range *range, bool autohinter) 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; @@ -624,16 +617,55 @@ int init_glyphs(Font *font, FT_Face face, const Range *range, bool autohinter) /* 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; + unsigned char *dst; + + image->w = bmp->width; + image->h = bmp->rows; + if(!image->w || !image->h) + { + image->data = NULL; + return 0; + } + + image->data = (unsigned 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; yrows; ++y) + { + if(bmp->pixel_mode==FT_PIXEL_MODE_MONO) { - for(y=0; yrows; ++y) for(x=0; xwidth; ++x) - glyph->image.data[x+(glyph->image.h-1-y)*glyph->image.w] = bmp->buffer[x-y*bmp->pitch]; + for(x=0; xwidth; ++x) + dst[x] = ((src[x/8]&(0x80>>(x%8))) ? 0xFF : 0x00); } else { - for(y=0; yrows; ++y) for(x=0; xwidth; ++x) - glyph->image.data[x+y*glyph->image.w] = bmp->buffer[x+y*bmp->pitch]; + for(x=0; xwidth; ++x) + dst[x] = src[x]; } + + src += bmp->pitch; + dst += image->w; } return 0; @@ -713,7 +745,7 @@ int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, bool s if(!npot) font->image.h = round_to_pot(font->image.h); - font->image.data = (char *)alloc_image_data(font->image.w, font->image.h); + font->image.data = (unsigned char *)alloc_image_data(font->image.w, font->image.h); if(!font->image.data) return -1; memset(font->image.data, 255, font->image.w*font->image.h); @@ -790,7 +822,7 @@ int render_packed(Font *font, unsigned margin, unsigned padding, bool npot) glyphs. Since glyphs are rectangular and the image is filled starting from the top, it's enough to track the number of used pixels at the top of each column. */ - font->image.data = (char *)alloc_image_data(font->image.w, font->image.h); + font->image.data = (unsigned char *)alloc_image_data(font->image.w, font->image.h); if(!font->image.data) return -1; memset(font->image.data, 255, font->image.w*font->image.h);