#!/usr/bin/env python # -*- coding: utf-8 -*- #Copyright (c) 2009,10 Walter Bender #Permission is hereby granted, free of charge, to any person obtaining a copy #of this software and associated documentation files (the "Software"), to deal #in the Software without restriction, including without limitation the rights #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #copies of the Software, and to permit persons to whom the Software is #furnished to do so, subject to the following conditions: #The above copyright notice and this permission notice shall be included in #all copies or substantial portions of the Software. #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. import pygtk pygtk.require('2.0') import gtk import os from gettext import gettext as _ class SVG: def __init__(self): self._x = 0 self._y = 0 self._min_x = 0 self._min_y = 0 self._max_x = 0 self._max_y = 0 self._width = 0 self._height = 0 self.docks = [] self._scale = 1 self._orientation = 0 self._radius = 8 self._stroke_width = 1 self._innie = [False] self._outie = False self._innie_x1 = (9-self._stroke_width)/2 self._innie_y1 = 3 self._innie_x2 = (9-self._stroke_width)/2 self._innie_y2 = (9-self._stroke_width)/2 self._innie_spacer = 9 self._slot = True self._cap = False self._tab = True self._bool = False self._slot_x = 10 self._slot_y = 2 self._porch = False self._porch_x = self._innie_x1+self._innie_x2+4*self._stroke_width self._porch_y = self._innie_y1+self._innie_y2+4*self._stroke_width self._expand_x = 0 self._expand_y = 0 self._else = False self._draw_innies = True self._hide = False self._show = False self._fill = "#00FF00" self._stroke = "#00A000" self._gradiant = False def basic_block(self): (x, y) = self._calculate_x_y() svg = self._new_path(x, y) svg += self._corner(1, -1) svg += self._do_slot() svg += self._rline_to(self._expand_x, 0) xx = self._x svg += self._corner(1, 1) for i in range(len(self._innie)): if self._innie[i] is True: svg += self._do_innie() if i==0 and self._porch is True: svg += self._do_porch() elif len(self._innie)-1 > i: svg += self._rline_to(0, 2*self._innie_y2+self._innie_spacer) svg += self._rline_to(0, self._expand_y) svg += self._corner(-1, 1) svg += self._line_to(xx, self._y) svg += self._rline_to(-self._expand_x, 0) if self._tab: svg += self._do_tab() else: svg += self._do_tail() svg += self._corner(-1, -1) svg += self._rline_to(0, -self._expand_y) if True in self._innie: svg += self._line_to(x, self._radius+self._innie_y2+\ self._stroke_width/2.0) svg += self._do_outie() self._calculate_w_h() svg += self._close_path() svg += self._style() if self._show is True: svg += self._show_dot(12, self._height-12-self._innie_y2-self._slot_y) if self._hide is True: svg += self._hide_dot(self._width-12, self._height-12-self._innie_y2-self._slot_y) svg += self._footer() return self._header() + svg def basic_flow(self): (x, y) = self._calculate_x_y() svg = self._new_path(x, y) svg += self._corner(1, -1) svg += self._do_slot() svg += self._rline_to(self._expand_x, 0) xx = self._x svg += self._corner(1, 1) for i in range(len(self._innie)): if self._innie[i] is True: svg += self._do_innie() svg += self._rline_to(0, 2*self._innie_y2+self._innie_spacer) if self._bool is True: svg += self._rline_to(0,self._radius/2.0) svg += self._do_boolean() svg += self._rline_to(0,self._radius/2.0) if self._else: svg += self._rline_to(self._radius*3+self._slot_x*2, 0) else: svg += self._rline_to(self._radius+self._slot_x, 0) hh = self._x svg += self._corner(1, 1) svg += self._rline_to(-self._radius,0) if self._else: svg += self._do_tab() svg += self._rline_to(-self._radius*2, 0) svg += self._do_tab() svg += self._rline_to(-self._radius, 0) svg += self._rline_to(0, self._expand_y) svg += self._corner(-1, 1) svg += self._line_to(xx, self._y) svg += self._rline_to(-self._expand_x, 0) if self._tab: svg += self._do_tab() else: svg += self._do_tail() svg += self._corner(-1, -1) svg += self._rline_to(0, -self._expand_y) if True in self._innie: svg += self._line_to(x, self._radius+self._innie_y2+\ self._stroke_width) svg += self._close_path() self._calculate_w_h() svg += self._style() if self._hide is True: svg += self._hide_dot(hh, self._height-12-self._innie_y2-self._slot_y) if self._show is True: svg += self._show_dot(hh-24, self._height-12-self._innie_y2-self._slot_y) svg += self._footer() return self._header() + svg def portfolio(self): (x, y) = self._calculate_x_y() x += self._innie_x1+self._innie_x2 svg = self._new_path(x, y) svg += self._corner(1, -1) svg += self._do_slot() xx = self._x svg += self._rline_to(self._expand_x, 0) svg += self._corner(1, 1) svg += self._rline_to(0, self._expand_y) for i in range(len(self._innie)): if self._innie[i] is True and i > 0 and self._draw_innies: svg += self._do_innie() svg += self._rline_to(0, 2*self._innie_y2+self._innie_spacer) else: svg += self._rline_to(0, 2*self._innie_y2+self._innie_spacer) svg += self._corner(-1, 1) svg += self._line_to(xx, self._y) svg += self._do_tab() svg += self._corner(-1, -1) for i in range(len(self._innie)): if self._innie[len(self._innie)-i-1] is True: svg += self._rline_to(0, -2*self._innie_y2-self._innie_spacer) svg += self._do_reverse_innie() else: svg += self._rline_to(0, -2*self._innie_y2-self._innie_spacer) svg += self._close_path() self._calculate_w_h() svg += self._style() svg += self._footer() return self._header() + svg def basic_box(self): self.set_outie(True) x = self._stroke_width/2.0+self._innie_x1+self._innie_x2 svg = self._new_path(x, self._stroke_width/2.0) svg += self._rline_to(self._expand_x, 0) svg += self._rline_to(0, 2*self._radius+self._innie_y2+self._expand_y) svg += self._rline_to(-self._expand_x, 0) svg += self._line_to(x, self._radius+self._innie_y2+\ self._stroke_width/2.0) svg += self._do_outie() svg += self._close_path() self._calculate_w_h() svg += self._style() svg += self._footer() return self._header() + svg def boolean_and_or(self): svg = self._start_boolean(self._stroke_width/2.0, self._radius*5.5+self._stroke_width/2.0+\ self._innie_y2+self._innie_spacer) svg += self._rline_to(0,-self._radius*3.5-self._innie_y2-\ self._innie_spacer-self._stroke_width) svg += self._rarc_to(1, -1) svg += self._rline_to(self._radius/2.0+self._expand_x, 0) xx = self._x svg += self._rline_to(0,self._radius/2.0) svg += self._do_boolean() svg += self._rline_to(0,self._radius*1.5+self._innie_y2+\ self._innie_spacer) svg += self._do_boolean() svg += self._rline_to(0,self._radius/2.0) svg += self._line_to(xx, self._y) svg += self._rline_to(-self._expand_x, 0) svg += self._end_boolean() return self._header() + svg def boolean_not(self): svg = self._start_boolean(self._stroke_width/2.0, self._radius*2.0+self._stroke_width/2.0) svg += self._rline_to(0,-self._stroke_width) svg += self._rarc_to(1, -1) svg += self._rline_to(self._radius/2.0+self._expand_x, 0) xx = self._x svg += self._rline_to(0,self._radius/2.0) svg += self._do_boolean() svg += self._rline_to(0,self._radius/2.0) svg += self._line_to(xx, self._y) svg += self._rline_to(-self._expand_x, 0) svg += self._end_boolean() return self._header() + svg def boolean_compare(self): yoffset = self._radius*2+2*self._innie_y2+\ self._innie_spacer+self._stroke_width/2.0 if self._porch is True: yoffset += self._porch_y svg = self._start_boolean(self._stroke_width/2.0, yoffset) yoffset = -2*self._innie_y2-self._innie_spacer-self._stroke_width if self._porch is True: yoffset -= self._porch_y svg += self._rline_to(0, yoffset) svg += self._rarc_to(1, -1) svg += self._rline_to(self._radius/2.0+self._expand_x, 0) svg += self._rline_to(0,self._radius) xx = self._x svg += self._do_innie() if self._porch is True: svg += self._do_porch() else: svg += self._rline_to(0, 2*self._innie_y2+self._innie_spacer) svg += self._do_innie() svg += self._rline_to(0, self._radius) svg += self._line_to(xx, self._y) svg += self._rline_to(-self._expand_x, 0) svg += self._end_boolean() return self._header() + svg def turtle(self, colors): self._fill, self._stroke = colors[2], "none" svg = self._rect(21, 21, 19.5, 18) self._fill = colors[3] svg += self._rect(3, 3, 30, 24) svg += self._rect(3, 3, 24, 24) svg += self._rect(3, 3, 30, 30) svg += self._rect(3, 3, 24, 30) svg += self._rect(3, 3, 27, 27) svg += self._rect(3, 3, 21, 27) svg += self._rect(3, 3, 33, 27) svg += self._rect(3, 3, 27, 21) svg += self._rect(3, 3, 21, 21) svg += self._rect(3, 3, 33, 21) svg += self._rect(3, 3, 27, 33) svg += self._rect(3, 3, 21, 33) svg += self._rect(3, 3, 33, 33) svg += self._rect(3, 3, 30, 36) svg += self._rect(3, 3, 24, 36) svg += self._rect(3, 3, 30, 18) svg += self._rect(3, 3, 24, 18) svg += self._rect(3, 3, 36, 24) svg += self._rect(3, 3, 36, 30) svg += self._rect(3, 3, 36, 18) svg += self._rect(3, 3, 36, 36) self._fill, self._stroke = colors[0], colors[0] svg += self._turtle_body() self._fill, self._stroke = colors[1], colors[1] svg += self._turtle_shell() self._fill, self._stroke = "#000000", "#000000" svg += self._circle(1.25,32.5,8) svg += self._circle(1.25,27.5,8) svg += self._footer() self._width, self._height = 60, 60 return self._header() + svg def palette(self, width, height): self._width, self._height = width, height self._fill, self._stroke = "#FFD000", "none" svg = self._rect(width, height, 0, 0) svg += self._hide_dot(width-12, height-12) svg += self._footer() return self._header() + svg def toolbar(self, width, height): self._width, self._height = width, height self._fill, self._stroke = "#282828", "none" svg = self._rect(width, height, 0, 0) svg += self._footer() return self._header() + svg def from_file(self, pathname): f = file(pathname, 'r') svg = f.read() f.close() return(svg) # # Utility methods # def set_draw_innies(self, flag=True): self._draw_innies = flag def set_hide(self, flag=False): self._hide = flag def set_show(self, flag=False): self._show = flag def get_width(self): return self._width def get_height(self): return self._height def get_innie_width(self): return (self._innie_x1+self._innie_x2)*self._scale def get_slot_depth(self): return self._slot_y*self._scale def clear_docks(self): self.docks = [] def set_scale(self, scale=1): self._scale = scale def set_orientation(self, orientation=0): self._orientation = orientation def expand(self, w=0, h=0): self._expand_x = w self._expand_y = h def set_stroke_width(self, stroke_width=1.5): self._stroke_width = stroke_width self._calc_porch_params() def set_colors(self, colors=["#00FF00","#00A000"]): self._fill = colors[0] self._stroke = colors[1] def set_fill_color(self, color="#00FF00"): self._fill = color def set_stroke_color(self, color="#00A000"): self._stroke = color def set_gradiant(self, flag=False): self._gradiant = flag def set_innie(self, innie_array=[False]): self._innie = innie_array def set_outie(self, flag=False): self._outie = flag def set_slot(self, flag=True): self._slot = flag if self._slot is True: self._cap = False def set_cap(self, flag=False): self._cap = flag if self._cap is True: self._slot = False def set_tab(self, flag=True): self._tab = flag def set_porch(self, flag=False): self._porch = flag def set_boolean(self, flag=False): self._bool = flag def set_else(self, flag=False): self._else = flag # # Exotic methods # def set_radius(self, radius=8): self._radius = radius def set_innie_params(self, x1=4, y1=3, x2=4, y2=4): self._innie_x1 = x1 self._innie_y1 = y1 self._innie_x2 = x2 self._innie_y2 = y2 self._calc_porch_params() def set_innie_spacer(self, innie_spacer = 0): self._innie_spacer = innie_spacer def set_slot_params(self, x=12, y=4): self._slot_x = x self._slot_y = y def _calc_porch_params(self): self._porch_x = self._innie_x1+self._innie_x2+4*self._stroke_width self._porch_y = self._innie_y1+self._innie_y2+4*self._stroke_width # # SVG helper methods # def _header(self): return "%s%s%s%s%s%s%s%s%.1f%s%s%.1f%s%s%s" % ( "\n", "\n", "\n", self._defs(), self._transform()) def _defs(self): if self._gradiant is True: return "%s%s%s%s%s%s%s%s%s%s%s%s%.1f%s%s%.1f%s%s%.1f%s%s" % ( " \n \n", " \n", " \n", " \n", " \n \n") else: return "" def _transform(self): if self._orientation != 0: orientation = "\n" % ( self._orientation, self._width/2.0, self._height/2.0) else: orientation = "" return "\n%s" % ( self._scale, self._scale, orientation ) def _footer(self): if self._orientation != 0: return " \n\n\n" else: return " \n\n" def _style(self): if self._gradiant is True: fill = "url(#linearGradient5678)" else: fill = self._fill return "%s%s;%s%s;%s%.1f;%s%s" % ( " style=\"fill:",fill, "fill-opacity:1;stroke:",self._stroke, "stroke-width:",self._stroke_width, "stroke-linecap:square;", "stroke-opacity:1;\" />\n") def _circle(self, r, cx, cy): return "%s%s%s%s%s%f%s%f%s%f%s" % ("\n") def _rect(self, w, h, x, y): return "%s%s%s%s%s%f%s%f%s%f%s%f%s" % ("\n") def _turtle_body(self): return "%s%s%s%s%s" % ("\n") def _turtle_shell(self): return "%s%s%s%s%s" % ("\n") def _check_min_max(self): if self._x < self._min_x: self._min_x = self._x if self._y < self._min_y: self._min_y = self._y if self._x > self._max_x: self._max_x = self._x if self._y > self._max_y: self._max_y = self._y def _line_to(self, x, y): if self._x == x and self._y == y: return "" else: self._x = x self._y = y self._check_min_max() return "L %.1f %.1f " % (x, y) def _rline_to(self, dx, dy): if dx == 0 and dy == 0: return "" else: return self._line_to(self._x+dx, self._y+dy) def _arc_to(self, x, y, r, a=90, l=0, s=1): if r == 0: return self._line_to(x, y) else: self._x = x self._y = y self._check_min_max() return "A %.1f %.1f %.1f %d %d %.1f %.1f " % ( r, r, a, l, s, x, y) def _rarc_to(self, sign_x, sign_y, a=90, l=0, s=1): if self._radius == 0: return "" else: x = self._x + sign_x*self._radius y = self._y + sign_y*self._radius return self._arc_to(x, y, self._radius, a, l, s) def _corner(self, sign_x, sign_y, a=90, l=0, s=1): svg_str = "" if self._radius > 0: r2 = self._radius/2.0 if sign_x*sign_y == 1: svg_str +=self._rline_to(sign_x*r2, 0) else: svg_str +=self._rline_to(0, sign_y*r2) x = self._x + sign_x*r2 y = self._y + sign_y*r2 svg_str += self._arc_to(x, y, r2, a, l, s) if sign_x*sign_y == 1: svg_str +=self._rline_to(0, sign_y*r2) else: svg_str +=self._rline_to(sign_x*r2, 0) return svg_str def _new_path(self, x, y): self._min_x = x self._min_y = y self._max_x = x self._max_y = y self._x = x self._y = y return "