# HG changeset patch # User Markus Mützel # Date 1675192272 -3600 # Node ID 8825cedf5482afcfe8d5f7e3ea4e7fe5623c45e0 # Parent f812dd8304d982e09c48a2cc688a3a36127500d0# Parent 82128f65258524d6050a6b42d3543a81f647b1db maint: Merge stable to default. diff -r f812dd8304d9 -r 8825cedf5482 scripts/plot/util/print.m --- a/scripts/plot/util/print.m Mon Jan 30 18:55:51 2023 +0100 +++ b/scripts/plot/util/print.m Tue Jan 31 20:11:12 2023 +0100 @@ -157,6 +157,20 @@ ## Caution: If Octave was built against Qt version earlier than 5.13, ## @option{-svgconvert} may lead to inaccurate rendering of image objects. ## +## @item -polymerge +## @itemx -nopolymerge +## @itemx -polymerge-all +## When using the SVG based backend @option{-svgconvert}, faces are rendered +## as triangles. In some cases, some viewers might display fine lines where +## those triangles share an edge. These options control whether all triangles +## that share edges are merged into polygons (@option{-polymerge-all} which +## might take some time for graphics consisting of many triangles -- including +## line markers), only consecutive polygons are merged (@option{-polymerge}), +## or no triangles are merged at all (@option{-no-polymerge}). By default, +## only consecutive triangles sharing an edge are merged, unless the printed +## figure contains patch or surface graphics objects in which case all +## triangles that are sharing an edge are merged. +## ## @item -portrait ## @itemx -landscape ## Specify the orientation of the plot for printed output. @@ -1160,7 +1174,8 @@ cmd = sprintf ('%s - %%s %3.2f "%s" %d "%%s"', ... undo_string_escapes (opts.svgconvert_binary), ... get (0, "screenpixelsperinch"), ... - undo_string_escapes (fullfile (fontdir, "FreeSans.otf")), 1); + undo_string_escapes (fullfile (fontdir, "FreeSans.otf")), + opts.polymerge); if (opts.debug) fprintf ("svgconvert command: '%s'\n", cmd); diff -r f812dd8304d9 -r 8825cedf5482 scripts/plot/util/private/__print_parse_opts__.m --- a/scripts/plot/util/private/__print_parse_opts__.m Mon Jan 30 18:55:51 2023 +0100 +++ b/scripts/plot/util/private/__print_parse_opts__.m Tue Jan 31 20:11:12 2023 +0100 @@ -59,6 +59,7 @@ arg_st.ghostscript.antialiasing_textalphabits = 4; arg_st.ghostscript.antialiasing_graphicsalphabits = 1; arg_st.lpr_binary = __quote_path__ (__find_binary__ ("lpr")); + arg_st.polymerge = 1; arg_st.name = ""; arg_st.orientation = ""; arg_st.pstoedit_binary = __quote_path__ (__find_binary__ ("pstoedit")); @@ -88,6 +89,11 @@ varargin(1) = []; endif + if (! isempty (findall (arg_st.figure, "type", "patch", ... + "-or", "type", "surface"))) + arg_st.polymerge = 2; + endif + for i = 1:numel (varargin) if (! ischar (varargin{i}) && ! iscellstr (varargin{i})) error ("print: input arguments must be a graphics handle or strings."); @@ -127,6 +133,12 @@ arg_st.svgconvert = true; elseif (strcmp (arg, "-nosvgconvert")) arg_st.svgconvert = false; + elseif (strcmp (arg, "-polymerge")) + arg_st.polymerge = 1; + elseif (strcmp (arg, "-nopolymerge")) + arg_st.polymerge = 0; + elseif (strcmp (arg, "-polymerge-all")) + arg_st.polymerge = 2; elseif (strcmp (arg, "-textspecial")) arg_st.special_flag = "textspecial"; elseif (strcmp (arg, "-fillpage")) diff -r f812dd8304d9 -r 8825cedf5482 src/octave-svgconvert.cc --- a/src/octave-svgconvert.cc Mon Jan 30 18:55:51 2023 +0100 +++ b/src/octave-svgconvert.cc Tue Jan 31 20:11:12 2023 +0100 @@ -161,10 +161,12 @@ void reset () { m_polygons.clear (); } - QList reconstruct () + QList reconstruct (int reconstruct_level) { if (m_polygons.isEmpty ()) return QList (); + else if (reconstruct_level < 2) + return m_polygons; // Once a polygon has been merged to another, it is marked unsuded QVector unused; @@ -749,7 +751,7 @@ parent_elt.removeChild (orig.at (ii)); } -void reconstruct_polygons (QDomElement& parent_elt) +void reconstruct_polygons (QDomElement& parent_elt, int reconstruct_level) { QDomNodeList nodes = parent_elt.childNodes (); QColor current_color; @@ -787,7 +789,8 @@ if (color != current_color) { // Reconstruct the previous series of triangles - QList polygons = current_polygon.reconstruct (); + QList polygons + = current_polygon.reconstruct (reconstruct_level); collection.push_back (QPair,QList > (replaced_nodes, polygons)); @@ -806,19 +809,20 @@ { if (current_polygon.count ()) { - QList polygons = current_polygon.reconstruct (); + QList polygons = current_polygon.reconstruct (reconstruct_level); collection.push_back (QPair,QList > (replaced_nodes, polygons)); replaced_nodes.clear (); current_polygon.reset (); } - reconstruct_polygons (elt); + reconstruct_polygons (elt, reconstruct_level); } } // Finish collection.push_back (QPair,QList > - (replaced_nodes, current_polygon.reconstruct ())); + (replaced_nodes, + current_polygon.reconstruct (reconstruct_level))); for (int ii = 0; ii < collection.count (); ii++) replace_polygons (parent_elt, collection[ii].first, collection[ii].second); @@ -876,7 +880,10 @@ * fmt: format of the output file. May be one of pdf or svg\n\ * dpi: device dependent resolution in screen pixel per inch\n\ * font: specify a file name for the default FreeSans font\n\ -* reconstruct: specify whether to reconstruct triangle to polygons (0 or 1)\n\ +* reconstruct: specify whether to reconstruct triangle to polygons\n\ + 0: no reconstruction (merging) of polygons\n\ + 1: merge consecutive triangles if they share an edge\n\ + 2: merge all triangles that share edges (might take a long time)\n\ * outfile: output file name\n"; if (strcmp (argv[1], "-h") == 0) @@ -977,8 +984,9 @@ } // Do basic polygons reconstruction - if (QString (argv[5]).toInt ()) - reconstruct_polygons (root); + int reconstruct_level = QString (argv[5]).toInt (); + if (reconstruct_level) + reconstruct_polygons (root, reconstruct_level); // Add custom properties to SVG add_custom_properties (root);