Commits

Manfred Moitzi committed 40abbb6

moved content of interface.by to mixins.py

renamed ITransfer to Transfer
renamed IViewBox to ViewBox
renamed IXLink to XLink

because they are mixins and **not** interfaces

Comments (0)

Files changed (19)

svgwrite/animate.py

 # License: GPLv3
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import IXLink
+from svgwrite.mixins import XLink
 
-class Set(BaseElement, IXLink):
+class Set(BaseElement, XLink):
     """ The **set** element provides a simple means of just setting the value
     of an attribute for a specified duration. It supports all attribute types,
     including those that cannot reasonably be interpolated, such as string

svgwrite/container.py

 """
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import IViewBox, ITransform, IXLink
+from svgwrite.mixins import ViewBox, Transform, XLink
 from svgwrite.mixins import Presentation, Clipping
 
-class Group(BaseElement, ITransform, Presentation):
+class Group(BaseElement, Transform, Presentation):
     """ The **Group** (SVG **g**) element is a container element for grouping
     together related graphics elements.
 
     """
     elementname= 'defs'
 
-class Symbol(BaseElement, IViewBox, Presentation, Clipping):
+class Symbol(BaseElement, ViewBox, Presentation, Clipping):
     """ The **symbol** element is used to define graphical template objects which
     can be instantiated by a **use** element. The use of **symbol** elements for
     graphics that are used multiple times in the same document adds structure and
     # ITransform interface is not valid for Symbol -> do not inherit from Group
     elementname = 'symbol'
 
-class Marker(BaseElement, IViewBox, Presentation):
+class Marker(BaseElement, ViewBox, Presentation):
     """ The **marker** element defines the graphics that is to be used for
     drawing arrowheads or polymarkers on a given **path**, **line**, **polyline**
     or **polygon** element.
         self.defs = Defs(factory=self) # defs container
         self.add(self.defs) # add defs as first element
 
-class Use(BaseElement, ITransform, IXLink, Presentation):
+class Use(BaseElement, Transform, XLink, Presentation):
     """ The **use** element references another element and indicates that the graphical
     contents of that element is included/drawn at that given point in the document.
 
         self.update_id() # if href is an object - 'id' - attribute may be changed!
         return super(Use, self).get_xml()
 
-class Hyperlink(BaseElement, ITransform, Presentation):
+class Hyperlink(BaseElement, Transform, Presentation):
     """ The **a** element indicate links (also known as Hyperlinks or Web links).
 
     The remote resource (the destination for the link) is defined by a `<IRI>`

svgwrite/filters.py

 # License: GPLv3
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import IXLink
-from svgwrite.mixins import Presentation
+from svgwrite.mixins import XLink, Presentation
 from svgwrite.utils import strlist
 
 class _FilterPrimitive(BaseElement, Presentation):
 class _feGaussianBlur(_FilterRequireInput):
     elementname = 'feGaussianBlur'
 
-class _feImage(_FilterNoInput, IXLink):
+class _feImage(_FilterNoInput, XLink):
     elementname = 'feImage'
     def __init__(self, href, start=None, size=None, **extra):
         super(_feImage, self).__init__(start, size, **extra)
         self.parent.add(obj) # add primitive filter to parent Filter()
         return obj
 
-class Filter(BaseElement, IXLink, Presentation):
+class Filter(BaseElement, XLink, Presentation):
     """
     The filter element is a container element for filter primitives, and
     also a **factory** for filter primitives.

svgwrite/gradients.py

 """
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import ITransform, IXLink
+from svgwrite.mixins import Transform, XLink
 
 class _GradientStop(BaseElement):
     elementname = 'stop'
         if opacity is not None:
             self['stop-opacity'] = opacity
 
-class _AbstractGradient(BaseElement, ITransform, IXLink):
+class _AbstractGradient(BaseElement, Transform, XLink):
     transformname = 'gradientTransform'
     def __init__(self, inherit=None, **extra):
         super(_AbstractGradient, self).__init__(**extra)

svgwrite/image.py

 # License: GPLv3
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import ITransform, _vert, _horiz
-from svgwrite.mixins import Clipping
+from svgwrite.mixins import Transform, _vert, _horiz, Clipping
 
-class Image(BaseElement, ITransform, Clipping):
+class Image(BaseElement, Transform, Clipping):
     """ The **image** element indicates that the contents of a complete file are
     to be rendered into a given rectangle within the current user coordinate
     system. The **image** element can refer to raster image files such as PNG

svgwrite/interface.py

-#coding:utf-8
-# Author:  mozman
-# Purpose: svg interface classes
-# Created: 16.09.2010
-# Copyright (C) 2010, Manfred Moitzi
-# License: GPLv3
-
-_horiz = {'center': 'xMid', 'left': 'xMin', 'right': 'xMax'}
-_vert  = {'middle': 'YMid', 'top': 'YMin', 'bottom':'YMax'}
-
-from svgwrite.utils import strlist
-
-class IViewBox(object):
-    """ The **IViewBox** interface provides the ability to specify that a
-    given set of graphics stretch to fit a particular container element.
-
-    The value of the **viewBox** attribute is a list of four numbers
-    **min-x**, **min-y**, **width** and **height**, separated by whitespace
-    and/or a comma, which specify a rectangle in **user space** which should
-    be mapped to the bounds of the viewport established by the given element,
-    taking into account attribute **preserveAspectRatio**.
-
-    """
-    def viewbox(self, minx=0, miny=0, width=0, height=0):
-        """ Specify a rectangle in **user space** (no units allowed) which
-        should be mapped to the bounds of the viewport established by the
-        given element.
-
-        :param number minx: left border of the viewBox
-        :param number miny: top border of the viewBox
-        :param number width: width of the viewBox
-        :param number height: height of the viewBox
-
-        """
-        self['viewBox'] = strlist( [minx, miny, width, height] )
-
-    def stretch(self):
-        """ Stretch viewBox in x and y direction to fill viewport, does not
-        preserve aspect ratio.
-        """
-        self['preserveAspectRatio'] = 'none'
-
-    def fit(self, horiz="center", vert="middle", scale="meet"):
-        """ Set the **preserveAspectRatio** attribute.
-
-        :param string horiz: horizontal alignment ``'left | center | right'``
-        :param string vert: vertical alignment ``'top | middle | bottom'``
-        :param string scale: scale method ``'meet | slice'``
-
-        ============= =======================================================
-        Scale methods Description
-        ============= =======================================================
-        ``'meet'``    preserve aspect ration and zoom to limits of viewBox
-        ``'slice'``   preserve aspect ration and viewBox touch viewport on
-                      all bounds, viewBox will extend beyond the bounds of
-                      the viewport
-        ============= =======================================================
-
-        """
-        if self.debug and scale not in ('meet', 'slice'):
-            raise ValueError("Invalid scale parameter '%s'" % scale)
-        self['preserveAspectRatio'] = "%s%s %s" % (_horiz[horiz],_vert[vert], scale)
-
-class ITransform(object):
-    """ The **ITransform** interface operates on the **transform** attribute.
-    The value of the **transform** attribute is a `<transform-list>`, which
-    is defined as a list of transform definitions, which are applied in the
-    order provided. The individual transform definitions are separated by
-    whitespace and/or a comma. All coordinates are **user
-    space coordinates**.
-
-    """
-    transformname = 'transform'
-    def translate(self, tx, ty=None):
-        """
-        Specifies a translation by **tx** and **ty**. If **ty** is not provided,
-        it is assumed to be zero.
-
-        :param number tx: user coordinate - no units allowed
-        :param number ty: user coordinate - no units allowed
-        """
-        self._add_transformation("translate(%s)" % strlist( [tx, ty] ))
-
-    def rotate(self, angle, center=None):
-        """
-        Specifies a rotation by **angle** degrees about a given point.
-        If optional parameter **center** are not supplied, the rotate is
-        about the origin of the current user coordinate system.
-
-        :param number angle: rotate-angle in degrees
-        :param 2-tuple center: rotate-center as user coordinate - no units allowed
-
-        """
-        self._add_transformation("rotate(%s)" % strlist( [angle, center] ))
-
-    def scale(self, sx, sy=None):
-        """
-        Specifies a scale operation by **sx** and **sy**. If **sy** is not
-        provided, it is assumed to be equal to **sx**.
-
-        :param number sx: scalar factor x-axis, no units allowed
-        :param number sy: scalar factor y-axis, no units allowed
-
-        """
-        self._add_transformation("scale(%s)" % strlist( [sx, sy] ))
-
-    def skewX(self, angle):
-        """ Specifies a skew transformation along the x-axis.
-
-        :param number angle: skew-angle in degrees, no units allowed
-
-        """
-        self._add_transformation("skewX(%s)" % angle)
-
-    def skewY(self, angle):
-        """ Specifies a skew transformation along the y-axis.
-
-        :param number angle: skew-angle in degrees, no units allowed
-
-        """
-        self._add_transformation("skewY(%s)" % angle)
-
-    def matrix(self, a, b, c, d, e, f):
-        self._add_transformation("matrix(%s)" % strlist( [a, b, c, d, e, f] ))
-
-    def _add_transformation(self, new_transform):
-        old_transform = self.attribs.get(self.transformname, '')
-        self[self.transformname] = ("%s %s" % (old_transform, new_transform)).strip()
-
-class IXLink(object):
-    """ XLink interface """
-    def set_href(self, element):
-        """
-        Create a reference to **element**.
-
-        :param element: if element is a `string` its the **id** name of the
-          referenced element, if element is a **BaseElement** class the **id**
-          SVG Attribute is used to create the reference.
-
-        """
-        self.href = element
-        self.update_id()
-
-    def set_xlink(self, title=None, show=None, role=None, arcrole=None):
-        """ Set XLink attributes (for `href` use :meth:`set_href`).
-        """
-        if role is not None:
-            self['xlink:role'] = role
-        if arcrole is not None:
-            self['xlink:arcrole'] = arcrole
-        if title is not None:
-            self['xlink:title'] = title
-        if show is not None:
-            self['xlink:show'] = show
-
-    def update_id(self):
-        if not hasattr(self, 'href'):
-            return
-        if isinstance(self.href, basestring):
-            idstr = self.href
-        else:
-            idstr = self.href.get_iri()
-        self.attribs['xlink:href'] = idstr

svgwrite/masking.py

 # License: GPLv3
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import ITransform
+from svgwrite.mixins import Transform
 
-class ClipPath(BaseElement, ITransform):
+class ClipPath(BaseElement, Transform):
     """
     The clipping path restricts the region to which paint can be applied.
     Conceptually, any parts of the drawing that lie outside of the region

svgwrite/mixins.py

 from svgwrite.utils import strlist
 from svgwrite.base import Title, Desc
 
+_horiz = {'center': 'xMid', 'left': 'xMin', 'right': 'xMax'}
+_vert  = {'middle': 'YMid', 'top': 'YMin', 'bottom':'YMax'}
+
+class ViewBox(object):
+    """ The **ViewBox** mixin provides the ability to specify that a
+    given set of graphics stretch to fit a particular container element.
+
+    The value of the **viewBox** attribute is a list of four numbers
+    **min-x**, **min-y**, **width** and **height**, separated by whitespace
+    and/or a comma, which specify a rectangle in **user space** which should
+    be mapped to the bounds of the viewport established by the given element,
+    taking into account attribute **preserveAspectRatio**.
+
+    """
+    def viewbox(self, minx=0, miny=0, width=0, height=0):
+        """ Specify a rectangle in **user space** (no units allowed) which
+        should be mapped to the bounds of the viewport established by the
+        given element.
+
+        :param number minx: left border of the viewBox
+        :param number miny: top border of the viewBox
+        :param number width: width of the viewBox
+        :param number height: height of the viewBox
+
+        """
+        self['viewBox'] = strlist( [minx, miny, width, height] )
+
+    def stretch(self):
+        """ Stretch viewBox in x and y direction to fill viewport, does not
+        preserve aspect ratio.
+        """
+        self['preserveAspectRatio'] = 'none'
+
+    def fit(self, horiz="center", vert="middle", scale="meet"):
+        """ Set the **preserveAspectRatio** attribute.
+
+        :param string horiz: horizontal alignment ``'left | center | right'``
+        :param string vert: vertical alignment ``'top | middle | bottom'``
+        :param string scale: scale method ``'meet | slice'``
+
+        ============= =======================================================
+        Scale methods Description
+        ============= =======================================================
+        ``'meet'``    preserve aspect ration and zoom to limits of viewBox
+        ``'slice'``   preserve aspect ration and viewBox touch viewport on
+                      all bounds, viewBox will extend beyond the bounds of
+                      the viewport
+        ============= =======================================================
+
+        """
+        if self.debug and scale not in ('meet', 'slice'):
+            raise ValueError("Invalid scale parameter '%s'" % scale)
+        self['preserveAspectRatio'] = "%s%s %s" % (_horiz[horiz],_vert[vert], scale)
+
+class Transform(object):
+    """ The **Transform** mixin operates on the **transform** attribute.
+    The value of the **transform** attribute is a `<transform-list>`, which
+    is defined as a list of transform definitions, which are applied in the
+    order provided. The individual transform definitions are separated by
+    whitespace and/or a comma. All coordinates are **user
+    space coordinates**.
+
+    """
+    transformname = 'transform'
+    def translate(self, tx, ty=None):
+        """
+        Specifies a translation by **tx** and **ty**. If **ty** is not provided,
+        it is assumed to be zero.
+
+        :param number tx: user coordinate - no units allowed
+        :param number ty: user coordinate - no units allowed
+        """
+        self._add_transformation("translate(%s)" % strlist( [tx, ty] ))
+
+    def rotate(self, angle, center=None):
+        """
+        Specifies a rotation by **angle** degrees about a given point.
+        If optional parameter **center** are not supplied, the rotate is
+        about the origin of the current user coordinate system.
+
+        :param number angle: rotate-angle in degrees
+        :param 2-tuple center: rotate-center as user coordinate - no units allowed
+
+        """
+        self._add_transformation("rotate(%s)" % strlist( [angle, center] ))
+
+    def scale(self, sx, sy=None):
+        """
+        Specifies a scale operation by **sx** and **sy**. If **sy** is not
+        provided, it is assumed to be equal to **sx**.
+
+        :param number sx: scalar factor x-axis, no units allowed
+        :param number sy: scalar factor y-axis, no units allowed
+
+        """
+        self._add_transformation("scale(%s)" % strlist( [sx, sy] ))
+
+    def skewX(self, angle):
+        """ Specifies a skew transformation along the x-axis.
+
+        :param number angle: skew-angle in degrees, no units allowed
+
+        """
+        self._add_transformation("skewX(%s)" % angle)
+
+    def skewY(self, angle):
+        """ Specifies a skew transformation along the y-axis.
+
+        :param number angle: skew-angle in degrees, no units allowed
+
+        """
+        self._add_transformation("skewY(%s)" % angle)
+
+    def matrix(self, a, b, c, d, e, f):
+        self._add_transformation("matrix(%s)" % strlist( [a, b, c, d, e, f] ))
+
+    def _add_transformation(self, new_transform):
+        old_transform = self.attribs.get(self.transformname, '')
+        self[self.transformname] = ("%s %s" % (old_transform, new_transform)).strip()
+
+class XLink(object):
+    """ XLink mixin """
+    def set_href(self, element):
+        """
+        Create a reference to **element**.
+
+        :param element: if element is a `string` its the **id** name of the
+          referenced element, if element is a **BaseElement** class the **id**
+          SVG Attribute is used to create the reference.
+
+        """
+        self.href = element
+        self.update_id()
+
+    def set_xlink(self, title=None, show=None, role=None, arcrole=None):
+        """ Set XLink attributes (for `href` use :meth:`set_href`).
+        """
+        if role is not None:
+            self['xlink:role'] = role
+        if arcrole is not None:
+            self['xlink:arcrole'] = arcrole
+        if title is not None:
+            self['xlink:title'] = title
+        if show is not None:
+            self['xlink:show'] = show
+
+    def update_id(self):
+        if not hasattr(self, 'href'):
+            return
+        if isinstance(self.href, basestring):
+            idstr = self.href
+        else:
+            idstr = self.href.get_iri()
+        self.attribs['xlink:href'] = idstr
+
 class Presentation(object):
     """
     Helper methods to set presentation attributes.
 
 from svgwrite.base import BaseElement
 from svgwrite.utils import strlist
-from svgwrite.interface import ITransform
-from svgwrite.mixins import Presentation, Markers
+from svgwrite.mixins import Presentation, Markers, Transform
 
-class Path(BaseElement, ITransform, Presentation, Markers):
+class Path(BaseElement, Transform, Presentation, Markers):
     """ The <path> element represent the outline of a shape which can be filled,
     stroked, used as a clipping path, or any combination of the three.
 

svgwrite/pattern.py

 # License: GPLv3
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import IXLink, IViewBox, ITransform
-from svgwrite.mixins import Presentation
+from svgwrite.mixins import XLink, ViewBox, Transform, Presentation
 
-class Pattern(BaseElement, IXLink, IViewBox, ITransform, Presentation):
+class Pattern(BaseElement, XLink, ViewBox, Transform, Presentation):
     """
     A pattern is used to fill or stroke an object using a pre-defined graphic
     object which can be replicated ("tiled") at fixed intervals in x and y to

svgwrite/shapes.py

 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import ITransform
-from svgwrite.mixins import Presentation, Markers
+from svgwrite.mixins import Presentation, Markers, Transform
 
-class Line(BaseElement, ITransform, Presentation, Markers):
+class Line(BaseElement, Transform, Presentation, Markers):
     """ The **line** element defines a line segment that starts at one point
     and ends at another.
     """
         self['x2'] = x2
         self['y2'] = y2
 
-class Rect(BaseElement, ITransform, Presentation):
+class Rect(BaseElement, Transform, Presentation):
     """ The **rect** element defines a rectangle which is axis-aligned with the current
     user coordinate system. Rounded rectangles can be achieved by setting appropriate
     values for attributes **rx** and **ry**.
         if rx: self['rx'] = rx
         if ry: self['ry'] = ry
 
-class Circle(BaseElement, ITransform, Presentation):
+class Circle(BaseElement, Transform, Presentation):
     """ The **circle** element defines a circle based on a center point and a radius.
     """
     elementname = 'circle'
         self['cy'] = cy
         self['r'] = r
 
-class Ellipse(BaseElement, ITransform, Presentation):
+class Ellipse(BaseElement, Transform, Presentation):
     """ The **ellipse** element defines an ellipse which is axis-aligned with the
     current user coordinate system based on a center point and two radii.
     """
         self['rx'] = rx
         self['ry'] = ry
 
-class Polyline(BaseElement, ITransform, Presentation, Markers):
+class Polyline(BaseElement, Transform, Presentation, Markers):
     """ The **polyline** element defines a set of connected straight line
     segments. Typically, **polyline** elements define open shapes.
     """
 """
 
 from svgwrite.base import BaseElement
-from svgwrite.interface import ITransform, IXLink
-from svgwrite.mixins import Presentation
+from svgwrite.mixins import Presentation, Transform, XLink
 from svgwrite.utils import iterflatlist, strlist
 
 class TSpan(BaseElement, Presentation):
         xml.text = unicode(self.text)
         return xml
 
-class Text(TSpan, ITransform):
+class Text(TSpan, Transform):
     """
     The **Text** element defines a graphics element consisting of text.
     The characters to be drawn are expressed as XML character data inside the
     """
     elementname = 'text'
 
-class TRef(BaseElement, IXLink, Presentation):
+class TRef(BaseElement, XLink, Presentation):
     """
     The textual content for a **Text** can be either character data directly
     embedded within the <text> element or the character data content of a
         self.update_id() # if href is an object - 'id' - attribute may be changed!
         return super(TRef, self).get_xml()
 
-class TextPath(BaseElement, IXLink, Presentation):
+class TextPath(BaseElement, XLink, Presentation):
     """
     In addition to text drawn in a straight line, SVG also includes the
     ability to place text along the shape of a **path** element. To specify that
     def add(self, element):
         raise NotImplementedError("add() not supported by TBreak class.")
 
-class TextArea(BaseElement, ITransform, Presentation):
+class TextArea(BaseElement, Transform, Presentation):
     """
     At this time **textArea** is only available for SVG 1.2 Tiny profile.
 

tests/test_defs.py

 import unittest
 
 from svgwrite.container import Group, Defs
-from svgwrite.interface import ITransform
 
 class TestDefs(unittest.TestCase):
     def test_constructor(self):
         defs = Defs()
-        self.assertTrue(isinstance(defs, ITransform))
-        self.assertTrue(isinstance(defs, Group))
         self.assertEqual(defs.tostring(), "<defs />")
 
     def test_add_subelement(self):

tests/test_group.py

 import unittest
 
 from svgwrite.container import Group
-from svgwrite.interface import ITransform
 
 class TestGroup(unittest.TestCase):
     def test_constructor(self):
         g = Group()
-        self.assertTrue(isinstance(g, ITransform))
         self.assertEqual(g.tostring(), "<g />")
 
     def test_add_subelement(self):

tests/test_itransform.py

 
 from svgwrite.params import Parameter
 from svgwrite.base import BaseElement
-from svgwrite.interface import ITransform
+from svgwrite.mixins import Transform
 
-class Mock(BaseElement, ITransform):
+class Mock(BaseElement, Transform):
     elementname = 'g'
     _parameter = Parameter(True, 'full')
 

tests/test_iviewbox.py

 
 from svgwrite.params import Parameter
 from svgwrite.base import BaseElement
-from svgwrite.interface import IViewBox
+from svgwrite.mixins import ViewBox
 
-class Mock(BaseElement, IViewBox):
+class Mock(BaseElement, ViewBox):
     elementname = 'svg'
     _parameter = Parameter(True, 'full')
 
-class TestITransfer(unittest.TestCase):
+class TestViewBox(unittest.TestCase):
     def test_mock_class(self):
         m = Mock()
         self.assertEqual(m.tostring(), '<svg />')

tests/test_ixlink.py

 from svgwrite.container import Group
 from svgwrite.params import Parameter
 from svgwrite.base import BaseElement
-from svgwrite.interface import IXLink
+from svgwrite.mixins import XLink
 
-class Mock(BaseElement, IXLink):
+class Mock(BaseElement, XLink):
     elementname = 'use'
     _parameter = Parameter(True, 'full')
 

tests/test_symbol.py

 import unittest
 
 from svgwrite.container import Symbol, Group
-from svgwrite.interface import IViewBox, ITransform
 
 class TestSymbol(unittest.TestCase):
     def test_constructor(self):
         symbol = Symbol()
-        self.assertTrue(isinstance(symbol, IViewBox))
-        self.assertFalse(isinstance(symbol, ITransform))
         self.assertEqual(symbol.tostring(), "<symbol />")
 
     def test_add_subelement(self):

tests/test_use.py

 import unittest
 
 from svgwrite.container import Use, Group
-from svgwrite.interface import ITransform, IXLink
 from svgwrite.utils import AutoID
 
 class TestUse(unittest.TestCase):
     def test_constructor(self):
         use = Use('#an_id', x=10, y=20, width=100, height=200)
-        self.assertTrue(isinstance(use, ITransform))
-        self.assertTrue(isinstance(use, IXLink))
         self.assertEqual(use.tostring(), '<use height="200" width="100" x="10" xlink:href="#an_id" y="20" />')
 
     def test_constructor2(self):
         use = Use('#an_id', insert=(10, 20), size=(100, 200))
-        self.assertTrue(isinstance(use, ITransform))
-        self.assertTrue(isinstance(use, IXLink))
         self.assertEqual(use.tostring(), '<use height="200" width="100" x="10" xlink:href="#an_id" y="20" />')
 
     def test_object_link(self):