From 9f1c238e2a3d35a9503078c934cdf40f52476982 Mon Sep 17 00:00:00 2001 From: handa Date: Mon, 13 Oct 2003 00:58:02 +0000 Subject: [PATCH] *** empty log message *** --- example/Makefile.am | 2 +- example/otfview.c | 103 ++++++++++++++++++++++++++++++++++----------------- src/otf.h | 7 ++-- src/otfdrive.c | 45 +++------------------- src/otfopen.c | 36 +++++++++++++++++- 5 files changed, 113 insertions(+), 80 deletions(-) diff --git a/example/Makefile.am b/example/Makefile.am index f7d7561..6497be1 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -10,7 +10,7 @@ otflist_LDFLAGS = `freetype-config --libs` ${CommonLDFLAGS} otfdump_SOURCE = otfdump.c otfdump_LDADD = ${CommonLDADD} -otfdump_LDFLAGS = ${CommonLDFLAGS} -lefence +otfdump_LDFLAGS = ${CommonLDFLAGS} otfdraw_SOURCE = otfdraw.c otfdraw_LDADD = ${CommonLDADD} diff --git a/example/otfview.c b/example/otfview.c index d1bfcd5..392729e 100644 --- a/example/otfview.c +++ b/example/otfview.c @@ -23,37 +23,38 @@ #define DEFAULT_FONT_NAME "6x13" XFontStruct *font; #define FONT_HEIGHT (font->ascent + font->descent) +#define FONT_DESCENT (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 | | | - | | +---------------------------+ | | - | +-------------------------------+ | - +-----------------------------------+ */ + +--- frame (form) -------------------------+ + | +--- command_area (box) ---------------+ | + | | quit charmap ... | | + | +--------------------------------------+ | + | +---- navi_area (box) -----------------+ | + | | FIRST PREV prev label next NEXT LAST | | + | +--------------------------------------+ | + | +--- 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 navi_area, FIRST, PREV, prev, label, next, NEXT, LAST; Widget glyph_area, glyph[128]; Widget render_area, clear, raw, seq, gsub, gpos; Widget raw_label, raw_image, seq_label, seq_image; @@ -62,7 +63,7 @@ Widget gsub_label, gsub_image, gpos_label, gpos_image; int glyph_char[128]; Display *display; -GC gc, gc_set, gc_or; +GC gc, gc_set, gc_or, gc_inv; typedef struct { Pixmap pixmap; @@ -103,6 +104,8 @@ create_pixmap (int pixel_size, int index) int err = FT_Load_Glyph (face, index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME); XImage ximage; Pixmap pixmap; + int height = glyph_height + 1 + FONT_HEIGHT; + char index_buf[5]; if (err) { @@ -123,12 +126,18 @@ create_pixmap (int pixel_size, int index) 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); + glyph_width, height, 1); + XFillRectangle (display, pixmap, gc, 0, 0, glyph_width, height); XPutImage (display, pixmap, gc, &ximage, 0, 0, glyph_x + face->glyph->bitmap_left, glyph_y - face->glyph->bitmap_top, ximage.width, ximage.height); + sprintf (index_buf, "%04X", index); + XDrawLine (display, pixmap, gc_inv, + 0, glyph_height + 1, glyph_width, glyph_height + 1); + XDrawString (display, pixmap, gc_inv, + (glyph_width - XTextWidth (font, index_buf, 4)) / 2, + height - FONT_DESCENT, index_buf, 4); bitmap[index].pixmap = pixmap; bitmap[index].width = ximage.width; bitmap[index].height = ximage.height; @@ -211,7 +220,9 @@ GlyphProc (Widget w, XtPointer client_data, XtPointer call_data) { int old_glyph_index = glyph_index; - if ((int) client_data == -2 && glyph_index > 0) + if ((int) client_data == -3 && glyph_index > 0) + glyph_index = 0; + else 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; @@ -219,6 +230,8 @@ GlyphProc (Widget w, XtPointer client_data, XtPointer call_data) glyph_index += 0x80; else if ((int) client_data == 2 && glyph_index < 0xF000) glyph_index = (glyph_index + 0x1000) & 0xF000; + else if ((int) client_data == 3 && glyph_index < 0xF000) + glyph_index = 0xFF80; if (glyph_index != old_glyph_index) update_glyph_area (); } @@ -260,12 +273,15 @@ void create_widgets () { String quit_action = "q: set() notify() unset()"; + String FIRST_action = "~Shiftf: 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 LAST_action = "~Shiftl: set() notify() unset()"; Arg arg[10]; int i, j; + int glyph_widget_height; frame = XtCreateManagedWidget ("frame", formWidgetClass, shell, NULL, 0); XtSetArg (arg[0], XtNleft, XawChainLeft); @@ -308,12 +324,17 @@ create_widgets () XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i); } - XtSetArg (arg[0], XtNlabel, "-0x1000 (P)"); + XtSetArg (arg[0], XtNlabel, " |< (f)"); + XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (FIRST_action)); + FIRST = XtCreateManagedWidget ("FIRST", commandWidgetClass, + navi_area, arg, 2); + XtAddCallback (FIRST, XtNcallback, GlyphProc, (XtPointer) -3); + 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, "-0x80 (p)"); + XtSetArg (arg[0], XtNlabel, "< (p)"); XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (prev_action)); prev = XtCreateManagedWidget ("prev", commandWidgetClass, navi_area, arg, 2); @@ -321,17 +342,23 @@ create_widgets () XtSetArg (arg[0], XtNlabel, " 0000 "); label = XtCreateManagedWidget ("label", labelWidgetClass, navi_area, arg, 1); - XtSetArg (arg[0], XtNlabel, "+0x80 (n)"); + 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, "+0x1000 (N)"); + 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], XtNlabel, ">| (l)"); + XtSetArg (arg[1], XtNaccelerators, XtParseAcceleratorTable (LAST_action)); + LAST = XtCreateManagedWidget ("LAST", commandWidgetClass, + navi_area, arg, 2); + XtAddCallback (LAST, XtNcallback, GlyphProc, (XtPointer) 3); + glyph_widget_height = glyph_height + 1 + FONT_HEIGHT; XtSetArg (arg[0], XtNleft, XawChainLeft); XtSetArg (arg[1], XtNright, XawChainLeft); XtSetArg (arg[2], XtNtop, XawChainTop); @@ -343,11 +370,12 @@ create_widgets () 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], XtNheight, glyph_widget_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++; + XtSetArg (arg[num_args], XtNinternalWidth, 0), num_args++; glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass, glyph_area, arg, num_args); XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k); @@ -445,6 +473,9 @@ main (int argc, char **argv) display = XtDisplay (shell); display_width = DisplayWidth (display, XScreenNumberOfScreen (XtScreen (shell))); + font = XLoadQueryFont (display, DEFAULT_FONT_NAME); + if (! font) + font = XLoadQueryFont (display, "fixed"); if (argc != 2) FATAL_ERROR ("%s\n", "Usage: otfview [ X-OPTION ... ] OTF-FILE"); @@ -538,6 +569,8 @@ main (int argc, char **argv) gc_set = XCreateGC (display, raw_pixmap, valuemask, &values); values.function = GXor; gc_or = XCreateGC (display, raw_pixmap, valuemask, &values); + values.function = GXcopyInverted; + gc_inv = XCreateGC (display, raw_pixmap, valuemask, &values); } for (i = 0; i < 0x10000; i++) diff --git a/src/otf.h b/src/otf.h index 6232dca..f490bf6 100644 --- a/src/otf.h +++ b/src/otf.h @@ -219,7 +219,7 @@ typedef struct unsigned version; unsigned numTables; OTF_EncodingRecord *EncodingRecord; - OTF_EncodingRecord *Unicode; + unsigned short *unicode_table; } OTF_cmap; @@ -1098,8 +1098,9 @@ extern int OTF_check_table (OTF *otf, char *name); typedef struct { /* Character code of the glyph. This is the only member that a - client has to set before calling the function - OTF_drive_XXX(). */ + client has to set before calling the function OTF_drive_XXX(). + The value less than 32 is treated as a place-holder character, + and OTF_drive_XXX () function just ignore the glyph. */ int c; /* Glyph ID of the glyph. */ diff --git a/src/otfdrive.c b/src/otfdrive.c index 7fc59b6..08b9007 100644 --- a/src/otfdrive.c +++ b/src/otfdrive.c @@ -888,45 +888,6 @@ lookup_gpos (OTF_LookupList *lookup_list, unsigned lookup_list_index, return gidx; } -static int -lookup_cmap (OTF_cmap *cmap, int c) -{ - char *errfmt = "cmap driving%s"; - int errret = -1; - int i; - - if (! cmap || ! cmap->Unicode) - return 0; - - switch (cmap->Unicode->subtable.format) - { - case 4: - { - OTF_EncodingSubtable4 *sub4 = cmap->Unicode->subtable.f.f4; - int segCount = sub4->segCountX2 / 2; - - for (i = 0; i < segCount; i++) - if (c <= sub4->segments[i].endCount) - break; - if (i == segCount || c < sub4->segments[i].startCount) - return 0; - if (sub4->segments[i].idRangeOffset == 0xFFFF) - return c + sub4->segments[i].idDelta; - if (c == 0xFFFF) - return 0; - return sub4->glyphIdArray[sub4->segments[i].idRangeOffset - + (c - sub4->segments[i].startCount)]; - } - break; - - default: - OTF_ERROR (OTF_ERROR_CMAP_DRIVE, " (not yet supported)"); - break; - } - - return 0; -} - /* API */ @@ -944,7 +905,11 @@ OTF_drive_cmap (OTF *otf, OTF_GlyphString *gstring) cmap = otf->cmap; for (i = 0; i < gstring->used; i++) { - gstring->glyphs[i].glyph_id = lookup_cmap (cmap, gstring->glyphs[i].c); + int c = gstring->glyphs[i].c; + if (c < 32 || ! cmap || ! cmap->unicode_table) + gstring->glyphs[i].glyph_id = 0; + else + gstring->glyphs[i].glyph_id = cmap->unicode_table[c]; if (gstring->glyphs[i].glyph_id < 0) return -1; } diff --git a/src/otfopen.c b/src/otfopen.c index 4182137..29f4133 100644 --- a/src/otfopen.c +++ b/src/otfopen.c @@ -441,6 +441,7 @@ read_cmap_table (OTF *otf, OTF_Stream *stream) char *errfmt = "cmap%s"; void *errret = NULL; OTF_cmap *cmap; + int unicode_index = -1; int i; OTF_CALLOC (cmap, 1, ""); @@ -454,7 +455,7 @@ read_cmap_table (OTF *otf, OTF_Stream *stream) READ_ULONG (stream, cmap->EncodingRecord[i].offset); if (cmap->EncodingRecord[i].platformID == 3 && cmap->EncodingRecord[i].encodingID == 1) - cmap->Unicode = cmap->EncodingRecord + i; + unicode_index = i; } for (i = 0; i < cmap->numTables; i++) { @@ -545,6 +546,39 @@ read_cmap_table (OTF *otf, OTF_Stream *stream) } } } + + if (unicode_index >= 0) + { + OTF_EncodingRecord *rec = cmap->EncodingRecord + unicode_index; + + OTF_MALLOC (cmap->unicode_table, 0x10000, ""); + switch (rec->subtable.format) + { + case 4: + { + OTF_EncodingSubtable4 *sub4 = rec->subtable.f.f4; + int segCount = sub4->segCountX2 / 2; + + for (i = 0; i < segCount; i++) + { + OTF_cmapSegument *seg = sub4->segments + i; + int c; + + if (seg->idRangeOffset == 0xFFFF) + for (c = seg->startCount; c <= seg->endCount; c++) + cmap->unicode_table[c] = c + seg->idDelta; + else + for (c = seg->startCount; c <= seg->endCount && c != 0xFFFF; + c++) + cmap->unicode_table[c] + = sub4->glyphIdArray[seg->idRangeOffset + + (c - seg->startCount)]; + } + } + } + + } + return cmap; } -- 1.7.10.4