diff options
Diffstat (limited to 'print/tex-xdvik/files/patch-texk-xdvik-dvi-draw.c')
-rw-r--r-- | print/tex-xdvik/files/patch-texk-xdvik-dvi-draw.c | 1143 |
1 files changed, 1143 insertions, 0 deletions
diff --git a/print/tex-xdvik/files/patch-texk-xdvik-dvi-draw.c b/print/tex-xdvik/files/patch-texk-xdvik-dvi-draw.c new file mode 100644 index 000000000000..5ed34b640897 --- /dev/null +++ b/print/tex-xdvik/files/patch-texk-xdvik-dvi-draw.c @@ -0,0 +1,1143 @@ +--- texk/xdvik/dvi-draw.c.orig 2022-02-13 02:57:24 UTC ++++ texk/xdvik/dvi-draw.c +@@ -56,6 +56,9 @@ in xdvi.c. + #include "statusline.h" + #include "hypertex.h" + #include "special.h" ++#ifdef PTEX ++#include "ptexmap.h" ++#endif + #include "my-snprintf.h" + #include "kpathsea/tex-file.h" + #include "mag.h" +@@ -531,8 +534,8 @@ print_char(ubyte ch, struct glyph *g) + } + + static const char *dvi_table1[] = { +- "SET1", "SET2", NULL, NULL, "SETRULE", "PUT1", "PUT2", NULL, +- NULL, "PUTRULE", "NOP", "BOP", "EOP", "PUSH", "POP", "RIGHT1", ++ "SET1", "SET2", "SET3", "SET4", "SETRULE", "PUT1", "PUT2", "PUT3", ++ "PUT4", "PUTRULE", "NOP", "BOP", "EOP", "PUSH", "POP", "RIGHT1", + "RIGHT2", "RIGHT3", "RIGHT4", "W0", "W1", "W2", "W3", "W4", + "X0", "X1", "X2", "X3", "X4", "DOWN1", "DOWN2", "DOWN3", + "DOWN4", "Y0", "Y1", "Y2", "Y3", "Y4", "Z0", "Z1", +@@ -542,7 +545,12 @@ static const char *dvi_table1[] = { + static const char *dvi_table2[] = { + "FNT1", "FNT2", "FNT3", "FNT4", "XXX1", "XXX2", "XXX3", "XXX4", + "FNTDEF1", "FNTDEF2", "FNTDEF3", "FNTDEF4", "PRE", "POST", "POSTPOST", +- "SREFL", "EREFL", NULL, NULL, NULL, NULL ++ "SREFL", "EREFL", NULL, NULL, NULL, ++#ifdef PTEX ++ "DIRECTION" ++#else /* !PTEX */ ++ NULL ++#endif /* !PTEX */ + }; + + static void +@@ -667,6 +675,146 @@ sample(bmUnitT *bits, int bytes_wide, int bit_skip, in + return n; + } + ++extern double bbox_matrix[2][2]; ++extern Boolean bbox_scaled, bbox_rotated; ++ ++static void moveH(int dir, long dx) ++{ ++ int pint=TATE; ++ if (pint&2) { pint&=1; dx=-dx;} ++ if (pint) { ++ DVI_H -= dx * bbox_matrix[1][0]; ++ DVI_V += dx * bbox_matrix[0][0]; ++ } else { ++ DVI_H += dir * dx * bbox_matrix[0][0]; ++ DVI_V += dir * dx * bbox_matrix[1][0]; ++ } ++ PXL_V = pixel_conv(DVI_V); ++} ++ ++static void moveV(int dir, long dy) ++{ ++ int pint=TATE; ++ if (pint&2) { pint&=1; dy=-dy;} ++ if (pint) { ++ DVI_H -= dy * bbox_matrix[1][1]; ++ DVI_V += dy * bbox_matrix[0][1]; ++ } else { ++ DVI_H += dir * dy * bbox_matrix[0][1]; ++ DVI_V += dir * dy * bbox_matrix[1][1]; ++ } ++ PXL_V = pixel_conv(DVI_V); ++} ++ ++#define PUSH_POSITION do { \ ++ dvi_h_sav = DVI_H; \ ++ dvi_v_sav = DVI_V; \ ++ pxl_v_sav = PXL_V; } while (0) ++#define POP_POSITION do { \ ++ DVI_H = dvi_h_sav; \ ++ DVI_V = dvi_v_sav; \ ++ PXL_V = pxl_v_sav; } while (0) ++#define DEFINE_POSITION_VAL \ ++ long dvi_h_sav, dvi_v_sav, pxl_v_sav ++ ++#ifndef WORDS_BIGENDIAN ++#define EXTREME_LEFT_BIT (1 << 0) ++#define EXTREME_RIGHT_BIT ((bmUnitT)(1 << (BMBITS-1))) ++#define SHIFT_RIGHT(a) ((a) <<= 1) ++#else /* WORDS_BIGENDIAN */ ++#define EXTREME_LEFT_BIT ((bmUnitT)(1 << (BMBITS-1))) ++#define EXTREME_RIGHT_BIT (1 << 0) ++#define SHIFT_RIGHT(a) ((a) >>= 1) ++#endif /* WORDS_BIGENDIAN */ ++ ++static void ++bbox_scale_bitmap(struct glyph *g) ++{ ++ bmUnitT *new_ptr; ++ int xmax, ymax, xmin, ymin, x, y; ++ double d; ++ ++ if (g->bitmap3.bits) { ++ if (g->matrix[0][0] == (float) bbox_matrix[0][0] ++ && g->matrix[0][1] == (float) bbox_matrix[0][1] ++ && g->matrix[1][0] == (float) bbox_matrix[1][0] ++ && g->matrix[1][1] == (float) bbox_matrix[1][1]) ++ return; ++ else ++ free(g->bitmap.bits); ++ } else { ++ g->bitmap3 = g->bitmap; ++ g->x3 = g->x; ++ g->y3 = g->y; ++ } ++ ++ xmax = ymax = xmin = ymin = 0; ++ x = g->bitmap3.w * bbox_matrix[0][0]; ++ y = g->bitmap3.w * bbox_matrix[1][0]; ++ if (xmax < x) xmax = x; ++ else if (xmin > x) xmin = x; ++ if (ymax < y) ymax = y; ++ else if (ymin > y) ymin = y; ++ x = g->bitmap3.w * bbox_matrix[0][0] + g->bitmap3.h * bbox_matrix[0][1]; ++ y = g->bitmap3.w * bbox_matrix[1][0] + g->bitmap3.h * bbox_matrix[1][1]; ++ if (xmax < x) xmax = x; ++ else if (xmin > x) xmin = x; ++ if (ymax < y) ymax = y; ++ else if (ymin > y) ymin = y; ++ x = g->bitmap3.h * bbox_matrix[0][1]; ++ y = g->bitmap3.h * bbox_matrix[1][1]; ++ if (xmax < x) xmax = x; ++ else if (xmin > x) xmin = x; ++ if (ymax < y) ymax = y; ++ else if (ymin > y) ymin = y; ++ xmin--; ymin--; xmax++; ymax++; ++ ++ d = bbox_matrix[0][0] * bbox_matrix[1][1] ++ - bbox_matrix[0][1] * bbox_matrix[1][0]; ++ ++ g->x = g->x3 * bbox_matrix[0][0] + g->y3 * bbox_matrix[0][1] - xmin; ++ g->y = g->x3 * bbox_matrix[1][0] + g->y3 * bbox_matrix[1][1] - ymin; ++ g->matrix[0][0] = (float) bbox_matrix[0][0]; ++ g->matrix[0][1] = (float) bbox_matrix[0][1]; ++ g->matrix[1][0] = (float) bbox_matrix[1][0]; ++ g->matrix[1][1] = (float) bbox_matrix[1][1]; ++ ++ free_bitmap2(g); ++ g->bitmap.w = xmax - xmin + 1; ++ g->bitmap.h = ymax - ymin + 1; ++ alloc_bitmap(&g->bitmap); ++ clear_bitmap(&g->bitmap); ++ ++ new_ptr = (bmUnitT *) g->bitmap.bits; ++ for (y = ymin; y <= ymax; y++) { ++ register bmUnitT m, *cp; ++ ++ cp = new_ptr; ++ m = EXTREME_LEFT_BIT; ++ for (x = xmin; x <= xmax; x++) { ++ int bx, by; ++ bx = (x * bbox_matrix[1][1] - y * bbox_matrix[0][1]) / d; ++ by = (y * bbox_matrix[0][0] - x * bbox_matrix[1][0]) / d; ++ if (bx >= 0 && bx < g->bitmap3.w ++ && by >= 0 && by < g->bitmap3.h ++ && *((bmUnitT *)g->bitmap3.bits ++ + by * (g->bitmap3.bytes_wide / BMBYTES) + bx / BMBITS) ++#ifndef WORDS_BIGENDIAN ++ & (1 << (bx % BMBITS))) ++#else ++ & (1 << (BMBITS - 1 - bx % BMBITS))) ++#endif ++ *cp |= m; ++ if (m == EXTREME_RIGHT_BIT) { ++ m = EXTREME_LEFT_BIT; ++ ++cp; ++ } ++ else SHIFT_RIGHT(m); ++ } ++ new_ptr = ADD(new_ptr, g->bitmap.bytes_wide); ++ } ++} ++ + static void + shrink_glyph(struct glyph *g) + { +@@ -757,6 +905,89 @@ shrink_glyph(struct glyph *g) + print_bitmap(&g->bitmap2); + } + ++#ifdef PTEX ++void ++rotate_bitmap(struct bitmap *bm) ++{ ++ struct bitmap new_bm; ++ bmUnitT *old_ptr, *new_ptr, *cp; ++ int x, y; ++ bmUnitT m1, m2; ++ ++ new_bm.h = bm->w; ++ new_bm.w = bm->h; ++ alloc_bitmap(&new_bm); ++ clear_bitmap(&new_bm); ++ old_ptr = ADD(bm->bits, bm->bytes_wide * bm->h); ++ new_ptr = (bmUnitT *)new_bm.bits; ++ ++ m1 = EXTREME_LEFT_BIT; ++ for (y = 0; y < bm->h; y++) { ++ old_ptr = SUB(old_ptr, bm->bytes_wide); ++ cp = old_ptr; ++ m2 = EXTREME_LEFT_BIT; ++ for (x = 0; x < bm->w; x++) { ++ if (*cp & m2) ++ *ADD(new_ptr, x*new_bm.bytes_wide) |= m1; ++ if (m2 == EXTREME_RIGHT_BIT) { ++ m2 = EXTREME_LEFT_BIT; ++ ++cp; ++ } ++ else SHIFT_RIGHT(m2); ++ } ++ if (m1 == EXTREME_RIGHT_BIT) { ++ m1 = EXTREME_LEFT_BIT; ++ ++new_ptr; ++ } ++ else SHIFT_RIGHT(m1); ++ } ++ ++ free(bm->bits); ++ *bm = new_bm; ++} ++ ++ ++void ++reverse_rotate_bitmap(struct bitmap *bm) ++{ ++ struct bitmap new_bm; ++ bmUnitT *old_ptr, *new_ptr, *cp; ++ int x, y; ++ bmUnitT m1, m2; ++ ++ new_bm.h = bm->w; ++ new_bm.w = bm->h; ++ alloc_bitmap(&new_bm); ++ clear_bitmap(&new_bm); ++ old_ptr = (bmUnitT *)bm->bits; ++ new_ptr = (bmUnitT *)new_bm.bits; ++ ++ m1 = EXTREME_LEFT_BIT; ++ for (y = 0; y < bm->h; y++) { ++ cp = old_ptr; ++ old_ptr = ADD(old_ptr, bm->bytes_wide); ++ m2 = EXTREME_LEFT_BIT; ++ for (x = bm->w; x--;) { ++ if (*cp & m2) ++ *ADD(new_ptr, x * new_bm.bytes_wide) |= m1; ++ if (m2 == EXTREME_RIGHT_BIT) { ++ m2 = EXTREME_LEFT_BIT; ++ ++cp; ++ } ++ else SHIFT_RIGHT(m2); ++ } ++ if (m1 == EXTREME_RIGHT_BIT) { ++ m1 = EXTREME_LEFT_BIT; ++ ++new_ptr; ++ } ++ else SHIFT_RIGHT(m1); ++ } ++ ++ free(bm->bits); ++ *bm = new_bm; ++} ++#endif /* PTEX */ ++ + #ifdef GREY + + #ifdef RGB_ANTI_ALIASING +@@ -969,6 +1200,7 @@ shrink_glyph_grey(struct glyph *g) + BMBITS, 0); + size = g->image2->bytes_per_line * g->bitmap2.h; + g->pixmap2 = g->image2->data = xmalloc(size != 0 ? size : 1); ++ ASSERT(g->pixmap2_gc2 == NULL, "pixmap2_gc2 is not NULL."); + } + /* ... and the pixmap used for globals.gc.fore2: */ + if (globals.gc.fore2 != NULL && g->pixmap2_gc2 == NULL) { +@@ -1281,8 +1513,13 @@ static ubyte scantable[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, /* SET1,SET2 (128,129) */ +- /* -,-,SETRULE,PUT1,PUT2,-,-,PUTRULE,NOP,BOP (130-139) */ ++#ifdef PTEX ++ /* SET3,SET4,SETRULE,PUT1,PUT2,PUT3,PUT4,PUTRULE,NOP,BOP (130-139) */ ++ 3, 4, 8, 1, 2, 3, 4, 8, 0, 44, ++#else ++ /* -,-,SETRULE,PUT1,PUT2,-,-,PUTRULE,NOP,BOP (132-139) */ + M4, M4, 8, 1, 2, M4, M4, 8, 0, 44, ++#endif + M1, 0, 0, 1, 2, 3, 4, 0, 1, 2, /* EOP,PUSH,POP,RIGHT1-4,W0M2 (140-149) */ + 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, /* W3-4,X0-4,DOWN1-3 (150-159) */ + 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, /* DOWN4,Y0-4,Z0-3 (160-169) */ +@@ -1335,9 +1572,11 @@ spcl_scan(Boolean (*spcl_proc)(char *str, int str_len, + ch = xone(fp); + xskip(fp, (long)ch + (long)xone(fp)); + break; ++#ifndef PTEX + case M4: /* unrecognizable */ + XDVI_FATAL((stderr, "unknown op-code %d", ch)); + break; ++#endif /* !PTEX */ + case M5: /* doesn't belong */ + dvi_fmt_error("spcl_scan: shouldn't happen: %s encountered", + dvi_table2[ch - (FNTNUM0 + 64)]); +@@ -1451,6 +1690,46 @@ prescan(FILE *fp) + * Routines to print characters. + */ + ++#ifdef PTEX ++static void ++set_char_rotate_glyph(struct glyph *g) ++{ ++ int tmp, rot = TATE - g->tdir; ++ if (rot<0) rot+=4; ++ switch(rot) { ++ case 2: ++ rotate_bitmap(&g->bitmap); ++ tmp = g->x; ++ g->x = g->bitmap.w - g->y; ++ g->y = tmp; ++ g->tdir = TATE; ++ free_bitmap2(g); ++ case 1: ++ rotate_bitmap(&g->bitmap); ++ tmp = g->x; ++ g->x = g->bitmap.w - g->y; ++ g->y = tmp; ++ g->tdir = TATE; ++ free_bitmap2(g); ++ break; ++ case 3: ++ reverse_rotate_bitmap(&g->bitmap); ++ tmp = g->x; ++ g->x = g->y; ++ g->y = g->bitmap.h - tmp; ++ g->tdir = TATE; ++ free_bitmap2(g); ++ } ++} ++#endif /* PTEX */ ++ ++static setcharRetvalT ++common_set_char( ++#ifdef TEXXET ++ wide_ubyte, ++#endif ++ struct glyph *); ++ + setcharRetvalT + set_char( + #ifdef TEXXET +@@ -1459,9 +1738,6 @@ set_char( + wide_ubyte ch) + { + struct glyph *g; +-#ifdef TEXXET +- long dvi_h_sav; +-#endif + + if (ch > maxchar) + realloc_font(currinf.fontp, (wide_ubyte)ch); +@@ -1495,14 +1771,41 @@ set_char( + print_char((ubyte) ch, g); + currinf.fontp->timestamp = ++current_timestamp; + } ++#ifdef PTEX ++ set_char_rotate_glyph(g); ++#endif /* PTEX */ ++#ifdef TEXXET ++ common_set_char(cmd, g); ++#else ++ return common_set_char(g); ++#endif ++} + ++static setcharRetvalT ++common_set_char( + #ifdef TEXXET +- dvi_h_sav = DVI_H; +- if (currinf.dir < 0) +- DVI_H -= g->dvi_adv; ++ wide_ubyte cmd, ++#endif ++ struct glyph *g) ++{ ++#ifdef TEXXET ++ DEFINE_POSITION_VAL; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -g->dvi_adv); + + if (scan_frame == NULL) { + #endif ++ if (bbox_scaled) ++ bbox_scale_bitmap(g); ++ else if (g->bitmap3.bits) { ++ free(g->bitmap.bits); ++ g->bitmap = g->bitmap3; ++ g->bitmap3.bits = NULL; ++ g->x = g->x3; ++ g->y = g->y3; ++ free_bitmap2(g); ++ } + + #ifdef RGB_ANTI_ALIASING + if (currwin.shrinkfactor == -1) { +@@ -1544,9 +1847,9 @@ set_char( + #ifdef TEXXET + } + if (cmd == PUT1 || (resource.omega && cmd == PUT2)) +- DVI_H = dvi_h_sav; +- else if (currinf.dir > 0) +- DVI_H += g->dvi_adv; ++ POP_POSITION; ++ else if (TATE || currinf.dir > 0) ++ moveH(1, g->dvi_adv); + return; + #else + return g->dvi_adv; +@@ -1601,7 +1904,34 @@ set_empty_char( + #endif + } + ++#ifdef PTEX + setcharRetvalT ++set_char2( ++#ifdef TEXXET ++ wide_ubyte cmd, ++#endif ++ wide_ubyte ch) ++{ ++ struct glyph *g; ++ ++ if (ch > currinf.fontp->maxchar || ++ (g = currinf.fontp->kglyph[ch]) == NULL || g->bitmap.bits == NULL) { ++ (*currinf.fontp->read_char)(currinf.fontp, ch); ++ g = currinf.fontp->kglyph[ch]; ++ free_bitmap2(g); ++ g->tdir = currinf.fontp->dir; ++ if (globals.debug & DBG_BITMAP) print_char((ubyte) ch, g); ++ } ++ set_char_rotate_glyph(g); ++#ifdef TEXXET ++ common_set_char(cmd, g); ++#else ++ return common_set_char(g); ++#endif ++} ++#endif /* PTEX */ ++ ++setcharRetvalT + load_n_set_char( + #ifdef TEXXET + wide_ubyte cmd, +@@ -1648,7 +1978,7 @@ set_vf_char( + wide_ubyte oldmaxchar; + static ubyte c; + #ifdef TEXXET +- long dvi_h_sav; ++ DEFINE_POSITION_VAL; + #endif + + if (ch > maxchar) +@@ -1664,9 +1994,9 @@ set_vf_char( + #endif + } + #ifdef TEXXET +- dvi_h_sav = DVI_H; +- if (currinf.dir < 0) +- DVI_H -= m->dvi_adv; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -m->dvi_adv); + if (scan_frame == NULL) { + #endif + oldinfo = currinf; +@@ -1691,9 +2021,9 @@ set_vf_char( + #ifdef TEXXET + } + if (cmd == PUT1 || (resource.omega && cmd == PUT2)) +- DVI_H = dvi_h_sav; +- else if (currinf.dir > 0) +- DVI_H += m->dvi_adv; ++ POP_POSITION; ++ else if (TATE || currinf.dir > 0) ++ moveH(1, m->dvi_adv); + return; + #else + return m->dvi_adv; +@@ -1811,9 +2141,64 @@ set_no_char( + * Set rule. Arguments are coordinates of lower left corner. + */ + ++static void ++set_rotated_rule(long h, long w) ++{ ++ XPoint points[4]; ++ int pint = TATE; ++ if (pint&2) { pint&=1; ++ w=-w; h=-h; ++ } ++ points[0].x = PXL_H - currwin.base_x; ++ points[0].y = PXL_V - currwin.base_y; ++#ifdef PTEX ++ if (pint) { ++ points[1].x = -w * bbox_matrix[1][0]; ++ points[1].y = w * bbox_matrix[0][0]; ++ points[2].x = h * bbox_matrix[1][1]; ++ points[2].y = -h * bbox_matrix[0][1]; ++ } else ++#endif /* PTEX */ ++ { ++ points[1].x = DIR * w * bbox_matrix[0][0]; ++ points[1].y = DIR * w * bbox_matrix[1][0]; ++ points[2].x = -h * bbox_matrix[0][1]; ++ points[2].y = -h * bbox_matrix[1][1]; ++ } ++ points[3].x = -points[1].x; ++ points[3].y = -points[1].y; ++ ++ if (--globals.ev.ctr == 0) { ++ if (read_events(EV_NOWAIT) & EV_GE_MAG_GONE) { ++ /* fprintf(stderr, "longjmp1!\n"); */ ++ longjmp(globals.ev.canit, 1); ++ } ++ } ++#if COLOR ++ if (fg_active != fg_current) ++ do_color_change(); ++#endif ++ XFillPolygon(DISP, currwin.win, ++ htex_inside_href ? globals.gc.high: globals.gc.rule, ++ points, 4, Convex, CoordModePrevious); ++} ++ + static void + set_rule(int h, int w) + { ++ if (bbox_rotated) { ++ set_rotated_rule(h, w); ++ return; ++ } ++ h = h * bbox_matrix[1][1]; ++ w = w * bbox_matrix[0][0]; ++#ifdef PTEX ++ if (TATE==1) ++ put_rule(PXL_H, PXL_V, (unsigned int)h, (unsigned int)w); ++ else if (TATE==3) /* dtou */ ++ put_rule(PXL_H - h + 1, PXL_V - w + 1, (unsigned int)h, (unsigned int)w); ++ else ++#endif /* PTEX */ + #ifdef TEXXET + put_rule(PXL_H - (currinf.dir < 0 ? w - 1 : 0), PXL_V - h + 1, + (unsigned int)w, (unsigned int)h); +@@ -1858,7 +2243,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + #ifdef TEXXET + (*currinf.set_char_p) (ch, ch); + #else +- DVI_H += (*currinf.set_char_p) (ch); ++ moveH(1, (*currinf.set_char_p) (ch)); + #endif + } + else if (FNTNUM0 <= ch && ch <= (ubyte) (FNTNUM0 + 63)) { +@@ -1875,7 +2260,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + #else + a = (*currinf.set_char_p) (xone(fp)); + if (ch != PUT1) +- DVI_H += a; ++ moveH(1, a); + #endif + break; + +@@ -1890,11 +2275,43 @@ draw_part(FILE *fp, struct frame *minframe, double cur + #else + a = (*currinf.set_char_p) (xnum(fp, 2)); + if (ch != PUT2) +- DVI_H += a; ++ moveH(1, a); + #endif + } + break; + ++ case SET3: ++ case PUT3: ++ if (!resource.omega) ++ dvi_fmt_error("%s:%d: draw_part: op-code %d only works with the \"-omega\" option", ++ __FILE__, __LINE__, ch); ++ else { ++#ifdef TEXXET ++ (*currinf.set_char_p) (ch, xnum(fp, 3)); ++#else ++ a = (*currinf.set_char_p) (xnum(fp, 3)); ++ if (ch != PUT3) ++ moveH(1, a); ++#endif ++ } ++ break; ++ ++ case SET4: ++ case PUT4: ++ if (!resource.omega) ++ dvi_fmt_error("%s:%d: draw_part: op-code %d only works with the \"-omega\" option", ++ __FILE__, __LINE__, ch); ++ else { ++#ifdef TEXXET ++ (*currinf.set_char_p) (ch, xnum(fp, 4)); ++#else ++ a = (*currinf.set_char_p) (xnum(fp, 4)); ++ if (ch != PUT4) ++ moveH(1, a); ++#endif ++ } ++ break; ++ + case SETRULE: + /* Be careful, dvicopy outputs rules with + height = 0x80000000. We don't want any +@@ -1908,7 +2325,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + ) { + set_rule(pixel_round(xspell_conv(a)), pixel_round(b)); + } +- DVI_H += DIR * b; ++ moveH(DIR, b); + break; + + case PUTRULE: +@@ -1932,6 +2349,9 @@ draw_part(FILE *fp, struct frame *minframe, double cur + DVI_V = OFFSET_Y; + PXL_V = pixel_conv(DVI_V); + WW = XX = YY = ZZ = 0; ++ bbox_matrix[0][0] = bbox_matrix[1][1] = 1.0; ++ bbox_matrix[0][1] = bbox_matrix[1][0] = 0.0; ++ bbox_scaled = bbox_rotated = False; + break; + + case EOP: +@@ -2026,7 +2446,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + case RIGHT2: + case RIGHT3: + case RIGHT4: +- DVI_H += DIR * xspell_conv(xsnum(fp, ch - RIGHT1 + 1)); ++ moveH(DIR, xspell_conv(xsnum(fp, ch - RIGHT1 + 1))); + break; + + case W1: +@@ -2035,7 +2455,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + case W4: + WW = xspell_conv(xsnum(fp, ch - W0)); + case W0: +- DVI_H += DIR * WW; ++ moveH(DIR, WW); + break; + + case X1: +@@ -2044,15 +2464,14 @@ draw_part(FILE *fp, struct frame *minframe, double cur + case X4: + XX = xspell_conv(xsnum(fp, ch - X0)); + case X0: +- DVI_H += DIR * XX; ++ moveH(DIR, XX); + break; + + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: +- DVI_V += xspell_conv(xsnum(fp, ch - DOWN1 + 1)); +- PXL_V = pixel_conv(DVI_V); ++ moveV(1, xspell_conv(xsnum(fp, ch - DOWN1 + 1))); + break; + + case Y1: +@@ -2061,8 +2480,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + case Y4: + YY = xspell_conv(xsnum(fp, ch - Y0)); + case Y0: +- DVI_V += YY; +- PXL_V = pixel_conv(DVI_V); ++ moveV(1, YY); + break; + + case Z1: +@@ -2071,8 +2489,7 @@ draw_part(FILE *fp, struct frame *minframe, double cur + case Z4: + ZZ = xspell_conv(xsnum(fp, ch - Z0)); + case Z0: +- DVI_V += ZZ; +- PXL_V = pixel_conv(DVI_V); ++ moveV(1, ZZ); + break; + + case FNT1: +@@ -2119,6 +2536,11 @@ draw_part(FILE *fp, struct frame *minframe, double cur + dvi_fmt_error("%s:%d: draw_part: shouldn't happen: %s encountered", + __FILE__, __LINE__, dvi_table2[ch - (FNTNUM0 + 64)]); + break; ++#ifdef PTEX ++ case TDIR: ++ TATE = xone(fp); ++ break; ++#endif /* PTEX */ + + default: + dvi_fmt_error("%s:%d: draw_part: unknown op-code %d", __FILE__, __LINE__, ch); +@@ -2305,7 +2727,7 @@ draw_page(void) + psp.endpage(); + #endif + if (currwin.win == mane.win && resource.postscript != 1) { +- display_bboxes(); ++ display_bboxes(); + } + if (search_have_match(current_page)) { + /* highlight search match */ +@@ -2915,7 +3337,15 @@ do_char(wide_ubyte ch, + last_dvi_h1 = DVI_H; + last_u_glyph = u_glyph; + last_pxl_v = pxl_v1; ++#ifdef PTEX ++ if (currinf.fontp->flags & FONT_KANJI) { ++ last_dvi_h2 = DVI_H + currinf.fontp->kglyph[ch]->dvi_adv; ++ } else { ++#endif /* PTEX */ + last_dvi_h2 = DVI_H + currinf.fontp->glyph[ch].dvi_adv; ++#ifdef PTEX ++ } ++#endif /* PTEX */ + last_x = x2; + } + +@@ -2929,6 +3359,10 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ub + return 0; /* error; we'll catch it later */ + maxchar = currinf.fontp->maxchar; + currinf.set_char_p = currinf.fontp->set_char_p; ++#if FREETYPE ++ if (currinf.set_char_p == set_ft_char) ++ do_load_freetype_font(); ++#endif + } + + if (currinf.set_char_p == set_empty_char) +@@ -2961,10 +3395,6 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ub + } + maxchar = currinf.fontp->maxchar; + currinf.set_char_p = currinf.fontp->set_char_p; +-#if FREETYPE +- if (currinf.set_char_p == set_ft_char) +- do_load_freetype_font(); +-#endif + } + + if (currinf.set_char_p == set_char) { +@@ -2992,25 +3422,56 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ub + } + #ifdef TEXXET + if (geom_scan_frame == NULL) { +- long dvi_h_sav = DVI_H; +- if (currinf.dir < 0) +- DVI_H -= g->dvi_adv; ++ DEFINE_POSITION_VAL; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -g->dvi_adv); + #endif + x = G_PXL_H - g->x; + y = PXL_V - g->y; + do_char(ch, currinf, info, PXL_V, y, x, x + g->bitmap.w - 1, g); + #ifdef TEXXET +- DVI_H = dvi_h_sav; ++ POP_POSITION; + } + #endif + return DIR * g->dvi_adv; + } ++#ifdef PTEX ++ else if (currinf.set_char_p == set_char2) { ++ struct glyph *g; ++ long x, y; ++ ++ g = currinf.fontp->kglyph[ch]; ++ if (g == NULL || g->bitmap.bits == NULL) { ++ (*currinf.fontp->read_char)(currinf.fontp, ch); ++ g = currinf.fontp->kglyph[ch]; ++ free_bitmap2(g); ++ g->tdir = currinf.fontp->dir; ++ } ++ ++#ifdef TEXXET ++ if (geom_scan_frame == NULL) { ++ DEFINE_POSITION_VAL; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -g->dvi_adv); ++#endif ++ x = G_PXL_H - g->x; ++ y = PXL_V - g->y; ++ do_char(ch, currinf, info, PXL_V, y, x, x + g->bitmap.w - 1, g); ++#ifdef TEXXET ++ POP_POSITION; ++ } ++#endif ++ return DIR * g->dvi_adv; ++ } ++#endif /* PTEX */ + else if (currinf.set_char_p == set_vf_char) { + struct macro *m; + struct drawinf oldinfo; + wide_ubyte oldmaxchar; + #ifdef TEXXET +- long dvi_h_sav; ++ DEFINE_POSITION_VAL; + #endif + + if (ch > maxchar) +@@ -3018,9 +3479,9 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ub + if ((m = &currinf.fontp->macro[ch])->pos == NULL) + return 0; /* catch the error later */ + #ifdef TEXXET +- dvi_h_sav = DVI_H; +- if (currinf.dir < 0) +- DVI_H -= m->dvi_adv; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -m->dvi_adv); + if (geom_scan_frame == NULL) { + #endif + oldinfo = currinf; +@@ -3036,7 +3497,7 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ub + currinf = oldinfo; + maxchar = oldmaxchar; + #ifdef TEXXET +- DVI_H = dvi_h_sav; ++ POP_POSITION; + } + #endif + return DIR * m->dvi_adv; +@@ -3048,6 +3509,11 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ub + return 0; + } + ++#define xmoveH(dir,dx) \ ++ do { moveH(dir,dx); PXL_V = xpixel_conv(DVI_V); } while(0) ++#define xmoveV(dir,dy) \ ++ do { moveV(dir,dy); PXL_V = xpixel_conv(DVI_V); } while(0) ++ + /* + * Handle a character in geometric scanning routine. + */ +@@ -3063,6 +3529,10 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ub + return 0; /* error; we'll catch it later */ + maxchar = currinf.fontp->maxchar; + currinf.set_char_p = currinf.fontp->set_char_p; ++#if FREETYPE ++ if (currinf.set_char_p == set_ft_char) ++ do_load_freetype_font(); ++#endif + } + + if (currinf.set_char_p == set_empty_char) +@@ -3095,10 +3565,6 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ub + } + maxchar = currinf.fontp->maxchar; + currinf.set_char_p = currinf.fontp->set_char_p; +-#if FREETYPE +- if (currinf.set_char_p == set_ft_char) +- do_load_freetype_font(); +-#endif + } + + if (currinf.set_char_p == set_char) { +@@ -3126,27 +3592,58 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ub + } + #ifdef TEXXET + if (geom_scan_frame == NULL) { +- long dvi_h_sav = DVI_H; +- if (currinf.dir < 0) +- DVI_H -= g->dvi_adv; ++ DEFINE_POSITION_VAL; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -g->dvi_adv); + #endif + x = G_PXL_H - g->x; + y = PXL_V - g->y; + g_info->geom_box(info, x, y, + x + g->bitmap.w - 1, y + g->bitmap.h - 1); ++#ifdef TEXXET ++ POP_POSITION; ++ } ++#endif ++ return DIR * g->dvi_adv; ++ } ++#ifdef PTEX ++ else if (currinf.set_char_p == set_char2) { ++ struct glyph *g; ++ long x, y; + ++ g = currinf.fontp->kglyph[ch]; ++ if (g == NULL || g->bitmap.bits == NULL) { ++ (*currinf.fontp->read_char)(currinf.fontp, ch); ++ g = currinf.fontp->kglyph[ch]; ++ free_bitmap2(g); ++ g->tdir = currinf.fontp->dir; ++ } ++ + #ifdef TEXXET +- DVI_H = dvi_h_sav; ++ if (geom_scan_frame == NULL) { ++ DEFINE_POSITION_VAL; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -g->dvi_adv); ++#endif ++ x = G_PXL_H - g->x; ++ y = PXL_V - g->y; ++ g_info->geom_box(info, x, y, ++ x + g->bitmap.w - 1, y + g->bitmap.h - 1); ++#ifdef TEXXET ++ POP_POSITION; + } + #endif + return DIR * g->dvi_adv; + } ++#endif /* PTEX */ + else if (currinf.set_char_p == set_vf_char) { + struct macro *m; + struct drawinf oldinfo; + wide_ubyte oldmaxchar; + #ifdef TEXXET +- long dvi_h_sav; ++ DEFINE_POSITION_VAL; + #endif + + if (ch > maxchar) +@@ -3154,9 +3651,9 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ub + if ((m = &currinf.fontp->macro[ch])->pos == NULL) + return 0; /* catch the error later */ + #ifdef TEXXET +- dvi_h_sav = DVI_H; +- if (currinf.dir < 0) +- DVI_H -= m->dvi_adv; ++ PUSH_POSITION; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, -m->dvi_adv); + if (geom_scan_frame == NULL) { + #endif + oldinfo = currinf; +@@ -3172,7 +3669,7 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ub + currinf = oldinfo; + maxchar = oldmaxchar; + #ifdef TEXXET +- DVI_H = dvi_h_sav; ++ POP_POSITION; + } + #endif + return DIR * m->dvi_adv; +@@ -3192,21 +3689,35 @@ static void + geom_do_rule(struct scan_info *info, long h, long w) + { + long x, y; ++ struct geom_info *g_info = info->data; + #ifdef TEXXET +- long dvi_h_save = DVI_H; ++ DEFINE_POSITION_VAL; ++ PUSH_POSITION; + #endif +- struct geom_info *g_info = info->data; +- ++ ++ if (bbox_rotated) { ++ fprintf(stderr, "geom_do_rotated_rule(h, w) is not implemented!\n"); ++ return; ++ } ++ h = h * bbox_matrix[1][1]; ++ w = w * bbox_matrix[0][0]; ++ + #ifdef TEXXET +- if (currinf.dir < 0) +- DVI_H -= w - 1; ++ if (! TATE && currinf.dir < 0) ++ moveH(1, - w + 1); + #endif + x = G_PXL_H; + y = PXL_V; ++#ifdef PTEX ++ if (TATE) ++ g_info->geom_box(info, x, y, x + xpixel_round(h) - 1, ++ y + xpixel_round(w) - 1); ++ else ++#endif /* PTEX */ + g_info->geom_box(info, x, y - xpixel_round(h) + 1, + x + xpixel_round(w) - 1, y); + #ifdef TEXXET +- DVI_H = dvi_h_save; ++ POP_POSITION; + #endif + } + +@@ -3236,7 +3747,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + for (;;) { + ch = xone(fp); + if (ch <= (ubyte)(SETCHAR0 + 127)) +- DVI_H += char_proc(fp, info, ch); ++ xmoveH(1, char_proc(fp, info, ch)); + else if (FNTNUM0 <= ch && ch <= (ubyte) (FNTNUM0 + 63)) { + change_font((unsigned long)(ch - FNTNUM0)); + } +@@ -3248,7 +3759,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + case PUT1: + a = char_proc(fp, info, xone(fp)); + if (ch != PUT1) +- DVI_H += a; ++ xmoveH(1, a); + break; + + case SET2: +@@ -3262,11 +3773,43 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + #else + a = char_proc(fp, info, xnum(fp, 2)); + if (ch != PUT2) +- DVI_H += a; ++ xmoveH(1, a); + #endif + } + break; + ++ case SET3: ++ case PUT3: ++ if (!resource.omega) ++ dvi_fmt_error("%s:%d: draw_part: op-code %d only works with the \"-omega\" option", ++ __FILE__, __LINE__, ch); ++ else { ++#ifdef TEXXET ++ char_proc(fp, info, xnum(fp, 3)); ++#else ++ a = char_proc(fp, info, xnum(fp, 3)); ++ if (ch != PUT3) ++ xmoveH(1, a); ++#endif ++ } ++ break; ++ ++ case SET4: ++ case PUT4: ++ if (!resource.omega) ++ dvi_fmt_error("%s:%d: draw_part: op-code %d only works with the \"-omega\" option", ++ __FILE__, __LINE__, ch); ++ else { ++#ifdef TEXXET ++ char_proc(fp, info, xnum(fp, 4)); ++#else ++ a = char_proc(fp, info, xnum(fp, 4)); ++ if (ch != PUT4) ++ xmoveH(1, a); ++#endif ++ } ++ break; ++ + case SETRULE: + /* Be careful, dvicopy outputs rules with + height = 0x80000000. We don't want any +@@ -3282,7 +3825,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + if (info->geom_special != NULL) + geom_do_rule(info, xspell_conv(a), b); + } +- DVI_H += DIR * b; ++ moveH(DIR, b); + break; + + case PUTRULE: +@@ -3403,7 +3946,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + case RIGHT2: + case RIGHT3: + case RIGHT4: +- DVI_H += DIR * xspell_conv(xsnum(fp, ch - RIGHT1 + 1)); ++ xmoveH(DIR, xspell_conv(xsnum(fp, ch - RIGHT1 + 1))); + break; + + case W1: +@@ -3412,7 +3955,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + case W4: + WW = xspell_conv(xsnum(fp, ch - W0)); + case W0: +- DVI_H += DIR * WW; ++ xmoveH(DIR, WW); + break; + + case X1: +@@ -3421,15 +3964,14 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + case X4: + XX = xspell_conv(xsnum(fp, ch - X0)); + case X0: +- DVI_H += DIR * XX; ++ xmoveH(DIR, XX); + break; + + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: +- DVI_V += xspell_conv(xsnum(fp, ch - DOWN1 + 1)); +- PXL_V = xpixel_conv(DVI_V); ++ xmoveV(1, xspell_conv(xsnum(fp, ch - DOWN1 + 1))); + break; + + case Y1: +@@ -3438,8 +3980,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + case Y4: + YY = xspell_conv(xsnum(fp, ch - Y0)); + case Y0: +- DVI_V += YY; +- PXL_V = xpixel_conv(DVI_V); ++ xmoveV(1, YY); + break; + + case Z1: +@@ -3448,8 +3989,7 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + case Z4: + ZZ = xspell_conv(xsnum(fp, ch - Z0)); + case Z0: +- DVI_V += ZZ; +- PXL_V = xpixel_conv(DVI_V); ++ xmoveV(1, ZZ); + break; + + case FNT1: +@@ -3485,6 +4025,12 @@ geom_scan_part(long(*char_proc)(FILE *, struct scan_in + a = (long)xone(fp); + xskip(fp, a + (long)xone(fp)); + break; ++ ++#ifdef PTEX ++ case TDIR: ++ TATE = xone(fp); ++ break; ++#endif /* PTEX */ + + #ifndef TEXXET + case SREFL: |