line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Grid::Coord;
|
2
|
1
|
|
|
1
|
|
679
|
use strict; use warnings;
|
|
1
|
|
|
1
|
|
3
|
|
|
1
|
|
|
|
|
29
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
23
|
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
1117
|
use Data::Dumper;
|
|
1
|
|
|
|
|
26862
|
|
|
1
|
|
|
|
|
88
|
|
5
|
1
|
|
|
1
|
|
9
|
use Carp qw/confess/;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
602
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.05';
|
8
|
|
|
|
|
|
|
# $Id$
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
########################################### main pod documentation begin ##
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Grid::Coord - abstract representation and manipulation of points and rectangles
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Grid::Coord
|
19
|
|
|
|
|
|
|
my $point1 = Grid::Coord->new(5,4); # point(y=>5, x=>4)
|
20
|
|
|
|
|
|
|
my $rect1 = Grid::Coord->new(2,3 => 6,5); # rectangle
|
21
|
|
|
|
|
|
|
print "TRUE" if $rect1->contains($point1);
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my $rect2 = Grid::Coord->new(3,4 => 5,5); # another rectangle
|
24
|
|
|
|
|
|
|
my $rect3 = $rect1->overlap($rect2) # (3,4 => 5,5)
|
25
|
|
|
|
|
|
|
print $rect3->stringify; # "(3,4 => 5,5)"
|
26
|
|
|
|
|
|
|
print $rect3; # "(3,4 => 5,5)"
|
27
|
|
|
|
|
|
|
print "TRUE" if $rect3->equals(Grid::Coord->new(3,4 => 5,5));
|
28
|
|
|
|
|
|
|
print "TRUE" if $rect3 == Grid::Coord->new(3,4 => 5,5);
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
Manage points or rectangles on a grid. This is generic, and could
|
33
|
|
|
|
|
|
|
be used for spreadsheets, ascii art, or other nefarious purposes.
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 USAGE
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head2 Constructor
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
Grid->Coord->new($y, $x);
|
40
|
|
|
|
|
|
|
Grid->Coord->new($min_y, $min_x, $max_y, $max_x);
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head2 Accessing coordinates
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
The C, C, C, C functions:
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
print $coord->max_x; # get value
|
47
|
|
|
|
|
|
|
$coord->min_x(4); # set value to 4
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head2 Relationships with other Coords
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
$c3 = $c1->overlap($c2);
|
52
|
|
|
|
|
|
|
print "TRUE" if $rect1->contains($rect2);
|
53
|
|
|
|
|
|
|
print "TRUE" if $rect1->equals($rect2);
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head2 Overloaded operators
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
Four operators are overloaded:
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=over 4
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item * the stringification operator
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
So that C does something reasonable
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item * the equality operator
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
so that C
|
68
|
|
|
|
|
|
|
does the right thing.
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=item * the add operator
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
So that C<$c1 + $c2> is a synonym for C<$c1->offset($c2)>
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item * the subtract operator
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
So that C<$c1 - $c2> is a synonym for C<$c1->delta($c2)>
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=back
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head2 Iterating
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
The iterator returns a Grid::Coord object for each cell in the current
|
83
|
|
|
|
|
|
|
Grid::Coord range.
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
my $it = $grid->cell_iterator; # or ->cell_iterator_rowwise
|
86
|
|
|
|
|
|
|
# my $it = $grid->cell_iterator_colwise; # top to bottom
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
while (my $cell = $it3->()) {
|
89
|
|
|
|
|
|
|
# do something to $cell
|
90
|
|
|
|
|
|
|
}
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
You can also iterate columns/rows with
|
93
|
|
|
|
|
|
|
$grid->cells_iterator
|
94
|
|
|
|
|
|
|
$grid->rows_iterator
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head1 BUGS
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
None reported yet.
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head1 SUPPORT
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
From the author.
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 AUTHOR
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
osfameron@cpan.org
|
107
|
|
|
|
|
|
|
http://osfameron.perlmonk.org/
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=head1 COPYRIGHT
|
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
This program is free software; you can redistribute
|
112
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself.
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
The full text of the license can be found in the
|
115
|
|
|
|
|
|
|
LICENSE file included with this module.
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=head1 SEE ALSO
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
perl(1).
|
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=cut
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
use overload
|
125
|
1
|
|
|
|
|
14
|
q("") => \&stringify,
|
126
|
|
|
|
|
|
|
q(==) => \&equals,
|
127
|
|
|
|
|
|
|
q(!=) => \¬_equals,
|
128
|
|
|
|
|
|
|
q(+) => \&offset,
|
129
|
1
|
|
|
1
|
|
7
|
q(-) => \δ
|
|
1
|
|
|
|
|
2
|
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub new
|
132
|
|
|
|
|
|
|
{
|
133
|
267
|
|
|
267
|
0
|
761
|
my $class = shift;
|
134
|
|
|
|
|
|
|
|
135
|
267
|
100
|
|
|
|
678
|
if (@_ == 2) {
|
|
|
50
|
|
|
|
|
|
136
|
70
|
|
|
|
|
120
|
push @_, @_;
|
137
|
|
|
|
|
|
|
} elsif (@_ != 4) {
|
138
|
0
|
|
|
|
|
0
|
die "Grid::Coord objects must be (y,x) or (miny,minx=>maxy,maxx)\n";
|
139
|
|
|
|
|
|
|
}
|
140
|
|
|
|
|
|
|
|
141
|
267
|
|
66
|
|
|
1330
|
my $self = bless [@_], (ref ($class) || $class);
|
142
|
267
|
|
|
|
|
1031
|
return ($self);
|
143
|
|
|
|
|
|
|
}
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub min_y {
|
146
|
210
|
|
|
210
|
0
|
222
|
my $self=shift;
|
147
|
210
|
50
|
|
|
|
871
|
if (! @_) { return $self->[0] }
|
|
210
|
|
|
|
|
496
|
|
148
|
0
|
|
|
|
|
0
|
else { $self->[0] = shift }
|
149
|
|
|
|
|
|
|
}
|
150
|
|
|
|
|
|
|
sub min_x {
|
151
|
206
|
|
|
206
|
0
|
229
|
my $self=shift;
|
152
|
206
|
50
|
|
|
|
307
|
if (! @_) { return $self->[1] }
|
|
206
|
|
|
|
|
446
|
|
153
|
0
|
|
|
|
|
0
|
else { $self->[1] = shift }
|
154
|
|
|
|
|
|
|
}
|
155
|
|
|
|
|
|
|
sub max_y {
|
156
|
206
|
|
|
206
|
0
|
216
|
my $self=shift;
|
157
|
206
|
50
|
|
|
|
306
|
if (! @_) { return $self->[2] }
|
|
206
|
|
|
|
|
462
|
|
158
|
0
|
|
|
|
|
0
|
else { $self->[2] = shift }
|
159
|
|
|
|
|
|
|
}
|
160
|
|
|
|
|
|
|
sub max_x {
|
161
|
206
|
|
|
206
|
0
|
207
|
my $self=shift;
|
162
|
206
|
50
|
|
|
|
295
|
if (! @_) { return $self->[3] }
|
|
206
|
|
|
|
|
474
|
|
163
|
0
|
|
|
|
|
0
|
else { $self->[3] = shift }
|
164
|
|
|
|
|
|
|
}
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub is_point {
|
167
|
460
|
|
|
460
|
0
|
504
|
my $self = shift;
|
168
|
460
|
|
|
|
|
664
|
for (0..1) {
|
169
|
716
|
|
|
|
|
1128
|
my ($min, $max) = ($self->[$_], $self->[$_+2]);
|
170
|
716
|
100
|
66
|
|
|
2447
|
return unless defined $min && defined $max;
|
171
|
405
|
100
|
|
|
|
962
|
return unless $min == $max;
|
172
|
|
|
|
|
|
|
}
|
173
|
49
|
|
|
|
|
132
|
return 1;
|
174
|
|
|
|
|
|
|
}
|
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub overlap {
|
177
|
103
|
|
|
103
|
0
|
358
|
my ($self, $other)=@_;
|
178
|
103
|
50
|
|
|
|
323
|
if (! $other->isa(__PACKAGE__)) {
|
179
|
0
|
|
|
|
|
0
|
die "Can't overlap with something that isn't a Grid::Coord object!\n";
|
180
|
|
|
|
|
|
|
}
|
181
|
103
|
|
|
|
|
201
|
my @coords = (
|
182
|
|
|
|
|
|
|
max($self->min_y, $other->min_y),
|
183
|
|
|
|
|
|
|
max($self->min_x, $other->min_x),
|
184
|
|
|
|
|
|
|
min($self->max_y, $other->max_y),
|
185
|
|
|
|
|
|
|
min($self->max_x, $other->max_x)
|
186
|
|
|
|
|
|
|
);
|
187
|
103
|
100
|
100
|
|
|
453
|
return if ($coords[0] > $coords[2] or
|
188
|
|
|
|
|
|
|
$coords[1] > $coords[3]);
|
189
|
88
|
|
|
|
|
183
|
return $self->new(@coords);
|
190
|
|
|
|
|
|
|
}
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub contains {
|
193
|
2
|
|
|
2
|
0
|
6
|
my ($self, $other)=@_;
|
194
|
2
|
50
|
|
|
|
10
|
if (! $other->isa(__PACKAGE__)) {
|
195
|
0
|
|
|
|
|
0
|
die "Can't 'contains' with something that isn't a Grid::Coord object!\n";
|
196
|
|
|
|
|
|
|
}
|
197
|
2
|
|
|
|
|
5
|
return ($self->overlap($other) == $other);
|
198
|
|
|
|
|
|
|
}
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub stringify {
|
201
|
460
|
|
|
460
|
0
|
1603
|
my $self=shift;
|
202
|
460
|
100
|
|
|
|
776
|
my @rep = map { defined $_ ? $_ : 'null' } @$self;
|
|
1840
|
|
|
|
|
3657
|
|
203
|
460
|
100
|
|
|
|
967
|
if ($self->is_point) {
|
204
|
49
|
|
|
|
|
218
|
return "($rep[0],$rep[1])"
|
205
|
|
|
|
|
|
|
} else {
|
206
|
411
|
|
|
|
|
2020
|
return "($rep[0],$rep[1], $rep[2],$rep[3])";
|
207
|
|
|
|
|
|
|
}
|
208
|
|
|
|
|
|
|
}
|
209
|
|
|
|
|
|
|
sub equals {
|
210
|
37
|
|
|
37
|
0
|
56
|
my ($self, $other) = @_;
|
211
|
37
|
|
|
|
|
65
|
for (0..3) {
|
212
|
|
|
|
|
|
|
return unless
|
213
|
123
|
100
|
100
|
|
|
545
|
(defined $self->[$_]) ?
|
|
|
100
|
|
|
|
|
|
214
|
|
|
|
|
|
|
defined $other->[$_] && $self->[$_] == $other->[$_]
|
215
|
|
|
|
|
|
|
: ! defined $other->[$_];
|
216
|
|
|
|
|
|
|
}
|
217
|
26
|
|
|
|
|
102
|
return $self;
|
218
|
|
|
|
|
|
|
}
|
219
|
|
|
|
|
|
|
sub not_equals {
|
220
|
|
|
|
|
|
|
# new versions of Test::Builder seem to make cmp_ok fail on this
|
221
|
1
|
|
|
1
|
0
|
3
|
my ($self, $other) = @_;
|
222
|
1
|
|
|
|
|
4
|
return ! $self->equals($other);
|
223
|
|
|
|
|
|
|
}
|
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub offset { # 'add' 2 ranges together, offsetting them
|
226
|
120
|
|
|
120
|
0
|
149
|
my $self=shift;
|
227
|
120
|
100
|
|
|
|
223
|
if (ref $_[0] eq "Grid::Coord") {
|
228
|
61
|
|
|
|
|
79
|
my $other = shift;
|
229
|
61
|
|
|
|
|
57
|
my @coords;
|
230
|
61
|
|
|
|
|
95
|
for (0..3) {
|
231
|
128
|
|
|
128
|
|
4288
|
push @coords, only($self->[$_],$other->[$_],sub { return $_[0]+$_[1] })
|
232
|
244
|
|
|
|
|
1250
|
}
|
233
|
61
|
|
|
|
|
153
|
return $self->new(@coords);
|
234
|
|
|
|
|
|
|
} else {
|
235
|
59
|
|
|
|
|
118
|
return $self->offset($self->new(@_));
|
236
|
|
|
|
|
|
|
}
|
237
|
|
|
|
|
|
|
}
|
238
|
|
|
|
|
|
|
sub delta { # 'subtract' 2 ranges together, calculating the offest
|
239
|
3
|
|
|
3
|
0
|
10
|
my $self=shift;
|
240
|
3
|
50
|
|
|
|
8
|
if (ref $_[0] eq "Grid::Coord") {
|
241
|
3
|
|
|
|
|
4
|
my $other = shift;
|
242
|
3
|
|
|
|
|
3
|
my @coords;
|
243
|
3
|
|
|
|
|
6
|
for (0..3) {
|
244
|
12
|
|
|
12
|
|
53
|
push @coords, only($self->[$_],$other->[$_],sub { return $_[1]-$_[0] })
|
245
|
12
|
|
|
|
|
41
|
}
|
246
|
3
|
|
|
|
|
7
|
return $self->new(@coords);
|
247
|
|
|
|
|
|
|
} else {
|
248
|
0
|
|
|
|
|
0
|
return $self->offset($self->new(@_));
|
249
|
|
|
|
|
|
|
}
|
250
|
|
|
|
|
|
|
}
|
251
|
|
|
|
|
|
|
|
252
|
3
|
|
|
3
|
0
|
1450
|
sub head { my $self=shift; return $self->new($self->[0], $self->[1]) }
|
|
3
|
|
|
|
|
12
|
|
253
|
2
|
|
|
2
|
0
|
4
|
sub tail { my $self=shift; return $self->new($self->[2], $self->[3]) }
|
|
2
|
|
|
|
|
7
|
|
254
|
|
|
|
|
|
|
|
255
|
15
|
|
|
15
|
0
|
19
|
sub row {my $self=shift; return $self->new($self->[0],undef,$self->[0],undef)}
|
|
15
|
|
|
|
|
41
|
|
256
|
16
|
|
|
16
|
0
|
18
|
sub col {my $self=shift; return $self->new(undef, $self->[1],undef,$self->[1])}
|
|
16
|
|
|
|
|
44
|
|
257
|
|
|
|
|
|
|
|
258
|
206
|
|
66
|
206
|
0
|
345
|
sub min { return only(@_) || (($_[0] < $_[1]) ? $_[0] : $_[1]) }
|
259
|
206
|
|
66
|
206
|
0
|
333
|
sub max { return only(@_) || (($_[0] > $_[1]) ? $_[0] : $_[1]) }
|
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=begin developer
|
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=head3 only
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
A convenience function. Has 2 forms.
|
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
only($a, $b);
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
The 2 arg form returns the other argument if one argument is undef.
|
272
|
|
|
|
|
|
|
(As a consequence, if both are null, it returns null). If neither are undef,
|
273
|
|
|
|
|
|
|
it also returns null. This is useful for the min and max functions, where
|
274
|
|
|
|
|
|
|
we want to be able to calculate intersections, but also of row and column
|
275
|
|
|
|
|
|
|
ranges where one side may be undef).
|
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
only($a, $b, sub { ... });
|
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
Again, returns the other argument if one argument is undef. However, if neither
|
280
|
|
|
|
|
|
|
is undef it passes both arguments to the coderef. This is useful in calculating
|
281
|
|
|
|
|
|
|
offsets, where we want this kind of behaviour:
|
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
0 + 0 = 0
|
284
|
|
|
|
|
|
|
undef + 0 = 0
|
285
|
|
|
|
|
|
|
undef + undef = undef
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=cut
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
sub only {
|
290
|
668
|
100
|
|
668
|
1
|
1979
|
if (! defined $_[0]) { return $_[1]}
|
|
314
|
|
|
|
|
1052
|
|
291
|
354
|
100
|
|
|
|
581
|
if (! defined $_[1]) { return $_[0]}
|
|
82
|
|
|
|
|
258
|
|
292
|
272
|
100
|
|
|
|
455
|
if (my $coderef=$_[2]) {
|
293
|
140
|
|
|
|
|
276
|
return $coderef->(@_)
|
294
|
|
|
|
|
|
|
} else {
|
295
|
|
|
|
|
|
|
return
|
296
|
132
|
|
|
|
|
591
|
}
|
297
|
|
|
|
|
|
|
}
|
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
{
|
300
|
1
|
|
|
1
|
|
1474
|
no warnings 'once';
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
484
|
|
301
|
|
|
|
|
|
|
*cell_iterator=\&cell_iterator_rowwise;
|
302
|
|
|
|
|
|
|
}
|
303
|
|
|
|
|
|
|
sub cell_iterator_rowwise {
|
304
|
1
|
|
|
1
|
0
|
3
|
my $self=shift;
|
305
|
6
|
|
|
6
|
|
14
|
return $self->_cell_iterator(
|
306
|
|
|
|
|
|
|
$self->rows_iterator,
|
307
|
1
|
|
|
|
|
6
|
sub{$self->cols_iterator});
|
308
|
|
|
|
|
|
|
}
|
309
|
|
|
|
|
|
|
sub cell_iterator_colwise {
|
310
|
1
|
|
|
1
|
0
|
2
|
my $self=shift;
|
311
|
5
|
|
|
5
|
|
19
|
return $self->_cell_iterator(
|
312
|
|
|
|
|
|
|
$self->cols_iterator,
|
313
|
1
|
|
|
|
|
3
|
sub{$self->rows_iterator});
|
314
|
|
|
|
|
|
|
}
|
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub _cell_iterator {
|
317
|
|
|
|
|
|
|
# We pass in the major-line iterator as an iterator.
|
318
|
|
|
|
|
|
|
# However, as the minor-line iterator will be created
|
319
|
|
|
|
|
|
|
# various times, we pass in a factory function instead!
|
320
|
|
|
|
|
|
|
|
321
|
2
|
|
|
2
|
|
5
|
my ($self, $maj_it, $min_fac) = @_;
|
322
|
2
|
|
|
|
|
4
|
my $min_it = $min_fac->();
|
323
|
|
|
|
|
|
|
|
324
|
2
|
|
|
|
|
4
|
my $maj=$maj_it->();
|
325
|
|
|
|
|
|
|
return sub {
|
326
|
|
|
|
|
|
|
{
|
327
|
42
|
100
|
|
42
|
|
190
|
return unless $maj;
|
|
51
|
|
|
|
|
96
|
|
328
|
49
|
100
|
|
|
|
93
|
if (my $min=$min_it->()) {
|
329
|
40
|
|
|
|
|
91
|
return $maj->overlap($min)
|
330
|
|
|
|
|
|
|
} else {
|
331
|
9
|
|
|
|
|
17
|
$maj = $maj_it->();
|
332
|
9
|
|
|
|
|
23
|
$min_it = $min_fac->();
|
333
|
9
|
|
|
|
|
36
|
redo;
|
334
|
|
|
|
|
|
|
}
|
335
|
|
|
|
|
|
|
}
|
336
|
|
|
|
|
|
|
}
|
337
|
2
|
|
|
|
|
21
|
}
|
338
|
|
|
|
|
|
|
sub rows_iterator {
|
339
|
7
|
|
|
7
|
0
|
10
|
my $self=shift;
|
340
|
7
|
|
|
|
|
17
|
my $row=$self->row;
|
341
|
7
|
|
|
|
|
19
|
return $self->line_iterator($row, 1, undef);
|
342
|
|
|
|
|
|
|
}
|
343
|
|
|
|
|
|
|
sub cols_iterator {
|
344
|
8
|
|
|
8
|
0
|
12
|
my $self=shift;
|
345
|
8
|
|
|
|
|
16
|
my $col=$self->col;
|
346
|
8
|
|
|
|
|
27
|
return $self->line_iterator($col, undef, 1);
|
347
|
|
|
|
|
|
|
}
|
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sub line_iterator {
|
350
|
15
|
|
|
15
|
0
|
28
|
my ($self, $orig_line, $y, $x)=@_;
|
351
|
15
|
|
|
|
|
15
|
my $line=$orig_line;
|
352
|
|
|
|
|
|
|
return sub {
|
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
# TODO: warning on next line in eq
|
355
|
|
|
|
|
|
|
#if ($_[0] eq 'clone') { die;return line_iterator($self,$orig_line, $y,$x) }
|
356
|
|
|
|
|
|
|
|
357
|
73
|
|
|
73
|
|
3308
|
my $old_line = $line;
|
358
|
73
|
100
|
|
|
|
123
|
if ($line) {
|
359
|
58
|
|
|
|
|
133
|
$line = $line->offset($y,$x);
|
360
|
58
|
100
|
|
|
|
158
|
if (! $line->overlap($self)) {
|
361
|
13
|
|
|
|
|
22
|
$line=undef;
|
362
|
|
|
|
|
|
|
}
|
363
|
|
|
|
|
|
|
}
|
364
|
73
|
|
|
|
|
225
|
return $old_line;
|
365
|
|
|
|
|
|
|
}
|
366
|
15
|
|
|
|
|
88
|
}
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
1; #this line is important and will help the module return a true value
|
369
|
|
|
|
|
|
|
__END__
|