/* otfview.c -- View glyphs of OpenType fonts.
-Copyright (C) 2003, 2004, 2005
+Copyright (C) 2003, 2004, 2005, 2006, 2008
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO167
| | idxh[7] glyph[112] ... glyph[127]| |
| | idxl[0] ... idxl[15] | |
| +--------------------------------------+ |
+ | +---- uvs_area (box) (optional) -------+ |
+ | | uvs[?].w ... | |
+ | +--------------------------------------+ |
| +--- render_area (form) ---------------+ |
| | clear del bidi alt_subst | |
| | +--- raw (box) --------------------+ | |
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;
unsigned long foreground, background;
int advance;
} BitmapRec;
-BitmapRec bitmap[0x10000];
+BitmapRec bitmap[0x110000];
int render_width, render_height;
Pixmap raw_pixmap, seq_pixmap, gsub_pixmap, gpos_pixmap;
int codes[64];
} glyph_rec;
+OTF_EncodingSubtable14 *sub14 = NULL;
+
+struct {
+ Widget w;
+ int c;
+} uvs[256];
+
OTF *otf;
char *filename;
+int fontindex;
void
create_pixmap (int index)
if (charmap_index >= 0)
index = FT_Get_Char_Index (face, (FT_ULong) index);
- if (! index)
+ if (charmap_index >= 0 && ! index)
XtSetArg (arg[0], XtNbitmap, none_pixmap);
else
{
XtSetValues (index_label[i], arg, 2);
}
- sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
+ if (glyph_index < 0x10000)
+ sprintf (buf, " %04X-%04X ", glyph_index, glyph_index + 0x7F);
+ else
+ sprintf (buf, "%06X-%06X", glyph_index, glyph_index + 0x7F);
XtSetArg (arg[0], XtNlabel, buf);
XtSetValues (range, arg, 1);
}
+void
+update_uvs_area (int c)
+{
+ OTF_GlyphID code[256];
+ Arg arg[1];
+ int i;
+
+ OTF_get_variation_glyphs (otf, c, code);
+
+ for (i = 0; i < 256; i++)
+ if (uvs[i].w)
+ {
+ if (code[i])
+ XtSetArg (arg[0], XtNsensitive, True);
+ else
+ XtSetArg (arg[0], XtNsensitive, False);
+ XtSetValues (uvs[i].w, arg, 1);
+ }
+}
+
+
char *
get_features (OTF_FeatureList *list, FeatureRec *rec)
{
}
-#define DEVICE_DELTA(table, size) \
- (((size) >= (table).StartSize && (size) <= (table).EndSize) \
- ? (table).DeltaValue[(size) >= (table).StartSize] \
+#define DEVICE_DELTA(table, size) \
+ (((table).DeltaValue \
+ && ((size) >= (table).StartSize && (size) <= (table).EndSize)) \
+ ? (table).DeltaValue[(size) >= (table).StartSize] \
: 0)
void
gstring.glyphs = malloc (sizeof (OTF_Glyph) * len);
memset (gstring.glyphs, 0, sizeof (OTF_Glyph) * len);
for (i = 0; i < len; i++)
- gstring.glyphs[i].c = gstring.glyphs[i].glyph_id = glyph_rec.glyphs[i];
+ {
+ gstring.glyphs[i].c = glyph_rec.codes[i];
+ if (charmap_index < 0)
+ gstring.glyphs[i].glyph_id = glyph_rec.glyphs[i];
+ }
XFillRectangle (display, seq_pixmap, gc, 0, 0, render_width, render_height);
XDrawLine (display, seq_pixmap, gc_set, 0, glyph_y, render_width, glyph_y);
char *str;
OTF_drive_gdef (otf, &gstring);
+ OTF_drive_cmap (otf, &gstring);
if (otf->gsub)
{
str = get_features (&otf->gsub->FeatureList, &gsub);
str = get_features (&otf->gpos->FeatureList, &gpos);
if (str)
{
- OTF_drive_gpos (otf, &gstring, NULL, NULL, str);
+ OTF_drive_gpos2 (otf, &gstring, NULL, NULL, str);
free (str);
}
}
int prev_width;
int advance = bmp->advance;
- if (! bmp->pixmap)
+ if (gstring.glyphs[i].glyph_id && ! bmp->pixmap)
{
create_pixmap (gstring.glyphs[i].glyph_id);
if (! bmp->pixmap)
continue;
advance = bmp->advance;
}
- switch (g->positioning_type)
+ if (g->positioning_type)
{
- case 0:
- break;
-
- case 1: case 2:
- {
- int format = g->f.f1.format;
-
- if (format & OTF_XPlacement)
- 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;
- if (format & OTF_YPlaDevice)
- yoff += DEVICE_DELTA (g->f.f1.value->YPlaDevice, pixel_size);
- if (format & OTF_XAdvance)
- advance += g->f.f1.value->XAdvance * pixel_size / unitsPerEm;
- if (format & OTF_XAdvDevice)
- advance += DEVICE_DELTA (g->f.f1.value->XAdvDevice, pixel_size);
- }
- break;
+ while (1)
+ {
+ switch (g->positioning_type)
+ {
+ case 1: case 2:
+ {
+ int format = g->f.f1.format;
+
+ if (format & OTF_XPlacement)
+ 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;
+ if (format & OTF_YPlaDevice)
+ yoff += DEVICE_DELTA (g->f.f1.value->YPlaDevice, pixel_size);
+ if (format & OTF_XAdvance)
+ advance += g->f.f1.value->XAdvance * pixel_size / unitsPerEm;
+ if (format & OTF_XAdvDevice)
+ advance += DEVICE_DELTA (g->f.f1.value->XAdvDevice,
+ pixel_size);
+ }
+ break;
- case 3:
- /* Not yet supported. */
- break;
- case 4: case 5:
- if (! base)
- break;
- prev = base;
- prev_width = base_width;
- goto label_adjust_anchor;
- default: /* i.e. case 6 */
- if (! mark)
- break;
- prev = mark;
- prev_width = 0;
- label_adjust_anchor:
- {
- int base_x, base_y, mark_x, mark_y;
-
- base_x = g->f.f4.base_anchor->XCoordinate * pixel_size / unitsPerEm;
- base_y = g->f.f4.base_anchor->YCoordinate * pixel_size / unitsPerEm;
- mark_x = g->f.f4.mark_anchor->XCoordinate * pixel_size / unitsPerEm;
- mark_y = g->f.f4.mark_anchor->YCoordinate * pixel_size / unitsPerEm;
-
- if (g->f.f4.base_anchor->AnchorFormat != 1)
- adjust_anchor (g->f.f4.base_anchor, face, prev, &base_x, &base_y);
- if (g->f.f4.mark_anchor->AnchorFormat != 1)
- adjust_anchor (g->f.f4.mark_anchor, face, g, &mark_x, &mark_y);
- xoff = (base_x - prev_width) - mark_x;
- yoff = base_y - mark_y;
- }
+ case 3:
+ /* Not yet supported. */
+ break;
+ case 4: case 5:
+ if (! base)
+ break;
+ prev = base;
+ prev_width = base_width;
+ goto label_adjust_anchor;
+ default: /* i.e. case 6 */
+ if (! mark)
+ break;
+ prev = mark;
+ prev_width = 0;
+ label_adjust_anchor:
+ {
+ int base_x, base_y, mark_x, mark_y;
+
+ base_x = g->f.f4.base_anchor->XCoordinate * pixel_size / unitsPerEm;
+ base_y = g->f.f4.base_anchor->YCoordinate * pixel_size / unitsPerEm;
+ mark_x = g->f.f4.mark_anchor->XCoordinate * pixel_size / unitsPerEm;
+ mark_y = g->f.f4.mark_anchor->YCoordinate * pixel_size / unitsPerEm;
+
+ if (g->f.f4.base_anchor->AnchorFormat != 1)
+ adjust_anchor (g->f.f4.base_anchor, face, prev, &base_x, &base_y);
+ if (g->f.f4.mark_anchor->AnchorFormat != 1)
+ adjust_anchor (g->f.f4.mark_anchor, face, g, &mark_x, &mark_y);
+ xoff = (base_x - prev_width) - mark_x;
+ yoff = base_y - mark_y;
+ }
+ }
+ if (i + 1 == gstring.used
+ || gstring.glyphs[i + 1].glyph_id
+ || ! gstring.glyphs[i + 1].positioning_type)
+ break;
+ i++, g++;
+ }
}
-
+
XCopyArea (display, bmp->pixmap, seq_pixmap, gc_or,
glyph_x + bmp->x, glyph_y + bmp->y, bmp->width, bmp->height,
x + bmp->x + xoff, glyph_y + bmp->y - yoff);
XFillRectangle (display, raw_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];
- char buf[5];
-
- XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
- 0, 0, glyph_width, glyph_height,
- (glyph_width + 4) * i + 1, 1);
- XDrawRectangle (display, raw_pixmap, gc_set,
- (glyph_width + 4) * i, 0,
- glyph_width + 1, glyph_height + 1);
- XDrawLine (display, raw_pixmap, gc_set,
- (glyph_width + 4) * i + 1 + glyph_x, 1,
- (glyph_width + 4) * i + 1 + glyph_x, glyph_height + 1);
- XDrawLine (display, raw_pixmap, gc_set,
- (glyph_width + 4) * i + 1 + glyph_x + bmp->advance, 1,
- (glyph_width + 4) * i + 1 + glyph_x + bmp->advance,
- glyph_height + 1);
-
- sprintf (buf, "%04X", glyph_rec.codes[i]);
- XDrawString (display, raw_pixmap, gc_inv,
- (glyph_width + 1) * i + 1
- + (glyph_width - XTextWidth (font, buf, 4)) / 2,
- glyph_height + 2 + FONT_HEIGHT, buf, 4);
+ if (glyph_rec.glyphs[i] >= 0)
+ {
+ BitmapRec *bmp = bitmap + glyph_rec.glyphs[i];
+ char buf[5];
+
+ XCopyArea (display, bmp->pixmap, raw_pixmap, gc,
+ 0, 0, glyph_width, glyph_height,
+ (glyph_width + 4) * i + 1, 1);
+ XDrawRectangle (display, raw_pixmap, gc_set,
+ (glyph_width + 4) * i, 0,
+ glyph_width + 1, glyph_height + 1);
+ XDrawLine (display, raw_pixmap, gc_set,
+ (glyph_width + 4) * i + 1 + glyph_x, 1,
+ (glyph_width + 4) * i + 1 + glyph_x, glyph_height + 1);
+ XDrawLine (display, raw_pixmap, gc_set,
+ (glyph_width + 4) * i + 1 + glyph_x + bmp->advance, 1,
+ (glyph_width + 4) * i + 1 + glyph_x + bmp->advance,
+ glyph_height + 1);
+
+ sprintf (buf, "%04X", glyph_rec.codes[i]);
+ XDrawString (display, raw_pixmap, gc_inv,
+ (glyph_width + 4) * i + 1
+ + (glyph_width - XTextWidth (font, buf, 4)) / 2,
+ glyph_height + 2 + FONT_HEIGHT, buf, 4);
+ }
+ else
+ {
+ /* Variation Selector */
+ int idx = - glyph_rec.glyphs[i];
+ char buf[4];
+
+ sprintf (buf, "%03d", idx);
+ XDrawRectangle (display, raw_pixmap, gc_set,
+ (glyph_width + 4) * i, 0,
+ glyph_width + 1, glyph_height + 1);
+ XDrawString (display, raw_pixmap, gc_set,
+ (glyph_width + 4) * i + 1
+ + (glyph_width - XTextWidth (font, "VS", 2)) / 2,
+ 1 + glyph_height / 2, "VS", 2);
+ XDrawString (display, raw_pixmap, gc_set,
+ (glyph_width + 4) * i + 1
+ + (glyph_width - XTextWidth (font, buf, 3)) / 2,
+ 1 + glyph_height / 2 + FONT_ASCENT, buf, 3);
+ }
}
XtSetArg (arg[0], XtNbitmap, raw_pixmap);
XtSetValues (raw_image, arg, 1);
void
DumpProc (Widget w, XtPointer client_data, XtPointer call_data)
{
- int g_width, g_height, g_x, g_y, pix_width, pix_height;
- int margin = 20 * 300 / 25.4;
- int a4_width = 210 * 300 / 25.4 - margin * 2;
- int a4_height = 297 * 300 / 25.4 - margin * 2;
- int size = 100;
- Pixmap pixmap;
- XImage ximage, *image;
- int i, x, y;
- char *data;
- int bytes_per_line;
-
- FT_Set_Pixel_Sizes (face, 0, size);
- g_width = ((face->bbox.xMax - face->bbox.xMin) * size / face->units_per_EM);
- g_height = ((face->bbox.yMax - face->bbox.yMin) * size / face->units_per_EM);
- pix_width = (g_width + 1) * 16 + margin + 1;
- pix_height = (g_height + 1 + FONT_HEIGHT) * 16 + margin + 1;
- while (pix_width > a4_width || pix_height > a4_height)
+ int g_width, g_height;
+ float g_x, g_y;
+ /* unit in points (1/72 inch); to fit in both US-letter and A4 */
+ static int xoff = 30, yoff = 30;
+ static int unit = 30;
+ static int margin = 2;
+ static int title_height = 20, label_height = 10;
+ int total_width = (unit + margin * 2) * 16;
+ int total_height = (unit + margin * 2 + label_height) * 16 + title_height;
+ /* pixel size (dots) */
+ int size = 128;
+ int i, j, k, l;
+ char *name = alloca (strlen (filename) + 10);
+ FILE *fp;
+ int index = (glyph_index / 0x100) * 0x100;
+ float scale;
+
+ g_width = face->bbox.xMax - face->bbox.xMin;
+ g_height = face->bbox.yMax - face->bbox.yMin;
+ if (g_width > g_height)
{
- size--;
- FT_Set_Pixel_Sizes (face, 0, size);
- g_width = ((face->bbox.xMax - face->bbox.xMin)
- * size / face->units_per_EM);
- g_height = ((face->bbox.yMax - face->bbox.yMin)
- * size / face->units_per_EM);
- pix_width = (g_width + 1) * 16 + margin + 1;
- pix_height = (g_height + 1 + FONT_HEIGHT) * 16 + margin + 1;
+ scale = g_width * size;
+ g_x = face->bbox.xMin * unit / g_width;
+ g_y = face->bbox.yMin * unit / g_width;
}
-
- g_x = - (face->bbox.xMin * size / face->units_per_EM);
- g_y = face->bbox.yMax * size / face->units_per_EM;
- for (i = 0; i < 0xFF; i++)
+ else
{
- int idx;
-
- if (charmap_index >= 0)
- idx = FT_Get_Char_Index (face, (FT_ULong) i);
- else
- idx = i;
- if (FT_Load_Glyph (face, idx, FT_LOAD_RENDER | FT_LOAD_MONOCHROME) == 0)
- {
- if (g_x < - face->glyph->bitmap_left)
- g_x = - face->glyph->bitmap_left;
- if (g_y < face->glyph->bitmap_top)
- g_y = face->glyph->bitmap_top;
- if (g_width
- < g_x + face->glyph->bitmap_left + face->glyph->bitmap.width)
- g_width
- = g_x + face->glyph->bitmap_left + face->glyph->bitmap.width;
- if (g_height
- < g_y - face->glyph->bitmap_top + face->glyph->bitmap.rows)
- g_height
- = g_y - face->glyph->bitmap_top + face->glyph->bitmap.rows;
- }
+ scale = g_height * size;
+ g_x = face->bbox.xMin * unit / g_height;
+ g_y = face->bbox.yMin * unit / g_height;
}
- pix_width = (g_width + 1) * 16 + margin + 1;
- pix_height = (g_height + FONT_HEIGHT + 1) * 16 + margin + 1;
- pixmap = XCreatePixmap (display,
- RootWindow (display, DefaultScreen (display)),
- pix_width, pix_height, 1);
- XFillRectangle (display, pixmap, gc, 0, 0, pix_width, pix_height);
-
- for (i = 0, x = margin; i <= 16; i++, x += g_width + 1)
- XDrawLine (display, pixmap, gc_set, x, margin,
- x, margin + (g_height + FONT_HEIGHT + 1) * 16);
- for (i = 0, y = margin; i <= 16; i++, y += g_height + FONT_HEIGHT + 1)
- XDrawLine (display, pixmap, gc_set, margin, y,
- margin + (g_width + 1) * 16, y);
- for (i = 0; i < 256; i++)
- {
- char str[5];
- int idx;
+ scale /= face->units_per_EM;
- if (charmap_index >= 0)
- idx = FT_Get_Char_Index (face, (FT_ULong) i);
- else
- idx = i;
- x = margin + (g_width + 1) * (i % 16);
- y = margin + (g_height + FONT_HEIGHT + 1) * (i / 16);
- if (FT_Load_Glyph (face, idx, FT_LOAD_RENDER | FT_LOAD_MONOCHROME) == 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);
- XPutImage (display, pixmap, gc, &ximage, 0, 0,
- x + g_x + face->glyph->bitmap_left,
- y + g_y - face->glyph->bitmap_top,
- ximage.width, ximage.height);
- }
- sprintf (str, "0x%02X", i);
- XDrawString (display, pixmap, gc_inv,
- x + (g_width - XTextWidth (font, str, 4))/ 2,
- y + g_height + FONT_ASCENT, str, 4);
- }
+ FT_Set_Pixel_Sizes (face, 0, size);
+
+ sprintf (name, "%s-%04X.ps", face->family_name, index);
+ printf ("Writing %s ... ", name);
+ fflush (stdout);
+ fp = fopen (name, "w");
+
+ fprintf (fp, "%s\n", "%!PS-Adobe-2.0 EPSF-2.0");
+ fprintf (fp, "%s\n", "%%Creater: otfview");
+ fprintf (fp, "%s %s(%s)-%04X\n", "%%Title:",
+ face->family_name, face->style_name, index);
+ fprintf (fp, "%s\n", "%%Pages: 1");
+ fprintf (fp, "%s %d %d %d %d\n", "%%BoundingBox:",
+ xoff, yoff, xoff + total_width, yoff + total_height);
+ fprintf (fp, "%s\n", "%%EndComments");
+ fprintf (fp, "%s\n", "%%BeginProlog");
+ fprintf (fp, "/W %d def\n", unit + margin * 2);
+ fprintf (fp, "/H %d def\n", unit + margin * 2 + label_height);
+ fprintf (fp, "/STR 10 string def\n");
+ fprintf (fp, "/DrawIndex {\n");
+ fprintf (fp, " I 16 lt { (000) show } { I 256 lt { (00) show } { I 4096 lt { (0) show} if } ifelse } ifelse I 16 STR cvrs show\n");
+ fprintf (fp, "} def\n");
+ fprintf (fp, "/DrawTitle {\n");
+ fprintf (fp, " /Courier findfont 20 scalefont setfont\n");
+ fprintf (fp, " %d %d 4 add moveto\n", xoff + total_width / 2,
+ yoff + total_height - title_height + 2);
+ fprintf (fp, " (%s(%s)-%04X) dup stringwidth pop 2 div neg 0 rmoveto show\n",
+ face->family_name, face->style_name, index);
+ fprintf (fp, "} def\n");
+ fprintf (fp, "/DrawFrame { gsave %d %d translate 0 setlinewidth\n",
+ xoff, yoff);
+ fprintf (fp, " /Courier findfont 10 scalefont setfont\n");
+ fprintf (fp, " /I %d def\n", index);
+ fprintf (fp, " 0 1 16 { W mul 0 moveto 0 H 16 mul rlineto stroke } for\n");
+ fprintf (fp, " 0 1 16 { H mul 0 exch moveto W 16 mul 0 rlineto stroke } for\n");
+ fprintf (fp, " 0 1 15 { H mul %d add 0 exch moveto W 16 mul 0 rlineto stroke } for\n", label_height);
+ fprintf (fp, " 15 -1 0 { gsave H mul 0 exch translate 0 0 moveto\n");
+ fprintf (fp, " 0 1 15 { gsave W mul 0 moveto\n");
+ fprintf (fp, " 4 2 rmoveto DrawIndex /I I 1 add def grestore} for\n");
+ fprintf (fp, " grestore } for grestore } def\n");
+ fprintf (fp, "%s\n", "%%EndProlog");
+ fprintf (fp, "DrawTitle DrawFrame\n");
+
+ for (i = 0; i < 16; i++)
+ for (j = 0; j < 16; j++, index++)
+ {
+ int idx;
+
+ if (charmap_index >= 0)
+ idx = FT_Get_Char_Index (face, (FT_ULong) index);
+ else
+ idx = index;
+ if (idx > 0
+ && FT_Load_Glyph (face, idx, FT_LOAD_RENDER | FT_LOAD_MONOCHROME) == 0
+ && face->glyph->bitmap.rows > 0
+ && face->glyph->bitmap.width > 0)
+ {
+ unsigned char *p = face->glyph->bitmap.buffer;
+ int width = (face->glyph->bitmap.width - 1) / 8 + 1;
+
+ fprintf (fp, "gsave %f %f translate %d %d scale 0 0 moveto\n",
+ xoff + (unit + margin * 2) * j + margin - g_x,
+ yoff + (unit + label_height + margin * 2) * (15 - i) + label_height + margin - g_y,
+ unit, unit);
+ fprintf (fp, "%d %d true [%f 0 0 %f %d %d]\n",
+ width * 8, face->glyph->bitmap.rows,
+ scale, -scale, -face->glyph->bitmap_left,
+ face->glyph->bitmap_top);
+ fprintf (fp, "{< ");
+ for (k = 0; k < face->glyph->bitmap.rows;
+ k++, p += face->glyph->bitmap.pitch)
+ {
+ for (l = 0; l < width; l++)
+ fprintf (fp, "%02X", p[l]);
+ fprintf (fp, "\n");
+ }
+ fprintf (fp, ">} imagemask grestore\n");
+ }
+ else
+ {
+ int boxsize = unit + margin * 2;
+
+ fprintf (fp, "gsave 0 setlinewidth %d %d translate\n",
+ xoff + boxsize * j,
+ yoff + (boxsize + label_height) * (15 - i) + label_height);
+ fprintf (fp, "0 0 moveto %d %d lineto stroke\n",
+ boxsize, boxsize);
+ fprintf (fp, "0 %d moveto %d 0 lineto stroke grestore\n",
+ boxsize, boxsize);
+ }
+ }
+ fprintf (fp, "showpage\n");
+ fclose (fp);
+ printf ("done\n");
- image = XGetImage (display, pixmap, 0, 0, pix_width, pix_height,
- AllPlanes, XYPixmap);
- XInitImage (image);
- {
- char *name = alloca (strlen (filename) + 5);
- FILE *fp;
-
- sprintf (name, "%s.pbm", filename);
- printf ("Writing %s ...", name);
- fp = fopen (name, "w");
- fprintf (fp, "P4\n%d %d\n", image->width, image->height);
- bytes_per_line = (image->width + 7) / 8;
- data = image->data;
- for (y = 0; y < image->height; y++, data += image->bytes_per_line)
- fwrite (data, 1, bytes_per_line, fp);
- fclose (fp);
- printf ("done\n");
- }
FT_Set_Pixel_Sizes (face, 0, (int) pixel_size);
}
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;
+ glyph_index = (glyph_index - 1) & 0x1FF000;
else if ((int) client_data == -1 && glyph_index > 0)
glyph_index -= 0x80;
- else if ((int) client_data == 1 && glyph_index < 0xFF80)
+ else if ((int) client_data == 1 && glyph_index < 0x10FF80)
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;
+ else if ((int) client_data == 2 && glyph_index < 0x10F000)
+ glyph_index = (glyph_index + 0x1000) & 0x1FF000;
+ else if ((int) client_data == 3 && glyph_index < 0x10F000)
+ glyph_index = 0x10FF80;
if (glyph_index != old_glyph_index)
update_glyph_area ();
}
}
void
+UVSProc (Widget w, XtPointer client_data, XtPointer call_data)
+{
+ unsigned idx = (unsigned) client_data;
+ int selector = uvs[idx].c;
+ OTF_VariationSelectorRecord *record;
+ int i;
+
+ if (glyph_rec.n_glyphs >= 64)
+ return;
+ for (i = 0; i < sub14->nRecords; i++)
+ {
+ record = sub14->Records + i;
+ if (record->varSelector == selector)
+ break;
+ }
+ if (i < sub14->nRecords)
+ {
+ if (glyph_rec.n_glyphs > 0
+ && glyph_rec.glyphs[glyph_rec.n_glyphs - 1] < 0)
+ glyph_rec.n_glyphs--;
+ glyph_rec.codes[glyph_rec.n_glyphs] = selector;
+ glyph_rec.glyphs[glyph_rec.n_glyphs++] = - idx - 1;
+ update_render_area ();
+ }
+}
+
+void
RenderProc (Widget w, XtPointer client_data, XtPointer call_data)
{
if ((int) client_data < 0)
{
glyph_rec.codes[glyph_rec.n_glyphs] = glyph_index + (int) client_data;
glyph_rec.glyphs[glyph_rec.n_glyphs++] = index;
+ if (otf)
+ update_uvs_area (glyph_index + (int) client_data);
update_render_area ();
}
}
n += otf->gsub->ScriptList.Script[i].LangSysCount + 1;
if (otf->gpos)
for (i = 0; i < otf->gpos->ScriptList.ScriptCount; i++)
- n += otf->gsub->ScriptList.Script[i].LangSysCount + 1;
+ n += otf->gpos->ScriptList.Script[i].LangSysCount + 1;
script_langsys = alloca ((sizeof script_langsys[0]) * n);
n = 0;
nfeatures = 0;
script_langsys[n].script = tag;
script_langsys[n++].langsys = 0;
}
- for (j = 0; j < otf->gsub->ScriptList.Script[i].LangSysCount; j++)
+ for (j = 0; j < otf->gpos->ScriptList.Script[i].LangSysCount; j++)
{
int l;
if (k < prev_n)
{
- OTF_Script *script = otf->gsub->ScriptList.Script + i;
+ OTF_Script *script = otf->gpos->ScriptList.Script + i;
for (l = k; l < prev_n && tag == script_langsys[l].script; l++)
if (script->LangSysRecord[j].LangSysTag
XtSetArg (arg[6], XtNdefaultDistance, 0);
glyph_area = XtCreateManagedWidget ("glyph-area", formWidgetClass,
frame, arg, 7);
+
XtSetArg (arg[5], XtNfromVert, glyph_area);
+ if (sub14)
+ {
+ Arg arg2[3];
+
+ XtSetArg (arg[6], XtNorientation, XtorientHorizontal);
+ uvs_area = XtCreateManagedWidget ("uvs-area", boxWidgetClass,
+ frame, arg, 7);
+ XtSetArg (arg2[0], XtNborderWidth, 0);
+ XtSetArg (arg2[1], XtNlabel, "Variation Selector: ");
+ uvs_label = XtCreateManagedWidget ("uvs-label", labelWidgetClass,
+ uvs_area, arg2, 2);
+ XtSetArg (arg2[0], XtNborderWidth, 1);
+ for (i = 0; i < sub14->nRecords; i++)
+ {
+ OTF_VariationSelectorRecord *record = sub14->Records + i;;
+ unsigned selector = record->varSelector;
+ unsigned idx;
+ char lbl[4];
+
+ idx = (selector <= 0xFE0F ? selector - 0xFE00
+ : selector - 0xE0100 + 16);
+ if (uvs[idx].c)
+ continue;
+ uvs[idx].c = selector;
+ sprintf (lbl, "%03d", idx + 1);
+ XtSetArg (arg2[1], XtNlabel, lbl);
+ XtSetArg (arg2[2], XtNsensitive, False);
+ uvs[idx].w = XtCreateManagedWidget ("lbl", commandWidgetClass,
+ uvs_area, arg2, 3);
+ XtAddCallback (uvs[idx].w, XtNcallback, UVSProc, (XtPointer) idx);
+ }
+ XtSetArg (arg[5], XtNfromVert, uvs_area);
+ }
render_area = XtCreateManagedWidget ("render-area", formWidgetClass,
frame, arg, 6);
command_area, arg, 1);
XtAddCallback (quit, XtNcallback, QuitProc, NULL);
- dump = XtCreateManagedWidget ("Dump Image", commandWidgetClass,
+ dump = XtCreateManagedWidget ("DumpImage", commandWidgetClass,
command_area, arg, 1);
XtAddCallback (dump, XtNcallback, DumpProc, NULL);
return 0;
}
+void
+help (char **argv, int err)
+{
+ FILE *fp = err ? stderr : stdout;
+
+ fprintf (fp, "Usage: %s [ X-OPTION ... ] OTF-FILE [INDEX]\n",
+ basename (argv[0]));
+ fprintf (fp, " Environment variable PIXEL_SIZE specifies the pixel size.\n");
+ fprintf (fp, " The default pixel size is %d, but is reduced\n",
+ DEFAULT_PIXEL_SIZE);
+ fprintf (fp, " if your screen is not that wide.\n");
+ exit (err);
+}
int
main (int argc, char **argv)
if (! font)
font = XLoadQueryFont (display, "fixed");
- if (argc != 2 || !strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
+ if (argc < 2)
+ help (argv, 1);
+ if (!strcmp (argv[1], "-h") || !strcmp (argv[1], "--help"))
+ help (argv, 0);
+ filename = argv[1];
+ if (argc > 2)
{
- fprintf (stderr, "Usage: %s [ X-OPTION ... ] OTF-FILE\n",
- basename (argv[0]));
- fprintf (stderr,
- " Pixel size is decided by the environment variable PIXEL_SIZE ((default %d).\n", DEFAULT_PIXEL_SIZE);
- exit (argc != 2);
+ fontindex = atoi (argv[2]);
+ if (fontindex < 0)
+ FATAL_ERROR ("Invalid font index: %d\n", fontindex);
}
- filename = argv[1];
+
+ if ((err = FT_Init_FreeType (&library)))
+ FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
+ err = FT_New_Face (library, filename, fontindex, &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 (invalid face index?)");
+ if ((err = FT_Set_Pixel_Sizes (face, 0, pixel_size)))
+ FATAL_ERROR ("%s\n", "FT_Set_Pixel_Sizes: error");
+
if (strstr (filename, ".ttf")
|| strstr (filename, ".TTF")
|| strstr (filename, ".otf")
|| strstr (filename, ".OTF"))
{
- otf = OTF_open (filename);
+ 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;
+ else
+ 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 ((err = FT_Init_FreeType (&library)))
- FATAL_ERROR ("%s\n", "FT_Init_FreeType: error");
- err = FT_New_Face (library, filename, 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_Pixel_Sizes: error");
-
{
char title[256];
Arg arg[1];
XGCValues values;
gc = XCreateGC (display, none_pixmap, (unsigned long) 0, NULL);
+ XSetFont (display, gc, font->fid);
values.function = GXset;
values.line_width = 1;
gc_set = XCreateGC (display, none_pixmap, valuemask, &values);
+ XSetFont (display, gc_set, font->fid);
values.function = GXor;
gc_or = XCreateGC (display, none_pixmap, valuemask, &values);
values.function = GXcopyInverted;