1 """\
   2 SVG.py - Construct/display SVG scenes.
   3 
   4 The following code is a lightweight wrapper around SVG files. The metaphor
   5 is to construct a scene, add objects to it, and then write it to a file
   6 to display it.
   7 
   8 This program uses ImageMagick to display the SVG files. ImageMagick also 
   9 does a remarkable job of converting SVG files into other formats.
  10 """
  11 
  12 import os
  13 display_prog = 'start' # Command to execute to display images.
  14 
  15 class Scene:
  16     def __init__(self,name="svg",height=400,width=400):
  17         self.name = name
  18         self.items = []
  19         self.height = height
  20         self.width = width
  21         return
  22 
  23     def add(self,item): self.items.append(item)
  24 
  25     def strarray(self):
  26         var = ["<?xml version=\"1.0\"?>\n",
  27                "<svg height=\"%d\" width=\"%d\" >\n" % (self.height,self.width),
  28                " <g style=\"fill-opacity:1.0; stroke:black;\n",
  29                "  stroke-width:1;\">\n"]
  30         for item in self.items: var += item.strarray()
  31         var += [" </g>\n</svg>\n"]
  32         return var
  33 
  34     def write_svg(self,filename=None):
  35         if filename:
  36             self.svgname = filename
  37         else:
  38             self.svgname = self.name + ".svg"
  39         file = open(self.svgname,'w')
  40         file.writelines(self.strarray())
  41         file.close()
  42         return
  43 
  44     def display(self,prog=display_prog):
  45         os.system("%s %s" % (prog,self.svgname))
  46         return
  47 
  48 
  49 class Line:
  50     def __init__(self,start,end):
  51         self.start = start #xy tuple
  52         self.end = end     #xy tuple
  53         return
  54 
  55     def strarray(self):
  56         return ["  <line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" />\n" %\
  57                 (self.start[0],self.start[1],self.end[0],self.end[1])]
  58 
  59 class Polygon:
  60     def __init__(self,*args):
  61         self.points = list(args)
  62         #print "[+]",self.points
  63 
  64     def strarray(self):
  65 
  66         strpoints = '"'
  67         for p in self.points:
  68             strpoints += '%d,%d '%(p[0],p[1])
  69         strpoints += '"'
  70         #print "[+]",strpoints
  71         #strpoints=' '.join([','.join(map(str,p)) for p in self.points])
  72         return ["  <polygon points=%s" % strpoints,
  73                 "   style=\"fill:#cccccc;stroke:#000000;stroke-width:1\"/>"]
  74 
  75 class Circle:
  76     def __init__(self,center,radius,color):
  77         self.center = center #xy tuple
  78         self.radius = radius #xy tuple
  79         self.color = color   #rgb tuple in range(0,256)
  80         return
  81 
  82     def strarray(self):
  83         return ["  <circle cx=\"%d\" cy=\"%d\" r=\"%d\"\n" %\
  84                 (self.center[0],self.center[1],self.radius),
  85                 "    style=\"fill:%s;\"  />\n" % colorstr(self.color)]
  86 
  87 class Rectangle:
  88     def __init__(self,origin,height,width,color):
  89         self.origin = origin
  90         self.height = height
  91         self.width = width
  92         self.color = color
  93         return
  94 
  95     def strarray(self):
  96         return ["  <rect x=\"%d\" y=\"%d\" height=\"%d\"\n" %\
  97                 (self.origin[0],self.origin[1],self.height),
  98                 "    width=\"%d\" style=\"fill:%s;\" />\n" %\
  99                 (self.width,colorstr(self.color))]
 100 
 101 class Text:
 102     def __init__(self,origin,text,size=24):
 103         self.origin = origin
 104         self.text = text
 105         self.size = size
 106         return
 107 
 108     def strarray(self):
 109         return ["  <text x=\"%d\" y=\"%d\" font-size=\"%d\">\n" %\
 110                 (self.origin[0],self.origin[1],self.size),
 111                 "   %s\n" % self.text,
 112                 "  </text>\n"]
 113 
 114 
 115 def colorstr(rgb): return "#%x%x%x" % (rgb[0]/16,rgb[1]/16,rgb[2]/16)
 116 
 117 def test():
 118     scene = Scene('test')
 119     scene.add(Rectangle((100,100),200,200,(0,255,255)))
 120     scene.add(Line((200,200),(200,300)))
 121     scene.add(Line((200,200),(300,200)))
 122     scene.add(Line((200,200),(100,200)))
 123     scene.add(Line((200,200),(200,100)))
 124     scene.add(Circle((200,200),30,(0,0,255)))
 125     scene.add(Circle((200,300),30,(0,255,0)))
 126     scene.add(Circle((300,200),30,(255,0,0)))
 127     scene.add(Circle((100,200),30,(255,255,0)))
 128     scene.add(Circle((200,100),30,(255,0,255)))
 129     scene.add(Text((50,50),"Testing SVG"))
 130     scene.write_svg()
 131     scene.display()
 132     return
 133 
 134 if __name__ == '__main__': test()
web biohackers.net