1 /* otfview.c -- View glyphs of OpenType fonts.
3 Copyright (C) 2003, 2004, 2005
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H15PRO167
7 This file is part of libotf.
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.
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.
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. */
33 #ifdef HAVE_X11_XAW_COMMAND_H
35 #include <X11/Xatom.h>
36 #include <X11/Intrinsic.h>
37 #include <X11/StringDefs.h>
38 #include <X11/Shell.h>
39 #include <X11/Xaw/Command.h>
40 #include <X11/Xaw/Toggle.h>
41 #include <X11/Xaw/Box.h>
42 #include <X11/Xaw/Form.h>
43 #include <X11/Xaw/Viewport.h>
46 #include FT_FREETYPE_H
50 #define DEFAULT_PIXEL_SIZE 30
53 #define DEFAULT_FONT_NAME "6x13"
55 #define FONT_HEIGHT (font->ascent + font->descent)
56 #define FONT_ASCENT (font->ascent)
57 #define FONT_DESCENT (font->descent)
58 #define FONT_WIDTH (font->max_bounds.width)
62 +--- frame (form) -------------------------+
63 | +--- command_area (box) ---------------+ |
64 | | quit dump charmap ... | |
65 | +--------------------------------------+ |
66 | +---- navi_area (box) -----------------+ |
67 | | FIRST PREV prev range next NEXT LAST | |
68 | +--------------------------------------+ |
69 | +--- glyph_area (form) ----------------+ |
70 | | idxh[0] glyph[0] ... glyph[15] | |
72 | | idxh[7] glyph[112] ... glyph[127]| |
73 | | idxl[0] ... idxl[15] | |
74 | +--------------------------------------+ |
75 | +--- render_area (form) ---------------+ |
76 | | clear del bidi alt_subst | |
77 | | +--- raw (box) --------------------+ | |
78 | | | raw_label raw_image | | |
79 | | +----------------------------------+ | |
80 | | GSUB all none features... | |
81 | | GPOS all none features... | |
82 | | +--- seq (box) --------------------+ | |
83 | | | seq_label seq_image | | |
84 | | +----------------------------------+ | |
85 | +--------------------------------------+ |
86 +------------------------------------------+ */
88 Widget command_area, quit, dump, *charmap;
89 Widget navi_area, FIRST, PREV, prev, range, next, NEXT, LAST;
90 Widget glyph_area, glyph[128], index_label[8];
91 Widget render_area, clear, del, bidi, alt_subst, raw, seq;
92 Widget raw_label, raw_image, seq_label, seq_image;
93 unsigned long foreground, background;
105 OTF_GSUB_GPOS *gsub_gpos;
106 OTF_LangSys *langsys;
108 FeatureElement *features;
112 FeatureRec gsub, gpos;
114 /* Currently selected script and langsys. */
115 OTF_Tag script_tag, langsys_tag;
120 GC gc, gc_set, gc_or, gc_inv;
124 unsigned width, height;
129 BitmapRec bitmap[0x10000];
131 int render_width, render_height;
132 Pixmap raw_pixmap, seq_pixmap, gsub_pixmap, gpos_pixmap;
146 int do_alternate_subst;
147 unsigned glyph_width, glyph_height;
148 int glyph_x, glyph_y;
161 create_pixmap (int index)
163 int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
169 bitmap[index].pixmap = none_pixmap;
172 ximage.height = face->glyph->bitmap.rows;
173 ximage.width = face->glyph->bitmap.width;
175 ximage.bits_per_pixel = 1;
177 ximage.format = XYPixmap;
178 ximage.data = (char *) face->glyph->bitmap.buffer;
179 ximage.byte_order = MSBFirst;
180 ximage.bitmap_unit = 8;
181 ximage.bitmap_bit_order = MSBFirst;
182 ximage.bitmap_pad = 8;
183 ximage.bytes_per_line = face->glyph->bitmap.pitch;
184 XInitImage (&ximage);
185 pixmap = XCreatePixmap (display, DefaultRootWindow (display),
186 glyph_width, glyph_height, 1);
187 XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, glyph_height);
188 XPutImage (display, pixmap, gc, &ximage, 0, 0,
189 glyph_x + face->glyph->bitmap_left,
190 glyph_y - face->glyph->bitmap_top,
191 ximage.width, ximage.height);
192 bitmap[index].pixmap = pixmap;
193 bitmap[index].width = ximage.width;
194 bitmap[index].height = ximage.height;
195 bitmap[index].x = face->glyph->bitmap_left;
196 bitmap[index].y = - face->glyph->bitmap_top;
197 bitmap[index].advance = face->glyph->metrics.horiAdvance >> 6;
208 for (i = 0; i < 128; i++)
210 int index = glyph_index + i;
212 if (charmap_index >= 0)
213 index = FT_Get_Char_Index (face, (FT_ULong) index);
215 XtSetArg (arg[0], XtNbitmap, none_pixmap);
218 if (! bitmap[index].pixmap)
219 create_pixmap (index);
220 XtSetArg (arg[0], XtNbitmap, bitmap[index].pixmap);
222 XtSetValues (glyph[i], arg, 1);
225 msb = (glyph_index >> 7) % 2 ? 8 : 0;
226 for (i = 0; i < 8; i++)
230 sprintf (str, "%XX", i | msb );
231 XtSetArg (arg[0], XtNheight, glyph_height + 5);
232 XtSetArg (arg[1], XtNlabel, str);
233 XtSetValues (index_label[i], arg, 2);
236 sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
237 XtSetArg (arg[0], XtNlabel, buf);
238 XtSetValues (range, arg, 1);
242 get_features (OTF_FeatureList *list, FeatureRec *rec)
247 if (! rec->langsys || ! rec->features || ! rec->features[0].on)
249 for (i = n = 0; i < rec->langsys->FeatureCount; i++)
251 if (rec->features[i].on)
256 str = malloc (n * 5);
257 for (i = 0, p = str; i < n; i++, p += 5)
259 OTF_tag_name (rec->features[i].tag, p);
267 #define DEVICE_DELTA(table, size) \
268 (((size) >= (table).StartSize && (size) <= (table).EndSize) \
269 ? (table).DeltaValue[(size) >= (table).StartSize] \
273 adjust_anchor (OTF_Anchor *anchor, FT_Face ft_face,
274 OTF_Glyph *g, int *x, int *y)
276 if (anchor->AnchorFormat == 2)
279 int ap = anchor->f.f1.AnchorPoint;
281 FT_Load_Glyph (ft_face, (FT_UInt) g->glyph_id, FT_LOAD_MONOCHROME);
282 outline = &ft_face->glyph->outline;
283 if (ap < outline->n_points)
285 *x = outline->points[ap].x;
286 *y = outline->points[ap].y;
289 else if (anchor->AnchorFormat == 3)
291 *x += DEVICE_DELTA (anchor->f.f2.XDeviceTable, pixel_size);
292 *y += DEVICE_DELTA (anchor->f.f2.YDeviceTable, pixel_size);
300 OTF_GlyphString gstring;
301 OTF_Glyph *g, *prev, *base, *mark;
303 int len = glyph_rec.n_glyphs;
305 int unitsPerEm = face->units_per_EM;
307 gstring.size = gstring.used = len;
308 gstring.glyphs = malloc (sizeof (OTF_Glyph) * len);
309 memset (gstring.glyphs, 0, sizeof (OTF_Glyph) * len);
310 for (i = 0; i < len; i++)
311 gstring.glyphs[i].c = gstring.glyphs[i].glyph_id = glyph_rec.glyphs[i];
313 XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
314 XDrawLine (display, seq_pixmap, gc_set, 0, glyph_y, render_width, glyph_y);
319 OTF_drive_gdef (otf, &gstring);
322 str = get_features (&otf->gsub->FeatureList, &gsub);
325 if (do_alternate_subst)
326 OTF_drive_gsub_alternate (otf, &gstring, NULL, NULL, str);
328 OTF_drive_gsub (otf, &gstring, NULL, NULL, str);
334 str = get_features (&otf->gpos->FeatureList, &gpos);
337 OTF_drive_gpos (otf, &gstring, NULL, NULL, str);
348 for (prev = gstring.glyphs, g = gstring.glyphs + gstring.used - 1;
349 prev < g; prev++, g--)
350 temp = *prev, *prev = *g, *g = temp;
351 for (g = gstring.glyphs; g < gstring.glyphs + gstring.used; g++)
352 if (g->GlyphClass == 3)
356 while (g < gstring.glyphs + gstring.used && g->GlyphClass == 3)
358 for (g0 = g; prev < g0; prev++, g0--)
359 temp = *prev, *prev = *g, *g = temp;
365 for (i = 0, x = glyph_x, prev = NULL, g = gstring.glyphs;
366 i < gstring.used; i++, prev = g++)
368 BitmapRec *bmp = bitmap + gstring.glyphs[i].glyph_id;
369 int xoff = 0, yoff = 0;
371 int advance = bmp->advance;
375 create_pixmap (gstring.glyphs[i].glyph_id);
378 advance = bmp->advance;
380 switch (g->positioning_type)
387 int format = g->f.f1.format;
389 if (format & OTF_XPlacement)
390 xoff = g->f.f1.value->XPlacement * pixel_size / unitsPerEm;
391 if (format & OTF_XPlaDevice)
392 xoff += DEVICE_DELTA (g->f.f1.value->XPlaDevice, pixel_size);
393 if (format & OTF_YPlacement)
394 yoff = g->f.f1.value->YPlacement * pixel_size / unitsPerEm;
395 if (format & OTF_YPlaDevice)
396 yoff += DEVICE_DELTA (g->f.f1.value->YPlaDevice, pixel_size);
397 if (format & OTF_XAdvance)
398 advance += g->f.f1.value->XAdvance * pixel_size / unitsPerEm;
399 if (format & OTF_XAdvDevice)
400 advance += DEVICE_DELTA (g->f.f1.value->XAdvDevice, pixel_size);
405 /* Not yet supported. */
411 prev_width = base_width;
412 goto label_adjust_anchor;
413 default: /* i.e. case 6 */
420 int base_x, base_y, mark_x, mark_y;
422 base_x = g->f.f4.base_anchor->XCoordinate * pixel_size / unitsPerEm;
423 base_y = g->f.f4.base_anchor->YCoordinate * pixel_size / unitsPerEm;
424 mark_x = g->f.f4.mark_anchor->XCoordinate * pixel_size / unitsPerEm;
425 mark_y = g->f.f4.mark_anchor->YCoordinate * pixel_size / unitsPerEm;
427 if (g->f.f4.base_anchor->AnchorFormat != 1)
428 adjust_anchor (g->f.f4.base_anchor, face, prev, &base_x, &base_y);
429 if (g->f.f4.mark_anchor->AnchorFormat != 1)
430 adjust_anchor (g->f.f4.mark_anchor, face, g, &mark_x, &mark_y);
431 xoff = (base_x - prev_width) - mark_x;
432 yoff = base_y - mark_y;
436 XCopyArea (display, bmp->pixmap, seq_pixmap, gc_or,
437 glyph_x + bmp->x, glyph_y + bmp->y, bmp->width, bmp->height,
438 x + bmp->x + xoff, glyph_y + bmp->y - yoff);
441 if (g->GlyphClass == OTF_GlyphClass0)
442 base = mark = g, base_width = advance;
443 else if (g->GlyphClass == OTF_GlyphClassMark)
446 base = g, base_width = advance;
448 free (gstring.glyphs);
450 XtSetArg (arg[0], XtNbitmap, seq_pixmap);
451 XtSetValues (seq_image, arg, 1);
456 update_render_area ()
462 XFillRectangle (display, raw_pixmap, gc, 0, 0, render_width, render_height);
463 for (i = 0, x = glyph_x; i < glyph_rec.n_glyphs; i++)
465 BitmapRec *bmp = bitmap + glyph_rec.glyphs[i];
468 XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
469 0, 0, glyph_width, glyph_height,
470 (glyph_width + 4) * i + 1, 1);
471 XDrawRectangle (display, raw_pixmap, gc_set,
472 (glyph_width + 4) * i, 0,
473 glyph_width + 1, glyph_height + 1);
474 XDrawLine (display, raw_pixmap, gc_set,
475 (glyph_width + 4) * i + 1 + glyph_x, 1,
476 (glyph_width + 4) * i + 1 + glyph_x, glyph_height + 1);
477 XDrawLine (display, raw_pixmap, gc_set,
478 (glyph_width + 4) * i + 1 + glyph_x + bmp->advance, 1,
479 (glyph_width + 4) * i + 1 + glyph_x + bmp->advance,
482 sprintf (buf, "%04X", glyph_rec.codes[i]);
483 XDrawString (display, raw_pixmap, gc_inv,
484 (glyph_width + 1) * i + 1
485 + (glyph_width - XTextWidth (font, buf, 4)) / 2,
486 glyph_height + 2 + FONT_HEIGHT, buf, 4);
488 XtSetArg (arg[0], XtNbitmap, raw_pixmap);
489 XtSetValues (raw_image, arg, 1);
494 QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
496 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
500 DumpProc (Widget w, XtPointer client_data, XtPointer call_data)
502 int g_width, g_height, g_x, g_y, pix_width, pix_height;
503 int margin = 20 * 300 / 25.4;
504 int a4_width = 210 * 300 / 25.4 - margin * 2;
505 int a4_height = 297 * 300 / 25.4 - margin * 2;
508 XImage ximage, *image;
513 FT_Set_Pixel_Sizes (face, 0, size);
514 g_width = ((face->bbox.xMax - face->bbox.xMin) * size / face->units_per_EM);
515 g_height = ((face->bbox.yMax - face->bbox.yMin) * size / face->units_per_EM);
516 pix_width = (g_width + 1) * 16 + margin + 1;
517 pix_height = (g_height + 1 + FONT_HEIGHT) * 16 + margin + 1;
518 while (pix_width > a4_width || pix_height > a4_height)
521 FT_Set_Pixel_Sizes (face, 0, size);
522 g_width = ((face->bbox.xMax - face->bbox.xMin)
523 * size / face->units_per_EM);
524 g_height = ((face->bbox.yMax - face->bbox.yMin)
525 * size / face->units_per_EM);
526 pix_width = (g_width + 1) * 16 + margin + 1;
527 pix_height = (g_height + 1 + FONT_HEIGHT) * 16 + margin + 1;
530 g_x = - (face->bbox.xMin * size / face->units_per_EM);
531 g_y = face->bbox.yMax * size / face->units_per_EM;
532 for (i = 0; i < 0xFF; i++)
536 if (charmap_index >= 0)
537 idx = FT_Get_Char_Index (face, (FT_ULong) i);
540 if (FT_Load_Glyph (face, idx, FT_LOAD_RENDER | FT_LOAD_MONOCHROME) == 0)
542 if (g_x < - face->glyph->bitmap_left)
543 g_x = - face->glyph->bitmap_left;
544 if (g_y < face->glyph->bitmap_top)
545 g_y = face->glyph->bitmap_top;
547 < g_x + face->glyph->bitmap_left + face->glyph->bitmap.width)
549 = g_x + face->glyph->bitmap_left + face->glyph->bitmap.width;
551 < g_y - face->glyph->bitmap_top + face->glyph->bitmap.rows)
553 = g_y - face->glyph->bitmap_top + face->glyph->bitmap.rows;
556 pix_width = (g_width + 1) * 16 + margin + 1;
557 pix_height = (g_height + FONT_HEIGHT + 1) * 16 + margin + 1;
558 pixmap = XCreatePixmap (display,
559 RootWindow (display, DefaultScreen (display)),
560 pix_width, pix_height, 1);
561 XFillRectangle (display, pixmap, gc, 0, 0, pix_width, pix_height);
563 for (i = 0, x = margin; i <= 16; i++, x += g_width + 1)
564 XDrawLine (display, pixmap, gc_set, x, margin,
565 x, margin + (g_height + FONT_HEIGHT + 1) * 16);
566 for (i = 0, y = margin; i <= 16; i++, y += g_height + FONT_HEIGHT + 1)
567 XDrawLine (display, pixmap, gc_set, margin, y,
568 margin + (g_width + 1) * 16, y);
569 for (i = 0; i < 256; i++)
574 if (charmap_index >= 0)
575 idx = FT_Get_Char_Index (face, (FT_ULong) i);
578 x = margin + (g_width + 1) * (i % 16);
579 y = margin + (g_height + FONT_HEIGHT + 1) * (i / 16);
580 if (FT_Load_Glyph (face, idx, FT_LOAD_RENDER | FT_LOAD_MONOCHROME) == 0)
582 ximage.height = face->glyph->bitmap.rows;
583 ximage.width = face->glyph->bitmap.width;
585 ximage.bits_per_pixel = 1;
587 ximage.format = XYPixmap;
588 ximage.data = (char *) face->glyph->bitmap.buffer;
589 ximage.byte_order = MSBFirst;
590 ximage.bitmap_unit = 8;
591 ximage.bitmap_bit_order = MSBFirst;
592 ximage.bitmap_pad = 8;
593 ximage.bytes_per_line = face->glyph->bitmap.pitch;
594 XInitImage (&ximage);
595 XPutImage (display, pixmap, gc, &ximage, 0, 0,
596 x + g_x + face->glyph->bitmap_left,
597 y + g_y - face->glyph->bitmap_top,
598 ximage.width, ximage.height);
600 sprintf (str, "0x%02X", i);
601 XDrawString (display, pixmap, gc_inv,
602 x + (g_width - XTextWidth (font, str, 4))/ 2,
603 y + g_height + FONT_ASCENT, str, 4);
606 image = XGetImage (display, pixmap, 0, 0, pix_width, pix_height,
607 AllPlanes, XYPixmap);
610 char *name = alloca (strlen (filename) + 5);
613 sprintf (name, "%s.pbm", filename);
614 printf ("Writing %s ...", name);
615 fp = fopen (name, "w");
616 fprintf (fp, "P4\n%d %d\n", image->width, image->height);
617 bytes_per_line = (image->width + 7) / 8;
619 for (y = 0; y < image->height; y++, data += image->bytes_per_line)
620 fwrite (data, 1, bytes_per_line, fp);
624 FT_Set_Pixel_Sizes (face, 0, (int) pixel_size);
629 GlyphProc (Widget w, XtPointer client_data, XtPointer call_data)
631 int old_glyph_index = glyph_index;
633 if ((int) client_data == -3 && glyph_index > 0)
635 else if ((int) client_data == -2 && glyph_index > 0)
636 glyph_index = (glyph_index - 1) & 0xF000;
637 else if ((int) client_data == -1 && glyph_index > 0)
639 else if ((int) client_data == 1 && glyph_index < 0xFF80)
641 else if ((int) client_data == 2 && glyph_index < 0xF000)
642 glyph_index = (glyph_index + 0x1000) & 0xF000;
643 else if ((int) client_data == 3 && glyph_index < 0xF000)
644 glyph_index = 0xFF80;
645 if (glyph_index != old_glyph_index)
646 update_glyph_area ();
650 CharmapProc (Widget w, XtPointer client_data, XtPointer call_data)
652 if (charmap_index == (int) client_data)
654 charmap_index = (int) client_data;
655 if (charmap_index >= 0)
656 FT_Set_Charmap (face, face->charmaps[charmap_index]);
657 update_glyph_area ();
661 RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
663 if ((int) client_data < 0)
665 if (glyph_rec.n_glyphs > 0)
667 if ((int) client_data == -2)
668 glyph_rec.n_glyphs--;
670 glyph_rec.n_glyphs = 0;
671 update_render_area ();
674 else if (glyph_rec.n_glyphs < 64)
676 int index = glyph_index + (int) client_data;
678 if (charmap_index >= 0)
679 index = FT_Get_Char_Index (face, (FT_ULong) index);
680 if (bitmap[index].pixmap)
682 glyph_rec.codes[glyph_rec.n_glyphs] = glyph_index + (int) client_data;
683 glyph_rec.glyphs[glyph_rec.n_glyphs++] = index;
684 update_render_area ();
690 BidiProc (Widget w, XtPointer client_data, XtPointer call_data)
694 reversed = ! reversed;
696 XtSetArg (arg[0], XtNlabel, "L<-R");
698 XtSetArg (arg[0], XtNlabel, "L->R");
699 XtSetValues (w, arg, 1);
704 AltSubstProc (Widget w, XtPointer client_data, XtPointer call_data)
706 do_alternate_subst = ! do_alternate_subst;
711 FeatureProc (Widget w, XtPointer client_data, XtPointer call_data)
713 FeatureRec *rec = (FeatureRec *) client_data;
720 XtSetArg (arg[0], XtNlabel, &label);
721 XtGetValues (w, arg, 1);
722 if (! strcmp (label, "all"))
724 else if (! strcmp (label, "none"))
728 for (idx = 0; idx < rec->langsys->FeatureCount; idx++)
729 if (rec->features[idx].w == w)
731 if (idx == rec->langsys->FeatureCount)
738 for (i = j = 0; j < rec->langsys->FeatureCount; j++)
740 int index = rec->langsys->FeatureIndex[j];
743 = rec->gsub_gpos->FeatureList.Feature[index].FeatureTag;
744 rec->features[j].on = on;
749 OTF_Tag tag = rec->features[idx].tag;
752 if (rec->features[i].on)
755 j < rec->langsys->FeatureCount && rec->features[j].on; j++)
756 rec->features[j - 1].tag = rec->features[j].tag;
757 rec->features[j - 1].tag = tag;
758 rec->features[j - 1].on = 0;
762 for (j = i + 1; i > 0 && ! rec->features[i - 1].on; i--)
763 rec->features[i].tag = rec->features[i - 1].tag;
764 rec->features[i].tag = tag;
765 rec->features[i].on = 1;
773 if (rec->features[i].on)
775 XtSetArg (arg[0], XtNborderWidth, 3);
776 XtSetArg (arg[1], XtNinternalHeight, 2);
777 XtSetArg (arg[2], XtNinternalWidth, 2);
781 XtSetArg (arg[0], XtNborderWidth, 1);
782 XtSetArg (arg[1], XtNinternalHeight, 4);
783 XtSetArg (arg[2], XtNinternalWidth, 4);
785 OTF_tag_name (rec->features[i].tag, str);
786 XtSetArg (arg[3], XtNlabel, str);
787 XtSetValues (rec->features[i].w, arg, 4);
793 setup_feature_rec (FeatureRec *rec)
799 if (! rec->gsub_gpos)
801 for (i = 0; i < rec->gsub_gpos->ScriptList.ScriptCount; i++)
802 if (rec->gsub_gpos->ScriptList.Script[i].ScriptTag == script_tag)
804 OTF_Script *script = rec->gsub_gpos->ScriptList.Script + i;
808 for (j = 0; j < script->LangSysCount; j++)
809 if (script->LangSysRecord[j].LangSysTag == langsys_tag)
811 rec->langsys = script->LangSys + j;
816 rec->langsys = &rec->gsub_gpos->ScriptList.Script[i].DefaultLangSys;
824 XtSetArg (arg[0], XtNborderWidth, 1);
825 XtSetArg (arg[1], XtNinternalHeight, 4);
826 XtSetArg (arg[2], XtNinternalWidth, 4);
827 XtSetArg (arg[3], XtNborderColor, foreground);
828 XtSetArg (arg[4], XtNsensitive, True);
829 for (i = 0; i < rec->langsys->FeatureCount; i++)
831 OTF_Feature *feature = rec->gsub_gpos->FeatureList.Feature;
832 int index = rec->langsys->FeatureIndex[i];
835 if (! rec->features[i].w)
837 Widget w = XtCreateManagedWidget ("", commandWidgetClass,
838 rec->parent, arg, 0);
839 XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
840 rec->features[i].w = w;
843 rec->features[i].tag = feature[index].FeatureTag;
844 rec->features[i].on = 0;
845 OTF_tag_name (rec->features[i].tag, label);
846 XtSetArg (arg[5], XtNlabel, label);
847 XtSetValues (rec->features[i].w, arg, 6);
850 XtSetArg (arg[0], XtNborderColor, background);
851 XtSetArg (arg[1], XtNsensitive, False);
852 XtSetArg (arg[2], XtNlabel, " ");
853 for (; i < rec->num_features; i++)
855 if (! rec->features[i].w)
857 Widget w = XtCreateManagedWidget ("", commandWidgetClass,
858 rec->parent, arg, 0);
859 XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
860 rec->features[i].w = w;
862 XtSetValues (rec->features[i].w, arg, 3);
867 compose_script_langsys (OTF_Tag script, OTF_Tag langsys, char *name)
869 OTF_tag_name (script, name);
873 OTF_tag_name (langsys, name + 5);
880 decompose_script_langsys (OTF_Tag *script, OTF_Tag *langsys, char *name)
882 *script = OTF_tag (name);
884 *langsys = OTF_tag (name + 5);
890 ScriptProc (Widget w, XtPointer client_data, XtPointer call_data)
893 OTF_Tag script, langsys;
896 XtSetArg (arg[0], XtNlabel, &name);
897 XtGetValues (w, arg, 1);
898 decompose_script_langsys (&script, &langsys, name);
899 if (script_tag == script && langsys_tag == langsys)
902 langsys_tag = langsys;
903 setup_feature_rec (&gsub);
904 setup_feature_rec (&gpos);
909 create_otf_script_widgets (Widget prev)
921 XtSetArg (arg[0], XtNborderWidth, 0);
922 XtSetArg (arg[1], XtNleft, XawChainLeft);
923 XtSetArg (arg[2], XtNright, XawChainLeft);
924 XtSetArg (arg[3], XtNtop, XawChainTop);
925 XtSetArg (arg[4], XtNbottom, XawChainTop);
926 XtSetArg (arg[5], XtNfromVert, prev);
927 XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
928 prev = XtCreateManagedWidget ("Script", boxWidgetClass, render_area, arg, 7);
929 XtCreateManagedWidget ("script(langsys)", labelWidgetClass, prev, arg, 1);
933 for (i = 0; i < otf->gsub->ScriptList.ScriptCount; i++)
934 n += otf->gsub->ScriptList.Script[i].LangSysCount + 1;
936 for (i = 0; i < otf->gpos->ScriptList.ScriptCount; i++)
937 n += otf->gsub->ScriptList.Script[i].LangSysCount + 1;
938 script_langsys = alloca ((sizeof script_langsys[0]) * n);
942 for (i = 0; i < otf->gsub->ScriptList.ScriptCount; i++)
944 OTF_Tag tag = otf->gsub->ScriptList.Script[i].ScriptTag;
946 script_langsys[n].script = tag;
947 script_langsys[n++].langsys = 0;
949 < otf->gsub->ScriptList.Script[i].DefaultLangSys.FeatureCount)
951 = otf->gsub->ScriptList.Script[i].DefaultLangSys.FeatureCount;
952 for (j = 0; j < otf->gsub->ScriptList.Script[i].LangSysCount; j++)
954 script_langsys[n].script = tag;
955 script_langsys[n++].langsys
956 = otf->gsub->ScriptList.Script[i].LangSysRecord[j].LangSysTag;
958 < otf->gsub->ScriptList.Script[i].LangSys[j].FeatureCount)
960 = otf->gsub->ScriptList.Script[i].LangSys[j].FeatureCount;
963 gsub.num_features = nfeatures;
966 gsub.num_features = nfeatures;
967 gsub.features = malloc ((sizeof (FeatureElement)) * nfeatures);
968 memset (gsub.features, 0, (sizeof (FeatureElement)) * nfeatures);
973 for (i = 0; i < otf->gpos->ScriptList.ScriptCount; i++)
975 OTF_Tag tag = otf->gpos->ScriptList.Script[i].ScriptTag;
979 < otf->gpos->ScriptList.Script[i].DefaultLangSys.FeatureCount)
981 = otf->gpos->ScriptList.Script[i].DefaultLangSys.FeatureCount;
982 for (k = 0; k < prev_n; k++)
983 if (tag == script_langsys[k].script)
987 script_langsys[n].script = tag;
988 script_langsys[n++].langsys = 0;
990 for (j = 0; j < otf->gsub->ScriptList.Script[i].LangSysCount; j++)
996 OTF_Script *script = otf->gsub->ScriptList.Script + i;
998 for (l = k; l < prev_n && tag == script_langsys[l].script; l++)
999 if (script->LangSysRecord[j].LangSysTag
1000 == script_langsys[l].langsys)
1007 script_langsys[n].script = tag;
1008 script_langsys[n++].langsys = 0;
1011 < otf->gpos->ScriptList.Script[i].LangSys[j].FeatureCount)
1013 = otf->gpos->ScriptList.Script[i].LangSys[j].FeatureCount;
1019 gpos.num_features = nfeatures;
1020 gpos.features = malloc ((sizeof (FeatureElement)) * nfeatures);
1021 memset (gpos.features, 0, (sizeof (FeatureElement)) * nfeatures);
1027 script_tag = script_langsys[0].script;
1028 langsys_tag = script_langsys[0].langsys;
1029 compose_script_langsys (script_tag, langsys_tag, name);
1033 XtSetArg (arg[0], XtNforeground, background);
1034 XtSetArg (arg[1], XtNbackground, foreground);
1035 XtCreateManagedWidget (name, labelWidgetClass, prev, arg, 2);
1039 XtSetArg (arg[0], XtNstate, True);
1040 w = XtCreateManagedWidget (name, toggleWidgetClass, prev, arg, 1);
1041 XtAddCallback (w, XtNcallback, ScriptProc, NULL);
1042 XtSetArg (arg[0], XtNradioGroup, w);
1043 for (i = 1; i < n; i++)
1045 compose_script_langsys (script_langsys[i].script,
1046 script_langsys[i].langsys, name);
1047 w = XtCreateManagedWidget (name, toggleWidgetClass, prev, arg, 1);
1048 XtAddCallback (w, XtNcallback, ScriptProc, NULL);
1056 create_otf_widgets (Widget prev, FeatureRec *rec)
1061 XtSetArg (arg[0], XtNborderWidth, 0);
1062 XtSetArg (arg[1], XtNleft, XawChainLeft);
1063 XtSetArg (arg[2], XtNright, XawChainLeft);
1064 XtSetArg (arg[3], XtNtop, XawChainTop);
1065 XtSetArg (arg[4], XtNbottom, XawChainTop);
1066 XtSetArg (arg[5], XtNfromVert, prev);
1067 XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
1068 prev = XtCreateManagedWidget (rec->label, boxWidgetClass, render_area,
1070 XtCreateManagedWidget (rec->label, labelWidgetClass, prev, arg, 1);
1071 XtSetArg (arg[0], XtNborderWidth, 1);
1072 XtSetArg (arg[1], XtNinternalHeight, 4);
1073 XtSetArg (arg[2], XtNinternalWidth, 4);
1074 w = XtCreateManagedWidget ("all", commandWidgetClass, prev, arg, 3);
1075 XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
1076 w = XtCreateManagedWidget ("none", commandWidgetClass, prev, arg, 3);
1077 XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
1080 setup_feature_rec (rec);
1087 String quit_action = "<KeyPress>q: set() notify() unset()";
1088 String FIRST_action = "<KeyPress>f: set() notify() unset()\n\
1089 <KeyPress>Home: set() notify() unset()";
1090 String PREV_action = "Shift<KeyPress>p: set() notify() unset()\n\
1091 <KeyPress>Up: set() notify() unset()";
1092 String prev_action = "~Shift<KeyPress>p: set() notify() unset()\n\
1093 <KeyPress>Left: set() notify() unset()";
1094 String next_action = "~Shift<KeyPress>n: set() notify() unset()\n\
1095 <KeyPress>Right: set() notify() unset()";
1096 String NEXT_action = "Shift<KeyPress>n: set() notify() unset()\n\
1097 <KeyPress>Down: set() notify() unset()";
1098 String LAST_action = "<KeyPress>l: set() notify() unset()\n\
1099 <KeyPress>End: set() notify() unset()";
1103 String trans = "<Expose>: Expose()";
1105 XtSetArg (arg[0], XtNtranslations, XtParseTranslationTable (trans));
1106 frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, arg, 1);
1108 XtSetArg (arg[0], XtNleft, XawChainLeft);
1109 XtSetArg (arg[1], XtNright, XawChainLeft);
1110 XtSetArg (arg[2], XtNtop, XawChainTop);
1111 XtSetArg (arg[3], XtNbottom, XawChainTop);
1112 XtSetArg (arg[4], XtNborderWidth, 0);
1113 XtSetArg (arg[5], XtNorientation, XtorientHorizontal);
1114 command_area = XtCreateManagedWidget ("command-area", boxWidgetClass,
1116 XtSetArg (arg[6], XtNfromVert, command_area);
1117 navi_area = XtCreateManagedWidget ("navi-area", boxWidgetClass,
1119 XtSetArg (arg[4], XtNborderWidth, 0);
1120 XtSetArg (arg[5], XtNfromVert, navi_area);
1121 XtSetArg (arg[6], XtNdefaultDistance, 0);
1122 glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
1124 XtSetArg (arg[5], XtNfromVert, glyph_area);
1125 render_area = XtCreateManagedWidget ("render-area", formWidgetClass,
1128 XtSetArg (arg[0], XtNaccelerators, XtParseAcceleratorTable (quit_action));
1129 quit = XtCreateManagedWidget ("Quit", commandWidgetClass,
1130 command_area, arg, 1);
1131 XtAddCallback (quit, XtNcallback, QuitProc, NULL);
1133 dump = XtCreateManagedWidget ("Dump Image", commandWidgetClass,
1134 command_area, arg, 1);
1135 XtAddCallback (dump, XtNcallback, DumpProc, NULL);
1137 XtSetArg (arg[0], XtNborderWidth, 0);
1138 XtSetArg (arg[1], XtNwidth, 10);
1139 XtCreateManagedWidget ("spacer", boxWidgetClass, command_area, arg, 2);
1141 charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
1142 XtSetArg (arg[0], XtNstate, True);
1143 charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, toggleWidgetClass,
1144 command_area, arg, 1);
1145 XtAddCallback (charmap[0], XtNcallback, CharmapProc, (XtPointer) -1);
1146 XtSetArg (arg[0], XtNradioGroup, charmap[0]);
1147 for (i = 0; i < face->num_charmaps; i++)
1149 charmap[i + 1] = XtCreateManagedWidget (charmap_rec[i + 1].name,
1151 command_area, arg, 1);
1152 XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i);
1155 XtSetArg (arg[0], XtNlabel, " |< (f)");
1156 XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (FIRST_action));
1157 FIRST = XtCreateManagedWidget ("FIRST", commandWidgetClass,
1159 XtAddCallback (FIRST, XtNcallback, GlyphProc, (XtPointer) -3);
1160 XtSetArg (arg[0], XtNlabel, "<< (P)");
1161 XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
1162 PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
1164 XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
1165 XtSetArg (arg[0], XtNlabel, "< (p)");
1166 XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
1167 prev = XtCreateManagedWidget ("prev", commandWidgetClass,
1169 XtAddCallback (prev, XtNcallback, GlyphProc, (XtPointer) -1);
1170 XtSetArg (arg[0], XtNlabel, " 0000 ");
1171 range = XtCreateManagedWidget ("range", labelWidgetClass,
1173 XtSetArg (arg[0], XtNforeground, &foreground);
1174 XtSetArg (arg[1], XtNbackground, &background);
1175 XtGetValues (range, arg, 2);
1177 XtSetArg (arg[0], XtNlabel, "> (n)");
1178 XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
1179 next = XtCreateManagedWidget ("next", commandWidgetClass,
1181 XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
1182 XtSetArg (arg[0], XtNlabel, ">> (N)");
1183 XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
1184 NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
1186 XtAddCallback (NEXT, XtNcallback, GlyphProc, (XtPointer) 2);
1187 XtSetArg (arg[0], XtNlabel, ">| (l)");
1188 XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (LAST_action));
1189 LAST = XtCreateManagedWidget ("LAST", commandWidgetClass,
1191 XtAddCallback (LAST, XtNcallback, GlyphProc, (XtPointer) 3);
1193 XtSetArg (arg[0], XtNleft, XawChainLeft);
1194 XtSetArg (arg[1], XtNright, XawChainLeft);
1195 XtSetArg (arg[2], XtNtop, XawChainTop);
1196 XtSetArg (arg[3], XtNbottom, XawChainTop);
1198 for (i = 0; i < 8; i++)
1204 sprintf (str, "%XX", i);
1205 XtSetArg (arg[n], XtNheight, glyph_height + 5), n++;
1206 XtSetArg (arg[n], XtNlabel, str), n++;
1207 XtSetArg (arg[n], XtNborderWidth, 0), n++;
1209 XtSetArg (arg[n], XtNfromVert, w), n++;
1210 head = XtCreateManagedWidget (str, labelWidgetClass, glyph_area, arg, n);
1211 index_label[i] = head;
1212 for (j = 0; j < 16; j++)
1218 XtSetArg (arg[n], XtNfromVert, w), n++;
1220 XtSetArg (arg[n], XtNfromHoriz, head), n++;
1222 XtSetArg (arg[n], XtNfromHoriz, glyph[k - 1]), n++;
1223 XtSetArg (arg[n], XtNbitmap, none_pixmap), n++;
1224 glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
1225 glyph_area, arg, n);
1226 XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k);
1230 /* 10 = (1 (border_width) + 4 (inner_width)) * 2 */
1231 XtSetArg(arg[4], XtNwidth, glyph_width + 10);
1232 XtSetArg (arg[5], XtNfromVert, glyph[112]);
1233 XtSetArg (arg[6], XtNfromHoriz, w);
1234 XtSetArg (arg[7], XtNborderWidth, 0);
1236 for (j = 0; j < 16; j++)
1240 sprintf (str, "X%X", j);
1241 XtSetArg (arg[8], XtNlabel, str);
1242 w = XtCreateManagedWidget ("idx", labelWidgetClass, glyph_area, arg, 9);
1243 XtSetArg (arg[6], XtNfromHoriz, w);
1246 XtSetArg (arg[0], XtNleft, XawChainLeft);
1247 XtSetArg (arg[1], XtNright, XawChainLeft);
1248 XtSetArg (arg[2], XtNtop, XawChainTop);
1249 XtSetArg (arg[3], XtNbottom, XawChainTop);
1250 XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
1251 XtSetArg (arg[5], XtNborderWidth, 0);
1252 w = XtCreateManagedWidget ("clear-box", boxWidgetClass, render_area, arg, 6);
1253 clear = XtCreateManagedWidget ("clear", commandWidgetClass, w, arg, 0);
1254 XtAddCallback (clear, XtNcallback, RenderProc, (XtPointer) -1);
1255 del = XtCreateManagedWidget ("delete", commandWidgetClass, w, arg, 0);
1256 XtAddCallback (del, XtNcallback, RenderProc, (XtPointer) -2);
1257 bidi = XtCreateManagedWidget ("L->R", toggleWidgetClass, w, arg, 0);
1258 XtAddCallback (bidi, XtNcallback, BidiProc, NULL);
1259 alt_subst = XtCreateManagedWidget ("AltSubst", toggleWidgetClass, w, arg, 0);
1260 XtAddCallback (alt_subst, XtNcallback, AltSubstProc, NULL);
1262 XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
1263 XtSetArg (arg[5], XtNborderWidth, 0);
1264 XtSetArg (arg[6], XtNfromVert, w);
1265 raw = XtCreateManagedWidget ("raw", boxWidgetClass, render_area, arg, 7);
1267 XtSetArg (arg[0], XtNborderWidth, 0);
1268 XtSetArg (arg[1], XtNlabel, "raw: ");
1269 raw_label = XtCreateManagedWidget ("raw-label", labelWidgetClass,
1271 XtSetArg (arg[1], XtNbitmap, raw_pixmap);
1272 raw_image = XtCreateManagedWidget ("raw-image", labelWidgetClass,
1277 OTF_get_table (otf, "GSUB");
1278 OTF_get_table (otf, "GPOS");
1279 w = create_otf_script_widgets (w);
1282 gsub.label = "GSUB";
1283 gsub.gsub_gpos = otf->gsub;
1284 w = create_otf_widgets (w, &gsub);
1288 gpos.label = "GPOS";
1289 gpos.gsub_gpos = otf->gpos;
1290 w = create_otf_widgets (w, &gpos);
1294 XtSetArg (arg[6], XtNfromVert, w);
1295 seq = XtCreateManagedWidget ("seq", boxWidgetClass, render_area, arg, 7);
1296 XtSetArg (arg[0], XtNborderWidth, 0);
1297 XtSetArg (arg[1], XtNlabel, "seq: ");
1298 seq_label = XtCreateManagedWidget ("seq-label", labelWidgetClass,
1300 XtSetArg (arg[1], XtNbitmap, seq_pixmap);
1301 seq_image = XtCreateManagedWidget ("seq-image", labelWidgetClass,
1303 XtInstallAllAccelerators (shell, shell);
1307 ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num)
1309 XTextProperty text_prop;
1310 char *pname = "otfview";
1311 char *fname = basename (filename);
1312 char *name = alloca (strlen (fname) + 3 + strlen (pname) + 1);
1314 sprintf (name, "%s - %s", pname, fname);
1315 text_prop.value = (unsigned char *) name;
1316 text_prop.encoding = XA_STRING;
1317 text_prop.format = 8;
1318 text_prop.nitems = strlen (name);
1319 XSetWMName (display, XtWindow (shell), &text_prop);
1322 /* Format MSG by FMT and print the result to the stderr, and exit. */
1324 #define FATAL_ERROR(fmt, arg) \
1326 fprintf (stderr, fmt, arg); \
1331 x_error_handler (Display *display, XErrorEvent *error)
1338 main (int argc, char **argv)
1340 XtActionsRec actions[] = { {"Expose", ExposeProc} };
1344 OTF_GlyphString gstring;
1349 int fixed_pixel_size = 0;
1352 pixel_size = DEFAULT_PIXEL_SIZE;
1354 char *str = getenv ("PIXEL_SIZE");
1356 if (str && (i = atoi (str)) > 0)
1359 fixed_pixel_size = 1;
1363 gstring.size = gstring.used = 256;
1364 g = calloc (256, sizeof (OTF_Glyph));
1367 shell = XtOpenApplication (&context, "OTFView", NULL, 0, &argc, argv, NULL,
1368 shellWidgetClass, arg, 0);
1369 display = XtDisplay (shell);
1370 /*XSynchronize (display, True);*/
1371 XSetErrorHandler (x_error_handler);
1372 display_width = DisplayWidth (display,
1373 XScreenNumberOfScreen (XtScreen (shell)));
1374 font = XLoadQueryFont (display, DEFAULT_FONT_NAME);
1376 font = XLoadQueryFont (display, "fixed");
1378 if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
1380 fprintf (stderr, "Usage: %s [ X-OPTION ... ] OTF-FILE\n",
1381 basename (argv[0]));
1383 " Pixel size is decided by the environment variable PIXEL_SIZE ((default %d).\n", DEFAULT_PIXEL_SIZE);
1387 if (strstr (filename, ".ttf")
1388 || strstr (filename, ".TTF")
1389 || strstr (filename, ".otf")
1390 || strstr (filename, ".OTF"))
1392 otf = OTF_open (filename);
1394 || OTF_get_table (otf, "head") < 0
1395 || OTF_get_table (otf, "cmap") < 0
1396 || (OTF_check_table (otf, "GSUB") < 0
1397 && OTF_check_table (otf, "GPOS") < 0))
1401 if ((err = FT_Init_FreeType (&library)))
1402 FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
1403 err = FT_New_Face (library, filename, 0, &face);
1404 if (err == FT_Err_Unknown_File_Format)
1405 FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
1407 FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
1408 if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
1409 FATAL_ERROR ("%s\n", "FT_Set_Pixel_Sizes: error");
1415 filename = basename (filename);
1416 sprintf (title, "%s family:%s style:%s",
1417 filename, face->family_name, face->style_name);
1418 XtSetArg (arg[0], XtNtitle, title);
1419 XtSetValues (shell, arg, 1);
1422 glyph_width = ((face->bbox.xMax - face->bbox.xMin)
1423 * pixel_size / face->units_per_EM);
1424 if (! fixed_pixel_size && glyph_width * 16 > display_width * 0.8)
1426 pixel_size = (pixel_size * display_width * 0.8 / 16 / glyph_width);
1427 FT_Set_Pixel_Sizes (face, 0, pixel_size);
1428 glyph_width = ((face->bbox.xMax - face->bbox.xMin)
1429 * pixel_size / face->units_per_EM);
1431 if (glyph_width < FONT_WIDTH * 4)
1432 glyph_width = FONT_WIDTH * 4;
1434 glyph_height = ((face->bbox.yMax - face->bbox.yMin)
1435 * pixel_size / face->units_per_EM);
1437 glyph_x = - (face->bbox.xMin * pixel_size / face->units_per_EM);
1438 glyph_y = face->bbox.yMax * pixel_size / face->units_per_EM;
1439 none_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
1440 glyph_width, glyph_height, 1);
1443 unsigned long valuemask = GCFunction | GCLineWidth;
1446 gc = XCreateGC (display, none_pixmap, (unsigned long) 0, NULL);
1447 values.function = GXset;
1448 values.line_width = 1;
1449 gc_set = XCreateGC (display, none_pixmap, valuemask, &values);
1450 values.function = GXor;
1451 gc_or = XCreateGC (display, none_pixmap, valuemask, &values);
1452 values.function = GXcopyInverted;
1453 gc_inv = XCreateGC (display, none_pixmap, valuemask, &values);
1456 XFillRectangle (display, none_pixmap, gc, 0, 0,
1457 glyph_width, glyph_height);
1458 XDrawString (display, none_pixmap, gc_inv,
1459 (glyph_width - XTextWidth (font, "none", 4)) / 2,
1460 glyph_height / 2, "none", 4);
1462 render_width = (glyph_width + 4) * 15 + 1;
1463 render_height = glyph_height + 2;
1465 charmap_rec[0].platform_id = -1;
1466 charmap_rec[0].encoding_id = -1;
1467 strcpy (charmap_rec[0].name, "no charmap");
1469 for (i = 0; i < face->num_charmaps; i++)
1471 charmap_rec[i + 1].platform_id = face->charmaps[i]->platform_id;
1472 charmap_rec[i + 1].encoding_id = face->charmaps[i]->encoding_id;
1473 sprintf (charmap_rec[i + 1].name, "%d-%d",
1474 charmap_rec[i + 1].platform_id, charmap_rec[i + 1].encoding_id);
1475 if (face->charmaps[i]->platform_id == 0
1476 || (face->charmaps[i]->platform_id == 3
1477 && face->charmaps[i]->encoding_id == 1))
1478 strcat (charmap_rec[i + 1].name, " (unicode)");
1479 else if (face->charmaps[i]->platform_id == 1
1480 && face->charmaps[i]->encoding_id == 0)
1481 strcat (charmap_rec[i + 1].name, " (apple-roman)");
1484 raw_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
1485 render_width, render_height, 1);
1486 seq_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
1487 render_width, render_height, 1);
1489 memset (bitmap, 0, sizeof (bitmap));
1493 update_glyph_area ();
1494 update_render_area ();
1496 XtAppAddActions (context, actions, XtNumber (actions));
1497 XtRealizeWidget (shell);
1498 XtAppMainLoop (context);
1503 #else /* not HAVE_X11_XAW_COMMAND_H */
1506 main (int argc, char **argv)
1509 "Building of this program failed (lack of some header files)\n");