Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / Pastel / Geometry / GeneralPath.pm
CommitLineData
86530b38
AT
1#$Id: GeneralPath.pm,v 1.7 2003/04/22 16:28:12 malay Exp $
2
3# Perl module for GeneralPath
4# Author: Malay < curiouser@ccmb.res.in >
5# Copyright Malay
6# You may distribute this module under the same terms as perl itself
7
8# POD documentation - main docs before the code
9
10=head1 NAME
11
12GeneralPath - DESCRIPTION of Object
13
14=head1 SYNOPSIS
15
16Give standard usage here
17
18=head1 DESCRIPTION
19
20Describe the object here
21
22=head1 CONTACT
23
24Malay <curiouser@ccmb.ap.nic.in>
25
26=cut
27
28# Let the code begin...
29
30package Pastel::Geometry::GeneralPath;
31@ISA = qw(Pastel::Root Pastel::Shape);
32
33use Pastel::Root;
34use Pastel::Shape;
35use Pastel::Geometry::PathIteratorI;
36use Pastel::Geometry::Point;
37use strict;
38use Carp;
39
40=head1 CONSTRUCTOR
41
42=cut
43
44# _init is where the heavy stuff will happen when new is called
45
46# Some static constants
47
48use constant WIND_EVEN_ODD => 'WIND_EVEN_ODD';
49use constant WIND_NON_ZERO => 'WIND_NON_ZERO';
50use constant SEG_MOVETO => 'SEG_MOVETO';
51use constant SEG_LINETO => 'SEG_LINETO';
52use constant SEG_QUADTO => 'SEG_QUADTO';
53use constant SEG_CUBICTO => 'SEG_CUBICTO';
54use constant SEG_CLOSE => 'SEG_CLOSE';
55use constant SEG_ARCTO => 'SEG_ARCTO';
56
57sub _init {
58 my ( $self, @args ) = @_;
59 my ( $rule, $shape ) = $self->_rearrange( [ 'RULE', 'SHAPE' ], @args );
60 if ( defined($rule) && $rule eq 'WIND_EVEN_ODD' ) {
61 $self->set_winding_rule('WIND_EVEN_ODD');
62 }
63 else {
64 $self->set_winding_rule('WIND_NON_ZERO'); # Default winding rule
65 }
66 $self->{types} = []; # Segment types
67 $self->{coord} = []; # xy coord of each point
68 $self->{numtypes} = 0; # y coord of current point
69 $self->{numcoord} = 0;
70 $self->{arc_rotation} = 0;
71
72 # set stuff in self from @args
73 return $self; # success - we hope!
74}
75
76sub get_winding_rule {
77 my $self = shift;
78 return $self->{wind};
79}
80
81
82sub set_winding_rule {
83 my ( $self, $rule ) = @_;
84
85 #print STDERR $rule;
86 if ( ( $rule ne 'WIND_EVEN_ODD' ) && ( $rule ne 'WIND_NON_ZERO' ) ) {
87 die
88'Illegal parameter in Pastel::Geometry::GeneralPath::set_winding_rule()\n';
89 }
90 else {
91 $self->{wind} = $rule;
92 if ( $rule eq 'WIND_EVEN_ODD' ) {
93
94 # default fill rule for SVG is nonzero
95 $self->set_fill_rule('evenodd'); # inherited from Pastel::Shape
96 }
97 }
98}
99
100sub set_arc_rotation {
101 my $self = shift;
102 my $r = shift;
103 if ($r){
104 $self->{arc_rotation} = $r;
105
106 }
107}
108
109sub get_arc_rotation {
110 return $_[0]->{arc_rotation};
111
112}
113sub move_to {
114 my ( $self, $x, $y ) = @_;
115 push ( @{ $self->{types} }, SEG_MOVETO );
116 push ( @{ $self->{coord} }, $x );
117 push ( @{ $self->{coord} }, $y );
118 $self->{numtypes}++;
119 $self->{numcoord} += 2;
120}
121
122sub line_to {
123 my ( $self, $x, $y ) = @_;
124 push ( @{ $self->{types} }, SEG_LINETO );
125 push ( @{ $self->{coord} }, $x );
126 push ( @{ $self->{coord} }, $y );
127 $self->{numtypes}++;
128 $self->{numcoord} += 2;
129}
130
131sub quad_to {
132 my $self = shift;
133 my @array = @_[ 0 .. 3 ];
134 push ( @{ $self->{types} }, SEG_QUADTO );
135 push ( @{ $self->{coord} }, @array );
136 $self->{numtypes}++;
137 $self->{numcoord} += 4;
138}
139
140sub curve_to {
141 my $self = shift;
142 my @array = @_[ 0 .. 5 ];
143 push ( @{ $self->{types} }, SEG_CUBICTO );
144 push ( @{ $self->{coord} }, @array );
145 $self->{numtypes}++;
146 $self->{numcoord} += 6;
147}
148
149sub close_path {
150 my $self = shift;
151 push ( @{ $self->{types} }, SEG_CLOSE );
152 $self->{numtypes}++;
153}
154
155sub arc_to {
156 my $self = shift;
157 push ( @{$self->{types} } , SEG_ARCTO );
158 $self->{numtypes}++;
159 push (@{$self->{coord}}, @_ );
160 $self->{numcoord} += 6;
161}
162sub get_current_point {
163 my $self = shift;
164 if ( $self->{numtypes} < 1 || $self->{numcoord} < 2 ) {
165 return undef;
166 }
167 my $index = $self->{numcoord};
168
169 # If last point is a CLOSE PATH then go back to the beginning
170
171 if ( $self->{types}[ $self->{numtypes} - 1 ] eq 'SEG_CLOSE' ) {
172 for ( my $j = $self->{numtypes} - 2 ; $j > 0 ; $j-- ) {
173 if ( $self->{types}[$j] eq 'SEG_MOVETO' ) {
174 last;
175 }
176 elsif ( $self->{types}[$j] eq 'SEG_LINETO' ) {
177 $index -= 2;
178 next;
179 }
180 elsif ( $self->{types}[$j] eq 'SEG_QUADTO' ) {
181 $index -= 4;
182 next;
183 }
184 elsif ( $self->{types}[$j] eq 'SEG_CUBICTO' ) {
185 $index -= 6;
186 next;
187 }
188 elsif ($self->{types}[$j] eq 'SEG_ARCTO' ){
189 $index -= 6;
190
191 }
192 elsif ( $self->{types}[$j] eq 'SEG_CLOSE' ) {
193 last;
194 }
195 }
196 }
197 return Pastel::Geometry::Point->new(
198 -x => $self->{coord}[ $index - 2 ],
199 -y => $self->{coord}[ $index - 1 ]
200 );
201
202}
203
204sub _draw {
205 my $self = shift;
206 my $graphics = shift;
207 my $s = '<path d="';
208 $s .= $self->to_svg();
209 $s .= '" style="' . $self->get_style($graphics) . '" />';
210 return $s;
211
212}
213
214sub to_svg {
215 my $self = shift;
216 my $index = 0;
217 my $s = "";
218
219 my $x = 0; # holds the last x coordinate
220 my $y = 0; # holds the last y coordinate
221
222 for ( my $i = 0 ; $i < $self->{numtypes} ; $i++ ) {
223 if ( $self->{types}[$i] eq 'SEG_MOVETO' ) {
224 $x = $self->{coord}[$index];
225 $y = $self->{coord}[ $index + 1 ];
226 $s .=
227 'M' . $self->{coord}[$index] . " " . $self->{coord}[ $index + 1 ];
228 $index += 2;
229 next;
230 }
231 elsif ( $self->{types}[$i] eq 'SEG_LINETO' ) {
232 if ( $self->{coord}[$index] == $x ) {
233 $y = $self->{coord}[ $index + 1 ];
234 $s .= 'V' . $y;
235 $index += 2;
236 next;
237 }
238 elsif ( $self->{coord}[ $index + 1 ] == $y ) {
239 $x = $self->{coord}[$index];
240 $s .= 'H' . $x;
241 $index += 2;
242 next;
243 }
244 else {
245 $x = $self->{coord}[$index];
246 $y = $self->{coord}[ $index + 1 ];
247 $s .= 'L'
248 . $self->{coord}[$index] . " "
249 . $self->{coord}[ $index + 1 ];
250 $index += 2;
251 next;
252 }
253 }
254 elsif ( $self->{types}[$i] eq 'SEG_QUADTO' ) {
255 $x = $self->{coord}[ $index + 2 ];
256 $y = $self->{coord}[ $index + 3 ];
257 $s .=
258 'Q' . $self->{coord}[$index] . " " . $self->{coord}[ $index + 1 ];
259 $s .= " " . $x . " " . $y;
260 $index += 4;
261 next;
262 }
263 elsif ( $self->{types}[$i] eq 'SEG_CUBICTO' ) {
264 $x = $self->{coord}[ $index + 4 ];
265 $y = $self->{coord}[ $index + 5 ];
266 $s .=
267 'C' . $self->{coord}[$index] . " " . $self->{coord}[ $index + 1 ];
268 $s .= " "
269 . $self->{coord}[ $index + 2 ] . " "
270 . $self->{coord}[ $index + 3 ];
271 $s .= " " . $x . " " . $y;
272 $index += 6;
273 next;
274 }
275 elsif ($self->{types}[$i] eq 'SEG_ARCTO'){
276 $x = $self->{coord}[ $index + 4];
277 $y = $self->{coord}[ $index + 5];
278 $s .= 'A'.$self->{coord}[$index]." ".$self->{coord}[$index + 1];
279 $s .= " ".$self->get_arc_rotation()." ";
280 $s .= $self->{coord}[$index + 2];
281 $s .= " ".$self->{coord}[$index + 3];
282 $s .= " ".$x." ".$y;
283 $index += 6;
284 next;
285
286
287 }
288 elsif ( $self->{types}[$i] eq 'SEG_CLOSE' ) {
289 $s .= 'z';
290 next;
291 }
292 }
293
294 return $s;
295}
296
297=head1 APPENDIX
298
299
300
301=cut
302
3031;