7 #include <X11/Intrinsic.h>
8 #include <X11/StringDefs.h>
10 #include <X11/Xaw/Box.h>
11 #include <X11/Xaw/Form.h>
12 #include <X11/Xaw/Command.h>
13 #include <X11/Xaw/Viewport.h>
16 #include FT_FREETYPE_H
20 #define DEFAULT_PIXEL_SIZE 30
21 #define DEFAULT_FONT_NAME "6x13"
23 #define FONT_HEIGHT (font->ascent + font->descent)
27 +---form----------------------------+
28 | +--- command_area --------------+ |
29 | | charmap ... quit| |
30 | | PREV prev label next NEXT | |
31 | +-------------------------------+ |
32 | +--- glyph_area ----------------+ |
36 | +-------------------------------+ |
37 | +--- render_area ---------------+ |
38 | | cmap: ... clear| |
41 | +-------------------------------+ |
42 +-----------------------------------+ */
43 Widget shell, form, command_area, glyph_area, render_area;
44 Widget PREV, prev, label, next, NEXT, *charmap, quit, glyph[128], clear;
46 unsigned char glyph_exist[0x10000];
47 Pixmap pixmap[0x10000];
60 unsigned glyph_width, glyph_height;
65 create_pixmap (int index, Display *display)
67 int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
74 ximage.height = face->glyph->bitmap.rows;
75 ximage.width = face->glyph->bitmap.width;
77 ximage.bits_per_pixel = 1;
79 ximage.format = XYPixmap;
80 ximage.data = (char *) face->glyph->bitmap.buffer;
81 ximage.byte_order = MSBFirst;
82 ximage.bitmap_unit = 8;
83 ximage.bitmap_bit_order = MSBFirst;
84 ximage.bitmap_pad = 8;
85 ximage.bytes_per_line = face->glyph->bitmap.pitch;
87 pixmap = XCreatePixmap (display, DefaultRootWindow (display),
88 glyph_width, glyph_height, 1);
89 gc = XCreateGC(display, pixmap, (unsigned long) 0, (XGCValues *) 0);
90 XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, glyph_height);
91 XPutImage (display, pixmap, gc, &ximage, 0, 0,
92 glyph_x + face->glyph->bitmap_left,
93 glyph_y - face->glyph->bitmap_top,
94 ximage.width, ximage.height);
95 XFreeGC (display, gc);
106 for (i = 0; i < 128; i++)
108 int index = glyph_index + i;
111 if (charmap_index >= 0)
112 index = FT_Get_Char_Index (face, (FT_ULong) index);
113 XtSetArg (arg[num_args], XtNbitmap, pixmap[index]), num_args++;
115 XtSetArg (arg[num_args], XtNlabel, "none"), num_args++;
116 XtSetValues (glyph[i], arg, num_args);
119 sprintf (buf, " %04X ", glyph_index);
120 XtSetArg (arg[0], XtNlabel, buf);
121 XtSetValues (label, arg, 1);
125 QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
127 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
131 ChangeProc (Widget w, XtPointer client_data, XtPointer call_data)
133 int old_glyph_index = glyph_index;
135 if ((int) client_data == -2 && glyph_index > 0)
136 glyph_index = (glyph_index - 1) & 0xF000;
137 else if ((int) client_data == -1 && glyph_index > 0)
139 else if ((int) client_data == 1 && glyph_index < 0xFF80)
141 else if ((int) client_data == 2 && glyph_index < 0xF000)
142 glyph_index = (glyph_index + 0x1000) & 0xF000;
143 if (glyph_index != old_glyph_index)
144 update_glyph_area ();
148 EncodingProc (Widget w, XtPointer client_data, XtPointer call_data)
150 if (charmap_index == (int) client_data)
152 charmap_index = (int) client_data;
153 if (charmap_index >= 0)
154 FT_Set_Charmap (face, face->charmaps[charmap_index]);
155 update_glyph_area ();
162 String PREV_action = "Shift<KeyPress>p: set() notify() unset()";
163 String prev_action = "~Shift<KeyPress>p: set() notify() unset()";
164 String next_action = "~Shift<KeyPress>n: set() notify() unset()";
165 String NEXT_action = "Shift<KeyPress>n: set() notify() unset()";
166 String quit_action = "<KeyPress>q: set() notify() unset()";
170 form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);
171 XtSetArg (arg[0], XtNborderWidth, 0);
172 command_area = XtCreateManagedWidget ("command-area", formWidgetClass,
174 XtSetArg (arg[0], XtNborderWidth, 1);
175 XtSetArg (arg[1], XtNfromVert, command_area);
176 XtSetArg (arg[2], XtNdefaultDistance, 0);
177 glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
179 XtSetArg (arg[0], XtNborderWidth, 0);
180 XtSetArg (arg[1], XtNfromVert, glyph_area);
181 render_area = XtCreateManagedWidget ("render", formWidgetClass,
184 charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
185 XtSetArg (arg[0], XtNleft, XawChainLeft);
186 XtSetArg (arg[1], XtNright, XawChainLeft);
187 XtSetArg (arg[2], XtNtop, XawChainTop);
188 XtSetArg (arg[3], XtNbottom, XawChainTop);
189 charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, commandWidgetClass,
190 command_area, arg, 4);
191 XtAddCallback (charmap[0], XtNcallback, EncodingProc, (XtPointer) -1);
192 for (i = 1; i <= face->num_charmaps; i++)
194 XtSetArg (arg[4], XtNfromHoriz, charmap[i - 1]);
195 charmap[i] = XtCreateManagedWidget (charmap_rec[i].name,
197 command_area, arg, 5);
198 XtAddCallback (charmap[i], XtNcallback, EncodingProc,
199 (XtPointer) (i - 1));
201 XtSetArg (arg[0], XtNleft, XawChainRight);
202 XtSetArg (arg[1], XtNright, XawChainRight);
203 XtSetArg (arg[4], XtNfromHoriz, charmap[i - 1]);
204 XtSetArg (arg[5], XtNaccelerators, XtParseAcceleratorTable (quit_action));
205 quit = XtCreateManagedWidget ("quit", commandWidgetClass,
206 command_area, arg, 6);
207 XtAddCallback (quit, XtNcallback, QuitProc, NULL);
209 XtSetArg (arg[4], XtNfromVert, charmap[0]);
210 XtSetArg (arg[5], XtNlabel, "<< (P)");
211 XtSetArg (arg[6], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
212 PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
213 command_area, arg, 7);
214 XtAddCallback (PREV, XtNcallback, ChangeProc, (XtPointer) -2);
215 XtSetArg (arg[5], XtNfromHoriz, PREV);
216 XtSetArg (arg[6], XtNlabel, "< (p)");
217 XtSetArg (arg[7], XtNaccelerators, XtParseAcceleratorTable (prev_action));
218 prev = XtCreateManagedWidget ("prev", commandWidgetClass,
219 command_area, arg, 8);
220 XtAddCallback (prev, XtNcallback, ChangeProc, (XtPointer) -1);
221 XtSetArg (arg[5], XtNfromHoriz, prev);
222 XtSetArg (arg[6], XtNlabel, " 0000 ");
223 label = XtCreateManagedWidget ("label", labelWidgetClass,
224 command_area, arg, 7);
225 XtSetArg (arg[5], XtNfromHoriz, label);
226 XtSetArg (arg[6], XtNlabel, "(n) >");
227 XtSetArg (arg[7], XtNaccelerators, XtParseAcceleratorTable (next_action));
228 next = XtCreateManagedWidget ("next", commandWidgetClass,
229 command_area, arg, 8);
230 XtAddCallback (next, XtNcallback, ChangeProc, (XtPointer) 1);
231 XtSetArg (arg[5], XtNfromHoriz, next);
232 XtSetArg (arg[6], XtNlabel, "(N) >>");
233 XtSetArg (arg[7], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
234 NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
235 command_area, arg, 8);
236 XtAddCallback (NEXT, XtNcallback, ChangeProc, (XtPointer) 2);
238 for (i = 0; i < 8; i++)
239 for (j = 0; j < 16; j++)
244 XtSetArg (arg[num_args], XtNwidth, glyph_width), num_args++;
245 XtSetArg (arg[num_args], XtNheight, glyph_height), num_args++;
247 XtSetArg (arg[num_args], XtNfromHoriz, glyph[k - 1]), num_args++;
249 XtSetArg (arg[num_args], XtNfromVert, glyph[k - 16]), num_args++;
250 glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
251 glyph_area, arg, num_args);
254 clear = XtCreateManagedWidget ("clear", commandWidgetClass,
255 render_area, NULL, 0);
257 XtInstallAllAccelerators (form, form);
260 /* Format MSG by FMT and print the result to the stderr, and exit. */
262 #define FATAL_ERROR(fmt, arg) \
264 fprintf (stderr, fmt, arg); \
269 main (int argc, char **argv)
276 OTF_GlyphString gstring;
281 int pixel_size = DEFAULT_PIXEL_SIZE;
283 gstring.size = gstring.used = 256;
284 g = calloc (256, sizeof (OTF_Glyph));
287 shell = XtOpenApplication (&context, "OTFView", NULL, 0, &argc, argv, NULL,
288 shellWidgetClass, NULL, 0);
289 display = XtDisplay (shell);
292 FATAL_ERROR ("%s\n", "Usage: otfview [ X-OPTION ... ] OTF-FILE");
294 if (strstr (argv[1], ".ttf")
295 || strstr (argv[1], ".TTF")
296 || strstr (argv[1], ".otf")
297 || strstr (argv[1], ".OTF"))
299 otf = OTF_open (argv[1]);
301 || OTF_get_table (otf, "head") < 0
302 || OTF_get_table (otf, "cmap") < 0)
306 if ((err = FT_Init_FreeType (&library)))
307 FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
308 err = FT_New_Face (library, argv[1], 0, &face);
309 if (err == FT_Err_Unknown_File_Format)
310 FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
312 FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
313 if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
314 FATAL_ERROR ("%s\n", "FT_Set_Char_Size: error");
316 glyph_width = ((face->bbox.xMax - face->bbox.xMin)
317 * pixel_size / face->units_per_EM);
318 glyph_height = ((face->bbox.yMax - face->bbox.yMin)
319 * pixel_size / face->units_per_EM);
320 glyph_x = - (face->bbox.xMin * pixel_size / face->units_per_EM);
321 glyph_y = face->bbox.yMax * pixel_size / face->units_per_EM;
323 charmap_rec[0].platform_id = -1;
324 charmap_rec[0].encoding_id = -1;
325 strcpy (charmap_rec[0].name, "bypass charmap");
327 for (i = 0; i < face->num_charmaps; i++)
329 charmap_rec[i + 1].platform_id = face->charmaps[i]->platform_id;
330 charmap_rec[i + 1].encoding_id = face->charmaps[i]->encoding_id;
331 sprintf (charmap_rec[i + 1].name, "%d-%d",
332 charmap_rec[i + 1].platform_id, charmap_rec[i + 1].encoding_id);
333 if (face->charmaps[i]->platform_id == 0
334 || (face->charmaps[i]->platform_id == 3
335 && face->charmaps[i]->encoding_id == 1))
336 strcat (charmap_rec[i + 1].name, " (unicode)");
337 else if (face->charmaps[i]->platform_id == 1
338 && face->charmaps[i]->encoding_id == 0)
339 strcat (charmap_rec[i + 1].name, " (apple-roman)");
342 for (i = 0; i < 0x10000; i++)
343 pixmap[i] = create_pixmap (i, display);
349 update_glyph_area ();
351 XtRealizeWidget (shell);
352 XtAppMainLoop (context);