From 050869535277b43b09f1d306605bb3a70f4ad6c5 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 5 May 2018 15:36:11 +0300 Subject: [PATCH] Perform color inversion and npot rounding in save_png --- ttf2png.c | 100 +++++++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/ttf2png.c b/ttf2png.c index 8445555..6543a8d 100644 --- a/ttf2png.c +++ b/ttf2png.c @@ -84,10 +84,10 @@ int copy_bitmap(const FT_Bitmap *, Image *); unsigned sqrti(unsigned); unsigned find_distance_to_edge(const Image *, int, int, unsigned); int create_distance_field(const FT_Bitmap *, Image *, unsigned, unsigned); -int render_grid(Font *, unsigned, unsigned, unsigned, bool, bool); -int render_packed(Font *, unsigned, unsigned, bool); +int render_grid(Font *, unsigned, unsigned, unsigned, bool); +int render_packed(Font *, unsigned, unsigned); int save_defs(const char *, const Font *); -int save_png(const char *, const Image *, char); +int save_png(const char *, const Image *, bool, bool, bool); char verbose = 0; @@ -260,18 +260,13 @@ int main(int argc, char **argv) } if(pack) - err = render_packed(&font, margin, padding, npot); + err = render_packed(&font, margin, padding); else - err = render_grid(&font, cellw, cellh, cpl, seq, npot); + err = render_grid(&font, cellw, cellh, cpl, seq); if(err) return 1; - if(invert || distfield) - { - for(i=0; (unsigned)iglyphs[font->n_glyphs-1].code; font->image.w = cpl*cellw; - if(!npot) - font->image.w = round_to_pot(font->image.w); if(seq) font->image.h = (font->n_glyphs+cpl-1)/cpl*cellh; else font->image.h = (last-first+cpl)/cpl*cellh; - if(!npot) - font->image.h = round_to_pot(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); + memset(font->image.data, 0, font->image.w*font->image.h); for(i=0; in_glyphs; ++i) { @@ -895,14 +886,14 @@ int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, bool s { if(cx+x>=font->image.w || cy+y>=font->image.h) continue; - font->image.data[cx+x+(cy+y)*font->image.w] = 255-glyph->image.data[x+y*glyph->image.w]; + font->image.data[cx+x+(cy+y)*font->image.w] = glyph->image.data[x+y*glyph->image.w]; } } return 0; } -int render_packed(Font *font, unsigned margin, unsigned padding, bool npot) +int render_packed(Font *font, unsigned margin, unsigned padding) { unsigned i; size_t area = 0; @@ -943,7 +934,7 @@ int render_packed(Font *font, unsigned margin, unsigned padding, bool npot) 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); + memset(font->image.data, 0, font->image.w*font->image.h); used_pixels = (unsigned *)malloc(font->image.w*sizeof(unsigned)); memset(used_pixels, 0, font->image.w*sizeof(unsigned)); used_glyphs = (char *)malloc(font->n_glyphs); @@ -1014,7 +1005,7 @@ int render_packed(Font *font, unsigned margin, unsigned padding, bool npot) { if(cx+x>=font->image.w || cy+y>=font->image.h) continue; - font->image.data[cx+x+(cy+y)*font->image.w] = 255-glyph->image.data[x+y*glyph->image.w]; + font->image.data[cx+x+(cy+y)*font->image.w] = glyph->image.data[x+y*glyph->image.w]; } for(x=0; ximage.w+2*padding; ++x) { @@ -1031,8 +1022,6 @@ int render_packed(Font *font, unsigned margin, unsigned padding, bool npot) /* Trim the image to the actually used size, in case the original estimate was too pessimistic. */ font->image.h = used_h; - if(!npot) - font->image.h = round_to_pot(font->image.h); free(used_glyphs); free(used_pixels); @@ -1075,15 +1064,17 @@ int save_defs(const char *fn, const Font *font) return 0; } -int save_png(const char *fn, const Image *image, char alpha) +int save_png(const char *fn, const Image *image, bool alpha, bool invert, bool npot) { FILE *out; png_struct *pngs; png_info *pngi; - png_byte **rows; - unsigned i; - png_byte *data2 = NULL; + unsigned w, h; + png_byte *row; + unsigned x, y; int color; + unsigned flip_bits = (invert==alpha ? 0xFF : 0x00); + unsigned char *src = image->data; if(!strcmp(fn, "-")) out = stdout; @@ -1111,38 +1102,53 @@ int save_png(const char *fn, const Image *image, char alpha) return -1; } + w = (npot ? image->w : round_to_pot(image->w)); + h = (npot ? image->h : round_to_pot(image->h)); + color = (alpha ? PNG_COLOR_TYPE_GRAY_ALPHA : PNG_COLOR_TYPE_GRAY); + png_set_IHDR(pngs, pngi, w, h, 8, color, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + png_init_io(pngs, out); - rows = (png_byte **)malloc(image->h*sizeof(png_byte *)); + png_write_info(pngs, pngi); + row = (png_byte *)malloc(w*(1+alpha)); if(alpha) { - data2 = (png_byte *)alloc_image_data(image->w*2, image->h); - if(!data2) - return -1; - for(i=0; iw*image->h; ++i) + for(x=0; xh; ++y) { - data2[i*2] = 255; - data2[i*2+1] = 255-image->data[i]; + for(x=0; xw; ++x) + row[x*2+1] = *src++^flip_bits; + png_write_row(pngs, row); } - for(i=0; ih; ++i) - rows[i] = (png_byte *)(data2+i*image->w*2); - color = PNG_COLOR_TYPE_GRAY_ALPHA; + + for(x=0; xh; ++i) - rows[i] = (png_byte *)(image->data+i*image->w); - color = PNG_COLOR_TYPE_GRAY; + memset(row+image->w, flip_bits, w-image->w); + for(y=0; yh; ++y) + { + for(x=0; xw; ++x) + row[x] = *src++^flip_bits; + png_write_row(pngs, row); + } + + memset(row, flip_bits, w); } - png_set_IHDR(pngs, pngi, image->w, image->h, 8, color, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_set_rows(pngs, pngi, rows); - png_write_png(pngs, pngi, PNG_TRANSFORM_IDENTITY, NULL); + + for(; yw, image->h, fn); + printf("Saved %dx%d PNG image to %s\n", w, h, fn); fclose(out); -- 2.45.2