1from .elements import DrawingElement, DrawingParentElement
2
3
4class DrawingDef(DrawingParentElement):
5 '''Parent class of SVG nodes that must be direct children of <defs>.'''
6 def get_svg_defs(self):
7 return (self,)
8
9class DrawingDefSub(DrawingParentElement):
10 '''Parent class of SVG nodes that are meant to be descendants of a Def.'''
11 pass
12
13class LinearGradient(DrawingDef):
14 '''
15 A linear gradient to use as a fill or other color.
16
17 Has <stop> nodes as children, added with `.add_stop()`.
18 '''
19 TAG_NAME = 'linearGradient'
20 def __init__(self, x1, y1, x2, y2, gradientUnits='userSpaceOnUse',
21 **kwargs):
22 super().__init__(x1=x1, y1=y1, x2=x2, y2=y2,
23 gradientUnits=gradientUnits, **kwargs)
24 def add_stop(self, offset, color, opacity=None, **kwargs):
25 stop = GradientStop(offset=offset, stop_color=color,
26 stop_opacity=opacity, **kwargs)
27 self.append(stop)
28
29class RadialGradient(DrawingDef):
30 '''
31 A radial gradient to use as a fill or other color
32
33 Has <stop> nodes as children, added with `.add_stop()`.
34 '''
35 TAG_NAME = 'radialGradient'
36 def __init__(self, cx, cy, r, gradientUnits='userSpaceOnUse', fy=None,
37 **kwargs):
38 super().__init__(cx=cx, cy=cy, r=r, gradientUnits=gradientUnits,
39 fy=fy, **kwargs)
40 def add_stop(self, offset, color, opacity=None, **kwargs):
41 stop = GradientStop(offset=offset, stop_color=color,
42 stop_opacity=opacity, **kwargs)
43 self.append(stop)
44
45class GradientStop(DrawingDefSub):
46 '''A control point for a radial or linear gradient.'''
47 TAG_NAME = 'stop'
48 has_content = False
49
50class ClipPath(DrawingDef):
51 '''
52 A shape used to crop another element by not drawing outside of this shape.
53
54 Has regular drawing elements as children.
55 '''
56 TAG_NAME = 'clipPath'
57
58class Mask(DrawingDef):
59 '''
60 A drawing where the gray value and transparency are used to control the
61 transparency of another shape.
62
63 Has regular drawing elements as children.
64 '''
65 TAG_NAME = 'mask'
66
67class Filter(DrawingDef):
68 '''
69 A filter to apply to geometry.
70
71 For example a blur filter.
72 '''
73 TAG_NAME = 'filter'
74
75class FilterItem(DrawingDefSub):
76 '''A child of Filter with any tag name.'''
77 has_content = False
78 def __init__(self, tag_name, **args):
79 super().__init__(**args)
80 self.TAG_NAME = tag_name
81
82class Marker(DrawingDef):
83 '''
84 A small drawing that can be placed at the ends of (or along) a path.
85
86 This can be used for arrow heads or points on a graph for example.
87 By default, units are multiples of stroke width.
88 '''
89 TAG_NAME = 'marker'
90 def __init__(self, minx, miny, maxx, maxy, scale=1, orient='auto',
91 **kwargs):
92 width = maxx - minx
93 height = maxy - miny
94 kwargs = {
95 'markerWidth': width if scale == 1 else float(width) * scale,
96 'markerHeight': height if scale == 1 else float(height) * scale,
97 'viewBox': '{} {} {} {}'.format(minx, miny, width, height),
98 'orient': orient,
99 **kwargs,
100 }
101 super().__init__(**kwargs)