Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
IconSvgRenderer.py
Go to the documentation of this file.
1#!/usr/bin/python
2# coding: utf-8
3#
4# IconSvgRenderer.py - Icon rendering utility script
5#
6# Copyright (C)
7# 2008, Joel Holdsworth <joel@airwebreathe.org.uk>
8#
9# This program is free software; you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by the
11# Free Software Foundation; either version 2 of the License, or (at your
12# option) any later version. See the file COPYING for further details.
13
14
15import os
16import sys
17import getopt
18import shutil
19from xml.dom import minidom
20
21
22rsvgPath = "./rsvg-convert"
23artworkLayerPrefix = "artwork:"
24
25#
26# 2/2011 some notes by Ichthyo
27# The purpose of this python script is
28# - to parse a SVG
29# - to invoke Inkscape to render this SVG into a raster image (icon)
30#
31# For the actual Cairo based SVG rendering we rely on an executable 'rsvg-convert',
32# which is built during the Lumiera build process.
33#
34# Judging from the code and the actual SVGs, this seems to work as follows:
35# The SVG contains a design to be rendered into raster images of various sizes.
36# These sizes are determined by special rectangles, which act as bounding box and
37# are placed on a special 'plate' layer, which is a child layer of the main
38# 'artwork:' layer. The grid of the SVG is setup such as to result in pixel sizes
39# suitable for icon generation. The actual size of the generated icons are then
40# parsed from the height and width attributes of the mentioned bounding box
41# rectangles.
42#
43# The parser seems to be rather simplistic; the sizes and positions need to be
44# integral numbers. In one instance we had a float number in the y coordinate,
45# which resulted in an invalid, zero sized output icon
46#
47#
48
49
50def createDirectory (name):
51 try:
52 if os.path.isfile (name):
53 os.remove (name)
54 if not os.path.exists (name):
55 os.mkdir (name)
56 except:
57 print('WARNING: createDirectory("%s") failed. Permission problems?' % name)
58
59
60def copyMergeDirectory (src, dst):
61 listing = os.listdir (src)
62 for file_name in listing:
63 src_file_path = os.path.join (src, file_name)
64 dst_file_path = os.path.join (dst, file_name)
65 shutil.copyfile (src_file_path, dst_file_path)
66
67def getDocumentSize (svg_element):
68 width = float(svg_element.getAttribute("width"))
69 height = float(svg_element.getAttribute("height"))
70 return [width, height]
71
72def findChildLayerElement (parent_element):
73 for node in parent_element.childNodes:
74 if node.nodeType == minidom.Node.ELEMENT_NODE:
75 if node.tagName == "g":
76 if node.getAttribute("inkscape:groupmode") == "layer":
77 return node
78 return None
79
80def parsePlateLayer (layer):
81 rectangles = []
82 for node in layer.childNodes:
83 if node.nodeType == minidom.Node.ELEMENT_NODE:
84 if node.tagName == "rect":
85 x = float(node.getAttribute("x"))
86 y = float(node.getAttribute("y"))
87 width = float(node.getAttribute("width"))
88 height = float(node.getAttribute("height"))
89 rectangles.append([x, y, width, height])
90 return rectangles
91
92
93def parseSVG (file_path):
94 print("Parsing " + file_path)
95 svgdoc = minidom.parse (file_path)
96 for root_node in svgdoc.childNodes:
97 if root_node.nodeType == minidom.Node.ELEMENT_NODE:
98 if root_node.tagName == "svg":
99 size = getDocumentSize (root_node)
100 layer = findChildLayerElement (root_node)
101 if layer != None:
102 layer_name = layer.getAttribute ("inkscape:label")
103 if layer_name[:len(artworkLayerPrefix)] == artworkLayerPrefix:
104 artwork_name = layer_name[len(artworkLayerPrefix):]
105 plate = findChildLayerElement(layer)
106 if plate != None:
107 return artwork_name, size, parsePlateLayer(plate)
108 return None
109
110
111def renderSvgRsvg (file_path, out_dir, artwork_name, rectangle, _doc_size):
112 # Prepare a Cairo context
113 width = int(rectangle[2])
114 height = int(rectangle[3])
115
116 if not os.path.exists(rsvgPath):
117 print("Error: executable %s not found." % rsvgPath)
118
119 os.spawnlp(os.P_WAIT, rsvgPath, rsvgPath,
120 "--source-rect=%g:%g:%g:%g" % (rectangle[0], rectangle[1], width, height),
121 "--output=" + os.path.join(out_dir, "%gx%g/%s.png" % (width, height, artwork_name)),
122 file_path)
123
124def renderSvgIcon (file_path, out_dir):
125 artwork_name, doc_size, rectangles = parseSVG (file_path)
126 for rectangle in rectangles:
127 renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size)
128
129def getTargetNames (file_path):
130 """get a list of target names to be rendered from the given source SVG
131 usable to setup the build targets for SCons
132 """
133 artwork_name, _ , rectangles = parseSVG (file_path)
134 return ["%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name) for rectangle in rectangles ]
135
136
138 print("render-icon.py SRCFILE.svg TARGETDIR")
139 print("An icon rendering utility script for lumiera")
140
142 _optlist, args = getopt.getopt(argv, "")
143
144 if len(args) == 2:
145 return args[0], args[1]
146
147 printHelp()
148 return None, None
149
150
151def main (argv):
152 in_path, out_dir = parseArguments(argv)
153
154 if not (in_path and out_dir):
155 print("Missing arguments in_path and out_dir.")
156 sys.exit(1)
157
158 if os.path.isfile(out_dir):
159 print("Unable to use '%s' as output directory, because it\'s a file." % out_dir)
160 sys.exit(1)
161 if not os.path.isdir(out_dir):
162 print("Output directory '%s' not found." % out_dir)
163 sys.exit(1)
164
165 # Create the icons folders
166 createDirectory(os.path.join(out_dir, "48x48"))
167 createDirectory(os.path.join(out_dir, "32x32"))
168 createDirectory(os.path.join(out_dir, "24x24"))
169 createDirectory(os.path.join(out_dir, "22x22"))
170 createDirectory(os.path.join(out_dir, "16x16"))
171
172 renderSvgIcon (in_path, out_dir)
173
174
175
176
177if __name__=="__main__":
178 main(sys.argv[1:])
179
int main()
Definition main.c:37
getDocumentSize(svg_element)
renderSvgIcon(file_path, out_dir)
parseSVG(file_path)
copyMergeDirectory(src, dst)
renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, _doc_size)
findChildLayerElement(parent_element)
getTargetNames(file_path)
get a list of target names to be rendered from the given source SVG usable to setup the build targets...