Commits

Manfred Moitzi committed 07e5c98

added pattern element

  • Participants
  • Parent commits 4aa79dc

Comments (0)

Files changed (8)

File doc/classes/pattern.rst

+:class:`Pattern`
+================
+
+.. autoclass:: svgwrite.pattern.Pattern
+
+.. seealso:: http://www.w3.org/TR/SVG11/pservers.html#PatternElement
+
+Methods
+-------
+
+.. automethod:: svgwrite.pattern.Pattern.__init__(insert=None, size=None, inherit=None, attribs=None, \*\*extra)
+
+.. method:: Pattern.add(element)
+
+Add *element* to the pattern content.
+
+The contents of the **pattern** are relative to a new coordinate system.
+If there is a **viewBox** attribute, then the new coordinate system is fitted
+into the region defined by the **x**, **y**, **width**, **height** and
+**patternUnits** attributes on the **pattern** element using the standard
+rules for **viewBox** and **preserveAspectRatio**. If there is no **viewBox**
+attribute, then the new coordinate system has its origin at (x, y), where x
+is established by the **x** attribute on the **pattern** element, and y is
+established by the **y** attribute on the ‘pattern’ element. Thus, in the
+following example::
+
+  <pattern x="10" y="10" width="20" height="20">
+    <rect x="5" y="5" width="10" height="10"/>
+  </pattern>
+
+or as :mod:`svgwrite` calls::
+
+  # dwg is the main svg drawing
+  pattern = dwg.pattern(insert=(10, 10), size=(20, 20))
+  pattern.add(dwg.rect(insert=(5, 5), size=(10, 10))
+
+the rectangle has its top/left located 5 units to the right and 5 units down
+from the origin of the pattern tile.
+
+SVG Attributes
+--------------
+
+* **patternUnits** -- ``'userSpaceOnUse | objectBoundingBox'``
+
+  Defines the coordinate system for attributes **x**, **y**, **width** and
+  **height**.
+
+  If patternUnits= ``'userSpaceOnUse'`` , **x** , **y**, **width** and **height**
+  represent values in the coordinate system that results from taking the
+  current user coordinate system in place at the time when the **pattern**
+  element is referenced (i.e., the user coordinate system for the element
+  referencing the **pattern** element via a **fill** or **stroke** property)
+  and then applying the transform specified by attribute **patternTransform**.
+
+  If patternUnits= ``'objectBoundingBox'`` , the user coordinate system for
+  attributes **x**, **y**, **width** and **height** is established using the
+  bounding box of the element to which the pattern is applied (see Object
+  bounding box units) and then applying the transform specified by attribute
+  **patternTransform**.
+
+  Default is ``'objectBoundingBox'``.
+
+* **patternContentUnits** -- ``'userSpaceOnUse | objectBoundingBox'``
+
+  Defines the coordinate system for the contents of the **pattern**. Note that
+  this attribute has no effect if attribute **viewBox** is specified.
+
+  If patternContentUnits= ``'userSpaceOnUse'`` , the user coordinate system for
+  the contents of the **pattern** element is the coordinate system that
+  results from taking the current user coordinate system in place at the time
+  when the **pattern** element is referenced (i.e., the user coordinate system
+  for the element referencing the **pattern** element via a **fill** or
+  **stroke** property) and then applying the transform specified by attribute
+  **patternTransform**.
+
+  If patternContentUnits= ``'objectBoundingBox'`` , the user coordinate system
+  for the contents of the **pattern** element is established using the bounding
+  box of the element to which the pattern is applied (see Object bounding box
+  units) and then applying the transform specified by attribute
+  **patternTransform**.
+
+  Default is ``'userSpaceOnUse'``.
+
+* **patternTransform** -- *<transform-list>*
+
+  Use the :class:`~svgwrite.interface.ITransform` interface to set transformations.
+
+  Contains the definition of an optional additional transformation from the
+  pattern coordinate system onto the target coordinate system (i.e.,
+  ``'userSpaceOnUse'`` or ``'objectBoundingBox'``). This allows for things
+  such as skewing the pattern tiles. This additional transformation matrix is
+  post-multiplied to (i.e., inserted to the right of) any previously defined
+  transformations, including the implicit transformation necessary to convert
+  from object bounding box units to user space.
+
+* **x** -- *<coordinate>*
+
+  **x**, **y**, **width** and **height** indicate how the pattern tiles are
+  placed and spaced. These attributes represent coordinates and values in the
+  coordinate space specified by the combination of attributes **patternUnits**
+  and **patternTransform**.
+
+  Default is '0'.
+
+* **y** -- *<coordinate>*
+
+  See **x**.
+
+  Default is '0'.
+
+* **width** -- *<length>*
+
+  See **x**.
+
+  A negative value is an error. A value of zero disables rendering of the
+  element (i.e., no paint is applied).
+
+  Default is '0'.
+
+* **height** -- *<length>*
+
+  See **x**.
+
+  A negative value is an error. A value of zero disables rendering of the
+  element (i.e., no paint is applied).
+
+  Default is '0'.
+
+* **xlink:href** -- `string`
+
+  A URI reference to a different **pattern** element within the current SVG
+  document fragment. Any attributes which are defined on the referenced
+  element which are not defined on this element are inherited by this element.
+  If this element has no children, and the referenced element does (possibly
+  due to its own **xlink:href** attribute), then this element inherits the
+  children from the referenced element. Inheritance can be indirect to an
+  arbitrary level; thus, if the referenced element inherits attributes or
+  children due to its own **xlink:href** attribute, then the current element
+  can inherit those attributes or children.
+
+* **preserveAspectRatio** -- ``'[defer] <align> [<meetOrSlice>]'``
+
+  Use the :class:`~svgwrite.interface.IViewBox` interface to set **viewbox**
+  and **preserveAspectRatio**.

File doc/index.rst

    :maxdepth: 1
 
    classes/gradients
+   classes/pattern
 
 Interfaces
 ----------

File doc/overview.rst

    classes/path
    classes/shapes
 
+Text Objects
+------------
+
+.. toctree::
+   :maxdepth: 1
+
+   classes/text
+
+Paint Server
+------------
+
+.. toctree::
+   :maxdepth: 1
+
+   classes/gradients
+   classes/pattern
+
 Interfaces
 ----------
 
 
     dwg.save()
 
+def radialGradient_drawing(name):
+    dwg = svgwrite.Drawing(name, width='20cm', height='15cm', profile='full', debug=True)
+
+    # set user coordinate space
+    dwg.viewbox(width=200, height=150)
+
+    # create a new radialGradient element and add it to the defs section of
+    # the drawing
+    gradient1 = dwg.defs.add(dwg.radialGradient())
+    # define the gradient from red to white
+    gradient1.add_stop_color(0, 'red').add_stop_color(1, 'white')
+    # use gradient for filling the rect
+    dwg.add(dwg.rect((10,10), (50,50), fill=gradient1.get_paint_server()))
+
+    wave = dwg.defs.add(dwg.radialGradient())
+    wave.add_colors(['blue', 'lightblue'] * 8)
+    dwg.add(dwg.rect((70,10), (50,50), fill=wave.get_paint_server()))
+
+    dwg.save()
+
 def koch_snowflake(name):
     # Koch Snowflake and Sierpinski Triangle combination fractal using recursion
     # ActiveState Recipe 577156
     print("start: example_linearGradient.svg\n")
     linearGradient_drawing('example_linearGradient.svg')
 
+    print("start: example_radialGradient.svg\n")
+    radialGradient_drawing('example_radialGradient.svg')
+
     if longrun:
         print("start long time running examples!\n")
 

File svgwrite/elementfactory.py

 import image
 import text
 import gradients
+import pattern
 
 factoryelements = {
     'g': container.Group,
     'textArea': text.TextArea,
     'linearGradient': gradients.LinearGradient,
     'radialGradient': gradients.RadialGradient,
+    'pattern': pattern.Pattern,
 }
 
 class ElementBuilder(object):

File svgwrite/gradients.py

 
 """
 
-import copy
-
 from base import BaseElement
 from interface import ITransform, IXLink
 
         :param opacity: defines the opacity of a given gradient stop
         """
         self.add(_GradientStop(offset, color, opacity, factory=self))
+        return self
 
     def add_colors(self, colors, sweep=(0., 1.), opacity=None):
         """ Add stop-colors from colors with linear offset distributuion
         for color in colors:
             self.add_stop_color(round(offset, 3), color, opacity)
             offset += delta
+        return self
 
     def get_xml(self):
         if hasattr(self, 'href'):

File svgwrite/pattern.py

+#!/usr/bin/env python
+#coding:utf-8
+# Author:  mozman --<mozman@gmx.at>
+# Purpose: pattern module
+# Created: 29.10.2010
+# Copyright (C) 2010, Manfred Moitzi
+# License: GPLv3
+
+from base import BaseElement
+from interface import IXLink, IViewBox, ITransform
+from mixins import Presentation
+
+class Pattern(BaseElement, IXLink, IViewBox, ITransform, 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
+    cover the areas to be painted. Patterns are defined using a `pattern` element
+    and then referenced by properties `fill` and `stroke` on a given graphics
+    element to indicate that the given element shall be filled or stroked with
+    the referenced pattern.
+    """
+    elementname = 'pattern'
+    transformname = 'patternTransform'
+
+    def __init__(self, insert=None, size=None, inherit=None, attribs=None, **extra):
+        """
+        :param 2-tuple insert: base point of the pattern (**x**, **y**)
+        :param 2-tuple size: size of the pattern (**width**, **height**)
+        :param inherit: pattern inherits properties from `inherit` see: **xlink:href**
+
+        """
+        super(Pattern, self).__init__(attribs=attribs, **extra)
+        if insert is not None:
+            self['x'] = insert[0]
+            self['y'] = insert[1]
+        if size is not None:
+            self['width'] = size[0]
+            self['height'] = size[1]
+        if inherit is not None:
+            if isinstance(inherit, basestring):
+                self.set_href(inherit)
+            else:
+                self.set_href(inherit.get_iri())
+
+        if self.debug:
+            self.validator.check_all_svg_attribute_values(self.elementname, self.attribs)
+
+    def get_paint_server(self):
+        """ Returns the <FuncIRI> of the gradient. """
+        return self.get_funciri()

File tests/test_pattern.py

+#!/usr/bin/env python
+#coding:utf-8
+# Author:  mozman --<mozman@gmx.at>
+# Purpose: test pattern module
+# Created: 29.10.2010
+# Copyright (C) 2010, Manfred Moitzi
+# License: GPLv3
+
+import unittest
+
+from svgwrite.pattern import Pattern
+
+class TestPattern(unittest.TestCase):
+    def test_constructor(self):
+        pattern = Pattern(insert=(10, 20), size=(30, 40), inherit='#test',
+                          debug=True, profile='full')
+        self.assertEqual(
+            pattern.tostring(),
+            '<pattern height="40" width="30" x="10" xlink:href="#test" y="20" />')
+
+if __name__=='__main__':
+    unittest.main()