diff options
-rw-r--r-- | Build/source/texk/dvipdfm-x/ChangeLog | 6 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/dvi.c | 266 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/dvicodes.h | 1 | ||||
-rw-r--r-- | Build/source/texk/dvipdfm-x/vf.c | 8 |
4 files changed, 243 insertions, 38 deletions
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index dcb1458091d..cca422e00d7 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,9 @@ +2014-07-22 Khaled Hosny <khaledhosny@eglug.org> + + * src/dvi.c, src/dvicodes.h: Support DVI-IVD inspired text reflection + for XeTeX. + * src/vf.c: Adapt + 2014-07-22 Karl Berry <karl@tug.org> * Makefile.am (check-libutil-source-list): new target for manual diff --git a/Build/source/texk/dvipdfm-x/dvi.c b/Build/source/texk/dvipdfm-x/dvi.c index 4b2aa6ff8ad..edd61d3ad8f 100644 --- a/Build/source/texk/dvipdfm-x/dvi.c +++ b/Build/source/texk/dvipdfm-x/dvi.c @@ -2,6 +2,8 @@ Copyright (C) 2002-2014 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. + + Copyright (C) 2012-2014 by Khaled Hosny <khaledhosny@eglug.org> Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> @@ -104,6 +106,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 @@ -1074,8 +1095,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 + switch (dvi_state.d) { case 0: dvi_state.h += x; break; @@ -1088,16 +1120,23 @@ void dvi_right (SIGNED_QUAD x) void dvi_down (SIGNED_QUAD y) { - switch (dvi_state.d) { - case 0: - dvi_state.v += y; break; - case 1: - dvi_state.h -= y; break; - case 3: - dvi_state.h += y; break; +#ifdef XETEX + if (lr_mode < SKIMMING) { +#endif + switch (dvi_state.d) { + case 0: + dvi_state.v += y; break; + case 1: + dvi_state.h -= y; break; + case 3: + dvi_state.h += y; break; + } +#ifdef XETEX } +#endif } +#if 0 /* Please remove this. * Optimization for 8-bit encodings. */ @@ -1158,6 +1197,7 @@ do_string (unsigned char *s, int len) dvi_state.v -= width; break; } } +#endif /* _FIXME_ * CMap decoder wants multibyte strings as input but @@ -1186,6 +1226,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 (!is_xetex && ch > 65535) { /* _FIXME_ */ @@ -1234,14 +1284,20 @@ dvi_set (SIGNED_QUAD ch) vf_set_char(ch, font->font_id); /* push/pop invoked */ break; } - switch (dvi_state.d) { - case 0: - dvi_state.h += width; break; - case 1: - dvi_state.v += width; break; - case 3: - dvi_state.v -= width; break; +#ifdef XETEX + if (lr_mode == LTYPESETTING) { +#endif + switch (dvi_state.d) { + case 0: + dvi_state.h += width; break; + case 1: + dvi_state.v += width; break; + case 3: + dvi_state.v -= width; break; + } +#ifdef XETEX } +#endif } void @@ -1321,18 +1377,20 @@ 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); - switch (dvi_state.d) { - case 0: - pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height); - break; - case 1: - pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width); - break; - case 3: - pdf_dev_set_rule(dvi_state.h - height, -dvi_state.v , height, width); - break; + switch (dvi_state.d) { + case 0: + pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height); + break; + case 1: + pdf_dev_set_rule(dvi_state.h, -dvi_state.v - width, height, width); + break; + case 3: + pdf_dev_set_rule(dvi_state.h - height, -dvi_state.v , height, width); + break; + } } } @@ -1370,10 +1428,24 @@ do_setrule (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); + 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 @@ -1383,9 +1455,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 @@ -1759,7 +1844,10 @@ do_fnt4 (void) static void do_xxx (UNSIGNED_QUAD size) { - 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; } @@ -1848,6 +1936,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) { @@ -1879,6 +2032,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; @@ -1893,6 +2059,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); @@ -1947,10 +2122,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; @@ -2025,8 +2202,10 @@ dvi_do_page (long n, double hmargin, double vmargin) { unsigned char opcode; +#if 0 unsigned char sbuf[SBUF_SIZE]; unsigned int slen = 0; +#endif /* before this is called, we have scanned the page for papersize specials and the complete DVI data is now in dvi_page_buffer */ @@ -2038,6 +2217,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; @@ -2050,6 +2230,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. @@ -2096,6 +2283,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 @@ -2108,6 +2299,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; @@ -2171,6 +2366,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; @@ -2674,6 +2872,10 @@ 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/dvipdfm-x/dvicodes.h b/Build/source/texk/dvipdfm-x/dvicodes.h index 0fa83e30120..885479bb83a 100644 --- a/Build/source/texk/dvipdfm-x/dvicodes.h +++ b/Build/source/texk/dvipdfm-x/dvicodes.h @@ -118,6 +118,7 @@ #define PTEXDIR 255 /* Ascii pTeX DIR command */ /* XeTeX ".xdv" codes */ +#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/dvipdfm-x/vf.c b/Build/source/texk/dvipdfm-x/vf.c index 4db994c9b41..4787777c782 100644 --- a/Build/source/texk/dvipdfm-x/vf.c +++ b/Build/source/texk/dvipdfm-x/vf.c @@ -465,9 +465,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; } @@ -477,9 +475,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; } |