(read_anchor_array): Do not read an anchor if its
[m17n/libotf.git] / example / otftobdf.c
1 /* otftobdf.c -- Generate BDF font from OpenType font.
2
3 Copyright (C) 2003, 2004
4   National Institute of Advanced Industrial Science and Technology (AIST)
5   Registration Number H15PRO167
6
7 This file is part of libotf.
8
9 Libotf is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 Libotf is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library, in a file named COPYING; if not,
21 write to the Free Software Foundation, Inc., 59 Temple Place, Suite
22 330, Boston, MA 02111-1307, USA.  */
23
24 #include <stdio.h>
25
26 #include <ft2build.h>
27 #include FT_FREETYPE_H
28
29 #include "config.h"
30 #ifdef HAVE_ALLOCA_H
31 #include <alloca.h>
32 #endif
33
34 #define DEFAULT_PIXEL_SIZE 16
35
36 FT_Face face;
37
38 /* Format MSG by FMT and print the result to the stderr, and exit.  */
39
40 #define FATAL_ERROR(fmt, arg)   \
41   do {                          \
42     fprintf (stderr, fmt, arg); \
43     exit (1);                   \
44   } while (0)
45
46 char *registry;
47
48 void
49 dump_header (FT_Face face, char *foundry, int nchars, int pixel_size)
50 {
51   int width = ((face->bbox.xMax - face->bbox.xMin)
52                * pixel_size / face->units_per_EM);
53   int height = ((face->bbox.yMax - face->bbox.yMin)
54                 * pixel_size / face->units_per_EM);
55   int x = face->bbox.xMin * pixel_size / face->units_per_EM;
56   int y = face->bbox.yMin * pixel_size / face->units_per_EM;
57
58   printf ("STARTFONT 2.1\n");
59   printf ("FONT -%s-%s-%s-R-Normal--%d-%d-72-72-C-%d-%s\n",
60           foundry, face->family_name, face->style_name,
61           pixel_size, pixel_size * 10, pixel_size * 10, registry);
62   printf ("SIZE %d 72 72\n", pixel_size);
63   printf ("FONTBOUNDINGBOX %d %d %d %d\n", width, height, x, y);
64   printf ("STARTPROPERTIES 2\n");
65   printf ("FONT_ASCENT %d\n", y + height);
66   printf ("FONT_DESCENT %d\n", -y);
67   printf ("ENDPROPERTIES 0\n");
68   printf ("CHARS %d\n", nchars);
69 }
70
71 void
72 dump_tailer ()
73 {
74   printf ("ENDFONT\n");
75 }
76
77 void
78 dump_image (int pixel_size, int index, int code, int full)
79 {
80   int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
81   int i,j;
82   unsigned char *buf;
83   FT_GlyphSlot glyph;
84   int dwidth, x, y;
85
86   if (err)
87     return;
88   glyph = face->glyph;
89   if (glyph->bitmap.rows * glyph->bitmap.width == 0)
90     return;
91   printf ("STARTCHAR U+%04X\n", code);
92   printf ("ENCODING %d\n", code);
93   printf ("SWIDTH %d 0\n",
94           (int) (glyph->metrics.horiAdvance >> 6) * 1000 / pixel_size);
95   if (full)
96     {
97       dwidth = glyph->bitmap.width;
98       x = 0;
99     }
100   else
101     {
102       dwidth = glyph->metrics.horiAdvance >> 6;
103       x = glyph->metrics.horiBearingX >> 6;
104     }
105   y = (glyph->metrics.horiBearingY - glyph->metrics.height) >> 6;
106   printf ("DWIDTH %d 0\n", dwidth);
107   printf ("BBX %d %d %d %d\n", glyph->bitmap.width, glyph->bitmap.rows, x, y);
108   printf ("BITMAP\n");
109   buf = (unsigned char *) glyph->bitmap.buffer;
110   for (i = 0; i < glyph->bitmap.rows; i++)
111     {
112       for (j = 0; j < (glyph->bitmap.width + 7) / 8; j++)
113         printf ("%02X", buf[i * glyph->bitmap.pitch + j]);
114       printf ("\n");
115     }
116   printf ("ENDCHAR\n");
117 }
118
119
120 int
121 main (int argc, char **argv)
122 {
123   FT_Library library;
124   int err;
125   int i;
126   int pixel_size = DEFAULT_PIXEL_SIZE;
127   FT_UInt code_table[0x10000];
128   int nchars;
129   char *filename;
130   int platform_id, encoding_id;
131
132   if (argc <= 1)
133     FATAL_ERROR ("Usage: %s ENCODING OTF-FILE\n", argv[0]);
134   if (sscanf (argv[1], "%d-%d", &platform_id, &encoding_id) != 2)
135     {
136       platform_id = -1;
137       filename = argv[1];
138     }
139   else
140     filename = argv[2];
141
142   if ((err = FT_Init_FreeType (&library)))
143     FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
144   err = FT_New_Face (library, filename, 0, &face);
145   if (err == FT_Err_Unknown_File_Format)
146     FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
147   else if (err)
148     FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
149   if (platform_id >= 0)
150     {
151       for (i = 0; i < face->num_charmaps; i++)
152         if (face->charmaps[i]->platform_id == platform_id
153             && face->charmaps[i]->encoding_id == encoding_id)
154           break;
155       if (i == face->num_charmaps)
156         FATAL_ERROR ("Unknown ENCODING: %s\n", argv[1]);
157       FT_Set_Charmap (face, face->charmaps[i]);
158       if (platform_id == 0)
159         {
160           if (encoding_id == 3)
161             registry = "iso10646-1";
162           else if (face->charmaps[i]->encoding_id == 4)
163             registry = "iso10646-full";
164         }
165       else if (face->charmaps[i]->platform_id == 3)
166         {
167           if (face->charmaps[i]->encoding_id == 1)
168             registry = "iso10646-1";
169           else if (face->charmaps[i]->encoding_id == 10)
170             registry = "iso10646-full";
171         }
172       else
173         {
174           registry = alloca (256);
175           sprintf (registry, "%d-%d", platform_id, encoding_id);
176         }
177     }
178   else
179     {
180       registry = "raw-glyph";
181     }
182
183   {
184     char *str = getenv ("PIXEL_SIZE");
185
186     if (str && (i = atoi (str)) > 0)
187       pixel_size = i;
188   }
189
190   if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
191     FATAL_ERROR ("%s\n", "FT_Set_Pixel_Sizes: error");
192
193   /*
194   for (i = nchars = 0; i < 0x10000; i++)
195     if (! FT_Load_Glyph (face, i, FT_LOAD_RENDER | FT_LOAD_MONOCHROME)
196         && face->glyph->bitmap.rows * face->glyph->bitmap.width)
197       nchars++;
198   */
199   for (i = 0; i < 0x10000; i++)
200     {
201       if (platform_id >= 0)
202         {
203           code_table[i] = FT_Get_Char_Index (face, (FT_ULong) i);
204           if (! code_table[i])
205             {
206               code_table[i] = -1;
207               continue;
208             }
209         }
210       else
211         {
212           code_table[i] = i;
213         }
214       if (! FT_Load_Glyph (face, code_table[i],
215                            FT_LOAD_RENDER | FT_LOAD_MONOCHROME)
216           && face->glyph->bitmap.rows * face->glyph->bitmap.width)
217         nchars++;
218       else
219         code_table[i] = -1;
220     }
221
222   dump_header (face, "unknown", nchars, pixel_size);
223   for (i = 0; i < 0x10000; i++)
224     if (code_table[i] >= 0)
225       dump_image (pixel_size, code_table[i], i, 0);
226   dump_tailer ();
227
228   exit (0);
229 }