X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=ttf2png.c;h=76c2e0d96d7330fa530fe00d842b42eca40573e7;hb=HEAD;hp=93576c1eb4daec90ec7db69f8ad3efac83060302;hpb=63abd0338f9d71caa40f8316c95b6e38216bdcc8;p=ttf2png.git diff --git a/ttf2png.c b/ttf2png.c index 93576c1..76c2e0d 100644 --- a/ttf2png.c +++ b/ttf2png.c @@ -1,6 +1,6 @@ /* ttf2png - True Type Font to PNG converter -Copyright (c) 2004-2018 Mikko Rasa, Mikkosoft Productions +Copyright (c) 2004-2021 Mikko Rasa, Mikkosoft Productions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ typedef struct sImage { unsigned w, h; unsigned char *data; + unsigned border; } Image; typedef struct sGlyph @@ -44,8 +45,8 @@ typedef struct sGlyph typedef struct sKerning { - unsigned left_code; - unsigned right_code; + Glyph *left_glyph; + Glyph *right_glyph; int distance; } Kerning; @@ -67,12 +68,12 @@ typedef struct sRange unsigned last; } Range; -typedef int bool; +typedef unsigned char bool; void usage(void); int convert_numeric_option(char, int); void convert_code_point_range(char, Range *); -unsigned str_to_code_point(const char *, char **); +int str_to_code_point(const char *, char **); void convert_size(char, unsigned *, unsigned *); void sort_and_compact_ranges(Range *, unsigned *); int range_cmp(const void *, const void *); @@ -288,8 +289,8 @@ int main(int argc, char **argv) void usage(void) { - printf("ttf2png 1.1 - True Type Font to PNG converter\n" - "Copyright (c) 2004-2018 Mikko Rasa, Mikkosoft Productions\n" + printf("ttf2png 2.0 - True Type Font to PNG converter\n" + "Copyright (c) 2004-2021 Mikko Rasa, Mikkosoft Productions\n" "Distributed under the GNU General Public License\n\n"); printf("Usage: ttf2png [options] \n\n"); @@ -308,8 +309,9 @@ void usage(void) " -p Pack the glyphs tightly instead of in a grid\n" " -m Margin around image edges (packed mode only) [0]\n" " -n Padding between glyphs (packed mode only) [1]\n" - " -g Allow non-power-of-two result\n" - " -f Create a distance field texture\n" + " -g Allow non-power-of-two result\n"); + printf(" -f Create a distance field texture\n" + " -b Specify distance field border zone width\n" " -d File name for writing glyph definitions\n" " -h Print this message\n"); } @@ -342,11 +344,11 @@ void convert_code_point_range(char opt, Range *range) } value = str_to_code_point(optarg, &ptr); - if(value>0 && *ptr==',') + if(value>=0 && *ptr==',') { range->first = value; value = str_to_code_point(ptr+1, &ptr); - if(value>0 && !*ptr) + if(value>=(int)range->first && !*ptr) { range->last = value; return; @@ -357,7 +359,7 @@ void convert_code_point_range(char opt, Range *range) exit(1); } -unsigned str_to_code_point(const char *nptr, char **endptr) +int str_to_code_point(const char *nptr, char **endptr) { if(nptr[0]=='U' && nptr[1]=='+') return strtoul(nptr+2, endptr, 16); @@ -372,9 +374,9 @@ unsigned str_to_code_point(const char *nptr, char **endptr) for(bytes=1; (bytes<4 && (nptr[0]&(0x80>>bytes))); ++bytes) if((nptr[bytes]&0xC0)!=0x80) - return 0; + return -1; if(bytes<2) - return 0; + return -1; code = nptr[0]&(0x3F>>bytes); for(i=1; iw = w; image->h = h; image->data = NULL; + image->border = 0; if(!image->w || !image->h) return 0; @@ -560,8 +563,8 @@ 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->left_glyph = &font->glyphs[i]; + kern->right_glyph = &font->glyphs[j]; kern->distance = (kerning.x/scale+32)/64; } } @@ -748,6 +751,7 @@ int create_distance_field(const FT_Bitmap *bmp, Image *image, unsigned scale, un if(copy_bitmap(bmp, &base_image)) return -1; + image->border = margin; for(y=0; yh; ++y) for(x=0; xw; ++x) { int bx = (x-margin)*scale+scale/2; @@ -875,7 +879,7 @@ int render_packed(Font *font, unsigned margin, unsigned padding) { unsigned i; size_t area = 0; - char *used_glyphs; + bool *used_glyphs; unsigned *used_pixels; unsigned cx = margin, cy; unsigned used_h = 0; @@ -914,7 +918,7 @@ int render_packed(Font *font, unsigned margin, unsigned padding) 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); + used_glyphs = (bool *)malloc(font->n_glyphs); memset(used_glyphs, 0, font->n_glyphs); for(cy=margin; cy+marginimage.h;) @@ -1021,19 +1025,38 @@ int save_defs(const char *fn, const Font *font) fprintf(out, "# Image/font info:\n"); fprintf(out, "# width height size ascent descent\n"); fprintf(out, "font %d %d %d %d %d\n", font->image.w, font->image.h, font->size, font->ascent, font->descent); + + fprintf(out, "\n# Code point mapping:\n"); + fprintf(out, "# code index\n"); + for(i=0; in_glyphs; ++i) + { + const Glyph *g = &font->glyphs[i]; + fprintf(out, "code %u %u\n", g->code, g->index); + } + + fprintf(out, "\n# Metrics info:\n"); + fprintf(out, "# index width height offset_x offset_y advance\n"); + for(i=0; in_glyphs; ++i) + { + const Glyph *g = &font->glyphs[i]; + int b = g->image.border; + fprintf(out, "metrics %u %u %u %d %d %d\n", g->index, g->image.w-2*b, g->image.h-2*b, g->offset_x+b, g->offset_y+b, g->advance); + } + fprintf(out, "\n# Glyph info:\n"); - fprintf(out, "# code x y width height offset_x offset_y advance\n"); + fprintf(out, "# index x y width height border\n"); for(i=0; in_glyphs; ++i) { const Glyph *g = &font->glyphs[i]; - fprintf(out, "glyph %u %u %u %u %u %d %d %d\n", g->code, g->x, g->y, g->image.w, g->image.h, g->offset_x, g->offset_y, g->advance); + fprintf(out, "glyph %u %u %u %u %u %u\n", g->index, g->x, g->y, g->image.w, g->image.h, g->image.border); } + fprintf(out, "\n# Kerning info:\n"); fprintf(out, "# left right distance\n"); for(i=0; in_kerning; ++i) { const Kerning *k = &font->kerning[i]; - fprintf(out, "kern %u %u %d\n", k->left_code, k->right_code, k->distance); + fprintf(out, "kern %u %u %d\n", k->left_glyph->index, k->right_glyph->index, k->distance); } fclose(out);