Blame example/otfview.c

Packit daac2c
/* otfview.c -- View glyphs of OpenType fonts.
Packit daac2c
Packit daac2c
Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010
Packit daac2c
  National Institute of Advanced Industrial Science and Technology (AIST)
Packit daac2c
  Registration Number H15PRO167
Packit daac2c
Packit daac2c
This file is part of libotf.
Packit daac2c
Packit daac2c
Libotf is free software; you can redistribute it and/or modify it
Packit daac2c
under the terms of the GNU Lesser General Public License as published
Packit daac2c
by the Free Software Foundation; either version 2.1 of the License, or
Packit daac2c
(at your option) any later version.
Packit daac2c
Packit daac2c
Libotf is distributed in the hope that it will be useful, but WITHOUT
Packit daac2c
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit daac2c
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit daac2c
License for more details.
Packit daac2c
Packit daac2c
You should have received a copy of the GNU Lesser General Public
Packit daac2c
License along with this library, in a file named COPYING; if not,
Packit daac2c
write to the Free Software Foundation, Inc., 59 Temple Place, Suite
Packit daac2c
330, Boston, MA 02111-1307, USA.  */
Packit daac2c
Packit daac2c
#include <stdio.h>
Packit daac2c
#include <stdlib.h>
Packit daac2c
#include <string.h>
Packit daac2c
#include <sys/stat.h>
Packit daac2c
#include <unistd.h>
Packit daac2c
#include <libgen.h>
Packit daac2c
Packit daac2c
#include "config.h"
Packit daac2c
#ifdef HAVE_ALLOCA_H
Packit daac2c
#include <alloca.h>
Packit daac2c
#endif
Packit daac2c
Packit daac2c
#ifdef HAVE_X11_XAW_COMMAND_H
Packit daac2c
Packit daac2c
#include <X11/Xatom.h>
Packit daac2c
#include <X11/Intrinsic.h>
Packit daac2c
#include <X11/StringDefs.h>
Packit daac2c
#include <X11/Shell.h>
Packit daac2c
#include <X11/Xaw/Command.h>
Packit daac2c
#include <X11/Xaw/Toggle.h>
Packit daac2c
#include <X11/Xaw/Box.h>
Packit daac2c
#include <X11/Xaw/Form.h>
Packit daac2c
#include <X11/Xaw/Viewport.h>
Packit daac2c
Packit daac2c
#include <ft2build.h>
Packit daac2c
#include FT_FREETYPE_H
Packit daac2c
Packit daac2c
#include <otf.h>
Packit daac2c
Packit daac2c
#define CAST_FROM_XTPOINTER(TYPE, DATA, VAR)	\
Packit daac2c
  do {						\
Packit daac2c
    long TYPE temp = (long TYPE) (DATA);	\
Packit daac2c
    (VAR) = temp;				\
Packit daac2c
  } while (0)
Packit daac2c
Packit daac2c
#define XtAddCallbackWithCast(TYPE, W, PROC, VAR)		\
Packit daac2c
  do {								\
Packit daac2c
    long TYPE temp = (long TYPE) (VAR);				\
Packit daac2c
    XtAddCallback (W, XtNcallback, PROC, (XtPointer) temp);	\
Packit daac2c
  } while (0)
Packit daac2c
Packit daac2c
Packit daac2c
#define DEFAULT_PIXEL_SIZE 30
Packit daac2c
int pixel_size;
Packit daac2c
Packit daac2c
#define DEFAULT_FONT_NAME "6x13"
Packit daac2c
XFontStruct *font;
Packit daac2c
#define FONT_HEIGHT (font->ascent + font->descent)
Packit daac2c
#define FONT_ASCENT (font->ascent)
Packit daac2c
#define FONT_DESCENT (font->descent)
Packit daac2c
#define FONT_WIDTH (font->max_bounds.width)
Packit daac2c
Packit daac2c
XtAppContext context;
Packit daac2c
/* Widget structure.
Packit daac2c
   +--- frame (form) -------------------------+
Packit daac2c
   | +--- command_area (box) ---------------+ |
Packit daac2c
   | | quit dump charmap ...                | |
Packit daac2c
   | +--------------------------------------+ |
Packit daac2c
   | +---- navi_area (box) -----------------+ |
Packit daac2c
   | | FIRST PREV prev range next NEXT LAST | |
Packit daac2c
   | +--------------------------------------+ |
Packit daac2c
   | +--- glyph_area (form) ----------------+ |
Packit daac2c
   | | idxh[0] glyph[0]    ...    glyph[15] | |
Packit daac2c
   | |   ...                        ...     | |
Packit daac2c
   | | idxh[7] glyph[112]  ...    glyph[127]| |
Packit daac2c
   | |         idxl[0]     ...    idxl[15]  | |
Packit daac2c
   | +--------------------------------------+ |
Packit daac2c
   | +--- script_area (box) ----------------+ |
Packit daac2c
   | | script(langsys) DFLT ...             | |
Packit daac2c
   | +--------------------------------------+ |
Packit daac2c
   | +---- uvs_area (box) (optional) -------+ |
Packit daac2c
   | | uvs[?].w ...                         | |
Packit daac2c
   | +--------------------------------------+ |
Packit daac2c
   | +--- render_area (form) ---------------+ |
Packit daac2c
   | | clear del bidi alt_subst             | |
Packit daac2c
   | | +--- raw (box) --------------------+ | |
Packit daac2c
   | | | raw_label raw_image              | | |
Packit daac2c
   | | +----------------------------------+ | |
Packit daac2c
   | | GSUB all none features...            | |
Packit daac2c
   | | GPOS all none features...            | |
Packit daac2c
   | | +--- seq (box) --------------------+ | |
Packit daac2c
   | | | seq_label seq_image              | | |
Packit daac2c
   | | +----------------------------------+ | |
Packit daac2c
   | | +--- code (box) -------------------+ | |
Packit daac2c
   | | | code_label code_list ...         | | |   
Packit daac2c
   | | +----------------------------------+ | |
Packit daac2c
   | +--------------------------------------+ |
Packit daac2c
   +------------------------------------------+ */
Packit daac2c
Widget shell, frame;
Packit daac2c
Widget command_area, quit, dump, *charmap;
Packit daac2c
Widget navi_area, FIRST, PREV, prev, range, next, NEXT, LAST;
Packit daac2c
Widget glyph_area, glyph[128], index_label[8];
Packit daac2c
Widget uvs_area, uvs_label;
Packit daac2c
Widget render_area, clear, del, bidi, alt_subst, raw, seq, code;
Packit daac2c
Widget raw_label, raw_image, seq_label, seq_image, code_label, code_list;
Packit daac2c
unsigned long foreground, background;
Packit daac2c
Packit daac2c
typedef struct
Packit daac2c
{
Packit daac2c
  OTF_Tag tag;
Packit daac2c
  int on;
Packit daac2c
  Widget w;
Packit daac2c
} FeatureElement;
Packit daac2c
Packit daac2c
typedef struct
Packit daac2c
{
Packit daac2c
  char *label;
Packit daac2c
  OTF_GSUB_GPOS *gsub_gpos;
Packit daac2c
  OTF_LangSys *langsys;
Packit daac2c
  int num_features;
Packit daac2c
  FeatureElement *features;
Packit daac2c
  Widget parent;
Packit daac2c
} FeatureRec;
Packit daac2c
Packit daac2c
FeatureRec gsub, gpos;
Packit daac2c
Packit daac2c
/* Currently selected script and langsys.  */
Packit daac2c
OTF_Tag script_tag, langsys_tag;
Packit daac2c
Packit daac2c
int glyph_char[128];
Packit daac2c
Packit daac2c
Display *display;
Packit daac2c
GC gc, gc_set, gc_or, gc_inv;
Packit daac2c
Packit daac2c
typedef struct {
Packit daac2c
  Pixmap pixmap;
Packit daac2c
  unsigned width, height;
Packit daac2c
  int x, y;
Packit daac2c
  int advance;
Packit daac2c
} BitmapRec;
Packit daac2c
Packit daac2c
BitmapRec bitmap[0x110000];
Packit daac2c
Packit daac2c
int render_width, render_height;
Packit daac2c
Pixmap raw_pixmap, seq_pixmap, gsub_pixmap, gpos_pixmap;
Packit daac2c
Pixmap none_pixmap;
Packit daac2c
Packit daac2c
FT_Face face;
Packit daac2c
Packit daac2c
struct {
Packit daac2c
  int platform_id;
Packit daac2c
  int encoding_id;
Packit daac2c
  char name[20];
Packit daac2c
} charmap_rec[10];
Packit daac2c
Packit daac2c
int charmap_index;
Packit daac2c
Packit daac2c
int reversed;
Packit daac2c
int do_alternate_subst;
Packit daac2c
unsigned glyph_width, glyph_height;
Packit daac2c
int glyph_x, glyph_y;
Packit daac2c
int glyph_index;
Packit daac2c
Packit daac2c
struct {
Packit daac2c
  int n_glyphs;
Packit daac2c
  int glyphs[64];
Packit daac2c
  int codes[64];
Packit daac2c
} glyph_rec;
Packit daac2c
Packit daac2c
OTF_EncodingSubtable14 *sub14 = NULL;
Packit daac2c
Packit daac2c
struct {
Packit daac2c
  Widget w;
Packit daac2c
  int c;
Packit daac2c
} uvs[256];
Packit daac2c
Packit daac2c
OTF *otf;
Packit daac2c
char *filename;
Packit daac2c
int fontindex;
Packit daac2c
Packit daac2c
void
Packit daac2c
create_pixmap (int index)
Packit daac2c
{
Packit daac2c
  int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
Packit daac2c
  XImage ximage;
Packit daac2c
  Pixmap pixmap;
Packit daac2c
  
Packit daac2c
  if (err)
Packit daac2c
    {
Packit daac2c
      bitmap[index].pixmap = none_pixmap;
Packit daac2c
      return;
Packit daac2c
    }
Packit daac2c
  ximage.height = face->glyph->bitmap.rows;
Packit daac2c
  ximage.width = face->glyph->bitmap.width;
Packit daac2c
  ximage.depth = 1;
Packit daac2c
  ximage.bits_per_pixel = 1;
Packit daac2c
  ximage.xoffset = 0;
Packit daac2c
  ximage.format = XYPixmap;
Packit daac2c
  ximage.data = (char *) face->glyph->bitmap.buffer;
Packit daac2c
  ximage.byte_order = MSBFirst;
Packit daac2c
  ximage.bitmap_unit = 8;
Packit daac2c
  ximage.bitmap_bit_order = MSBFirst;
Packit daac2c
  ximage.bitmap_pad = 8;
Packit daac2c
  ximage.bytes_per_line = face->glyph->bitmap.pitch;
Packit daac2c
  XInitImage (&ximage);
Packit daac2c
  pixmap = XCreatePixmap (display, DefaultRootWindow (display),
Packit daac2c
			  glyph_width, glyph_height, 1);
Packit daac2c
  XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, glyph_height);
Packit daac2c
  XPutImage (display, pixmap, gc, &ximage, 0, 0,
Packit daac2c
	     glyph_x + face->glyph->bitmap_left,
Packit daac2c
	     glyph_y - face->glyph->bitmap_top,
Packit daac2c
	     ximage.width, ximage.height);
Packit daac2c
  bitmap[index].pixmap = pixmap;
Packit daac2c
  bitmap[index].width = ximage.width;
Packit daac2c
  bitmap[index].height = ximage.height;
Packit daac2c
  bitmap[index].x = face->glyph->bitmap_left;
Packit daac2c
  bitmap[index].y = - face->glyph->bitmap_top;
Packit daac2c
  bitmap[index].advance = face->glyph->metrics.horiAdvance >> 6;
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
update_glyph_area ()
Packit daac2c
{
Packit daac2c
  int i;
Packit daac2c
  Arg arg[2];
Packit daac2c
  char buf[16];
Packit daac2c
  int msb;
Packit daac2c
Packit daac2c
  for (i = 0; i < 128; i++)
Packit daac2c
    {
Packit daac2c
      int index = glyph_index + i;
Packit daac2c
Packit daac2c
      if (charmap_index >= 0)
Packit daac2c
	index = FT_Get_Char_Index (face, (FT_ULong) index);
Packit daac2c
      if (charmap_index >= 0 && ! index)
Packit daac2c
	XtSetArg (arg[0], XtNbitmap, none_pixmap);
Packit daac2c
      else
Packit daac2c
	{
Packit daac2c
	  if (! bitmap[index].pixmap)
Packit daac2c
	    create_pixmap (index);
Packit daac2c
	  XtSetArg (arg[0], XtNbitmap, bitmap[index].pixmap);
Packit daac2c
	}
Packit daac2c
      XtSetValues (glyph[i], arg, 1);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  msb = (glyph_index >> 7) % 2 ? 8 : 0;
Packit daac2c
  for (i = 0; i < 8; i++)
Packit daac2c
    {
Packit daac2c
      char str[3];
Packit daac2c
Packit daac2c
      sprintf (str, "%XX", i | msb );
Packit daac2c
      XtSetArg (arg[0], XtNheight, glyph_height + 5);
Packit daac2c
      XtSetArg (arg[1], XtNlabel, str);
Packit daac2c
      XtSetValues (index_label[i], arg, 2);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  if (glyph_index < 0x10000)
Packit daac2c
    sprintf (buf, "  %04X-%04X  ", glyph_index, glyph_index + 0x7F);
Packit daac2c
  else
Packit daac2c
    sprintf (buf, "%06X-%06X", glyph_index, glyph_index + 0x7F);
Packit daac2c
  XtSetArg (arg[0], XtNlabel, buf);
Packit daac2c
  XtSetValues (range, arg, 1);
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
update_uvs_area (int c)
Packit daac2c
{
Packit daac2c
  OTF_GlyphID code[256];
Packit daac2c
  Arg arg[1];
Packit daac2c
  int i;
Packit daac2c
Packit daac2c
  OTF_get_variation_glyphs (otf, c, code);
Packit daac2c
Packit daac2c
  for (i = 0; i < 256; i++)
Packit daac2c
    if (uvs[i].w)
Packit daac2c
      {
Packit daac2c
	if (code[i])
Packit daac2c
	  XtSetArg (arg[0], XtNsensitive, True);
Packit daac2c
	else
Packit daac2c
	  XtSetArg (arg[0], XtNsensitive, False);
Packit daac2c
	XtSetValues (uvs[i].w, arg, 1);
Packit daac2c
      }
Packit daac2c
}
Packit daac2c
Packit daac2c
Packit daac2c
char *
Packit daac2c
get_features (OTF_FeatureList *list, FeatureRec *rec)
Packit daac2c
{
Packit daac2c
  int i, n;
Packit daac2c
  char *str, *p;
Packit daac2c
Packit daac2c
  if (! rec->langsys || ! rec->features)
Packit daac2c
    return NULL;
Packit daac2c
  for (i = n = 0; i < rec->langsys->FeatureCount; i++)
Packit daac2c
    if (rec->features[i].on)
Packit daac2c
      n++;
Packit daac2c
  if (n == 0)
Packit daac2c
    return NULL;
Packit daac2c
  str = malloc (n * 5);
Packit daac2c
  for (i = 0, p = str; i < rec->langsys->FeatureCount; i++)
Packit daac2c
    if (rec->features[i].on)
Packit daac2c
      {
Packit daac2c
	OTF_tag_name (rec->features[i].tag, p);
Packit daac2c
	p[4] = ',';
Packit daac2c
	p += 5;
Packit daac2c
      }
Packit daac2c
  p[-1] = '\0';
Packit daac2c
  return str;
Packit daac2c
}
Packit daac2c
Packit daac2c
Packit daac2c
#define DEVICE_DELTA(table, size)					\
Packit daac2c
  (((table).DeltaValue							\
Packit daac2c
    && ((size) >= (table).StartSize && (size) <= (table).EndSize))	\
Packit daac2c
   ? (table).DeltaValue[(size) >= (table).StartSize]			\
Packit daac2c
   : 0)
Packit daac2c
Packit daac2c
void
Packit daac2c
adjust_anchor (OTF_Anchor *anchor, FT_Face ft_face,
Packit daac2c
	       OTF_Glyph *g, int *x, int *y)
Packit daac2c
{
Packit daac2c
  if (anchor->AnchorFormat == 2)
Packit daac2c
    {
Packit daac2c
      FT_Outline *outline;
Packit daac2c
      int ap = anchor->f.f1.AnchorPoint;
Packit daac2c
Packit daac2c
      FT_Load_Glyph (ft_face, (FT_UInt) g->glyph_id, FT_LOAD_MONOCHROME);
Packit daac2c
      outline = &ft_face->glyph->outline;
Packit daac2c
      if (ap < outline->n_points)
Packit daac2c
	{
Packit daac2c
	  *x = outline->points[ap].x;
Packit daac2c
	  *y = outline->points[ap].y;
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
  else if (anchor->AnchorFormat == 3)
Packit daac2c
    {
Packit daac2c
      *x += DEVICE_DELTA (anchor->f.f2.XDeviceTable, pixel_size);
Packit daac2c
      *y += DEVICE_DELTA (anchor->f.f2.YDeviceTable, pixel_size);
Packit daac2c
    }
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
update_seq_area ()
Packit daac2c
{
Packit daac2c
  int i, x;
Packit daac2c
  OTF_GlyphString gstring;
Packit daac2c
  OTF_Glyph *g, *prev, *base, *mark;
Packit daac2c
  int base_width;
Packit daac2c
  int len = glyph_rec.n_glyphs;
Packit daac2c
  Arg arg[1];
Packit daac2c
  int unitsPerEm = face->units_per_EM;
Packit daac2c
  OTF_Tag *log = NULL;
Packit daac2c
  int logsize;
Packit daac2c
Packit daac2c
  gstring.size = gstring.used = len;
Packit daac2c
  gstring.glyphs = malloc (sizeof (OTF_Glyph) * len);
Packit daac2c
  memset (gstring.glyphs, 0, sizeof (OTF_Glyph) * len);
Packit daac2c
  for (i = 0; i < len; i++)
Packit daac2c
    {
Packit daac2c
      gstring.glyphs[i].c = glyph_rec.codes[i];
Packit daac2c
      if (charmap_index < 0)
Packit daac2c
	gstring.glyphs[i].glyph_id = glyph_rec.glyphs[i];
Packit daac2c
    }
Packit daac2c
Packit daac2c
  XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
Packit daac2c
  XDrawLine (display, seq_pixmap, gc_set, 0, glyph_y, render_width, glyph_y);
Packit daac2c
  if (otf)
Packit daac2c
    {
Packit daac2c
      char *script_name = NULL, *langsys_name = NULL, buf[10];
Packit daac2c
      char *str;
Packit daac2c
Packit daac2c
      if (script_tag)
Packit daac2c
	{
Packit daac2c
	  script_name = buf;
Packit daac2c
	  OTF_tag_name (script_tag, script_name);
Packit daac2c
	}
Packit daac2c
      if (langsys_tag)
Packit daac2c
	{
Packit daac2c
	  langsys_name = buf + 5;
Packit daac2c
	  OTF_tag_name (langsys_tag, langsys_name);
Packit daac2c
	}
Packit daac2c
Packit daac2c
      OTF_drive_cmap (otf, &gstring);
Packit daac2c
      OTF_drive_gdef (otf, &gstring);
Packit daac2c
      if (otf->gsub)
Packit daac2c
	{
Packit daac2c
	  str = get_features (&otf->gsub->FeatureList, &gsub);
Packit daac2c
	  if (str)
Packit daac2c
	    {
Packit daac2c
	      if (do_alternate_subst)
Packit daac2c
		OTF_drive_gsub_alternate (otf, &gstring,
Packit daac2c
					  script_name, langsys_name, str);
Packit daac2c
	      else
Packit daac2c
		{
Packit daac2c
		  OTF_drive_gsub_with_log (otf, &gstring,
Packit daac2c
					   script_name, langsys_name, str);
Packit daac2c
		  logsize = gstring.used * 2;
Packit daac2c
		  log = alloca (sizeof (OTF_Tag) * logsize);
Packit daac2c
		  for (i = 0; i < gstring.used; i++)
Packit daac2c
		    {
Packit daac2c
		      int idx = gstring.glyphs[i].positioning_type >> 4;
Packit daac2c
		      if (idx)
Packit daac2c
			log[i] = otf->gsub->FeatureList.Feature[idx - 1].FeatureTag;
Packit daac2c
		      else
Packit daac2c
			log[i] = 0;
Packit daac2c
		    }
Packit daac2c
		}
Packit daac2c
	      free (str);
Packit daac2c
	    }
Packit daac2c
	}
Packit daac2c
      if (otf->gpos)
Packit daac2c
	{
Packit daac2c
	  str = get_features (&otf->gpos->FeatureList, &gpos);
Packit daac2c
	  if (str)
Packit daac2c
	    {
Packit daac2c
	      OTF_drive_gpos_with_log (otf, &gstring,
Packit daac2c
				       script_name, langsys_name, str);
Packit daac2c
	      if (log)
Packit daac2c
		{
Packit daac2c
		  if (logsize < gstring.used)
Packit daac2c
		    {
Packit daac2c
		      OTF_Tag *log2 = alloca (sizeof (OTF_Tag) * gstring.used);
Packit daac2c
		      memset (log2, 0, sizeof (OTF_Tag) * gstring.used);
Packit daac2c
		      memcpy (log2, log, sizeof (OTF_Tag) * logsize);
Packit daac2c
		      logsize = gstring.used;
Packit daac2c
		      log = log2;
Packit daac2c
		    }
Packit daac2c
		}
Packit daac2c
	      else
Packit daac2c
		{
Packit daac2c
		  logsize = gstring.used;
Packit daac2c
		  log = alloca (sizeof (OTF_Tag) * logsize);
Packit daac2c
		  memset (log, 0, sizeof (OTF_Tag) * logsize);
Packit daac2c
		}
Packit daac2c
	      for (i = 0; i < gstring.used; i++)
Packit daac2c
		{
Packit daac2c
		  int idx = gstring.glyphs[i].positioning_type >> 4;
Packit daac2c
		  if (idx)
Packit daac2c
		    log[i] = otf->gpos->FeatureList.Feature[idx - 1].FeatureTag;
Packit daac2c
Packit daac2c
		}
Packit daac2c
	      free (str);
Packit daac2c
	    }
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
Packit daac2c
  prev = NULL;
Packit daac2c
  if (reversed)
Packit daac2c
    {
Packit daac2c
      OTF_Glyph temp;
Packit daac2c
Packit daac2c
      for (prev = gstring.glyphs, g = gstring.glyphs + gstring.used - 1;
Packit daac2c
	   prev < g; prev++, g--)
Packit daac2c
	temp = *prev, *prev = *g, *g = temp;
Packit daac2c
      for (g = gstring.glyphs; g < gstring.glyphs + gstring.used; g++)
Packit daac2c
	if (g->GlyphClass == 3)
Packit daac2c
	  {
Packit daac2c
	    OTF_Glyph *g0;
Packit daac2c
	    prev = g++;
Packit daac2c
	    while (g < gstring.glyphs + gstring.used && g->GlyphClass == 3)
Packit daac2c
	      g++;
Packit daac2c
	    for (g0 = g; prev < g0; prev++, g0--)
Packit daac2c
	      temp = *prev, *prev = *g, *g = temp;
Packit daac2c
	  }
Packit daac2c
    }
Packit daac2c
Packit daac2c
Packit daac2c
  mark = base = NULL;
Packit daac2c
  for (i = 0, x = glyph_x, prev = NULL, g = gstring.glyphs;
Packit daac2c
       i < gstring.used; i++, prev = g++)
Packit daac2c
    {
Packit daac2c
      BitmapRec *bmp = bitmap + gstring.glyphs[i].glyph_id;
Packit daac2c
      int xoff = 0, yoff = 0;
Packit daac2c
      int prev_width;
Packit daac2c
      int advance = bmp->advance;
Packit daac2c
Packit daac2c
      if (gstring.glyphs[i].glyph_id && ! bmp->pixmap)
Packit daac2c
	{
Packit daac2c
	  create_pixmap (gstring.glyphs[i].glyph_id);
Packit daac2c
	  if (! bmp->pixmap)
Packit daac2c
	    continue;
Packit daac2c
	  advance = bmp->advance;
Packit daac2c
	}
Packit daac2c
      if (g->positioning_type & 0xF)
Packit daac2c
	{
Packit daac2c
	  while (1)
Packit daac2c
	    {
Packit daac2c
	      switch (g->positioning_type & 0xF)
Packit daac2c
		{
Packit daac2c
		case 1: case 2:
Packit daac2c
		  {
Packit daac2c
		    int format = g->f.f1.format;
Packit daac2c
Packit daac2c
		    if (format & OTF_XPlacement)
Packit daac2c
		      xoff += g->f.f1.value->XPlacement * pixel_size / unitsPerEm;
Packit daac2c
		    if (format & OTF_XPlaDevice)
Packit daac2c
		      xoff += DEVICE_DELTA (g->f.f1.value->XPlaDevice, pixel_size);
Packit daac2c
		    if (format & OTF_YPlacement)
Packit daac2c
		      yoff += g->f.f1.value->YPlacement * pixel_size / unitsPerEm;
Packit daac2c
		    if (format & OTF_YPlaDevice)
Packit daac2c
		      yoff += DEVICE_DELTA (g->f.f1.value->YPlaDevice, pixel_size);
Packit daac2c
		    if (format & OTF_XAdvance)
Packit daac2c
		      advance += g->f.f1.value->XAdvance * pixel_size / unitsPerEm;
Packit daac2c
		    if (format & OTF_XAdvDevice)
Packit daac2c
		      advance += DEVICE_DELTA (g->f.f1.value->XAdvDevice,
Packit daac2c
					       pixel_size);
Packit daac2c
		  }
Packit daac2c
		  break;
Packit daac2c
Packit daac2c
		case 3:
Packit daac2c
		  /* Not yet supported.  */
Packit daac2c
		  break;
Packit daac2c
		case 4: case 5:
Packit daac2c
		  if (! base)
Packit daac2c
		    break;
Packit daac2c
		  prev = base;
Packit daac2c
		  prev_width = base_width;
Packit daac2c
		  goto label_adjust_anchor;
Packit daac2c
		default: 		/* i.e. case 6 */
Packit daac2c
		  if (! mark)
Packit daac2c
		    break;
Packit daac2c
		  prev = mark;
Packit daac2c
		  prev_width = 0;
Packit daac2c
		label_adjust_anchor:
Packit daac2c
		  {
Packit daac2c
		    int base_x, base_y, mark_x, mark_y;
Packit daac2c
Packit daac2c
		    base_x = g->f.f4.base_anchor->XCoordinate * pixel_size / unitsPerEm;
Packit daac2c
		    base_y = g->f.f4.base_anchor->YCoordinate * pixel_size / unitsPerEm;
Packit daac2c
		    mark_x = g->f.f4.mark_anchor->XCoordinate * pixel_size / unitsPerEm;
Packit daac2c
		    mark_y = g->f.f4.mark_anchor->YCoordinate * pixel_size / unitsPerEm;
Packit daac2c
Packit daac2c
		    if (g->f.f4.base_anchor->AnchorFormat != 1)
Packit daac2c
		      adjust_anchor (g->f.f4.base_anchor, face, prev, &base_x, &base_y);
Packit daac2c
		    if (g->f.f4.mark_anchor->AnchorFormat != 1)
Packit daac2c
		      adjust_anchor (g->f.f4.mark_anchor, face, g, &mark_x, &mark_y);
Packit daac2c
		    xoff = (base_x - prev_width) - mark_x;
Packit daac2c
		    yoff = base_y - mark_y;
Packit daac2c
		  }
Packit daac2c
		}
Packit daac2c
	      if (i + 1 == gstring.used
Packit daac2c
		  || gstring.glyphs[i + 1].glyph_id
Packit daac2c
		  || ! (gstring.glyphs[i + 1].positioning_type & 0xF))
Packit daac2c
		break;
Packit daac2c
	      i++, g++;
Packit daac2c
	    }
Packit daac2c
	}
Packit daac2c
Packit daac2c
      XCopyArea (display, bmp->pixmap, seq_pixmap, gc_or,
Packit daac2c
		 glyph_x + bmp->x, glyph_y + bmp->y, bmp->width, bmp->height,
Packit daac2c
		 x + bmp->x + xoff, glyph_y + bmp->y - yoff);
Packit daac2c
      x += advance;
Packit daac2c
Packit daac2c
      if (g->GlyphClass == OTF_GlyphClass0)
Packit daac2c
	base = mark = g, base_width = advance;
Packit daac2c
      else if (g->GlyphClass == OTF_GlyphClassMark)
Packit daac2c
	mark = g;
Packit daac2c
      else
Packit daac2c
	base = g, base_width = advance;
Packit daac2c
    }
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNbitmap, seq_pixmap);
Packit daac2c
  XtSetValues (seq_image, arg, 1);
Packit daac2c
Packit daac2c
  if (gstring.used > 0)
Packit daac2c
    {
Packit daac2c
      int size = render_width / FONT_WIDTH;
Packit daac2c
      char *buf = alloca (size + 1);
Packit daac2c
      char name[5];
Packit daac2c
Packit daac2c
      sprintf (buf, "%04X", gstring.glyphs[0].glyph_id);
Packit daac2c
      if (log && log[0])
Packit daac2c
	{
Packit daac2c
	  OTF_tag_name (log[0], name);
Packit daac2c
	  sprintf (buf + 4, " (%s)", name);
Packit daac2c
	  x = 11;
Packit daac2c
	}
Packit daac2c
      else
Packit daac2c
	x = 4;
Packit daac2c
      for (i = 1; i < gstring.used && x + 5 < size; i++, x += 5)
Packit daac2c
	{
Packit daac2c
	  sprintf (buf + x, " %04X", gstring.glyphs[i].glyph_id);
Packit daac2c
	  if (log && log[i] && x + 11 < size)
Packit daac2c
	    {
Packit daac2c
	      OTF_tag_name (log[i], name);
Packit daac2c
	      sprintf (buf + x + 5, "(%s)", name);
Packit daac2c
	      x += 6;
Packit daac2c
	    }
Packit daac2c
	}
Packit daac2c
      while (x < size)
Packit daac2c
	buf[x++] = ' ';
Packit daac2c
      buf[x] = '\0';
Packit daac2c
      XtSetArg (arg[0], XtNlabel, buf);
Packit daac2c
      XtSetValues (code_list, arg, 1);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  free (gstring.glyphs);
Packit daac2c
}
Packit daac2c
Packit daac2c
Packit daac2c
void
Packit daac2c
update_render_area ()
Packit daac2c
{
Packit daac2c
  int i;
Packit daac2c
  int x;
Packit daac2c
  Arg arg[1];
Packit daac2c
Packit daac2c
  XFillRectangle (display, raw_pixmap, gc, 0, 0, render_width, render_height);
Packit daac2c
  for (i = 0, x = glyph_x; i < glyph_rec.n_glyphs; i++)
Packit daac2c
    {
Packit daac2c
      if (glyph_rec.glyphs[i] >= 0)
Packit daac2c
	{
Packit daac2c
	  BitmapRec *bmp = bitmap + glyph_rec.glyphs[i];
Packit daac2c
	  char buf[5];
Packit daac2c
Packit daac2c
	  XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
Packit daac2c
		     0, 0, glyph_width, glyph_height,
Packit daac2c
		     (glyph_width + 4) * i + 1, 1);
Packit daac2c
	  XDrawRectangle (display, raw_pixmap, gc_set,
Packit daac2c
			  (glyph_width + 4) * i, 0,
Packit daac2c
			  glyph_width + 1, glyph_height + 1);
Packit daac2c
	  XDrawLine (display, raw_pixmap, gc_set,
Packit daac2c
		     (glyph_width + 4) * i + 1 + glyph_x, 1,
Packit daac2c
		     (glyph_width + 4) * i + 1 + glyph_x, glyph_height + 1);
Packit daac2c
	  XDrawLine (display, raw_pixmap, gc_set,
Packit daac2c
		     (glyph_width + 4) * i + 1 + glyph_x + bmp->advance, 1,
Packit daac2c
		     (glyph_width + 4) * i + 1 + glyph_x + bmp->advance,
Packit daac2c
		     glyph_height + 1);
Packit daac2c
Packit daac2c
	  sprintf (buf, "%04X", glyph_rec.codes[i]);
Packit daac2c
	  XDrawString (display, raw_pixmap, gc_inv, 
Packit daac2c
		       (glyph_width + 4) * i + 1
Packit daac2c
		       + (glyph_width - XTextWidth (font, buf, 4)) / 2,
Packit daac2c
		       glyph_height + 2 + FONT_HEIGHT, buf, 4);
Packit daac2c
	}
Packit daac2c
      else
Packit daac2c
	{
Packit daac2c
	  /* Variation Selector */
Packit daac2c
	  int idx = - glyph_rec.glyphs[i];
Packit daac2c
	  char buf[4];
Packit daac2c
Packit daac2c
	  sprintf (buf, "%03d", idx);
Packit daac2c
	  XDrawRectangle (display, raw_pixmap, gc_set,
Packit daac2c
			  (glyph_width + 4) * i, 0,
Packit daac2c
			  glyph_width + 1, glyph_height + 1);
Packit daac2c
	  XDrawString (display, raw_pixmap, gc_set,
Packit daac2c
		       (glyph_width + 4) * i + 1
Packit daac2c
		       + (glyph_width - XTextWidth (font, "VS", 2)) / 2,
Packit daac2c
		       1 + glyph_height / 2, "VS", 2);
Packit daac2c
	  XDrawString (display, raw_pixmap, gc_set,
Packit daac2c
		       (glyph_width + 4) * i + 1
Packit daac2c
		       + (glyph_width - XTextWidth (font, buf, 3)) / 2,
Packit daac2c
		       1 + glyph_height / 2 + FONT_ASCENT, buf, 3);
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
  XtSetArg (arg[0], XtNbitmap, raw_pixmap);
Packit daac2c
  XtSetValues (raw_image, arg, 1);
Packit daac2c
  update_seq_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  XtAppSetExitFlag (XtWidgetToApplicationContext (w));
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
DumpProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  int g_width, g_height;
Packit daac2c
  float g_x, g_y;
Packit daac2c
  /* unit in points (1/72 inch); to fit in both US-letter and A4 */
Packit daac2c
  static int xoff = 30, yoff = 30;
Packit daac2c
  static int unit = 30;
Packit daac2c
  static int margin = 2;
Packit daac2c
  static int title_height = 20, label_height = 10;
Packit daac2c
  int total_width = (unit + margin * 2) * 16;
Packit daac2c
  int total_height = (unit + margin * 2 + label_height) * 16 + title_height;
Packit daac2c
  /* pixel size (dots) */
Packit daac2c
  int size = 128;
Packit daac2c
  int i, j, k, l;
Packit daac2c
  char *name = alloca (strlen (filename) + 10);
Packit daac2c
  FILE *fp;
Packit daac2c
  int index = (glyph_index / 0x100) * 0x100;
Packit daac2c
  float scale;
Packit daac2c
Packit daac2c
  g_width = face->bbox.xMax - face->bbox.xMin;
Packit daac2c
  g_height = face->bbox.yMax - face->bbox.yMin;
Packit daac2c
  if (g_width > g_height)
Packit daac2c
    {
Packit daac2c
      scale = g_width * size;
Packit daac2c
      g_x = face->bbox.xMin * unit / g_width;
Packit daac2c
      g_y = face->bbox.yMin * unit / g_width;
Packit daac2c
    }
Packit daac2c
  else
Packit daac2c
    {
Packit daac2c
      scale = g_height * size;
Packit daac2c
      g_x = face->bbox.xMin * unit / g_height;
Packit daac2c
      g_y = face->bbox.yMin * unit / g_height;
Packit daac2c
    }
Packit daac2c
  scale /= face->units_per_EM;
Packit daac2c
Packit daac2c
  FT_Set_Pixel_Sizes (face, 0, size);
Packit daac2c
Packit daac2c
  sprintf (name, "%s-%04X.ps", face->family_name, index);
Packit daac2c
  printf ("Writing %s ... ", name);
Packit daac2c
  fflush (stdout);
Packit daac2c
  fp = fopen (name, "w");
Packit daac2c
Packit daac2c
  fprintf (fp, "%s\n", "%!PS-Adobe-2.0 EPSF-2.0");
Packit daac2c
  fprintf (fp, "%s\n", "%%Creater: otfview");
Packit daac2c
  fprintf (fp, "%s %s(%s)-%04X\n", "%%Title:",
Packit daac2c
	   face->family_name, face->style_name, index);
Packit daac2c
  fprintf (fp, "%s\n", "%%Pages: 1");
Packit daac2c
  fprintf (fp, "%s %d %d %d %d\n", "%%BoundingBox:",
Packit daac2c
	   xoff, yoff, xoff + total_width, yoff + total_height);
Packit daac2c
  fprintf (fp, "%s\n", "%%EndComments");
Packit daac2c
  fprintf (fp, "%s\n", "%%BeginProlog");
Packit daac2c
  fprintf (fp, "/W %d def\n", unit + margin * 2);
Packit daac2c
  fprintf (fp, "/H %d def\n", unit + margin * 2 + label_height);
Packit daac2c
  fprintf (fp, "/STR 10 string def\n");
Packit daac2c
  fprintf (fp, "/DrawIndex {\n");
Packit daac2c
  fprintf (fp, "  I 16 lt { (000) show } { I 256 lt { (00) show } { I 4096 lt { (0) show} if } ifelse } ifelse I 16 STR cvrs show\n");
Packit daac2c
  fprintf (fp, "} def\n");
Packit daac2c
  fprintf (fp, "/DrawTitle {\n");
Packit daac2c
  fprintf (fp, "  /Courier findfont 20 scalefont setfont\n");
Packit daac2c
  fprintf (fp, "  %d %d 4 add moveto\n", xoff + total_width / 2,
Packit daac2c
	   yoff + total_height - title_height + 2);
Packit daac2c
  fprintf (fp, "  (%s(%s)-%04X) dup stringwidth pop 2 div neg 0 rmoveto show\n",
Packit daac2c
	   face->family_name, face->style_name, index);
Packit daac2c
  fprintf (fp, "} def\n");
Packit daac2c
  fprintf (fp, "/DrawFrame { gsave %d %d translate 0 setlinewidth\n",
Packit daac2c
	   xoff, yoff);
Packit daac2c
  fprintf (fp, "  /Courier findfont 10 scalefont setfont\n");
Packit daac2c
  fprintf (fp, "  /I %d def\n", index);
Packit daac2c
  fprintf (fp, "  0 1 16 { W mul 0 moveto 0 H 16 mul rlineto stroke } for\n");
Packit daac2c
  fprintf (fp, "  0 1 16 { H mul 0 exch moveto W 16 mul 0 rlineto stroke } for\n");
Packit daac2c
  fprintf (fp, "  0 1 15 { H mul %d add 0 exch moveto W 16 mul 0 rlineto stroke } for\n", label_height);
Packit daac2c
  fprintf (fp, "  15 -1 0 { gsave H mul 0 exch translate 0 0 moveto\n");
Packit daac2c
  fprintf (fp, "    0 1 15 { gsave W mul 0 moveto\n");
Packit daac2c
  fprintf (fp, "      4 2 rmoveto DrawIndex /I I 1 add def grestore} for\n");
Packit daac2c
  fprintf (fp, "    grestore } for grestore } def\n");
Packit daac2c
  fprintf (fp, "%s\n", "%%EndProlog");
Packit daac2c
  fprintf (fp, "DrawTitle DrawFrame\n");
Packit daac2c
Packit daac2c
  for (i = 0; i < 16; i++)
Packit daac2c
    for (j = 0; j < 16; j++, index++)
Packit daac2c
      {
Packit daac2c
	int idx;
Packit daac2c
Packit daac2c
	if (charmap_index >= 0) 
Packit daac2c
	  idx = FT_Get_Char_Index (face, (FT_ULong) index);
Packit daac2c
	else
Packit daac2c
	  idx = index;
Packit daac2c
	if (idx > 0
Packit daac2c
	    && FT_Load_Glyph (face, idx, FT_LOAD_RENDER | FT_LOAD_MONOCHROME) == 0
Packit daac2c
	    && face->glyph->bitmap.rows > 0
Packit daac2c
	    && face->glyph->bitmap.width > 0)
Packit daac2c
	  {
Packit daac2c
	    unsigned char *p = face->glyph->bitmap.buffer;
Packit daac2c
	    int width = (face->glyph->bitmap.width - 1) / 8 + 1;
Packit daac2c
Packit daac2c
	    fprintf (fp, "gsave %f %f translate %d %d scale 0 0 moveto\n",
Packit daac2c
		     xoff + (unit + margin * 2) * j + margin - g_x,
Packit daac2c
		     yoff + (unit + label_height + margin * 2) * (15 - i) + label_height + margin - g_y,
Packit daac2c
		     unit, unit);
Packit daac2c
	    fprintf (fp, "%d %d true [%f 0 0 %f %d %d]\n",
Packit daac2c
		     width * 8, face->glyph->bitmap.rows,
Packit daac2c
		     scale, -scale, -face->glyph->bitmap_left,
Packit daac2c
		     face->glyph->bitmap_top);
Packit daac2c
	    fprintf (fp, "{< ");
Packit daac2c
	    for (k = 0; k < face->glyph->bitmap.rows;
Packit daac2c
		 k++, p += face->glyph->bitmap.pitch)
Packit daac2c
	      {
Packit daac2c
		for (l = 0; l < width; l++)
Packit daac2c
		  fprintf (fp, "%02X", p[l]);
Packit daac2c
		fprintf (fp, "\n");
Packit daac2c
	      }
Packit daac2c
	    fprintf (fp, ">} imagemask grestore\n");
Packit daac2c
	  }
Packit daac2c
	else
Packit daac2c
	  {
Packit daac2c
	    int boxsize = unit + margin * 2;
Packit daac2c
Packit daac2c
	    fprintf (fp, "gsave 0 setlinewidth %d %d translate\n",
Packit daac2c
		     xoff + boxsize * j,
Packit daac2c
		     yoff + (boxsize + label_height) * (15 - i) + label_height);
Packit daac2c
	    fprintf (fp, "0 0 moveto %d %d lineto stroke\n",
Packit daac2c
		     boxsize, boxsize);
Packit daac2c
	    fprintf (fp, "0 %d moveto %d 0 lineto stroke grestore\n",
Packit daac2c
		     boxsize, boxsize);
Packit daac2c
	  }
Packit daac2c
      }
Packit daac2c
  fprintf (fp, "showpage\n");
Packit daac2c
  fclose (fp);
Packit daac2c
  printf ("done\n");
Packit daac2c
Packit daac2c
  FT_Set_Pixel_Sizes (face, 0, (int) pixel_size);
Packit daac2c
}
Packit daac2c
Packit daac2c
Packit daac2c
void
Packit daac2c
GlyphProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  int old_glyph_index = glyph_index;
Packit daac2c
  int data;
Packit daac2c
Packit daac2c
  CAST_FROM_XTPOINTER (int, client_data, data);
Packit daac2c
Packit daac2c
  if (data == -3 && glyph_index > 0)
Packit daac2c
    glyph_index = 0;
Packit daac2c
  else if (data == -2 && glyph_index > 0)
Packit daac2c
    glyph_index = (glyph_index - 1) & 0x1FF000;
Packit daac2c
  else if (data == -1 && glyph_index > 0)
Packit daac2c
    glyph_index -= 0x80;
Packit daac2c
  else if (data == 1 && glyph_index < 0x10FF80)
Packit daac2c
    glyph_index += 0x80;
Packit daac2c
  else if (data == 2 && glyph_index < 0x10F000)
Packit daac2c
    glyph_index = (glyph_index + 0x1000) & 0x1FF000;
Packit daac2c
  else if (data == 3 && glyph_index < 0x10F000)
Packit daac2c
    glyph_index = 0x10FF80;
Packit daac2c
  if (glyph_index != old_glyph_index)
Packit daac2c
    update_glyph_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
CharmapProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  int data;
Packit daac2c
Packit daac2c
  CAST_FROM_XTPOINTER (int, client_data, data);
Packit daac2c
Packit daac2c
  if (charmap_index == data)
Packit daac2c
    return;
Packit daac2c
  charmap_index = data;
Packit daac2c
  if (charmap_index >= 0)
Packit daac2c
    FT_Set_Charmap (face, face->charmaps[charmap_index]);
Packit daac2c
  update_glyph_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
UVSProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  unsigned idx;
Packit daac2c
  int selector;
Packit daac2c
  OTF_VariationSelectorRecord *record;
Packit daac2c
  int i;
Packit daac2c
Packit daac2c
  CAST_FROM_XTPOINTER (unsigned, client_data, idx);
Packit daac2c
  selector = uvs[idx].c;
Packit daac2c
Packit daac2c
  if (glyph_rec.n_glyphs >= 64)
Packit daac2c
    return;
Packit daac2c
  for (i = 0; i < sub14->nRecords; i++)
Packit daac2c
    {
Packit daac2c
      record = sub14->Records + i;
Packit daac2c
      if (record->varSelector == selector)
Packit daac2c
	break;
Packit daac2c
    }
Packit daac2c
  if (i < sub14->nRecords)
Packit daac2c
    {
Packit daac2c
      if (glyph_rec.n_glyphs > 0
Packit daac2c
	  && glyph_rec.glyphs[glyph_rec.n_glyphs - 1] < 0)
Packit daac2c
	glyph_rec.n_glyphs--;
Packit daac2c
      glyph_rec.codes[glyph_rec.n_glyphs] = selector;
Packit daac2c
      glyph_rec.glyphs[glyph_rec.n_glyphs++] = - idx - 1;
Packit daac2c
      update_render_area ();
Packit daac2c
    }
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  int data;
Packit daac2c
Packit daac2c
  CAST_FROM_XTPOINTER (int, client_data, data);
Packit daac2c
Packit daac2c
  if (data < 0)
Packit daac2c
    {
Packit daac2c
      if (glyph_rec.n_glyphs > 0)
Packit daac2c
	{
Packit daac2c
	  if (data == -2)
Packit daac2c
	    glyph_rec.n_glyphs--;
Packit daac2c
	  else
Packit daac2c
	    glyph_rec.n_glyphs = 0;
Packit daac2c
	  update_render_area ();
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
  else if (glyph_rec.n_glyphs < 64)
Packit daac2c
    {
Packit daac2c
      int index = glyph_index + data;
Packit daac2c
Packit daac2c
      if (charmap_index >= 0)
Packit daac2c
	index = FT_Get_Char_Index (face, (FT_ULong) index);
Packit daac2c
      if (bitmap[index].pixmap)
Packit daac2c
	{
Packit daac2c
	  glyph_rec.codes[glyph_rec.n_glyphs] = glyph_index + data;
Packit daac2c
	  glyph_rec.glyphs[glyph_rec.n_glyphs++] = index;
Packit daac2c
	  if (otf)
Packit daac2c
	    update_uvs_area (glyph_index + data);
Packit daac2c
	  update_render_area ();
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
BidiProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  Arg arg[1];
Packit daac2c
Packit daac2c
  reversed = ! reversed;
Packit daac2c
  if (reversed)
Packit daac2c
    XtSetArg (arg[0], XtNlabel, "L<-R");
Packit daac2c
  else
Packit daac2c
    XtSetArg (arg[0], XtNlabel, "L->R");
Packit daac2c
  XtSetValues (w, arg, 1);
Packit daac2c
  update_seq_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
AltSubstProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  do_alternate_subst = ! do_alternate_subst;
Packit daac2c
  update_seq_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
FeatureProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  FeatureRec *rec = (FeatureRec *) client_data;
Packit daac2c
  int idx, i, j;
Packit daac2c
  Arg arg[4];
Packit daac2c
  char *label;
Packit daac2c
Packit daac2c
  if (! rec->langsys)
Packit daac2c
    return;
Packit daac2c
  XtSetArg (arg[0], XtNlabel, &label);
Packit daac2c
  XtGetValues (w, arg, 1);
Packit daac2c
  if (! strcmp (label, "all"))
Packit daac2c
    idx = -2;
Packit daac2c
  else if (! strcmp (label, "none"))
Packit daac2c
    idx = -1;
Packit daac2c
  else
Packit daac2c
    {
Packit daac2c
      for (idx = 0; idx < rec->langsys->FeatureCount; idx++)
Packit daac2c
	if (rec->features[idx].w == w)
Packit daac2c
	  break;
Packit daac2c
      if (idx == rec->langsys->FeatureCount)
Packit daac2c
	idx = -1;
Packit daac2c
    }
Packit daac2c
  if (idx < 0)
Packit daac2c
    {
Packit daac2c
      int on = idx == -2;
Packit daac2c
      char str[5];
Packit daac2c
Packit daac2c
      for (i = 0; i < rec->langsys->FeatureCount; i++)
Packit daac2c
	if (rec->features[i].on != on)
Packit daac2c
	  {
Packit daac2c
	    rec->features[i].on = on;
Packit daac2c
	    if (on)
Packit daac2c
	      {
Packit daac2c
		XtSetArg (arg[0], XtNborderWidth, 3);
Packit daac2c
		XtSetArg (arg[1], XtNinternalHeight, 2);
Packit daac2c
		XtSetArg (arg[2], XtNinternalWidth, 2);
Packit daac2c
	      }
Packit daac2c
	    else
Packit daac2c
	      {
Packit daac2c
		XtSetArg (arg[0], XtNborderWidth, 1);
Packit daac2c
		XtSetArg (arg[1], XtNinternalHeight, 4);
Packit daac2c
		XtSetArg (arg[2], XtNinternalWidth, 4);
Packit daac2c
	      }
Packit daac2c
	    OTF_tag_name (rec->features[i].tag, str);
Packit daac2c
	    XtSetArg (arg[3], XtNlabel, str);
Packit daac2c
	    XtSetValues (rec->features[i].w, arg, 4);
Packit daac2c
	  }
Packit daac2c
    }
Packit daac2c
  else
Packit daac2c
    {
Packit daac2c
      char str[5];
Packit daac2c
Packit daac2c
      rec->features[idx].on = ! rec->features[idx].on;
Packit daac2c
      if (rec->features[idx].on)
Packit daac2c
	{
Packit daac2c
	  XtSetArg (arg[0], XtNborderWidth, 3);
Packit daac2c
	  XtSetArg (arg[1], XtNinternalHeight, 2);
Packit daac2c
	  XtSetArg (arg[2], XtNinternalWidth, 2);
Packit daac2c
	}
Packit daac2c
      else
Packit daac2c
	{
Packit daac2c
	  XtSetArg (arg[0], XtNborderWidth, 1);
Packit daac2c
	  XtSetArg (arg[1], XtNinternalHeight, 4);
Packit daac2c
	  XtSetArg (arg[2], XtNinternalWidth, 4);
Packit daac2c
	}
Packit daac2c
      OTF_tag_name (rec->features[idx].tag, str);
Packit daac2c
      XtSetArg (arg[3], XtNlabel, str);
Packit daac2c
      XtSetValues (rec->features[idx].w, arg, 4);
Packit daac2c
    }
Packit daac2c
  update_seq_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
setup_feature_rec (FeatureRec *rec)
Packit daac2c
{
Packit daac2c
  int i, j;
Packit daac2c
  Arg arg[10];
Packit daac2c
Packit daac2c
  rec->langsys = NULL;
Packit daac2c
  if (! rec->gsub_gpos)
Packit daac2c
    return;
Packit daac2c
  for (i = 0; i < rec->gsub_gpos->ScriptList.ScriptCount; i++)
Packit daac2c
    if (rec->gsub_gpos->ScriptList.Script[i].ScriptTag == script_tag)
Packit daac2c
      {
Packit daac2c
	OTF_Script *script = rec->gsub_gpos->ScriptList.Script + i;
Packit daac2c
Packit daac2c
	if (langsys_tag)
Packit daac2c
	  {
Packit daac2c
	    for (j = 0; j < script->LangSysCount; j++)
Packit daac2c
	      if (script->LangSysRecord[j].LangSysTag == langsys_tag)
Packit daac2c
		{
Packit daac2c
		  rec->langsys = script->LangSys + j;
Packit daac2c
		  break;
Packit daac2c
		}
Packit daac2c
	  }
Packit daac2c
	if (! rec->langsys)
Packit daac2c
	  rec->langsys = &rec->gsub_gpos->ScriptList.Script[i].DefaultLangSys;
Packit daac2c
	break;
Packit daac2c
      }
Packit daac2c
Packit daac2c
  if (! rec->langsys)
Packit daac2c
    i = 0;
Packit daac2c
  else
Packit daac2c
    {
Packit daac2c
      XtSetArg (arg[0], XtNborderWidth, 1);
Packit daac2c
      XtSetArg (arg[1], XtNinternalHeight, 4);
Packit daac2c
      XtSetArg (arg[2], XtNinternalWidth, 4);
Packit daac2c
      XtSetArg (arg[3], XtNborderColor, foreground);
Packit daac2c
      XtSetArg (arg[4], XtNsensitive, True);
Packit daac2c
      for (i = 0; i < rec->langsys->FeatureCount; i++)
Packit daac2c
	{
Packit daac2c
	  OTF_Feature *feature = rec->gsub_gpos->FeatureList.Feature;
Packit daac2c
	  int index = rec->langsys->FeatureIndex[i];
Packit daac2c
	  char label[5];
Packit daac2c
Packit daac2c
	  if (! rec->features[i].w)
Packit daac2c
	    {
Packit daac2c
	      Widget w = XtCreateManagedWidget ("", commandWidgetClass,
Packit daac2c
						rec->parent, arg, 0);
Packit daac2c
	      XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
Packit daac2c
	      rec->features[i].w = w;
Packit daac2c
	    }
Packit daac2c
Packit daac2c
	  rec->features[i].tag = feature[index].FeatureTag;
Packit daac2c
	  rec->features[i].on = 0;
Packit daac2c
	  OTF_tag_name (rec->features[i].tag, label);
Packit daac2c
	  XtSetArg (arg[5], XtNlabel, label);
Packit daac2c
	  XtSetValues (rec->features[i].w, arg, 6);
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
  XtSetArg (arg[0], XtNborderColor, background);
Packit daac2c
  XtSetArg (arg[1], XtNsensitive, False);
Packit daac2c
  XtSetArg (arg[2], XtNlabel, "    ");
Packit daac2c
  for (; i < rec->num_features; i++)
Packit daac2c
    {
Packit daac2c
      if (! rec->features[i].w)
Packit daac2c
	{
Packit daac2c
	  Widget w = XtCreateManagedWidget ("", commandWidgetClass,
Packit daac2c
					    rec->parent, arg, 0);
Packit daac2c
	  XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
Packit daac2c
	  rec->features[i].w = w;
Packit daac2c
	}
Packit daac2c
      XtSetValues (rec->features[i].w, arg, 3);
Packit daac2c
    }
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
compose_script_langsys (OTF_Tag script, OTF_Tag langsys, char *name)
Packit daac2c
{
Packit daac2c
  OTF_tag_name (script, name);
Packit daac2c
  if (langsys)
Packit daac2c
    {
Packit daac2c
      name[4] = '(';
Packit daac2c
      OTF_tag_name (langsys, name + 5);
Packit daac2c
      name[9] = ')';
Packit daac2c
      name[10] = '\0';
Packit daac2c
    }
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
decompose_script_langsys (OTF_Tag *script, OTF_Tag *langsys, char *name)
Packit daac2c
{
Packit daac2c
  *script = OTF_tag (name);
Packit daac2c
  if (name[4])
Packit daac2c
    *langsys = OTF_tag (name + 5);
Packit daac2c
  else
Packit daac2c
    *langsys = 0;
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
ScriptProc (Widget w, XtPointer client_data, XtPointer call_data)
Packit daac2c
{
Packit daac2c
  char *name;
Packit daac2c
  OTF_Tag script, langsys;
Packit daac2c
  Arg arg[1];
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNlabel, &name);
Packit daac2c
  XtGetValues (w, arg, 1);
Packit daac2c
  decompose_script_langsys (&script, &langsys, name);
Packit daac2c
  if (script_tag == script && langsys_tag == langsys)
Packit daac2c
    return;
Packit daac2c
  script_tag = script;
Packit daac2c
  langsys_tag = langsys;
Packit daac2c
  setup_feature_rec (&gsub);
Packit daac2c
  setup_feature_rec (&gpos);
Packit daac2c
  update_seq_area ();
Packit daac2c
}
Packit daac2c
Packit daac2c
Widget
Packit daac2c
create_otf_script_widgets (Widget prev)
Packit daac2c
{
Packit daac2c
  Widget w;
Packit daac2c
  Arg arg[10];
Packit daac2c
  int n, prev_n, i, j;
Packit daac2c
  struct {
Packit daac2c
    OTF_Tag script;
Packit daac2c
    OTF_Tag langsys;
Packit daac2c
  } *script_langsys;
Packit daac2c
  char name[11];
Packit daac2c
  int nfeatures;
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[1], XtNleft, XawChainLeft);
Packit daac2c
  XtSetArg (arg[2], XtNright, XawChainLeft);
Packit daac2c
  XtSetArg (arg[3], XtNtop, XawChainTop);
Packit daac2c
  XtSetArg (arg[4], XtNbottom, XawChainTop);
Packit daac2c
  XtSetArg (arg[5], XtNfromVert, prev);
Packit daac2c
  XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
Packit daac2c
  prev = XtCreateManagedWidget ("Script", boxWidgetClass, render_area, arg, 7);
Packit daac2c
  XtCreateManagedWidget ("script(langsys)", labelWidgetClass, prev, arg, 1);
Packit daac2c
Packit daac2c
  n = 0;
Packit daac2c
  if (otf->gsub)
Packit daac2c
    for (i = 0; i < otf->gsub->ScriptList.ScriptCount; i++)
Packit daac2c
      n += otf->gsub->ScriptList.Script[i].LangSysCount + 1;
Packit daac2c
  if (otf->gpos)
Packit daac2c
    for (i = 0; i < otf->gpos->ScriptList.ScriptCount; i++)
Packit daac2c
      n += otf->gpos->ScriptList.Script[i].LangSysCount + 1;
Packit daac2c
  script_langsys = alloca ((sizeof script_langsys[0]) * n);
Packit daac2c
  n = 0;
Packit daac2c
  nfeatures = 0;
Packit daac2c
  if (otf->gsub)
Packit daac2c
    for (i = 0; i < otf->gsub->ScriptList.ScriptCount; i++)
Packit daac2c
      {
Packit daac2c
	OTF_Tag tag = otf->gsub->ScriptList.Script[i].ScriptTag;
Packit daac2c
Packit daac2c
	script_langsys[n].script = tag;
Packit daac2c
	script_langsys[n++].langsys = 0;
Packit daac2c
	if (nfeatures
Packit daac2c
	    < otf->gsub->ScriptList.Script[i].DefaultLangSys.FeatureCount)
Packit daac2c
	  nfeatures
Packit daac2c
	    = otf->gsub->ScriptList.Script[i].DefaultLangSys.FeatureCount;
Packit daac2c
	for (j = 0; j < otf->gsub->ScriptList.Script[i].LangSysCount; j++)
Packit daac2c
	  {
Packit daac2c
	    script_langsys[n].script = tag;
Packit daac2c
	    script_langsys[n++].langsys
Packit daac2c
	      = otf->gsub->ScriptList.Script[i].LangSysRecord[j].LangSysTag;
Packit daac2c
	    if (nfeatures
Packit daac2c
		< otf->gsub->ScriptList.Script[i].LangSys[j].FeatureCount)
Packit daac2c
	      nfeatures
Packit daac2c
		= otf->gsub->ScriptList.Script[i].LangSys[j].FeatureCount;
Packit daac2c
	  }
Packit daac2c
      }
Packit daac2c
  gsub.num_features = nfeatures;
Packit daac2c
  if (nfeatures > 0)
Packit daac2c
    {
Packit daac2c
      gsub.num_features = nfeatures;
Packit daac2c
      gsub.features = malloc ((sizeof (FeatureElement)) * nfeatures);
Packit daac2c
      memset (gsub.features, 0, (sizeof (FeatureElement)) * nfeatures);
Packit daac2c
    }
Packit daac2c
  prev_n = n;
Packit daac2c
  nfeatures = 0;
Packit daac2c
  if (otf->gpos)
Packit daac2c
    for (i = 0; i < otf->gpos->ScriptList.ScriptCount; i++)
Packit daac2c
      {
Packit daac2c
	OTF_Tag tag = otf->gpos->ScriptList.Script[i].ScriptTag;
Packit daac2c
	int k;
Packit daac2c
Packit daac2c
	if (nfeatures
Packit daac2c
	    < otf->gpos->ScriptList.Script[i].DefaultLangSys.FeatureCount)
Packit daac2c
	  nfeatures
Packit daac2c
	    = otf->gpos->ScriptList.Script[i].DefaultLangSys.FeatureCount;
Packit daac2c
	for (k = 0; k < prev_n; k++)
Packit daac2c
	  if (tag == script_langsys[k].script)
Packit daac2c
	    break;
Packit daac2c
	if (k == prev_n)
Packit daac2c
	  {
Packit daac2c
	    script_langsys[n].script = tag;
Packit daac2c
	    script_langsys[n++].langsys = 0;
Packit daac2c
	  }
Packit daac2c
	for (j = 0; j < otf->gpos->ScriptList.Script[i].LangSysCount; j++)
Packit daac2c
	  {
Packit daac2c
	    int l;
Packit daac2c
Packit daac2c
	    if (k < prev_n)
Packit daac2c
	      {
Packit daac2c
		OTF_Script *script = otf->gpos->ScriptList.Script + i;
Packit daac2c
Packit daac2c
		for (l = k; l < prev_n && tag == script_langsys[l].script; l++)
Packit daac2c
		  if (script->LangSysRecord[j].LangSysTag
Packit daac2c
		      == script_langsys[l].langsys)
Packit daac2c
		    break;
Packit daac2c
	      }
Packit daac2c
	    else
Packit daac2c
	      l = prev_n;
Packit daac2c
	    if (l == prev_n)
Packit daac2c
	      {
Packit daac2c
		script_langsys[n].script = tag;
Packit daac2c
		script_langsys[n++].langsys = 0;
Packit daac2c
	      }
Packit daac2c
	    if (nfeatures
Packit daac2c
		< otf->gpos->ScriptList.Script[i].LangSys[j].FeatureCount)
Packit daac2c
	      nfeatures
Packit daac2c
		= otf->gpos->ScriptList.Script[i].LangSys[j].FeatureCount;
Packit daac2c
	  }
Packit daac2c
      }
Packit daac2c
Packit daac2c
  if (nfeatures > 0)
Packit daac2c
    {
Packit daac2c
      gpos.num_features = nfeatures;
Packit daac2c
      gpos.features = malloc ((sizeof (FeatureElement)) * nfeatures);
Packit daac2c
      memset (gpos.features, 0, (sizeof (FeatureElement)) * nfeatures);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  if (n == 0)
Packit daac2c
    return prev;
Packit daac2c
Packit daac2c
  script_tag = script_langsys[0].script;
Packit daac2c
  langsys_tag = script_langsys[0].langsys;
Packit daac2c
  compose_script_langsys (script_tag, langsys_tag, name);
Packit daac2c
Packit daac2c
  if (n == 1)
Packit daac2c
    {
Packit daac2c
      XtSetArg (arg[0], XtNforeground, background);
Packit daac2c
      XtSetArg (arg[1], XtNbackground, foreground);
Packit daac2c
      XtCreateManagedWidget (name, labelWidgetClass, prev, arg, 2);
Packit daac2c
    }
Packit daac2c
  else
Packit daac2c
    {
Packit daac2c
      Widget box;
Packit daac2c
      XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
      XtSetArg (arg[1], XtNwidth, render_width - (FONT_WIDTH * 15));
Packit daac2c
      XtSetArg (arg[2], XtNorientation, XtorientHorizontal);
Packit daac2c
      box = XtCreateManagedWidget ("scritp-list", boxWidgetClass, prev, arg, 2);
Packit daac2c
      XtSetArg (arg[0], XtNstate, True);
Packit daac2c
      w = XtCreateManagedWidget (name, toggleWidgetClass, box, arg, 1);
Packit daac2c
      XtAddCallback (w, XtNcallback, ScriptProc, NULL);
Packit daac2c
      XtSetArg (arg[0], XtNradioGroup, w);
Packit daac2c
      for (i = 1; i < n; i++)
Packit daac2c
	{
Packit daac2c
	  compose_script_langsys (script_langsys[i].script,
Packit daac2c
				  script_langsys[i].langsys, name);
Packit daac2c
	  w = XtCreateManagedWidget (name, toggleWidgetClass, box, arg, 1);
Packit daac2c
	  XtAddCallback (w, XtNcallback, ScriptProc, NULL);
Packit daac2c
	}	  
Packit daac2c
    }
Packit daac2c
  return prev;
Packit daac2c
}
Packit daac2c
Packit daac2c
Packit daac2c
Widget
Packit daac2c
create_otf_widgets (Widget prev, FeatureRec *rec)
Packit daac2c
{
Packit daac2c
  Arg arg[10];
Packit daac2c
  Widget w;
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[1], XtNleft, XawChainLeft);
Packit daac2c
  XtSetArg (arg[2], XtNright, XawChainLeft);
Packit daac2c
  XtSetArg (arg[3], XtNtop, XawChainTop);
Packit daac2c
  XtSetArg (arg[4], XtNbottom, XawChainTop);
Packit daac2c
  XtSetArg (arg[5], XtNfromVert, prev);
Packit daac2c
  XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
Packit daac2c
  prev = XtCreateManagedWidget (rec->label, boxWidgetClass, render_area,
Packit daac2c
				arg, 7);
Packit daac2c
  XtCreateManagedWidget (rec->label, labelWidgetClass, prev, arg, 1);
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 1);
Packit daac2c
  XtSetArg (arg[1], XtNinternalHeight, 4);
Packit daac2c
  XtSetArg (arg[2], XtNinternalWidth, 4);
Packit daac2c
  w = XtCreateManagedWidget ("all", commandWidgetClass, prev, arg, 3);
Packit daac2c
  XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
Packit daac2c
  w = XtCreateManagedWidget ("none", commandWidgetClass, prev, arg, 3);
Packit daac2c
  XtAddCallback (w, XtNcallback, FeatureProc, (XtPointer) rec);
Packit daac2c
Packit daac2c
  rec->parent = prev;
Packit daac2c
  setup_feature_rec (rec);
Packit daac2c
  return prev;
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
create_widgets ()
Packit daac2c
{
Packit daac2c
  String quit_action = "<KeyPress>q: set() notify() unset()";
Packit daac2c
  String FIRST_action = "<KeyPress>f: set() notify() unset()\n\
Packit daac2c
			 <KeyPress>Home: set() notify() unset()";
Packit daac2c
  String PREV_action = "Shift<KeyPress>p: set() notify() unset()\n\
Packit daac2c
			 <KeyPress>Up: set() notify() unset()";
Packit daac2c
  String prev_action = "~Shift<KeyPress>p: set() notify() unset()\n\
Packit daac2c
			 <KeyPress>Left: set() notify() unset()";
Packit daac2c
  String next_action = "~Shift<KeyPress>n: set() notify() unset()\n\
Packit daac2c
			 <KeyPress>Right: set() notify() unset()";
Packit daac2c
  String NEXT_action = "Shift<KeyPress>n: set() notify() unset()\n\
Packit daac2c
			 <KeyPress>Down: set() notify() unset()";
Packit daac2c
  String LAST_action = "<KeyPress>l: set() notify() unset()\n\
Packit daac2c
			 <KeyPress>End: set() notify() unset()";
Packit daac2c
  Arg arg[10];
Packit daac2c
  int i, j;
Packit daac2c
  Widget prev, w;
Packit daac2c
  String trans = "<Expose>: Expose()";
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNtranslations, XtParseTranslationTable (trans));
Packit daac2c
  frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, arg, 1);
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNleft, XawChainLeft);
Packit daac2c
  XtSetArg (arg[1], XtNright, XawChainLeft);
Packit daac2c
  XtSetArg (arg[2], XtNtop, XawChainTop);
Packit daac2c
  XtSetArg (arg[3], XtNbottom, XawChainTop);
Packit daac2c
  XtSetArg (arg[4], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[5], XtNorientation, XtorientHorizontal);
Packit daac2c
  command_area = XtCreateManagedWidget ("command-area", boxWidgetClass,
Packit daac2c
					frame, arg, 6);
Packit daac2c
  XtSetArg (arg[6], XtNfromVert, command_area);
Packit daac2c
  navi_area = XtCreateManagedWidget ("navi-area", boxWidgetClass,
Packit daac2c
				     frame, arg, 7);
Packit daac2c
  XtSetArg (arg[4], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[5], XtNfromVert, navi_area);
Packit daac2c
  XtSetArg (arg[6], XtNdefaultDistance, 0);
Packit daac2c
  glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
Packit daac2c
				      frame, arg, 7);
Packit daac2c
Packit daac2c
  XtSetArg (arg[5], XtNfromVert, glyph_area);
Packit daac2c
  if (sub14)
Packit daac2c
    {
Packit daac2c
      Arg arg2[3];
Packit daac2c
Packit daac2c
      XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
Packit daac2c
      uvs_area = XtCreateManagedWidget ("uvs-area", boxWidgetClass,
Packit daac2c
					frame, arg, 7);
Packit daac2c
      XtSetArg (arg2[0], XtNborderWidth, 0);
Packit daac2c
      XtSetArg (arg2[1], XtNlabel, "Variation Selector: ");
Packit daac2c
      uvs_label = XtCreateManagedWidget ("uvs-label", labelWidgetClass,
Packit daac2c
					 uvs_area, arg2, 2);
Packit daac2c
      XtSetArg (arg2[0], XtNborderWidth, 1);
Packit daac2c
      for (i = 0; i < sub14->nRecords; i++)
Packit daac2c
	{
Packit daac2c
	  OTF_VariationSelectorRecord *record = sub14->Records + i;
Packit daac2c
	  unsigned selector = record->varSelector;
Packit daac2c
	  unsigned idx;
Packit daac2c
	  char lbl[4];
Packit daac2c
	  
Packit daac2c
	  idx = (selector <= 0xFE0F ? selector - 0xFE00
Packit daac2c
		 : selector - 0xE0100 + 16);
Packit daac2c
	  if (uvs[idx].c)
Packit daac2c
	    continue;
Packit daac2c
	  uvs[idx].c = selector;
Packit daac2c
	  sprintf (lbl, "%03d", idx + 1);
Packit daac2c
	  XtSetArg (arg2[1], XtNlabel, lbl);
Packit daac2c
	  XtSetArg (arg2[2], XtNsensitive, False);
Packit daac2c
	  uvs[idx].w = XtCreateManagedWidget ("lbl", commandWidgetClass,
Packit daac2c
						   uvs_area, arg2, 3);
Packit daac2c
	  XtAddCallbackWithCast (unsigned, uvs[idx].w, UVSProc, idx);
Packit daac2c
	}
Packit daac2c
      XtSetArg (arg[5], XtNfromVert, uvs_area);
Packit daac2c
    }
Packit daac2c
  render_area = XtCreateManagedWidget ("render-area", formWidgetClass,
Packit daac2c
				       frame, arg, 6);
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNaccelerators, XtParseAcceleratorTable (quit_action));
Packit daac2c
  quit = XtCreateManagedWidget ("Quit", commandWidgetClass,
Packit daac2c
				command_area, arg, 1);
Packit daac2c
  XtAddCallback (quit, XtNcallback, QuitProc, NULL);
Packit daac2c
Packit daac2c
  dump = XtCreateManagedWidget ("DumpImage", commandWidgetClass,
Packit daac2c
				command_area, arg, 1);
Packit daac2c
  XtAddCallback (dump, XtNcallback, DumpProc, NULL);
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[1], XtNwidth, 10);
Packit daac2c
  XtCreateManagedWidget ("spacer", boxWidgetClass, command_area, arg, 2);
Packit daac2c
Packit daac2c
  charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
Packit daac2c
  XtSetArg (arg[0], XtNstate, True);
Packit daac2c
  charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, toggleWidgetClass,
Packit daac2c
				      command_area, arg, 1);
Packit daac2c
  XtAddCallback (charmap[0], XtNcallback, CharmapProc, (XtPointer) -1);
Packit daac2c
  XtSetArg (arg[0], XtNradioGroup, charmap[0]);
Packit daac2c
  for (i = 0; i < face->num_charmaps; i++)
Packit daac2c
    {
Packit daac2c
      charmap[i + 1] = XtCreateManagedWidget (charmap_rec[i + 1].name,
Packit daac2c
					      toggleWidgetClass,
Packit daac2c
					      command_area, arg, 1);
Packit daac2c
      XtAddCallbackWithCast (int, charmap[i + 1], CharmapProc, i);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNlabel, " |< (f)");
Packit daac2c
  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (FIRST_action));
Packit daac2c
  FIRST = XtCreateManagedWidget ("FIRST", commandWidgetClass,
Packit daac2c
				 navi_area, arg, 2);
Packit daac2c
  XtAddCallback (FIRST, XtNcallback, GlyphProc, (XtPointer) -3);
Packit daac2c
  XtSetArg (arg[0], XtNlabel, "<< (P)");
Packit daac2c
  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
Packit daac2c
  PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
Packit daac2c
				navi_area, arg, 2);
Packit daac2c
  XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
Packit daac2c
  XtSetArg (arg[0], XtNlabel, "< (p)");
Packit daac2c
  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
Packit daac2c
  prev = XtCreateManagedWidget ("prev", commandWidgetClass,
Packit daac2c
				navi_area, arg, 2);
Packit daac2c
  XtAddCallback (prev, XtNcallback, GlyphProc, (XtPointer) -1);
Packit daac2c
  XtSetArg (arg[0], XtNlabel, " 0000 ");
Packit daac2c
  range = XtCreateManagedWidget ("range", labelWidgetClass,
Packit daac2c
				 navi_area, arg, 1);
Packit daac2c
  XtSetArg (arg[0], XtNforeground, &foreground);
Packit daac2c
  XtSetArg (arg[1], XtNbackground, &background);
Packit daac2c
  XtGetValues (range, arg, 2);
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNlabel, "> (n)");
Packit daac2c
  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
Packit daac2c
  next = XtCreateManagedWidget ("next", commandWidgetClass,
Packit daac2c
				navi_area, arg, 2);
Packit daac2c
  XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
Packit daac2c
  XtSetArg (arg[0], XtNlabel, ">> (N)");
Packit daac2c
  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
Packit daac2c
  NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
Packit daac2c
				navi_area, arg, 2);
Packit daac2c
  XtAddCallback (NEXT, XtNcallback, GlyphProc, (XtPointer) 2);
Packit daac2c
  XtSetArg (arg[0], XtNlabel, ">| (l)");
Packit daac2c
  XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (LAST_action));
Packit daac2c
  LAST = XtCreateManagedWidget ("LAST", commandWidgetClass,
Packit daac2c
				navi_area, arg, 2);
Packit daac2c
  XtAddCallback (LAST, XtNcallback, GlyphProc, (XtPointer) 3);
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNleft, XawChainLeft);
Packit daac2c
  XtSetArg (arg[1], XtNright, XawChainLeft);
Packit daac2c
  XtSetArg (arg[2], XtNtop, XawChainTop);
Packit daac2c
  XtSetArg (arg[3], XtNbottom, XawChainTop);
Packit daac2c
Packit daac2c
  for (i = 0; i < 8; i++)
Packit daac2c
    {
Packit daac2c
      char str[3];
Packit daac2c
      int n = 4;
Packit daac2c
      Widget head;
Packit daac2c
Packit daac2c
      sprintf (str, "%XX", i);
Packit daac2c
      XtSetArg (arg[n], XtNheight, glyph_height + 5), n++;
Packit daac2c
      XtSetArg (arg[n], XtNlabel, str), n++;
Packit daac2c
      XtSetArg (arg[n], XtNborderWidth, 0), n++;
Packit daac2c
      if (i > 0)
Packit daac2c
	XtSetArg (arg[n], XtNfromVert, w), n++;
Packit daac2c
      head = XtCreateManagedWidget (str, labelWidgetClass, glyph_area, arg, n);
Packit daac2c
      index_label[i] = head;
Packit daac2c
      for (j = 0; j < 16; j++)
Packit daac2c
	{
Packit daac2c
	  int k = i * 16 + j;
Packit daac2c
Packit daac2c
	  n = 4;
Packit daac2c
	  if (i > 0)
Packit daac2c
	    XtSetArg (arg[n], XtNfromVert, w), n++;
Packit daac2c
	  if (j == 0)
Packit daac2c
	    XtSetArg (arg[n], XtNfromHoriz, head), n++;
Packit daac2c
	  else
Packit daac2c
	    XtSetArg (arg[n], XtNfromHoriz, glyph[k - 1]), n++;
Packit daac2c
	  XtSetArg (arg[n], XtNbitmap, none_pixmap), n++;
Packit daac2c
	  glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
Packit daac2c
					    glyph_area, arg, n);
Packit daac2c
	  XtAddCallbackWithCast (int, glyph[k], RenderProc, k);
Packit daac2c
	}
Packit daac2c
      w = head;
Packit daac2c
    }
Packit daac2c
  /* 10 = (1 (border_width) + 4 (inner_width)) * 2 */
Packit daac2c
  XtSetArg(arg[4], XtNwidth, glyph_width + 10);
Packit daac2c
  XtSetArg (arg[5], XtNfromVert, glyph[112]);
Packit daac2c
  XtSetArg (arg[6], XtNfromHoriz, w);
Packit daac2c
  XtSetArg (arg[7], XtNborderWidth, 0);
Packit daac2c
Packit daac2c
  for (j = 0; j < 16; j++)
Packit daac2c
    {
Packit daac2c
      char str[3];
Packit daac2c
Packit daac2c
      sprintf (str, "X%X", j);
Packit daac2c
      XtSetArg (arg[8], XtNlabel, str);
Packit daac2c
      w = XtCreateManagedWidget ("idx", labelWidgetClass, glyph_area, arg, 9);
Packit daac2c
      XtSetArg (arg[6], XtNfromHoriz, w);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNleft, XawChainLeft);
Packit daac2c
  XtSetArg (arg[1], XtNright, XawChainLeft);
Packit daac2c
  XtSetArg (arg[2], XtNtop, XawChainTop);
Packit daac2c
  XtSetArg (arg[3], XtNbottom, XawChainTop);
Packit daac2c
  XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
Packit daac2c
  XtSetArg (arg[5], XtNborderWidth, 0);
Packit daac2c
  w = XtCreateManagedWidget ("clear-box", boxWidgetClass, render_area, arg, 6);
Packit daac2c
  clear = XtCreateManagedWidget ("clear", commandWidgetClass, w, arg, 0);
Packit daac2c
  XtAddCallback (clear, XtNcallback, RenderProc, (XtPointer) -1);
Packit daac2c
  del = XtCreateManagedWidget ("delete", commandWidgetClass, w, arg, 0);
Packit daac2c
  XtAddCallback (del, XtNcallback, RenderProc, (XtPointer) -2);
Packit daac2c
  bidi = XtCreateManagedWidget ("L->R", toggleWidgetClass, w, arg, 0);
Packit daac2c
  XtAddCallback (bidi, XtNcallback, BidiProc, NULL);
Packit daac2c
  alt_subst = XtCreateManagedWidget ("AltSubst", toggleWidgetClass, w, arg, 0);
Packit daac2c
  XtAddCallback (alt_subst, XtNcallback, AltSubstProc, NULL);
Packit daac2c
Packit daac2c
  XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
Packit daac2c
  XtSetArg (arg[5], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[6], XtNfromVert, w);
Packit daac2c
  raw = XtCreateManagedWidget ("raw", boxWidgetClass, render_area, arg, 7);
Packit daac2c
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[1], XtNlabel, "raw: ");
Packit daac2c
  raw_label = XtCreateManagedWidget ("raw-label", labelWidgetClass,
Packit daac2c
				      raw, arg, 2);
Packit daac2c
  XtSetArg (arg[1], XtNbitmap, raw_pixmap);
Packit daac2c
  raw_image = XtCreateManagedWidget ("raw-image", labelWidgetClass,
Packit daac2c
				      raw, arg, 2);
Packit daac2c
  w = raw;
Packit daac2c
  if (otf)
Packit daac2c
    {
Packit daac2c
      OTF_get_table (otf, "GSUB");
Packit daac2c
      OTF_get_table (otf, "GPOS");
Packit daac2c
      w = create_otf_script_widgets (w);
Packit daac2c
      if (otf->gsub)
Packit daac2c
	{
Packit daac2c
	  gsub.label = "GSUB";
Packit daac2c
	  gsub.gsub_gpos = otf->gsub;
Packit daac2c
	  w = create_otf_widgets (w, &gsub);
Packit daac2c
	}
Packit daac2c
      if (otf->gpos)
Packit daac2c
	{
Packit daac2c
	  gpos.label = "GPOS";
Packit daac2c
	  gpos.gsub_gpos = otf->gpos;
Packit daac2c
	  w = create_otf_widgets (w, &gpos);
Packit daac2c
	}
Packit daac2c
    }
Packit daac2c
Packit daac2c
  XtSetArg (arg[6], XtNfromVert, w);
Packit daac2c
  seq = XtCreateManagedWidget ("seq", boxWidgetClass, render_area, arg, 7);
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[1], XtNlabel, "seq: ");
Packit daac2c
  seq_label = XtCreateManagedWidget ("seq-label", labelWidgetClass,
Packit daac2c
				     seq, arg, 2);
Packit daac2c
  XtSetArg (arg[1], XtNbitmap, seq_pixmap);
Packit daac2c
  seq_image = XtCreateManagedWidget ("seq-image", labelWidgetClass,
Packit daac2c
				     seq, arg, 2);
Packit daac2c
  XtSetArg (arg[6], XtNfromVert, seq);
Packit daac2c
  code = XtCreateManagedWidget ("code", boxWidgetClass, render_area, arg, 7);
Packit daac2c
  XtSetArg (arg[0], XtNborderWidth, 0);
Packit daac2c
  XtSetArg (arg[1], XtNlabel, "code:");
Packit daac2c
  code_label = XtCreateManagedWidget ("code-label", labelWidgetClass,
Packit daac2c
				     code, arg, 2);
Packit daac2c
  XtSetArg (arg[1], XtNlabel, "");
Packit daac2c
  XtSetArg (arg[2], XtNwidth, render_width);
Packit daac2c
  code_list = XtCreateManagedWidget ("code-list", labelWidgetClass,
Packit daac2c
				     code, arg, 3);
Packit daac2c
  XtInstallAllAccelerators (shell, shell);
Packit daac2c
}
Packit daac2c
Packit daac2c
static void
Packit daac2c
ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num)
Packit daac2c
{
Packit daac2c
  XTextProperty text_prop;
Packit daac2c
  char *pname = "otfview";
Packit daac2c
  char *fname = basename (filename);
Packit daac2c
  char *name = alloca (strlen (fname) + 3 + strlen (pname) + 1);
Packit daac2c
Packit daac2c
  sprintf (name, "%s - %s", pname, fname);
Packit daac2c
  text_prop.value = (unsigned char *) name;
Packit daac2c
  text_prop.encoding = XA_STRING;
Packit daac2c
  text_prop.format = 8;
Packit daac2c
  text_prop.nitems = strlen (name);
Packit daac2c
  XSetWMName (display, XtWindow (shell), &text_prop);
Packit daac2c
}
Packit daac2c
Packit daac2c
/* Format MSG by FMT and print the result to the stderr, and exit.  */
Packit daac2c
Packit daac2c
#define FATAL_ERROR(fmt, arg)	\
Packit daac2c
  do {				\
Packit daac2c
    fprintf (stderr, fmt, arg);	\
Packit daac2c
    exit (1);			\
Packit daac2c
  } while (0)
Packit daac2c
Packit daac2c
static int
Packit daac2c
x_error_handler (Display *display, XErrorEvent *error)
Packit daac2c
{
Packit daac2c
  return 0;
Packit daac2c
}
Packit daac2c
Packit daac2c
void
Packit daac2c
help (char **argv, int err)
Packit daac2c
{
Packit daac2c
  FILE *fp = err ? stderr : stdout;
Packit daac2c
Packit daac2c
  fprintf (fp, "Usage: %s [ X-OPTION ... ]  OTF-FILE [INDEX]\n",
Packit daac2c
	   basename (argv[0]));
Packit daac2c
  fprintf (fp, "  Environment variable PIXEL_SIZE specifies the pixel size.\n");
Packit daac2c
  fprintf (fp, "  The default pixel size is %d, but is reduced\n",
Packit daac2c
	   DEFAULT_PIXEL_SIZE);
Packit daac2c
  fprintf (fp, "  if your screen is not that wide.\n");
Packit daac2c
  exit (err);
Packit daac2c
}
Packit daac2c
Packit daac2c
int
Packit daac2c
main (int argc, char **argv)
Packit daac2c
{
Packit daac2c
  XtActionsRec actions[] = { {"Expose", ExposeProc} };
Packit daac2c
  Arg arg[10];
Packit daac2c
Packit daac2c
  FT_Library library;
Packit daac2c
  OTF_GlyphString gstring;
Packit daac2c
  OTF_Glyph *g;
Packit daac2c
Packit daac2c
  int err;
Packit daac2c
  int i;
Packit daac2c
  int fixed_pixel_size = 0;
Packit daac2c
  int display_width;
Packit daac2c
Packit daac2c
  pixel_size = DEFAULT_PIXEL_SIZE;
Packit daac2c
  {
Packit daac2c
    char *str = getenv ("PIXEL_SIZE");
Packit daac2c
Packit daac2c
    if (str && (i = atoi (str)) > 0)
Packit daac2c
      {
Packit daac2c
	pixel_size = i;
Packit daac2c
	fixed_pixel_size = 1;
Packit daac2c
      }
Packit daac2c
  }
Packit daac2c
Packit daac2c
  gstring.size = gstring.used = 256;
Packit daac2c
  g = calloc (256, sizeof (OTF_Glyph));
Packit daac2c
  gstring.glyphs = g;
Packit daac2c
Packit daac2c
  shell = XtOpenApplication (&context, "OTFView", NULL, 0, &argc, argv, NULL,
Packit daac2c
			     shellWidgetClass, arg, 0);
Packit daac2c
  display = XtDisplay (shell);
Packit daac2c
  /*XSynchronize (display, True);*/
Packit daac2c
  XSetErrorHandler (x_error_handler);
Packit daac2c
  display_width = DisplayWidth (display,
Packit daac2c
				XScreenNumberOfScreen (XtScreen (shell)));
Packit daac2c
  font = XLoadQueryFont (display, DEFAULT_FONT_NAME);
Packit daac2c
  if (! font)
Packit daac2c
    font = XLoadQueryFont (display, "fixed");
Packit daac2c
Packit daac2c
  if (argc < 2)
Packit daac2c
    help (argv, 1);
Packit daac2c
  if (!strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
Packit daac2c
    help (argv, 0);
Packit daac2c
  filename = argv[1];
Packit daac2c
  if (argc > 2)
Packit daac2c
    {
Packit daac2c
      fontindex = atoi (argv[2]);
Packit daac2c
      if (fontindex < 0)
Packit daac2c
	FATAL_ERROR ("Invalid font index: %d\n", fontindex);
Packit daac2c
    }
Packit daac2c
Packit daac2c
  if ((err = FT_Init_FreeType (&library)))
Packit daac2c
    FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
Packit daac2c
  err = FT_New_Face (library, filename, fontindex, &face);
Packit daac2c
  if (err == FT_Err_Unknown_File_Format)
Packit daac2c
    FATAL_ERROR ("%s\n", "FT_New_Face: unknown file format");
Packit daac2c
  else if (err)
Packit daac2c
    FATAL_ERROR ("%s\n", "FT_New_Face: unknown error (invalid face index?)");
Packit daac2c
  if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
Packit daac2c
    FATAL_ERROR ("%s\n", "FT_Set_Pixel_Sizes: error");
Packit daac2c
Packit daac2c
  if (strstr (filename, ".ttf")
Packit daac2c
      || strstr (filename, ".TTF")
Packit daac2c
      || strstr (filename, ".otf")
Packit daac2c
      || strstr (filename, ".OTF"))
Packit daac2c
    {
Packit daac2c
      otf = OTF_open_ft_face (face);
Packit daac2c
      if (otf)
Packit daac2c
	{
Packit daac2c
	  if (OTF_get_table (otf, "head") < 0
Packit daac2c
	      || OTF_get_table (otf, "cmap") < 0
Packit daac2c
	      || (OTF_check_table (otf, "GSUB") < 0
Packit daac2c
		  && OTF_check_table (otf, "GPOS") < 0))
Packit daac2c
	    {
Packit daac2c
	      OTF_close (otf);
Packit daac2c
	      otf = NULL;
Packit daac2c
	    }
Packit daac2c
	}
Packit daac2c
      if (otf)
Packit daac2c
	for (i = 0; i < otf->cmap->numTables; i++)
Packit daac2c
	  if (otf->cmap->EncodingRecord[i].subtable.format == 14)
Packit daac2c
	    {
Packit daac2c
	      sub14 = otf->cmap->EncodingRecord[i].subtable.f.f14;
Packit daac2c
	      break;
Packit daac2c
	    }
Packit daac2c
    }
Packit daac2c
Packit daac2c
  {
Packit daac2c
    char title[256];
Packit daac2c
    Arg arg[1];
Packit daac2c
Packit daac2c
    filename = basename (filename);
Packit daac2c
    sprintf (title, "%s family:%s style:%s",
Packit daac2c
	     filename, face->family_name, face->style_name);
Packit daac2c
    XtSetArg (arg[0], XtNtitle, title);
Packit daac2c
    XtSetValues (shell, arg, 1);
Packit daac2c
  }
Packit daac2c
Packit daac2c
  glyph_width = ((face->bbox.xMax - face->bbox.xMin)
Packit daac2c
		 * pixel_size / face->units_per_EM);
Packit daac2c
  if (! fixed_pixel_size && glyph_width * 16 > display_width * 0.8)
Packit daac2c
    {
Packit daac2c
      pixel_size = (pixel_size * display_width * 0.8 / 16 / glyph_width);
Packit daac2c
      FT_Set_Pixel_Sizes (face, 0, pixel_size);
Packit daac2c
      glyph_width = ((face->bbox.xMax - face->bbox.xMin)
Packit daac2c
		     * pixel_size / face->units_per_EM);
Packit daac2c
    }
Packit daac2c
  if (glyph_width < FONT_WIDTH * 4)
Packit daac2c
    glyph_width = FONT_WIDTH * 4;
Packit daac2c
Packit daac2c
  glyph_height = ((face->bbox.yMax - face->bbox.yMin)
Packit daac2c
		  *  pixel_size / face->units_per_EM);
Packit daac2c
Packit daac2c
  glyph_x = - (face->bbox.xMin * pixel_size / face->units_per_EM);
Packit daac2c
  glyph_y = face->bbox.yMax * pixel_size / face->units_per_EM;
Packit daac2c
  none_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
Packit daac2c
			       glyph_width, glyph_height, 1);
Packit daac2c
Packit daac2c
  {
Packit daac2c
    unsigned long valuemask =  GCFunction | GCLineWidth;
Packit daac2c
    XGCValues values;
Packit daac2c
Packit daac2c
    gc = XCreateGC (display, none_pixmap, (unsigned long) 0, NULL);
Packit daac2c
    XSetFont (display, gc, font->fid);
Packit daac2c
    values.function = GXset;
Packit daac2c
    values.line_width = 1;
Packit daac2c
    gc_set = XCreateGC (display, none_pixmap, valuemask, &values);
Packit daac2c
    XSetFont (display, gc_set, font->fid);
Packit daac2c
    values.function = GXor;
Packit daac2c
    gc_or = XCreateGC (display, none_pixmap, valuemask, &values);
Packit daac2c
    values.function = GXcopyInverted;
Packit daac2c
    gc_inv = XCreateGC (display, none_pixmap, valuemask, &values);
Packit daac2c
  }
Packit daac2c
Packit daac2c
  XFillRectangle (display, none_pixmap, gc, 0, 0,
Packit daac2c
		  glyph_width, glyph_height);
Packit daac2c
  XDrawString (display, none_pixmap, gc_inv,
Packit daac2c
	       (glyph_width - XTextWidth (font, "none", 4)) / 2,
Packit daac2c
	       glyph_height / 2, "none", 4);
Packit daac2c
Packit daac2c
  render_width = (glyph_width + 4) * 15 + 1;
Packit daac2c
  render_height = glyph_height + 2;
Packit daac2c
Packit daac2c
  charmap_rec[0].platform_id = -1;
Packit daac2c
  charmap_rec[0].encoding_id = -1;
Packit daac2c
  strcpy (charmap_rec[0].name, "no charmap");
Packit daac2c
Packit daac2c
  for (i = 0; i < face->num_charmaps; i++)
Packit daac2c
    {
Packit daac2c
      charmap_rec[i + 1].platform_id = face->charmaps[i]->platform_id;
Packit daac2c
      charmap_rec[i + 1].encoding_id = face->charmaps[i]->encoding_id;
Packit daac2c
      sprintf (charmap_rec[i + 1].name, "%d-%d",
Packit daac2c
	       charmap_rec[i + 1].platform_id, charmap_rec[i + 1].encoding_id);
Packit daac2c
      if (face->charmaps[i]->platform_id == 0
Packit daac2c
	  || (face->charmaps[i]->platform_id == 3
Packit daac2c
	      && face->charmaps[i]->encoding_id == 1))
Packit daac2c
	strcat (charmap_rec[i + 1].name, " (unicode)");
Packit daac2c
      else if (face->charmaps[i]->platform_id == 1
Packit daac2c
	       && face->charmaps[i]->encoding_id == 0)
Packit daac2c
	strcat (charmap_rec[i + 1].name, " (apple-roman)");
Packit daac2c
    }
Packit daac2c
Packit daac2c
  raw_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
Packit daac2c
			      render_width, render_height, 1);
Packit daac2c
  seq_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
Packit daac2c
			      render_width, render_height, 1);
Packit daac2c
Packit daac2c
  memset (bitmap, 0, sizeof (bitmap));
Packit daac2c
  create_widgets ();
Packit daac2c
  glyph_index = 0;
Packit daac2c
  charmap_index = -1;
Packit daac2c
  update_glyph_area ();
Packit daac2c
  update_render_area ();
Packit daac2c
Packit daac2c
  XtAppAddActions (context, actions, XtNumber (actions));
Packit daac2c
  XtRealizeWidget (shell);
Packit daac2c
  XtAppMainLoop (context);
Packit daac2c
Packit daac2c
  exit (0);
Packit daac2c
}
Packit daac2c
Packit daac2c
#else /* not HAVE_X11_XAW_COMMAND_H */
Packit daac2c
Packit daac2c
int
Packit daac2c
main (int argc, char **argv)
Packit daac2c
{
Packit daac2c
  fprintf (stderr, 
Packit daac2c
	   "Building of this program failed (lack of some header files)\n");
Packit daac2c
  exit (1);
Packit daac2c
}
Packit daac2c
Packit daac2c
#endif