From e3366bd818a5ea5359cc4b09d0769741c0ea6d04 Mon Sep 17 00:00:00 2001 From: handa Date: Wed, 9 Jul 2003 13:11:33 +0000 Subject: [PATCH] *** empty log message *** --- example/Makefile.am | 6 +- example/otfview.c | 5 +- example/otfviewx.c | 330 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 example/otfviewx.c diff --git a/example/Makefile.am b/example/Makefile.am index e38ebff..7583fd6 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = otfdump otfdraw otfview otflist +bin_PROGRAMS = otfviewx otfdump otfdraw otfview otflist INCLUDES = `freetype-config --cflags` CommonLDADD = ${top_builddir}/src/libotf.la @@ -19,3 +19,7 @@ otfdraw_LDFLAGS = `freetype-config --libs` ${X_LIBS} ${X_PRE_LIBS} -lX11 -ldl ${ otfview_SOURCE = otfview.c otfview_LDADD = ${CommonLDADD} otfview_LDFLAGS = `freetype-config --libs` ${X_LIBS} ${X_PRE_LIBS} -lX11 -ldl ${CommonLDFLAGS} + +otfviewx_SOURCE = otfviewx.c +otfviewx_LDADD = ${CommonLDADD} +otfviewx_LDFLAGS = `freetype-config --libs` ${X_LIBS} ${X_PRE_LIBS} -lX11 -lXt -lXaw -lXmu -ldl -static diff --git a/example/otfview.c b/example/otfview.c index 6b2e416..f2253d4 100644 --- a/example/otfview.c +++ b/example/otfview.c @@ -280,7 +280,7 @@ main (int argc, char **argv) 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; + 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 @@ -507,7 +507,8 @@ main (int argc, char **argv) if (update_mask & UPDATE_BITMAP) { x = margin + 1; - y = (margin * 2 + rendering_area_height + font_height + 2 + 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) { diff --git a/example/otfviewx.c b/example/otfviewx.c new file mode 100644 index 0000000..121d633 --- /dev/null +++ b/example/otfviewx.c @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include FT_FREETYPE_H + +#include + +#define DEFAULT_PIXEL_SIZE 30 +#define DEFAULT_FONT_NAME "6x13" +XFontStruct *font; +#define FONT_HEIGHT (font->ascent + font->descent) + +XtAppContext context; +/* Widget structure. + +---form----------------------------+ + | +--- command_area --------------+ | + | | prev next charmap ... quit| | + | +-------------------------------+ | + | +--- glyph_area ----------------+ | + | | | | + | | | | + | | | | + | +-------------------------------+ | + | +--- render_area ---------------+ | + | | cmap: ... clear| | + | | GSUB: ... | | + | | GPOS: ... | | + | +-------------------------------+ | + +-----------------------------------+ */ +Widget shell, form, command_area, glyph_area, render_area; +Widget prev, next, *charmap, quit, glyph[128], clear; + +unsigned char glyph_exist[0x10000]; +Pixmap pixmap[0x10000]; + +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; + +Pixmap +create_pixmap (int index, Display *display) +{ + int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME); + XImage ximage; + Pixmap pixmap; + GC gc; + + if (err) + return (Pixmap) 0; + 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); + 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; +} + +void +update_glyph_area () +{ + int i; + + for (i = 0; i < 128; i++) + { + int index = glyph_index + i; + Arg arg[2]; + int num_args = 0; + + 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], XtNlabel, "none"), num_args++; + XtSetValues (glyph[i], arg, num_args); + } +} + +void +QuitProc (Widget w, XtPointer client_data, XtPointer call_data) +{ + XtAppSetExitFlag (XtWidgetToApplicationContext (w)); +} + +void +ChangeProc (Widget w, XtPointer client_data, XtPointer call_data) +{ + if ((int) client_data < 0 && glyph_index > 0) + { + glyph_index -= 128; + update_glyph_area (); + } + else if ((int) client_data > 0 && glyph_index <= 0xFF00) + { + glyph_index += 128; + update_glyph_area (); + } +} + +void +EncodingProc (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 (); +} + +static void +ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num) +{ +} + +static void +KeyProc (Widget w, XEvent *event, String *str, Cardinal *num) +{ + fprintf (stderr, "key pressed\n"); +} + +/* 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) +{ + XtActionsRec actions[] = { {"Expose", ExposeProc}, + {"Key", KeyProc} }; + String prev_action = "<: set() notify() unset()\n\ + p: set() notify() unset()\n"; + String next_action = ">: set() notify() unset()\n\ + n: set() notify() unset()\n"; + String quit_action = "q: set() notify() unset()"; + Arg arg[10]; + Display *display; + + FT_Library library; + + OTF *otf = NULL; + OTF_GlyphString gstring; + OTF_Glyph *g; + + int err; + int i, j; + 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); + XtAppAddActions (context, actions, XtNumber (actions)); + + 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 = 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, "bypass 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)"); + } + + for (i = 0; i < 0x10000; i++) + pixmap[i] = create_pixmap (i, display); + + 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)); + XtSetArg (arg[0], XtNleft, XawChainLeft); + XtSetArg (arg[1], XtNright, XawChainLeft); + XtSetArg (arg[2], XtNtop, XawChainTop); + XtSetArg (arg[3], XtNbottom, XawChainTop); + XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (prev_action)); + prev = XtCreateManagedWidget ("prev", commandWidgetClass, + command_area, arg, 5); + XtAddCallback (prev, XtNcallback, ChangeProc, (XtPointer) -1); + XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (next_action)); + XtSetArg (arg[5], XtNfromHoriz, prev); + next = XtCreateManagedWidget ("next", commandWidgetClass, + command_area, arg, 6); + XtAddCallback (next, XtNcallback, ChangeProc, (XtPointer) 1); + XtSetArg (arg[4], XtNfromHoriz, next); + charmap[0] = XtCreateManagedWidget (charmap_rec[0].name, commandWidgetClass, + command_area, arg, 5); + 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[4], XtNfromHoriz, charmap[i - 1]); + XtSetArg (arg[5], XtNaccelerators, XtParseAcceleratorTable (quit_action)); + quit = XtCreateManagedWidget ("quit", commandWidgetClass, + command_area, arg, 6); + XtAddCallback (quit, XtNcallback, QuitProc, NULL); + + for (i = 0; i < 8; i++) + for (j = 0; j < 16; j++) + { + int k = i * 16 + j; + int num_args = 0; + + 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); + } + + clear = XtCreateManagedWidget ("clear", commandWidgetClass, + render_area, NULL, 0); + + glyph_index = 0; + charmap_index = -1; + update_glyph_area (); + + XtInstallAllAccelerators (form, form); + XtRealizeWidget (shell); + XtAppMainLoop (context); + + exit (0); +} -- 1.7.10.4