summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c
diff options
context:
space:
mode:
authorLuigi Scarso <luigi.scarso@gmail.com>2023-01-24 16:49:02 +0000
committerLuigi Scarso <luigi.scarso@gmail.com>2023-01-24 16:49:02 +0000
commit80c93c8f00f58020c56174ee314ad783b1bd44af (patch)
treeec219ff9452437c6b22801195a23098106b491dc /Build/source/texk/web2c
parent89aa8fb4ad7c472e9442873a3b4d2ad19666ee97 (diff)
fix for r2l multiline link etc rectangles (H.Hagen)
git-svn-id: svn://tug.org/texlive/trunk@65617 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c')
-rw-r--r--Build/source/texk/web2c/luatexdir/ChangeLog3
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex_svnversion.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfannot.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfdest.c10
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfgen.c8
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflink.c45
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflistout.c323
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflistout.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftables.c58
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftables.h5
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfthread.c11
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftypes.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.h7
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textoken.c3
14 files changed, 328 insertions, 153 deletions
diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog
index 91c53445205..268589a75ed 100644
--- a/Build/source/texk/web2c/luatexdir/ChangeLog
+++ b/Build/source/texk/web2c/luatexdir/ChangeLog
@@ -1,3 +1,6 @@
+2023-01-24 Luigi Scarso <luigi.scarso@gmail.com>
+ * fix for r2l multiline link etc rectangles (H.Hagen)
+
2023-01-17 Luigi Scarso <luigi.scarso@gmail.com>
* \pdfvariable omitmediabox 1 (H.Hagen)
* luatex 1.16.0
diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h
index cfbc8af82ab..a6eb6c1a292 100644
--- a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h
+++ b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -1,4 +1,4 @@
#ifndef luatex_svn_revision_h
#define luatex_svn_revision_h
-#define luatex_svn_revision 7556
+#define luatex_svn_revision 7557
#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.c b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.c
index e501947c78f..d2a1cb2688e 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.c
@@ -37,7 +37,7 @@ void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
alt_rule.wd = width(p);
alt_rule.ht = height(p);
alt_rule.dp = depth(p);
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, 0);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
obj_annot_ptr(pdf, pdf_annot_objnum(p)) = p;
addto_page_resources(pdf, obj_type_annot, pdf_annot_objnum(p));
}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c
index ca3c76faa3c..0a0da0f89ff 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c
@@ -105,10 +105,11 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
The different branches for matrixused is somewhat strange and should
always be used
*/
+ pdf_ann_margin(p) = pdf_dest_margin;
switch (pdf_dest_type(p)) {
case pdf_dest_xyz:
if (matrixused())
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
else {
pdf_ann_left(p) = pos.h;
pdf_ann_top(p) = pos.v;
@@ -117,14 +118,14 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
case pdf_dest_fith:
case pdf_dest_fitbh:
if (matrixused())
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
else
pdf_ann_top(p) = pos.v;
break;
case pdf_dest_fitv:
case pdf_dest_fitbv:
if (matrixused())
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
else
pdf_ann_left(p) = pos.h;
break;
@@ -132,7 +133,8 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
case pdf_dest_fitb:
break;
case pdf_dest_fitr:
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
+ break;
}
}
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c
index 52d771bc36b..076b324e334 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c
@@ -929,10 +929,10 @@ void pdf_add_rect_spec(PDF pdf, halfword r)
void pdf_add_rect_spec(PDF pdf, halfword r)
{
/* the check is now here */
- pdf_add_bp(pdf, pdf_ann_left(r) < pdf_ann_right(r) ? pdf_ann_left(r) : pdf_ann_right(r));
- pdf_add_bp(pdf, pdf_ann_bottom(r) < pdf_ann_top(r) ? pdf_ann_bottom(r) : pdf_ann_top(r));
- pdf_add_bp(pdf, pdf_ann_left(r) < pdf_ann_right(r) ? pdf_ann_right(r) : pdf_ann_left(r));
- pdf_add_bp(pdf, pdf_ann_bottom(r) < pdf_ann_top(r) ? pdf_ann_top(r) : pdf_ann_bottom(r));
+ pdf_add_bp(pdf, (pdf_ann_left(r) < pdf_ann_right(r) ? pdf_ann_left(r) : pdf_ann_right(r) ) - pdf_ann_margin(r));
+ pdf_add_bp(pdf, (pdf_ann_bottom(r) < pdf_ann_top(r) ? pdf_ann_bottom(r) : pdf_ann_top(r) ) - pdf_ann_margin(r));
+ pdf_add_bp(pdf, (pdf_ann_left(r) < pdf_ann_right(r) ? pdf_ann_right(r) : pdf_ann_left(r) ) + pdf_ann_margin(r));
+ pdf_add_bp(pdf, (pdf_ann_bottom(r) < pdf_ann_top(r) ? pdf_ann_top(r) : pdf_ann_bottom(r)) + pdf_ann_margin(r));
}
void pdf_rectangle(PDF pdf, halfword r)
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflink.c b/Build/source/texk/web2c/luatexdir/pdf/pdflink.c
index b5bad7a682b..ed908e6456c 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdflink.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflink.c
@@ -47,6 +47,8 @@ void push_link_level(PDF pdf, halfword p)
pdf->link_stack[pdf->link_stack_ptr].nesting_level = cur_s;
pdf->link_stack[pdf->link_stack_ptr].link_node = copy_node_list(p);
pdf->link_stack[pdf->link_stack_ptr].ref_link_node = p;
+ pdf->link_stack[pdf->link_stack_ptr].direction = pdf->posstruct->dir;
+ pdf->link_stack[pdf->link_stack_ptr].count = 0;
}
void pop_link_level(PDF pdf)
@@ -69,7 +71,9 @@ void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
alt_rule.wd = width(p);
alt_rule.ht = height(p);
alt_rule.dp = depth(p);
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin);
+ pdf->link_stack[pdf->link_stack_ptr].count++;
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
+ pdf_ann_margin(p) = pdf_link_margin;
/*tex The reference for the annot object must be set here. */
obj_annot_ptr(pdf, pdf_link_objnum(p)) = p;
k = pdf_link_objnum(p);
@@ -95,15 +99,15 @@ void end_link(PDF pdf, halfword p)
if (is_running(width(pdf->link_stack[pdf->link_stack_ptr].link_node))) {
q = pdf->link_stack[pdf->link_stack_ptr].ref_link_node;
if (global_shipping_mode == SHIPPING_PAGE && matrixused()) {
- matrixrecalculate(pos.h + pdf_link_margin);
- pdf_ann_left(q) = getllx() - pdf_link_margin;
- pdf_ann_top(q) = getlly() - pdf_link_margin;
- pdf_ann_right(q) = geturx() + pdf_link_margin;
- pdf_ann_bottom(q) = getury() + pdf_link_margin;
+ matrixrecalculate(pos.h);
+ pdf_ann_left(q) = getllx();
+ pdf_ann_top(q) = getlly();
+ pdf_ann_right(q) = geturx();
+ pdf_ann_bottom(q) = getury();
} else {
switch (pdf->posstruct->dir) {
case dir_TLT:
- pdf_ann_right(q) = pos.h + pdf_link_margin;
+ pdf_ann_right(q) = pos.h;
break;
case dir_TRT:
/*tex
@@ -111,19 +115,35 @@ void end_link(PDF pdf, halfword p)
to the moment we write the rectangle, but it did not
consider this case.
*/
+ if (pdf_linking) {
+ /* begin of experiment, can be simplified */
+ if (pdf->link_stack[pdf->link_stack_ptr].count > 1) {
+ pdf_ann_right(q) = pdf_ann_right(q) - pdf_ann_left(q) + pos.h;
+ pdf_ann_left(q) = pos.h;
+ if (pdf_ann_left(q) > pdf_ann_right(q)) {
+ halfword r = pdf_ann_right(q);
+ halfword l = pdf_ann_left(q);
+ pdf_ann_right(q) = pos.h - r;
+ pdf_ann_left(q) = pos.h;
+ }
+ break;
+ }
+ /* end of experiment */
+ }
if (pdf_ann_left(q)<pdf_ann_right(q)) {
- pdf_ann_left(q) = pos.h - pdf_link_margin;
+ pdf_ann_left(q) = pos.h;
} else {
- pdf_ann_right(q) = pos.h - pdf_link_margin;
+ pdf_ann_right(q) = pos.h;
}
break;
case dir_LTL:
case dir_RTT:
- pdf_ann_bottom(q) = pos.v - pdf_link_margin;
+ pdf_ann_bottom(q) = pos.v;
break;
default:
- pdf_ann_right(q) = pos.h + pdf_link_margin;
+ pdf_ann_right(q) = pos.h;
formatted_warning("pdf backend","forcing bad dir %i to TLT in link",pdf->posstruct->dir);
+ break;
}
}
}
@@ -147,12 +167,13 @@ void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i)
scaled_whd alt_rule;
p = copy_node(pdf->link_stack[(int) i].link_node);
pdf->link_stack[(int) i].ref_link_node = p;
+ pdf->link_stack[(int) i].count++;
/*tex This node is not a normal link node. */
subtype(p) = pdf_link_data_node;
alt_rule.wd = width(p);
alt_rule.ht = height(p);
alt_rule.dp = depth(p);
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
k = pdf_create_obj(pdf, obj_type_others, 0);
obj_annot_ptr(pdf, k) = p;
set_obj_scheduled(pdf, pdf_link_objnum(p));
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c
index 02c7025c330..6561626d8ba 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c
@@ -154,6 +154,110 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_
return enddir_ptr;
}
+/*tex
+ With |\pdfvariable linking = 1| a few alternative code paths witll be used that try to compensate
+ for multiline side effects as well as left- and right skip (no other skips yet). After days of
+ looking for better ways I settled on this hackery approach. After all for > 15 years we had the
+ old handling and so a flag makes sense. I (HH) don't use this code myself so it's a it of a
+ gamble wrt usage scenarios.
+*/
+
+halfword calculate_width_to_endlink(halfword p, halfword this_box, halfword *leftskip, halfword *rightskip)
+{
+ halfword q = p;
+ scaled w = 0;
+ /*tex The glue value before rounding: */
+ real glue_temp;
+ real cur_glue = 0.0;
+ int level = 0;
+ /*tex rounded equivalent of |cur_glue| times the glue ratio */
+ scaled cur_g = 0;
+ int g_sign = glue_sign(this_box);
+ int g_order = glue_order(this_box);
+ *leftskip = 0;
+ while (q != null) {
+ if (is_char_node(q))
+ w += pack_width(box_dir(this_box), dir_TRT, q, true);
+ else {
+ switch (type(q)) {
+ case hlist_node:
+ case vlist_node:
+ w += pack_width(box_dir(this_box), box_dir(q), q, false);
+ break;
+ case rule_node:
+ case margin_kern_node:
+ w += width(q);
+ break;
+ case kern_node:
+ /*tex Officially we should check the subtype. */
+ w += kern_width(q);
+ break;
+ case math_node:
+ /*tex Begin of |mathskip| code. */
+ if (glue_is_zero(q)) {
+ w += surround(q);
+ break;
+ } else {
+ /*tex Fall through |mathskip|. */
+ }
+ /*tex End of |mathskip| code. */
+ case glue_node:
+ /* this is a terrible hack related to multiline links with directions */
+ {
+ halfword ww = w;
+
+ w += width(q) - cur_g;
+ if (g_sign != normal) {
+ if (g_sign == stretching) {
+ if (stretch_order(q) == g_order) {
+ cur_glue = cur_glue + stretch(q);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue);
+ cur_g = float_round(glue_temp);
+ }
+ } else if (shrink_order(q) == g_order) {
+ cur_glue = cur_glue - shrink(q);
+ vet_glue(float_cast(glue_set(this_box)) * cur_glue);
+ cur_g = float_round(glue_temp);
+ }
+ }
+ w += cur_g;
+ /* also experiment */
+ if (type(q) == glue_node) {
+ if (subtype(q) == left_skip_glue) {
+ *leftskip = w - ww;
+ w = ww;
+ } else if (subtype(q) == right_skip_glue) {
+ *rightskip = w - ww;
+ w = ww;
+ }
+ }
+ }
+ break;
+ case disc_node:
+ /* (HH): The frontend should append already. */
+ if (vlink(no_break(q)) != null)
+ w += simple_advance_width(no_break(q));
+ break;
+ case whatsit_node:
+ if (subtype(q) == pdf_end_link_node) {
+ if (level == 0) {
+ return w;
+ } else {
+ --level;
+ }
+ } else if (subtype(q) == pdf_start_link_node) {
+ ++level;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ q = vlink(q);
+ }
+ return w;
+}
+
/*tex
The |out_what| procedure takes care of outputting the whatsit nodes for
@@ -260,13 +364,14 @@ void hlist_out(PDF pdf, halfword this_box, int rule_callback_id)
We ignore this link. This is a compatibility-with-pdftex feature needed for latex. It
is suboptimal in the sense that when the whatsit is set, the next box is influenced,
so there there can be side effects when used in the middle of a line, when using
- vadjust, etc. But we can assume that tha macro package knows when and where this
+ vadjust, etc. But we can assume that the macro package knows when and where this
mechanism is triggered, so a more sophisticated solution is not needed (and would be
confusing in its own anyway.)
I would not be surprised of we have some leak here but it's harmless.
*/
} else if (pdf->link_stack[i].nesting_level == cur_s) {
+ /* hm, cur is zero */
append_link(pdf, this_box, cur, (small_number) i);
}
}
@@ -413,130 +518,130 @@ void hlist_out(PDF pdf, halfword this_box, int rule_callback_id)
vet_glue(float_cast(glue_set(this_box)) * cur_glue);
cur_g = float_round(glue_temp);
}
- }
- rule.wd = rule.wd + cur_g;
- if (subtype(p) >= a_leaders) {
- /*tex
- Output leaders in an hlist, |goto fin_rule| if a rule
- or to |next_p| if done.
- */
- leader_box = leader_ptr(p);
- if (type(leader_box) == rule_node) {
- rule.ht = height(leader_box);
- rule.dp = depth(leader_box);
- rleft = 0;
- rright = 0;
- goto FIN_RULE;
}
- if (textdir_parallel(box_dir(leader_box), localpos.dir))
- leader_wd = width(leader_box);
- else
- leader_wd = height(leader_box) + depth(leader_box);
- if ((leader_wd > 0) && (rule.wd > 0)) {
- /*tex Compensate for floating-point rounding. */
- rule.wd = rule.wd + 10;
- edge = cur.h + rule.wd;
- lx = 0;
+ rule.wd = rule.wd + cur_g;
+ if (subtype(p) >= a_leaders) {
/*tex
- Let |cur.h| be the position of the first box, and
- set |leader_wd+lx| to the spacing between
- corresponding parts of boxes.
+ Output leaders in an hlist, |goto fin_rule| if a rule
+ or to |next_p| if done.
*/
- if (subtype(p) == g_leaders) {
- save_h = cur.h;
- switch (localpos.dir) {
- case dir_TLT:
- cur.h += refpos->pos.h - shipbox_refpos.h;
- cur.h = leader_wd * (cur.h / leader_wd);
- cur.h -= refpos->pos.h - shipbox_refpos.h;
- break;
- case dir_TRT:
- cur.h = refpos->pos.h - shipbox_refpos.h - cur.h;
- cur.h = leader_wd * (cur.h / leader_wd);
- cur.h = refpos->pos.h - shipbox_refpos.h - cur.h;
- break;
- case dir_LTL:
- case dir_RTT:
- cur.h = refpos->pos.v - shipbox_refpos.v - cur.h;
- cur.h = leader_wd * (cur.h / leader_wd);
- cur.h = refpos->pos.v - shipbox_refpos.v - cur.h;
- break;
- default:
- formatted_warning("pdf backend","forcing bad dir %i to TLT in hlist case 1",localpos.dir);
- localpos.dir = dir_TLT;
- cur.h += refpos->pos.h - shipbox_refpos.h;
- cur.h = leader_wd * (cur.h / leader_wd);
- cur.h -= refpos->pos.h - shipbox_refpos.h;
- break;
- }
- if (cur.h < save_h)
- cur.h += leader_wd;
- } else if (subtype(p) == a_leaders) {
- save_h = cur.h;
- cur.h = leader_wd * (cur.h / leader_wd);
- if (cur.h < save_h)
- cur.h += leader_wd;
- } else {
- /*tex The number of box copies: */
- lq = rule.wd / leader_wd;
- /*tex The remaining space: */
- lr = rule.wd % leader_wd;
- if (subtype(p) == c_leaders) {
- cur.h += lr / 2;
- } else {
- lx = lr / (lq + 1);
- cur.h += (lr - (lq - 1) * lx) / 2;
- }
+ leader_box = leader_ptr(p);
+ if (type(leader_box) == rule_node) {
+ rule.ht = height(leader_box);
+ rule.dp = depth(leader_box);
+ rleft = 0;
+ rright = 0;
+ goto FIN_RULE;
}
- while (cur.h + leader_wd <= edge) {
+ if (textdir_parallel(box_dir(leader_box), localpos.dir))
+ leader_wd = width(leader_box);
+ else
+ leader_wd = height(leader_box) + depth(leader_box);
+ if ((leader_wd > 0) && (rule.wd > 0)) {
+ /*tex Compensate for floating-point rounding. */
+ rule.wd = rule.wd + 10;
+ edge = cur.h + rule.wd;
+ lx = 0;
/*tex
- Output a leader box at |cur.h|, then advance
- |cur.h| by |leader_wd+lx|.
+ Let |cur.h| be the position of the first box, and
+ set |leader_wd+lx| to the spacing between
+ corresponding parts of boxes.
*/
- if (pardir_parallel(box_dir(leader_box), localpos.dir)) {
- basepoint.v = 0;
- if (textdir_opposite(box_dir(leader_box), localpos.dir))
- basepoint.h = width(leader_box);
- else
- basepoint.h = 0;
+ if (subtype(p) == g_leaders) {
+ save_h = cur.h;
+ switch (localpos.dir) {
+ case dir_TLT:
+ cur.h += refpos->pos.h - shipbox_refpos.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h -= refpos->pos.h - shipbox_refpos.h;
+ break;
+ case dir_TRT:
+ cur.h = refpos->pos.h - shipbox_refpos.h - cur.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h = refpos->pos.h - shipbox_refpos.h - cur.h;
+ break;
+ case dir_LTL:
+ case dir_RTT:
+ cur.h = refpos->pos.v - shipbox_refpos.v - cur.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h = refpos->pos.v - shipbox_refpos.v - cur.h;
+ break;
+ default:
+ formatted_warning("pdf backend","forcing bad dir %i to TLT in hlist case 1",localpos.dir);
+ localpos.dir = dir_TLT;
+ cur.h += refpos->pos.h - shipbox_refpos.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ cur.h -= refpos->pos.h - shipbox_refpos.h;
+ break;
+ }
+ if (cur.h < save_h)
+ cur.h += leader_wd;
+ } else if (subtype(p) == a_leaders) {
+ save_h = cur.h;
+ cur.h = leader_wd * (cur.h / leader_wd);
+ if (cur.h < save_h)
+ cur.h += leader_wd;
} else {
- if (!is_mirrored(box_dir(leader_box))) {
- if (partextdir_eq(box_dir(leader_box), localpos.dir))
- basepoint.h = height(leader_box);
+ /*tex The number of box copies: */
+ lq = rule.wd / leader_wd;
+ /*tex The remaining space: */
+ lr = rule.wd % leader_wd;
+ if (subtype(p) == c_leaders) {
+ cur.h += lr / 2;
+ } else {
+ lx = lr / (lq + 1);
+ cur.h += (lr - (lq - 1) * lx) / 2;
+ }
+ }
+ while (cur.h + leader_wd <= edge) {
+ /*tex
+ Output a leader box at |cur.h|, then advance
+ |cur.h| by |leader_wd+lx|.
+ */
+ if (pardir_parallel(box_dir(leader_box), localpos.dir)) {
+ basepoint.v = 0;
+ if (textdir_opposite(box_dir(leader_box), localpos.dir))
+ basepoint.h = width(leader_box);
else
- basepoint.h = depth(leader_box);
+ basepoint.h = 0;
} else {
- if (partextdir_eq(box_dir(leader_box), localpos.dir))
- basepoint.h = depth(leader_box);
+ if (!is_mirrored(box_dir(leader_box))) {
+ if (partextdir_eq(box_dir(leader_box), localpos.dir))
+ basepoint.h = height(leader_box);
+ else
+ basepoint.h = depth(leader_box);
+ } else {
+ if (partextdir_eq(box_dir(leader_box), localpos.dir))
+ basepoint.h = depth(leader_box);
+ else
+ basepoint.h = height(leader_box);
+ }
+ if (partextdir_eq(localpos.dir, box_dir(leader_box)))
+ basepoint.v = -(width(leader_box) / 2);
else
- basepoint.h = height(leader_box);
+ basepoint.v = (width(leader_box) / 2);
}
- if (partextdir_eq(localpos.dir, box_dir(leader_box)))
- basepoint.v = -(width(leader_box) / 2);
+ if (!is_mirrored(localpos.dir))
+ basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box down */
else
- basepoint.v = (width(leader_box) / 2);
+ basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box up */
+ tmpcur.h = cur.h + basepoint.h;
+ tmpcur.v = basepoint.v;
+ synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
+ outer_doing_leaders = doing_leaders;
+ doing_leaders = true;
+ if (type(leader_box) == vlist_node)
+ vlist_out(pdf, leader_box, rule_callback_id);
+ else
+ hlist_out(pdf, leader_box, rule_callback_id);
+ doing_leaders = outer_doing_leaders;
+ cur.h += leader_wd + lx;
}
- if (!is_mirrored(localpos.dir))
- basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box down */
- else
- basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box up */
- tmpcur.h = cur.h + basepoint.h;
- tmpcur.v = basepoint.v;
- synch_pos_with_cur(pdf->posstruct, refpos, tmpcur);
- outer_doing_leaders = doing_leaders;
- doing_leaders = true;
- if (type(leader_box) == vlist_node)
- vlist_out(pdf, leader_box, rule_callback_id);
- else
- hlist_out(pdf, leader_box, rule_callback_id);
- doing_leaders = outer_doing_leaders;
- cur.h += leader_wd + lx;
+ cur.h = edge - 10;
+ goto NEXTP;
}
- cur.h = edge - 10;
- goto NEXTP;
}
}
- }
goto MOVE_PAST;
break;
case kern_node:
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h
index dd3775816a3..5d873979a98 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.h
@@ -29,4 +29,6 @@
extern void hlist_out(PDF pdf, halfword this_box, int rule_callback_id);
extern void vlist_out(PDF pdf, halfword this_box, int rule_callback_id);
+extern halfword calculate_width_to_endlink(halfword p, halfword this_box, halfword *leftskip, halfword *rightskip);
+
#endif
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.c b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c
index f7a0df0063a..66f25ecd7c0 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c
@@ -221,22 +221,56 @@ void check_obj_type(PDF pdf, int t, int objnum)
}
}
-void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule, scaled margin)
+/*
+ The next helper is needed for multiline TRT links. Several variants were tried but in the end
+ this one is the most reliable: we calculate the width till we meet an endlink or the end of
+ the line. When we have an inline one, for now we just use the old method and keep the running
+ property (that way we're compatible). For practical purposes this calculation resides in the
+ file that handles the list. By moving the code here instead of dealing with it in lists we
+ handle all rectangles but we'll see where that fails in which case we will have a parameter
+ passed to |set_rect_dimens| and have control per feature, maybe even under parameter control.
+*/
+
+void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule)
{
- /*tex The positions relative to cur: */
+ /*tex
+ The positions relative to cur: |pdf| contains current point on page):
+ */
scaledpos ll, ur, pos_ll, pos_ur;
posstructure localpos;
localpos.dir = pdf->posstruct->dir;
- /*tex |pdf| contains current point on page: */
- ll.h = 0;
+
+ halfword lcrap = 0;
+ halfword rcrap = 0;
+ halfword lskip = 0;
+ halfword rskip = 0;
+
+ if (pdf_linking) {
+ /* begin of experiment */
+ if (subtype(p) == pdf_link_data_node) {
+ alt_rule.wd = calculate_width_to_endlink(list_ptr(parent_box), parent_box, &lskip, &rskip);
+ if (pdf->link_stack[pdf->link_stack_ptr].direction == dir_TRT) {
+ alt_rule.wd = -alt_rule.wd;
+ localpos.dir = dir_TRT;
+ lcrap = lskip;
+ } else {
+ lcrap = -lskip;
+ }
+ } else if (subtype(p) == pdf_start_link_node) {
+ alt_rule.wd = calculate_width_to_endlink(p, parent_box, &lskip, &rskip);
+ }
+ /* end of experiment */
+ }
+
+ ll.h = - lcrap - rcrap;
+ if (is_running(alt_rule.wd))
+ ur.h = width(parent_box) - cur.h;
+ else
+ ur.h = alt_rule.wd - lcrap - rcrap;
if (is_running(alt_rule.dp))
ll.v = depth(parent_box) - cur.v;
else
ll.v = alt_rule.dp;
- if (is_running(alt_rule.wd))
- ur.h = width(parent_box) - cur.h;
- else
- ur.h = alt_rule.wd;
if (is_running(alt_rule.ht))
ur.v = -height(parent_box) - cur.v;
else
@@ -257,10 +291,10 @@ void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, sc
pos_ur.h = geturx();
pos_ur.v = getury();
}
- pdf_ann_left(p) = pos_ll.h - margin;
- pdf_ann_bottom(p) = pos_ll.v - margin;
- pdf_ann_right(p) = pos_ur.h + margin;
- pdf_ann_top(p) = pos_ur.v + margin;
+ pdf_ann_left(p) = pos_ll.h;
+ pdf_ann_bottom(p) = pos_ll.v;
+ pdf_ann_right(p) = pos_ur.h;
+ pdf_ann_top(p) = pos_ur.v;
}
void libpdffinish(PDF pdf)
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h
index 57fdec1ce9a..578b44aa778 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.h
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.h
@@ -108,7 +108,7 @@ extern void check_obj_exists(PDF pdf, int objnum);
extern void check_obj_type(PDF pdf, int t, int objnum);
extern int pdf_get_obj(PDF pdf, int t, int i, boolean byname);
extern int pdf_create_obj(PDF pdf, int t, int i);
-extern void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule, scaled margin);
+extern void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule);
extern void libpdffinish(PDF);
# define set_width(A,B) width(A)=(B)
@@ -143,6 +143,7 @@ typedef enum {
c_pdf_omit_charset,
c_pdf_omit_infodict,
c_pdf_omit_mediabox,
+ c_pdf_linking,
} pdf_backend_counters ;
typedef enum {
@@ -195,6 +196,7 @@ extern int pdf_cur_form;
# define pdf_omit_infodict get_tex_extension_count_register(c_pdf_omit_infodict)
# define pdf_omit_mediabox get_tex_extension_count_register(c_pdf_omit_mediabox)
# define pdf_recompress get_tex_extension_count_register(c_pdf_recompress)
+# define pdf_linking get_tex_extension_count_register(c_pdf_linking)
# define pdf_h_origin get_tex_extension_dimen_register(d_pdf_h_origin)
# define pdf_v_origin get_tex_extension_dimen_register(d_pdf_v_origin)
@@ -221,6 +223,7 @@ extern int pdf_cur_form;
# define set_pdf_omit_mediabox(i) set_tex_extension_count_register(c_pdf_omit_mediabox,i)
# define set_pdf_gen_tounicode(i) set_tex_extension_count_register(c_pdf_gen_tounicode,i)
# define set_pdf_recompress(i) set_tex_extension_count_register(c_pdf_recompress,i)
+# define set_pdf_linking(i) set_tex_extension_count_register(c_pdf_linking,i)
# define set_pdf_decimal_digits(i) set_tex_extension_count_register(c_pdf_decimal_digits,i)
# define set_pdf_pk_resolution(i) set_tex_extension_count_register(c_pdf_pk_resolution,i)
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.c b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.c
index 20cc7bf0a45..27dbc557435 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.c
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.c
@@ -76,7 +76,8 @@ void do_thread(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
alt_rule.wd = width(p);
alt_rule.ht = height(p);
alt_rule.dp = depth(p);
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_thread_margin);
+ pdf_ann_margin(p) = pdf_thread_margin;
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
append_bead(pdf, p);
pdf->last_thread = p;
}
@@ -99,7 +100,7 @@ void append_thread(PDF pdf, halfword parent_box, scaledpos cur)
alt_rule.wd = width(p);
alt_rule.ht = height(p);
alt_rule.dp = depth(p);
- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_thread_margin);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule);
append_bead(pdf, p);
pdf->last_thread = p;
}
@@ -115,13 +116,13 @@ void end_thread(PDF pdf, halfword p)
switch (pdf->posstruct->dir) {
case dir_TLT:
case dir_TRT:
- pdf_ann_bottom(pdf->last_thread) = pos.v - pdf_thread_margin;
+ pdf_ann_bottom(pdf->last_thread) = pos.v;
break;
case dir_LTL:
- pdf_ann_right(pdf->last_thread) = pos.h + pdf_thread_margin;
+ pdf_ann_right(pdf->last_thread) = pos.h;
break;
case dir_RTT:
- pdf_ann_left(pdf->last_thread) = pos.h - pdf_thread_margin;
+ pdf_ann_left(pdf->last_thread) = pos.h;
break;
default:
formatted_warning("pdf backend","forcing bad dir %i to TLT in end tread",pdf->posstruct->dir);
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h
index f9e1d3ba347..d724d1c3492 100644
--- a/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdftypes.h
@@ -190,6 +190,8 @@ typedef struct pdf_link_stack_record {
int ref_link_node; /* points to original |pdf_start_link_node|, or a
copy of |link_node| created by |append_link| in
case of multi-line link */
+ int direction;
+ int count;
} pdf_link_stack_record;
/* types of objects */
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
index a5549deb963..b65efe7b8bc 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
@@ -876,9 +876,9 @@ typedef enum {
# define pdf_obj_objnum(a) vinfo((a) + 2)
-# define pdf_annot_node_size 8
-# define pdf_dest_node_size 8
-# define pdf_thread_node_size 8
+# define pdf_annot_node_size 9 /* all need the same size, rect margin related ! */
+# define pdf_dest_node_size 9
+# define pdf_thread_node_size 9
/*
when a whatsit node representing annotation is created, words |1..3| are
@@ -895,6 +895,7 @@ typedef enum {
# define pdf_ann_top(a) varmem[(a) + 3].cint
# define pdf_ann_right(a) varmem[(a) + 4].cint
# define pdf_ann_bottom(a) varmem[(a) + 5].cint
+# define pdf_ann_margin(a) varmem[(a) + 8].cint /* so all need to have the same size */
# define pdf_literal_data(a) vlink((a)+2)
# define pdf_literal_mode(a) type((a)+2)
diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.c b/Build/source/texk/web2c/luatexdir/tex/textoken.c
index b6f8bbb8c7c..4abe6377b55 100644
--- a/Build/source/texk/web2c/luatexdir/tex/textoken.c
+++ b/Build/source/texk/web2c/luatexdir/tex/textoken.c
@@ -2619,10 +2619,11 @@ static int do_variable_pdf(halfword c)
else if (scan_keyword("pkfixeddpi")) { do_variable_backend_int(c_pdf_pk_fixed_dpi); }
else if (scan_keyword("suppressoptionalinfo")) { do_variable_backend_int(c_pdf_suppress_optional_info); }
else if (scan_keyword("omitcidset")) { do_variable_backend_int(c_pdf_omit_cidset); }
+ else if (scan_keyword("recompress")) { do_variable_backend_int(c_pdf_recompress); }
else if (scan_keyword("omitcharset")) { do_variable_backend_int(c_pdf_omit_charset); }
else if (scan_keyword("omitinfodict")) { do_variable_backend_int(c_pdf_omit_infodict); }
else if (scan_keyword("omitmediabox")) { do_variable_backend_int(c_pdf_omit_mediabox); }
- else if (scan_keyword("recompress")) { do_variable_backend_int(c_pdf_recompress); }
+ else if (scan_keyword("linking")) { do_variable_backend_int(c_pdf_linking); }
else if (scan_keyword("horigin")) { do_variable_backend_dimen(d_pdf_h_origin); }
else if (scan_keyword("vorigin")) { do_variable_backend_dimen(d_pdf_v_origin); }