From 475c30a50b1db712ca9466981cb52397fd5e461d Mon Sep 17 00:00:00 2001 From: replabrobin Date: Sat, 24 Jun 2023 08:48:39 +0100 Subject: [PATCH 1/2] use fillMode directly instead of _fillRule and reportlab monkeypatch --- .gitignore | 3 +- svglib/svglib.py | 44 +++--------------------- tests/samples/misc/fill-rule-evenodd.svg | 42 ++++++++++++++++++++++ tests/samples/misc/fill-rule-nonzero.svg | 42 ++++++++++++++++++++++ tests/test_basic.py | 2 +- 5 files changed, 92 insertions(+), 41 deletions(-) create mode 100644 tests/samples/misc/fill-rule-evenodd.svg create mode 100644 tests/samples/misc/fill-rule-nonzero.svg diff --git a/.gitignore b/.gitignore index bf2b547..6cbaba0 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,8 @@ docs/_build env/ .workon dist/ -tests/samples/misc/*-svglib.pdf +tests/samples/misc/*.pdf +tests/samples/others/*.pdf tests/samples/wikipedia/flags tests/samples/wikipedia/symbols tests/samples/W3C_SVG_12_TinyTestSuite.tar.gz diff --git a/svglib/svglib.py b/svglib/svglib.py index 727b669..7dcf216 100755 --- a/svglib/svglib.py +++ b/svglib/svglib.py @@ -24,6 +24,7 @@ import tempfile import shlex import shutil +import sys from collections import defaultdict, namedtuple from reportlab.pdfbase.pdfmetrics import stringWidth @@ -1320,7 +1321,7 @@ def applyStyleOnShape(self, shape, node, only_explicit=False): mappingN = ( (["fill"], "fillColor", "convertColor", ["black"]), (["fill-opacity"], "fillOpacity", "convertOpacity", [1]), - (["fill-rule"], "_fillRule", "convertFillRule", ["nonzero"]), + (["fill-rule"], "fillMode", "convertFillRule", ["nonzero"]), (["stroke"], "strokeColor", "convertColor", ["none"]), (["stroke-width"], "strokeWidth", "convertLength", ["1"]), (["stroke-opacity"], "strokeOpacity", "convertOpacity", [1]), @@ -1378,7 +1379,9 @@ def applyStyleOnShape(self, shape, node, only_explicit=False): meth = getattr(ac, func) setattr(shape, rlgAttr, meth(*svgAttrValues)) except (AttributeError, KeyError, ValueError): - logger.debug("Exception during applyStyleOnShape") + logger.debug("applyStyleOnShape setattr(%s,%r,%s(*%r)) caused %s exception" % ( + shape.__class__.__name__,rlgAttr,meth.__name__,svgAttrValues, + sys.exc_info()[0].__class__.__name__)) if getattr(shape, 'fillOpacity', None) is not None and shape.fillColor: shape.fillColor.alpha = shape.fillOpacity if getattr(shape, 'strokeWidth', None) == 0: @@ -1507,40 +1510,3 @@ def copy_shape_properties(source_shape, dest_shape): setattr(dest_shape, prop, val) except AttributeError: pass - - -def monkeypatch_reportlab(): - """ - https://bitbucket.org/rptlab/reportlab/issues/95/ - ReportLab always use 'Even-Odd' filling mode for paths, this patch forces - RL to honor the path fill rule mode (possibly 'Non-Zero Winding') instead. - """ - from reportlab.pdfgen.canvas import Canvas - from reportlab.graphics import shapes - - original_renderPath = shapes._renderPath - - def patchedRenderPath(path, drawFuncs, **kwargs): - # Patched method to transfer fillRule from Path to PDFPathObject - # Get back from bound method to instance - try: - drawFuncs[0].__self__.fillMode = path._fillRule - except AttributeError: - pass - return original_renderPath(path, drawFuncs, **kwargs) - shapes._renderPath = patchedRenderPath - - original_drawPath = Canvas.drawPath - - def patchedDrawPath(self, path, **kwargs): - current = self._fillMode - if hasattr(path, 'fillMode'): - self._fillMode = path.fillMode - else: - self._fillMode = FILL_NON_ZERO - original_drawPath(self, path, **kwargs) - self._fillMode = current - Canvas.drawPath = patchedDrawPath - - -monkeypatch_reportlab() diff --git a/tests/samples/misc/fill-rule-evenodd.svg b/tests/samples/misc/fill-rule-evenodd.svg new file mode 100644 index 0000000..2803bb4 --- /dev/null +++ b/tests/samples/misc/fill-rule-evenodd.svg @@ -0,0 +1,42 @@ + + Fill-rule shapes, with evenodd fill + + + one sub-path + + + crossing + + + reversing + + + two sub-paths + + + same-direction + + + opposite + + diff --git a/tests/samples/misc/fill-rule-nonzero.svg b/tests/samples/misc/fill-rule-nonzero.svg new file mode 100644 index 0000000..63ff23b --- /dev/null +++ b/tests/samples/misc/fill-rule-nonzero.svg @@ -0,0 +1,42 @@ + + Fill-rule shapes, with nonzero fill + + + one sub-path + + + crossing + + + reversing + + + two sub-paths + + + same-direction + + + opposite + + diff --git a/tests/test_basic.py b/tests/test_basic.py index bc3d319..728cc48 100755 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -457,7 +457,7 @@ def test_fillrule(self): node = minimal_svg_node('') poly = Polygon() converter.applyStyleOnShape(poly, node) - assert poly._fillRule == FILL_EVEN_ODD + assert poly.fillMode == FILL_EVEN_ODD def test_stroke(self): converter = svglib.Svg2RlgShapeConverter(None) From a8539adb6da39c14e18a4439c96743f37888d49c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 24 Jun 2023 07:57:48 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- svglib/svglib.py | 2 +- tests/samples/misc/fill-rule-evenodd.svg | 16 ++++++++-------- tests/samples/misc/fill-rule-nonzero.svg | 16 ++++++++-------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/svglib/svglib.py b/svglib/svglib.py index 7dcf216..b2cf86b 100755 --- a/svglib/svglib.py +++ b/svglib/svglib.py @@ -1379,7 +1379,7 @@ def applyStyleOnShape(self, shape, node, only_explicit=False): meth = getattr(ac, func) setattr(shape, rlgAttr, meth(*svgAttrValues)) except (AttributeError, KeyError, ValueError): - logger.debug("applyStyleOnShape setattr(%s,%r,%s(*%r)) caused %s exception" % ( + logger.debug("applyStyleOnShape setattr({},{!r},{}(*{!r})) caused {} exception".format( shape.__class__.__name__,rlgAttr,meth.__name__,svgAttrValues, sys.exc_info()[0].__class__.__name__)) if getattr(shape, 'fillOpacity', None) is not None and shape.fillColor: diff --git a/tests/samples/misc/fill-rule-evenodd.svg b/tests/samples/misc/fill-rule-evenodd.svg index 2803bb4..da4fad1 100644 --- a/tests/samples/misc/fill-rule-evenodd.svg +++ b/tests/samples/misc/fill-rule-evenodd.svg @@ -15,27 +15,27 @@ text { one sub-path - - crossing - reversing two sub-paths - - same-direction - opposite diff --git a/tests/samples/misc/fill-rule-nonzero.svg b/tests/samples/misc/fill-rule-nonzero.svg index 63ff23b..543ab54 100644 --- a/tests/samples/misc/fill-rule-nonzero.svg +++ b/tests/samples/misc/fill-rule-nonzero.svg @@ -15,27 +15,27 @@ text { one sub-path - - crossing - reversing two sub-paths - - same-direction - opposite