From 1728f718973403eeb3c0c451cf71a3b485cf0651 Mon Sep 17 00:00:00 2001 From: Esteban82 Date: Tue, 15 Sep 2026 14:48:53 -0300 Subject: [PATCH 1/2] pstext: shrink the outer rectangle used to clip -D+v leader lines by the text box MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A near-infinite placeholder rectangle (±10,000,000 units) was used to build the even-odd clip path that cuts the leader line where it enters the text box. Ghostscript's pdfwrite device (used by psconvert for PDF/EPS output) miscomputes that clip when the outer/inner rectangle size ratio is this extreme, dropping the entire line instead of just the part inside the box. Size the outer rectangle from the actual text box and line length instead. Co-Authored-By: Claude Sonnet 5 --- src/postscriptlight.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/postscriptlight.c b/src/postscriptlight.c index 520fea61216..a6f748e4482 100644 --- a/src/postscriptlight.c +++ b/src/postscriptlight.c @@ -4086,8 +4086,12 @@ int PSL_plotline_clipped_by_textbox(struct PSL_CTRL *PSL, double x0, double y0, PSL_defunits(PSL, "PSL_dx", offset[0]); PSL_defunits(PSL, "PSL_dy", offset[1]); - /* Build even-odd clip path: huge outer rectangle + textbox rectangle (the hole) */ - PSL_command(PSL, "N -10000000 -10000000 M 20000000 0 D 0 20000000 D -20000000 0 D P\n"); + /* Build even-odd clip path: outer rectangle + textbox rectangle (the hole). The outer + * rectangle just needs to comfortably enclose both the textbox hole and the full line; + * an astronomically large placeholder standing for "infinity" makes some PDF converters + * (e.g., Ghostscript's pdfwrite) miscompute the clip and drop the entire line (#9209). */ + PSL_command(PSL, "/PSL_obx PSL_dim_w PSL_dim_h add PSL_dx add PSL_dy add %d add def\n", abs(ixl) + abs(iyl) + 100); + PSL_command(PSL, "N PSL_obx neg PSL_obx neg M PSL_obx 2 mul 0 D 0 PSL_obx 2 mul D PSL_obx 2 mul neg 0 D P\n"); PSL_command(PSL, "%s PSL_dim_x0 add PSL_dx sub %s PSL_dim_d add PSL_dy sub M ", jx[x_just], jy[y_just]); PSL_command(PSL, "PSL_dim_x1 PSL_dim_x0 sub PSL_dx 2 mul add 0 D "); From bff94f6dbe665c87bf14bbe430ab7ef7373a9281 Mon Sep 17 00:00:00 2001 From: Esteban82 Date: Tue, 15 Sep 2026 16:09:08 -0300 Subject: [PATCH 2/2] pstext: make the leader-line clip bound unconditionally monotone The outer rectangle summed PSL_dim_h signed, but that value is negative for text sitting entirely below the baseline (an all-subscript label such as "@-,@-"), and PSL_dx/PSL_dy are negative for a negative -C. A signed sum could then shrink the rectangle below the hole it has to contain: for 200p all-subscript text the bound came out 183 units against a hole reaching 1175, leaving the two disjoint, so even-odd yielded outer OR hole and the leader line was drawn through the label unclipped. Sum absolute values instead, so the bound depends only on the magnitudes of the same quantities the hole is built from and cannot shrink. Co-Authored-By: Claude Opus 5 --- src/postscriptlight.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/postscriptlight.c b/src/postscriptlight.c index a6f748e4482..8c5aff5fb04 100644 --- a/src/postscriptlight.c +++ b/src/postscriptlight.c @@ -4087,10 +4087,15 @@ int PSL_plotline_clipped_by_textbox(struct PSL_CTRL *PSL, double x0, double y0, PSL_defunits(PSL, "PSL_dy", offset[1]); /* Build even-odd clip path: outer rectangle + textbox rectangle (the hole). The outer - * rectangle just needs to comfortably enclose both the textbox hole and the full line; - * an astronomically large placeholder standing for "infinity" makes some PDF converters - * (e.g., Ghostscript's pdfwrite) miscompute the clip and drop the entire line (#9209). */ - PSL_command(PSL, "/PSL_obx PSL_dim_w PSL_dim_h add PSL_dx add PSL_dy add %d add def\n", abs(ixl) + abs(iyl) + 100); + * rectangle just needs to enclose both the hole and the whole line; an astronomically + * large placeholder standing for "infinity" makes some PDF converters (e.g. Ghostscript's + * pdfwrite) miscompute the clip and drop the entire line (#9209). Sum absolute values + * only: PSL_dim_h is negative for text sitting entirely below the baseline (all-subscript) + * and PSL_dx|dy for a negative -C, so a signed sum could shrink the rectangle below the + * hole it must contain. PSL_dim_h enters twice since it also bounds the justify shift. */ + PSL_command(PSL, "/PSL_obx PSL_dim_w abs PSL_dim_h abs 2 mul add PSL_dim_d abs add " + "PSL_dim_x0 abs add PSL_dim_x1 abs add PSL_dx abs add PSL_dy abs add %d add def\n", + abs(ixl) + abs(iyl) + 100); PSL_command(PSL, "N PSL_obx neg PSL_obx neg M PSL_obx 2 mul 0 D 0 PSL_obx 2 mul D PSL_obx 2 mul neg 0 D P\n"); PSL_command(PSL, "%s PSL_dim_x0 add PSL_dx sub %s PSL_dim_d add PSL_dy sub M ", jx[x_just], jy[y_just]);