Code

Node tool: fix snapping of node rotation center
[inkscape.git] / share / filters / samplify.py
1 # This script produces a sample SVG demonstrating all filters in a filters file.
2 #
3 # It takes two inputs: the sample file with the object that will be cloned and filtered, and
4 # the file with filters (such as Inkscape's share/filters/filters.svg).
5 #
6 # Run it thus:
7 #
8 #    python samplify.py sample.svg filters.svg > out.svg
9 #
10 # It requires 'inkscape' in executable path for dimension queries.
12 import sys, os, string
13 from lxml import etree
15 if len(sys.argv) < 3:
16     sys.stderr.write ("Usage: python samplify.py sample.svg filters.svg > out.svg\n")
17     sys.exit(1)
19 # namespaces we need to be aware of
20 NSS = {
21 u'sodipodi' :u'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
22 u'cc'       :u'http://web.resource.org/cc/',
23 u'svg'      :u'http://www.w3.org/2000/svg',
24 u'dc'       :u'http://purl.org/dc/elements/1.1/',
25 u'rdf'      :u'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
26 u'inkscape' :u'http://www.inkscape.org/namespaces/inkscape',
27 u'xlink'    :u'http://www.w3.org/1999/xlink',
28 u'xml'      :u'http://www.w3.org/XML/1998/namespace'
29 }
31 # helper function to add namespace URI to a name
32 def addNS(tag, ns=None):
33     val = tag
34     if ns!=None and len(ns)>0 and NSS.has_key(ns) and len(tag)>0 and tag[0]!='{':
35         val = "{%s}%s" % (NSS[ns], tag)
36     return val
38 # attributes and elements we will use, prepared with their namespace
39 a_href = addNS('href', 'xlink')
40 a_menu = addNS('menu', 'inkscape')
41 a_tooltip = addNS('menu-tooltip', 'inkscape')
42 a_label = addNS('label', 'inkscape')
43 e_text = addNS('text', 'svg')
44 e_tspan = addNS('tspan', 'svg')
45 e_flowRoot = addNS('flowRoot', 'svg')
46 e_flowPara = addNS('flowPara', 'svg')
47 e_flowSpan = addNS('flowSpan', 'svg')
48 e_g = addNS('g', 'svg')
49 e_use = addNS('use', 'svg')
50 e_defs = addNS('defs', 'svg')
51 e_filter = addNS('filter', 'svg')
52 e_rect = addNS('rect', 'svg')
53 e_svg = addNS('svg', 'svg')
54 e_switch = addNS('switch', 'svg')
57 tstream = open(sys.argv[1], 'rb')
58 tdoc = etree.parse(tstream)
60 fstream = open(sys.argv[2], 'rb')
61 fdoc = etree.parse(fstream)
63 menus = []
65 for defs in fdoc.getroot().getchildren():
66     for fi in defs.getchildren():
67         if fi.tag == e_filter and fi.attrib[a_menu] not in menus:
68             menus.append(fi.attrib[a_menu])
70 menu_shifts = {}
71 for m in menus:
72     menu_shifts[m] = 0
74 menus.sort()
76 #print menus
78 def copy_element (a):
79     b = etree.Element(a.tag, nsmap=NSS)
80     for i in a.items():
81         b.set(i[0], i[1])
82     b.text = a.text
83     b.tail = a.tail
84     return b
86 #query inkscape about the bounding box of obj
87 q = {'x':0,'y':0,'width':0,'height':0}
88 file = sys.argv[1]
89 id = tdoc.getroot().attrib["id"]
90 for query in q.keys():
91     f,err = os.popen3('inkscape --query-%s --query-id=%s "%s"' % (query,id,file))[1:]
92     q[query] = float(f.read())
93     f.close()
94     err.close()
96 # add some margins
97 q['width'] = q['width'] * 1.3
98 q['height'] = q['height'] * 1.3
100 #print q    
102 root = tdoc.getroot()
103 tout = etree.ElementTree(copy_element(root))
104 newroot = tout.getroot()
105 for ch in root.getchildren():
106     chcopy = ch.__deepcopy__(-1)
107     newroot.append(chcopy)
108     if ch.tag == e_defs:
109         for defs in fdoc.getroot().getchildren():
110             for fi in defs.getchildren():
111                 ficopy = fi.__deepcopy__(-1)
112                 newroot.getchildren()[-1].append(ficopy)
113     if ch.tag == e_g:
114         newroot.getchildren()[-1].attrib["id"] = "original"
115         for menu in menus:
116             text = etree.Element(e_text, nsmap=NSS)
117             text.attrib['x']=str(q['x'] - q['width'] * 0.2)
118             text.attrib['y']=str( q['y'] + q['height'] * (menus.index(menu) + 1.4) )
119             text.attrib['style']="font-size:%d;text-anchor:end;" % (q['height']*0.2)
120             text.text = menu
121             newroot.append(text)
122         for defs in fdoc.getroot().getchildren():
123             for fi in defs.getchildren():
124                 if fi.tag != e_filter:
125                     continue
126                 clone = etree.Element(e_use, nsmap=NSS)
127                 clone.attrib[a_href]='#original'
128                 clone.attrib["style"]='filter:url(#'+fi.attrib["id"]+')'
129                 menu = fi.attrib[a_menu]
130                 clone.attrib["transform"] = 'translate('+str( q['width'] * menu_shifts[menu] )+', '+str( q['height'] * (menus.index(menu) + 1) )+')'
131                 newroot.append(clone)
133                 text = etree.Element(e_text, nsmap=NSS)
134                 text.attrib['x']=str( q['x'] + q['width'] * (menu_shifts[menu] + 0.5) )
135                 text.attrib['y']=str( q['y'] + q['height'] * (menus.index(menu) + 1.86) )
136                 text.attrib['style']="font-size:%d;text-anchor:middle;" % (q['height']*0.08)
137                 text.text = fi.attrib[a_label]
138                 newroot.append(text)
140                 if a_tooltip not in fi.keys():
141                     print "no menu-tooltip for", fi.attrib["id"]
142                     sys.exit()
144                 text = etree.Element(e_text, nsmap=NSS)
145                 text.attrib['x']=str( q['x'] + q['width'] * (menu_shifts[menu] + 0.5) )
146                 text.attrib['y']=str( q['y'] + q['height'] * (menus.index(menu) + 1.92) )
147                 text.attrib['style']="font-size:%d;text-anchor:middle;" % (q['height']*0.04)
148                 text.text = fi.attrib[a_tooltip]
149                 newroot.append(text)
151                 menu_shifts[menu] = menu_shifts[menu] + 1
152         break
154 total_width = max(menu_shifts.values()) * q['width']    
155 total_height = (len(menus) + 1) * q['height']
156 tout.getroot().attrib['width'] = str(total_width)
157 tout.getroot().attrib['height'] = str(total_height)
159 print etree.tostring(tout, encoding='UTF-8')