*** empty log message ***
[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 #define DEFAULT_PIXEL_SIZE 16
30
31 FT_Face face;
32
33 /* Format MSG by FMT and print the result to the stderr, and exit.  */
34
35 #define FATAL_ERROR(fmt, arg)   \
36   do {                          \
37     fprintf (stderr, fmt, arg); \
38     exit (1);                   \
39   } while (0)
40
41 char *registry;
42
43 void
44 dump_header (FT_Face face, char *foundry, int nchars, int pixel_size)
45 {
46   int width = ((face->bbox.xMax - face->bbox.xMin)
47                * pixel_size / face->units_per_EM);
48   int height = ((face->bbox.yMax - face->bbox.yMin)
49                 * pixel_size / face->units_per_EM);
50   int x = face->bbox.xMin * pixel_size / face->units_per_EM;
51   int y = face->bbox.yMin * pixel_size / face->units_per_EM;
52
53   printf ("STARTFONT 2.1\n");
54   printf ("FONT -%s-%s-%s-R-Normal--%d-%d-72-72-C-%d-%s\n",
55           foundry, face->family_name, face->style_name,
56           pixel_size, pixel_size * 10, pixel_size * 10, registry);
57   printf ("SIZE %d 72 72\n", pixel_size);
58   printf ("FONTBOUNDINGBOX %d %d %d %d\n", width, height, x, y);
59   printf ("STARTPROPERTIES 2\n");
60   printf ("FONT_ASCENT %d\n", y + height);
61   printf ("FONT_DESCENT %d\n", -y);
62   printf ("ENDPROPERTIES 0\n");
63   printf ("CHARS %d\n", nchars);
64 }
65
66 void
67 dump_tailer ()
68 {
69   printf ("ENDFONT\n");
70 }
71
72 void
73 dump_image (int pixel_size, int index, int code, int full)
74 {
75   int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
76   int i,j;
77   unsigned char *buf;
78   FT_GlyphSlot glyph;
79   int dwidth, x, y;
80   
81   if (err)
82     return;
83   glyph = face->glyph;
84   if (glyph->bitmap.rows * glyph->bitmap.width == 0)
85     return;
86   printf ("STARTCHAR U+%04X\n", code);
87   printf ("ENCODING %d\n", code);
88   printf ("SWIDTH %d 0\n",
89           (int) (glyph->metrics.horiAdvance >> 6) * 1000 / pixel_size);
90   if (full)
91     {
92       dwidth = glyph->bitmap.width;
93       x = 0;
94     }
95   else
96     {
97       dwidth = glyph->metrics.horiAdvance >> 6;
98       x = glyph->metrics.horiBearingX >> 6;
99     }
100   y = (glyph->metrics.horiBearingY - glyph->metrics.height) >> 6;
101   printf ("DWIDTH %d 0\n", dwidth);
102   printf ("BBX %d %d %d %d\n", glyph->bitmap.width, glyph->bitmap.rows, x, y);
103   printf ("BITMAP\n");
104   buf = (unsigned char *) glyph->bitmap.buffer;
105   for (i = 0; i < glyph->bitmap.rows; i++)
106     {
107       for (j = 0; j < (glyph->bitmap.width + 7) / 8; j++)
108         printf ("%02X", buf[i * glyph->bitmap.pitch + j]);
109       printf ("\n");
110     }
111   printf ("ENDCHAR\n");
112 }
113
114
115 int
116 main (int argc, char **argv)
117 {
118   FT_Library library;
119   int err;
120   int i;
121   int pixel_size = DEFAULT_PIXEL_SIZE;
122   FT_UInt code_table[0x10000];
123   int nchars;
124   char *filename;
125   int platform_id, encoding_id;
126
127   if (argc < 1)
128     FATAL_ERROR ("Usage: %s ENCODING OTF-FILE\n", argv[0]);
129   if (sscanf (argv[1], "%d-%d", &platform_id, &encoding_id) != 2)
130     {
131       platform_id = -1;
132       filename = argv[1];
133     }
134   else
135     filename = argv[2];
136   
137   if ((err = FT_Init_FreeType (&library)))
138     FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
139   err = FT_New_Face (library, filename, 0, &face);
140   if (err == FT_Err_Unknown_File_Format)
141     FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
142   else if (err)
143     FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
144   if (platform_id >= 0)
145     {
146       for (i = 0; i < face->num_charmaps; i++)
147         if (face->charmaps[i]->platform_id == platform_id
148             && face->charmaps[i]->encoding_id == encoding_id)
149           break;
150       if (i == face->num_charmaps)
151         FATAL_ERROR ("Unknown ENCODING: %s\n", argv[1]);
152       FT_Set_Charmap (face, face->charmaps[i]);
153       if (platform_id == 0)
154         {
155           if (encoding_id == 3)
156             registry = "iso10646-1";
157           else if (face->charmaps[i]->encoding_id == 4)
158             registry = "iso10646-full";
159         }
160       else if (face->charmaps[i]->platform_id == 3)
161         {
162           if (face->charmaps[i]->encoding_id == 1)
163             registry = "iso10646-1";
164           else if (face->charmaps[i]->encoding_id == 10)
165             registry = "iso10646-full";
166         }
167       else
168         {
169           registry = alloca (256);
170           sprintf (registry, "%d-%d", platform_id, encoding_id);
171         }
172     }
173   else
174     {
175       registry = "raw-glyph";
176     }
177
178   {
179     char *str = getenv ("PIXEL_SIZE");
180
181     if (str && (i = atoi (str)) > 0)
182       pixel_size = i;
183   }
184
185   if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
186     FATAL_ERROR ("%s\n", "FT_Set_Pixel_Sizes: error");
187
188   /*
189   for (i = nchars = 0; i < 0x10000; i++)
190     if (! FT_Load_Glyph (face, i, FT_LOAD_RENDER | FT_LOAD_MONOCHROME)
191         && face->glyph->bitmap.rows * face->glyph->bitmap.width)
192       nchars++;
193   */
194   for (i = 0; i < 0x10000; i++)
195     {
196       if (platform_id >= 0)
197         {
198           code_table[i] = FT_Get_Char_Index (face, (FT_ULong) i);
199           if (! code_table[i])
200             {
201               code_table[i] = -1;
202               continue;
203             }
204         }
205       else
206         {
207           code_table[i] = i;
208         }
209       if (! FT_Load_Glyph (face, code_table[i],
210                            FT_LOAD_RENDER | FT_LOAD_MONOCHROME)
211           && face->glyph->bitmap.rows * face->glyph->bitmap.width)
212         nchars++;
213       else
214         code_table[i] = -1;
215     }
216
217   dump_header (face, "unknown", nchars, pixel_size);
218   for (i = 0; i < 0x10000; i++)
219     if (code_table[i] >= 0)
220       dump_image (pixel_size, code_table[i], i, 0);
221   dump_tailer ();
222
223   exit (0);
224 }