line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package GD::Window; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
31164
|
use 5.008006; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
50
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
43
|
|
5
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
45
|
|
6
|
1
|
|
|
1
|
|
5
|
use Carp qw( croak ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
83
|
|
7
|
1
|
|
|
1
|
|
6
|
use vars qw/$VERSION $AUTOLOAD/; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1795
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
require Exporter; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw( |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
) ] ); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
our @EXPORT = qw( |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my %imWindowedFuncs = ( |
27
|
|
|
|
|
|
|
setPixel => {x => [0], 'y' => [1]}, |
28
|
|
|
|
|
|
|
line => {x => [0,2], 'y' => [1,3]}, |
29
|
|
|
|
|
|
|
dashedLine => {x => [0,2], 'y' => [1,3]}, |
30
|
|
|
|
|
|
|
rectangle => {x => [0,2], 'y' => [1,3]}, |
31
|
|
|
|
|
|
|
filledRectangle => {x => [0,2], 'y' => [1,3]}, |
32
|
|
|
|
|
|
|
ellipse => {x => [0], 'y' => [1], w => [2], h => [3]}, |
33
|
|
|
|
|
|
|
filledEllipse => {x => [0], 'y' => [1], w => [2], h => [3]}, |
34
|
|
|
|
|
|
|
arc => {x => [0], 'y' => [1], w => [2], h => [3]}, |
35
|
|
|
|
|
|
|
filledArc => {x => [0], 'y' => [1], w => [2], h => [3]}, |
36
|
|
|
|
|
|
|
fill => {x => [0], 'y' => [1]}, |
37
|
|
|
|
|
|
|
fillToBorder => {x => [0], 'y' => [1]}, |
38
|
|
|
|
|
|
|
copy => {x => [1], 'y' => [2]}, |
39
|
|
|
|
|
|
|
copyMerge => {x => [1], 'y' => [2]}, |
40
|
|
|
|
|
|
|
copyMergeGray => {x => [1], 'y' => [2]}, |
41
|
|
|
|
|
|
|
copyResized => {x => [1], 'y' => [2], w => [5], h => [6]}, |
42
|
|
|
|
|
|
|
copyResampled => {x => [1], 'y' => [2], w => [5], h => [6]}, |
43
|
|
|
|
|
|
|
copyRotated => {x => [1], 'y' => [2]}, |
44
|
|
|
|
|
|
|
string => {x => [1], 'y' => [2]}, |
45
|
|
|
|
|
|
|
stringUp => {x => [1], 'y' => [2]}, |
46
|
|
|
|
|
|
|
char => {x => [1], 'y' => [2]}, |
47
|
|
|
|
|
|
|
charUp => {x => [1], 'y' => [2]}, |
48
|
|
|
|
|
|
|
stringFT => {x => [4], 'y' => [5]}, |
49
|
|
|
|
|
|
|
stringFTCircle => {x => [0], 'y' => [1]}, |
50
|
|
|
|
|
|
|
clip => {x => [0,2], 'y' => [1,3]}, |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
my %imWindowedPolyFuncs = (openPolygon => 1, |
54
|
|
|
|
|
|
|
unclosedPolygon => 1, |
55
|
|
|
|
|
|
|
filledPolygon => 1); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
my $invertY_g = 0; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub new { |
62
|
0
|
|
|
0
|
1
|
|
my $that = shift; |
63
|
0
|
|
0
|
|
|
|
my $class = ref($that) || $that; |
64
|
0
|
|
|
|
|
|
my ($im, $imX1, $imY1, $imX2, $imY2, |
65
|
|
|
|
|
|
|
$winX1, $winY1, $winX2, $winY2, |
66
|
|
|
|
|
|
|
%args) = @_; |
67
|
|
|
|
|
|
|
|
68
|
0
|
0
|
|
|
|
|
if (scalar(@_) < 9) { |
69
|
0
|
|
|
|
|
|
croak "Missing some arguments for new GD::Window"; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# Fill in the window's boundary |
73
|
0
|
0
|
|
|
|
|
my $self = { im => $im, |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
74
|
|
|
|
|
|
|
minX => $winX1 > $winX2 ? $winX2 : $winX1, |
75
|
|
|
|
|
|
|
minY => $winY1 > $winY2 ? $winY2 : $winY1, |
76
|
|
|
|
|
|
|
maxX => $winX1 > $winX2 ? $winX1 : $winX2, |
77
|
|
|
|
|
|
|
maxY => $winY1 > $winY2 ? $winY1 : $winY2, |
78
|
|
|
|
|
|
|
imMinX => $imX1 > $imX2 ? $imX2 : $imX1, |
79
|
|
|
|
|
|
|
imMinY => $imY1 > $imY2 ? $imY2 : $imY1, |
80
|
|
|
|
|
|
|
imMaxX => $imX1 > $imX2 ? $imX1 : $imX2, |
81
|
|
|
|
|
|
|
imMaxY => $imY1 > $imY2 ? $imY1 : $imY2, |
82
|
|
|
|
|
|
|
passThroughIfUnsupported => $args{passThrough}, |
83
|
|
|
|
|
|
|
useImage => $args{useImage}, |
84
|
|
|
|
|
|
|
invertY => defined $args{invertY} ? $args{invertY} : $invertY_g, |
85
|
|
|
|
|
|
|
}; |
86
|
|
|
|
|
|
|
|
87
|
0
|
0
|
|
|
|
|
if ($self->{useImage}) { |
88
|
|
|
|
|
|
|
# Need to make our own internal image |
89
|
0
|
|
|
|
|
|
$self->{parentIm} = $im; |
90
|
0
|
|
|
|
|
|
$self->{im} = GD::Image->new(($self->{maxX} - $self->{minX}), ($self->{maxY} - $self->{minY}), 1); |
91
|
0
|
|
|
|
|
|
$self->{scaleX} = 1; |
92
|
0
|
|
|
|
|
|
$self->{scaleY} = 1; |
93
|
0
|
|
|
|
|
|
$self->{srcImMinX} = $self->{imMinX}; |
94
|
0
|
|
|
|
|
|
$self->{srcImMinY} = $self->{imMinY}; |
95
|
0
|
|
|
|
|
|
$self->{imMinX} = 0; |
96
|
0
|
|
|
|
|
|
$self->{imMinY} = 0; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
else { |
99
|
0
|
|
|
|
|
|
$self->{scaleX} = ($self->{imMaxX} - $self->{imMinX})/($self->{maxX} - $self->{minX}); |
100
|
0
|
|
|
|
|
|
$self->{scaleY} = ($self->{imMaxY} - $self->{imMinY})/($self->{maxY} - $self->{minY}); |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# print "PostSub: $postSub\n"; |
104
|
0
|
0
|
|
|
|
|
if ($@) { |
105
|
0
|
|
|
|
|
|
die "Failed eval of autoloaded sub: $@"; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
0
|
|
|
|
|
|
bless ($self, $class); |
109
|
0
|
|
|
|
|
|
return $self; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
## |
114
|
|
|
|
|
|
|
# The autoload function catches all the supported image functions and |
115
|
|
|
|
|
|
|
# creates the appropriate transformations for them. |
116
|
|
|
|
|
|
|
# |
117
|
|
|
|
|
|
|
# If passThrough is defined on window creation, then unsupported |
118
|
|
|
|
|
|
|
# functions will simply be forwarded to the image. Otherwise, |
119
|
|
|
|
|
|
|
# we will croak. |
120
|
|
|
|
|
|
|
## |
121
|
|
|
|
|
|
|
sub AUTOLOAD { |
122
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
123
|
0
|
|
|
|
|
|
my ($name) = ($AUTOLOAD =~ /::([^:]+)$/); |
124
|
0
|
|
|
|
|
|
my @args = @_; |
125
|
|
|
|
|
|
|
|
126
|
0
|
0
|
|
|
|
|
if (exists $imWindowedFuncs{$name}) { |
|
|
0
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
my $fi = $imWindowedFuncs{$name}; |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Create the function that should be called |
130
|
0
|
|
|
|
|
|
my $body = " my \$s = shift;my \@args = \@_;\n"; |
131
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
foreach my $dim (qw(x y w h)) { |
133
|
0
|
0
|
|
|
|
|
if ($fi->{$dim}) { |
134
|
0
|
|
|
|
|
|
foreach my $idx (@{$fi->{$dim}}) { |
|
0
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
$body .= " \$args[$idx] = \$s->translate". uc($dim) ."(\$args[$idx]);\n"; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
# $body .= " print \"calling $name with \$s->{im} -> \@args\\n\"; my \$res = \$s->{im}->$name(\@args); \$s->postRenderAdjustment(); return \$res; \n"; |
140
|
0
|
|
|
|
|
|
$body .= " my \$res = \$s->{im}->$name(\@args); \$s->postRenderAdjustment(); return \$res; \n"; |
141
|
|
|
|
|
|
|
# print "Eval: $body\n"; |
142
|
0
|
|
|
|
|
|
eval "sub $name { $body }; return $name(\@args);"; |
143
|
0
|
0
|
|
|
|
|
if ($@) { |
144
|
0
|
|
|
|
|
|
die "Failed eval of autoloaded sub: $@"; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
elsif (exists $imWindowedPolyFuncs{$name}) { |
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
my $body = qq ^ |
150
|
|
|
|
|
|
|
my (\$self, \$poly, \$color) = \@_; |
151
|
|
|
|
|
|
|
my \$transPoly = GD::Polygon->new; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# Need to go through all the points and adjust them |
154
|
|
|
|
|
|
|
foreach my \$vertex (\$poly->vertices) { |
155
|
|
|
|
|
|
|
\$transPoly->addPt(\$self->translateX(\$vertex->[0]), \$self->translateY(\$vertex->[1])); |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
\$self->{im}->$name(\$transPoly, \$color); |
158
|
|
|
|
|
|
|
^; |
159
|
|
|
|
|
|
|
# print "Adding \@{\$vertex}\n"; |
160
|
|
|
|
|
|
|
# my \@v = \$transPoly->vertices; |
161
|
|
|
|
|
|
|
#foreach my \$v (\@v) { |
162
|
|
|
|
|
|
|
# print "poly: \@{\$v}\n"; |
163
|
|
|
|
|
|
|
#} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
# print "BODY: $body\n"; |
166
|
0
|
|
|
|
|
|
eval "sub $name { $body }; return $name(\@args);"; |
167
|
0
|
0
|
|
|
|
|
if ($@) { |
168
|
0
|
|
|
|
|
|
die "Failed eval of autoloaded sub: $@"; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
else { |
173
|
0
|
0
|
0
|
|
|
|
if ($self->{passThroughIfUnsupported} || $self->{useImage}) { |
174
|
0
|
|
|
|
|
|
eval("sub $name { my \$s = shift; my \$res = \$s->{im}->$name(\@_); \$s->postRenderAdjustment(); return \$res;}; return $name(\@_);"); |
175
|
0
|
0
|
|
|
|
|
if ($@) { |
176
|
0
|
|
|
|
|
|
die "Failed eval of autoloaded sub: $@"; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
else { |
180
|
0
|
|
|
|
|
|
croak "Sub $name is not supported by GD::Window"; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
## |
188
|
|
|
|
|
|
|
# Methods that can't be handled by the AUTOLOAD |
189
|
|
|
|
|
|
|
## |
190
|
|
|
|
|
|
|
sub boundsSafe { |
191
|
0
|
|
|
0
|
0
|
|
my ($self, $x, $y) = @_; |
192
|
0
|
|
0
|
|
|
|
return ($x >= $self->{minX} && |
193
|
|
|
|
|
|
|
$x <= $self->{maxX} && |
194
|
|
|
|
|
|
|
$y >= $self->{minY} && |
195
|
|
|
|
|
|
|
$y <= $self->{maxY}); |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub bounds { |
199
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
200
|
0
|
0
|
|
|
|
|
if (!$self->{invertY}) { |
201
|
0
|
|
|
|
|
|
return($self->{minX}, |
202
|
|
|
|
|
|
|
$self->{minY}, |
203
|
|
|
|
|
|
|
$self->{maxX}, |
204
|
|
|
|
|
|
|
$self->{maxY}); |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
else { |
207
|
0
|
|
|
|
|
|
return($self->{minX}, |
208
|
|
|
|
|
|
|
$self->{maxY}, |
209
|
|
|
|
|
|
|
$self->{maxX}, |
210
|
|
|
|
|
|
|
$self->{minY}); |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub dimensions { |
216
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
217
|
0
|
|
|
|
|
|
return($self->{maxX} - $self->{minX}, |
218
|
|
|
|
|
|
|
$self->{maxY} - $self->{minY}); |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
## |
223
|
|
|
|
|
|
|
# Public Methods for changing globals |
224
|
|
|
|
|
|
|
## |
225
|
|
|
|
|
|
|
sub invertY { |
226
|
0
|
|
|
0
|
1
|
|
my ($that, $val) = @_; |
227
|
|
|
|
|
|
|
|
228
|
0
|
0
|
|
|
|
|
if (ref($that)) { |
229
|
0
|
|
|
|
|
|
$that->{invertY} = $val; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
else { |
232
|
0
|
|
|
|
|
|
$invertY_g = $val; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
## |
239
|
|
|
|
|
|
|
# Private Methods |
240
|
|
|
|
|
|
|
## |
241
|
|
|
|
|
|
|
sub translateX { |
242
|
0
|
|
|
0
|
0
|
|
my ($self, $x) = @_; |
243
|
0
|
|
|
|
|
|
my $newX = ($x - $self->{minX}) * $self->{scaleX} + $self->{imMinX}; |
244
|
|
|
|
|
|
|
# print "translate from $x to $newX, $self->{scaleX}, $self->{minX}, $self->{imMinX}\n"; |
245
|
0
|
|
|
|
|
|
return $newX; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub translateY { |
249
|
0
|
|
|
0
|
0
|
|
my ($self, $y) = @_; |
250
|
0
|
0
|
|
|
|
|
if ($self->{invertY}) { |
251
|
0
|
|
|
|
|
|
$y = $self->{maxY} - $y; |
252
|
|
|
|
|
|
|
} |
253
|
0
|
|
|
|
|
|
my $newY = ($y - $self->{minY}) * $self->{scaleY} + $self->{imMinY}; |
254
|
|
|
|
|
|
|
# print "translate from $y to $newY, $self->{scaleY}\n"; |
255
|
0
|
|
|
|
|
|
return $newY; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub translateW { |
259
|
0
|
|
|
0
|
0
|
|
my ($self, $w) = @_; |
260
|
0
|
|
|
|
|
|
return $w * $self->{scaleX}; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
sub translateH { |
264
|
0
|
|
|
0
|
0
|
|
my ($self, $h) = @_; |
265
|
0
|
|
|
|
|
|
return $h * $self->{scaleY}; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub postRenderAdjustment { |
269
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
270
|
0
|
0
|
|
|
|
|
return if !$self->{useImage}; |
271
|
0
|
|
|
|
|
|
$self->{parentIm}->copyResampled( |
272
|
|
|
|
|
|
|
$self->{im}, $self->{srcImMinX}, $self->{srcImMinY}, 0, 0, |
273
|
|
|
|
|
|
|
($self->{imMaxX} - $self->{srcImMinX}), ($self->{imMaxY} - $self->{srcImMinY}), |
274
|
|
|
|
|
|
|
($self->{maxX} - $self->{minX}), ($self->{maxY} - $self->{minY})); |
275
|
|
|
|
|
|
|
}; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
|
278
|
0
|
|
|
0
|
|
|
sub DESTROY {} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
1; |
282
|
|
|
|
|
|
|
__END__ |