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