The SVG specs has a chapter on
styling. The SVG and Cascading Style Sheets (CSS) share many styling properties. There are two ways to style an
element in SVG. We can style an element using individual attributes or combining
them together as the value of style
attribute. For example, we can create
a blue rectangle with red border like this.
<rect
fill="blue"
stroke="red"
stroke-width="2"
x="10" y="10" width="30" height="20" />
Or we can specify a single style
attribute like this.
<rect
style="fill:blue; stroke:red; stroke-width:3"
x="50" y="50" width="30" height="20" />
SVG elements generated by Inkscape itself use the style
attribute.
The style.py
module in inkex
directory defines several classes. The most notable
one is the Style
class which derives from OrderedDict
class. The __init__
method
of the class is written in a way that it accepts a dictionary, a string, key value
pairs, or another Style
object as the initial value. The Python interpreter session
below shows how to initialize a Style
object in different ways.
george@Inspiron-5515:~$ /usr/bin/python3
>>> import sys
>>> sys.path.append('/usr/share/inkscape/extensions')
>>> from inkex import Style
>>> s = Style({'fill':'red', 'stroke':'green'})
>>> s
Style([('fill', 'red'), ('stroke', 'green')])
>>> str(s)
'fill:red;stroke:green'
>>> st1 = Style('fill:red; stroke:green')
>>> str(st1)
'fill:red;stroke:green'
>>> st2 = Style(fill='red', stroke='green')
>>> str(st2)
'fill:red;stroke:green'
>>> st3 = Style(st2)
>>> str(st3)
'fill:red;stroke:green'
The static method parse_str
parses a string and yields key value pair as a tuple
from which we can create a new Style
object. The to_str
method converts a Style
object
to a string.
The update
method is similar to Python dictionary update
method. The Style
class
also defines the __add__
and __sub__
methods so we can add or subtract
Style
class objects. The operators +
or -
create new copies of
Style
object.
>>> st4 = Style({'stroke-width':'3'})
>>> st5 = st3 + st4
>>> print(st5)
fill:red;stroke:green;stroke-width:3
>>> st6 = st5 - {'fill':'red'}
>>> print(st6)
stroke:green;stroke-width:3
The Style
class also defines a get_color
and a set_color
method. We can use them
like the examples shown below.
>>> st6.get_color('stroke')
[0, 128, 0, 1.0]
>>> st6.set_color('red', 'fill')
>>> print(st6)
stroke:green;stroke-width:3;fill:#ff0000
When we are working on element style in an Inkscape extension, we change the element
style in Inkscape itself and watch the style value in XML editor. Once we find a value
to use, we can set the same style attribute and value in extension code.
As shown in previous chapters, we set style
property of an element object with a
Style
object.
element.style = st2 # st2 is a Style object
The colors.py
module in inkex
directory defines an SVG_COLOR
dictionary with
148 color names and values. The is_color
function determines if a value is
a color that we can use.
>>> from inkex.colors import SVG_COLOR
>>> len(SVG_COLOR) # include a none
149
>>> SVG_COLOR['none']
>>> from inkex.colors import is_color
>>> is_color('#334')
True
>>> is_color('#334srd') # wrong value above F
False
>>> is_color('#33AABB')
True
>>> is_color('red')
True
>>> is_color(345)
True
>>> is_color('#334ABD00') # this is in rgba format
True
We usually use the color name as a string value such as red
or an RGB string value
such as #FF00CC
when we specify a color in extension code.
The Inkscape has a whole class of extensions dealing with colors. They are listed
under the Extensions > Color
menu. The Randomize
and Negative
are
interesting, and Grayscale
and Replace color
are sometimes useful.
Those extensions have
classes derived from ColorExtension
class which is defined in the
extensions.py
module.
Let’s take a look at the Grayscale
extension. The content of the color_grayscale.py
module is listed below. It only overrides a modify_color
method. The color
argument is the color of the element to be modified. The name
argument is one of the
color attribute names stroke
, fill
, stop-color
, flood-color
or lighting-color
defined in the Style
class. The return value is the new modified color.
#!/usr/bin/env python
"""Convert to grey"""
import inkex
class Grayscale(inkex.ColorExtension):
"""Make all colours grayscale"""
def modify_color(self, name, color):
# ITU-R Recommendation BT.709 (NTSC and PAL)
# l = 0.2125 * r + 0.7154 * g + 0.0721 * b
lum = 0.299 * color.red + 0.587 * color.green + 0.114 * color.blue
return inkex.Color((int(round(lum)),
int(round(lum)), int(round(lum))))
if __name__ == '__main__':
Grayscale().run()
12. Colors and Styles