From 428c2cf31bffbf4874b29a797dc4f51df3944515 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 10 Jul 2003 13:02:28 +0000 Subject: [PATCH] *** empty log message *** --- example/otfviewx.c | 360 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 263 insertions(+), 97 deletions(-) diff --git a/example/otfviewx.c b/example/otfviewx.c index 039cb8c..b992e3d 100644 --- a/example/otfviewx.c +++ b/example/otfviewx.c @@ -7,9 +7,10 @@ #include #include #include +#include +#include #include #include -#include #include #include @@ -24,32 +25,59 @@ XFontStruct *font; 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]; @@ -61,16 +89,25 @@ unsigned glyph_width, glyph_height; 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; @@ -86,14 +123,17 @@ create_pixmap (int index, Display *display) 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 @@ -110,25 +150,63 @@ update_glyph_area () 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; @@ -145,7 +223,7 @@ ChangeProc (Widget w, XtPointer client_data, XtPointer call_data) } 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; @@ -155,91 +233,109 @@ EncodingProc (Widget w, XtPointer client_data, XtPointer call_data) 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 = "q: set() notify() unset()"; String PREV_action = "Shiftp: set() notify() unset()"; String prev_action = "~Shiftp: set() notify() unset()"; String next_action = "~Shiftn: set() notify() unset()"; String NEXT_action = "Shiftn: set() notify() unset()"; - String quit_action = "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++; @@ -249,14 +345,64 @@ create_widgets () 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) \ @@ -268,11 +414,8 @@ create_widgets () int main (int argc, char **argv) { - Display *display; - FT_Library library; - OTF *otf = NULL; OTF_GlyphString gstring; OTF_Glyph *g; @@ -299,7 +442,9 @@ main (int argc, char **argv) otf = OTF_open (argv[1]); if (! otf || OTF_get_table (otf, "head") < 0 - || OTF_get_table (otf, "cmap") < 0) + || OTF_get_table (otf, "cmap") < 0 + || (OTF_get_table (otf, "gsub") < 0 + && OTF_get_table (otf, "gpos") < 0)) otf = NULL; } @@ -322,7 +467,7 @@ main (int argc, char **argv) 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++) { @@ -339,14 +484,35 @@ main (int argc, char **argv) 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); -- 1.7.10.4