From 200c502201305b99e3aaf9ac87e401013991d192 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 19 Sep 2022 10:10:17 +0200 Subject: [PATCH 1/4] GKS: use round line caps for polyline/fillarea --- lib/gks/pdf.c | 2 +- lib/gks/plugin/aggplugin.cxx | 4 +++- lib/gks/plugin/cairoplugin.c | 10 +++++++--- lib/gks/plugin/gsplugin.c | 7 ++----- lib/gks/plugin/pgfplugin.c | 2 +- lib/gks/plugin/qtplugin_impl.cxx | 4 ++-- lib/gks/plugin/svgplugin.c | 10 +++++----- lib/gks/ps.c | 7 ++----- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/gks/pdf.c b/lib/gks/pdf.c index 9d4e49ed4..5432db0be 100644 --- a/lib/gks/pdf.c +++ b/lib/gks/pdf.c @@ -87,7 +87,7 @@ typedef unsigned long uLong; #define pdf_curveto(p) pdf_printf(p->content, "c\n") #define pdf_setdash(p, dash) pdf_printf(p->content, "%s 0 d\n", dash) -#define pdf_setlinewidth(p, width) pdf_printf(p->content, "0 J 1 j %s w\n", pdf_double(width)) +#define pdf_setlinewidth(p, width) pdf_printf(p->content, "1 J 1 j %s w\n", pdf_double(width)) #define pdf_text(p, xorg, yorg, text) \ pdf_printf(p->content, "BT\n/F%d %d Tf\n%.2f %.2f Td\n(%s) Tj\nET\n", p->font, p->pt, xorg, yorg, text) diff --git a/lib/gks/plugin/aggplugin.cxx b/lib/gks/plugin/aggplugin.cxx index 669af80f9..407fbb181 100644 --- a/lib/gks/plugin/aggplugin.cxx +++ b/lib/gks/plugin/aggplugin.cxx @@ -674,6 +674,8 @@ static void fill_routine(int n, double *px, double *py, int tnr) else { p->stroke.width(p->linewidth); + p->stroke.line_cap(agg::butt_cap); + p->stroke.line_join(agg::round_join); p->stroke_col = agg::rgba(p->rgb[p->color][0], p->rgb[p->color][1], p->rgb[p->color][2], p->transparency); stroke_path(p->path, true); } @@ -864,7 +866,7 @@ static void polymarker(int n, const double *px, const double *py) static void fillarea(int n, double *px, double *py) { - p->linewidth = p->nominal_size; + p->linewidth = gkss->bwidth * p->nominal_size; p->color = gkss->asf[12] ? gkss->facoli : 1; p->rasterizer.filling_rule(agg::fill_even_odd); diff --git a/lib/gks/plugin/cairoplugin.c b/lib/gks/plugin/cairoplugin.c index 837b92729..9f93d70e3 100644 --- a/lib/gks/plugin/cairoplugin.c +++ b/lib/gks/plugin/cairoplugin.c @@ -483,7 +483,7 @@ static void line_routine(int n, double *px, double *py, int linetype, int tnr) seg_xform(&x, &y); NDC_to_DC(x, y, x0, y0); - cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(p->cr, CAIRO_LINE_JOIN_ROUND); set_line_width(p->linewidth); @@ -591,7 +591,11 @@ static void fillarea(int n, double *px, double *py) { int fl_color; - p->linewidth = p->nominal_size; + p->linewidth = gkss->bwidth * p->nominal_size; + set_line_width(p->linewidth); + + cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join(p->cr, CAIRO_LINE_JOIN_ROUND); fl_color = gkss->asf[12] ? gkss->facoli : 1; set_color(fl_color); @@ -617,7 +621,7 @@ static void polyline(int n, double *px, double *py) ln_width = gkss->asf[1] ? gkss->lwidth : 1; ln_color = gkss->asf[2] ? gkss->plcoli : 1; - cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(p->cr, CAIRO_LINE_JOIN_ROUND); p->linewidth = ln_width * p->nominal_size; set_line_width(p->linewidth); diff --git a/lib/gks/plugin/gsplugin.c b/lib/gks/plugin/gsplugin.c index 7105c67f2..2cda9f864 100644 --- a/lib/gks/plugin/gsplugin.c +++ b/lib/gks/plugin/gsplugin.c @@ -1188,7 +1188,7 @@ static void ps_init(int *pages) set_color(-1, p->wtype); set_foreground(-1, p->wtype); - packb("0 setlinecap 1 setlinejoin"); + packb("1 setlinecap 1 setlinejoin"); set_linewidth(-1.0); set_markersize(-1.0); packb("0 ma"); @@ -1779,15 +1779,12 @@ static void draw_lines(int n, double *px, double *py, int *attributes) p->green[ln_color] = ((rgba >> 8) & 0xff) / 255.0; p->blue[ln_color] = ((rgba >> 16) & 0xff) / 255.0; - packb("np 1 setlinecap"); set_linewidth(line_width); set_color(-ln_color, p->wtype); snprintf(buffer, 50, "%d %d m %d %d l sk", xim1, yim1, xi, yi); packb(buffer); } - - packb("0 setlinecap"); } static void set_bordercolor(int wtype) @@ -2276,7 +2273,7 @@ void gks_gsplugin(int fctid, int dx, int dy, int dimx, int *ia, int lr1, double style = gkss->asf[10] ? gkss->ints : predef_ints[gkss->findex - 1]; color = gkss->asf[12] ? gkss->facoli : 1; set_color(color, p->wtype); - set_linewidth(1.0); + set_linewidth(gkss->bwidth); if (gkss->clip_tnr != 0) { packb("gsave"); diff --git a/lib/gks/plugin/pgfplugin.c b/lib/gks/plugin/pgfplugin.c index a76190d9c..1c9ea403f 100644 --- a/lib/gks/plugin/pgfplugin.c +++ b/lib/gks/plugin/pgfplugin.c @@ -572,7 +572,7 @@ static void fillarea(int n, double *px, double *py) int fl_color; fl_color = gkss->asf[12] ? gkss->facoli : 1; - p->linewidth = p->nominal_size; + p->linewidth = gkss->bwidth * p->nominal_size; pgf_printf(p->stream, "\\definecolor{mycolor}{HTML}{%s}\n", p->rgb[fl_color]); diff --git a/lib/gks/plugin/qtplugin_impl.cxx b/lib/gks/plugin/qtplugin_impl.cxx index bb9375ac9..f48f3b7c1 100644 --- a/lib/gks/plugin/qtplugin_impl.cxx +++ b/lib/gks/plugin/qtplugin_impl.cxx @@ -423,7 +423,7 @@ static void polyline(int n, double *px, double *py) p->pixmap->setPen(pen); } else - p->pixmap->setPen(QPen(transparent_color, ln_width, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin)); + p->pixmap->setPen(QPen(transparent_color, ln_width, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); line_routine(n, px, py, ln_type, gkss->cntnr); @@ -771,7 +771,7 @@ static void fillarea(int n, double *px, double *py) if (fl_inter == GKS_K_INTSTYLE_HOLLOW) { p->pixmap->setPen( - QPen(transparent_color, gkss->bwidth * p->nominal_size, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin)); + QPen(transparent_color, gkss->bwidth * p->nominal_size, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); line_routine(n, px, py, DrawBorder, gkss->cntnr); } else if (fl_inter == GKS_K_INTSTYLE_SOLID) diff --git a/lib/gks/plugin/svgplugin.c b/lib/gks/plugin/svgplugin.c index 4035a7510..3d5364686 100644 --- a/lib/gks/plugin/svgplugin.c +++ b/lib/gks/plugin/svgplugin.c @@ -559,7 +559,7 @@ static void stroke(void) svg_printf(p->stream, "rect_index, p->rgb[p->color][0], p->rgb[p->color][1], p->rgb[p->color][2], p->linewidth, p->transparency); @@ -612,7 +612,7 @@ static void line_routine(int n, double *px, double *py, int linetype, int tnr) svg_printf(p->stream, "rect_index, p->rgb[p->color][0], p->rgb[p->color][1], p->rgb[p->color][2], p->linewidth, p->transparency); @@ -1252,7 +1252,7 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) break; case 'S': /* stroke */ svg_printf(p->stream, - "\" fill=\"none\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-linecap=\"butt\" " + "\" fill=\"none\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-linecap=\"round\" " "stroke-linejoin=\"round\" stroke-width=\"%g\" />", p->rgb[gkss->bcoli][0], p->rgb[gkss->bcoli][1], p->rgb[gkss->bcoli][2], p->transparency, gkss->bwidth * p->nominal_size); @@ -1260,7 +1260,7 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) break; case 's': /* close and stroke */ svg_printf(p->stream, - "Z\" fill=\"none\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-linecap=\"butt\" " + "Z\" fill=\"none\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-linecap=\"round\" " "stroke-linejoin=\"round\" stroke-width=\"%g\" />", p->rgb[gkss->bcoli][0], p->rgb[gkss->bcoli][1], p->rgb[gkss->bcoli][2], p->transparency, gkss->bwidth * p->nominal_size); @@ -1278,7 +1278,7 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) case 'F': /* fill and stroke */ svg_printf(p->stream, "Z\" fill=\"#%02x%02x%02x\" fill-rule=\"evenodd\" fill-opacity=\"%g\" stroke=\"#%02x%02x%02x\" " - "stroke-opacity=\"%g\" stroke-width=\"%g\" />", + "stroke-opacity=\"%g\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"%g\" />", p->rgb[p->color][0], p->rgb[p->color][1], p->rgb[p->color][2], p->transparency, p->rgb[gkss->bcoli][0], p->rgb[gkss->bcoli][1], p->rgb[gkss->bcoli][2], p->transparency, gkss->bwidth * p->nominal_size); diff --git a/lib/gks/ps.c b/lib/gks/ps.c index 56469cb3f..74cdddc9f 100644 --- a/lib/gks/ps.c +++ b/lib/gks/ps.c @@ -1140,7 +1140,7 @@ static void ps_init(int *pages) set_color(-1, p->wtype); set_foreground(-1, p->wtype); - packb("0 setlinecap 1 setlinejoin"); + packb("1 setlinecap 1 setlinejoin"); set_linewidth(-1.0); set_markersize(-1.0); packb("0 ma"); @@ -1728,15 +1728,12 @@ static void draw_lines(int n, double *px, double *py, int *attributes) p->green[ln_color] = ((rgba >> 8) & 0xff) / 255.0; p->blue[ln_color] = ((rgba >> 16) & 0xff) / 255.0; - packb("np 1 setlinecap"); set_linewidth(line_width); set_color(-ln_color, p->wtype); snprintf(buffer, 50, "%d %d m %d %d l sk", xim1, yim1, xi, yi); packb(buffer); } - - packb("0 setlinecap"); } static void set_bordercolor(int wtype) @@ -2100,7 +2097,7 @@ void gks_drv_ps(int fctid, int dx, int dy, int dimx, int *ia, int lr1, double *r style = gkss->asf[10] ? gkss->ints : predef_ints[gkss->findex - 1]; color = gkss->asf[12] ? gkss->facoli : 1; set_color(color, p->wtype); - set_linewidth(1.0); + set_linewidth(gkss->bwidth); if (gkss->clip_tnr != 0) { packb("gsave"); From cffaf01fd0ef8e2d0226dce303ed5126bf3c9599 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 19 Sep 2022 16:17:34 +0200 Subject: [PATCH 2/4] Fix bug in polymarker3d function --- lib/gr/gr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gr/gr.c b/lib/gr/gr.c index c8317f1bc..bd6ca0b00 100644 --- a/lib/gr/gr.c +++ b/lib/gr/gr.c @@ -6182,7 +6182,7 @@ void gr_polymarker3d(int n, double *px, double *py, double *pz) zpoint[i] = point[i].z; } - if (m > 0) gr_polymarker(m, xpoint, ypoint); + if (m > 0) gks_polymarker(m, xpoint, ypoint); if (flag_graphics) { From 2672dfef9cf59d92761d2e72d736db6845818e88 Mon Sep 17 00:00:00 2001 From: Daniel Kaiser Date: Mon, 19 Sep 2022 16:50:17 +0200 Subject: [PATCH 3/4] GKS: use round line caps for polyline/fillarea --- lib/gks/plugin/aggplugin.cxx | 7 ++++++- lib/gks/plugin/cairoplugin.c | 3 ++- lib/gks/plugin/pgfplugin.c | 11 ++++++----- lib/gks/quartz/GKSView.m | 6 +++--- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/gks/plugin/aggplugin.cxx b/lib/gks/plugin/aggplugin.cxx index 407fbb181..8132ddd35 100644 --- a/lib/gks/plugin/aggplugin.cxx +++ b/lib/gks/plugin/aggplugin.cxx @@ -473,7 +473,9 @@ static void fill_path(agg::path_storage &path) p->rasterizer.reset(); p->rasterizer.add_path(p->curve); p->renderer_aa.color(p->fill_col); + p->rasterizer.filling_rule(agg::fill_even_odd); agg::render_scanlines(p->rasterizer, p->scanline, p->renderer_aa); + p->rasterizer.filling_rule(agg::fill_non_zero); p->path.remove_all(); } @@ -496,7 +498,9 @@ static void fill_stroke_path(agg::path_storage &path) p->rasterizer.reset(); p->rasterizer.add_path(p->curve); p->renderer_aa.color(p->fill_col); + p->rasterizer.filling_rule(agg::fill_even_odd); agg::render_scanlines(p->rasterizer, p->scanline, p->renderer_aa); + p->rasterizer.filling_rule(agg::fill_non_zero); p->rasterizer.reset(); p->rasterizer.add_path(p->stroke); p->renderer_aa.color(p->stroke_col); @@ -673,8 +677,9 @@ static void fill_routine(int n, double *px, double *py, int tnr) } else { + p->rasterizer.filling_rule(agg::fill_non_zero); p->stroke.width(p->linewidth); - p->stroke.line_cap(agg::butt_cap); + p->stroke.line_cap(agg::round_cap); p->stroke.line_join(agg::round_join); p->stroke_col = agg::rgba(p->rgb[p->color][0], p->rgb[p->color][1], p->rgb[p->color][2], p->transparency); stroke_path(p->path, true); diff --git a/lib/gks/plugin/cairoplugin.c b/lib/gks/plugin/cairoplugin.c index 9f93d70e3..2a7225ce3 100644 --- a/lib/gks/plugin/cairoplugin.c +++ b/lib/gks/plugin/cairoplugin.c @@ -1784,8 +1784,9 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) GKS_UNUSED(n); cairo_new_path(p->cr); - cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(p->cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_fill_rule(p->cr, CAIRO_FILL_RULE_EVEN_ODD); set_line_width(gkss->bwidth * p->nominal_size); j = 0; diff --git a/lib/gks/plugin/pgfplugin.c b/lib/gks/plugin/pgfplugin.c index 1c9ea403f..3a51c8c2d 100644 --- a/lib/gks/plugin/pgfplugin.c +++ b/lib/gks/plugin/pgfplugin.c @@ -1075,11 +1075,11 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) int i, j; double x[3], y[3], w, h, a1, a2; double cur_x = 0, cur_y = 0, start_x = 0, start_y = 0; - int line_width; + double line_width; PGF_stream *buf; GKS_UNUSED(n); - line_width = nint(gkss->bwidth); + line_width = gkss->bwidth * p->nominal_size; if (line_width < 1) line_width = 0; pgf_printf(p->stream, "\\definecolor{pathstroke}{HTML}{%s}\n", p->rgb[gkss->bcoli]); @@ -1214,8 +1214,9 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) break; case 'F': /* fill and stroke */ pgf_printf(buf, "-- cycle;\n"); - pgf_printf(p->stream, "\\filldraw[color=pathstroke, fill=pathfill, line width=%fpt, opacity=%f] ", line_width, - p->transparency); + pgf_printf(p->stream, + "\\filldraw[color=pathstroke, fill=pathfill, even odd rule, line width=%fpt, opacity=%f] ", + line_width, p->transparency); pgf_memcpy(p->stream, (char *)buf->buffer, buf->length); pgf_clear_stream(buf); cur_x = start_x; @@ -1223,7 +1224,7 @@ static void draw_path(int n, double *px, double *py, int nc, int *codes) break; case 'f': /* fill */ pgf_printf(buf, "-- cycle;\n"); - pgf_printf(p->stream, "\\fill[fill=pathfill, opacity=%f] ", p->transparency); + pgf_printf(p->stream, "\\fill[fill=pathfill, even odd rule, opacity=%f] ", p->transparency); pgf_memcpy(p->stream, (char *)buf->buffer, buf->length); pgf_clear_stream(buf); cur_x = start_x; diff --git a/lib/gks/quartz/GKSView.m b/lib/gks/quartz/GKSView.m index 55c0acba6..feed4fb90 100644 --- a/lib/gks/quartz/GKSView.m +++ b/lib/gks/quartz/GKSView.m @@ -1608,7 +1608,7 @@ - (void)draw_path:(int)n:(double *)px:(double *)py:(int)nc:(int *)codes begin_context(context); - CGContextSetLineCap(context, kCGLineCapButt); + CGContextSetLineCap(context, kCGLineCapRound); CGContextSetLineJoin(context, kCGLineJoinRound); CGContextSetLineWidth(context, gkss->bwidth * p->nominal_size); [self set_stroke_color:gkss->bcoli:context]; @@ -1746,13 +1746,13 @@ - (void)draw_path:(int)n:(double *)px:(double *)py:(int)nc:(int *)codes CGContextClosePath(context); cur_x = start_x; cur_y = start_y; - CGContextDrawPath(context, kCGPathFill); + CGContextDrawPath(context, kCGPathEOFill); break; case 'F': CGContextClosePath(context); cur_x = start_x; cur_y = start_y; - CGContextDrawPath(context, kCGPathFillStroke); + CGContextDrawPath(context, kCGPathEOFillStroke); break; case 'Z': CGContextClosePath(context); From 0a0989e17e7c62c3666168a9130e109ea0aeeede Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 20 Sep 2022 09:40:06 +0200 Subject: [PATCH 4/4] Fix Postscript image bug --- lib/gks/ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gks/ps.c b/lib/gks/ps.c index 74cdddc9f..b85791854 100644 --- a/lib/gks/ps.c +++ b/lib/gks/ps.c @@ -1328,7 +1328,7 @@ static void cell_array(double xmin, double xmax, double ymin, double ymax, int d else if (swap == 2) snprintf(buffer, 100, "/ImageMatrix [%d 0 0 %d 0 0]", dx, dy); else - snprintf(buffer, 100, "/ImageMatrix [-%d 0 %d %d 0 0]", dx, dx, dy); + snprintf(buffer, 100, "/ImageMatrix [-%d 0 0 %d %d 0]", dx, dy, dx); packb(buffer); snprintf(buffer, 100, "/DataSource Data /BitsPerComponent 8 /Decode [0 1%s]", wtype % 2 == 0 ? " 0 1 0 1" : "");