X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=ttf2png.c;h=58b901666a282e4e1aee2805f1d53741a5a10568;hb=7e78e3535d807df01c113e4a870082d79d9ecf49;hp=ae559b106ee14290666ccbf85a79565bd3ca4911;hpb=4fd8c77456f73fb6b30d4ed7125e3990e70a6eed;p=ttf2png.git diff --git a/ttf2png.c b/ttf2png.c index ae559b1..58b9016 100644 --- a/ttf2png.c +++ b/ttf2png.c @@ -61,14 +61,17 @@ typedef struct sFont Image image; } Font; +typedef int bool; + void usage(void); int convert_numeric_option(char, int); -void convert_code_point_range(char, int *, int *); -void convert_size(char, int *, int *); +void convert_code_point_range(char, unsigned *, unsigned *); +unsigned str_to_code_point(const char *, char **); +void convert_size(char, unsigned *, unsigned *); unsigned round_to_pot(unsigned); void *alloc_image_data(size_t, size_t); -int init_font(Font *, FT_Face, unsigned, unsigned, int); -int render_grid(Font *, unsigned, unsigned, unsigned, int); +int init_font(Font *, FT_Face, 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); @@ -78,19 +81,19 @@ char verbose = 0; int main(int argc, char **argv) { char *fn; - int begin = 0; - int end = 255; - int size = 10; - int cpl = 0; - int cellw = 0; - int cellh = 0; - char autohinter = 0; - char seq = 0; - char alpha = 0; - char invert = 0; - char pack = 0; - int margin = 0; - int padding = 1; + unsigned begin = 0; + unsigned end = 255; + unsigned size = 10; + unsigned cpl = 0; + unsigned cellw = 0; + unsigned cellh = 0; + bool autohinter = 0; + bool seq = 0; + bool alpha = 0; + bool invert = 0; + bool pack = 0; + unsigned margin = 0; + unsigned padding = 1; FT_Library freetype; FT_Face face; @@ -207,6 +210,12 @@ int main(int argc, char **argv) if(err) return 1; + if(!font.n_glyphs) + { + fprintf(stderr, "No glyphs found in the requested range\n"); + return 1; + } + if(pack) err = render_packed(&font, margin, padding); else @@ -279,8 +288,9 @@ int convert_numeric_option(char opt, int min_value) return value; } -void convert_code_point_range(char opt, int *begin, int *end) +void convert_code_point_range(char opt, unsigned *begin, unsigned *end) { + int value; char *ptr; if(!strcmp(optarg, "all")) @@ -290,20 +300,63 @@ void convert_code_point_range(char opt, int *begin, int *end) return; } - *begin = strtol(optarg, &ptr, 0); - if(*begin>0 && *ptr==',') + value = str_to_code_point(optarg, &ptr); + if(value>0 && *ptr==',') { - *end = strtol(ptr+1, &ptr, 0); - if(*end>0 && !*ptr) + *begin = value; + value = str_to_code_point(ptr+1, &ptr); + if(value>0 && !*ptr) + { + *end = value; return; + } } printf("Invalid option argument in -%c %s\n", opt, optarg); exit(1); } -void convert_size(char opt, int *width, int *height) +unsigned str_to_code_point(const char *nptr, char **endptr) +{ + if(nptr[0]=='U' && nptr[1]=='+') + return strtoul(nptr+2, endptr, 16); + else if(nptr[0]&0x80) + { + unsigned bytes; + unsigned code; + unsigned i; + + if(endptr) + *endptr = (char *)nptr; + + for(bytes=1; (bytes<4 && (nptr[0]&(0x80>>bytes))); ++bytes) + if((nptr[bytes]&0xC0)!=0x80) + return 0; + if(bytes<2) + return 0; + + code = nptr[0]&(0x3F>>bytes); + for(i=1; i0) + value = strtol(optarg, &ptr, 0); + if(value>0) { + *width = value; if(*ptr=='x') { - *height = strtol(ptr+1, &ptr, 0); - if(*height>0 && !*ptr) + value = strtol(ptr+1, &ptr, 0); + if(value>0 && !*ptr) + { + *height = value; return; + } } else if(!*ptr) { @@ -375,7 +432,7 @@ void *alloc_image_data(size_t a, size_t b) return ptr; } -int init_font(Font *font, FT_Face face, unsigned first, unsigned last, int autohinter) +int init_font(Font *font, FT_Face face, unsigned first, unsigned last, bool autohinter) { unsigned i, j; unsigned size = 0; @@ -409,7 +466,25 @@ int init_font(Font *font, FT_Face face, unsigned first, unsigned last, int autoh FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); if(verbose>=2) - printf(" Char %u: glyph %u, size %dx%d\n", i, n, bmp->width, bmp->rows); + { + printf(" Code point U+%04X", i); + if(i>=0x20 && i<0x7F) + printf(" (%c)", i); + else if(i>=0xA0 && i<=0x10FFFF) + { + char utf8[5]; + unsigned bytes; + + for(bytes=2; i>>(1+bytes*5); ++bytes) ; + for(j=0; j>((bytes-j-1)*6))&0x3F); + utf8[0] |= 0xF0<<(4-bytes); + utf8[j] = 0; + + printf(" (%s)", utf8); + } + printf(": glyph %u, size %dx%d\n", n, bmp->width, bmp->rows); + } if(bmp->pixel_mode!=FT_PIXEL_MODE_GRAY) { @@ -490,7 +565,7 @@ int init_font(Font *font, FT_Face face, unsigned first, unsigned last, int autoh return 0; } -int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, int seq) +int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, bool seq) { unsigned i; int top = 0, bot = 0;