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