| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package GD::Icons; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.04'; |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# $Id: Icons.pm,v 1.8 2007/08/06 15:36:54 canaran Exp $ |
|
6
|
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
20793
|
use warnings; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
37
|
|
|
8
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
31
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
658
|
use GD::Icons::Config; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
39
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
10
|
use Carp; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
67
|
|
|
13
|
1
|
|
|
1
|
|
439
|
use GD; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
############### |
|
16
|
|
|
|
|
|
|
# CONSTRUCTOR # |
|
17
|
|
|
|
|
|
|
############### |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub new { |
|
20
|
|
|
|
|
|
|
my ($class, %params) = @_; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $self = bless {}, $class; |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $config_file = $params{config_file}; |
|
25
|
|
|
|
|
|
|
my $gd_icons_config = GD::Icons::Config->new($config_file); |
|
26
|
|
|
|
|
|
|
$self->config($gd_icons_config->config); |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Assign alpha |
|
29
|
|
|
|
|
|
|
my $alpha = $params{alpha} ? $params{alpha} : 0; |
|
30
|
|
|
|
|
|
|
if ($alpha =~ /[^0-9]/ or $alpha > 127) { |
|
31
|
|
|
|
|
|
|
croak("alpha must be a value between 0 and 127!"); |
|
32
|
|
|
|
|
|
|
} |
|
33
|
|
|
|
|
|
|
$self->alpha($alpha); |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Parse shapes keys |
|
36
|
|
|
|
|
|
|
my $shape_keys = |
|
37
|
|
|
|
|
|
|
$params{shape_keys} |
|
38
|
|
|
|
|
|
|
? $params{shape_keys} |
|
39
|
|
|
|
|
|
|
: [":default"]; |
|
40
|
|
|
|
|
|
|
$self->shape_keys($shape_keys); |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
my $shape_values = |
|
43
|
|
|
|
|
|
|
$params{shape_values} |
|
44
|
|
|
|
|
|
|
? $params{shape_values} |
|
45
|
|
|
|
|
|
|
: $self->all_shapes; |
|
46
|
|
|
|
|
|
|
$self->shape_values($shape_values); |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
# Parse color keys |
|
49
|
|
|
|
|
|
|
my $color_keys = |
|
50
|
|
|
|
|
|
|
$params{color_keys} |
|
51
|
|
|
|
|
|
|
? $params{color_keys} |
|
52
|
|
|
|
|
|
|
: [":default"]; |
|
53
|
|
|
|
|
|
|
$self->color_keys($color_keys); |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
my $color_values = |
|
56
|
|
|
|
|
|
|
$params{color_values} |
|
57
|
|
|
|
|
|
|
? $params{color_values} |
|
58
|
|
|
|
|
|
|
: $self->all_colors; |
|
59
|
|
|
|
|
|
|
$self->color_values($color_values); |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# Parse sval keys |
|
62
|
|
|
|
|
|
|
my $sval_keys = |
|
63
|
|
|
|
|
|
|
$params{sval_keys} |
|
64
|
|
|
|
|
|
|
? $params{sval_keys} |
|
65
|
|
|
|
|
|
|
: [":default"]; |
|
66
|
|
|
|
|
|
|
$self->sval_keys($sval_keys); |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
my $sval_values = |
|
69
|
|
|
|
|
|
|
$params{sval_values} |
|
70
|
|
|
|
|
|
|
? $params{sval_values} |
|
71
|
|
|
|
|
|
|
: [map { $_ / (@$sval_keys) * 100 } (1 .. @$sval_keys)]; # ratio only |
|
72
|
|
|
|
|
|
|
$self->sval_values($sval_values); |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
my $icon_dir = $params{icon_dir} |
|
75
|
|
|
|
|
|
|
or croak("A icon_dir is required!"); |
|
76
|
|
|
|
|
|
|
$self->icon_dir($icon_dir); |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
my $icon_prefix = $params{icon_prefix}; |
|
79
|
|
|
|
|
|
|
if (!defined $icon_prefix) { |
|
80
|
|
|
|
|
|
|
croak("A icon_prefix is required!"); |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
$self->icon_prefix($icon_prefix); |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
return $self; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
################## |
|
88
|
|
|
|
|
|
|
# PUBLIC METHODS # |
|
89
|
|
|
|
|
|
|
################## |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# Function : Get method that ignores _* names |
|
92
|
|
|
|
|
|
|
# Arguments : None |
|
93
|
|
|
|
|
|
|
# Returns : \@all |
|
94
|
|
|
|
|
|
|
# Notes : None provided. |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub all_colors { |
|
97
|
|
|
|
|
|
|
my ($self) = @_; |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
my $config = $self->config; |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
my @all; |
|
102
|
|
|
|
|
|
|
foreach (sort keys %{$config->{color}}) { |
|
103
|
|
|
|
|
|
|
push @all, $_ unless /^_/; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
return \@all; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# Function : Get method that ignores _* names |
|
110
|
|
|
|
|
|
|
# Arguments : None |
|
111
|
|
|
|
|
|
|
# Returns : \@all |
|
112
|
|
|
|
|
|
|
# Notes : None provided. |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub all_shapes { |
|
115
|
|
|
|
|
|
|
my ($self) = @_; |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
my $config = $self->config; |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
my @all; |
|
120
|
|
|
|
|
|
|
foreach (sort keys %{$config->{shape}}) { |
|
121
|
|
|
|
|
|
|
push @all, $_ unless /^_/; |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
return \@all; |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Function : Get/set method for icon location |
|
128
|
|
|
|
|
|
|
# Arguments : $shape_key, $color_key, $sval_key, $value |
|
129
|
|
|
|
|
|
|
# Returns : $value |
|
130
|
|
|
|
|
|
|
# Notes : None provided. |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub icon { |
|
133
|
|
|
|
|
|
|
my ($self, $shape_key, $color_key, $sval_key, $value) = @_; |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
$self->{icons}->{$shape_key}->{$color_key}->{$sval_key} = $value |
|
136
|
|
|
|
|
|
|
if @_ > 4; |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
return $self->{icons}->{$shape_key}->{$color_key}->{$sval_key}; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# Function : Make ... |
|
142
|
|
|
|
|
|
|
# Arguments : |
|
143
|
|
|
|
|
|
|
# Returns : |
|
144
|
|
|
|
|
|
|
# Notes : None provided. |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub generate_icons { |
|
147
|
|
|
|
|
|
|
my ($self) = @_; |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
my $config = $self->config; |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
my $alpha = $self->alpha; |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
my @shape_keys = @{$self->shape_keys}; |
|
154
|
|
|
|
|
|
|
my @shape_values = @{$self->shape_values}; |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
my @color_keys = @{$self->color_keys}; |
|
157
|
|
|
|
|
|
|
my @color_values = @{$self->color_values}; |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
my @sval_keys = @{$self->sval_keys}; |
|
160
|
|
|
|
|
|
|
my @sval_values = @{$self->sval_values}; |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
my $icon_dir = $self->icon_dir; |
|
163
|
|
|
|
|
|
|
my $icon_prefix = $self->icon_prefix; |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
foreach my $shape_i (0 .. $#shape_keys) { |
|
166
|
|
|
|
|
|
|
foreach my $color_i (0 .. $#color_keys) { |
|
167
|
|
|
|
|
|
|
foreach my $sval_i (0 .. $#sval_keys) { |
|
168
|
|
|
|
|
|
|
my $shape = |
|
169
|
|
|
|
|
|
|
$config->{shape}->{$shape_values[$shape_i % @shape_values] |
|
170
|
|
|
|
|
|
|
}; # @shape_values here, not $#shape_values |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
my $color = |
|
173
|
|
|
|
|
|
|
$self->_resolve_color( |
|
174
|
|
|
|
|
|
|
$color_values[$color_i % @color_values]) |
|
175
|
|
|
|
|
|
|
; # @color_values here, not $#color_values |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
my $sval = $sval_values[$sval_i]; |
|
178
|
|
|
|
|
|
|
if (@sval_values > 1) { |
|
179
|
|
|
|
|
|
|
$color = $self->_blend_in_sval($color, $sval); |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
my ($line_color) = $shape =~ /lc\[([^\[\]]+)\]/; |
|
183
|
|
|
|
|
|
|
if ($line_color eq ":fill") { |
|
184
|
|
|
|
|
|
|
$line_color = [@$color]; |
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
$line_color = $self->_resolve_color($line_color); |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
my ($line_thickness) = $shape =~ /lt\[(\d+)\]/; |
|
189
|
|
|
|
|
|
|
my ($side_length) = $shape =~ /sl\[(\d+)\]/; |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
my $image = new GD::Image($side_length, $side_length); |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
my $white_color = $image->colorAllocateAlpha(255, 255, 255, $alpha); |
|
194
|
|
|
|
|
|
|
my $fill_color = $image->colorAllocateAlpha(@$color, $alpha); |
|
195
|
|
|
|
|
|
|
my $draw_color = $image->colorAllocateAlpha(@$line_color, $alpha); |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
$image->transparent($white_color); |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
$image->setThickness($line_thickness); |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
while ($shape =~ /\s*(py|fl|nm)\[([0-9, ]+|:auto)\]\s*/g) { |
|
202
|
|
|
|
|
|
|
my ($action, $values) = ($1, $2); |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
if ($action eq "py") { |
|
205
|
|
|
|
|
|
|
my @points = split(" ", $values); |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
foreach my $i (0 .. $#points - 1) { |
|
208
|
|
|
|
|
|
|
my ($x1, $y1) = split(",", $points[$i]); |
|
209
|
|
|
|
|
|
|
my ($x2, $y2) = split(",", $points[$i + 1]); |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
$image->line($x1, $y1, $x2, $y2, $draw_color); |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
elsif ($action eq "fl") { |
|
216
|
|
|
|
|
|
|
my ($x1, $y1) = split(",", $values); |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
$image->fill($x1, $y1, $fill_color); |
|
219
|
|
|
|
|
|
|
} |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
elsif ($action eq "nm" && $values eq ":auto") { |
|
222
|
|
|
|
|
|
|
my ($number) = $shape_keys[$shape_i] =~ /:(\d+)/; |
|
223
|
|
|
|
|
|
|
if ($number && $number > 99) { |
|
224
|
|
|
|
|
|
|
$number = 'M'; |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
if (!$number) { |
|
227
|
|
|
|
|
|
|
$number = 'U'; |
|
228
|
|
|
|
|
|
|
} |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
my $x = int(($side_length - 5 * length($number)) / 2) + 1; |
|
231
|
|
|
|
|
|
|
my $y = ($side_length - 8) / 2; |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
$image->string(gdTinyFont, $x, $y, $number, $draw_color); |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
else { |
|
237
|
|
|
|
|
|
|
croak( |
|
238
|
|
|
|
|
|
|
"Unrecognized action ($action) in shapes file!"); |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
} |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
my $icon_file = |
|
243
|
|
|
|
|
|
|
qq[$icon_dir/${icon_prefix}-${shape_i}-${color_i}-${sval_i}.png]; |
|
244
|
|
|
|
|
|
|
my $icon_file_name = |
|
245
|
|
|
|
|
|
|
qq[${icon_prefix}-${shape_i}-${color_i}-${sval_i}.png]; |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
$self->icon( |
|
248
|
|
|
|
|
|
|
$shape_keys[$shape_i], $color_keys[$color_i], |
|
249
|
|
|
|
|
|
|
$sval_keys[$sval_i], $icon_file_name |
|
250
|
|
|
|
|
|
|
); |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
open(PNG, ">$icon_file") |
|
253
|
|
|
|
|
|
|
or croak("Cannot write file ($icon_file): $!"); |
|
254
|
|
|
|
|
|
|
binmode PNG; |
|
255
|
|
|
|
|
|
|
print PNG $image->png; |
|
256
|
|
|
|
|
|
|
close PNG; |
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
} |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
return 1; |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
################### |
|
266
|
|
|
|
|
|
|
# GET/SET METHODS # |
|
267
|
|
|
|
|
|
|
################### |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub alpha { |
|
270
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
271
|
|
|
|
|
|
|
$self->{alpha} = $value if @_ > 1; |
|
272
|
|
|
|
|
|
|
return $self->{alpha}; |
|
273
|
|
|
|
|
|
|
} |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub color_keys { |
|
276
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
277
|
|
|
|
|
|
|
$self->{color_keys} = $value if @_ > 1; |
|
278
|
|
|
|
|
|
|
return $self->{color_keys}; |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
sub color_values { |
|
282
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
283
|
|
|
|
|
|
|
$self->{color_values} = $value if @_ > 1; |
|
284
|
|
|
|
|
|
|
return $self->{color_values}; |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub config { |
|
288
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
289
|
|
|
|
|
|
|
$self->{config} = $value if @_ > 1; |
|
290
|
|
|
|
|
|
|
return $self->{config}; |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub icon_dir { |
|
294
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
295
|
|
|
|
|
|
|
$self->{icon_dir} = $value if @_ > 1; |
|
296
|
|
|
|
|
|
|
return $self->{icon_dir}; |
|
297
|
|
|
|
|
|
|
} |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub icon_prefix { |
|
300
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
301
|
|
|
|
|
|
|
$self->{icon_prefix} = $value if @_ > 1; |
|
302
|
|
|
|
|
|
|
return $self->{icon_prefix}; |
|
303
|
|
|
|
|
|
|
} |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub shape_keys { |
|
306
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
307
|
|
|
|
|
|
|
$self->{shape_keys} = $value if @_ > 1; |
|
308
|
|
|
|
|
|
|
return $self->{shape_keys}; |
|
309
|
|
|
|
|
|
|
} |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub shape_values { |
|
312
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
313
|
|
|
|
|
|
|
$self->{shape_values} = $value if @_ > 1; |
|
314
|
|
|
|
|
|
|
return $self->{shape_values}; |
|
315
|
|
|
|
|
|
|
} |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
sub sval_keys { |
|
318
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
319
|
|
|
|
|
|
|
$self->{sval_keys} = $value if @_ > 1; |
|
320
|
|
|
|
|
|
|
return $self->{sval_keys}; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub sval_values { |
|
324
|
|
|
|
|
|
|
my ($self, $value) = @_; |
|
325
|
|
|
|
|
|
|
$self->{sval_values} = $value if @_ > 1; |
|
326
|
|
|
|
|
|
|
return $self->{sval_values}; |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
########################### |
|
330
|
|
|
|
|
|
|
# PRIVATE/UTILITY METHODS # |
|
331
|
|
|
|
|
|
|
########################### |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
# Function : Apply an S Value to color in RGB |
|
334
|
|
|
|
|
|
|
# Arguments : (\@color, $sval_percent) |
|
335
|
|
|
|
|
|
|
# Returns : \@new_color |
|
336
|
|
|
|
|
|
|
# Notes : This is a private method. |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub _blend_in_sval { |
|
339
|
|
|
|
|
|
|
my ($self, $color, $sval_percent) = @_; |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
my ($rval, $gval, $bval) = @$color; |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
my ($hval, $sval, $vval) = $self->_RGBtoHSV($rval, $gval, $bval); |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
$sval = int($sval * $sval_percent / 100); |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
my @new_color = $self->_HSVtoRGB($hval, $sval, $vval); |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
return \@new_color; |
|
350
|
|
|
|
|
|
|
} |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# Function : Determine the type of color designation |
|
353
|
|
|
|
|
|
|
# Arguments : $color |
|
354
|
|
|
|
|
|
|
# Returns : $rgb |
|
355
|
|
|
|
|
|
|
# Notes : This is a private method. |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub _resolve_color { |
|
358
|
|
|
|
|
|
|
my ($self, $color) = @_; |
|
359
|
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
my $rgb; |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
if (ref $color) { |
|
363
|
|
|
|
|
|
|
$rgb = $color; |
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
elsif ($color =~ /^#/) { |
|
367
|
|
|
|
|
|
|
$rgb = $self->_hex2rgb($color); |
|
368
|
|
|
|
|
|
|
} |
|
369
|
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
else { |
|
371
|
|
|
|
|
|
|
my $hex = $self->config->{color}->{$color}; |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
$rgb = $self->_hex2rgb($hex); |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
croak("Cannot resolve color ($color)!") unless $rgb; |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
return $rgb; |
|
379
|
|
|
|
|
|
|
} |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# Function : Convert hex to rgb |
|
382
|
|
|
|
|
|
|
# Arguments : $hex |
|
383
|
|
|
|
|
|
|
# Returns : \@rgb |
|
384
|
|
|
|
|
|
|
# Notes : This is a private method. |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
sub _hex2rgb { |
|
387
|
|
|
|
|
|
|
my ($self, $hex) = @_; |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
$hex =~ s/^#//; |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
my @rgb = map { hex(substr($hex, $_, 2)); } qw[0 2 4]; |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
return \@rgb; |
|
394
|
|
|
|
|
|
|
} |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
################################################## |
|
397
|
|
|
|
|
|
|
# _HSVtoRGB and _RGBtoHSV subs incorporated from # |
|
398
|
|
|
|
|
|
|
# GD::Simple module written by Lincoln Stein # |
|
399
|
|
|
|
|
|
|
################################################## |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
# ($red,$green,$blue) = GD::Simple->HSVtoRGB($hue,$saturation,$value) |
|
402
|
|
|
|
|
|
|
# |
|
403
|
|
|
|
|
|
|
# Convert a Hue/Saturation/Value (HSV) color into an RGB triple. The |
|
404
|
|
|
|
|
|
|
# hue, saturation and value are integers from 0 to 255. |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
sub _HSVtoRGB { |
|
407
|
|
|
|
|
|
|
my $self = shift; |
|
408
|
|
|
|
|
|
|
@_ == 3 |
|
409
|
|
|
|
|
|
|
or croak "Usage: _HSVtoRGB(\$hue,\$saturation,\$value)"; |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
my ($h, $s, $v) = @_; |
|
412
|
|
|
|
|
|
|
my ($r, $g, $b, $i, $f, $p, $q, $t); |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
if ($s == 0) { |
|
415
|
|
|
|
|
|
|
## achromatic (grey) |
|
416
|
|
|
|
|
|
|
return ($v, $v, $v); |
|
417
|
|
|
|
|
|
|
} |
|
418
|
|
|
|
|
|
|
$h %= 255; |
|
419
|
|
|
|
|
|
|
$s /= 255; ## scale saturation from 0.0-1.0 |
|
420
|
|
|
|
|
|
|
$h /= 255; ## scale hue from 0 to 1.0 |
|
421
|
|
|
|
|
|
|
$h *= 360; ## and now scale it to 0 to 360 |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
$h /= 60; ## sector 0 to 5 |
|
424
|
|
|
|
|
|
|
$i = $h % 6; |
|
425
|
|
|
|
|
|
|
$f = $h - $i; ## factorial part of h |
|
426
|
|
|
|
|
|
|
$p = $v * (1 - $s); |
|
427
|
|
|
|
|
|
|
$q = $v * (1 - $s * $f); |
|
428
|
|
|
|
|
|
|
$t = $v * (1 - $s * (1 - $f)); |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
if ($i < 1) { |
|
431
|
|
|
|
|
|
|
$r = $v; |
|
432
|
|
|
|
|
|
|
$g = $t; |
|
433
|
|
|
|
|
|
|
$b = $p; |
|
434
|
|
|
|
|
|
|
} |
|
435
|
|
|
|
|
|
|
elsif ($i < 2) { |
|
436
|
|
|
|
|
|
|
$r = $q; |
|
437
|
|
|
|
|
|
|
$g = $v; |
|
438
|
|
|
|
|
|
|
$b = $p; |
|
439
|
|
|
|
|
|
|
} |
|
440
|
|
|
|
|
|
|
elsif ($i < 3) { |
|
441
|
|
|
|
|
|
|
$r = $p; |
|
442
|
|
|
|
|
|
|
$g = $v; |
|
443
|
|
|
|
|
|
|
$b = $t; |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
elsif ($i < 4) { |
|
446
|
|
|
|
|
|
|
$r = $p; |
|
447
|
|
|
|
|
|
|
$g = $q; |
|
448
|
|
|
|
|
|
|
$b = $v; |
|
449
|
|
|
|
|
|
|
} |
|
450
|
|
|
|
|
|
|
elsif ($i < 5) { |
|
451
|
|
|
|
|
|
|
$r = $t; |
|
452
|
|
|
|
|
|
|
$g = $p; |
|
453
|
|
|
|
|
|
|
$b = $v; |
|
454
|
|
|
|
|
|
|
} |
|
455
|
|
|
|
|
|
|
else { |
|
456
|
|
|
|
|
|
|
$r = $v; |
|
457
|
|
|
|
|
|
|
$g = $p; |
|
458
|
|
|
|
|
|
|
$b = $q; |
|
459
|
|
|
|
|
|
|
} |
|
460
|
|
|
|
|
|
|
return (int($r + 0.5), int($g + 0.5), int($b + 0.5)); |
|
461
|
|
|
|
|
|
|
} |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
# ($hue,$saturation,$value) = GD::Simple->RGBtoHSV($hue,$saturation,$value) |
|
464
|
|
|
|
|
|
|
# |
|
465
|
|
|
|
|
|
|
# Convert a Red/Green/Blue (RGB) value into a Hue/Saturation/Value (HSV) |
|
466
|
|
|
|
|
|
|
# triple. The hue, saturation and value are integers from 0 to 255. |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
sub _RGBtoHSV { |
|
469
|
|
|
|
|
|
|
my $self = shift; |
|
470
|
|
|
|
|
|
|
my ($r, $g, $bl) = @_; |
|
471
|
|
|
|
|
|
|
my ($min, undef, $max) = sort { $a <=> $b } ($r, $g, $bl); |
|
472
|
|
|
|
|
|
|
return (0, 0, 0) unless $max > 0; |
|
473
|
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
my $v = $max; |
|
475
|
|
|
|
|
|
|
my $s = 255 * ($max - $min) / $max; |
|
476
|
|
|
|
|
|
|
my $h; |
|
477
|
|
|
|
|
|
|
my $range = $max - $min; |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
if ($range == 0) { # all colors are equal, so monochrome |
|
480
|
|
|
|
|
|
|
return (0, 0, $max); |
|
481
|
|
|
|
|
|
|
} |
|
482
|
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
if ($max == $r) { |
|
484
|
|
|
|
|
|
|
$h = 60 * ($g - $bl) / $range; |
|
485
|
|
|
|
|
|
|
} |
|
486
|
|
|
|
|
|
|
elsif ($max == $g) { |
|
487
|
|
|
|
|
|
|
$h = 60 * ($bl - $r) / $range + 120; |
|
488
|
|
|
|
|
|
|
} |
|
489
|
|
|
|
|
|
|
else { |
|
490
|
|
|
|
|
|
|
$h = 60 * ($r - $g) / $range + 240; |
|
491
|
|
|
|
|
|
|
} |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
$h = int($h * 255 / 360 + 0.5); |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
return ($h, $s, $v); |
|
496
|
|
|
|
|
|
|
} |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
1; |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
__END__ |