summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2013-01-19 14:52:52 +0000
committerKhaled Hosny <khaledhosny@eglug.org>2013-01-19 14:52:52 +0000
commitab86c5998dd59cb60e7d7e89dd10bebe96bceeec (patch)
tree2f685da99e3d21a07e0a330665f493d638147ea2
parent509ffbd4e19a96a5e56121efeb6ad9f6ab5a907f (diff)
Support DVI-IVD inspired text reflection for XeTeX
git-svn-id: svn://tug.org/texlive/trunk@28874 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/xdvipdfmx/ChangeLog16
-rw-r--r--Build/source/texk/xdvipdfmx/src/dvi.c241
-rw-r--r--Build/source/texk/xdvipdfmx/src/dvicodes.h1
-rw-r--r--Build/source/texk/xdvipdfmx/src/vf.c8
4 files changed, 234 insertions, 32 deletions
diff --git a/Build/source/texk/xdvipdfmx/ChangeLog b/Build/source/texk/xdvipdfmx/ChangeLog
index 821df41561d..16c61d2d6d3 100644
--- a/Build/source/texk/xdvipdfmx/ChangeLog
+++ b/Build/source/texk/xdvipdfmx/ChangeLog
@@ -1,11 +1,17 @@
+2013-01-19 Khaled Hosny <khaledhosny@eglug.org>
+
+ * src/dvi.c, src/dvicodes.h: Support DVI-IVD inspired text reflection
+ for XeTeX.
+ * src/vf.c: Adapt
+
2013-01-11 Peter Breitenlohner <peb@mppmu.mpg.de>
Reduce dvipdfmx/xdvipdfmx diffs.
- src/agl.c: Definition of hval_free() moved up.
- src/pdffont.h: Added #ifdef XETEX ... #endif.
- src/t1_load.c: Added #ifdef XETEX ... #else ... #endif.
- src/dpxconf.[ch], src/dpxcrypt.[ch]: Copied from ../dvipdfmx.
- src/sfnt.c: '#if HAVE_CONFIG_H' => '#ifdef HAVE_CONFIG_H'.
+ * src/agl.c: Definition of hval_free() moved up.
+ * src/pdffont.h: Added #ifdef XETEX ... #endif.
+ * src/t1_load.c: Added #ifdef XETEX ... #else ... #endif.
+ * src/dpxconf.[ch], src/dpxcrypt.[ch]: Copied from ../dvipdfmx.
+ * src/sfnt.c: '#if HAVE_CONFIG_H' => '#ifdef HAVE_CONFIG_H'.
2013-01-10 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
diff --git a/Build/source/texk/xdvipdfmx/src/dvi.c b/Build/source/texk/xdvipdfmx/src/dvi.c
index 84a034753dd..3b4b4608766 100644
--- a/Build/source/texk/xdvipdfmx/src/dvi.c
+++ b/Build/source/texk/xdvipdfmx/src/dvi.c
@@ -2,6 +2,8 @@
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+ Copyright (C) 2012-2013 by Khaled Hosny
+
Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
@@ -105,6 +107,25 @@ double get_origin (int x)
return x ? dev_origin_x : dev_origin_y;
}
+#ifdef XETEX
+#define LTYPESETTING 0 /* typesetting from left to right */
+#define RTYPESETTING 1 /* typesetting from right to left */
+#define SKIMMING 2 /* skimming through reflected segment measuring its width */
+#define REVERSE(MODE) (LTYPESETTING + RTYPESETTING - MODE)
+
+struct dvi_lr
+{
+ int state, font;
+ unsigned long buf_index;
+};
+
+static struct dvi_lr lr_state; /* state at start of current skimming */
+static int lr_mode; /* current direction or skimming depth */
+static SIGNED_QUAD lr_width; /* total width of reflected segment */
+static SIGNED_QUAD lr_width_stack[DVI_STACK_DEPTH_MAX];
+static unsigned lr_width_stack_depth = 0;
+#endif
+
#define PHYSICAL 1
#define VIRTUAL 2
#define SUBFONT 3
@@ -1112,8 +1133,19 @@ static void do_moveto (SIGNED_QUAD x, SIGNED_QUAD y)
dvi_state.v = y;
}
+/* FIXME: dvi_forward() might be a better name */
void dvi_right (SIGNED_QUAD x)
{
+#ifdef XETEX
+ if (lr_mode >= SKIMMING) {
+ lr_width += x;
+ return;
+ }
+
+ if (lr_mode == RTYPESETTING)
+ x = -x;
+#endif
+
if (!dvi_state.d) {
dvi_state.h += x;
} else {
@@ -1123,13 +1155,20 @@ void dvi_right (SIGNED_QUAD x)
void dvi_down (SIGNED_QUAD y)
{
- if (!dvi_state.d) {
- dvi_state.v += y;
- } else {
- dvi_state.h -= y;
+#ifdef XETEX
+ if (lr_mode < SKIMMING) {
+#endif
+ if (!dvi_state.d) {
+ dvi_state.v += y;
+ } else {
+ dvi_state.h -= y;
+ }
+#ifdef XETEX
}
+#endif
}
+#if 0
/* Please remove this.
* Optimization for 8-bit encodings.
*/
@@ -1187,6 +1226,7 @@ do_string (unsigned char *s, int len)
dvi_state.v += width;
}
}
+#endif
/* _FIXME_
* CMap decoder wants multibyte strings as input but
@@ -1215,6 +1255,16 @@ dvi_set (SIGNED_QUAD ch)
width = tfm_get_fw_width(font->tfm_id, ch);
width = sqxfw(font->size, width);
+#ifdef XETEX
+ if (lr_mode >= SKIMMING) {
+ lr_width += width;
+ return;
+ }
+
+ if (lr_mode == RTYPESETTING)
+ dvi_right(width);
+#endif
+
switch (font->type) {
case PHYSICAL:
if (ch > 255) { /* _FIXME_ */
@@ -1257,11 +1307,17 @@ dvi_set (SIGNED_QUAD ch)
break;
}
- if (!dvi_state.d) {
- dvi_state.h += width;
- } else {
- dvi_state.v += width;
+#ifdef XETEX
+ if (lr_mode == LTYPESETTING) {
+#endif
+ if (!dvi_state.d) {
+ dvi_state.h += width;
+ } else {
+ dvi_state.v += width;
+ }
+#ifdef XETEX
}
+#endif
}
void
@@ -1334,12 +1390,14 @@ dvi_put (SIGNED_QUAD ch)
void
dvi_rule (SIGNED_QUAD width, SIGNED_QUAD height)
{
- do_moveto(dvi_state.h, dvi_state.v);
+ if (width > 0 && height > 0) {
+ do_moveto(dvi_state.h, dvi_state.v);
- if (!dvi_state.d) {
- pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height);
- } else { /* right ? */
- pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width);
+ if (!dvi_state.d) {
+ pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height);
+ } else { /* right ? */
+ pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width);
+ }
}
}
@@ -1365,14 +1423,28 @@ do_set2 (void)
static void
do_setrule (void)
{
- SIGNED_QUAD width, height;
+ SIGNED_QUAD width, height;
height = get_buffered_signed_quad();
width = get_buffered_signed_quad();
- if (width > 0 && height > 0) {
+#ifdef XETEX
+ switch (lr_mode) {
+ case LTYPESETTING:
+ dvi_rule(width, height);
+ dvi_right(width);
+ break;
+ case RTYPESETTING:
+ dvi_right(width);
dvi_rule(width, height);
+ break;
+ default:
+ lr_width += width;
+ break;
}
+#else
+ dvi_rule(width, height);
dvi_right(width);
+#endif
}
static void
@@ -1382,9 +1454,22 @@ do_putrule (void)
height = get_buffered_signed_quad ();
width = get_buffered_signed_quad ();
- if (width > 0 && height > 0) {
+#ifdef XETEX
+ switch (lr_mode) {
+ case LTYPESETTING:
+ dvi_rule(width, height);
+ break;
+ case RTYPESETTING:
+ dvi_right(width);
dvi_rule(width, height);
+ dvi_right(-width);
+ break;
+ default:
+ break;
}
+#else
+ dvi_rule(width, height);
+#endif
}
static void
@@ -1790,7 +1875,10 @@ do_xxx (UNSIGNED_QUAD size)
dvi_do_special(buffer, size);
RELEASE(buffer);
#else
- dvi_do_special(dvi_page_buffer + dvi_page_buf_index, size);
+#ifdef XETEX
+ if (lr_mode < SKIMMING)
+#endif
+ dvi_do_special(dvi_page_buffer + dvi_page_buf_index, size);
dvi_page_buf_index += size;
#endif
}
@@ -1880,6 +1968,71 @@ do_dir (void)
#ifdef XETEX
static void
+lr_width_push (void)
+{
+ if (lr_width_stack_depth >= DVI_STACK_DEPTH_MAX)
+ ERROR("Segment width stack exceeded limit.");
+
+ lr_width_stack[lr_width_stack_depth++] = lr_width;
+}
+
+static void
+lr_width_pop (void)
+{
+ if (lr_width_stack_depth <= 0)
+ ERROR("Tried to pop an empty segment width stack.");
+
+ lr_width = lr_width_stack[--lr_width_stack_depth];
+}
+
+static void
+dvi_begin_reflect (void)
+{
+ if (lr_mode >= SKIMMING) {
+ ++lr_mode;
+ } else {
+ lr_state.buf_index = dvi_page_buf_index;
+ lr_state.font = current_font;
+ lr_state.state = lr_mode;
+ lr_mode = SKIMMING;
+ lr_width = 0;
+ }
+}
+
+static void
+dvi_end_reflect (void)
+{
+ switch (lr_mode) {
+ case SKIMMING:
+ current_font = lr_state.font;
+ dvi_page_buf_index = lr_state.buf_index;
+ lr_mode = REVERSE(lr_state.state); /* must precede dvi_right */
+ dvi_right(-lr_width);
+ lr_width_push();
+ break;
+ case LTYPESETTING:
+ case RTYPESETTING:
+ lr_width_pop();
+ dvi_right(-lr_width);
+ lr_mode = REVERSE(lr_mode);
+ break;
+ default: /* lr_mode > SKIMMING */
+ lr_mode--;
+ }
+}
+
+static void
+do_reflect (void)
+{
+ UNSIGNED_BYTE value;
+ value = get_buffered_unsigned_byte();
+ if (value == 0)
+ dvi_begin_reflect();
+ else
+ dvi_end_reflect();
+}
+
+static void
do_native_font_def (int scanning)
{
if (scanning) {
@@ -1916,6 +2069,19 @@ do_native_font_def (int scanning)
}
static void
+skip_glyph_array_glyphs (int yLocsPresent)
+{
+ unsigned int i, slen = 0;
+ slen = (unsigned int) get_buffered_unsigned_pair();
+ for (i = 0; i < slen; i++) {
+ get_buffered_signed_quad();
+ if (yLocsPresent)
+ get_buffered_signed_quad();
+ get_buffered_unsigned_pair();
+ }
+}
+
+static void
do_glyph_array (int yLocsPresent)
{
struct loaded_font *font;
@@ -1930,6 +2096,15 @@ do_glyph_array (int yLocsPresent)
width = get_buffered_signed_quad();
+ if (lr_mode >= SKIMMING) {
+ lr_width += width;
+ skip_glyph_array_glyphs(yLocsPresent);
+ return;
+ }
+
+ if (lr_mode == RTYPESETTING)
+ dvi_right(width);
+
slen = (unsigned int) get_buffered_unsigned_pair();
xloc = NEW(slen, spt_t);
yloc = NEW(slen, spt_t);
@@ -2000,10 +2175,12 @@ do_glyph_array (int yLocsPresent)
RELEASE(xloc);
RELEASE(yloc);
- if (!dvi_state.d) {
- dvi_state.h += width;
- } else {
- dvi_state.v += width;
+ if (lr_mode == LTYPESETTING) {
+ if (!dvi_state.d) {
+ dvi_state.h += width;
+ } else {
+ dvi_state.v += width;
+ }
}
return;
@@ -2091,6 +2268,7 @@ dvi_do_page (long n,
dvi_stack_depth = 0;
for (;;) {
+#if 0
/* The most likely opcodes are individual setchars.
* These are buffered for speed. */
slen = 0;
@@ -2103,6 +2281,13 @@ dvi_do_page (long n,
}
if (slen == SBUF_SIZE)
continue;
+#endif
+ opcode = get_buffered_unsigned_byte();
+
+ if (opcode <= SET_CHAR_127) {
+ dvi_set(opcode);
+ continue;
+ }
/* If we are here, we have an opcode that is something
* other than SET_CHAR.
@@ -2148,6 +2333,10 @@ dvi_do_page (long n,
case PUSH:
dvi_push();
+#ifdef XETEX
+ if (lr_mode >= SKIMMING)
+ lr_width_push();
+#endif
/* The following line needs to go here instead of in
* dvi_push() since logical structure of document is
* oblivous to virtual fonts. For example the last line on a
@@ -2160,6 +2349,10 @@ dvi_do_page (long n,
break;
case POP:
dvi_pop();
+#ifdef XETEX
+ if (lr_mode >= SKIMMING)
+ lr_width_pop();
+#endif
/* Above explanation holds for following line too */
dvi_mark_depth();
break;
@@ -2223,6 +2416,9 @@ dvi_do_page (long n,
#ifdef XETEX
/* XeTeX extension */
+ case XDV_REFLECT:
+ do_reflect();
+ break;
case XDV_GLYPH_STRING:
do_glyph_array(0);
break;
@@ -2743,6 +2939,9 @@ dvi_scan_specials (long page_no,
case FNT_DEF4: do_fntdef4(1); break;
#ifdef XETEX
+ case XDV_REFLECT:
+ get_and_buffer_unsigned_byte(fp);
+ break;
case XDV_GLYPH_STRING:
{
UNSIGNED_PAIR count;
diff --git a/Build/source/texk/xdvipdfmx/src/dvicodes.h b/Build/source/texk/xdvipdfmx/src/dvicodes.h
index 4de92c5bd0c..1495b420da7 100644
--- a/Build/source/texk/xdvipdfmx/src/dvicodes.h
+++ b/Build/source/texk/xdvipdfmx/src/dvicodes.h
@@ -122,6 +122,7 @@
#define DIR 255 /* Ascii pTeX DIR command */
#ifdef XETEX
+#define XDV_REFLECT 250 /* begin/end (possiply recursive) reflected segment */
#define XDV_PIC_FILE 251 /* include graphic or PDF file */
#define XDV_NATIVE_FONT_DEF 252 /* fontdef for native platform font */
#define XDV_GLYPH_ARRAY 253 /* string of glyph IDs with X and Y positions */
diff --git a/Build/source/texk/xdvipdfmx/src/vf.c b/Build/source/texk/xdvipdfmx/src/vf.c
index bfd735b8ab2..883f4114f64 100644
--- a/Build/source/texk/xdvipdfmx/src/vf.c
+++ b/Build/source/texk/xdvipdfmx/src/vf.c
@@ -460,9 +460,7 @@ static void vf_putrule(unsigned char **start, unsigned char *end, spt_t ptsize)
SIGNED_QUAD width, height;
height = signed_quad (start, end);
width = signed_quad (start, end);
- if (width > 0 && height > 0) {
- dvi_rule (sqxfw(ptsize,width), sqxfw(ptsize, height));
- }
+ dvi_rule (sqxfw(ptsize,width), sqxfw(ptsize, height));
return;
}
@@ -472,9 +470,7 @@ static void vf_setrule(unsigned char **start, unsigned char *end, spt_t ptsize)
height = signed_quad (start, end);
width = signed_quad (start, end);
s_width = sqxfw(ptsize, width);
- if (width > 0 && height > 0) {
- dvi_rule (s_width, sqxfw(ptsize, height));
- }
+ dvi_rule (s_width, sqxfw(ptsize, height));
dvi_right (s_width);
return;
}