3
Copyright (C) 2009 Aurelio A. Heckert, aurium (a) gmail dot com
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
import inkex, simplestyle, math, re, string
21
class InterpAttG(inkex.Effect):
24
inkex.Effect.__init__(self)
25
self.OptionParser.add_option("-a", "--att",
26
action="store", type="string",
27
dest="att", default="fill",
28
help="Attribute to be interpolated.")
29
self.OptionParser.add_option("-o", "--att-other",
30
action="store", type="string",
32
help="Other atribute (for a limited UI).")
33
self.OptionParser.add_option("-t", "--att-other-type",
34
action="store", type="string",
35
dest="att_other_type",
36
help="The other attribute type.")
37
self.OptionParser.add_option("-w", "--att-other-where",
38
action="store", type="string",
39
dest="att_other_where",
40
help="That is a tag attribute or a style attribute?")
41
self.OptionParser.add_option("-s", "--start-val",
42
action="store", type="string",
43
dest="start_val", default="#F00",
44
help="Initial interpolation value.")
45
self.OptionParser.add_option("-e", "--end-val",
46
action="store", type="string",
47
dest="end_val", default="#00F",
48
help="End interpolation value.")
49
self.OptionParser.add_option("-u", "--unit",
50
action="store", type="string",
51
dest="unit", default="color",
54
def getColorValues(self):
55
sv = string.replace( self.options.start_val, '#', '' )
56
ev = string.replace( self.options.end_val, '#', '' )
57
if re.search('\s|,', sv):
58
# There are separators. That must be a integer RGB color definition.
59
sv = re.split( '[\s,]+', sv )
60
ev = re.split( '[\s,]+', ev )
61
self.R_ini = int( sv[0] )
62
self.G_ini = int( sv[1] )
63
self.B_ini = int( sv[2] )
64
self.R_end = int( ev[0] )
65
self.G_end = int( ev[1] )
66
self.B_end = int( ev[2] )
68
# There is no separator. That must be a Hex RGB color definition.
70
self.R_ini = int( sv[0] + sv[0], 16 )
71
self.G_ini = int( sv[1] + sv[1], 16 )
72
self.B_ini = int( sv[2] + sv[2], 16 )
73
self.R_end = int( ev[0] + ev[0], 16 )
74
self.G_end = int( ev[1] + ev[1], 16 )
75
self.B_end = int( ev[2] + ev[2], 16 )
76
else: #the len must be 6
77
self.R_ini = int( sv[0] + sv[1], 16 )
78
self.G_ini = int( sv[2] + sv[3], 16 )
79
self.B_ini = int( sv[4] + sv[5], 16 )
80
self.R_end = int( ev[0] + ev[1], 16 )
81
self.G_end = int( ev[2] + ev[3], 16 )
82
self.B_end = int( ev[4] + ev[5], 16 )
83
self.R_inc = ( self.R_end - self.R_ini ) / float( self.tot_el - 1 )
84
self.G_inc = ( self.G_end - self.G_ini ) / float( self.tot_el - 1 )
85
self.B_inc = ( self.B_end - self.B_ini ) / float( self.tot_el - 1 )
86
self.R_cur = self.R_ini
87
self.G_cur = self.G_ini
88
self.B_cur = self.B_ini
90
def getNumberValues(self):
91
sv = self.options.start_val
92
ev = self.options.end_val
93
if self.inte_att_type and self.inte_att_type != 'none':
94
sv = inkex.unittouu( sv + self.inte_att_type )
95
ev = inkex.unittouu( ev + self.inte_att_type )
96
self.val_cur = self.val_ini = sv
98
self.val_inc = ( ev - sv ) / float( self.tot_el - 1 )
100
def getTotElements(self):
102
self.collection = None
103
if len( self.selected ) == 0:
105
if len( self.selected ) > 1:
107
self.collection = self.options.ids
108
for i in self.options.ids:
109
path = '//*[@id="%s"]' % i
110
self.collection[self.tot_el] = self.document.xpath(path, namespaces=inkex.NSS)[0]
114
self.collection = self.selected[ self.options.ids[0] ]
115
for i in self.collection:
119
if self.options.att == 'other':
120
self.inte_att = self.options.att_other
121
self.inte_att_type = self.options.att_other_type
122
self.where = self.options.att_other_where
124
self.inte_att = self.options.att
125
if self.inte_att == 'width':
126
self.inte_att_type = 'float'
128
elif self.inte_att == 'height':
129
self.inte_att_type = 'float'
131
elif self.inte_att == 'scale':
132
self.inte_att_type = 'float'
133
self.where = 'transform'
134
elif self.inte_att == 'trans-x':
135
self.inte_att_type = 'float'
136
self.where = 'transform'
137
elif self.inte_att == 'trans-y':
138
self.inte_att_type = 'float'
139
self.where = 'transform'
140
elif self.inte_att == 'fill':
141
self.inte_att_type = 'color'
143
elif self.inte_att == 'opacity':
144
self.inte_att_type = 'float'
147
self.getTotElements()
149
if self.inte_att_type == 'color':
150
self.getColorValues()
152
self.getNumberValues()
154
if self.collection is None:
155
inkex.errormsg( 'There is no selection to interpolate' )
158
for node in self.collection:
159
if self.inte_att_type == 'color':
161
str(int(round(self.R_cur))) +','+ \
162
str(int(round(self.G_cur))) +','+ \
163
str(int(round(self.B_cur))) +')'
165
if self.inte_att_type == 'float':
167
else: # inte_att_type == 'int'
168
val = round(self.val_cur)
170
if self.where == 'style':
171
s = node.get('style')
172
re_find = '(^|;)'+ self.inte_att +':[^;]*(;|$)'
173
if re.search( re_find, s ):
174
s = re.sub( re_find, '\\1'+ self.inte_att +':'+ str(val) +'\\2', s )
176
s += ';'+ self.inte_att +':'+ str(val)
177
node.set( 'style', s )
178
elif self.where == 'transform':
179
t = node.get('transform')
181
if self.inte_att == 'trans-x':
182
val = "translate("+ str(val) +",0)"
183
elif self.inte_att == 'trans-y':
184
val = "translate(0,"+ str(val) +")"
186
val = self.inte_att + "("+ str(val) +")"
187
node.set( 'transform', t +" "+ val )
188
else: # self.where == 'tag':
189
node.set( self.inte_att, str(val) )
191
if self.inte_att_type == 'color':
192
self.R_cur += self.R_inc
193
self.G_cur += self.G_inc
194
self.B_cur += self.B_inc
196
self.val_cur += self.val_inc
200
if __name__ == '__main__': #pragma: no cover