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