#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Form.h>
-#include <X11/Xaw/Command.h>
#include <X11/Xaw/Viewport.h>
#include <ft2build.h>
XtAppContext context;
/* Widget structure.
- +---form----------------------------+
- | +--- command_area --------------+ |
- | | charmap ... quit| |
+ +--- frame (form) ------------------+
+ | +--- command_area (box) --------+ |
+ | | quit charmap ... | |
+ | +-------------------------------+ |
+ | +---- navi_area (box) ----------+ |
| | PREV prev label next NEXT | |
| +-------------------------------+ |
- | +--- glyph_area ----------------+ |
- | | | |
- | | | |
- | | | |
+ | +--- glyph_area (form) ---------+ |
+ | | glyph[0] ... glyph[15] | |
+ | | ... ... | |
+ | | glyph[112] ... glyph[127]| |
| +-------------------------------+ |
- | +--- render_area ---------------+ |
- | | cmap: ... clear| |
- | | GSUB: ... | |
- | | GPOS: ... | |
+ | +--- render_area (form) --------+ |
+ | | clear | |
+ | | +--- raw (box) -------------+ | |
+ | | | raw_label raw_image | | |
+ | | +--- seq (box) -------------+ | |
+ | | | seq_label seq_image | | |
+ | | +--- gsub (box) ------------+ | |
+ | | | gsub_label gsub_image | | |
+ | | +--- gpos (box) ------------+ | |
+ | | | gpos_label gpos_image | | |
+ | | +---------------------------+ | |
| +-------------------------------+ |
+-----------------------------------+ */
-Widget shell, form, command_area, glyph_area, render_area;
-Widget PREV, prev, label, next, NEXT, *charmap, quit, glyph[128], clear;
+Widget shell, frame;
+Widget command_area, quit, *charmap;
+Widget navi_area, PREV, prev, label, next, NEXT;
+Widget glyph_area, glyph[128];
+Widget render_area, clear, raw, seq, gsub, gpos;
+Widget raw_label, raw_image, seq_label, seq_image;
+Widget gsub_label, gsub_image, gpos_label, gpos_image;
-unsigned char glyph_exist[0x10000];
-Pixmap pixmap[0x10000];
+int glyph_char[128];
+
+Display *display;
+GC gc, gc_set, gc_or;
+
+typedef struct {
+ Pixmap pixmap;
+ unsigned width, height;
+ int x, y;
+ int advance;
+} BitmapRec;
+
+BitmapRec bitmap[0x10000];
+
+int render_width, render_height;
+Pixmap raw_pixmap, seq_pixmap, gsub_pixmap, gpos_pixmap;
FT_Face face;
-struct
-{
+struct {
int platform_id;
int encoding_id;
char name[20];
int glyph_x, glyph_y;
int glyph_index;
-Pixmap
-create_pixmap (int index, Display *display)
+struct {
+ int n_glyphs;
+ int glyphs[64];
+} glyph_rec;
+
+OTF *otf;
+
+void
+create_pixmap (int pixel_size, int index)
{
int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
XImage ximage;
Pixmap pixmap;
- GC gc;
if (err)
- return (Pixmap) 0;
+ {
+ bitmap[index].pixmap = (Pixmap) 0;
+ return;
+ }
ximage.height = face->glyph->bitmap.rows;
ximage.width = face->glyph->bitmap.width;
ximage.depth = 1;
XInitImage (&ximage);
pixmap = XCreatePixmap (display, DefaultRootWindow (display),
glyph_width, glyph_height, 1);
- gc = XCreateGC(display, pixmap, (unsigned long) 0, (XGCValues *) 0);
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);
- XFreeGC (display, gc);
- return pixmap;
+ bitmap[index].pixmap = pixmap;
+ bitmap[index].width = ximage.width;
+ bitmap[index].height = ximage.height;
+ bitmap[index].x = face->glyph->bitmap_left;
+ bitmap[index].y = - face->glyph->bitmap_top;
+ bitmap[index].advance = face->glyph->metrics.horiAdvance >> 6;
}
void
if (charmap_index >= 0)
index = FT_Get_Char_Index (face, (FT_ULong) index);
- XtSetArg (arg[num_args], XtNbitmap, pixmap[index]), num_args++;
- if (! pixmap[index])
+ XtSetArg (arg[num_args], XtNbitmap, bitmap[index].pixmap), num_args++;
+ if (! bitmap[index].pixmap)
XtSetArg (arg[num_args], XtNlabel, "none"), num_args++;
XtSetValues (glyph[i], arg, num_args);
}
- sprintf (buf, " %04X ", glyph_index);
+ sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
XtSetArg (arg[0], XtNlabel, buf);
XtSetValues (label, arg, 1);
}
void
+update_render_area ()
+{
+ int i;
+ int x;
+ Arg arg[1];
+
+ XFillRectangle (display, raw_pixmap, gc, 0, 0, render_width, render_height);
+ XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
+ for (i = 0, x = glyph_x; i < glyph_rec.n_glyphs; i++)
+ {
+ BitmapRec *bmp = bitmap + glyph_rec.glyphs[i];
+
+ XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
+ 0, 0, glyph_width, glyph_height,
+ (glyph_width + 1) * i + 1, 1);
+ XDrawRectangle (display, raw_pixmap, gc_set,
+ (glyph_width + 1) * i, 0,
+ glyph_width + 1, glyph_height + 1);
+ XCopyArea (display, bmp->pixmap, seq_pixmap, gc_or,
+ glyph_x + bmp->x, glyph_y + bmp->y, bmp->width, bmp->height,
+ x + bmp->x, glyph_y + bmp->y);
+ x += bmp->advance;
+ }
+ XtSetArg (arg[0], XtNbitmap, raw_pixmap);
+ XtSetValues (raw_image, arg, 1);
+ XtSetArg (arg[0], XtNbitmap, seq_pixmap);
+ XtSetValues (seq_image, arg, 1);
+ if (! otf)
+ return;
+ XFillRectangle (display, gsub_pixmap, gc, 0, 0, render_width, render_height);
+ XFillRectangle (display, gpos_pixmap, gc, 0, 0, render_width, render_height);
+ XtSetArg (arg[0], XtNbitmap, gsub_pixmap);
+ XtSetValues (gsub_image, arg, 1);
+ XtSetArg (arg[0], XtNbitmap, gpos_pixmap);
+ XtSetValues (gpos_image, arg, 1);
+}
+
+void
QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
{
XtAppSetExitFlag (XtWidgetToApplicationContext (w));
}
void
-ChangeProc (Widget w, XtPointer client_data, XtPointer call_data)
+GlyphProc (Widget w, XtPointer client_data, XtPointer call_data)
{
int old_glyph_index = glyph_index;
}
void
-EncodingProc (Widget w, XtPointer client_data, XtPointer call_data)
+CharmapProc (Widget w, XtPointer client_data, XtPointer call_data)
{
if (charmap_index == (int) client_data)
return;
update_glyph_area ();
}
+void
+RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+ if ((int) client_data < 0)
+ {
+ glyph_rec.n_glyphs = 0;
+ update_render_area ();
+ }
+ else if (glyph_rec.n_glyphs < 64)
+ {
+ int index = glyph_index + (int) client_data;
+ if (charmap_index >= 0)
+ index = FT_Get_Char_Index (face, (FT_ULong) index);
+ glyph_rec.glyphs[glyph_rec.n_glyphs++] = index;
+ update_render_area ();
+ }
+}
void
create_widgets ()
{
+ String quit_action = "<KeyPress>q: set() notify() unset()";
String PREV_action = "Shift<KeyPress>p: set() notify() unset()";
String prev_action = "~Shift<KeyPress>p: set() notify() unset()";
String next_action = "~Shift<KeyPress>n: set() notify() unset()";
String NEXT_action = "Shift<KeyPress>n: set() notify() unset()";
- String quit_action = "<KeyPress>q: set() notify() unset()";
Arg arg[10];
int i, j;
- form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);
- XtSetArg (arg[0], XtNborderWidth, 0);
- command_area = XtCreateManagedWidget ("command-area", formWidgetClass,
- form, arg, 1);
- XtSetArg (arg[0], XtNborderWidth, 1);
- XtSetArg (arg[1], XtNfromVert, command_area);
- XtSetArg (arg[2], XtNdefaultDistance, 0);
- glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
- form, arg, 3);
- XtSetArg (arg[0], XtNborderWidth, 0);
- XtSetArg (arg[1], XtNfromVert, glyph_area);
- render_area = XtCreateManagedWidget ("render", formWidgetClass,
- form, arg, 2);
-
- charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
+ frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, NULL, 0);
XtSetArg (arg[0], XtNleft, XawChainLeft);
XtSetArg (arg[1], XtNright, XawChainLeft);
XtSetArg (arg[2], XtNtop, XawChainTop);
XtSetArg (arg[3], XtNbottom, XawChainTop);
- charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, commandWidgetClass,
- command_area, arg, 4);
- XtAddCallback (charmap[0], XtNcallback, EncodingProc, (XtPointer) -1);
- for (i = 1; i <= face->num_charmaps; i++)
- {
- XtSetArg (arg[4], XtNfromHoriz, charmap[i - 1]);
- charmap[i] = XtCreateManagedWidget (charmap_rec[i].name,
- commandWidgetClass,
- command_area, arg, 5);
- XtAddCallback (charmap[i], XtNcallback, EncodingProc,
- (XtPointer) (i - 1));
- }
- XtSetArg (arg[0], XtNleft, XawChainRight);
- XtSetArg (arg[1], XtNright, XawChainRight);
- XtSetArg (arg[4], XtNfromHoriz, charmap[i - 1]);
- XtSetArg (arg[5], XtNaccelerators, XtParseAcceleratorTable (quit_action));
+ XtSetArg (arg[4], XtNborderWidth, 0);
+ XtSetArg (arg[5], XtNorientation, XtorientHorizontal);
+ command_area = XtCreateManagedWidget ("command-area", boxWidgetClass,
+ frame, arg, 6);
+ XtSetArg (arg[6], XtNfromVert, command_area);
+ navi_area = XtCreateManagedWidget ("navi-area", boxWidgetClass,
+ frame, arg, 7);
+ XtSetArg (arg[4], XtNborderWidth, 1);
+ XtSetArg (arg[5], XtNfromVert, navi_area);
+ XtSetArg (arg[6], XtNdefaultDistance, 0);
+ glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
+ frame, arg, 7);
+ XtSetArg (arg[4], XtNborderWidth, 0);
+ XtSetArg (arg[5], XtNfromVert, glyph_area);
+ render_area = XtCreateManagedWidget ("render-area", formWidgetClass,
+ frame, arg, 6);
+
+ XtSetArg (arg[0], XtNaccelerators, XtParseAcceleratorTable (quit_action));
quit = XtCreateManagedWidget ("quit", commandWidgetClass,
- command_area, arg, 6);
+ command_area, arg, 1);
XtAddCallback (quit, XtNcallback, QuitProc, NULL);
- XtSetArg (arg[4], XtNfromVert, charmap[0]);
- XtSetArg (arg[5], XtNlabel, "<< (P)");
- XtSetArg (arg[6], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
+ charmap = alloca (sizeof (Widget) * (face->num_charmaps + 1));
+ XtSetArg (arg[0], XtNstate, True);
+ charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, toggleWidgetClass,
+ command_area, arg, 1);
+ XtAddCallback (charmap[0], XtNcallback, CharmapProc, (XtPointer) -1);
+ XtSetArg (arg[0], XtNradioGroup, charmap[0]);
+ for (i = 0; i < face->num_charmaps; i++)
+ {
+ charmap[i + 1] = XtCreateManagedWidget (charmap_rec[i + 1].name,
+ toggleWidgetClass,
+ command_area, arg, 1);
+ XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i);
+ }
+
+ XtSetArg (arg[0], XtNlabel, "<< (P)");
+ XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (PREV_action));
PREV = XtCreateManagedWidget ("PREV", commandWidgetClass,
- command_area, arg, 7);
- XtAddCallback (PREV, XtNcallback, ChangeProc, (XtPointer) -2);
- XtSetArg (arg[5], XtNfromHoriz, PREV);
- XtSetArg (arg[6], XtNlabel, "< (p)");
- XtSetArg (arg[7], XtNaccelerators, XtParseAcceleratorTable (prev_action));
+ navi_area, arg, 2);
+ XtAddCallback (PREV, XtNcallback, GlyphProc, (XtPointer) -2);
+ XtSetArg (arg[0], XtNlabel, "< (p)");
+ XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action));
prev = XtCreateManagedWidget ("prev", commandWidgetClass,
- command_area, arg, 8);
- XtAddCallback (prev, XtNcallback, ChangeProc, (XtPointer) -1);
- XtSetArg (arg[5], XtNfromHoriz, prev);
- XtSetArg (arg[6], XtNlabel, " 0000 ");
+ navi_area, arg, 2);
+ XtAddCallback (prev, XtNcallback, GlyphProc, (XtPointer) -1);
+ XtSetArg (arg[0], XtNlabel, " 0000 ");
label = XtCreateManagedWidget ("label", labelWidgetClass,
- command_area, arg, 7);
- XtSetArg (arg[5], XtNfromHoriz, label);
- XtSetArg (arg[6], XtNlabel, "(n) >");
- XtSetArg (arg[7], XtNaccelerators, XtParseAcceleratorTable (next_action));
+ navi_area, arg, 1);
+ XtSetArg (arg[0], XtNlabel, "(n) >");
+ XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (next_action));
next = XtCreateManagedWidget ("next", commandWidgetClass,
- command_area, arg, 8);
- XtAddCallback (next, XtNcallback, ChangeProc, (XtPointer) 1);
- XtSetArg (arg[5], XtNfromHoriz, next);
- XtSetArg (arg[6], XtNlabel, "(N) >>");
- XtSetArg (arg[7], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
+ navi_area, arg, 2);
+ XtAddCallback (next, XtNcallback, GlyphProc, (XtPointer) 1);
+ XtSetArg (arg[0], XtNlabel, "(N) >>");
+ XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (NEXT_action));
NEXT = XtCreateManagedWidget ("NEXT", commandWidgetClass,
- command_area, arg, 8);
- XtAddCallback (NEXT, XtNcallback, ChangeProc, (XtPointer) 2);
+ navi_area, arg, 2);
+ XtAddCallback (NEXT, XtNcallback, GlyphProc, (XtPointer) 2);
+ XtSetArg (arg[0], XtNleft, XawChainLeft);
+ XtSetArg (arg[1], XtNright, XawChainLeft);
+ XtSetArg (arg[2], XtNtop, XawChainTop);
+ XtSetArg (arg[3], XtNbottom, XawChainTop);
for (i = 0; i < 8; i++)
for (j = 0; j < 16; j++)
{
int k = i * 16 + j;
- int num_args = 0;
+ int num_args = 4;
XtSetArg (arg[num_args], XtNwidth, glyph_width), num_args++;
XtSetArg (arg[num_args], XtNheight, glyph_height), num_args++;
XtSetArg (arg[num_args], XtNfromVert, glyph[k - 16]), num_args++;
glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass,
glyph_area, arg, num_args);
+ XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k);
}
+ XtSetArg (arg[0], XtNleft, XawChainLeft);
+ XtSetArg (arg[1], XtNright, XawChainLeft);
+ XtSetArg (arg[2], XtNtop, XawChainTop);
+ XtSetArg (arg[3], XtNbottom, XawChainTop);
clear = XtCreateManagedWidget ("clear", commandWidgetClass,
- render_area, NULL, 0);
+ render_area, arg, 4);
+ XtAddCallback (clear, XtNcallback, RenderProc, (XtPointer) -1);
+ XtSetArg (arg[4], XtNorientation, XtorientHorizontal);
+ XtSetArg (arg[5], XtNborderWidth, 0);
+ XtSetArg (arg[6], XtNfromVert, clear);
+ raw = XtCreateManagedWidget ("raw", boxWidgetClass,
+ render_area, arg, 7);
+ XtSetArg (arg[0], XtNborderWidth, 0);
+ XtSetArg (arg[1], XtNlabel, "raw: ");
+ raw_label = XtCreateManagedWidget ("raw-label", labelWidgetClass,
+ raw, arg, 2);
+ XtSetArg (arg[1], XtNbitmap, raw_pixmap);
+ raw_image = XtCreateManagedWidget ("raw-image", labelWidgetClass,
+ raw, arg, 2);
+ XtSetArg (arg[6], XtNfromVert, raw);
+ seq = XtCreateManagedWidget ("seq", boxWidgetClass,
+ render_area, arg, 7);
+ XtSetArg (arg[0], XtNborderWidth, 0);
+ XtSetArg (arg[1], XtNlabel, "seq: ");
+ seq_label = XtCreateManagedWidget ("seq-label", labelWidgetClass,
+ seq, arg, 2);
+ XtSetArg (arg[1], XtNbitmap, seq_pixmap);
+ seq_image = XtCreateManagedWidget ("seq-image", labelWidgetClass,
+ seq, arg, 2);
+ if (otf)
+ {
+ XtSetArg (arg[6], XtNfromVert, seq);
+ gsub = XtCreateManagedWidget ("gsub", boxWidgetClass,
+ render_area, arg, 7);
+ XtSetArg (arg[0], XtNborderWidth, 0);
+ XtSetArg (arg[1], XtNlabel, "gsub: ");
+ gsub_label = XtCreateManagedWidget ("gsub-label", labelWidgetClass,
+ gsub, arg, 2);
+ gsub_image = XtCreateManagedWidget ("gsub-image", labelWidgetClass,
+ gsub, arg, 1);
+ XtSetArg (arg[6], XtNfromVert, gsub);
+ gpos = XtCreateManagedWidget ("gpos", boxWidgetClass,
+ render_area, arg, 7);
+ XtSetArg (arg[0], XtNborderWidth, 0);
+ XtSetArg (arg[1], XtNlabel, "gpos: ");
+ gpos_label = XtCreateManagedWidget ("gpos-label", labelWidgetClass,
+ gpos, arg, 2);
+ gpos_image = XtCreateManagedWidget ("gpos-image", labelWidgetClass,
+ gpos, arg, 1);
+ }
- XtInstallAllAccelerators (form, form);
+ XtInstallAllAccelerators (frame, frame);
}
+
/* Format MSG by FMT and print the result to the stderr, and exit. */
#define FATAL_ERROR(fmt, arg) \
int
main (int argc, char **argv)
{
- Display *display;
-
FT_Library library;
- OTF *otf = NULL;
OTF_GlyphString gstring;
OTF_Glyph *g;
otf = OTF_open (argv[1]);
if (! otf
|| OTF_get_table (otf, "head") < 0
- || OTF_get_table (otf, "cmap") < 0)
+ || OTF_get_table (otf, "cmap") < 0
+ || (OTF_get_table (otf, "gsub") < 0
+ && OTF_get_table (otf, "gpos") < 0))
otf = NULL;
}
charmap_rec[0].platform_id = -1;
charmap_rec[0].encoding_id = -1;
- strcpy (charmap_rec[0].name, "bypass charmap");
+ strcpy (charmap_rec[0].name, "no charmap");
for (i = 0; i < face->num_charmaps; i++)
{
strcat (charmap_rec[i + 1].name, " (apple-roman)");
}
- for (i = 0; i < 0x10000; i++)
- pixmap[i] = create_pixmap (i, display);
+ render_width = (glyph_width + 1) * 15 + 1;
+ render_height = glyph_height + 2;
+ raw_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+ render_width, render_height, 1);
+ seq_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+ render_width, render_height, 1);
+ gsub_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+ render_width, render_height, 1);
+ gpos_pixmap = XCreatePixmap (display, DefaultRootWindow (display),
+ render_width, render_height, 1);
+ {
+ unsigned long valuemask = GCFunction | GCLineWidth;
+ XGCValues values;
+
+ gc = XCreateGC (display, raw_pixmap, (unsigned long) 0, NULL);
+ values.function = GXset;
+ values.line_width = 1;
+ gc_set = XCreateGC (display, raw_pixmap, valuemask, &values);
+ values.function = GXor;
+ gc_or = XCreateGC (display, raw_pixmap, valuemask, &values);
+ }
+ for (i = 0; i < 0x10000; i++)
+ create_pixmap (pixel_size, i);
create_widgets ();
-
glyph_index = 0;
charmap_index = -1;
update_glyph_area ();
+ update_render_area ();
XtRealizeWidget (shell);
XtAppMainLoop (context);