]> git.vpit.fr Git - perl/modules/LaTeX-TikZ.git/blob - lib/LaTeX/TikZ/Mod/Pattern/Lines.pm
c2272fec642a020d609b9f4dd9dc04aba7983ec8
[perl/modules/LaTeX-TikZ.git] / lib / LaTeX / TikZ / Mod / Pattern / Lines.pm
1 package LaTeX::TikZ::Mod::Pattern::Lines;
2
3 use strict;
4 use warnings;
5
6 =head1 NAME
7
8 LaTeX::TikZ::Mod::Pattern::Lines - An hatched pattern modifier.
9
10 =head1 VERSION
11
12 Version 0.01
13
14 =cut
15
16 our $VERSION = '0.01';
17
18 use Sub::Name ();
19
20 use LaTeX::TikZ::Tools;
21
22 use Any::Moose;
23 use Any::Moose 'Util::TypeConstraints';
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 sub tag { join '/', ref $_[0], $_[0]->direction }
149
150 =head2 C<covers>
151
152 =cut
153
154 sub covers {
155  my ($this, $other) = @_;
156
157  LaTeX::TikZ::Tools::numeq($this->line_width, $other->line_width) or return 0;
158
159  my $ratio = $other->space_width / $this->space_width;
160
161  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