Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve __repr__ and Viewbox #117

Merged
merged 15 commits into from
Aug 22, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 60 additions & 29 deletions svgelements/svgelements.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
and the Arc can do exact arc calculations if scipy is installed.
"""

SVGELEMENTS_VERSION = "1.5.5"
SVGELEMENTS_VERSION = "1.5.6"
Sophist-UK marked this conversation as resolved.
Show resolved Hide resolved

MIN_DEPTH = 5
ERROR = 1e-12
Expand Down Expand Up @@ -3030,24 +3030,36 @@ def matrix_multiply(m, s):


class Viewbox:
def __init__(self, viewbox, preserve_aspect_ratio=None):
def __init__(self, *args, x=None, y=None, width=None, height=None, preserveAspectRatio=None):
"""
Sophist-UK marked this conversation as resolved.
Show resolved Hide resolved
Viewbox controls the scaling between the drawing size view that is observing that drawing.

:param viewbox: either values or viewbox attribute or a Viewbox object
:param preserve_aspect_ratio: preserveAspectRatio
:param preserveAspectRatio: preserveAspectRatio
"""
self.x = None
self.y = None
self.width = None
self.height = None
self.preserve_aspect_ratio = preserve_aspect_ratio
if isinstance(viewbox, dict):
self.property_by_values(viewbox)
elif isinstance(viewbox, Viewbox):
self.property_by_object(viewbox)
self.x = x
self.y = y
self.width = width
self.height = height
if args and len(args) <= 2:
viewbox = args[0]
if isinstance(viewbox, dict):
self.property_by_values(viewbox)
elif isinstance(viewbox, Viewbox):
self.property_by_object(viewbox)
else:
self.set_viewbox(viewbox)
if len(args) == 2:
preserveAspectRatio = args[1]
elif len(args) == 4:
self.x = float(args[0])
self.y = float(args[1])
self.width = float(args[2])
self.height = float(args[3])
if preserveAspectRatio == SVG_VALUE_NONE:
self.preserveAspectRatio = None
else:
self.set_viewbox(viewbox)
self.preserveAspectRatio = preserveAspectRatio

def __eq__(self, other):
if not isinstance(other, Viewbox):
Expand All @@ -3060,7 +3072,7 @@ def __eq__(self, other):
return False
if self.height != other.height:
return False
return self.preserve_aspect_ratio == other.preserve_aspect_ratio
return self.preserveAspectRatio == other.preserveAspectRatio

def __str__(self):
return "%s %s %s %s" % (
Expand All @@ -3071,21 +3083,33 @@ def __str__(self):
)

def __repr__(self):
return "%s('%s')" % (self.__class__.__name__, str(self))
values = []
if self.x is not None:
values.append("x=%s" % Length.str(self.x))
if self.y is not None:
values.append("y=%s" % Length.str(self.y))
if self.width is not None:
values.append("width=%s" % Length.str(self.width))
if self.height is not None:
values.append("height=%s" % Length.str(self.height))
if self.preserveAspectRatio is not None:
values.append("%s=%s" % (SVG_ATTR_PRESERVEASPECTRATIO, self.preserveAspectRatio))
params = ", ".join(values)
Sophist-UK marked this conversation as resolved.
Show resolved Hide resolved
return "Viewbox(%s)" % params

def property_by_object(self, obj):
self.x = obj.x
self.y = obj.y
self.width = obj.width
self.height = obj.height
self.preserve_aspect_ratio = obj.preserve_aspect_ratio
self.preserveAspectRatio = obj.preserveAspectRatio
Sophist-UK marked this conversation as resolved.
Show resolved Hide resolved

def property_by_values(self, values):
viewbox = values.get(SVG_ATTR_VIEWBOX)
if viewbox is not None:
self.set_viewbox(viewbox)
if SVG_ATTR_PRESERVEASPECTRATIO in values:
self.preserve_aspect_ratio = values[SVG_ATTR_PRESERVEASPECTRATIO]
self.preserveAspectRatio = values[SVG_ATTR_PRESERVEASPECTRATIO]

def set_viewbox(self, viewbox):
if viewbox is not None:
Expand All @@ -3108,7 +3132,7 @@ def transform(self, element):
self.y,
self.width,
self.height,
self.preserve_aspect_ratio,
self.preserveAspectRatio,
)

@staticmethod
Expand Down Expand Up @@ -7392,7 +7416,7 @@ def property_by_values(self, values):
class Pattern(SVGElement, list):
def __init__(self, *args, **kwargs):
self.viewbox = None
self.preserve_aspect_ratio = None
self.preserveAspectRatio = None
self.x = None
self.y = None
self.width = None
Expand All @@ -7415,7 +7439,7 @@ def viewbox_transform(self):
def property_by_object(self, s):
SVGElement.property_by_object(self, s)
self.viewbox = s.viewbox
self.preserve_aspect_ratio = s.preserve_aspect_ratio
self.preserveAspectRatio = s.preserveAspectRatio

self.x = s.x
self.y = s.y
Expand All @@ -7438,7 +7462,7 @@ def property_by_values(self, values):
if viewbox is not None:
self.viewbox = Viewbox(viewbox)
if SVG_ATTR_PRESERVEASPECTRATIO in values:
self.preserve_aspect_ratio = values[SVG_ATTR_PRESERVEASPECTRATIO]
self.preserveAspectRatio = values[SVG_ATTR_PRESERVEASPECTRATIO]
self.x = Length(values.get(SVG_ATTR_X, 0)).value()
self.y = Length(values.get(SVG_ATTR_Y, 0)).value()
self.width = Length(values.get(SVG_ATTR_WIDTH, "100%")).value()
Expand Down Expand Up @@ -7672,7 +7696,7 @@ def __init__(self, *args, **kwargs):
self.url = None
self.data = None
self.viewbox = None
self.preserve_aspect_ratio = None
self.preserveAspectRatio = None
self.x = None
self.y = None
self.width = None
Expand Down Expand Up @@ -7703,8 +7727,6 @@ def __init__(self, *args, **kwargs):

def __repr__(self):
values = []
if self.url is not None:
values.append("%s=%s" % (SVG_HREF, self.url))
if self.x != 0:
values.append("%s=%s" % (SVG_ATTR_X, Length.str(self.x)))
if self.y != 0:
Expand All @@ -7713,12 +7735,18 @@ def __repr__(self):
values.append("%s=%s" % (SVG_ATTR_WIDTH, Length.str(self.width)))
if self.height != "100%":
values.append("%s=%s" % (SVG_ATTR_HEIGHT, Length.str(self.height)))
if self.preserve_aspect_ratio is not None:
if self.image_width != 0:
values.append("image_width=%s" % Length.str(self.image_width))
if self.image_height != 0:
values.append("image_height=%s" % Length.str(self.image_height))
Sophist-UK marked this conversation as resolved.
Show resolved Hide resolved
if self.preserveAspectRatio is not None:
values.append(
"%s=%s" % (SVG_ATTR_PRESERVEASPECTRATIO, self.preserve_aspect_ratio)
"%s=%s" % (SVG_ATTR_PRESERVEASPECTRATIO, self.preserveAspectRatio)
)
if self.viewbox is not None:
values.append("%s=%s" % (SVG_ATTR_VIEWBOX, repr(self.viewbox)))
if self.url is not None:
values.append("%s='%s'" % (SVG_HREF, self.url))
params = ", ".join(values)
return "SVGImage(%s)" % params

Expand All @@ -7729,7 +7757,7 @@ def property_by_object(self, s):
self.url = s.url
self.data = s.data
self.viewbox = s.viewbox
self.preserve_aspect_ratio = s.preserve_aspect_ratio
self.preserveAspectRatio = s.preserveAspectRatio

self.x = s.x
self.y = s.y
Expand All @@ -7752,7 +7780,10 @@ def property_by_values(self, values):
if viewbox is not None:
self.viewbox = Viewbox(viewbox)
if SVG_ATTR_PRESERVEASPECTRATIO in values:
self.preserve_aspect_ratio = values[SVG_ATTR_PRESERVEASPECTRATIO]
if values[SVG_ATTR_PRESERVEASPECTRATIO] == SVG_VALUE_NONE:
self.preserveAspectRatio = None
else:
self.preserveAspectRatio = values[SVG_ATTR_PRESERVEASPECTRATIO]
self.x = Length(values.get(SVG_ATTR_X, 0)).value()
self.y = Length(values.get(SVG_ATTR_Y, 0)).value()
self.width = Length(values.get(SVG_ATTR_WIDTH, "100%")).value()
Expand Down Expand Up @@ -7849,7 +7880,7 @@ def set_values_by_image(self):
self.image_height = self.image.height
self.viewbox = Viewbox(
"0 0 %d %d" % (self.image_width, self.image_height),
self.preserve_aspect_ratio,
self.preserveAspectRatio,
)
self.render(width=self.image_width, height=self.image_height)
self.transform = Matrix(self.viewbox_transform) * self.transform
Expand Down
4 changes: 2 additions & 2 deletions test/test_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_copy_objects(self):
self.assertEqual(matrix, matrix_copy)

# SVG OBJECTS
viewbox = Viewbox('0 0 103 109', preserve_aspect_ratio="xMaxyMin slice")
viewbox = Viewbox('0 0 103 109', preserveAspectRatio="xMaxyMin slice")
viewbox_copy = copy(viewbox)
# self.assertEqual(viewbox, viewbox_copy)

Expand Down Expand Up @@ -143,4 +143,4 @@ def test_copy_objects(self):
svg = SVG.parse(q)
svg_copy = copy(svg)
self.assertEqual(svg, svg_copy)
self.assertIsNotNone(svg_copy.values)
self.assertIsNotNone(svg_copy.values)
6 changes: 3 additions & 3 deletions test/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ def test_group_2rect(self):
r1 = rects[1]
self.assertEqual(r1.implicit_x, 0)
self.assertEqual(r1.implicit_y, 0)
self.assertEqual(r1.implicit_width, 200)
self.assertEqual(r1.implicit_height, 200)
self.assertEqual(round(r1.implicit_width,12), 200)
self.assertEqual(round(r1.implicit_height,12), 200)
Sophist-UK marked this conversation as resolved.
Show resolved Hide resolved
print(r1.bbox())

def test_issue_107(self):
Expand All @@ -68,4 +68,4 @@ def test_issue_107(self):
m *= "translate(100,100)" # Test __imul__
n = m * 'scale(2)' # Test __mult__
self.assertEqual(n[0][0].transform, Matrix("matrix(2,0,0,2,200,200)"))
self.assertEqual(m[0][0].transform, Matrix("matrix(1,0,0,1,100,100)"))
self.assertEqual(m[0][0].transform, Matrix("matrix(1,0,0,1,100,100)"))
9 changes: 9 additions & 0 deletions test/test_viewbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@

class TestElementViewbox(unittest.TestCase):

def test_viewbox_init(self):
# Test various ways of creating a viewbox are equal.
v1 = Viewbox('0 0 100 100')
v2 = Viewbox(x=0, y=0, width=100, height=100)
v3 = Viewbox(v1)
self.assertEqual(v1, v2)
self.assertEqual(v1, v3)
self.assertEqual(v2, v3)

def test_viewbox_incomplete_transform(self):
q = io.StringIO(u'''<?xml version="1.0" encoding="utf-8" ?>
<svg/>''')
Expand Down