index 6881994750e2c767526c76847caf6cf2df67815f..8f67c6090dee855d5144afe6b444be5659661f84 100644 (file)
-#!/usr/bin/env python \r
-'''\r
-Copyright (C) 2006 Jos Hirth, kaioa.com\r
-\r
-This program is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with this program; if not, write to the Free Software\r
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-'''\r
-import sys, copy, optparse, simplestyle, inkex\r
-\r
-import xml.xpath\r
-\r
-color_props_fill=('fill:','stop-color:','flood-color:','lighting-color:')\r
-color_props_stroke=('stroke:',)\r
-color_props = color_props_fill + color_props_stroke\r
-\r
-\r
-class ColorEffect(inkex.Effect):\r
- def __init__(self):\r
- inkex.Effect.__init__(self,use_minidom=True)\r
- self.visited = []\r
-\r
- def effect(self):\r
- if len(self.selected)==0:\r
- self.getAttribs(self.document)\r
- else:\r
- for id,node in self.selected.iteritems():\r
- self.getAttribs(node)\r
-\r
- def getAttribs(self,node):\r
- self.changeStyle(node)\r
- if node.hasChildNodes():\r
- childs=node.childNodes\r
- for child in childs:\r
- self.getAttribs(child)\r
- \r
- def changeStyle(self,node):\r
- if node.hasAttributes():\r
- style=node.getAttribute('style') # fixme: this will break for presentation attributes!\r
- if style!='':\r
- #inkex.debug('old style:'+style)\r
- styles=style.split(';')\r
- for i in range(len(styles)):\r
- for c in range(len(color_props)):\r
- if styles[i].startswith(color_props[c]):\r
- styles[i]=color_props[c]+self.process_prop(styles[i][len(color_props[c]):])\r
- #inkex.debug('new style:'+';'.join(styles))\r
- node.setAttribute('style',';'.join(styles))\r
- '''\r
- def changeStyle(self,node):\r
- if node.hasAttributes():\r
- sa=node.getAttribute('style')\r
- if sa!='':\r
- debug(sa)\r
- styles=simplestyle.parseStyle(sa)\r
- for c in range(len(colortags)):\r
- if colortags[c] in styles.keys():\r
- styles[colortags[c]]=self.process_prop(styles[colortags[c]])\r
- node.setAttribute('style',simplestyle.formatStyle(styles))\r
- ''' \r
- def process_prop(self,col):\r
- #debug('got:'+col)\r
- if simplestyle.isColor(col):\r
- c=simplestyle.parseColor(col)\r
- col='#'+self.colmod(c[0],c[1],c[2])\r
- #debug('made:'+col)\r
- if col.startswith('url(#'):\r
- id = col[len('url(#'):col.find(')')]\r
- #inkex.debug('ID:' + id )\r
- path = '//*[@id="%s"]' % id\r
- for node in xml.xpath.Evaluate(path,self.document):\r
- self.process_gradient(node)\r
- return col\r
-\r
- def process_gradient(self, node):\r
- if node.hasAttributes(): \r
- this_id=node.getAttribute('id')\r
- if this_id in self.visited:\r
- # prevent multiple processing of the same gradient if it is used by more than one selected object\r
- #inkex.debug("already had: " + this_id)\r
- return\r
- self.visited.append(this_id)\r
- #inkex.debug("visited: " + str(self.visited))\r
- self.changeStyle(node)\r
- if node.hasChildNodes():\r
- for child in node.childNodes:\r
- self.process_gradient(child)\r
- if node.hasAttributes(): \r
- href=node.getAttribute('xlink:href')\r
- if href.startswith('#'):\r
- id = href[len('#'):len(href)]\r
- #inkex.debug('ID:' + id )\r
- path = '//*[@id="%s"]' % id\r
- for node in xml.xpath.Evaluate(path,self.document):\r
- self.process_gradient(node)\r
- \r
- def colmod(self,r,g,b):\r
- pass\r
-\r
- def rgb_to_hsl(self,r, g, b):\r
- rgb_max = max (max (r, g), b)\r
- rgb_min = min (min (r, g), b)\r
- delta = rgb_max - rgb_min\r
- hsl = [0.0, 0.0, 0.0]\r
- hsl[2] = (rgb_max + rgb_min)/2.0\r
- if delta == 0:\r
- hsl[0] = 0.0\r
- hsl[1] = 0.0\r
- else:\r
- if hsl[2] <= 0.5:\r
- hsl[1] = delta / (rgb_max + rgb_min)\r
- else:\r
- hsl[1] = delta / (2 - rgb_max - rgb_min)\r
- if r == rgb_max:\r
- hsl[0] = (g - b) / delta\r
- else:\r
- if g == rgb_max:\r
- hsl[0] = 2.0 + (b - r) / delta\r
- else:\r
- if b == rgb_max:\r
- hsl[0] = 4.0 + (r - g) / delta\r
- hsl[0] = hsl[0] / 6.0\r
- if hsl[0] < 0:\r
- hsl[0] = hsl[0] + 1\r
- if hsl[0] > 1:\r
- hsl[0] = hsl[0] - 1\r
- return hsl\r
-\r
- def hue_2_rgb (self, v1, v2, h):\r
- if h < 0:\r
- h += 6.0\r
- if h > 6:\r
- h -= 6.0\r
- if h < 1:\r
- return v1 + (v2 - v1) * h\r
- if h < 3:\r
- return v2\r
- if h < 4:\r
- return v1 + (v2 - v1) * (4 - h)\r
- return v1\r
-\r
- def hsl_to_rgb (self,h, s, l):\r
- rgb = [0, 0, 0]\r
- if s == 0:\r
- rgb[0] = l\r
- rgb[1] = l\r
- rgb[2] = l\r
- else:\r
- if l < 0.5:\r
- v2 = l * (1 + s)\r
- else:\r
- v2 = l + s - l*s\r
- v1 = 2*l - v2\r
- rgb[0] = self.hue_2_rgb (v1, v2, h*6 + 2.0)\r
- rgb[1] = self.hue_2_rgb (v1, v2, h*6)\r
- rgb[2] = self.hue_2_rgb (v1, v2, h*6 - 2.0)\r
- return rgb\r
+#!/usr/bin/env python
+'''
+Copyright (C) 2006 Jos Hirth, kaioa.com
+Copyright (C) 2007 Aaron C. Spike
+Copyright (C) 2009 Monash University
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+'''
+import sys, copy, simplestyle, inkex
+import random
+
+color_props_fill = ('fill', 'stop-color', 'flood-color', 'lighting-color')
+color_props_stroke = ('stroke',)
+color_props = color_props_fill + color_props_stroke
+
+
+class ColorEffect(inkex.Effect):
+ def __init__(self):
+ inkex.Effect.__init__(self)
+ self.visited = []
+
+ def effect(self):
+ if len(self.selected)==0:
+ self.getAttribs(self.document.getroot())
+ else:
+ for id,node in self.selected.iteritems():
+ self.getAttribs(node)
+
+ def getAttribs(self,node):
+ self.changeStyle(node)
+ for child in node:
+ self.getAttribs(child)
+
+ def changeStyle(self,node):
+ for attr in color_props:
+ val = node.get(attr)
+ if val:
+ new_val = self.process_prop(val)
+ if new_val != val:
+ node.set(attr, new_val)
+
+ if node.attrib.has_key('style'):
+ # References for style attribute:
+ # http://www.w3.org/TR/SVG11/styling.html#StyleAttribute,
+ # http://www.w3.org/TR/CSS21/syndata.html
+ #
+ # The SVG spec is ambiguous as to how style attributes should be parsed.
+ # For example, it isn't clear whether semicolons are allowed to appear
+ # within strings or comments, or indeed whether comments are allowed to
+ # appear at all.
+ #
+ # The processing here is just something simple that should usually work,
+ # without trying too hard to get everything right.
+ # (Won't work for the pathalogical case that someone escapes a property
+ # name, probably does the wrong thing if colon or semicolon is used inside
+ # a comment or string value.)
+ style = node.get('style') # fixme: this will break for presentation attributes!
+ if style:
+ #inkex.debug('old style:'+style)
+ declarations = style.split(';')
+ for i,decl in enumerate(declarations):
+ parts = decl.split(':', 2)
+ if len(parts) == 2:
+ (prop, val) = parts
+ prop = prop.strip().lower()
+ if prop in color_props:
+ val = val.strip()
+ new_val = self.process_prop(val)
+ if new_val != val:
+ declarations[i] = prop + ':' + new_val
+ #inkex.debug('new style:'+';'.join(declarations))
+ node.set('style', ';'.join(declarations))
+
+ def process_prop(self,col):
+ #debug('got:'+col)
+ if simplestyle.isColor(col):
+ c=simplestyle.parseColor(col)
+ col='#'+self.colmod(c[0],c[1],c[2])
+ #debug('made:'+col)
+ if col.startswith('url(#'):
+ id = col[len('url(#'):col.find(')')]
+ newid = '%s-%d' % (id, int(random.random() * 1000))
+ #inkex.debug('ID:' + id )
+ path = '//*[@id="%s"]' % id
+ for node in self.document.xpath(path, namespaces=inkex.NSS):
+ self.process_gradient(node, newid)
+ col = 'url(#%s)' % newid
+ return col
+
+ def process_gradient(self, node, newid):
+ #if node.hasAttributes():
+ #this_id=node.getAttribute('id')
+ #if this_id in self.visited:
+ ## prevent multiple processing of the same gradient if it is used by more than one selected object
+ ##inkex.debug("already had: " + this_id)
+ #return
+ #self.visited.append(this_id)
+ #inkex.debug("visited: " + str(self.visited))
+ newnode = copy.deepcopy(node)
+ newnode.set('id', newid)
+ node.getparent().append(newnode)
+ self.changeStyle(newnode)
+ for child in newnode:
+ self.changeStyle(child)
+ xlink = inkex.addNS('href','xlink')
+ if newnode.attrib.has_key(xlink):
+ href=newnode.get(xlink)
+ if href.startswith('#'):
+ id = href[len('#'):len(href)]
+ #inkex.debug('ID:' + id )
+ newhref = '%s-%d' % (id, int(random.random() * 1000))
+ newnode.set(xlink, '#%s' % newhref)
+ path = '//*[@id="%s"]' % id
+ for node in self.document.xpath(path, namespaces=inkex.NSS):
+ self.process_gradient(node, newhref)
+
+ def colmod(self,r,g,b):
+ pass
+
+ def rgb_to_hsl(self,r, g, b):
+ rgb_max = max (max (r, g), b)
+ rgb_min = min (min (r, g), b)
+ delta = rgb_max - rgb_min
+ hsl = [0.0, 0.0, 0.0]
+ hsl[2] = (rgb_max + rgb_min)/2.0
+ if delta == 0:
+ hsl[0] = 0.0
+ hsl[1] = 0.0
+ else:
+ if hsl[2] <= 0.5:
+ hsl[1] = delta / (rgb_max + rgb_min)
+ else:
+ hsl[1] = delta / (2 - rgb_max - rgb_min)
+ if r == rgb_max:
+ hsl[0] = (g - b) / delta
+ else:
+ if g == rgb_max:
+ hsl[0] = 2.0 + (b - r) / delta
+ else:
+ if b == rgb_max:
+ hsl[0] = 4.0 + (r - g) / delta
+ hsl[0] = hsl[0] / 6.0
+ if hsl[0] < 0:
+ hsl[0] = hsl[0] + 1
+ if hsl[0] > 1:
+ hsl[0] = hsl[0] - 1
+ return hsl
+
+ def hue_2_rgb (self, v1, v2, h):
+ if h < 0:
+ h += 6.0
+ if h > 6:
+ h -= 6.0
+ if h < 1:
+ return v1 + (v2 - v1) * h
+ if h < 3:
+ return v2
+ if h < 4:
+ return v1 + (v2 - v1) * (4 - h)
+ return v1
+
+ def hsl_to_rgb (self,h, s, l):
+ rgb = [0, 0, 0]
+ if s == 0:
+ rgb[0] = l
+ rgb[1] = l
+ rgb[2] = l
+ else:
+ if l < 0.5:
+ v2 = l * (1 + s)
+ else:
+ v2 = l + s - l*s
+ v1 = 2*l - v2
+ rgb[0] = self.hue_2_rgb (v1, v2, h*6 + 2.0)
+ rgb[1] = self.hue_2_rgb (v1, v2, h*6)
+ rgb[2] = self.hue_2_rgb (v1, v2, h*6 - 2.0)
+ return rgb
+
+# vi: set autoindent shiftwidth=2 tabstop=8 expandtab softtabstop=2 :