Big change to implement driving OpenType
authorhanda <handa>
Mon, 12 Jul 2004 01:51:49 +0000 (01:51 +0000)
committerhanda <handa>
Mon, 12 Jul 2004 01:51:49 +0000 (01:51 +0000)
tables (GSUB and GPOS).

example/otfview.c

index 8ada490..b6bc94a 100644 (file)
@@ -57,33 +57,42 @@ XtAppContext context;
    | | quit dump charmap ...                | |
    | +--------------------------------------+ |
    | +---- navi_area (box) -----------------+ |
-   | | FIRST PREV prev label next NEXT LAST | |
+   | | FIRST PREV prev range next NEXT LAST | |
    | +--------------------------------------+ |
    | +--- glyph_area (form) ----------------+ |
-   | | glyph[0]        ...        glyph[15] | |
+   | | idxh[0] glyph[0]    ...    glyph[15] | |
    | |   ...                        ...     | |
-   | | glyph[112]      ...        glyph[127]| |
+   | | idxh[7] glyph[112]  ...    glyph[127]| |
+   | |         idxl[0]     ...    idxl[15]  | |
    | +--------------------------------------+ |
    | +--- render_area (form) ---------------+ |
-   | | clear                                | |
+   | | clear del                            | |
    | | +--- raw (box) --------------------+ | |
    | | | raw_label raw_image              | | |
+   | | +----------------------------------+ | |
+   | | GSUB all none features...            | |
+   | | GPOS all none features...            | |
    | | +--- 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, dump, *charmap;
-Widget navi_area, FIRST, PREV, prev, label, next, NEXT, LAST;
-Widget glyph_area, glyph[128];
-Widget render_area, clear, raw, seq, gsub, gpos;
+Widget navi_area, FIRST, PREV, prev, range, next, NEXT, LAST;
+Widget glyph_area, glyph[128], index_label[8];
+Widget render_area, clear, del, raw, seq;
 Widget raw_label, raw_image, seq_label, seq_image;
-Widget gsub_label, gsub_image, gpos_label, gpos_image;
+unsigned long foreground, background;
+
+typedef struct
+{
+  int idx;
+  int on;
+  Widget w;
+} FeatureRec;
+
+FeatureRec gsub[64], gpos[64];
 
 int glyph_char[128];
 
@@ -132,8 +141,6 @@ create_pixmap (int pixel_size, int index)
   int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
   XImage ximage;
   Pixmap pixmap;
-  int height = glyph_height + 1 + FONT_HEIGHT;
-  char index_buf[5];
   
   if (err)
     {
@@ -154,18 +161,12 @@ create_pixmap (int pixel_size, int index)
   ximage.bytes_per_line = face->glyph->bitmap.pitch;
   XInitImage (&ximage);
   pixmap = XCreatePixmap (display, DefaultRootWindow (display),
-                         glyph_width, height, 1);
-  XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, height);
+                         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);
-  sprintf (index_buf, "%04X", index);
-  XDrawLine (display, pixmap, gc_inv,
-            0, glyph_height + 1, glyph_width, glyph_height + 1);
-  XDrawString (display, pixmap, gc_inv,
-              (glyph_width - XTextWidth (font, index_buf, 4)) / 2,
-              height - FONT_DESCENT, index_buf, 4);
   bitmap[index].pixmap = pixmap;
   bitmap[index].width = ximage.width;
   bitmap[index].height = ximage.height;
@@ -180,6 +181,7 @@ update_glyph_area ()
   int i;
   Arg arg[2];
   char buf[16];
+  int msb;
 
   for (i = 0; i < 128; i++)
     {
@@ -194,11 +196,109 @@ update_glyph_area ()
       XtSetValues (glyph[i], arg, 1);
     }
 
+  msb = (glyph_index >> 7) % 2 ? 8 : 0;
+  for (i = 0; i < 8; i++)
+    {
+      char str[3];
+
+      sprintf (str, "%XX", i | msb );
+      XtSetArg (arg[0], XtNheight, glyph_height + 5);
+      XtSetArg (arg[1], XtNlabel, str);
+      XtSetValues (index_label[i], arg, 2);
+    }
+
   sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
   XtSetArg (arg[0], XtNlabel, buf);
-  XtSetValues (label, arg, 1);
+  XtSetValues (range, arg, 1);
 }
 
+char *
+get_features (OTF_FeatureList *list, FeatureRec *features)
+{
+  int len = list->FeatureCount;
+  int i, n;
+  char *str, *p;
+
+  if (! features[0].on)
+    return NULL;
+  for (i = n = 0; i < len; i++)
+    {
+      if (features[i].on)
+       n++;
+      else
+       break;
+    }
+  if (i == len)
+    {
+      str = malloc (2);
+      strcpy (str, "*");
+      return str;
+    }
+  str = malloc (n * 5);
+  for (i = 0, p = str; i < len ; i++, p += 5)
+    if (features[i].on)
+      {
+       OTF_tag_name (list->Feature[features[i].idx].FeatureTag, p);
+       p[4] = ',';
+      }
+  p[-1] = '\0';
+  return str;
+}
+
+
+void
+update_seq_area ()
+{
+  int i, x;
+  OTF_GlyphString gstring;
+  int len = glyph_rec.n_glyphs;
+  Arg arg[1];
+
+  gstring.size = gstring.used = len;
+  gstring.glyphs = alloca (sizeof (OTF_Glyph) * len);
+  memset (gstring.glyphs, 0, sizeof (OTF_Glyph) * len);
+  for (i = 0; i < len; i++)
+    gstring.glyphs[i].c = gstring.glyphs[i].glyph_id = glyph_rec.glyphs[i];
+
+  XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
+  if (otf)
+    {
+      char *str;
+
+      if (otf->gsub)
+       {
+         str = get_features (&otf->gsub->FeatureList, gsub);
+         if (str)
+           {
+             OTF_drive_gsub (otf, &gstring, NULL, NULL, str);
+             free (str);
+           }
+       }
+      if (otf->gpos)
+       {
+         str = get_features (&otf->gpos->FeatureList, gpos);
+         if (str)
+           {
+             OTF_drive_gpos (otf, &gstring, NULL, NULL, str);
+             free (str);
+           }
+       }
+    }
+
+  for (i = 0, x = glyph_x; i < gstring.used; i++)
+    {
+      BitmapRec *bmp = bitmap + gstring.glyphs[i].glyph_id;
+
+      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, seq_pixmap);
+  XtSetValues (seq_image, arg, 1);
+}
+
+
 void
 update_render_area ()
 {
@@ -207,7 +307,6 @@ update_render_area ()
   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];
@@ -215,16 +314,16 @@ update_render_area ()
 
       XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
                 0, 0, glyph_width, glyph_height,
-                (glyph_width + 1) * i + 1, 1);
+                (glyph_width + 4) * i + 1, 1);
       XDrawRectangle (display, raw_pixmap, gc_set,
-                     (glyph_width + 1) * i, 0,
+                     (glyph_width + 4) * i, 0,
                      glyph_width + 1, glyph_height + 1);
       XDrawLine (display, raw_pixmap, gc_set,
-                (glyph_width + 1) * i + 1 + glyph_x, 1,
-                (glyph_width + 1) * i + 1 + glyph_x, glyph_height + 1);
+                (glyph_width + 4) * i + 1 + glyph_x, 1,
+                (glyph_width + 4) * i + 1 + glyph_x, glyph_height + 1);
       XDrawLine (display, raw_pixmap, gc_set,
-                (glyph_width + 1) * i + 1 + glyph_x + bmp->advance, 1,
-                (glyph_width + 1) * i + 1 + glyph_x + bmp->advance,
+                (glyph_width + 4) * i + 1 + glyph_x + bmp->advance, 1,
+                (glyph_width + 4) * i + 1 + glyph_x + bmp->advance,
                 glyph_height + 1);
 
       sprintf (buf, "%04X", glyph_rec.codes[i]);
@@ -232,23 +331,10 @@ update_render_area ()
                   (glyph_width + 1) * i + 1
                   + (glyph_width - XTextWidth (font, buf, 4)) / 2,
                   glyph_height + 2 + FONT_HEIGHT, buf, 4);
-      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);
+  update_seq_area ();
 }
 
 void
@@ -423,8 +509,14 @@ RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
 {
   if ((int) client_data < 0)
     {
-      glyph_rec.n_glyphs = 0;
-      update_render_area ();
+      if (glyph_rec.n_glyphs > 0)
+       {
+         if ((int) client_data == -2)
+           glyph_rec.n_glyphs--;
+         else
+           glyph_rec.n_glyphs = 0;
+         update_render_area ();
+       }
     }
   else if (glyph_rec.n_glyphs < 64)
     {
@@ -442,6 +534,134 @@ RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
 }
 
 void
+FeatureProc (OTF_FeatureList *list, FeatureRec *features, int idx)
+{
+  int i, j;
+  Arg arg[3];
+
+  if (idx < 0)
+    {
+      int on = idx == -2;
+
+      for (idx = 0; idx < list->FeatureCount; idx++)
+       {
+         features[idx].idx = idx;
+         features[idx].on = on;
+       }
+      i = 0, j = list->FeatureCount - 1;
+    }
+  else
+    {
+      i = idx;
+      idx = features[i].idx;
+
+      if (features[i].on)
+       {
+         for (j = i; j + 1 < list->FeatureCount && features[j + 1].on; j++)
+           features[j].idx = features[j + 1].idx;
+         features[j].idx = idx;
+         features[j].on = 0;
+       }
+      else
+       {
+         for (j = i; i > 0 && ! features[i - 1].on; i--)
+           features[i].idx = features[i - 1].idx;
+         features[i].idx = idx;
+         features[i].on = 1;
+       }
+    }
+
+  for (; i <= j; i++)
+    {
+      char str[5];
+
+      OTF_tag_name (list->Feature[features[i].idx].FeatureTag, str);
+      XtSetArg (arg[0], XtNlabel, str);
+      if (features[i].on)
+       {
+         XtSetArg (arg[1], XtNforeground, background);
+         XtSetArg (arg[2], XtNbackground, foreground);
+       }
+      else
+       {
+         XtSetArg (arg[1], XtNforeground, foreground);
+         XtSetArg (arg[2], XtNbackground, background);
+       }
+      XtSetValues (features[i].w, arg, 3);
+    }
+  update_seq_area ();
+}
+
+void
+GsubProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+  FeatureProc (&otf->gsub->FeatureList, gsub, (int) client_data);
+}             
+
+void
+GposProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+  FeatureProc (&otf->gpos->FeatureList, gpos, (int) client_data);
+}
+
+Widget
+create_otf_widgets (int flag, Widget prev)
+{
+  char *label;
+  OTF_FeatureList *list;
+  XtCallbackProc proc;
+  FeatureRec *features;
+  Arg arg[10];
+  Widget w;
+  char *box_label, feature_label[5];
+  int i;
+
+  if (flag)
+    {
+      label = "GSUB";
+      list = &otf->gsub->FeatureList;
+      proc = GsubProc;
+      features = gsub;
+    }
+  else
+    {
+      label = "GPOS";
+      list = &otf->gpos->FeatureList;
+      proc = GposProc;
+      features = gpos;
+    }
+  box_label = alloca (strlen (label) + 4);
+
+  strcpy (box_label, label);
+  strcat (box_label, "box");
+
+  XtSetArg (arg[0], XtNborderWidth, 0);
+  XtSetArg (arg[1], XtNleft, XawChainLeft);
+  XtSetArg (arg[2], XtNright, XawChainLeft);
+  XtSetArg (arg[3], XtNtop, XawChainTop);
+  XtSetArg (arg[4], XtNbottom, XawChainTop);
+  XtSetArg (arg[5], XtNfromVert, prev);
+  XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
+  prev = XtCreateManagedWidget (box_label, boxWidgetClass, render_area, arg, 7);
+  XtCreateManagedWidget (label, labelWidgetClass, prev, arg, 1);
+  w = XtCreateManagedWidget ("all", commandWidgetClass, prev, NULL, 0);
+  XtAddCallback (w, XtNcallback, proc, (XtPointer) -2);
+  w = XtCreateManagedWidget ("none", commandWidgetClass, prev, NULL, 0);
+  XtAddCallback (w, XtNcallback, proc, (XtPointer) -1);
+  for (i = 0; i < list->FeatureCount; i++)
+    {
+      OTF_tag_name (list->Feature[i].FeatureTag, feature_label);
+      features[i].idx = i;
+      w = XtCreateManagedWidget (feature_label, commandWidgetClass, prev,
+                                NULL, 0);
+      XtAddCallback (w, XtNcallback, proc, (XtPointer) i);
+      features[i].w = w;
+    }
+
+  return prev;
+}
+
+void
 create_widgets (int pixel_size)
 {
   String quit_action = "<KeyPress>q: set() notify() unset()";
@@ -453,7 +673,7 @@ create_widgets (int pixel_size)
   String LAST_action = "~Shift<KeyPress>l: set() notify() unset()";
   Arg arg[10];
   int i, j;
-  int glyph_widget_height;
+  Widget prev, w;
 
   frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, NULL, 0);
   XtSetArg (arg[0], XtNleft, XawChainLeft);
@@ -467,12 +687,11 @@ create_widgets (int pixel_size)
   XtSetArg (arg[6], XtNfromVert, command_area);
   navi_area = XtCreateManagedWidget ("navi-area", boxWidgetClass,
                                     frame, arg, 7);
-  XtSetArg (arg[4], XtNborderWidth, 1);
+  XtSetArg (arg[4], XtNborderWidth, 0);
   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);
@@ -516,8 +735,12 @@ create_widgets (int pixel_size)
                                navi_area, arg, 2);
   XtAddCallback (prev, XtNcallback, GlyphProc, (XtPointer) -1);
   XtSetArg (arg[0], XtNlabel, " 0000 ");
-  label = XtCreateManagedWidget ("label", labelWidgetClass,
+  range = XtCreateManagedWidget ("range", labelWidgetClass,
                                 navi_area, arg, 1);
+  XtSetArg (arg[0], XtNforeground, &foreground);
+  XtSetArg (arg[1], XtNbackground, &background);
+  XtGetValues (range, arg, 2);
+
   XtSetArg (arg[0], XtNlabel, "> (n)");
   XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
   next = XtCreateManagedWidget ("next", commandWidgetClass,
@@ -534,41 +757,77 @@ create_widgets (int pixel_size)
                                navi_area, arg, 2);
   XtAddCallback (LAST, XtNcallback, GlyphProc, (XtPointer) 3);
 
-  glyph_widget_height = glyph_height + 1 + FONT_HEIGHT;
   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_widget_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++;
-       XtSetArg (arg[num_args], XtNinternalWidth, 0), num_args++;
-       glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
-                                         glyph_area, arg, num_args);
-       XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k);
-      }
+    {
+      char str[3];
+      int n = 4;
+      Widget head;
+
+      sprintf (str, "%XX", i);
+      XtSetArg (arg[n], XtNheight, glyph_height + 5), n++;
+      XtSetArg (arg[n], XtNlabel, str), n++;
+      XtSetArg (arg[n], XtNborderWidth, 0), n++;
+      if (i > 0)
+       XtSetArg (arg[n], XtNfromVert, w), n++;
+      head = XtCreateManagedWidget (str, labelWidgetClass, glyph_area, arg, n);
+      index_label[i] = head;
+      for (j = 0; j < 16; j++)
+       {
+         int k = i * 16 + j;
+
+         n = 4;
+         XtSetArg (arg[n], XtNheight, glyph_height), n++;
+         XtSetArg (arg[n], XtNwidth, glyph_width), n++;
+         if (i > 0)
+           XtSetArg (arg[n], XtNfromVert, w), n++;
+         if (j == 0)
+           XtSetArg (arg[n], XtNfromHoriz, head), n++;
+         else
+           XtSetArg (arg[n], XtNfromHoriz, glyph[k - 1]), n++;
+         XtSetArg (arg[n], XtNinternalWidth, 0), n++;
+         glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
+                                           glyph_area, arg, n);
+         XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k);
+       }
+      w = head;
+    }
+  XtSetArg(arg[4], XtNwidth, glyph_width + 2);
+  XtSetArg (arg[5], XtNfromVert, glyph[112]);
+  XtSetArg (arg[6], XtNfromHoriz, w);
+  XtSetArg (arg[7], XtNborderWidth, 0);
+
+  for (j = 0; j < 16; j++)
+    {
+      char str[3];
+
+      sprintf (str, "X%X", j);
+      XtSetArg (arg[8], XtNlabel, str);
+      w = XtCreateManagedWidget ("idx", labelWidgetClass, glyph_area, arg, 9);
+      XtSetArg (arg[6], XtNfromHoriz, w);
+    }
 
   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);
+  XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
+  XtSetArg (arg[5], XtNborderWidth, 0);
+  w = XtCreateManagedWidget ("clear-box", boxWidgetClass, render_area, arg, 6);
+  clear = XtCreateManagedWidget ("clear", commandWidgetClass, w, arg, 0);
   XtAddCallback (clear, XtNcallback, RenderProc, (XtPointer) -1);
+  del = XtCreateManagedWidget ("delete", commandWidgetClass, w, arg, 0);
+  XtAddCallback (del, XtNcallback, RenderProc, (XtPointer) -2);
+
   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[6], XtNfromVert, w);
+  raw = XtCreateManagedWidget ("raw", boxWidgetClass, render_area, arg, 7);
+
   XtSetArg (arg[0], XtNborderWidth, 0);
   XtSetArg (arg[1], XtNlabel, "raw: ");
   raw_label = XtCreateManagedWidget ("raw-label", labelWidgetClass,
@@ -576,9 +835,17 @@ create_widgets (int pixel_size)
   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);
+  w = raw;
+  if (otf)
+    {
+      if (OTF_get_table (otf, "GSUB") >= 0)
+       w = create_otf_widgets (1, w);
+      if (OTF_get_table (otf, "GPOS") >= 0)
+       w = create_otf_widgets (0, w);
+    }
+
+  XtSetArg (arg[6], XtNfromVert, w);
+  seq = XtCreateManagedWidget ("seq", boxWidgetClass, render_area, arg, 7);
   XtSetArg (arg[0], XtNborderWidth, 0);
   XtSetArg (arg[1], XtNlabel, "seq: ");
   seq_label = XtCreateManagedWidget ("seq-label", labelWidgetClass,
@@ -586,28 +853,6 @@ create_widgets (int pixel_size)
   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);
 }
 
@@ -620,6 +865,13 @@ create_widgets (int pixel_size)
     exit (1);                  \
   } while (0)
 
+static int
+x_error_handler (Display *display, XErrorEvent *error)
+{
+  return 0;
+}
+
+
 int
 main (int argc, char **argv)
 {
@@ -651,6 +903,8 @@ main (int argc, char **argv)
   shell = XtOpenApplication (&context, "OTFView", NULL, 0, &argc, argv, NULL,
                             shellWidgetClass, NULL, 0);
   display = XtDisplay (shell);
+  /*XSynchronize (display, True);*/
+  XSetErrorHandler (x_error_handler);
   display_width = DisplayWidth (display,
                                XScreenNumberOfScreen (XtScreen (shell)));
   font = XLoadQueryFont (display, DEFAULT_FONT_NAME);
@@ -673,11 +927,16 @@ main (int argc, char **argv)
       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_check_table (otf, "GSUB") < 0
+             && OTF_check_table (otf, "GPOS") < 0))
        otf = NULL;
     }
 
+  if (otf)
+    {
+      memset (gsub, 0, sizeof gsub);
+      memset (gpos, 0, sizeof gpos);
+    }
   if ((err = FT_Init_FreeType (&library)))
     FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
   err = FT_New_Face (library, filename, 0, &face);
@@ -757,8 +1016,8 @@ main (int argc, char **argv)
               (glyph_width - XTextWidth (font, "none", 4)) / 2,
               glyph_height / 2, "none", 4);
 
-  render_width = (glyph_width + 1) * 15 + 1;
-  render_height = glyph_height + FONT_HEIGHT + 2;
+  render_width = (glyph_width + 4) * 15 + 1;
+  render_height = glyph_height + 2;
 
   charmap_rec[0].platform_id = -1;
   charmap_rec[0].encoding_id = -1;
@@ -783,10 +1042,6 @@ main (int argc, char **argv)
                              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);
 
   for (i = 0; i < 0x10000; i++)
     create_pixmap (pixel_size, i);