/* 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
| | idxh[7] glyph[112] ... glyph[127]| |
| | idxl[0] ... idxl[15] | |
| +--------------------------------------+ |
+ | +--- script_area (box) ----------------+ |
+ | | script(langsys) DFLT ... | |
+ | +--------------------------------------+ |
| +---- uvs_area (box) (optional) -------+ |
| | uvs[?].w ... | |
| +--------------------------------------+ |
| | +--- seq (box) --------------------+ | |
| | | seq_label seq_image | | |
| | +----------------------------------+ | |
+ | | +--- code (box) -------------------+ | |
+ | | | code_label code_list ... | | |
+ | | +----------------------------------+ | |
| +--------------------------------------+ |
+------------------------------------------+ */
Widget shell, frame;
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
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;
}
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);
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);
}
}
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);
}
}
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)
}
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++;
}
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);
}
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);
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 ();
}
}
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);
}
}
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);
}