File Coverage

blib/lib/LaTeX/TikZ/Mod/Pattern/Lines.pm
Criterion Covered Total %
statement 23 23 100.0
branch 1 2 50.0
condition n/a
subroutine 8 8 100.0
pod 2 2 100.0
total 34 35 97.1


line stmt bran cond sub pod time code
1             package LaTeX::TikZ::Mod::Pattern::Lines;
2              
3 2     2   2546 use strict;
  2         6  
  2         88  
4 2     2   16 use warnings;
  2         5  
  2         108  
5              
6             =head1 NAME
7              
8             LaTeX::TikZ::Mod::Pattern::Lines - An hatched pattern modifier.
9              
10             =head1 VERSION
11              
12             Version 0.02
13              
14             =cut
15              
16             our $VERSION = '0.02';
17              
18 2     2   13 use Sub::Name ();
  2         5  
  2         43  
19              
20 2     2   13 use LaTeX::TikZ::Tools;
  2         5  
  2         49  
21              
22 2     2   12 use Any::Moose;
  2         5  
  2         19  
23 2     2   5371 use Any::Moose 'Util::TypeConstraints';
  2         6  
  2         10  
24              
25             =head1 RELATIONSHIPS
26              
27             This class inherits the L<LaTeX::TikZ::Mod::Pattern> class and its L</tag>, L</covers>, L<LaTeX::TikZ::Mod::Pattern/declare> and L<LaTeX::TikZ::Mod::Pattern/apply> methods.
28              
29             =cut
30              
31             extends 'LaTeX::TikZ::Mod::Pattern';
32              
33             =head1 ATTRIBUTES
34              
35             =head2 C<direction>
36              
37             =cut
38              
39             enum 'LaTeX::TikZ::Mod::Pattern::Direction' => (
40             'horizontal', 'vertical', 'north east', 'north west',
41             );
42              
43             has 'direction' => (
44             is => 'ro',
45             isa => 'LaTeX::TikZ::Mod::Pattern::Direction',
46             default => 'horizontal',
47             );
48              
49             =head2 C<line_width>
50              
51             =cut
52              
53             has 'line_width' => (
54             is => 'ro',
55             isa => subtype('Num' => where { LaTeX::TikZ::Tools::numcmp($_, 0) >= 0 }),
56             default => 1,
57             );
58              
59             =head2 C<space_width>
60              
61             =cut
62              
63             has 'space_width' => (
64             is => 'ro',
65             isa => subtype('Num' => where { LaTeX::TikZ::Tools::numcmp($_, 0) >= 0 }),
66             default => 10,
67             );
68              
69             my $W = Sub::Name::subname('WIDTH' => sub { sprintf '#WIDTH=%0.1f#', @_ });
70              
71             my $forge_template = Sub::Name::subname('forge_template' => sub {
72             my ($direction, $line_width, $space_width) = @_;
73              
74             my ($low_left, $up_right, $tile_size, $line_begin, $line_end);
75             my ($width, $half_width, $shadow_min, $shadow_max);
76              
77             $width = $W->($space_width);
78             $half_width = $W->($space_width / 2);
79              
80             $shadow_min = $W->(- $line_width);
81             $shadow_max = $W->($space_width + $line_width);
82             $line_width = $W->($line_width);
83              
84             $low_left = "\\pgfqpoint{$shadow_min}{$shadow_min}";
85             $up_right = "\\pgfqpoint{$shadow_max}{$shadow_max}";
86             $tile_size = "\\pgfqpoint{$width}{$width}";
87              
88             if ($direction =~ /^(?:horizontal|vertical)$/) {
89              
90             if ($direction eq 'horizontal') {
91             $line_begin = "\\pgfqpoint{$shadow_min}{$half_width}";
92             $line_end = "\\pgfqpoint{$shadow_max}{$half_width}";
93             } else {
94             $line_begin = "\\pgfqpoint{$half_width}{$shadow_min}";
95             $line_end = "\\pgfqpoint{$half_width}{$shadow_max}";
96             }
97              
98             } elsif ($direction =~ /^north (?:east|west)$/) {
99              
100             if ($direction eq 'north east') {
101             $line_begin = "\\pgfqpoint{$shadow_min}{$shadow_min}";
102             $line_end = "\\pgfqpoint{$shadow_max}{$shadow_max}";
103             } else {
104             $line_begin = "\\pgfqpoint{$shadow_min}{$shadow_max}";
105             $line_end = "\\pgfqpoint{$shadow_max}{$shadow_min}";
106             }
107              
108             } else {
109             return;
110             }
111              
112             return [
113             "\\pgfdeclarepatternformonly{#NAME#}{$low_left}{$up_right}{$tile_size}{",
114             "\\pgfsetlinewidth{$line_width}",
115             "\\pgfpathmoveto{$line_begin}",
116             "\\pgfpathlineto{$line_end}",
117             "\\pgfusepath{stroke}",
118             "}",
119             ];
120             });
121              
122             around 'BUILDARGS' => sub {
123             my ($orig, $class, %args) = @_;
124              
125             confess('Can\'t specify an explicit template for a '. __PACKAGE__ .' pattern')
126             if exists $args{template};
127              
128             my @params = qw/direction line_width space_width/;
129              
130             my $meta = $class->meta;
131             for (@params) {
132             my $attr = $meta->find_attribute_by_name($_);
133             $args{$_} = $attr->default if $attr->has_default and not exists $args{$_};
134             $attr->type_constraint->assert_valid($args{$_});
135             }
136              
137             $args{template} = $forge_template->(@args{@params});
138              
139             $class->$orig(%args);
140             };
141              
142             =head1 METHODS
143              
144             =head2 C<tag>
145              
146             =cut
147              
148 12     12 1 60 sub tag { join '/', ref $_[0], $_[0]->direction }
149              
150             =head2 C<covers>
151              
152             =cut
153              
154             sub covers {
155 1     1 1 3 my ($this, $other) = @_;
156              
157 1 50       11 LaTeX::TikZ::Tools::numeq($this->line_width, $other->line_width) or return 0;
158              
159 1         7 my $ratio = $other->space_width / $this->space_width;
160              
161 1         5 return LaTeX::TikZ::Tools::numeq($ratio, int $ratio);
162             }
163              
164             __PACKAGE__->meta->make_immutable;
165              
166             =head1 SEE ALSO
167              
168             L<LaTeX::TikZ>, L<LaTeX::TikZ::Mod::Pattern>.
169              
170             =head1 AUTHOR
171              
172             Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
173              
174             You can contact me by mail or on C<irc.perl.org> (vincent).
175              
176             =head1 BUGS
177              
178             Please report any bugs or feature requests to C<bug-latex-tikz at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=LaTeX-TikZ>.
179             I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
180              
181             =head1 SUPPORT
182              
183             You can find documentation for this module with the perldoc command.
184              
185             perldoc LaTeX::TikZ
186              
187             =head1 COPYRIGHT & LICENSE
188              
189             Copyright 2010 Vincent Pit, all rights reserved.
190              
191             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
192              
193             =cut
194              
195             1; # End of LaTeX::TikZ::Mod::Pattern::Lines