X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=example%2Fotfview.c;h=82c3cfeda47683fe3f077966c4059f76312a3061;hb=bf40bc427bf292f450654ae2ab1195428caa00b1;hp=3700d9efcffa1d4254a5636a139fd63ed02356da;hpb=7a97ff0e6621fea8d6d1e993e042747e438934eb;p=m17n%2Flibotf.git diff --git a/example/otfview.c b/example/otfview.c index 3700d9e..82c3cfe 100644 --- a/example/otfview.c +++ b/example/otfview.c @@ -1,6 +1,6 @@ /* otfview.c -- View glyphs of OpenType fonts. -Copyright (C) 2003, 2004, 2005, 2006, 2008 +Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO167 @@ -47,6 +47,19 @@ write to the Free Software Foundation, Inc., 59 Temple Place, Suite #include +#define CAST_FROM_XTPOINTER(TYPE, DATA, VAR) \ + do { \ + long TYPE temp = (long TYPE) (DATA); \ + (VAR) = temp; \ + } while (0) + +#define XtAddCallbackWithCast(TYPE, W, PROC, VAR) \ + do { \ + long TYPE temp = (long TYPE) (VAR); \ + XtAddCallback (W, XtNcallback, PROC, (XtPointer) temp); \ + } while (0) + + #define DEFAULT_PIXEL_SIZE 30 int pixel_size; @@ -72,6 +85,9 @@ XtAppContext context; | | idxh[7] glyph[112] ... glyph[127]| | | | idxl[0] ... idxl[15] | | | +--------------------------------------+ | + | +--- script_area (box) ----------------+ | + | | script(langsys) DFLT ... | | + | +--------------------------------------+ | | +---- uvs_area (box) (optional) -------+ | | | uvs[?].w ... | | | +--------------------------------------+ | @@ -85,6 +101,9 @@ XtAppContext context; | | +--- seq (box) --------------------+ | | | | | seq_label seq_image | | | | | +----------------------------------+ | | + | | +--- code (box) -------------------+ | | + | | | code_label code_list ... | | | + | | +----------------------------------+ | | | +--------------------------------------+ | +------------------------------------------+ */ Widget shell, frame; @@ -92,8 +111,8 @@ Widget command_area, quit, dump, *charmap; Widget navi_area, FIRST, PREV, prev, range, next, NEXT, LAST; Widget glyph_area, glyph[128], index_label[8]; Widget uvs_area, uvs_label; -Widget render_area, clear, del, bidi, alt_subst, raw, seq; -Widget raw_label, raw_image, seq_label, seq_image; +Widget render_area, clear, del, bidi, alt_subst, raw, seq, code; +Widget raw_label, raw_image, seq_label, seq_image, code_label, code_list; unsigned long foreground, background; typedef struct @@ -280,21 +299,21 @@ get_features (OTF_FeatureList *list, FeatureRec *rec) int i, n; char *str, *p; - if (! rec->langsys || ! rec->features || ! rec->features[0].on) + if (! rec->langsys || ! rec->features) return NULL; for (i = n = 0; i < rec->langsys->FeatureCount; i++) - { - if (rec->features[i].on) - n++; - else - break; - } + if (rec->features[i].on) + n++; + if (n == 0) + return NULL; str = malloc (n * 5); - for (i = 0, p = str; i < n; i++, p += 5) - { - OTF_tag_name (rec->features[i].tag, p); - p[4] = ','; - } + for (i = 0, p = str; i < rec->langsys->FeatureCount; i++) + if (rec->features[i].on) + { + OTF_tag_name (rec->features[i].tag, p); + p[4] = ','; + p += 5; + } p[-1] = '\0'; return str; } @@ -340,6 +359,8 @@ update_seq_area () int len = glyph_rec.n_glyphs; Arg arg[1]; int unitsPerEm = face->units_per_EM; + OTF_Tag *log = NULL; + int logsize; gstring.size = gstring.used = len; gstring.glyphs = malloc (sizeof (OTF_Glyph) * len); @@ -355,19 +376,45 @@ update_seq_area () XDrawLine (display, seq_pixmap, gc_set, 0, glyph_y, render_width, glyph_y); if (otf) { + char *script_name = NULL, *langsys_name = NULL, buf[10]; char *str; - OTF_drive_gdef (otf, &gstring); + if (script_tag) + { + script_name = buf; + OTF_tag_name (script_tag, script_name); + } + if (langsys_tag) + { + langsys_name = buf + 5; + OTF_tag_name (langsys_tag, langsys_name); + } + OTF_drive_cmap (otf, &gstring); + OTF_drive_gdef (otf, &gstring); if (otf->gsub) { str = get_features (&otf->gsub->FeatureList, &gsub); if (str) { if (do_alternate_subst) - OTF_drive_gsub_alternate (otf, &gstring, NULL, NULL, str); + OTF_drive_gsub_alternate (otf, &gstring, + script_name, langsys_name, str); else - OTF_drive_gsub (otf, &gstring, NULL, NULL, str); + { + OTF_drive_gsub_with_log (otf, &gstring, + script_name, langsys_name, str); + logsize = gstring.used * 2; + log = alloca (sizeof (OTF_Tag) * logsize); + for (i = 0; i < gstring.used; i++) + { + int idx = gstring.glyphs[i].positioning_type >> 4; + if (idx) + log[i] = otf->gsub->FeatureList.Feature[idx - 1].FeatureTag; + else + log[i] = 0; + } + } free (str); } } @@ -376,7 +423,32 @@ update_seq_area () str = get_features (&otf->gpos->FeatureList, &gpos); if (str) { - OTF_drive_gpos2 (otf, &gstring, NULL, NULL, str); + OTF_drive_gpos_with_log (otf, &gstring, + script_name, langsys_name, str); + if (log) + { + if (logsize < gstring.used) + { + OTF_Tag *log2 = alloca (sizeof (OTF_Tag) * gstring.used); + memset (log2, 0, sizeof (OTF_Tag) * gstring.used); + memcpy (log2, log, sizeof (OTF_Tag) * logsize); + logsize = gstring.used; + log = log2; + } + } + else + { + logsize = gstring.used; + log = alloca (sizeof (OTF_Tag) * logsize); + memset (log, 0, sizeof (OTF_Tag) * logsize); + } + for (i = 0; i < gstring.used; i++) + { + int idx = gstring.glyphs[i].positioning_type >> 4; + if (idx) + log[i] = otf->gpos->FeatureList.Feature[idx - 1].FeatureTag; + + } free (str); } } @@ -419,22 +491,22 @@ update_seq_area () continue; advance = bmp->advance; } - if (g->positioning_type) + if (g->positioning_type & 0xF) { while (1) { - switch (g->positioning_type) + switch (g->positioning_type & 0xF) { case 1: case 2: { int format = g->f.f1.format; if (format & OTF_XPlacement) - xoff = g->f.f1.value->XPlacement * pixel_size / unitsPerEm; + xoff += g->f.f1.value->XPlacement * pixel_size / unitsPerEm; if (format & OTF_XPlaDevice) xoff += DEVICE_DELTA (g->f.f1.value->XPlaDevice, pixel_size); if (format & OTF_YPlacement) - yoff = g->f.f1.value->YPlacement * pixel_size / unitsPerEm; + yoff += g->f.f1.value->YPlacement * pixel_size / unitsPerEm; if (format & OTF_YPlaDevice) yoff += DEVICE_DELTA (g->f.f1.value->YPlaDevice, pixel_size); if (format & OTF_XAdvance) @@ -478,7 +550,7 @@ update_seq_area () } if (i + 1 == gstring.used || gstring.glyphs[i + 1].glyph_id - || ! gstring.glyphs[i + 1].positioning_type) + || ! (gstring.glyphs[i + 1].positioning_type & 0xF)) break; i++, g++; } @@ -496,10 +568,43 @@ update_seq_area () else base = g, base_width = advance; } - free (gstring.glyphs); XtSetArg (arg[0], XtNbitmap, seq_pixmap); XtSetValues (seq_image, arg, 1); + + if (gstring.used > 0) + { + int size = render_width / FONT_WIDTH; + char *buf = alloca (size + 1); + char name[5]; + + sprintf (buf, "%04X", gstring.glyphs[0].glyph_id); + if (log && log[0]) + { + OTF_tag_name (log[0], name); + sprintf (buf + 4, " (%s)", name); + x = 11; + } + else + x = 4; + for (i = 1; i < gstring.used && x + 5 < size; i++, x += 5) + { + sprintf (buf + x, " %04X", gstring.glyphs[i].glyph_id); + if (log && log[i] && x + 11 < size) + { + OTF_tag_name (log[i], name); + sprintf (buf + x + 5, "(%s)", name); + x += 6; + } + } + while (x < size) + buf[x++] = ' '; + buf[x] = '\0'; + XtSetArg (arg[0], XtNlabel, buf); + XtSetValues (code_list, arg, 1); + } + + free (gstring.glyphs); } @@ -708,18 +813,21 @@ void GlyphProc (Widget w, XtPointer client_data, XtPointer call_data) { int old_glyph_index = glyph_index; + int data; + + CAST_FROM_XTPOINTER (int, client_data, data); - if ((int) client_data == -3 && glyph_index > 0) + if (data == -3 && glyph_index > 0) glyph_index = 0; - else if ((int) client_data == -2 && glyph_index > 0) + else if (data == -2 && glyph_index > 0) glyph_index = (glyph_index - 1) & 0x1FF000; - else if ((int) client_data == -1 && glyph_index > 0) + else if (data == -1 && glyph_index > 0) glyph_index -= 0x80; - else if ((int) client_data == 1 && glyph_index < 0x10FF80) + else if (data == 1 && glyph_index < 0x10FF80) glyph_index += 0x80; - else if ((int) client_data == 2 && glyph_index < 0x10F000) + else if (data == 2 && glyph_index < 0x10F000) glyph_index = (glyph_index + 0x1000) & 0x1FF000; - else if ((int) client_data == 3 && glyph_index < 0x10F000) + else if (data == 3 && glyph_index < 0x10F000) glyph_index = 0x10FF80; if (glyph_index != old_glyph_index) update_glyph_area (); @@ -728,9 +836,13 @@ GlyphProc (Widget w, XtPointer client_data, XtPointer call_data) void CharmapProc (Widget w, XtPointer client_data, XtPointer call_data) { - if (charmap_index == (int) client_data) + int data; + + CAST_FROM_XTPOINTER (int, client_data, data); + + if (charmap_index == data) return; - charmap_index = (int) client_data; + charmap_index = data; if (charmap_index >= 0) FT_Set_Charmap (face, face->charmaps[charmap_index]); update_glyph_area (); @@ -739,11 +851,14 @@ CharmapProc (Widget w, XtPointer client_data, XtPointer call_data) void UVSProc (Widget w, XtPointer client_data, XtPointer call_data) { - unsigned idx = (unsigned) client_data; - int selector = uvs[idx].c; + unsigned idx; + int selector; OTF_VariationSelectorRecord *record; int i; + CAST_FROM_XTPOINTER (unsigned, client_data, idx); + selector = uvs[idx].c; + if (glyph_rec.n_glyphs >= 64) return; for (i = 0; i < sub14->nRecords; i++) @@ -766,11 +881,15 @@ UVSProc (Widget w, XtPointer client_data, XtPointer call_data) void RenderProc (Widget w, XtPointer client_data, XtPointer call_data) { - if ((int) client_data < 0) + int data; + + CAST_FROM_XTPOINTER (int, client_data, data); + + if (data < 0) { if (glyph_rec.n_glyphs > 0) { - if ((int) client_data == -2) + if (data == -2) glyph_rec.n_glyphs--; else glyph_rec.n_glyphs = 0; @@ -779,16 +898,16 @@ RenderProc (Widget w, XtPointer client_data, XtPointer call_data) } else if (glyph_rec.n_glyphs < 64) { - int index = glyph_index + (int) client_data; + int index = glyph_index + data; if (charmap_index >= 0) index = FT_Get_Char_Index (face, (FT_ULong) index); if (bitmap[index].pixmap) { - glyph_rec.codes[glyph_rec.n_glyphs] = glyph_index + (int) client_data; + glyph_rec.codes[glyph_rec.n_glyphs] = glyph_index + data; glyph_rec.glyphs[glyph_rec.n_glyphs++] = index; if (otf) - update_uvs_area (glyph_index + (int) client_data); + update_uvs_area (glyph_index + data); update_render_area (); } } @@ -842,43 +961,35 @@ FeatureProc (Widget w, XtPointer client_data, XtPointer call_data) if (idx < 0) { int on = idx == -2; + char str[5]; - for (i = j = 0; j < rec->langsys->FeatureCount; j++) - { - int index = rec->langsys->FeatureIndex[j]; - - rec->features[j].tag - = rec->gsub_gpos->FeatureList.Feature[index].FeatureTag; - rec->features[j].on = on; - } + for (i = 0; i < rec->langsys->FeatureCount; i++) + if (rec->features[i].on != on) + { + rec->features[i].on = on; + if (on) + { + XtSetArg (arg[0], XtNborderWidth, 3); + XtSetArg (arg[1], XtNinternalHeight, 2); + XtSetArg (arg[2], XtNinternalWidth, 2); + } + else + { + XtSetArg (arg[0], XtNborderWidth, 1); + XtSetArg (arg[1], XtNinternalHeight, 4); + XtSetArg (arg[2], XtNinternalWidth, 4); + } + OTF_tag_name (rec->features[i].tag, str); + XtSetArg (arg[3], XtNlabel, str); + XtSetValues (rec->features[i].w, arg, 4); + } } else { - OTF_Tag tag = rec->features[idx].tag; - - i = idx; - if (rec->features[i].on) - { - for (j = i + 1; - j < rec->langsys->FeatureCount && rec->features[j].on; j++) - rec->features[j - 1].tag = rec->features[j].tag; - rec->features[j - 1].tag = tag; - rec->features[j - 1].on = 0; - } - else - { - for (j = i + 1; i > 0 && ! rec->features[i - 1].on; i--) - rec->features[i].tag = rec->features[i - 1].tag; - rec->features[i].tag = tag; - rec->features[i].on = 1; - } - } - - for (; i < j; i++) - { char str[5]; - if (rec->features[i].on) + rec->features[idx].on = ! rec->features[idx].on; + if (rec->features[idx].on) { XtSetArg (arg[0], XtNborderWidth, 3); XtSetArg (arg[1], XtNinternalHeight, 2); @@ -890,9 +1001,9 @@ FeatureProc (Widget w, XtPointer client_data, XtPointer call_data) XtSetArg (arg[1], XtNinternalHeight, 4); XtSetArg (arg[2], XtNinternalWidth, 4); } - OTF_tag_name (rec->features[i].tag, str); + OTF_tag_name (rec->features[idx].tag, str); XtSetArg (arg[3], XtNlabel, str); - XtSetValues (rec->features[i].w, arg, 4); + XtSetValues (rec->features[idx].w, arg, 4); } update_seq_area (); } @@ -1144,15 +1255,20 @@ create_otf_script_widgets (Widget prev) } else { + Widget box; + XtSetArg (arg[0], XtNborderWidth, 0); + XtSetArg (arg[1], XtNwidth, render_width - (FONT_WIDTH * 15)); + XtSetArg (arg[2], XtNorientation, XtorientHorizontal); + box = XtCreateManagedWidget ("scritp-list", boxWidgetClass, prev, arg, 2); XtSetArg (arg[0], XtNstate, True); - w = XtCreateManagedWidget (name, toggleWidgetClass, prev, arg, 1); + w = XtCreateManagedWidget (name, toggleWidgetClass, box, arg, 1); XtAddCallback (w, XtNcallback, ScriptProc, NULL); XtSetArg (arg[0], XtNradioGroup, w); for (i = 1; i < n; i++) { compose_script_langsys (script_langsys[i].script, script_langsys[i].langsys, name); - w = XtCreateManagedWidget (name, toggleWidgetClass, prev, arg, 1); + w = XtCreateManagedWidget (name, toggleWidgetClass, box, arg, 1); XtAddCallback (w, XtNcallback, ScriptProc, NULL); } } @@ -1245,7 +1361,7 @@ create_widgets () XtSetArg (arg2[0], XtNborderWidth, 1); for (i = 0; i < sub14->nRecords; i++) { - OTF_VariationSelectorRecord *record = sub14->Records + i;; + OTF_VariationSelectorRecord *record = sub14->Records + i; unsigned selector = record->varSelector; unsigned idx; char lbl[4]; @@ -1260,7 +1376,7 @@ create_widgets () XtSetArg (arg2[2], XtNsensitive, False); uvs[idx].w = XtCreateManagedWidget ("lbl", commandWidgetClass, uvs_area, arg2, 3); - XtAddCallback (uvs[idx].w, XtNcallback, UVSProc, (XtPointer) idx); + XtAddCallbackWithCast (unsigned, uvs[idx].w, UVSProc, idx); } XtSetArg (arg[5], XtNfromVert, uvs_area); } @@ -1291,7 +1407,7 @@ create_widgets () charmap[i + 1] = XtCreateManagedWidget (charmap_rec[i + 1].name, toggleWidgetClass, command_area, arg, 1); - XtAddCallback (charmap[i + 1], XtNcallback, CharmapProc, (XtPointer) i); + XtAddCallbackWithCast (int, charmap[i + 1], CharmapProc, i); } XtSetArg (arg[0], XtNlabel, " |< (f)"); @@ -1365,7 +1481,7 @@ create_widgets () XtSetArg (arg[n], XtNbitmap, none_pixmap), n++; glyph[k] = XtCreateManagedWidget ("glyph", commandWidgetClass, glyph_area, arg, n); - XtAddCallback (glyph[k], XtNcallback, RenderProc, (XtPointer) k); + XtAddCallbackWithCast (int, glyph[k], RenderProc, k); } w = head; } @@ -1442,6 +1558,16 @@ create_widgets () XtSetArg (arg[1], XtNbitmap, seq_pixmap); seq_image = XtCreateManagedWidget ("seq-image", labelWidgetClass, seq, arg, 2); + XtSetArg (arg[6], XtNfromVert, seq); + code = XtCreateManagedWidget ("code", boxWidgetClass, render_area, arg, 7); + XtSetArg (arg[0], XtNborderWidth, 0); + XtSetArg (arg[1], XtNlabel, "code:"); + code_label = XtCreateManagedWidget ("code-label", labelWidgetClass, + code, arg, 2); + XtSetArg (arg[1], XtNlabel, ""); + XtSetArg (arg[2], XtNwidth, render_width); + code_list = XtCreateManagedWidget ("code-list", labelWidgetClass, + code, arg, 3); XtInstallAllAccelerators (shell, shell); } @@ -1558,18 +1684,24 @@ main (int argc, char **argv) || strstr (filename, ".OTF")) { otf = OTF_open_ft_face (face); - if (! otf - || OTF_get_table (otf, "head") < 0 - || OTF_get_table (otf, "cmap") < 0 - || (OTF_check_table (otf, "GSUB") < 0 - && OTF_check_table (otf, "GPOS") < 0)) - otf = NULL; - for (i = 0; i < otf->cmap->numTables; i++) - if (otf->cmap->EncodingRecord[i].subtable.format == 14) - { - sub14 = otf->cmap->EncodingRecord[i].subtable.f.f14; - break; - } + if (otf) + { + if (OTF_get_table (otf, "head") < 0 + || OTF_get_table (otf, "cmap") < 0 + || (OTF_check_table (otf, "GSUB") < 0 + && OTF_check_table (otf, "GPOS") < 0)) + { + OTF_close (otf); + otf = NULL; + } + } + if (otf) + for (i = 0; i < otf->cmap->numTables; i++) + if (otf->cmap->EncodingRecord[i].subtable.format == 14) + { + sub14 = otf->cmap->EncodingRecord[i].subtable.f.f14; + break; + } } {