summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/dvi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/dvi.c')
-rw-r--r--Build/source/texk/dvipdfm-x/dvi.c106
1 files changed, 76 insertions, 30 deletions
diff --git a/Build/source/texk/dvipdfm-x/dvi.c b/Build/source/texk/dvipdfm-x/dvi.c
index a4afab61bdb..3dc94d440e1 100644
--- a/Build/source/texk/dvipdfm-x/dvi.c
+++ b/Build/source/texk/dvipdfm-x/dvi.c
@@ -806,11 +806,62 @@ dvi_set_phantom_height (double height, double depth)
catch_phantom = 2;
}
+/* All those things related to "compensation" is intruduced due to
+ * bcontent/econtent specials. They are originally implemented with
+ * modification to very important part of pdfdev functions such as
+ * pdf_dev_set_string(), and it made things very unclear.
+ *
+ * It is not good idea to modify the core part of PDF output routines
+ * just for implementing DVI "special" command. They do not make sense
+ * and just look odd when PDF output routines are separated from dvipdfmx.
+ */
+static struct spt_coord {
+ spt_t x, y;
+} compensation = { 0, 0 };
+
+void dvi_set_compensation (double x, double y)
+{
+ compensation.x = (spt_t) round(x / dvi2pts);
+ compensation.y = (spt_t) round(y / dvi2pts);
+}
+
+static void
+set_string (spt_t xpos,
+ spt_t ypos,
+ const void *instr_ptr,
+ int instr_len,
+ spt_t width,
+ int font_id,
+ int ctype)
+{
+ xpos -= compensation.x;
+ ypos -= compensation.y;
+ pdf_dev_set_string(xpos, ypos, instr_ptr, instr_len, width, font_id, ctype);
+}
+
+static void
+set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
+{
+ xpos -= compensation.x;
+ ypos -= compensation.y;
+ pdf_dev_set_rule(xpos, ypos, width, height);
+}
+
+static void
+calc_rect (pdf_rect *r, spt_t xpos, spt_t ypos, spt_t width, spt_t height, spt_t depth)
+{
+ xpos -= compensation.x;
+ ypos -= compensation.y;
+ pdf_dev_set_rect(r, xpos, ypos, width, height, depth);
+}
+
void
dvi_do_special (const void *buffer, int32_t size)
{
- double x_user, y_user, mag;
+ double x_user, y_user, mag;
const char *p;
+ int is_drawable = 0;
+ pdf_rect rect = {0.0, 0.0, 0.0, 0.0};
graphics_mode();
@@ -820,10 +871,15 @@ dvi_do_special (const void *buffer, int32_t size)
y_user = -dvi_state.v * dvi2pts;
mag = dvi_tell_mag();
- if (spc_exec_special(p, size, x_user, y_user, mag) < 0) {
+ if (spc_exec_special(p, size, x_user, y_user, mag, &is_drawable, &rect) < 0) {
if (dpx_conf.verbose_level > 0) {
dump(p, p + size);
}
+ return;
+ }
+
+ if (dvi_is_tracking_boxes() && is_drawable) {
+ pdf_doc_expand_box(&rect);
}
return;
@@ -1174,7 +1230,7 @@ void dvi_right (int32_t x)
default:
width = dvi_state.h - save_h;
}
- pdf_dev_set_rect (&rect, save_h, -save_v, width, height, depth);
+ calc_rect(&rect, save_h, -save_v, width, height, depth);
pdf_doc_expand_box(&rect);
}
}
@@ -1235,23 +1291,19 @@ dvi_set (int32_t ch)
wbuf[1] = UTF32toUTF16HS(ch) & 0xff;
wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff;
wbuf[3] = UTF32toUTF16LS(ch) & 0xff;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4,
- width, font->font_id, 2);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 4, width, font->font_id, 2);
} else if (ch > 255) { /* _FIXME_ */
wbuf[0] = (ch >> 8) & 0xff;
wbuf[1] = ch & 0xff;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
- width, font->font_id, 2);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
} else if (font->subfont_id >= 0) {
unsigned short uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
wbuf[0] = (uch >> 8) & 0xff;
wbuf[1] = uch & 0xff;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
- width, font->font_id, 2);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
} else {
wbuf[0] = (unsigned char) ch;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1,
- width, font->font_id, 1);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 1, width, font->font_id, 1);
}
if (dvi_is_tracking_boxes()) {
pdf_rect rect;
@@ -1261,8 +1313,7 @@ dvi_set (int32_t ch)
height = sqxfw(font->size, height);
depth = sqxfw(font->size, depth);
- pdf_dev_set_rect (&rect, dvi_state.h, -dvi_state.v,
- width, height, depth);
+ calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
pdf_doc_expand_box(&rect);
}
break;
@@ -1302,30 +1353,27 @@ dvi_put (int32_t ch)
/* Treat a single character as a one byte string and use the
* string routine.
*/
- if (ch > 65535) { /* _FIXME_ */
+ if (ch > 65535) {
+ /* FIXME: This is a private extension made by someone... */
wbuf[0] = (UTF32toUTF16HS(ch) >> 8) & 0xff;
wbuf[1] = UTF32toUTF16HS(ch) & 0xff;
wbuf[2] = (UTF32toUTF16LS(ch) >> 8) & 0xff;
wbuf[3] = UTF32toUTF16LS(ch) & 0xff;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 4,
- width, font->font_id, 2);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 4, width, font->font_id, 2);
} else if (ch > 255) { /* _FIXME_ */
wbuf[0] = (ch >> 8) & 0xff;
wbuf[1] = ch & 0xff;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
- width, font->font_id, 2);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
} else if (font->subfont_id >= 0) {
unsigned int uch;
uch = lookup_sfd_record(font->subfont_id, (unsigned char) ch);
wbuf[0] = (uch >> 8) & 0xff;
wbuf[1] = uch & 0xff;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 2,
- width, font->font_id, 2);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 2, width, font->font_id, 2);
} else {
wbuf[0] = (unsigned char) ch;
- pdf_dev_set_string(dvi_state.h, -dvi_state.v, wbuf, 1,
- width, font->font_id, 1);
+ set_string(dvi_state.h, -dvi_state.v, wbuf, 1, width, font->font_id, 1);
}
if (dvi_is_tracking_boxes()) {
pdf_rect rect;
@@ -1335,8 +1383,7 @@ dvi_put (int32_t ch)
height = sqxfw(font->size, height);
depth = sqxfw(font->size, depth);
- pdf_dev_set_rect (&rect, dvi_state.h, -dvi_state.v,
- width, height, depth);
+ calc_rect(&rect, dvi_state.h, -dvi_state.v, width, height, depth);
pdf_doc_expand_box(&rect);
}
break;
@@ -1362,13 +1409,13 @@ dvi_rule (int32_t width, int32_t height)
switch (dvi_state.d) {
case 0:
- pdf_dev_set_rule(dvi_state.h, -dvi_state.v, width, height);
+ 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);
+ 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);
+ set_rule(dvi_state.h - height, -dvi_state.v , height, width);
break;
}
}
@@ -1843,15 +1890,14 @@ do_glyphs (int do_actual_text)
pdf_rect rect;
height = (double)font->size * ascent / (double)font->unitsPerEm;
depth = (double)font->size * -descent / (double)font->unitsPerEm;
- pdf_dev_set_rect(&rect, dvi_state.h + xloc[i], -dvi_state.v - yloc[i], glyph_width, height, depth);
+ calc_rect(&rect, dvi_state.h + xloc[i], -dvi_state.v - yloc[i], glyph_width, height, depth);
pdf_doc_expand_box(&rect);
}
}
wbuf[0] = glyph_id >> 8;
wbuf[1] = glyph_id & 0xff;
- pdf_dev_set_string(dvi_state.h + xloc[i], -dvi_state.v - yloc[i], wbuf, 2,
- glyph_width, font->font_id, -1);
+ set_string(dvi_state.h + xloc[i], -dvi_state.v - yloc[i], wbuf, 2, glyph_width, font->font_id, -1);
}
if (font->rgba_used == 1) {