]> git.tdb.fi Git - ttf2png.git/blob - ttf2png.c
Make sure there code point ranges are in order
[ttf2png.git] / ttf2png.c
1 /*
2 ttf2png - True Type Font to PNG converter
3 Copyright (c) 2004-2008 Mikko Rasa
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include <stdio.h>
21 #include <ctype.h>
22 #include <unistd.h>
23 #include <getopt.h>
24 #include <png.h>
25 #include <ft2build.h>
26 #include FT_FREETYPE_H
27
28 typedef struct sImage
29 {
30         unsigned w, h;
31         char *data;
32 } Image;
33
34 typedef struct sGlyph
35 {
36         unsigned index;
37         unsigned code;
38         Image image;
39         unsigned x, y;
40         int offset_x;
41         int offset_y;
42         int advance;
43 } Glyph;
44
45 typedef struct sKerning
46 {
47         unsigned left_code;
48         unsigned right_code;
49         int distance;
50 } Kerning;
51
52 typedef struct sFont
53 {
54         unsigned size;
55         int ascent;
56         int descent;
57         unsigned n_glyphs;
58         Glyph *glyphs;
59         unsigned n_kerning;
60         Kerning *kerning;
61         Image image;
62 } Font;
63
64 typedef struct sRange
65 {
66         unsigned first;
67         unsigned last;
68 } Range;
69
70 typedef int bool;
71
72 void usage(void);
73 int convert_numeric_option(char, int);
74 void convert_code_point_range(char, Range *);
75 unsigned str_to_code_point(const char *, char **);
76 void convert_size(char, unsigned *, unsigned *);
77 void sort_and_compact_ranges(Range *, unsigned *);
78 int range_cmp(const void *, const void *);
79 unsigned round_to_pot(unsigned);
80 void *alloc_image_data(size_t, size_t);
81 int init_font(Font *, FT_Face, const Range *, unsigned, bool);
82 int init_glyphs(Font *, FT_Face, const Range *, bool);
83 int render_grid(Font *, unsigned, unsigned, unsigned, bool);
84 int render_packed(Font *, unsigned, unsigned);
85 int save_defs(const char *, const Font *);
86 int save_png(const char *, const Image *, char);
87
88 char verbose = 0;
89
90 int main(int argc, char **argv)
91 {
92         char *fn;
93         Range *ranges = NULL;
94         unsigned n_ranges = 0;
95         unsigned size = 10;
96         unsigned cpl = 0;
97         unsigned cellw = 0;
98         unsigned cellh = 0;
99         bool autohinter = 0;
100         bool seq = 0;
101         bool alpha = 0;
102         bool invert = 0;
103         bool pack = 0;
104         unsigned margin = 0;
105         unsigned padding = 1;
106
107         FT_Library freetype;
108         FT_Face face;
109
110         int err;
111         int i;
112
113         char *out_fn = "font.png";
114         char *def_fn = NULL;
115
116         Font font;
117
118         if(argc<2)
119         {
120                 usage();
121                 return 1;
122         }
123
124         while((i = getopt(argc, argv, "r:s:l:c:o:atvh?ed:pim:n:")) != -1)
125         {
126                 switch(i)
127                 {
128                 case 'r':
129                         ranges = (Range *)realloc(ranges, (++n_ranges)*sizeof(Range));
130                         convert_code_point_range('r', &ranges[n_ranges-1]);
131                         break;
132                 case 's':
133                         size = convert_numeric_option('s', 1);
134                         break;
135                 case 'l':
136                         cpl = convert_numeric_option('l', 1);
137                         break;
138                 case 'c':
139                         convert_size('c', &cellw, &cellh);
140                         break;
141                 case 'o':
142                         out_fn = optarg;
143                         break;
144                 case 'a':
145                         autohinter = 1;
146                         break;
147                 case 't':
148                         alpha = 1;
149                         break;
150                 case 'v':
151                         ++verbose;
152                         break;
153                 case 'h':
154                 case '?':
155                         usage();
156                         return 0;
157                 case 'e':
158                         seq = 1;
159                         break;
160                 case 'd':
161                         def_fn = optarg;
162                         break;
163                 case 'p':
164                         pack = 1;
165                         break;
166                 case 'i':
167                         invert = 1;
168                         break;
169                 case 'm':
170                         margin = convert_numeric_option('m', 0);
171                         break;
172                 case 'n':
173                         padding = convert_numeric_option('n', 0);
174                         break;
175                 }
176         }
177         if(!strcmp(out_fn, "-"))
178                 verbose = 0;
179
180         if(optind!=argc-1)
181         {
182                 usage();
183                 return 1;
184         }
185
186         fn = argv[optind];
187
188         err = FT_Init_FreeType(&freetype);
189         if(err)
190         {
191                 fprintf(stderr, "Couldn't initialize FreeType library\n");
192                 return 1;
193         }
194
195         err = FT_New_Face(freetype, fn, 0, &face);
196         if(err)
197         {
198                 fprintf(stderr, "Couldn't load font file\n");
199                 if(err==FT_Err_Unknown_File_Format)
200                         fprintf(stderr, "Unknown file format\n");
201                 return 1;
202         }
203
204         if(verbose)
205         {
206                 const char *name = FT_Get_Postscript_Name(face);
207                 printf("Font name: %s\n", name);
208                 printf("Glyphs:    %ld\n", face->num_glyphs);
209         }
210
211         err = FT_Set_Pixel_Sizes(face, 0, size);
212         if(err)
213         {
214                 fprintf(stderr, "Couldn't set size\n");
215                 return 1;
216         }
217
218         font.size = size;
219         sort_and_compact_ranges(ranges, &n_ranges);
220         err = init_font(&font, face, ranges, n_ranges, autohinter);
221         if(err)
222                 return 1;
223
224         if(!font.n_glyphs)
225         {
226                 fprintf(stderr, "No glyphs found in the requested range\n");
227                 return 1;
228         }
229
230         if(pack)
231                 err = render_packed(&font, margin, padding);
232         else
233                 err = render_grid(&font, cellw, cellh, cpl, seq);
234         if(err)
235                 return 1;
236
237         if(invert)
238         {
239                 for(i=0; (unsigned)i<font.image.w*font.image.h; ++i)
240                         font.image.data[i] = 255-font.image.data[i];
241         }
242         err = save_png(out_fn, &font.image, alpha);
243         if(err)
244                 return 1;
245
246         if(def_fn)
247                 save_defs(def_fn, &font);
248
249         for(i=0; (unsigned)i<font.n_glyphs; ++i)
250                 free(font.glyphs[i].image.data);
251         free(font.glyphs);
252         free(font.kerning);
253         free(font.image.data);
254
255         FT_Done_Face(face);
256         FT_Done_FreeType(freetype);
257
258         return 0;
259 }
260
261 void usage(void)
262 {
263         printf("ttf2png 1.1 - True Type Font to PNG converter\n"
264                 "Copyright (c) 2004-2018  Mikko Rasa, Mikkosoft Productions\n"
265                 "Distributed under the GNU General Public License\n\n");
266
267         printf("Usage: ttf2png [options] <TTF file>\n\n");
268
269         printf("Accepted options (default values in [brackets])\n"
270                 "  -r  Range of code points to convert [0,255]\n"
271                 "  -s  Font size to use, in pixels [10]\n"
272                 "  -l  Number of glyphs to put in one line [auto]\n"
273                 "  -c  Glyph cell size, in pixels (grid mode only) [auto]\n"
274                 "  -o  Output file name (or - for stdout) [font.png]\n");
275         printf("  -a  Force autohinter\n"
276                 "  -t  Render glyphs to alpha channel\n"
277                 "  -i  Invert colors of the glyphs\n"
278                 "  -v  Increase the level of verbosity\n"
279                 "  -e  Use cells in sequence, without gaps (grid mode only)\n"
280                 "  -p  Pack the glyphs tightly instead of in a grid\n"
281                 "  -m  Margin around image edges (packed mode only) [0]\n"
282                 "  -n  Padding between glyphs (packed mode only) [1]\n"
283                 "  -d  File name for writing glyph definitions\n"
284                 "  -h  Print this message\n");
285 }
286
287 int convert_numeric_option(char opt, int min_value)
288 {
289         int value;
290         char *ptr;
291
292         value = strtol(optarg, &ptr, 0);
293         if(value<min_value || *ptr)
294         {
295                 printf("Invalid option argument in -%c %s\n", opt, optarg);
296                 exit(1);
297         }
298
299         return value;
300 }
301
302 void convert_code_point_range(char opt, Range *range)
303 {
304         int value;
305         char *ptr;
306
307         if(!strcmp(optarg, "all"))
308         {
309                 range->first = 0;
310                 range->last = 0x10FFFF;
311                 return;
312         }
313
314         value = str_to_code_point(optarg, &ptr);
315         if(value>0 && *ptr==',')
316         {
317                 range->first = value;
318                 value = str_to_code_point(ptr+1, &ptr);
319                 if(value>0 && !*ptr)
320                 {
321                         range->last = value;
322                         return;
323                 }
324         }
325
326         printf("Invalid option argument in -%c %s\n", opt, optarg);
327         exit(1);
328 }
329
330 unsigned str_to_code_point(const char *nptr, char **endptr)
331 {
332         if(nptr[0]=='U' && nptr[1]=='+')
333                 return strtoul(nptr+2, endptr, 16);
334         else if(nptr[0]&0x80)
335         {
336                 unsigned bytes;
337                 unsigned code;
338                 unsigned i;
339
340                 if(endptr)
341                         *endptr = (char *)nptr;
342
343                 for(bytes=1; (bytes<4 && (nptr[0]&(0x80>>bytes))); ++bytes)
344                         if((nptr[bytes]&0xC0)!=0x80)
345                                 return 0;
346                 if(bytes<2)
347                         return 0;
348
349                 code = nptr[0]&(0x3F>>bytes);
350                 for(i=1; i<bytes; ++i)
351                         code = (code<<6)|(nptr[i]&0x3F);
352
353                 if(endptr)
354                         *endptr = (char *)nptr+bytes;
355
356                 return code;
357         }
358         else if(isdigit(nptr[0]))
359                 return strtoul(nptr, endptr, 0);
360         else
361         {
362                 if(endptr)
363                         *endptr = (char *)nptr+1;
364                 return *nptr;
365         }
366 }
367
368 void convert_size(char opt, unsigned *width, unsigned *height)
369 {
370         int value;
371         char *ptr;
372
373         if(!strcmp(optarg, "auto"))
374         {
375                 *width = 0;
376                 *height = 0;
377                 return;
378         }
379         else if(!strcmp(optarg, "autorect"))
380         {
381                 *width = 0;
382                 *height = 1;
383                 return;
384         }
385
386         value = strtol(optarg, &ptr, 0);
387         if(value>0)
388         {
389                 *width = value;
390                 if(*ptr=='x')
391                 {
392                         value = strtol(ptr+1, &ptr, 0);
393                         if(value>0 && !*ptr)
394                         {
395                                 *height = value;
396                                 return;
397                         }
398                 }
399                 else if(!*ptr)
400                 {
401                         *height = *width;
402                         return;
403                 }
404         }
405
406         printf("Invalid option argument in -%c %s\n", opt, optarg);
407         exit(1);
408 }
409
410 void sort_and_compact_ranges(Range *ranges, unsigned *n_ranges)
411 {
412         unsigned i, j;
413
414         if(!*n_ranges)
415                 return;
416
417         qsort(ranges, *n_ranges, sizeof(Range), &range_cmp);
418         for(i=0, j=1; j<*n_ranges; ++j)
419         {
420                 if(ranges[i].last+1>=ranges[j].first)
421                 {
422                         if(ranges[j].last>ranges[i].last)
423                                 ranges[i].last = ranges[j].last;
424                 }
425                 else
426                 {
427                         ++i;
428                         if(i!=j)
429                                 ranges[i] = ranges[j];
430                 }
431         }
432
433         *n_ranges = i+1;
434 }
435
436 int range_cmp(const void *p1, const void *p2)
437 {
438         const Range *r1 = (const Range *)p1;
439         const Range *r2 = (const Range *)p2;
440         if(r1->first!=r2->first)
441                 return (r1->first<r2->first ? -1 : 1);
442         else if(r1->last!=r2->last)
443                 return (r1->last<r2->last ? -1 : 1);
444         else
445                 return 0;
446 }
447
448 unsigned round_to_pot(unsigned n)
449 {
450         n -= 1;
451         n |= n>>1;
452         n |= n>>2;
453         n |= n>>4;
454         n |= n>>8;
455         n |= n>>16;
456
457         return n+1;
458 }
459
460 void *alloc_image_data(size_t a, size_t b)
461 {
462         void *ptr;
463
464         /* Carry out the multiplication manually so we can check for overflow. */
465         while(b>1)
466         {
467                 size_t c = a;
468                 a *= 2;
469                 if(b&1)
470                         a += c;
471                 if(a<c)
472                 {
473                         fprintf(stderr, "Cannot allocate %lu kbytes of memory for image\n", (unsigned long)(c/1024*b));
474                         return NULL;
475                 }
476                 b /= 2;
477         }
478         ptr = malloc(a);
479         if(!ptr)
480                 fprintf(stderr, "Cannot allocate %lu kbytes of memory for image\n", (unsigned long)(a/1024*b));
481         return ptr;
482 }
483
484 int init_font(Font *font, FT_Face face, const Range *ranges, unsigned n_ranges, bool autohinter)
485 {
486         unsigned i, j;
487         unsigned size = 0;
488
489         font->ascent = (face->size->metrics.ascender+63)>>6;
490         font->descent = (face->size->metrics.descender+63)>>6;
491
492         if(verbose>=1)
493         {
494                 printf("Ascent:    %d\n", font->ascent);
495                 printf("Descent:   %d\n", font->descent);
496         }
497
498         font->n_glyphs = 0;
499         font->glyphs = NULL;
500         for(i=0; i<n_ranges; ++i)
501                 if(init_glyphs(font, face, &ranges[i], autohinter))
502                         return -1;
503
504         if(verbose>=1)
505                 printf("Loaded %u glyphs\n", font->n_glyphs);
506
507         font->n_kerning = 0;
508         font->kerning = NULL;
509         for(i=0; i<font->n_glyphs; ++i) for(j=0; j<font->n_glyphs; ++j)
510                 if(j!=i)
511                 {
512                         FT_Vector kerning;
513                         FT_Get_Kerning(face, font->glyphs[i].index, font->glyphs[j].index, FT_KERNING_DEFAULT, &kerning);
514
515                         /* FreeType documentation says that vertical kerning is practically
516                         never used, so we ignore it. */
517                         if(kerning.x)
518                         {
519                                 Kerning *kern;
520
521                                 if(font->n_kerning>=size)
522                                 {
523                                         size += 16;
524                                         font->kerning = (Kerning *)realloc(font->kerning, size*sizeof(Kerning));
525                                 }
526
527                                 kern = &font->kerning[font->n_kerning++];
528                                 kern->left_code = font->glyphs[i].code;
529                                 kern->right_code = font->glyphs[j].code;
530                                 kern->distance = kerning.x/64;
531                         }
532                 }
533
534         if(verbose>=1)
535                 printf("Loaded %d kerning pairs\n", font->n_kerning);
536
537         return 0;
538 }
539
540 int init_glyphs(Font *font, FT_Face face, const Range *range, bool autohinter)
541 {
542         unsigned i, j;
543         unsigned size = font->n_glyphs;
544
545         for(i=range->first; i<=range->last; ++i)
546         {
547                 unsigned n;
548                 FT_Bitmap *bmp = &face->glyph->bitmap;
549                 unsigned x, y;
550                 int flags = 0;
551                 Glyph *glyph;
552
553                 n = FT_Get_Char_Index(face, i);
554                 if(!n)
555                         continue;
556
557                 if(autohinter)
558                         flags |= FT_LOAD_FORCE_AUTOHINT;
559                 FT_Load_Glyph(face, n, flags);
560                 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
561
562                 if(verbose>=2)
563                 {
564                         printf("  Code point U+%04X", i);
565                         if(i>=0x20 && i<0x7F)
566                                 printf(" (%c)", i);
567                         else if(i>=0xA0 && i<=0x10FFFF)
568                         {
569                                 char utf8[5];
570                                 unsigned bytes;
571
572                                 for(bytes=2; i>>(1+bytes*5); ++bytes) ;
573                                 for(j=0; j<bytes; ++j)
574                                         utf8[j] = 0x80 | ((i>>((bytes-j-1)*6))&0x3F);
575                                 utf8[0] |= 0xF0<<(4-bytes);
576                                 utf8[j] = 0;
577
578                                 printf(" (%s)", utf8);
579                         }
580                         printf(": glyph %u, size %dx%d\n", n, bmp->width, bmp->rows);
581                 }
582
583                 if(bmp->pixel_mode!=FT_PIXEL_MODE_GRAY)
584                 {
585                         fprintf(stderr, "Warning: Glyph %u skipped, not grayscale\n", n);
586                         continue;
587                 }
588
589                 if(font->n_glyphs>=size)
590                 {
591                         size += 16;
592                         font->glyphs = (Glyph *)realloc(font->glyphs, size*sizeof(Glyph));
593                 }
594
595                 glyph = &font->glyphs[font->n_glyphs++];
596                 glyph->index = n;
597                 glyph->code = i;
598                 glyph->image.w = bmp->width;
599                 glyph->image.h = bmp->rows;
600                 glyph->image.data = (char *)malloc(bmp->width*bmp->rows);
601                 if(!glyph->image.data)
602                 {
603                         fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", bmp->width*bmp->rows);
604                         return -1;
605                 }
606                 glyph->offset_x = face->glyph->bitmap_left;
607                 glyph->offset_y = face->glyph->bitmap_top-bmp->rows;
608                 glyph->advance = (int)(face->glyph->advance.x+32)/64;
609
610                 /* Copy the glyph image since FreeType uses a global buffer, which would
611                 be overwritten by the next glyph.  Negative pitch means the scanlines
612                 start from the bottom. */
613                 if(bmp->pitch<0)
614                 {
615                         for(y=0; y<bmp->rows; ++y) for(x=0; x<bmp->width; ++x)
616                                 glyph->image.data[x+(glyph->image.h-1-y)*glyph->image.w] = bmp->buffer[x-y*bmp->pitch];
617                 }
618                 else
619                 {
620                         for(y=0; y<bmp->rows; ++y) for(x=0; x<bmp->width; ++x)
621                                 glyph->image.data[x+y*glyph->image.w] = bmp->buffer[x+y*bmp->pitch];
622                 }
623         }
624
625         return 0;
626 }
627
628 int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, bool seq)
629 {
630         unsigned i;
631         int top = 0, bot = 0;
632         unsigned first, last;
633         unsigned maxw = 0, maxh = 0;
634
635         /* Find extremes of the glyph images. */
636         for(i=0; i<font->n_glyphs; ++i)
637         {
638                 int y;
639
640                 y = font->glyphs[i].offset_y+font->glyphs[i].image.h;
641                 if(y>top)
642                         top = y;
643                 if(font->glyphs[i].offset_y<bot)
644                         bot = font->glyphs[i].offset_y;
645                 if(font->glyphs[i].image.w>maxw)
646                         maxw = font->glyphs[i].image.w;
647                 if(font->glyphs[i].image.h>maxh)
648                         maxh = font->glyphs[i].image.h;
649         }
650
651         if(cellw==0)
652         {
653                 /* Establish a large enough cell to hold all glyphs in the range. */
654                 int square = (cellh==cellw);
655                 cellw = maxw;
656                 cellh = top-bot;
657                 if(square)
658                 {
659                         if(cellh>cellw)
660                                 cellw = cellh;
661                         else
662                                 cellh = cellw;
663                 }
664         }
665
666         if(verbose>=1)
667         {
668                 printf("Max size:  %u x %u\n", maxw, maxh);
669                 printf("Y range:   [%d %d]\n", bot, top);
670                 printf("Cell size: %u x %u\n", cellw, cellh);
671                 if(maxw>cellw || (unsigned)(top-bot)>cellh)
672                         fprintf(stderr, "Warning: character size exceeds cell size\n");
673         }
674
675         if(cpl==0)
676         {
677                 /* Determine number of characters per line, trying to fit all the glyphs
678                 in a square image. */
679                 for(i=1;; i<<=1)
680                 {
681                         cpl = i/cellw;
682                         if(cpl>0 && font->n_glyphs/cpl*cellh<=cpl*cellw)
683                                 break;
684                 }
685         }
686
687         first = font->glyphs[0].code;
688         if(!seq)
689                 first -= first%cpl;
690         last = font->glyphs[font->n_glyphs-1].code;
691
692         font->image.w = round_to_pot(cpl*cellw);
693         if(seq)
694                 font->image.h = round_to_pot((font->n_glyphs+cpl-1)/cpl*cellh);
695         else
696                 font->image.h = round_to_pot((last-first+cpl)/cpl*cellh);
697
698         font->image.data = (char *)alloc_image_data(font->image.w, font->image.h);
699         if(!font->image.data)
700                 return -1;
701         memset(font->image.data, 255, font->image.w*font->image.h);
702
703         for(i=0; i<font->n_glyphs; ++i)
704         {
705                 Glyph *glyph;
706                 unsigned ci, cx, cy;
707                 unsigned x, y;
708
709                 glyph = &font->glyphs[i];
710
711                 if(seq)
712                         ci = i;
713                 else
714                         ci = glyph->code-first;
715
716                 cx = (ci%cpl)*cellw;
717                 cy = (ci/cpl)*cellh;
718
719                 if(cellw>glyph->image.w)
720                         cx += (cellw-glyph->image.w)/2;
721                 cy += top-glyph->offset_y-glyph->image.h;
722
723                 glyph->x = cx;
724                 glyph->y = cy;
725
726                 for(y=0; y<glyph->image.h; ++y) for(x=0; x<glyph->image.w; ++x)
727                 {
728                         if(cx+x>=font->image.w || cy+y>=font->image.h)
729                                 continue;
730                         font->image.data[cx+x+(cy+y)*font->image.w] = 255-glyph->image.data[x+y*glyph->image.w];
731                 }
732         }
733
734         return 0;
735 }
736
737 int render_packed(Font *font, unsigned margin, unsigned padding)
738 {
739         unsigned i;
740         size_t area = 0;
741         char *used_glyphs;
742         unsigned *used_pixels;
743         unsigned cx = margin, cy;
744         unsigned used_h = 0;
745
746         /* Compute the total area occupied by glyphs and padding. */
747         for(i=0; i<font->n_glyphs; ++i)
748         {
749                 size_t a = area+(font->glyphs[i].image.w+padding)*(font->glyphs[i].image.h+padding);
750                 if(a<area)
751                 {
752                         fprintf(stderr, "Overflow in counting total glyph area\n");
753                         return -1;
754                 }
755                 area = a;
756         }
757
758         /* Find an image size that's no higher than wide, allowing for some
759         imperfections in the packing. */
760         for(font->image.w=1;; font->image.w<<=1)
761         {
762                 if(font->image.w<=margin*2)
763                         continue;
764                 font->image.h = (area*5/4)/(font->image.w-margin*2)+margin*2;
765                 if(font->image.h<=font->image.w)
766                         break;
767         }
768         font->image.h = round_to_pot(font->image.h);
769
770         /* Allocate arrays for storing the image and keeping track of used pixels and
771         glyphs.  Since glyphs are rectangular and the image is filled starting from
772         the top, it's enough to track the number of used pixels at the top of each
773         column. */
774         font->image.data = (char *)alloc_image_data(font->image.w, font->image.h);
775         if(!font->image.data)
776                 return -1;
777         memset(font->image.data, 255, font->image.w*font->image.h);
778         used_pixels = (unsigned *)malloc(font->image.w*sizeof(unsigned));
779         memset(used_pixels, 0, font->image.w*sizeof(unsigned));
780         used_glyphs = (char *)malloc(font->n_glyphs);
781         memset(used_glyphs, 0, font->n_glyphs);
782
783         for(cy=margin; cy+margin<font->image.h;)
784         {
785                 unsigned w;
786                 unsigned x, y;
787                 Glyph *glyph = NULL;
788                 unsigned best_score = 0;
789                 unsigned target_h = 0;
790
791                 /* Find the leftmost free pixel on this row.  Also record the lowest
792                 extent of glyphs to the left of the free position. */
793                 for(; (cx+margin<font->image.w && used_pixels[cx]>cy); ++cx)
794                         if(used_pixels[cx]-cy-padding>target_h)
795                                 target_h = used_pixels[cx]-cy-padding;
796
797                 if(cx+margin>=font->image.w)
798                 {
799                         cx = margin;
800                         ++cy;
801                         continue;
802                 }
803
804                 /* Count the free pixel at this position. */
805                 for(w=0; (cx+w+margin<font->image.w && used_pixels[cx+w]<=cy); ++w) ;
806
807                 /* Find a suitable glyph to put here. */
808                 for(i=0; i<font->n_glyphs; ++i)
809                 {
810                         Glyph *g;
811
812                         g = &font->glyphs[i];
813                         if(!used_glyphs[i] && g->image.w<=w)
814                         {
815                                 unsigned score;
816
817                                 /* Prefer glyphs that would reach exactly as low as the ones left
818                                 of here.  This aims to create a straight edge at the bottom for
819                                 lining up further glyphs. */
820                                 score = g->image.h+padding;
821                                 if(g->image.h==target_h)
822                                         score *= g->image.w;
823                                 else
824                                         score += g->image.w;
825
826                                 if(score>best_score)
827                                 {
828                                         glyph = g;
829                                         best_score = score;
830                                 }
831                         }
832                 }
833
834                 if(!glyph)
835                 {
836                         cx += w;
837                         continue;
838                 }
839
840                 used_glyphs[glyph-font->glyphs] = 1;
841                 glyph->x = cx;
842                 glyph->y = cy;
843
844                 for(y=0; y<glyph->image.h; ++y) for(x=0; x<glyph->image.w; ++x)
845                 {
846                         if(cx+x>=font->image.w || cy+y>=font->image.h)
847                                 continue;
848                         font->image.data[cx+x+(cy+y)*font->image.w] = 255-glyph->image.data[x+y*glyph->image.w];
849                 }
850                 for(x=0; x<glyph->image.w+2*padding; ++x)
851                 {
852                         if(cx+x<padding || cx+x>=font->image.w+padding)
853                                 continue;
854                         if(used_pixels[cx+x-padding]<cy+glyph->image.h+padding)
855                                 used_pixels[cx+x-padding] = cy+glyph->image.h+padding;
856                 }
857
858                 if(cy+glyph->image.h+margin>used_h)
859                         used_h = cy+glyph->image.h+margin;
860         }
861
862         /* Trim the image to the actually used size, in case the original estimate
863         was too pessimistic. */
864         font->image.h = round_to_pot(used_h);
865
866         free(used_glyphs);
867         free(used_pixels);
868
869         return 0;
870 }
871
872 int save_defs(const char *fn, const Font *font)
873 {
874         FILE *out;
875         unsigned i;
876
877         out = fopen(fn, "w");
878         if(!out)
879         {
880                 fprintf(stderr, "Couldn't open %s\n",fn);
881                 return -1;
882         }
883
884         fprintf(out, "# Image/font info:\n");
885         fprintf(out, "# width height size ascent descent\n");
886         fprintf(out, "font %d %d %d %d %d\n", font->image.w, font->image.h, font->size, font->ascent, font->descent);
887         fprintf(out, "\n# Glyph info:\n");
888         fprintf(out, "# code x y width height offset_x offset_y advance\n");
889         for(i=0; i<font->n_glyphs; ++i)
890         {
891                 const Glyph *g = &font->glyphs[i];
892                 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);
893         }
894         fprintf(out, "\n# Kerning info:\n");
895         fprintf(out, "# left right distance\n");
896         for(i=0; i<font->n_kerning; ++i)
897         {
898                 const Kerning *k = &font->kerning[i];
899                 fprintf(out, "kern %u %u %d\n", k->left_code, k->right_code, k->distance);
900         }
901
902         fclose(out);
903
904         return 0;
905 }
906
907 int save_png(const char *fn, const Image *image, char alpha)
908 {
909         FILE *out;
910         png_struct *pngs;
911         png_info *pngi;
912         png_byte **rows;
913         unsigned i;
914         png_byte *data2 = 0;
915         int color;
916
917         if(!strcmp(fn, "-"))
918                 out = stdout;
919         else
920         {
921                 out = fopen(fn, "wb");
922                 if(!out)
923                 {
924                         fprintf(stderr, "Couldn't open %s\n",fn);
925                         return -1;
926                 }
927         }
928
929         pngs = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
930         if(!pngs)
931         {
932                 fprintf(stderr, "Error writing PNG file\n");
933                 return -1;
934         }
935         pngi = png_create_info_struct(pngs);
936         if(!pngi)
937         {
938                 png_destroy_write_struct(&pngs, NULL);
939                 fprintf(stderr, "Error writing PNG file\n");
940                 return -1;
941         }
942
943         png_init_io(pngs, out);
944         rows = (png_byte **)malloc(image->h*sizeof(png_byte *));
945         if(alpha)
946         {
947                 data2 = (png_byte *)alloc_image_data(image->w*2, image->h);
948                 if(!data2)
949                         return -1;
950                 for(i=0; i<image->w*image->h; ++i)
951                 {
952                         data2[i*2] = 255;
953                         data2[i*2+1] = 255-image->data[i];
954                 }
955                 for(i=0; i<image->h; ++i)
956                         rows[i] = (png_byte *)(data2+i*image->w*2);
957                 color = PNG_COLOR_TYPE_GRAY_ALPHA;
958         }
959         else
960         {
961                 for(i=0; i<image->h; ++i)
962                         rows[i] = (png_byte *)(image->data+i*image->w);
963                 color = PNG_COLOR_TYPE_GRAY;
964         }
965         png_set_IHDR(pngs, pngi, image->w, image->h, 8, color, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
966         png_set_rows(pngs, pngi, rows);
967         png_write_png(pngs, pngi, PNG_TRANSFORM_IDENTITY, NULL);
968         png_destroy_write_struct(&pngs, &pngi);
969         free(rows);
970         if(alpha)
971                 free(data2);
972
973         if(verbose)
974                 printf("Saved %dx%d PNG image to %s\n", image->w, image->h, fn);
975
976         fclose(out);
977
978         return 0;
979 }