Code

Attempt fix for Bug #178022
[inkscape.git] / share / extensions / coloreffect.py
1 #!/usr/bin/env python \r
2 '''\r
3 Copyright (C) 2006 Jos Hirth, kaioa.com\r
4 Copyright (C) 2007 Aaron C. Spike\r
5 \r
6 This program is free software; you can redistribute it and/or modify\r
7 it under the terms of the GNU General Public License as published by\r
8 the Free Software Foundation; either version 2 of the License, or\r
9 (at your option) any later version.\r
10 \r
11 This program is distributed in the hope that it will be useful,\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 GNU General Public License for more details.\r
15 \r
16 You should have received a copy of the GNU General Public License\r
17 along with this program; if not, write to the Free Software\r
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 '''\r
20 import sys, copy, optparse, simplestyle, inkex, copy\r
21 \r
22 import random\r
23 \r
24 color_props_fill=('fill:','stop-color:','flood-color:','lighting-color:')\r
25 color_props_stroke=('stroke:',)\r
26 color_props = color_props_fill + color_props_stroke\r
27 \r
28 \r
29 class ColorEffect(inkex.Effect):\r
30   def __init__(self):\r
31     inkex.Effect.__init__(self)\r
32     self.visited = []\r
33 \r
34   def effect(self):\r
35     if len(self.selected)==0:\r
36       self.getAttribs(self.document.getroot())\r
37     else:\r
38       for id,node in self.selected.iteritems():\r
39         self.getAttribs(node)\r
40 \r
41   def getAttribs(self,node):\r
42     self.changeStyle(node)\r
43     for child in node:\r
44       self.getAttribs(child)\r
45   \r
46   def changeStyle(self,node):\r
47     if node.attrib.has_key('style'):\r
48       style=node.get('style') # fixme: this will break for presentation attributes!\r
49       if style!='':\r
50         #inkex.debug('old style:'+style)\r
51         styles=style.split(';')\r
52         for i in range(len(styles)):\r
53           for c in range(len(color_props)):\r
54             if styles[i].startswith(color_props[c]):\r
55               styles[i]=color_props[c]+self.process_prop(styles[i][len(color_props[c]):])\r
56         #inkex.debug('new style:'+';'.join(styles))\r
57         node.set('style',';'.join(styles))\r
58 \r
59   def process_prop(self,col):\r
60     #debug('got:'+col)\r
61     if simplestyle.isColor(col):\r
62       c=simplestyle.parseColor(col)\r
63       col='#'+self.colmod(c[0],c[1],c[2])\r
64       #debug('made:'+col)\r
65     if col.startswith('url(#'):\r
66       id = col[len('url(#'):col.find(')')]\r
67       newid = '%s-%d' % (id, int(random.random() * 1000))\r
68       #inkex.debug('ID:' + id )\r
69       path = '//*[@id="%s"]' % id\r
70       for node in self.document.xpath(path, namespaces=inkex.NSS):\r
71         self.process_gradient(node, newid)\r
72       col = 'url(#%s)' % newid\r
73     return col\r
74 \r
75   def process_gradient(self, node, newid):\r
76     #if node.hasAttributes():                           \r
77        #this_id=node.getAttribute('id')\r
78        #if this_id in self.visited:\r
79          ## prevent multiple processing of the same gradient if it is used by more than one selected object\r
80          ##inkex.debug("already had: " + this_id)\r
81          #return\r
82        #self.visited.append(this_id)\r
83        #inkex.debug("visited: " + str(self.visited))\r
84     newnode = copy.deepcopy(node)\r
85     newnode.set('id', newid)\r
86     node.getparent().append(newnode)\r
87     self.changeStyle(newnode)\r
88     for child in newnode:\r
89       self.changeStyle(child)\r
90     xlink = inkex.addNS('href','xlink')\r
91     if newnode.attrib.has_key(xlink):\r
92       href=newnode.get(xlink)\r
93       if href.startswith('#'):\r
94         id = href[len('#'):len(href)]\r
95         #inkex.debug('ID:' + id )\r
96         newhref = '%s-%d' % (id, int(random.random() * 1000))\r
97         newnode.set(xlink, '#%s' % newhref)\r
98         path = '//*[@id="%s"]' % id\r
99         for node in self.document.xpath(path, namespaces=inkex.NSS):\r
100           self.process_gradient(node, newhref)\r
101  \r
102   def colmod(self,r,g,b):\r
103     pass\r
104 \r
105   def rgb_to_hsl(self,r, g, b):\r
106     rgb_max = max (max (r, g), b)\r
107     rgb_min = min (min (r, g), b)\r
108     delta = rgb_max - rgb_min\r
109     hsl = [0.0, 0.0, 0.0]\r
110     hsl[2] = (rgb_max + rgb_min)/2.0\r
111     if delta == 0:\r
112         hsl[0] = 0.0\r
113         hsl[1] = 0.0\r
114     else:\r
115         if hsl[2] <= 0.5:\r
116             hsl[1] = delta / (rgb_max + rgb_min)\r
117         else:\r
118             hsl[1] = delta / (2 - rgb_max - rgb_min)\r
119         if r == rgb_max:\r
120             hsl[0] = (g - b) / delta\r
121         else:\r
122             if g == rgb_max:\r
123                 hsl[0] = 2.0 + (b - r) / delta\r
124             else:\r
125                 if b == rgb_max:\r
126                     hsl[0] = 4.0 + (r - g) / delta\r
127         hsl[0] = hsl[0] / 6.0\r
128         if hsl[0] < 0:\r
129             hsl[0] = hsl[0] + 1\r
130         if hsl[0] > 1:\r
131             hsl[0] = hsl[0] - 1\r
132     return hsl\r
133 \r
134   def hue_2_rgb (self, v1, v2, h):\r
135     if h < 0:\r
136         h += 6.0\r
137     if h > 6:\r
138         h -= 6.0\r
139     if h < 1:\r
140         return v1 + (v2 - v1) * h\r
141     if h < 3:\r
142         return v2\r
143     if h < 4:\r
144         return v1 + (v2 - v1) * (4 - h)\r
145     return v1\r
146 \r
147   def hsl_to_rgb (self,h, s, l):\r
148     rgb = [0, 0, 0]\r
149     if s == 0:\r
150         rgb[0] = l\r
151         rgb[1] = l\r
152         rgb[2] = l\r
153     else:\r
154         if l < 0.5:\r
155             v2 = l * (1 + s)\r
156         else:\r
157             v2 = l + s - l*s\r
158         v1 = 2*l - v2\r
159         rgb[0] = self.hue_2_rgb (v1, v2, h*6 + 2.0)\r
160         rgb[1] = self.hue_2_rgb (v1, v2, h*6)\r
161         rgb[2] = self.hue_2_rgb (v1, v2, h*6 - 2.0)\r
162     return rgb\r