comparison tools/svg2code.py @ 822:586e50f82c1f

Unify coding style tag for emacs and vim.
author Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
date Tue, 14 Sep 2010 01:08:39 +0800
parents bb4f651090bf
children
comparison
equal deleted inserted replaced
821:bfdc82bbd6e4 822:586e50f82c1f
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*-
3 # vim: sw=4:ts=8:sts=4
2 from xml.dom.minidom import parse 4 from xml.dom.minidom import parse
3 import sys 5 import sys
4 import re 6 import re
5 7
6 svgns='http://www.w3.org/2000/svg' 8 svgns='http://www.w3.org/2000/svg'
129 prop_map = node.style_map 131 prop_map = node.style_map
130 except: 132 except:
131 style_str = node.getAttribute('style') 133 style_str = node.getAttribute('style')
132 prop_map = get_style_map(style_str) 134 prop_map = get_style_map(style_str)
133 pass 135 pass
134 136
135 if node.hasAttribute('fill-opacity'): 137 if node.hasAttribute('fill-opacity'):
136 opacity = float(node.getAttribute('fill-opacity')) 138 opacity = float(node.getAttribute('fill-opacity'))
137 elif node.hasAttribute('opacity'): 139 elif node.hasAttribute('opacity'):
138 opacity = float(node.getAttribute('opacity')) 140 opacity = float(node.getAttribute('opacity'))
139 else: 141 else:
232 # This function calculate the ellipse with information from SVG path data. 234 # This function calculate the ellipse with information from SVG path data.
233 # 235 #
234 # \see calc_center_and_x_aix() 236 # \see calc_center_and_x_aix()
235 def _calc_ellipse_of_arc(x0, y0, rx, ry, x_rotate, large, sweep, x, y): 237 def _calc_ellipse_of_arc(x0, y0, rx, ry, x_rotate, large, sweep, x, y):
236 import math 238 import math
237 239
238 _sin = math.sin(x_rotate) 240 _sin = math.sin(x_rotate)
239 _cos = math.cos(x_rotate) 241 _cos = math.cos(x_rotate)
240 242
241 nrx = x * _cos + y * _sin # Not Rotated X 243 nrx = x * _cos + y * _sin # Not Rotated X
242 nry = x * -_sin + y * _cos 244 nry = x * -_sin + y * _cos
243 nrx0 = x0 * _cos + y0 * _sin 245 nrx0 = x0 * _cos + y0 * _sin
244 nry0 = x0 * -_sin + y0 * _cos 246 nry0 = x0 * -_sin + y0 * _cos
245 247
246 udx = (nrx - nrx0) / 2 / rx # ux - umx 248 udx = (nrx - nrx0) / 2 / rx # ux - umx
247 udy = (nry - nry0) / 2 / ry # uy - umy 249 udy = (nry - nry0) / 2 / ry # uy - umy
248 umx = (nrx + nrx0) / 2 / rx 250 umx = (nrx + nrx0) / 2 / rx
249 umy = (nry + nry0) / 2 / ry 251 umy = (nry + nry0) / 2 / ry
250 252
277 udcy = -udcy 279 udcy = -udcy
278 pass 280 pass
279 281
280 nrcx = rx * (udcx + umx) 282 nrcx = rx * (udcx + umx)
281 nrcy = ry * (udcy + umy) 283 nrcy = ry * (udcy + umy)
282 284
283 cx = nrcx * _cos - nrcy * _sin 285 cx = nrcx * _cos - nrcy * _sin
284 cy = nrcx * _sin + nrcy * _cos 286 cy = nrcx * _sin + nrcy * _cos
285 287
286 return cx, cy 288 return cx, cy
287 289
288 # M x y : Move to (x,y) 290 # M x y : Move to (x,y)
289 # Z : close path 291 # Z : close path
290 # L x y : lineto (x,y) 292 # L x y : lineto (x,y)
311 'T': 2, 't':2, 313 'T': 2, 't':2,
312 'A': 7, 'a':7} 314 'A': 7, 'a':7}
313 315
314 def _angle_rotated_ellipse(x, y, rx, ry, x_rotate): 316 def _angle_rotated_ellipse(x, y, rx, ry, x_rotate):
315 import math 317 import math
316 318
317 _cos = math.cos(x_rotate) 319 _cos = math.cos(x_rotate)
318 _sin = math.sin(x_rotate) 320 _sin = math.sin(x_rotate)
319 321
320 nrx = (x * _cos + y * _sin) / rx 322 nrx = (x * _cos + y * _sin) / rx
321 nry = (-x * _sin + y * _cos) / ry 323 nry = (-x * _sin + y * _cos) / ry
322 324
323 xy_tan = nry / nrx 325 xy_tan = nry / nrx
324 xy_angle = math.atan(xy_tan) 326 xy_angle = math.atan(xy_tan)
325 327
326 if nrx < 0: 328 if nrx < 0:
327 xy_angle = math.pi + xy_angle 329 xy_angle = math.pi + xy_angle
328 pass 330 pass
329 331
330 return xy_angle 332 return xy_angle
331 333
332 def rotate(x, y, angle): 334 def rotate(x, y, angle):
333 import math 335 import math
334 _cos = math.cos(angle) 336 _cos = math.cos(angle)
338 return nx, ny 340 return nx, ny
339 341
340 def translate_path_data(data, codefo): 342 def translate_path_data(data, codefo):
341 import string 343 import string
342 import math 344 import math
343 345
344 temp = data.split() 346 temp = data.split()
345 fields=[] 347 fields=[]
346 for f in temp: 348 for f in temp:
347 for s in f.split(','): 349 for s in f.split(','):
348 if s != '': 350 if s != '':
383 if cmd == 'v': 385 if cmd == 'v':
384 arg = float(f) 386 arg = float(f)
385 pnts.append(pnts[-2]) 387 pnts.append(pnts[-2])
386 pnts.append(arg + pnts[-2]) 388 pnts.append(arg + pnts[-2])
387 continue 389 continue
388 390
389 arg = float(f) 391 arg = float(f)
390 if (cmd not in 'am') and (cmd in string.lowercase): 392 if (cmd not in 'am') and (cmd in string.lowercase):
391 # relative and not arc or moveto 393 # relative and not arc or moveto
392 arg = arg + pnts[-2] 394 arg = arg + pnts[-2]
393 pass 395 pass
422 c2x, c2y = rotate(rx, ry, x_rotate) 424 c2x, c2y = rotate(rx, ry, x_rotate)
423 c2x, c2y = c2x + cx, c2y + cy 425 c2x, c2y = c2x + cx, c2y + cy
424 426
425 c3x, c3y = rotate(-rx, ry, x_rotate) 427 c3x, c3y = rotate(-rx, ry, x_rotate)
426 c3x, c3y = c3x + cx, c3y + cy 428 c3x, c3y = c3x + cx, c3y + cy
427 429
428 pnts[-7:] = [c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, abs_x, abs_y] 430 pnts[-7:] = [c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, abs_x, abs_y]
429 431
430 start_angle = _angle_rotated_ellipse(x0 - cx, y0 - cy, 432 start_angle = _angle_rotated_ellipse(x0 - cx, y0 - cy,
431 rx, ry, x_rotate) 433 rx, ry, x_rotate)
432 stop_angle = _angle_rotated_ellipse(x - cx, y - cy, 434 stop_angle = _angle_rotated_ellipse(x - cx, y - cy,
433 rx, ry, x_rotate) 435 rx, ry, x_rotate)
434 436
435 # sweep == 1 for positive-angle direction 437 # sweep == 1 for positive-angle direction
436 # sweep == 0 for negative-angle direction 438 # sweep == 0 for negative-angle direction
437 if start_angle > stop_angle and sweep: 439 if start_angle > stop_angle and sweep:
438 stop_angle = math.pi * 2 + stop_angle 440 stop_angle = math.pi * 2 + stop_angle
439 elif start_angle < stop_angle and not sweep: 441 elif start_angle < stop_angle and not sweep:
440 start_angle = math.pi * 2 + start_angle 442 start_angle = math.pi * 2 + start_angle
441 pass 443 pass
442 444
443 float_args.extend([cx, cy, rx, ry, 445 float_args.extend([cx, cy, rx, ry,
444 start_angle, stop_angle, x_rotate]) 446 start_angle, stop_angle, x_rotate])
445 pass 447 pass
446 pass 448 pass
447 return commands, pnts, float_args 449 return commands, pnts, float_args
546 map = translate_font_style(tspan, codefo) 548 map = translate_font_style(tspan, codefo)
547 tspan.style_map = map 549 tspan.style_map = map
548 pass 550 pass
549 if tspan.hasAttribute('x'): 551 if tspan.hasAttribute('x'):
550 # Render the tspan as an independent text if the x 552 # Render the tspan as an independent text if the x
551 # attribute is defined. All elements inside 553 # attribute is defined. All elements inside
552 # the tspan will be ignore by the outter text or tspan elements. 554 # the tspan will be ignore by the outter text or tspan elements.
553 # FIXME: We need to apply the style map recursively. 555 # FIXME: We need to apply the style map recursively.
554 merge_style(tspan, text) 556 merge_style(tspan, text)
555 translate_text(tspan, coord_id, codefo, doc) 557 translate_text(tspan, coord_id, codefo, doc)
556 return '' 558 return ''
583 else: 585 else:
584 font_sz = float(style_map['font-size']) 586 font_sz = float(style_map['font-size'])
585 print >> codefo, 'PANGO_SIZE(%d,%d,%d)dnl' % (font_sz*1024,start,end) 587 print >> codefo, 'PANGO_SIZE(%d,%d,%d)dnl' % (font_sz*1024,start,end)
586 pass 588 pass
587 pass 589 pass
588 590
589 if style_map.has_key('font-style'): 591 if style_map.has_key('font-style'):
590 font_style = style_map['font-style'].lower() 592 font_style = style_map['font-style'].lower()
591 if font_style == 'normal': 593 if font_style == 'normal':
592 print >> codefo, 'PANGO_STYLE(PANGO_STYLE_NORMAL,%d,%d)dnl' % (start,end) 594 print >> codefo, 'PANGO_STYLE(PANGO_STYLE_NORMAL,%d,%d)dnl' % (start,end)
593 elif font_style == 'italic': 595 elif font_style == 'italic':
672 pass 674 pass
673 pass 675 pass
674 676
675 def stext_generate_font_attributes(text, attrs, coord_id, codefo, doc): 677 def stext_generate_font_attributes(text, attrs, coord_id, codefo, doc):
676 text_id = _get_id(text) 678 text_id = _get_id(text)
677 679
678 for start, end, node in attrs: 680 for start, end, node in attrs:
679 style_map = node.style_map 681 style_map = node.style_map
680 682
681 font_sz = 10 683 font_sz = 10
682 if style_map.has_key('font-size'): 684 if style_map.has_key('font-size'):
683 fsz = style_map['font-size'] 685 fsz = style_map['font-size']
684 if fsz.endswith('px'): 686 if fsz.endswith('px'):
685 font_sz = float(fsz[:-2]) 687 font_sz = float(fsz[:-2])
686 else: 688 else:
687 font_sz = float(fsz) 689 font_sz = float(fsz)
688 pass 690 pass
689 pass 691 pass
690 692
691 if style_map.has_key('font-family'): 693 if style_map.has_key('font-family'):
692 font_family = style_map['font-family'] 694 font_family = style_map['font-family']
693 else: 695 else:
694 font_family = 'serif' 696 font_family = 'serif'
695 pass 697 pass
696 698
697 font_slant = 0 699 font_slant = 0
698 if style_map.has_key('font-style'): 700 if style_map.has_key('font-style'):
699 fn_style = style_map['font-style'] 701 fn_style = style_map['font-style']
700 if fn_style == 'normal': 702 if fn_style == 'normal':
701 font_slant = 0 703 font_slant = 0
704 elif fn_style == 'oblique': 706 elif fn_style == 'oblique':
705 font_slant = 110 707 font_slant = 110
706 else: 708 else:
707 raise ValueError, '%s is not a valid font-style' % (fn_style) 709 raise ValueError, '%s is not a valid font-style' % (fn_style)
708 pass 710 pass
709 711
710 font_weight = 80 712 font_weight = 80
711 if style_map.has_key('font-weight'): 713 if style_map.has_key('font-weight'):
712 fn_weight = style_map['font-weight'] 714 fn_weight = style_map['font-weight']
713 if fn_weight == 'normal': 715 if fn_weight == 'normal':
714 font_weight = 80 716 font_weight = 80
724 font_weight = 70 726 font_weight = 70
725 else: 727 else:
726 font_weight = int(fn_weight) 728 font_weight = int(fn_weight)
727 pass 729 pass
728 pass 730 pass
729 731
730 print >> codefo, 'STYLE_BLOCK([%s], %d, [%s], %f, %d, %d)dnl' % ( 732 print >> codefo, 'STYLE_BLOCK([%s], %d, [%s], %f, %d, %d)dnl' % (
731 text_id, end - start, font_family, font_sz, 733 text_id, end - start, font_family, font_sz,
732 font_slant, font_weight) 734 font_slant, font_weight)
733 pass 735 pass
734 pass 736 pass
735 737
736 def stext_gen_text(text, coord_id, codefo, doc, txt_strs, attrs): 738 def stext_gen_text(text, coord_id, codefo, doc, txt_strs, attrs):
737 if not txt_strs: 739 if not txt_strs:
738 return 740 return
739 741
740 text_id = _get_id(text) 742 text_id = _get_id(text)
741 x = float(text.getAttribute('x')) 743 x = float(text.getAttribute('x'))
742 y = float(text.getAttribute('y')) 744 y = float(text.getAttribute('y'))
743 print >> codefo, 'dnl' 745 print >> codefo, 'dnl'
744 print >> codefo, \ 746 print >> codefo, \
755 @check_mbname 757 @check_mbname
756 def translate_text(text, coord_id, codefo, doc): 758 def translate_text(text, coord_id, codefo, doc):
757 coord_id = translate_shape_transform(text, coord_id, codefo) 759 coord_id = translate_shape_transform(text, coord_id, codefo)
758 try: 760 try:
759 map = text.style_map 761 map = text.style_map
760 except: 762 except:
761 map = translate_font_style(text, codefo) 763 map = translate_font_style(text, codefo)
762 text.style_map = map 764 text.style_map = map
763 pass 765 pass
764 attrs = [] 766 attrs = []
765 attr = [0, 0, text] 767 attr = [0, 0, text]
779 pass 781 pass
780 782
781 @check_mbname 783 @check_mbname
782 def translate_image(image, coord_id, codefo, doc): 784 def translate_image(image, coord_id, codefo, doc):
783 coord_id = translate_shape_transform(image, coord_id, codefo) 785 coord_id = translate_shape_transform(image, coord_id, codefo)
784 786
785 image_id = _get_id(image) 787 image_id = _get_id(image)
786 if not image.hasAttributeNS(xlinkns, 'href'): 788 if not image.hasAttributeNS(xlinkns, 'href'):
787 raise ValueError, 'image %s must has a href attribute.' % (image_id) 789 raise ValueError, 'image %s must has a href attribute.' % (image_id)
788 href = image.getAttributeNS(xlinkns, 'href') 790 href = image.getAttributeNS(xlinkns, 'href')
789 if image.hasAttribute('x'): 791 if image.hasAttribute('x'):
813 print >> codefo, 'dnl' 815 print >> codefo, 'dnl'
814 print >> codefo, \ 816 print >> codefo, \
815 'ADD_IMAGE([%s], [%s], %f, %f, %f, %f, [%s])dnl' % ( 817 'ADD_IMAGE([%s], [%s], %f, %f, %f, %f, [%s])dnl' % (
816 image_id, href, x, y, width, height, coord_id) 818 image_id, href, x, y, width, height, coord_id)
817 pass 819 pass
818 820
819 821
820 reo_func = re.compile('([a-zA-Z]+)\\([^\\)]*\\)') 822 reo_func = re.compile('([a-zA-Z]+)\\([^\\)]*\\)')
821 reo_translate = re.compile('translate\\(([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)\\)') 823 reo_translate = re.compile('translate\\(([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)\\)')
822 reo_matrix = re.compile('matrix\\(([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)\\)') 824 reo_matrix = re.compile('matrix\\(([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)\\)')
823 def translate_transform(coord_id, transform, codefo, prefix): 825 def translate_transform(coord_id, transform, codefo, prefix):
887 for scene in scenes_node.childNodes: 889 for scene in scenes_node.childNodes:
888 if scene.localName != 'scene' or \ 890 if scene.localName != 'scene' or \
889 not scene.hasAttribute('ref') or \ 891 not scene.hasAttribute('ref') or \
890 not scene.hasAttribute('start'): 892 not scene.hasAttribute('start'):
891 continue 893 continue
892 894
893 start_str = scene.getAttribute('start') 895 start_str = scene.getAttribute('start')
894 start = end = int(start_str) 896 start = end = int(start_str)
895 if scene.hasAttribute('end'): 897 if scene.hasAttribute('end'):
896 end_str = scene.getAttribute('end') 898 end_str = scene.getAttribute('end')
897 end = int(end_str) 899 end = int(end_str)
898 pass 900 pass
899 ref = scene.getAttribute('ref') 901 ref = scene.getAttribute('ref')
900 902
901 while len(scenes) <= end: 903 while len(scenes) <= end:
902 scenes.append([]) 904 scenes.append([])
903 pass 905 pass
904 906
905 for i in range(start, end + 1): 907 for i in range(start, end + 1):
906 scenes[i].append(ref) 908 scenes[i].append(ref)
907 pass 909 pass
908 pass 910 pass
909 911
923 if node.localName == 'svg' and node.namespaceURI == svgns: 925 if node.localName == 'svg' and node.namespaceURI == svgns:
924 break; 926 break;
925 pass 927 pass
926 else: 928 else:
927 raise ValueErr, 'no any svg tag node.' 929 raise ValueErr, 'no any svg tag node.'
928 930
929 svg = node 931 svg = node
930 for node in svg.childNodes: 932 for node in svg.childNodes:
931 if node.localName == 'defs' and node.namespaceURI == svgns: 933 if node.localName == 'defs' and node.namespaceURI == svgns:
932 translate_defs(node, codefo, dom) 934 translate_defs(node, codefo, dom)
933 elif node.localName == 'metadata' and node.namespaceURI == svgns: 935 elif node.localName == 'metadata' and node.namespaceURI == svgns:
944 pass 946 pass
945 947
946 if __name__ == '__main__': 948 if __name__ == '__main__':
947 from os import path 949 from os import path
948 import optparse 950 import optparse
949 951
950 usage='usage: %prog [options] <SVG file> [<output>]' 952 usage='usage: %prog [options] <SVG file> [<output>]'
951 parser = optparse.OptionParser(usage=usage) 953 parser = optparse.OptionParser(usage=usage)
952 parser.add_option('-s', '--stext', dest='stext', 954 parser.add_option('-s', '--stext', dest='stext',
953 action='store_true', default=False, 955 action='store_true', default=False,
954 help='Use sh_stext instead of sh_text'); 956 help='Use sh_stext instead of sh_text');
955 options, args = parser.parse_args() 957 options, args = parser.parse_args()
956 958
957 if len(args) == 2: 959 if len(args) == 2:
958 svgfn = args[0] 960 svgfn = args[0]
959 codefn = args[1] 961 codefn = args[1]
960 elif len(args) == 1: 962 elif len(args) == 1:
961 svgfn = args[0] 963 svgfn = args[0]
962 codefn = 'out.mb' 964 codefn = 'out.mb'
963 else: 965 else:
964 parser.print_help() 966 parser.print_help()
965 sys.exit(1) 967 sys.exit(1)
966 pass 968 pass
967 969
968 struct_name = path.basename(codefn).split('.')[0] 970 struct_name = path.basename(codefn).split('.')[0]
969 971
970 if options.stext: 972 if options.stext:
971 gen_text = stext_gen_text 973 gen_text = stext_gen_text
972 else: 974 else: