diff options
Diffstat (limited to '')
-rwxr-xr-x | libraries/edje/utils/inkscape2edc | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/libraries/edje/utils/inkscape2edc b/libraries/edje/utils/inkscape2edc new file mode 100755 index 0000000..25a1a8c --- /dev/null +++ b/libraries/edje/utils/inkscape2edc | |||
@@ -0,0 +1,309 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | import os | ||
4 | import os.path | ||
5 | import subprocess | ||
6 | import logging as log | ||
7 | import re | ||
8 | |||
9 | |||
10 | class Inkscape2Edc(object): | ||
11 | cmd = "inkscape --without-gui" | ||
12 | def __init__(self, infile, outfile, group, | ||
13 | relative1_x=None, relative2_x=None, | ||
14 | relative1_y=None, relative2_y=None, | ||
15 | images_dir="", | ||
16 | show_max=True, show_min=True, show_mouse_events=True): | ||
17 | self.infile = infile | ||
18 | self.outfile = outfile | ||
19 | self.group = group | ||
20 | self.relative1_x = relative1_x | ||
21 | self.relative2_x = relative2_x | ||
22 | self.relative1_y = relative1_y | ||
23 | self.relative2_y = relative2_y | ||
24 | self.images_dir = images_dir | ||
25 | self.show_max = show_max | ||
26 | self.show_min = show_min | ||
27 | self.show_mouse_events = show_mouse_events | ||
28 | |||
29 | self.images = {} | ||
30 | self.sizes = {} | ||
31 | self.known_ids = tuple() | ||
32 | self.w = 0 | ||
33 | self.h = 0 | ||
34 | |||
35 | self.out = open(self.outfile, "wb") | ||
36 | self.basedir = os.path.dirname(self.outfile) | ||
37 | |||
38 | def _exec_cmd(self, *args): | ||
39 | s = " ".join(args) | ||
40 | cmd = "%s --file=%r %s" % (self.cmd, self.infile, s) | ||
41 | try: | ||
42 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, | ||
43 | stderr=subprocess.PIPE, shell=True) | ||
44 | except Exception, e: | ||
45 | log.error("cmd=%r exception: %s", cmd, e) | ||
46 | return "" | ||
47 | |||
48 | out, err = p.communicate() | ||
49 | if err: | ||
50 | log.error("cmd=%r error: %s", cmd, err) | ||
51 | |||
52 | return out | ||
53 | |||
54 | def load_sizes(self): | ||
55 | sizes = self._exec_cmd("--query-all").split('\n') | ||
56 | |||
57 | self.sizes = {} | ||
58 | order = [] | ||
59 | for line in sizes: | ||
60 | if not line: | ||
61 | continue | ||
62 | try: | ||
63 | oid, x, y, w, h = line.split(',') | ||
64 | except ValueError: | ||
65 | log.warn("could not parse size line: %r", line) | ||
66 | continue | ||
67 | x = float(x) | ||
68 | y = float(y) | ||
69 | w = float(w) | ||
70 | h = float(h) | ||
71 | self.sizes[oid] = (x, y, w, h) | ||
72 | order.append(oid) | ||
73 | |||
74 | self.known_ids = tuple(order) | ||
75 | |||
76 | self.w = float(self._exec_cmd("--query-width")) | ||
77 | self.h = float(self._exec_cmd("--query-height")) | ||
78 | |||
79 | def output_file_header(self): | ||
80 | self.out.write("""\ | ||
81 | collections { | ||
82 | group { | ||
83 | name: "%(group)s"; | ||
84 | """ % self.__dict__) | ||
85 | |||
86 | if self.show_min: | ||
87 | self.out.write(" min: %(w)d %(h)d;\n" % self.__dict__) | ||
88 | |||
89 | if self.show_max: | ||
90 | self.out.write(" max: %(w)d %(h)d;\n" % self.__dict__) | ||
91 | |||
92 | def output_file_section_parts_begin(self): | ||
93 | self.out.write(" parts {\n") | ||
94 | |||
95 | def output_file_section_parts_end(self): | ||
96 | self.out.write(" }\n") | ||
97 | |||
98 | def output_file_section_images_begin(self): | ||
99 | self.out.write(" images {\n") | ||
100 | |||
101 | def output_file_section_images_end(self): | ||
102 | self.out.write(" }\n") | ||
103 | |||
104 | def output_file_foot(self): | ||
105 | self.out.write("""\ | ||
106 | } | ||
107 | } | ||
108 | """) | ||
109 | |||
110 | def output_image(self, oid): | ||
111 | img = os.path.join(self.images_dir, oid) | ||
112 | img += ".png" | ||
113 | |||
114 | self._exec_cmd("--export-id='%s'" % oid, | ||
115 | "--export-id-only", | ||
116 | "--export-png='%s'" % os.path.join(self.basedir, img)) | ||
117 | |||
118 | self.out.write(' image: "%s" COMP;\n' % img) | ||
119 | self.images[oid] = img | ||
120 | |||
121 | def output_part_desc_rel(self, x, y, w, h): | ||
122 | def choose_rel(relative, value, value_max): | ||
123 | if relative is not None: | ||
124 | return relative | ||
125 | elif value <= abs(value_max - value): | ||
126 | return 0.0 | ||
127 | else: | ||
128 | return 1.0 | ||
129 | |||
130 | x2 = x + w - 1 | ||
131 | y2 = y + h - 1 | ||
132 | |||
133 | rx1 = choose_rel(self.relative1_x, x, w) | ||
134 | rx2 = choose_rel(self.relative2_x, x2, w) | ||
135 | ry1 = choose_rel(self.relative1_y, y, h) | ||
136 | ry2 = choose_rel(self.relative2_y, y2, h) | ||
137 | |||
138 | ox1 = x - self.w * rx1 | ||
139 | ox2 = x2 - self.w * rx2 | ||
140 | |||
141 | oy1 = y - self.h * ry1 | ||
142 | oy2 = y2 - self.h * ry2 | ||
143 | |||
144 | self.out.write("""\ | ||
145 | rel1 { | ||
146 | relative: %03.1f %03.1f; | ||
147 | offset: %d %d; | ||
148 | } | ||
149 | rel2 { | ||
150 | relative: %03.1f %03.1f; | ||
151 | offset: %d %d; | ||
152 | } | ||
153 | """ % (rx1, ry1, ox1, oy1, rx2, ry2, ox2, oy2)) | ||
154 | |||
155 | |||
156 | def output_part(self, oid): | ||
157 | try: | ||
158 | x, y, w, h = self.sizes[oid] | ||
159 | except KeyError: | ||
160 | log.error("no such object id: %s", oid) | ||
161 | return | ||
162 | |||
163 | info = { | ||
164 | "name": oid, | ||
165 | "x": x, | ||
166 | "y": y, | ||
167 | "w": w, | ||
168 | "h": h, | ||
169 | } | ||
170 | |||
171 | self.out.write(""" | ||
172 | part { | ||
173 | name: "%(name)s"; | ||
174 | type: IMAGE; | ||
175 | """ % info) | ||
176 | |||
177 | if self.show_mouse_events: | ||
178 | self.out.write(" mouse_events: 0;\n") | ||
179 | |||
180 | self.out.write("""\ | ||
181 | description { | ||
182 | state: "default" 0.0; | ||
183 | """) | ||
184 | |||
185 | if self.show_min: | ||
186 | self.out.write(" min: %(w)d %(h)d;\n" % info) | ||
187 | |||
188 | if self.show_max: | ||
189 | self.out.write(" max: %(w)d %(h)d;\n" % info) | ||
190 | |||
191 | self.output_part_desc_rel(x, y, w, h) | ||
192 | self.out.write("""\ | ||
193 | image.normal: "%s"; | ||
194 | } | ||
195 | } | ||
196 | """ % (self.images[oid],)) | ||
197 | |||
198 | |||
199 | def foreach_id(inkscape2edc, ids=None, re_exclude=None): | ||
200 | if ids: | ||
201 | for oid in inkscape2edc.known_ids: | ||
202 | if oid in ids: | ||
203 | yield oid | ||
204 | else: | ||
205 | for oid in inkscape2edc.known_ids: | ||
206 | if re_exclude is not None and re_exclude.match(oid): | ||
207 | continue | ||
208 | yield oid | ||
209 | |||
210 | |||
211 | if __name__ == "__main__": | ||
212 | import optparse | ||
213 | |||
214 | usage = "usage: %prog [options] <input.svg>" | ||
215 | parser = optparse.OptionParser(usage=usage) | ||
216 | |||
217 | parser.add_option("-i", "--id", action="append", default=[], | ||
218 | help=("Object ID to use, it will be the part name. " | ||
219 | "Multiple usage to use more object ids.")) | ||
220 | parser.add_option("-e", "--exclude", action="store", default=None, | ||
221 | help=("Exclude regular expression." | ||
222 | "Matching IDs will be ignored.")) | ||
223 | parser.add_option("-o", "--output", action="store", default=None, | ||
224 | help="Output file to use") | ||
225 | parser.add_option("-g", "--group", action="store", default=None, | ||
226 | help="Group name") | ||
227 | parser.add_option("-d", "--images-dir", action="store", default="", | ||
228 | help="Directory where to output images.") | ||
229 | parser.add_option("--no-min", action="store_true", | ||
230 | help="Do not output min values") | ||
231 | parser.add_option("--no-max", action="store_true", | ||
232 | help="Do not output max values") | ||
233 | parser.add_option("--no-mouse_events", action="store_true", | ||
234 | help="Do not output mouse_events lines") | ||
235 | parser.add_option("--relative1-y", action="store", | ||
236 | choices=("top", "bottom", "auto"), | ||
237 | default="auto", | ||
238 | help=("Choose what to use as base for rel1 y values, " | ||
239 | "top=0.0, bottom=1.0, auto=nearest")) | ||
240 | parser.add_option("--relative2-y", action="store", | ||
241 | choices=("top", "bottom", "auto"), | ||
242 | default="auto", | ||
243 | help=("Choose what to use as base for rel2 y values, " | ||
244 | "top=0.0, bottom=1.0, auto=nearest")) | ||
245 | parser.add_option("--relative1-x", action="store", | ||
246 | choices=("left", "right", "auto"), | ||
247 | default="auto", | ||
248 | help=("Choose what to use as base for rel1 x values, " | ||
249 | "left=0.0, right=1.0, auto=nearest")) | ||
250 | parser.add_option("--relative2-x", action="store", | ||
251 | choices=("left", "right", "auto"), | ||
252 | default="auto", | ||
253 | help=("Choose what to use as base for rel2 x values, " | ||
254 | "left=0.0, right=1.0, auto=nearest")) | ||
255 | |||
256 | |||
257 | options, args = parser.parse_args() | ||
258 | |||
259 | try: | ||
260 | infile = args[0] | ||
261 | except IndexError: | ||
262 | parser.print_help() | ||
263 | raise SystemExit("missing input file name") | ||
264 | |||
265 | fname = os.path.splitext(infile)[0] | ||
266 | if not options.output: | ||
267 | options.output = fname + ".edc" | ||
268 | |||
269 | if not options.group: | ||
270 | options.group = fname | ||
271 | |||
272 | rx_map = {"left": 0.0, "right": 1.0} | ||
273 | options.relative1_x = rx_map.get(options.relative1_x, None) | ||
274 | options.relative2_x = rx_map.get(options.relative2_x, None) | ||
275 | |||
276 | ry_map = {"top": 0.0, "bottom": 1.0} | ||
277 | options.relative1_y = ry_map.get(options.relative1_y, None) | ||
278 | options.relative2_y = ry_map.get(options.relative2_y, None) | ||
279 | |||
280 | o = Inkscape2Edc(infile, options.output, options.group, | ||
281 | relative1_x=options.relative1_x, | ||
282 | relative2_x=options.relative2_x, | ||
283 | relative1_y=options.relative1_y, | ||
284 | relative2_y=options.relative2_y, | ||
285 | images_dir=options.images_dir, | ||
286 | show_max=not options.no_max, show_min=not options.no_min, | ||
287 | show_mouse_events=not options.no_mouse_events) | ||
288 | |||
289 | re_exclude = None | ||
290 | if options.exclude: | ||
291 | re_exclude = re.compile(options.exclude) | ||
292 | |||
293 | if options.images_dir: | ||
294 | os.makedirs(options.images_dir) | ||
295 | |||
296 | o.load_sizes() | ||
297 | o.output_file_header() | ||
298 | |||
299 | o.output_file_section_images_begin() | ||
300 | for oid in foreach_id(o, options.id, re_exclude): | ||
301 | o.output_image(oid) | ||
302 | o.output_file_section_images_end() | ||
303 | |||
304 | o.output_file_section_parts_begin() | ||
305 | for oid in foreach_id(o, options.id, re_exclude): | ||
306 | o.output_part(oid) | ||
307 | o.output_file_section_parts_end() | ||
308 | |||
309 | o.output_file_foot() | ||