Code

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