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
dump_header(FT_Face face,char * foundry,int nchars,int pixel_size)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
dump_tailer()72 dump_tailer ()
73 {
74 printf ("ENDFONT\n");
75 }
76
77 void
dump_image(int pixel_size,int index,int code,int full)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
main(int argc,char ** argv)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 }
230