*** empty log message ***
authorhanda <handa>
Sat, 19 Jul 2003 05:54:05 +0000 (05:54 +0000)
committerhanda <handa>
Sat, 19 Jul 2003 05:54:05 +0000 (05:54 +0000)
example/Makefile.am
example/otfview.c
example/otfviewx.c [deleted file]

index 2cce228..f7d7561 100644 (file)
@@ -1,4 +1,4 @@
-bin_PROGRAMS = otfviewx otfdump otfdraw otfview otflist
+bin_PROGRAMS = otfdump otfdraw otfview otflist
 
 INCLUDES = `freetype-config --cflags`
 CommonLDADD = ${top_builddir}/src/libotf.la
@@ -19,7 +19,3 @@ otfdraw_LDFLAGS = `freetype-config --libs` ${X_LIBS} ${X_PRE_LIBS} -lX11 -lXt -l
 otfview_SOURCE = otfview.c
 otfview_LDADD = ${CommonLDADD}
 otfview_LDFLAGS = `freetype-config --libs` ${X_LIBS} ${X_PRE_LIBS} -lX11 -lXt -lXaw -lXmu -ldl -static
-
-otfviewx_SOURCE = otfviewx.c
-otfviewx_LDADD = ${CommonLDADD}
-otfviewx_LDFLAGS = `freetype-config --libs` ${X_LIBS} ${X_PRE_LIBS} -lX11 -lXt -lXaw -lXmu -ldl -static
index f2253d4..cf46900 100644 (file)
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <libgen.h>
 
-#include <otf.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Viewport.h>
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/Xutil.h>
+#include <otf.h>
+
+#define DEFAULT_PIXEL_SIZE 30
+#define DEFAULT_FONT_NAME "6x13"
+XFontStruct *font;
+#define FONT_HEIGHT (font->ascent + font->descent)
+
+XtAppContext context;
+/* Widget structure.
+   +--- frame (form) ------------------+
+   | +--- command_area (box) --------+ |
+   | | quit charmap ...              | |
+   | +-------------------------------+ |
+   | +---- navi_area (box) ----------+ |
+   | | PREV prev label next NEXT     | |
+   | +-------------------------------+ |
+   | +--- glyph_area (form) ---------+ |
+   | | glyph[0]     ...    glyph[15] | |
+   | |   ...                 ...     | |
+   | | glyph[112]   ...    glyph[127]| |
+   | +-------------------------------+ |
+   | +--- render_area (form) --------+ |
+   | | clear                         | |
+   | | +--- raw (box) -------------+ | |
+   | | | raw_label raw_image       | | |
+   | | +--- seq (box) -------------+ | |
+   | | | seq_label seq_image       | | |
+   | | +--- gsub (box) ------------+ | |
+   | | | gsub_label gsub_image     | | |
+   | | +--- gpos (box) ------------+ | |
+   | | | gpos_label gpos_image     | | |
+   | | +---------------------------+ | |
+   | +-------------------------------+ |
+   +-----------------------------------+ */
+Widget shell, frame;
+Widget command_area, quit, *charmap;
+Widget navi_area, PREV, prev, label, next, NEXT;
+Widget glyph_area, glyph[128];
+Widget render_area, clear, raw, seq, gsub, gpos;
+Widget raw_label, raw_image, seq_label, seq_image;
+Widget gsub_label, gsub_image, gpos_label, gpos_image;
+
+int glyph_char[128];
 
-#define PIXEL_SIZE 40
+Display *display;
+GC gc, gc_set, gc_or;
 
-#define FONT_NAME "6x13"
-#define FONT_HEIGHT 14
+typedef struct {
+  Pixmap pixmap;
+  unsigned width, height;
+  int x, y;
+  int advance;
+} BitmapRec;
 
-int font_height, font_width;
+BitmapRec bitmap[0x10000];
+
+int render_width, render_height;
+Pixmap raw_pixmap, seq_pixmap, gsub_pixmap, gpos_pixmap;
 
-FT_Library library;
 FT_Face face;
 
-Display *display;
-int screen;
-Window win;
-XFontStruct *font;
-GC gc_norm, gc_rev, gc_xor;
-unsigned long valuemask;
-unsigned long foreground, background;
-XGCValues values;
+struct {
+  int platform_id;
+  int encoding_id;
+  char name[20];
+} charmap_rec[10];
 
-typedef struct
+int charmap_index;
+
+unsigned glyph_width, glyph_height;
+int glyph_x, glyph_y;
+int glyph_index;
+
+struct {
+  int n_glyphs;
+  int glyphs[64];
+} glyph_rec;  
+
+OTF *otf;
+
+void
+create_pixmap (int pixel_size, int index)
 {
-  int advance;
-  int left, top;
-  int rows;
-  int width;
-  int pitch;
-  int unicode;
-  unsigned char* buf;
-} Bitmap;
+  int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
+  XImage ximage;
+  Pixmap pixmap;
+  
+  if (err)
+    {
+      bitmap[index].pixmap = (Pixmap) 0;
+      return;
+    }
+  ximage.height = face->glyph->bitmap.rows;
+  ximage.width = face->glyph->bitmap.width;
+  ximage.depth = 1;
+  ximage.bits_per_pixel = 1;
+  ximage.xoffset = 0;
+  ximage.format = XYPixmap;
+  ximage.data = (char *) face->glyph->bitmap.buffer;
+  ximage.byte_order = MSBFirst;
+  ximage.bitmap_unit = 8;
+  ximage.bitmap_bit_order = MSBFirst;
+  ximage.bitmap_pad = 8;
+  ximage.bytes_per_line = face->glyph->bitmap.pitch;
+  XInitImage (&ximage);
+  pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+                         glyph_width, glyph_height, 1);
+  XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, glyph_height);
+  XPutImage (display, pixmap, gc, &ximage, 0, 0,
+            glyph_x + face->glyph->bitmap_left,
+            glyph_y - face->glyph->bitmap_top,
+            ximage.width, ximage.height);
+  bitmap[index].pixmap = pixmap;
+  bitmap[index].width = ximage.width;
+  bitmap[index].height = ximage.height;
+  bitmap[index].x = face->glyph->bitmap_left;
+  bitmap[index].y = - face->glyph->bitmap_top;
+  bitmap[index].advance = face->glyph->metrics.horiAdvance >> 6;
+}
 
-Bitmap bitmap[0x10000];
+void
+update_glyph_area ()
+{
+  int i;
+  Arg arg[2];
+  char buf[16];
+
+  for (i = 0; i < 128; i++)
+    {
+      int index = glyph_index + i;
+      int num_args = 0;
+
+      if (charmap_index >= 0)
+       index = FT_Get_Char_Index (face, (FT_ULong) index);
+      XtSetArg (arg[num_args], XtNbitmap, bitmap[index].pixmap), num_args++;
+      if (! bitmap[index].pixmap)
+       XtSetArg (arg[num_args], XtNlabel, "none"), num_args++;
+      XtSetValues (glyph[i], arg, num_args);
+    }
 
-/* Unicode to glyph index mapping table.  */
-int utog[0x10000];
+  sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
+  XtSetArg (arg[0], XtNlabel, buf);
+  XtSetValues (label, arg, 1);
+}
 
 void
-draw_bitmap (int index, int x, int y)
+update_render_area ()
 {
-  Bitmap *bmp = bitmap + index;
-  unsigned char *buf = bmp->buf;
-  int i, j;
+  int i;
+  int x;
+  Arg arg[1];
 
-  if (buf)
+  XFillRectangle (display, raw_pixmap, gc, 0, 0, render_width, render_height);
+  XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
+  for (i = 0, x = glyph_x; i < glyph_rec.n_glyphs; i++)
     {
-      x += bmp->left;
-      y -= bmp->top;
-      for (i = 0; i < bmp->rows; i++, buf += bmp->pitch)
-       for (j = 0; j < bmp->width; j++)
-         if (buf[j / 8] & (1 << (7 - (j % 8))))
-           XDrawPoint (display, win, gc_norm, x + j, y + i);
+      BitmapRec *bmp = bitmap + glyph_rec.glyphs[i];
+
+      XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
+                0, 0, glyph_width, glyph_height,
+                (glyph_width + 1) * i + 1, 1);
+      XDrawRectangle (display, raw_pixmap, gc_set,
+                     (glyph_width + 1) * i, 0,
+                     glyph_width + 1, glyph_height + 1);
+      XCopyArea (display, bmp->pixmap, seq_pixmap, gc_or,
+                glyph_x + bmp->x, glyph_y + bmp->y, bmp->width, bmp->height,
+                x + bmp->x, glyph_y + bmp->y);
+      x += bmp->advance;
     }
+  XtSetArg (arg[0], XtNbitmap, raw_pixmap);
+  XtSetValues (raw_image, arg, 1);
+  XtSetArg (arg[0], XtNbitmap, seq_pixmap);
+  XtSetValues (seq_image, arg, 1);
+  if (! otf)
+    return;
+  XFillRectangle (display, gsub_pixmap, gc, 0, 0, render_width, render_height);
+  XFillRectangle (display, gpos_pixmap, gc, 0, 0, render_width, render_height);
+  XtSetArg (arg[0], XtNbitmap, gsub_pixmap);
+  XtSetValues (gsub_image, arg, 1);
+  XtSetArg (arg[0], XtNbitmap, gpos_pixmap);
+  XtSetValues (gpos_image, arg, 1);
 }
 
 void
-quit (char *msg)
+QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
 {
-  fprintf (stderr, "Error by %s\n", msg);
-  exit (1);
+  XtAppSetExitFlag (XtWidgetToApplicationContext (w));
 }
 
+void
+GlyphProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+  int old_glyph_index = glyph_index;
+
+  if ((int) client_data == -2 && glyph_index > 0)
+    glyph_index = (glyph_index - 1) & 0xF000;
+  else if ((int) client_data == -1 && glyph_index > 0)
+    glyph_index -= 0x80;
+  else if ((int) client_data == 1 && glyph_index < 0xFF80)
+    glyph_index += 0x80;
+  else if ((int) client_data == 2 && glyph_index < 0xF000)
+    glyph_index = (glyph_index + 0x1000) & 0xF000;
+  if (glyph_index != old_glyph_index)
+    update_glyph_area ();
+}
 
-int
-read_unicode_seq (char *filename, int *code)
+void
+CharmapProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+  if (charmap_index == (int) client_data)
+    return;
+  charmap_index = (int) client_data;
+  if (charmap_index >= 0)
+    FT_Set_Charmap (face, face->charmaps[charmap_index]);
+  update_glyph_area ();
+}
+
+void
+RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
 {
-  FILE *fp = fopen (filename, "r");
-  int i = 0;
-      
-  if (! fp)
+  if ((int) client_data < 0)
     {
-      fprintf (stderr, "File \"%s\" can't be opened.\n", filename);
-      exit (1);
+      glyph_rec.n_glyphs = 0;
+      update_render_area ();
+    }
+  else if (glyph_rec.n_glyphs < 64)
+    {
+      int index = glyph_index + (int) client_data;
+      if (charmap_index >= 0)
+       index = FT_Get_Char_Index (face, (FT_ULong) index);
+      glyph_rec.glyphs[glyph_rec.n_glyphs++] = index;
+      update_render_area ();
     }
-  while (i < 256
-        && fscanf (fp, "%x", code + i) == 1)
-    i++;
-  fclose (fp);
-  return i;
 }
 
-
-typedef struct
+void
+create_widgets ()
 {
-  int platform_id;
-  int encoding_id;
-  int index;
-  char name[256];
-} CharmapRec;
+  String quit_action = "<KeyPress>q: set() notify() unset()";
+  String PREV_action = "Shift<KeyPress>p: set() notify() unset()";
+  String prev_action = "~Shift<KeyPress>p: set() notify() unset()";
+  String next_action = "~Shift<KeyPress>n: set() notify() unset()";
+  String NEXT_action = "Shift<KeyPress>n: set() notify() unset()";
+  Arg arg[10];
+  int i, j;
+
+  frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, NULL, 0);
+  XtSetArg (arg[0], XtNleft, XawChainLeft);
+  XtSetArg (arg[1], XtNright, XawChainLeft);
+  XtSetArg (arg[2], XtNtop, XawChainTop);
+  XtSetArg (arg[3], XtNbottom, XawChainTop);
+  XtSetArg (arg[4], XtNborderWidth, 0);
+  XtSetArg (arg[5], XtNorientation, XtorientHorizontal);
+  command_area = XtCreateManagedWidget ("command-area", boxWidgetClass,
+                                       frame, arg, 6);
+  XtSetArg (arg[6], XtNfromVert, command_area);
+  navi_area = XtCreateManagedWidget ("navi-area", boxWidgetClass,
+                                    frame, arg, 7);
+  XtSetArg (arg[4], XtNborderWidth, 1);
+  XtSetArg (arg[5], XtNfromVert, navi_area);
+  XtSetArg (arg[6], XtNdefaultDistance, 0);
+  glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
+                                     frame, arg, 7);
+  XtSetArg (arg[4], XtNborderWidth, 0);
+  XtSetArg (arg[5], XtNfromVert, glyph_area);
+  render_area = XtCreateManagedWidget ("render-area", formWidgetClass,
+                                      frame, arg, 6);
+
+  XtSetArg (arg[0], XtNaccelerators, XtParseAcceleratorTable (quit_action));
+  quit = XtCreateManagedWidget ("quit", commandWidgetClass,
+                               command_area, arg, 1);
+  XtAddCallback (quit, XtNcallback, QuitProc, NULL);
+
+  charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
+  XtSetArg (arg[0], XtNstate, True);
+  charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, toggleWidgetClass,
+                                     command_area, arg, 1);
+  XtAddCallback (charmap[0], XtNcallback, CharmapProc, (XtPointer) -1);
+  XtSetArg (arg[0], XtNradioGroup, charmap[0]);
+  for (i = 0; i < face->num_charmaps; i++)
+    {
+      charmap[i + 1] = XtCreateManagedWidget (charmap_rec[i + 1].name,
+                                             toggleWidgetClass,
+                                             command_area, arg, 1);
+      XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i);
+    }
+
+  XtSetArg (arg[0], XtNlabel, "<< (P)");
+  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
+  PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
+                               navi_area, arg, 2);
+  XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
+  XtSetArg (arg[0], XtNlabel, "< (p)");
+  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
+  prev = XtCreateManagedWidget ("prev", commandWidgetClass,
+                               navi_area, arg, 2);
+  XtAddCallback (prev, XtNcallback, GlyphProc, (XtPointer) -1);
+  XtSetArg (arg[0], XtNlabel, " 0000 ");
+  label = XtCreateManagedWidget ("label", labelWidgetClass,
+                                navi_area, arg, 1);
+  XtSetArg (arg[0], XtNlabel, "(n) >");
+  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
+  next = XtCreateManagedWidget ("next", commandWidgetClass,
+                               navi_area, arg, 2);
+  XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
+  XtSetArg (arg[0], XtNlabel, "(N) >>");
+  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
+  NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
+                               navi_area, arg, 2);
+  XtAddCallback (NEXT, XtNcallback, GlyphProc, (XtPointer) 2);
+
+  XtSetArg (arg[0], XtNleft, XawChainLeft);
+  XtSetArg (arg[1], XtNright, XawChainLeft);
+  XtSetArg (arg[2], XtNtop, XawChainTop);
+  XtSetArg (arg[3], XtNbottom, XawChainTop);
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 16; j++)
+      {
+       int k = i * 16 + j;
+       int num_args = 4;
+
+       XtSetArg (arg[num_args], XtNwidth, glyph_width), num_args++;
+       XtSetArg (arg[num_args], XtNheight, glyph_height), num_args++;
+       if (j > 0)
+         XtSetArg (arg[num_args], XtNfromHoriz, glyph[k - 1]), num_args++;
+       if (i > 0)
+         XtSetArg (arg[num_args], XtNfromVert, glyph[k - 16]), num_args++;
+       glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
+                                         glyph_area, arg, num_args);
+       XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k);
+      }
+
+  XtSetArg (arg[0], XtNleft, XawChainLeft);
+  XtSetArg (arg[1], XtNright, XawChainLeft);
+  XtSetArg (arg[2], XtNtop, XawChainTop);
+  XtSetArg (arg[3], XtNbottom, XawChainTop);
+  clear = XtCreateManagedWidget ("clear", commandWidgetClass,
+                                render_area, arg, 4);
+  XtAddCallback (clear, XtNcallback, RenderProc, (XtPointer) -1);
+  XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
+  XtSetArg (arg[5], XtNborderWidth, 0);
+  XtSetArg (arg[6], XtNfromVert, clear);
+  raw = XtCreateManagedWidget ("raw", boxWidgetClass,
+                               render_area, arg, 7);
+  XtSetArg (arg[0], XtNborderWidth, 0);
+  XtSetArg (arg[1], XtNlabel, "raw: ");
+  raw_label = XtCreateManagedWidget ("raw-label", labelWidgetClass,
+                                     raw, arg, 2);
+  XtSetArg (arg[1], XtNbitmap, raw_pixmap);
+  raw_image = XtCreateManagedWidget ("raw-image", labelWidgetClass,
+                                     raw, arg, 2);
+  XtSetArg (arg[6], XtNfromVert, raw);
+  seq = XtCreateManagedWidget ("seq", boxWidgetClass,
+                               render_area, arg, 7);
+  XtSetArg (arg[0], XtNborderWidth, 0);
+  XtSetArg (arg[1], XtNlabel, "seq: ");
+  seq_label = XtCreateManagedWidget ("seq-label", labelWidgetClass,
+                                     seq, arg, 2);
+  XtSetArg (arg[1], XtNbitmap, seq_pixmap);
+  seq_image = XtCreateManagedWidget ("seq-image", labelWidgetClass,
+                                     seq, arg, 2);
+  if (otf)
+    {
+      XtSetArg (arg[6], XtNfromVert, seq);
+      gsub = XtCreateManagedWidget ("gsub", boxWidgetClass,
+                                   render_area, arg, 7);
+      XtSetArg (arg[0], XtNborderWidth, 0);
+      XtSetArg (arg[1], XtNlabel, "gsub: ");
+      gsub_label = XtCreateManagedWidget ("gsub-label", labelWidgetClass,
+                                         gsub, arg, 2);
+      gsub_image = XtCreateManagedWidget ("gsub-image", labelWidgetClass,
+                                         gsub, arg, 1);
+      XtSetArg (arg[6], XtNfromVert, gsub);
+      gpos = XtCreateManagedWidget ("gpos", boxWidgetClass,
+                                   render_area, arg, 7);
+      XtSetArg (arg[0], XtNborderWidth, 0);
+      XtSetArg (arg[1], XtNlabel, "gpos: ");
+      gpos_label = XtCreateManagedWidget ("gpos-label", labelWidgetClass,
+                                         gpos, arg, 2);
+      gpos_image = XtCreateManagedWidget ("gpos-image", labelWidgetClass,
+                                         gpos, arg, 1);
+    }
+
+  XtInstallAllAccelerators (shell, shell);
+}
+
+
+/* Format MSG by FMT and print the result to the stderr, and exit.  */
+
+#define FATAL_ERROR(fmt, arg)  \
+  do {                         \
+    fprintf (stderr, fmt, arg);        \
+    exit (1);                  \
+  } while (0)
 
 int
 main (int argc, char **argv)
 {
-  OTF *otf = NULL;
-  int err;
-  int i, j;
-  int first_idx;
-  int update_mask;
-#define UPDATE_RENDERING 1
-#define UPDATE_CHARMAP 2
-#define UPDATE_BITMAP 3
+  FT_Library library;
+
   OTF_GlyphString gstring;
   OTF_Glyph *g;
-  int unicode_seq[256];
-  int n_codes = 0;
-  int pixel_size = PIXEL_SIZE;
-  CharmapRec *charmap_rec;
-  int charmap_index = -1;
-  char charmap_line[256];
-
-  /* Window structure.
-
-  +-------------------------+
-  | +--- rendering area --+ |
-  | |Unicode: ...         | |
-  | |   cmap: ...         | |
-  | |   GSUB: ...         | |
-  | |   GPOS: ...         | |
-  | +---------------------+ |
-  | +--- charmap area ----+ |
-  | |                     | |
-  | +---------------------+ |
-  | +--- bitmap area -----+ |
-  | |                     | |
-  | |                     | |
-  | |                     | |
-  | +---------------------+ |
-  +-------------------------+
-  */
-  int margin = 2;
-  int win_width, win_height;
-  int cols = 16, rows = 8;
-  int max_glyph_width, max_glyph_height;
-  int inner_width, rendering_area_height;
-  int charmap_area_height, bitmap_area_height;
-  int x, y, x0, y0, x1, y1;
-  char buf[1024];
+
+  int err;
+  int i;
+  int pixel_size = DEFAULT_PIXEL_SIZE;
 
   gstring.size = gstring.used = 256;
   g = calloc (256, sizeof (OTF_Glyph));
   gstring.glyphs = g;
 
-  if (argc != 2 && argc != 3)
-    {
-      fprintf (stderr, "Usage, otfview OTF-FILE [CODE-FILE]\n");
-      exit (1);
-    }
+  shell = XtOpenApplication (&context, "OTFView", NULL, 0, &argc, argv, NULL,
+                            shellWidgetClass, NULL, 0);
+  display = XtDisplay (shell);
+
+  if (argc != 2)
+    FATAL_ERROR ("%s\n", "Usage: otfview [ X-OPTION ... ]  OTF-FILE");
   
   if (strstr (argv[1], ".ttf")
       || strstr (argv[1], ".TTF")
@@ -167,377 +443,91 @@ main (int argc, char **argv)
       otf = OTF_open (argv[1]);
       if (! otf
          || OTF_get_table (otf, "head") < 0
-         || OTF_get_table (otf, "cmap") < 0)
-       {
-         OTF_perror ("otfview");
-         otf = NULL;
-       }
+         || OTF_get_table (otf, "cmap") < 0
+         || (OTF_get_table (otf, "gsub") < 0
+             && OTF_get_table (otf, "gpos") < 0))
+       otf = NULL;
     }
 
+  if ((err = FT_Init_FreeType (&library)))
+    FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
+  err = FT_New_Face (library, argv[1], 0, &face);
+  if (err == FT_Err_Unknown_File_Format)
+    FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
+  else if (err)
+    FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
+  if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
+    FATAL_ERROR ("%s\n", "FT_Set_Char_Size: error");
+
   {
-    char *p = getenv ("PIXEL_SIZE");
-    int n;
+    char title[256];
+    Arg arg[1];
 
-    if (p && sscanf (p, "%d", &n) == 1)
-      pixel_size = n;
+    sprintf (title, "%s family:%s style:%s",
+            basename (argv[1]), face->family_name, face->style_name);
+    XtSetArg (arg[0], XtNtitle, title);
+    XtSetValues (shell, arg, 1);
   }
 
-  err = FT_Init_FreeType (&library);
-  if (err)
-    quit ("FT_Init_FreeType");
-  err = FT_New_Face (library, argv[1], 0, &face);
-  if (err == FT_Err_Unknown_File_Format)
-    quit ("FT_New_Face: unknown file format");
-  else if (err)
-    quit ("FT_New_Face: unknown error");
-  err = FT_Set_Pixel_Sizes (face, 0, pixel_size);
-  if (err)
-    quit ("FT_Set_Char_Size");
-  charmap_rec = alloca (sizeof (CharmapRec) * face->num_charmaps);
-  strcpy (charmap_line, "raw");
+
+  glyph_width = ((face->bbox.xMax - face->bbox.xMin)
+                * pixel_size / face->units_per_EM);
+  glyph_height = ((face->bbox.yMax - face->bbox.yMin)
+                 *  pixel_size / face->units_per_EM);
+  glyph_x = - (face->bbox.xMin * pixel_size / face->units_per_EM);
+  glyph_y = face->bbox.yMax * pixel_size / face->units_per_EM;
+
+  charmap_rec[0].platform_id = -1;
+  charmap_rec[0].encoding_id = -1;
+  strcpy (charmap_rec[0].name, "no charmap");
+
   for (i = 0; i < face->num_charmaps; i++)
     {
-      strcat (charmap_line, "  ");
-      charmap_rec[i].index = strlen (charmap_line);
-      charmap_rec[i].platform_id = face->charmaps[i]->platform_id;
-      charmap_rec[i].encoding_id = face->charmaps[i]->encoding_id;
-      sprintf (charmap_rec[i].name, "%d-%d",
-              charmap_rec[i].platform_id, charmap_rec[i].encoding_id);
+      charmap_rec[i + 1].platform_id = face->charmaps[i]->platform_id;
+      charmap_rec[i + 1].encoding_id = face->charmaps[i]->encoding_id;
+      sprintf (charmap_rec[i + 1].name, "%d-%d",
+              charmap_rec[i + 1].platform_id, charmap_rec[i + 1].encoding_id);
       if (face->charmaps[i]->platform_id == 0
          || (face->charmaps[i]->platform_id == 3
              && face->charmaps[i]->encoding_id == 1))
-       strcat (charmap_rec[i].name, " (unicode)");
+       strcat (charmap_rec[i + 1].name, " (unicode)");
       else if (face->charmaps[i]->platform_id == 1
               && face->charmaps[i]->encoding_id == 0)
-       strcat (charmap_rec[i].name, " (apple-roman)");
-      strcat (charmap_line, charmap_rec[i].name);
+       strcat (charmap_rec[i + 1].name, " (apple-roman)");
     }
-  strcat (charmap_line, " ");
 
-  memset (utog, 0, sizeof (utog));
-  x0 = x1 = y0 = y1 = 0;
-  for (i = 0; i < 0x10000; i++)
-    {
-      err = FT_Load_Glyph (face, i, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
-      if (err)
-       bitmap[i].buf = NULL;
-      else
-       {
-         Bitmap *bmp = bitmap + i;
-         int bmpsize;
-
-         bmp->advance = face->glyph->metrics.horiAdvance >> 6;
-         bmp->left = face->glyph->bitmap_left;
-         bmp->top = face->glyph->bitmap_top;
-         bmp->rows = face->glyph->bitmap.rows;
-         bmp->width = face->glyph->bitmap.width;
-         bmp->pitch = face->glyph->bitmap.pitch;
-         bmpsize = bmp->rows * bmp->pitch;
-         bmp->buf = malloc (bmpsize);
-         memcpy (bmp->buf, face->glyph->bitmap.buffer, bmpsize);
-         if (x0 > bmp->left)
-           x0 = bmp->left;
-         if (y0 > - bmp->top)
-           y0 = - bmp->top;
-         if (x1 < bmp->left + bmp->width)
-           x1 = bmp->left + bmp->width;
-         if (y1 < bmp->rows - bmp->top)
-           y1 = bmp->rows - bmp->top;
-       }
-    }
-
-  max_glyph_height = y1 - y0;
-  max_glyph_width = x1 - x0;
+  render_width = (glyph_width + 1) * 15 + 1;
+  render_height = glyph_height + 2;
+  raw_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+                             render_width, render_height, 1);
+  seq_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+                             render_width, render_height, 1);
+  gsub_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+                              render_width, render_height, 1);
+  gpos_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+                              render_width, render_height, 1);
+  {
+    unsigned long valuemask =  GCFunction | GCLineWidth;
+    XGCValues values;
+
+    gc = XCreateGC (display, raw_pixmap, (unsigned long) 0, NULL);
+    values.function = GXset;
+    values.line_width = 1;
+    gc_set = XCreateGC (display, raw_pixmap, valuemask, &values);
+    values.function = GXor;
+    gc_or = XCreateGC (display, raw_pixmap, valuemask, &values);
+  }
 
   for (i = 0; i < 0x10000; i++)
-    {
-      if (i >= 0xD800 && i < 0xE000)
-       continue;
-      gstring.glyphs[i & 0xFF].c = i;
-      if ((i & 0xFF) == 0xFF)
-       {
-         OTF_drive_cmap (otf, &gstring);
-         for (j = 0; j < 0x100; j++)
-           {
-             utog[(i & 0xFF00) + j] = gstring.glyphs[j].glyph_id;
-             if (gstring.glyphs[j].glyph_id > 0
-                 && gstring.glyphs[j].glyph_id < 0x10000)
-               bitmap[gstring.glyphs[j].glyph_id].unicode = (i & 0xFF00) + j;
-           }
-       }
-    }
+    create_pixmap (pixel_size, i);
+  create_widgets ();
+  glyph_index = 0;
+  charmap_index = -1;
+  update_glyph_area ();
+  update_render_area ();
 
-  if (argc == 3)
-    n_codes = read_unicode_seq (argv[2], unicode_seq);
-
-  display = XOpenDisplay (NULL);
-  screen = DefaultScreen (display);
-  font = XLoadQueryFont (display, FONT_NAME);
-  if (! font)
-    font = XLoadQueryFont (display, "fixed");
-  font_height = font->ascent + font->descent;
-  font_width = font->max_bounds.width; 
-
-  inner_width = (max_glyph_width + 1) * cols + font_width * 4 + 2;
-  rendering_area_height= (max_glyph_height + 1) * 3 + font_height;
-  charmap_area_height = font_height * 2 + 6;
-  bitmap_area_height = (max_glyph_height + 1) * rows + font_height + 2;
-  win_width = inner_width + margin * 2;
-  win_height = (rendering_area_height
-               + charmap_area_height
-               + bitmap_area_height
-               + margin * 4);
-  win = XCreateSimpleWindow (display, RootWindow (display, screen),
-                            0, 0, win_width, win_height, 1,
-                            BlackPixel (display, screen),
-                            WhitePixel (display, screen));
-
-  valuemask = GCForeground | GCBackground | GCFunction | GCFont;
-
-  values.foreground = BlackPixel (display, screen);
-  values.background = WhitePixel (display, screen);
-  values.function = GXcopy;
-  values.font = font->fid;
-  gc_norm = XCreateGC (display, win, valuemask, &values);
-
-  values.foreground = WhitePixel (display, screen);
-  values.background = BlackPixel (display, screen);
-  values.function = GXcopy;
-  gc_rev = XCreateGC (display, win, valuemask, &values);
-
-  values.foreground = BlackPixel (display, screen);
-  values.background = WhitePixel (display, screen);
-  values.function = values.foreground ? GXxor : GXequiv;
-  gc_xor = XCreateGC (display, win, valuemask, &values);
-
-  XMapWindow (display, win);
-  XSelectInput (display, win, ExposureMask | KeyPressMask | ButtonPressMask);
-
-  first_idx = 0;
-  update_mask = 0;
-  while (1)
-    {
-      XEvent event;
-
-      XNextEvent (display, &event);
-
-      switch (event.type)
-       {
-       case ButtonPress:
-         {
-           int x = event.xbutton.x;
-           int y = event.xbutton.y;
-
-           if (x < margin || x >= margin + inner_width)
-             break;
-           if (margin + rendering_area_height + 3 <= y
-               && y < margin + rendering_area_height + 3 + font_height)
-             {
-               charmap_index++;
-               if (charmap_index >= face->num_charmaps)
-                 charmap_index = -1;
-               update_mask = UPDATE_CHARMAP | UPDATE_BITMAP;
-               goto redraw;
-             }
-           if (margin + 1 <= y && y < margin + 1 + font_height)
-             {
-               n_codes = read_unicode_seq (argv[2], unicode_seq);
-               
-               goto redraw;
-             }
-         }
-         break;
-
-       case KeyPress:
-         {
-           char buf[512];
-           KeySym keysym;
-           int n;
-
-           n = XLookupString ((XKeyEvent *) &event, buf, 512, &keysym, NULL);
-           if (! n)
-             break;
-           if (buf[0] == 'q')
-             goto finish;
-           if (buf[0] == 'n' || buf[0] == ' ')
-             {
-               if (first_idx + cols * rows < 0x10000)
-                 {
-                   first_idx += cols * rows;
-                   update_mask |= UPDATE_BITMAP;
-                   goto redraw;
-                 }
-             }
-           else if (buf[0] == 'p'
-                    || keysym == XK_BackSpace || keysym == XK_Delete)
-             {
-               if (first_idx > 0)
-                 {
-                   first_idx -= cols * rows;
-                   update_mask |= UPDATE_BITMAP;
-                   goto redraw;
-                 }
-             }
-         }
-         break;
-
-       default:
-         update_mask = UPDATE_RENDERING | UPDATE_BITMAP;
-         goto redraw;
-       }
-      continue;
-
-    redraw:
-      if (update_mask == (UPDATE_RENDERING | UPDATE_CHARMAP | UPDATE_BITMAP))
-       {
-         XClearWindow (display, win);
-         x = margin;
-         y = margin + font->ascent;
-         XDrawImageString (display, win, gc_norm, x, y, "Unicode: ", 9);
-         y += font_height + (max_glyph_height - font_height) / 2;
-         XDrawImageString (display, win, gc_norm, x, y, "   cmap: ", 9);
-         y += max_glyph_height + 1;
-         XDrawImageString (display, win, gc_norm, x, y, "   GSUB: ", 9);
-         y += max_glyph_height + 1;
-         XDrawImageString (display, win, gc_norm, x, y, "   GPOS: ", 9);
-
-         y = margin * 3 + rendering_area_height + charmap_area_height;
-         XDrawLine (display, win, gc_norm, x, y, x + inner_width - 1, y);
-         y += font_height + 1;
-         for (i = 0; i <= rows; i++, y += max_glyph_height + 1)
-           XDrawLine (display, win, gc_norm, x, y, x + inner_width - 1, y);
-         y = margin * 3 + rendering_area_height + charmap_area_height;
-         XDrawLine (display, win, gc_norm, x, y,
-                    x, y + bitmap_area_height - 1);
-         x += font_width * 4 + 1;
-         for (i = 0; i <= cols; i++, x += max_glyph_width + 1)
-           XDrawLine (display, win, gc_norm, x, y,
-                      x, y + bitmap_area_height - 1);
-         y += font->ascent + 1;
-         x = (margin + font_width * 4 + 2
-              + (max_glyph_width - font_width * 4) / 2);
-         for (i = 0; i < cols; i++, x += max_glyph_width + 1)
-           {
-             sprintf (buf, "xxx%X", i);
-             XDrawImageString (display, win, gc_norm, x, y, buf, 4);
-           }
-       }
-
-      if (otf && update_mask & UPDATE_RENDERING)      
-       {
-         x = margin + font_width * 9;
-         y = margin + font->ascent;
-         for (i = 0; i < n_codes; i++)
-           {
-             sprintf (buf + i * 5, "%04X ", unicode_seq[i]);
-             gstring.glyphs[i].c = unicode_seq[i];
-           }
-         gstring.used = n_codes;
-         XDrawImageString (display, win, gc_norm, x, y, buf, n_codes * 5);
-
-         OTF_drive_cmap (otf, &gstring);
-         y = margin + font_height + 1;
-         for (i = 0; i < n_codes; i++, x += max_glyph_width)
-           draw_bitmap (gstring.glyphs[i].glyph_id, x - x0, y - y0);
-
-         OTF_drive_gsub (otf, &gstring, "deva", NULL, NULL);
-         x = margin + font_width * 9;
-         y += max_glyph_height;
-         for (i = 0; i < gstring.used; i++, x += max_glyph_width)
-           draw_bitmap (gstring.glyphs[i].glyph_id, x - x0, y - y0);
-
-         OTF_drive_gpos (otf, &gstring, "deva", NULL, NULL);
-         x = margin + font_width * 9 - x0;
-         y += max_glyph_height - y0;
-         for (i = 0; i < gstring.used; i++)
-           {
-             int xoff = 0, yoff = 0;
-             OTF_Glyph *g = gstring.glyphs + i;
-
-             switch (g->positioning_type)
-               {
-               case 1: case 2:
-                 if (g->f.f1.format & OTF_XPlacement)
-                   xoff = pixel_size * ((double) (g->f.f1.value->XPlacement)
-                                        * 100 / otf->head->unitsPerEm);
-                 if (g->f.f1.format & OTF_YPlacement)
-                   yoff = pixel_size * ((double) (g->f.f1.value->YPlacement)
-                                        * 100 / otf->head->unitsPerEm);
-                 break;
-
-               case 4:
-                 xoff = (pixel_size
-                         * ((double) (g->f.f4.base_anchor->XCoordinate
-                                      - g->f.f4.mark_anchor->XCoordinate)
-                            * 100 / otf->head->unitsPerEm));
-                 yoff = (pixel_size
-                         * ((double) (g->f.f4.base_anchor->YCoordinate
-                                      - g->f.f4.mark_anchor->YCoordinate)
-                            * 100 / otf->head->unitsPerEm));
-                 break;
-               }
-
-             draw_bitmap (gstring.glyphs[i].glyph_id, x + xoff, y + yoff);
-             x += bitmap[gstring.glyphs[i].glyph_id].advance;
-           }
-       }
-
-      if (update_mask & UPDATE_CHARMAP)
-       {
-         char *p = charmap_line, *pend;
-
-         x = margin + 1;
-         y = margin * 3 + rendering_area_height + font->ascent + 1;
-         XDrawImageString (display, win, gc_norm, x, y, charmap_line,
-                           strlen (charmap_line));
-         if (charmap_index == -1)
-           pend = p + 3;
-         else
-           {
-             p += charmap_rec[charmap_index].index;
-             pend = p + strlen (charmap_rec[charmap_index].name);
-             FT_Set_Charmap (face, face->charmaps[charmap_index]);
-           }
-         x += font_width * (p - charmap_line);
-         *pend = '\0';
-         XDrawImageString (display, win, gc_rev, x, y, p, strlen (p));
-         *pend = ' ';
-       }
-
-      if (update_mask & UPDATE_BITMAP)
-       {
-         x = margin + 1;
-         y = (margin * 2 + rendering_area_height + charmap_area_height
-              + font_height + 2
-              + (max_glyph_height - font_height) / 2 + font->ascent);
-         for (i = 0; i < rows; i++, y += max_glyph_height + 1)
-           {
-             sprintf (buf, "%03Xx", (first_idx + i * cols) / 16);
-             XDrawImageString (display, win, gc_norm, x, y, buf, 4);
-           }
-         x += font_width * 4 + 1;
-         y = (margin * 3 + rendering_area_height + charmap_area_height
-              + font_height + 2);
-         for (i = 0; i < rows; i++)
-           for (j = 0; j < cols; j++)
-             {
-               unsigned index = first_idx + i * cols + j;
-
-               XClearArea (display, win, x + (max_glyph_width + 1) * j,
-                           y + (max_glyph_height + 1) * i,
-                           max_glyph_width, max_glyph_height, False);
-               if (charmap_index >= 0)
-                 index = FT_Get_Char_Index (face, (FT_ULong) index);
-
-               draw_bitmap (index,
-                            x + (max_glyph_width + 1) * j - x0,
-                            y + (max_glyph_height + 1) * i - y0);
-             }
-       }
-      update_mask = 0;
-    }
+  XtRealizeWidget (shell);
+  XtAppMainLoop (context);
 
- finish:
-  OTF_close (otf);
   exit (0);
 }
diff --git a/example/otfviewx.c b/example/otfviewx.c
deleted file mode 100644 (file)
index b992e3d..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Shell.h>
-#include <X11/Xaw/Command.h>
-#include <X11/Xaw/Toggle.h>
-#include <X11/Xaw/Box.h>
-#include <X11/Xaw/Form.h>
-#include <X11/Xaw/Viewport.h>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#include <otf.h>
-
-#define DEFAULT_PIXEL_SIZE 30
-#define DEFAULT_FONT_NAME "6x13"
-XFontStruct *font;
-#define FONT_HEIGHT (font->ascent + font->descent)
-
-XtAppContext context;
-/* Widget structure.
-   +--- frame (form) ------------------+
-   | +--- command_area (box) --------+ |
-   | | quit charmap ...              | |
-   | +-------------------------------+ |
-   | +---- navi_area (box) ----------+ |
-   | | PREV prev label next NEXT     | |
-   | +-------------------------------+ |
-   | +--- glyph_area (form) ---------+ |
-   | | glyph[0]     ...    glyph[15] | |
-   | |   ...                 ...     | |
-   | | glyph[112]   ...    glyph[127]| |
-   | +-------------------------------+ |
-   | +--- render_area (form) --------+ |
-   | | clear                         | |
-   | | +--- raw (box) -------------+ | |
-   | | | raw_label raw_image       | | |
-   | | +--- seq (box) -------------+ | |
-   | | | seq_label seq_image       | | |
-   | | +--- gsub (box) ------------+ | |
-   | | | gsub_label gsub_image     | | |
-   | | +--- gpos (box) ------------+ | |
-   | | | gpos_label gpos_image     | | |
-   | | +---------------------------+ | |
-   | +-------------------------------+ |
-   +-----------------------------------+ */
-Widget shell, frame;
-Widget command_area, quit, *charmap;
-Widget navi_area, PREV, prev, label, next, NEXT;
-Widget glyph_area, glyph[128];
-Widget render_area, clear, raw, seq, gsub, gpos;
-Widget raw_label, raw_image, seq_label, seq_image;
-Widget gsub_label, gsub_image, gpos_label, gpos_image;
-
-int glyph_char[128];
-
-Display *display;
-GC gc, gc_set, gc_or;
-
-typedef struct {
-  Pixmap pixmap;
-  unsigned width, height;
-  int x, y;
-  int advance;
-} BitmapRec;
-
-BitmapRec bitmap[0x10000];
-
-int render_width, render_height;
-Pixmap raw_pixmap, seq_pixmap, gsub_pixmap, gpos_pixmap;
-
-FT_Face face;
-
-struct {
-  int platform_id;
-  int encoding_id;
-  char name[20];
-} charmap_rec[10];
-
-int charmap_index;
-
-unsigned glyph_width, glyph_height;
-int glyph_x, glyph_y;
-int glyph_index;
-
-struct {
-  int n_glyphs;
-  int glyphs[64];
-} glyph_rec;  
-
-OTF *otf;
-
-void
-create_pixmap (int pixel_size, int index)
-{
-  int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
-  XImage ximage;
-  Pixmap pixmap;
-  
-  if (err)
-    {
-      bitmap[index].pixmap = (Pixmap) 0;
-      return;
-    }
-  ximage.height = face->glyph->bitmap.rows;
-  ximage.width = face->glyph->bitmap.width;
-  ximage.depth = 1;
-  ximage.bits_per_pixel = 1;
-  ximage.xoffset = 0;
-  ximage.format = XYPixmap;
-  ximage.data = (char *) face->glyph->bitmap.buffer;
-  ximage.byte_order = MSBFirst;
-  ximage.bitmap_unit = 8;
-  ximage.bitmap_bit_order = MSBFirst;
-  ximage.bitmap_pad = 8;
-  ximage.bytes_per_line = face->glyph->bitmap.pitch;
-  XInitImage (&ximage);
-  pixmap = XCreatePixmap (display, DefaultRootWindow (display),
-                         glyph_width, glyph_height, 1);
-  XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, glyph_height);
-  XPutImage (display, pixmap, gc, &ximage, 0, 0,
-            glyph_x + face->glyph->bitmap_left,
-            glyph_y - face->glyph->bitmap_top,
-            ximage.width, ximage.height);
-  bitmap[index].pixmap = pixmap;
-  bitmap[index].width = ximage.width;
-  bitmap[index].height = ximage.height;
-  bitmap[index].x = face->glyph->bitmap_left;
-  bitmap[index].y = - face->glyph->bitmap_top;
-  bitmap[index].advance = face->glyph->metrics.horiAdvance >> 6;
-}
-
-void
-update_glyph_area ()
-{
-  int i;
-  Arg arg[2];
-  char buf[16];
-
-  for (i = 0; i < 128; i++)
-    {
-      int index = glyph_index + i;
-      int num_args = 0;
-
-      if (charmap_index >= 0)
-       index = FT_Get_Char_Index (face, (FT_ULong) index);
-      XtSetArg (arg[num_args], XtNbitmap, bitmap[index].pixmap), num_args++;
-      if (! bitmap[index].pixmap)
-       XtSetArg (arg[num_args], XtNlabel, "none"), num_args++;
-      XtSetValues (glyph[i], arg, num_args);
-    }
-
-  sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
-  XtSetArg (arg[0], XtNlabel, buf);
-  XtSetValues (label, arg, 1);
-}
-
-void
-update_render_area ()
-{
-  int i;
-  int x;
-  Arg arg[1];
-
-  XFillRectangle (display, raw_pixmap, gc, 0, 0, render_width, render_height);
-  XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
-  for (i = 0, x = glyph_x; i < glyph_rec.n_glyphs; i++)
-    {
-      BitmapRec *bmp = bitmap + glyph_rec.glyphs[i];
-
-      XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
-                0, 0, glyph_width, glyph_height,
-                (glyph_width + 1) * i + 1, 1);
-      XDrawRectangle (display, raw_pixmap, gc_set,
-                     (glyph_width + 1) * i, 0,
-                     glyph_width + 1, glyph_height + 1);
-      XCopyArea (display, bmp->pixmap, seq_pixmap, gc_or,
-                glyph_x + bmp->x, glyph_y + bmp->y, bmp->width, bmp->height,
-                x + bmp->x, glyph_y + bmp->y);
-      x += bmp->advance;
-    }
-  XtSetArg (arg[0], XtNbitmap, raw_pixmap);
-  XtSetValues (raw_image, arg, 1);
-  XtSetArg (arg[0], XtNbitmap, seq_pixmap);
-  XtSetValues (seq_image, arg, 1);
-  if (! otf)
-    return;
-  XFillRectangle (display, gsub_pixmap, gc, 0, 0, render_width, render_height);
-  XFillRectangle (display, gpos_pixmap, gc, 0, 0, render_width, render_height);
-  XtSetArg (arg[0], XtNbitmap, gsub_pixmap);
-  XtSetValues (gsub_image, arg, 1);
-  XtSetArg (arg[0], XtNbitmap, gpos_pixmap);
-  XtSetValues (gpos_image, arg, 1);
-}
-
-void
-QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
-{
-  XtAppSetExitFlag (XtWidgetToApplicationContext (w));
-}
-
-void
-GlyphProc (Widget w, XtPointer client_data, XtPointer call_data)
-{
-  int old_glyph_index = glyph_index;
-
-  if ((int) client_data == -2 && glyph_index > 0)
-    glyph_index = (glyph_index - 1) & 0xF000;
-  else if ((int) client_data == -1 && glyph_index > 0)
-    glyph_index -= 0x80;
-  else if ((int) client_data == 1 && glyph_index < 0xFF80)
-    glyph_index += 0x80;
-  else if ((int) client_data == 2 && glyph_index < 0xF000)
-    glyph_index = (glyph_index + 0x1000) & 0xF000;
-  if (glyph_index != old_glyph_index)
-    update_glyph_area ();
-}
-
-void
-CharmapProc (Widget w, XtPointer client_data, XtPointer call_data)
-{
-  if (charmap_index == (int) client_data)
-    return;
-  charmap_index = (int) client_data;
-  if (charmap_index >= 0)
-    FT_Set_Charmap (face, face->charmaps[charmap_index]);
-  update_glyph_area ();
-}
-
-void
-RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
-{
-  if ((int) client_data < 0)
-    {
-      glyph_rec.n_glyphs = 0;
-      update_render_area ();
-    }
-  else if (glyph_rec.n_glyphs < 64)
-    {
-      int index = glyph_index + (int) client_data;
-      if (charmap_index >= 0)
-       index = FT_Get_Char_Index (face, (FT_ULong) index);
-      glyph_rec.glyphs[glyph_rec.n_glyphs++] = index;
-      update_render_area ();
-    }
-}
-
-void
-create_widgets ()
-{
-  String quit_action = "<KeyPress>q: set() notify() unset()";
-  String PREV_action = "Shift<KeyPress>p: set() notify() unset()";
-  String prev_action = "~Shift<KeyPress>p: set() notify() unset()";
-  String next_action = "~Shift<KeyPress>n: set() notify() unset()";
-  String NEXT_action = "Shift<KeyPress>n: set() notify() unset()";
-  Arg arg[10];
-  int i, j;
-
-  frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, NULL, 0);
-  XtSetArg (arg[0], XtNleft, XawChainLeft);
-  XtSetArg (arg[1], XtNright, XawChainLeft);
-  XtSetArg (arg[2], XtNtop, XawChainTop);
-  XtSetArg (arg[3], XtNbottom, XawChainTop);
-  XtSetArg (arg[4], XtNborderWidth, 0);
-  XtSetArg (arg[5], XtNorientation, XtorientHorizontal);
-  command_area = XtCreateManagedWidget ("command-area", boxWidgetClass,
-                                       frame, arg, 6);
-  XtSetArg (arg[6], XtNfromVert, command_area);
-  navi_area = XtCreateManagedWidget ("navi-area", boxWidgetClass,
-                                    frame, arg, 7);
-  XtSetArg (arg[4], XtNborderWidth, 1);
-  XtSetArg (arg[5], XtNfromVert, navi_area);
-  XtSetArg (arg[6], XtNdefaultDistance, 0);
-  glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
-                                     frame, arg, 7);
-  XtSetArg (arg[4], XtNborderWidth, 0);
-  XtSetArg (arg[5], XtNfromVert, glyph_area);
-  render_area = XtCreateManagedWidget ("render-area", formWidgetClass,
-                                      frame, arg, 6);
-
-  XtSetArg (arg[0], XtNaccelerators, XtParseAcceleratorTable (quit_action));
-  quit = XtCreateManagedWidget ("quit", commandWidgetClass,
-                               command_area, arg, 1);
-  XtAddCallback (quit, XtNcallback, QuitProc, NULL);
-
-  charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
-  XtSetArg (arg[0], XtNstate, True);
-  charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, toggleWidgetClass,
-                                     command_area, arg, 1);
-  XtAddCallback (charmap[0], XtNcallback, CharmapProc, (XtPointer) -1);
-  XtSetArg (arg[0], XtNradioGroup, charmap[0]);
-  for (i = 0; i < face->num_charmaps; i++)
-    {
-      charmap[i + 1] = XtCreateManagedWidget (charmap_rec[i + 1].name,
-                                             toggleWidgetClass,
-                                             command_area, arg, 1);
-      XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i);
-    }
-
-  XtSetArg (arg[0], XtNlabel, "<< (P)");
-  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
-  PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
-                               navi_area, arg, 2);
-  XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
-  XtSetArg (arg[0], XtNlabel, "< (p)");
-  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
-  prev = XtCreateManagedWidget ("prev", commandWidgetClass,
-                               navi_area, arg, 2);
-  XtAddCallback (prev, XtNcallback, GlyphProc, (XtPointer) -1);
-  XtSetArg (arg[0], XtNlabel, " 0000 ");
-  label = XtCreateManagedWidget ("label", labelWidgetClass,
-                                navi_area, arg, 1);
-  XtSetArg (arg[0], XtNlabel, "(n) >");
-  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
-  next = XtCreateManagedWidget ("next", commandWidgetClass,
-                               navi_area, arg, 2);
-  XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
-  XtSetArg (arg[0], XtNlabel, "(N) >>");
-  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
-  NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
-                               navi_area, arg, 2);
-  XtAddCallback (NEXT, XtNcallback, GlyphProc, (XtPointer) 2);
-
-  XtSetArg (arg[0], XtNleft, XawChainLeft);
-  XtSetArg (arg[1], XtNright, XawChainLeft);
-  XtSetArg (arg[2], XtNtop, XawChainTop);
-  XtSetArg (arg[3], XtNbottom, XawChainTop);
-  for (i = 0; i < 8; i++)
-    for (j = 0; j < 16; j++)
-      {
-       int k = i * 16 + j;
-       int num_args = 4;
-
-       XtSetArg (arg[num_args], XtNwidth, glyph_width), num_args++;
-       XtSetArg (arg[num_args], XtNheight, glyph_height), num_args++;
-       if (j > 0)
-         XtSetArg (arg[num_args], XtNfromHoriz, glyph[k - 1]), num_args++;
-       if (i > 0)
-         XtSetArg (arg[num_args], XtNfromVert, glyph[k - 16]), num_args++;
-       glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
-                                         glyph_area, arg, num_args);
-       XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k);
-      }
-
-  XtSetArg (arg[0], XtNleft, XawChainLeft);
-  XtSetArg (arg[1], XtNright, XawChainLeft);
-  XtSetArg (arg[2], XtNtop, XawChainTop);
-  XtSetArg (arg[3], XtNbottom, XawChainTop);
-  clear = XtCreateManagedWidget ("clear", commandWidgetClass,
-                                render_area, arg, 4);
-  XtAddCallback (clear, XtNcallback, RenderProc, (XtPointer) -1);
-  XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
-  XtSetArg (arg[5], XtNborderWidth, 0);
-  XtSetArg (arg[6], XtNfromVert, clear);
-  raw = XtCreateManagedWidget ("raw", boxWidgetClass,
-                               render_area, arg, 7);
-  XtSetArg (arg[0], XtNborderWidth, 0);
-  XtSetArg (arg[1], XtNlabel, "raw: ");
-  raw_label = XtCreateManagedWidget ("raw-label", labelWidgetClass,
-                                     raw, arg, 2);
-  XtSetArg (arg[1], XtNbitmap, raw_pixmap);
-  raw_image = XtCreateManagedWidget ("raw-image", labelWidgetClass,
-                                     raw, arg, 2);
-  XtSetArg (arg[6], XtNfromVert, raw);
-  seq = XtCreateManagedWidget ("seq", boxWidgetClass,
-                               render_area, arg, 7);
-  XtSetArg (arg[0], XtNborderWidth, 0);
-  XtSetArg (arg[1], XtNlabel, "seq: ");
-  seq_label = XtCreateManagedWidget ("seq-label", labelWidgetClass,
-                                     seq, arg, 2);
-  XtSetArg (arg[1], XtNbitmap, seq_pixmap);
-  seq_image = XtCreateManagedWidget ("seq-image", labelWidgetClass,
-                                     seq, arg, 2);
-  if (otf)
-    {
-      XtSetArg (arg[6], XtNfromVert, seq);
-      gsub = XtCreateManagedWidget ("gsub", boxWidgetClass,
-                                   render_area, arg, 7);
-      XtSetArg (arg[0], XtNborderWidth, 0);
-      XtSetArg (arg[1], XtNlabel, "gsub: ");
-      gsub_label = XtCreateManagedWidget ("gsub-label", labelWidgetClass,
-                                         gsub, arg, 2);
-      gsub_image = XtCreateManagedWidget ("gsub-image", labelWidgetClass,
-                                         gsub, arg, 1);
-      XtSetArg (arg[6], XtNfromVert, gsub);
-      gpos = XtCreateManagedWidget ("gpos", boxWidgetClass,
-                                   render_area, arg, 7);
-      XtSetArg (arg[0], XtNborderWidth, 0);
-      XtSetArg (arg[1], XtNlabel, "gpos: ");
-      gpos_label = XtCreateManagedWidget ("gpos-label", labelWidgetClass,
-                                         gpos, arg, 2);
-      gpos_image = XtCreateManagedWidget ("gpos-image", labelWidgetClass,
-                                         gpos, arg, 1);
-    }
-
-  XtInstallAllAccelerators (frame, frame);
-}
-
-
-/* Format MSG by FMT and print the result to the stderr, and exit.  */
-
-#define FATAL_ERROR(fmt, arg)  \
-  do {                         \
-    fprintf (stderr, fmt, arg);        \
-    exit (1);                  \
-  } while (0)
-
-int
-main (int argc, char **argv)
-{
-  FT_Library library;
-
-  OTF_GlyphString gstring;
-  OTF_Glyph *g;
-
-  int err;
-  int i;
-  int pixel_size = DEFAULT_PIXEL_SIZE;
-
-  gstring.size = gstring.used = 256;
-  g = calloc (256, sizeof (OTF_Glyph));
-  gstring.glyphs = g;
-
-  shell = XtOpenApplication (&context, "OTFView", NULL, 0, &argc, argv, NULL,
-                            shellWidgetClass, NULL, 0);
-  display = XtDisplay (shell);
-
-  if (argc != 2)
-    FATAL_ERROR ("%s\n", "Usage: otfview [ X-OPTION ... ]  OTF-FILE");
-  
-  if (strstr (argv[1], ".ttf")
-      || strstr (argv[1], ".TTF")
-      || strstr (argv[1], ".otf")
-      || strstr (argv[1], ".OTF"))
-    {
-      otf = OTF_open (argv[1]);
-      if (! otf
-         || OTF_get_table (otf, "head") < 0
-         || OTF_get_table (otf, "cmap") < 0
-         || (OTF_get_table (otf, "gsub") < 0
-             && OTF_get_table (otf, "gpos") < 0))
-       otf = NULL;
-    }
-
-  if ((err = FT_Init_FreeType (&library)))
-    FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
-  err = FT_New_Face (library, argv[1], 0, &face);
-  if (err == FT_Err_Unknown_File_Format)
-    FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
-  else if (err)
-    FATAL_ERROR ("%s\n", "FT_New_Face: unknown error");
-  if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
-    FATAL_ERROR ("%s\n", "FT_Set_Char_Size: error");
-
-  glyph_width = ((face->bbox.xMax - face->bbox.xMin)
-                * pixel_size / face->units_per_EM);
-  glyph_height = ((face->bbox.yMax - face->bbox.yMin)
-                 *  pixel_size / face->units_per_EM);
-  glyph_x = - (face->bbox.xMin * pixel_size / face->units_per_EM);
-  glyph_y = face->bbox.yMax * pixel_size / face->units_per_EM;
-
-  charmap_rec[0].platform_id = -1;
-  charmap_rec[0].encoding_id = -1;
-  strcpy (charmap_rec[0].name, "no charmap");
-
-  for (i = 0; i < face->num_charmaps; i++)
-    {
-      charmap_rec[i + 1].platform_id = face->charmaps[i]->platform_id;
-      charmap_rec[i + 1].encoding_id = face->charmaps[i]->encoding_id;
-      sprintf (charmap_rec[i + 1].name, "%d-%d",
-              charmap_rec[i + 1].platform_id, charmap_rec[i + 1].encoding_id);
-      if (face->charmaps[i]->platform_id == 0
-         || (face->charmaps[i]->platform_id == 3
-             && face->charmaps[i]->encoding_id == 1))
-       strcat (charmap_rec[i + 1].name, " (unicode)");
-      else if (face->charmaps[i]->platform_id == 1
-              && face->charmaps[i]->encoding_id == 0)
-       strcat (charmap_rec[i + 1].name, " (apple-roman)");
-    }
-
-  render_width = (glyph_width + 1) * 15 + 1;
-  render_height = glyph_height + 2;
-  raw_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
-                             render_width, render_height, 1);
-  seq_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
-                             render_width, render_height, 1);
-  gsub_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
-                              render_width, render_height, 1);
-  gpos_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
-                              render_width, render_height, 1);
-  {
-    unsigned long valuemask =  GCFunction | GCLineWidth;
-    XGCValues values;
-
-    gc = XCreateGC (display, raw_pixmap, (unsigned long) 0, NULL);
-    values.function = GXset;
-    values.line_width = 1;
-    gc_set = XCreateGC (display, raw_pixmap, valuemask, &values);
-    values.function = GXor;
-    gc_or = XCreateGC (display, raw_pixmap, valuemask, &values);
-  }
-
-  for (i = 0; i < 0x10000; i++)
-    create_pixmap (pixel_size, i);
-  create_widgets ();
-  glyph_index = 0;
-  charmap_index = -1;
-  update_glyph_area ();
-  update_render_area ();
-
-  XtRealizeWidget (shell);
-  XtAppMainLoop (context);
-
-  exit (0);
-}