File Coverage

blib/lib/Imager/Search/Pattern.pm
Criterion Covered Total %
statement 67 81 82.7
branch 20 38 52.6
condition 3 6 50.0
subroutine 12 12 100.0
pod 1 3 33.3
total 103 140 73.5


line stmt bran cond sub pod time code
1             package Imager::Search::Pattern;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Imager::Search::Pattern - Search object for an image
8              
9             =head1 SYNOPSIS
10              
11             my $pattern = Imager::Search::Pattern->new(
12             driver => 'Imager::Search::Driver::HTML24',
13             image => $Imager,
14             );
15            
16             my $regexp = $pattern->regexp;
17              
18             =head1 DESCRIPTION
19              
20             B takes an L object, and converts it
21             into a partially-compiled regular expression.
22              
23             This partial regexp can then be quickly turned into the final L
24             once the widget of the target image is known, as well as being able to
25             be cached.
26              
27             This allows a single B object to be quickly
28             applied to many different sizes of target images.
29              
30             =head1 METHODS
31              
32             =cut
33              
34 5     5   86 use 5.006;
  5         15  
  5         189  
35 5     5   27 use strict;
  5         10  
  5         144  
36 5     5   22 use Carp ();
  5         17  
  5         107  
37 5     5   4592 use IO::File ();
  5         78758  
  5         109  
38 5     5   5416 use Params::Util ();
  5         25676  
  5         121  
39 5     5   16148 use Imager ();
  5         203502  
  5         139  
40              
41 5     5   54 use vars qw{$VERSION};
  5         9  
  5         258  
42             BEGIN {
43 5     5   116 $VERSION = '1.01';
44             }
45              
46 5         41 use Object::Tiny::XS qw{
47             name
48             driver
49             cache
50             file
51             image
52             height
53             width
54             lines
55 5     5   10816 };
  5         24008  
56              
57              
58              
59              
60              
61             #####################################################################
62             # Constructors
63              
64             =pod
65              
66             =head2 new
67              
68             $pattern = Imager::Search::Pattern->new(
69             driver => 'Imager::Search::Driver::HTML24',
70             file => 'search/image.gif',
71             cache => 1,
72             );
73              
74             =cut
75              
76             sub new {
77 6     6 1 14724 my $self = shift->SUPER::new(@_);
78              
79             # Check params
80 6 100       212 if ( Params::Util::_IDENTIFIER($self->driver) ) {
81 2         22 $self->{driver} = "Imager::Search::Driver::" . $self->driver;
82             }
83 6 50       199 if ( Params::Util::_DRIVER($self->driver, 'Imager::Search::Driver') ) {
84 6 50       814 unless ( Params::Util::_INSTANCE($self->driver, 'Imager::Search::Driver') ) {
85 6         52 $self->{driver} = $self->driver->new;
86             }
87             }
88 6 50       76 unless ( Params::Util::_INSTANCE($self->driver, 'Imager::Search::Driver') ) {
89 0         0 Carp::croak("Did not provide a valid driver");
90             }
91 6 100 66     62 if ( defined $self->file and not defined $self->image ) {
92             # Load the image from a file
93 5         39 $self->{image} = Imager->new;
94 5         134 $self->{image}->read( file => $self->file );
95             }
96 6 50       1367 if ( defined $self->image ) {
97 6 50       65 unless( Params::Util::_INSTANCE($self->image, 'Imager') ) {
98 0         0 Carp::croak("Did not provide a valid image");
99             }
100 6         45 $self->{height} = $self->image->getheight;
101 6         155 $self->{width} = $self->image->getwidth;
102 6         96 $self->{lines} = $self->driver->pattern_lines($self->image);
103             }
104 6 50       201 unless ( Params::Util::_POSINT($self->height) ) {
105 0         0 Carp::croak("Invalid or missing image height");
106             }
107 6 50       237 unless ( Params::Util::_POSINT($self->width) ) {
108 0         0 Carp::croak("Invalid or missing image width");
109             }
110 6 50       84 unless ( Params::Util::_ARRAY($self->lines) ) {
111 0         0 Carp::croak("Did not provide an ARRAY of line patterns");
112             }
113              
114             # Normalise caching behaviour
115 6         24 $self->{cache} = !! $self->cache;
116 6 50       25 if ( $self->cache ) {
117 0         0 $self->{regexp} = {};
118             }
119              
120 6         20 return $self;
121             }
122              
123             sub write {
124 1     1 0 266 my $self = shift;
125 1         3 my $io = undef;
126 1 50       8 if ( Params::Util::_INSTANCE($_[0], 'IO::Handle') ) {
    50          
127 0         0 $io = $_[0];
128             } elsif ( Params::Util::_STRING($_[0]) ) {
129 1         6 $io = IO::File->new( $_[0], 'w' );
130 1 50       181 unless ( Params::Util::_INSTANCE($io, 'IO::File') ) {
131 0         0 Carp::croak("Failed to open $_[0] to write");
132             }
133             } else {
134 0         0 Carp::croak("Did not provide a file or handle to write");
135             }
136              
137             # The first line is the class of this object
138 1         10 $io->print( "class: " . ref($self) . "\n" );
139              
140             # Next, a series of key: value pairs of the main properties
141 1         10 foreach my $key ( qw{ driver width height } ) {
142 3         20 $io->print( $key . ': ' . $self->$key() . "\n" );
143             }
144              
145             # Ending with a blank newline to indicate the end of the headers
146 1         7 $io->print("\n");
147              
148             # And now we print all of the pattern lines
149 1         6 my $lines = $self->lines;
150 1         3 foreach ( 0 .. $#$lines ) {
151 13         88 $io->print( $lines->[0] . "\n" );
152             }
153              
154             # Return without closing.
155             # Any file we opened will auto-close,
156             # and anyone passing a handle should close it themselves.
157 1         64 return 1;
158             }
159              
160              
161              
162              
163              
164             #####################################################################
165             # Main Methods
166              
167             sub regexp {
168 6     6 0 12 my $self = shift;
169              
170             # Get the width param
171 6         9 my $width = undef;
172 6 50       87 if ( Params::Util::_INSTANCE($_[0], 'Imager') ) {
    50          
    0          
173 0         0 $width = $_[0]->getwidth;
174             } elsif ( Params::Util::_INSTANCE($_[0], 'Imager::Search::Image') ) {
175 6         19 $width = $_[0]->width;
176             } elsif ( Params::Util::_POSINT($_[0]) ) {
177 0         0 $width = $_[0];
178             } else {
179 0         0 Carp::croak("Did not provide a width to Imager::Search::Pattern::regexp");
180             }
181              
182             # Return the cached version if possible
183 6 50 33     32 if ( $self->cache and $self->{regexp}->{$width} ) {
184 0         0 return $self->{regexp}->{$width};
185             }
186              
187             # Hand off to the driver to build the regexp
188 6         37 my $regexp = $self->driver->pattern_regexp( $self, $width );
189              
190             # Cache if needed
191 6 50       27 if ( $self->cache ) {
192 0         0 $self->{regexp}->{$width} = $regexp;
193             }
194              
195 6         18 return $regexp;
196             }
197              
198             1;
199              
200             =pod
201              
202             =head1 SUPPORT
203              
204             See the SUPPORT section of the main L module.
205              
206             =head1 AUTHOR
207              
208             Adam Kennedy Eadamk@cpan.orgE
209              
210             =head1 COPYRIGHT
211              
212             Copyright 2007 - 2011 Adam Kennedy.
213              
214             This program is free software; you can redistribute
215             it and/or modify it under the same terms as Perl itself.
216              
217             The full text of the license can be found in the
218             LICENSE file included with this module.
219              
220             =cut