Source code for pisak.svg

"""
Creation and modification of SVG images within PISAK.
"""
import re
import os

import gi

gi.require_version('Rsvg', '2.0')

from gi.repository import Rsvg

from pisak import exceptions, dirs


[docs]class PisakSVGError(exceptions.PisakException): """ SVG related exception. """ pass
[docs]class PisakSVG: """ SVG file object being PISAK icon. """ def __init__(self, name): super().__init__() self.path = dirs.get_icon_path(name) with open(self.path, 'r') as svg_file: self.string = svg_file.read() self.css = PisakCSS() self._style() def _style(self): """ Add style to the svg. """ parts = re.split('(<svg.*?>)', self.string, flags=re.DOTALL) self.styled_svg = ''.join([parts[0], parts[1], '\n', self.css.__str__(), '\n', parts[2]])
[docs] def get_handle(self): """ Returns Rsvg.Handle of styled svg. """ return Rsvg.Handle.new_from_data(bytes(self.styled_svg, 'utf-8'))
[docs] def get_pixbuf(self): """ Returns pixbuf from Rsvg.Handle of styled svg. """ handle = self.get_handle() return handle.get_pixbuf()
[docs] def change_color(self, color): """ Change color of whole SVG. :param color: should be string, you can define color in hex, rgb(0-255, 0-255, 0-255) or word(ie. green, blue). """ self.css.path = {'stroke' : str(color), 'fill' : str(color)} self.css.g = {'stroke' : str(color), 'fill' : str(color)} for i in range(1, 6): self.css.__setattr__('#L{}'.format(i), {'stroke' : str(color), 'fill' : str(color)}) self._style()
[docs] def change_color_selectively(self, color, node_name): """ Change color of one of the nodes of the SVG or create such node with set colors. :param color: should be string, you can. define color in hex, rgb(0-255, 0-255, 0-255) or word(ie. green, blue). :param node_name: name of the node which color is to be changed. """ self.css.__setattr__(node_name, {'stroke' : str(color), 'fill' : str(color)})
[docs]class PisakCSS: """ CSS object to style PisakSVG - icons. """ def __init__(self): super().__init__() def __str__(self): """ Convert PisakCSS to string. """ braces = ['<style type="text/css">\n<![CDATA[', ']]>\n</style>'] node_braces = ['{', '}'] string = '' for node_name, props in self.__dict__.items(): node = '\n'.join(['{}: {};'.format(name, value) for name, value in props.items()]) string = '{}\n{} {}\n{}\n{}\n'.format(string, node_name, node_braces[0], node, node_braces[1]) string = "{0}\n{1}\n{2}".format(braces[0], string, braces[1]) return string def __setattr__(self, node_name, props): """ Update an existing node of name with props or create new node. :param node_name: name of the node as string. :param props: dic of pairs of property name (key of type string) and it's value(value of type string). """ try: self.__getattribute__(node_name).update(props) except AttributeError: super().__setattr__(node_name, props)
[docs] def delete_prop(self, node_name, prop): """ Delete property from node. :param node_name: Node name from which to delete the property. :param prop: Property name to be deleted. """ msg = '{}({}) does not exist.' try: del self.__getattribute__(node_name)[prop] except AttributeError: _LOG.warning(msg.format('Node', node_name)) except KeyError: _LOG.warning(msg.format('Property', prop))