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