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