]> git.tdb.fi Git - ttf2png.git/commitdiff
Support more ways of specifying code point ranges
authorMikko Rasa <tdb@tdb.fi>
Sat, 14 Apr 2018 13:28:19 +0000 (16:28 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 14 Apr 2018 13:28:19 +0000 (16:28 +0300)
Readme
ttf2png.c

diff --git a/Readme b/Readme
index 3e9eb40b323aa81d348344f9065aff765ccd7457..7ce6e70badfe2a479c7b87b2b84d548b8aa9b659 100644 (file)
--- a/Readme
+++ b/Readme
@@ -13,7 +13,9 @@ Command-line options
 
   -r <low>,<high>
     Range of code points to convert, specified as unicode code points.  The
-    default is 0,255, matching the ISO-8859-1 (Latin-1) character set.
+    default is 0,255, matching the ISO-8859-1 (Latin-1) character set.  Code
+    points can be specified as plain numbers, unicode code points (U+xxxx) or
+    UTF-8 characters.
 
   -s <pixels>
     Font size to use.  The default is 10 pixels.
@@ -133,6 +135,9 @@ some fonts, not all of the glyphs fit completely inside the character box.
 
 Changelog
 
+next
+- Alternate ways of specifying code point ranges
+
 1.1
 - Controllable margin and padding in packed mode
 - Do not generate overly large images in sequential grid mode
index d9869bf173671caa4b6908f8f1cd357cb0e978ad..15b554dbfc22291797830264a38d537269fe3b96 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -66,6 +66,7 @@ typedef int bool;
 void usage(void);
 int convert_numeric_option(char, 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);
@@ -293,11 +294,11 @@ void convert_code_point_range(char opt, unsigned *begin, unsigned *end)
                return;
        }
 
-       value = strtol(optarg, &ptr, 0);
+       value = str_to_code_point(optarg, &ptr);
        if(value>0 && *ptr==',')
        {
                *begin = value;
-               value = strtol(ptr+1, &ptr, 0);
+               value = str_to_code_point(ptr+1, &ptr);
                if(value>0 && !*ptr)
                {
                        *end = value;
@@ -309,6 +310,44 @@ void convert_code_point_range(char opt, unsigned *begin, unsigned *end)
        exit(1);
 }
 
+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;