]> git.tdb.fi Git - ttf2png.git/commitdiff
Make sure there code point ranges are in order
authorMikko Rasa <tdb@tdb.fi>
Sat, 14 Apr 2018 14:12:01 +0000 (17:12 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 14 Apr 2018 14:12:01 +0000 (17:12 +0300)
And that there are no overlapping ranges.  The grid rendering logic
depends on being able to determine the total range of code points from
the first and last converted glyph.

ttf2png.c

index 2a087ff3ac02eff7acfe403821f6a6704e672f23..6224fc3419436c10c94bd2e1ec0198774fdc4270 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -74,6 +74,8 @@ int convert_numeric_option(char, int);
 void convert_code_point_range(char, Range *);
 unsigned 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 *);
 unsigned round_to_pot(unsigned);
 void *alloc_image_data(size_t, size_t);
 int init_font(Font *, FT_Face, const Range *, unsigned, bool);
@@ -214,6 +216,7 @@ int main(int argc, char **argv)
        }
 
        font.size = size;
+       sort_and_compact_ranges(ranges, &n_ranges);
        err = init_font(&font, face, ranges, n_ranges, autohinter);
        if(err)
                return 1;
@@ -404,6 +407,44 @@ void convert_size(char opt, unsigned *width, unsigned *height)
        exit(1);
 }
 
+void sort_and_compact_ranges(Range *ranges, unsigned *n_ranges)
+{
+       unsigned i, j;
+
+       if(!*n_ranges)
+               return;
+
+       qsort(ranges, *n_ranges, sizeof(Range), &range_cmp);
+       for(i=0, j=1; j<*n_ranges; ++j)
+       {
+               if(ranges[i].last+1>=ranges[j].first)
+               {
+                       if(ranges[j].last>ranges[i].last)
+                               ranges[i].last = ranges[j].last;
+               }
+               else
+               {
+                       ++i;
+                       if(i!=j)
+                               ranges[i] = ranges[j];
+               }
+       }
+
+       *n_ranges = i+1;
+}
+
+int range_cmp(const void *p1, const void *p2)
+{
+       const Range *r1 = (const Range *)p1;
+       const Range *r2 = (const Range *)p2;
+       if(r1->first!=r2->first)
+               return (r1->first<r2->first ? -1 : 1);
+       else if(r1->last!=r2->last)
+               return (r1->last<r2->last ? -1 : 1);
+       else
+               return 0;
+}
+
 unsigned round_to_pot(unsigned n)
 {
        n -= 1;