]> git.tdb.fi Git - ttf2png.git/blobdiff - ttf2png.c
Support more ways of specifying code point ranges
[ttf2png.git] / ttf2png.c
index ae559b106ee14290666ccbf85a79565bd3ca4911..15b554dbfc22291797830264a38d537269fe3b96 100644 (file)
--- 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;
@@ -279,8 +282,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 +294,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; i<bytes; ++i)
+                       code = (code<<6)|(nptr[i]&0x3F);
+
+               if(endptr)
+                       *endptr = (char *)nptr+bytes;
+
+               return code;
+       }
+       else if(isdigit(nptr[0]))
+               return strtoul(nptr, endptr, 0);
+       else
+       {
+               if(endptr)
+                       *endptr = (char *)nptr+1;
+               return *nptr;
+       }
+}
+
+void convert_size(char opt, unsigned *width, unsigned *height)
 {
+       int value;
        char *ptr;
 
        if(!strcmp(optarg, "auto"))
@@ -319,14 +366,18 @@ void convert_size(char opt, int *width, int *height)
                return;
        }
 
-       *width = strtol(optarg, &ptr, 0);
-       if(*width>0)
+       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 +426,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;
@@ -490,7 +541,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;