| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package CAD::Drawing::IO::Circ; |
|
2
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# use CAD::Drawing; |
|
5
|
1
|
|
|
1
|
|
1525
|
use CAD::Drawing::Defined; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
265
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $circtag = ".circ_data"; |
|
8
|
|
|
|
|
|
|
#require Exporter; |
|
9
|
|
|
|
|
|
|
#@EXPORT = qw( |
|
10
|
|
|
|
|
|
|
# pingcirc |
|
11
|
|
|
|
|
|
|
# ); |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
29
|
|
|
15
|
1
|
|
|
1
|
|
5
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
37
|
|
|
16
|
1
|
|
|
1
|
|
8
|
use Carp; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
1671
|
|
|
17
|
|
|
|
|
|
|
######################################################################## |
|
18
|
|
|
|
|
|
|
=pod |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 NAME |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
CAD::Drawing::IO::Circ - load and save for circle data |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 NOTICE |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
This module and the format upon which it relies should be considered |
|
27
|
|
|
|
|
|
|
extremely experimental and should not be used in production except under |
|
28
|
|
|
|
|
|
|
short-term and disposable conditions. |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 INFO |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
This module is intended only as a backend to CAD::Drawing::IO. The only |
|
33
|
|
|
|
|
|
|
method from here which you may want to call directly is pingcirc(), |
|
34
|
|
|
|
|
|
|
which will return information stored in the ".circ_data" file. |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
For loading and saving, please use the front-end interface provided by |
|
37
|
|
|
|
|
|
|
load() and save() in CAD::Drawing::IO. |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 AUTHOR |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
Eric L. Wilhelm |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
http://scratchcomputing.com |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
This module is copyright (C) 2004-2006 by Eric L. Wilhelm. Portions |
|
48
|
|
|
|
|
|
|
copyright (C) 2003 by Eric L. Wilhelm and A. Zahner Co. |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=head1 LICENSE |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
This module is distributed under the same terms as Perl. See the Perl |
|
53
|
|
|
|
|
|
|
source package for details. |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
You may use this software under one of the following licenses: |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
(1) GNU General Public License |
|
58
|
|
|
|
|
|
|
(found at http://www.gnu.org/copyleft/gpl.html) |
|
59
|
|
|
|
|
|
|
(2) Artistic License |
|
60
|
|
|
|
|
|
|
(found at http://www.perl.com/pub/language/misc/Artistic.html) |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head1 NO WARRANTY |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
This software is distributed with ABSOLUTELY NO WARRANTY. The author, |
|
65
|
|
|
|
|
|
|
his former employer, and any other contributors will in no way be held |
|
66
|
|
|
|
|
|
|
liable for any loss or damages resulting from its use. |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=head1 Modifications |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
The source code of this module is made freely available and |
|
71
|
|
|
|
|
|
|
distributable under the GPL or Artistic License. Modifications to and |
|
72
|
|
|
|
|
|
|
use of this software must adhere to one of these licenses. Changes to |
|
73
|
|
|
|
|
|
|
the code should be noted as such and this notification (as well as the |
|
74
|
|
|
|
|
|
|
above copyright information) must remain intact on all copies of the |
|
75
|
|
|
|
|
|
|
code. |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Additionally, while the author is actively developing this code, |
|
78
|
|
|
|
|
|
|
notification of any intended changes or extensions would be most helpful |
|
79
|
|
|
|
|
|
|
in avoiding repeated work for all parties involved. Please contact the |
|
80
|
|
|
|
|
|
|
author with any such development plans. |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
CAD::Drawing |
|
85
|
|
|
|
|
|
|
CAD::Drawing::IO |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=cut |
|
88
|
|
|
|
|
|
|
######################################################################## |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head1 Requisite Plug-in Functions |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
See CAD::Drawing::IO for a description of the plug-in architecture. |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut |
|
95
|
|
|
|
|
|
|
######################################################################## |
|
96
|
|
|
|
|
|
|
# the following are required to be a disc I/O plugin: |
|
97
|
|
|
|
|
|
|
our $can_save_type = "circ"; |
|
98
|
|
|
|
|
|
|
our $can_load_type = $can_save_type; |
|
99
|
|
|
|
|
|
|
our $is_inherited = 1; |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head2 check_type |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Returns true if $type is "circ" or $filename is a directory containing a |
|
104
|
|
|
|
|
|
|
".circ" file. |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
$fact = check_type($filename, $type); |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
|
109
|
|
|
|
|
|
|
sub check_type { |
|
110
|
0
|
|
|
0
|
1
|
|
my ($filename, $type) = @_; |
|
111
|
0
|
0
|
0
|
|
|
|
if(defined($type)) { |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
112
|
0
|
0
|
|
|
|
|
($type eq "circ") && return("circ"); |
|
113
|
0
|
|
|
|
|
|
return(); |
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
elsif((-d $filename) && (-e "$filename/$circtag")) { |
|
116
|
0
|
|
|
|
|
|
return("circ"); |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
elsif(($filename =~ s/^circ(\..*?)://) and (-d $filename)) { |
|
119
|
|
|
|
|
|
|
## print "suffix: $1\n"; |
|
120
|
0
|
|
|
|
|
|
return("circ$1"); |
|
121
|
|
|
|
|
|
|
} |
|
122
|
0
|
|
|
|
|
|
return(); |
|
123
|
|
|
|
|
|
|
} # end subroutine check_type definition |
|
124
|
|
|
|
|
|
|
######################################################################## |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
######################################################################## |
|
127
|
|
|
|
|
|
|
=head1 Methods |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=cut |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=head2 load |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
@list = load($drw, $directory, $opts); |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=cut |
|
136
|
|
|
|
|
|
|
sub load { |
|
137
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
138
|
0
|
|
|
|
|
|
my ($directory, $opts) = @_; |
|
139
|
0
|
|
|
|
|
|
my $info = {}; |
|
140
|
0
|
0
|
|
|
|
|
if($opts->{type} =~ m/(\..*)$/) { |
|
141
|
0
|
|
|
|
|
|
$info->{suffix} = $1; |
|
142
|
0
|
|
|
|
|
|
$directory =~ s/^circ.*://; |
|
143
|
|
|
|
|
|
|
# print "loading from $directory\n"; |
|
144
|
|
|
|
|
|
|
# FIXME: need to unify this type/opts:foo syntax! |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
else { |
|
147
|
0
|
0
|
|
|
|
|
$info = $self->pingcirc($directory) or croak("no $circtag file"); |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
# FIXME: add $info somewhere to toplevel of $self ? |
|
150
|
|
|
|
|
|
|
# except that self is not owned by $info! |
|
151
|
0
|
|
|
|
|
|
my $suffix = $info->{suffix}; |
|
152
|
0
|
|
|
|
|
|
my ($s, $n) = check_select($opts); |
|
153
|
0
|
|
|
|
|
|
my @addr_list; |
|
154
|
|
|
|
|
|
|
my @list; # files to load |
|
155
|
0
|
0
|
|
|
|
|
if($s->{l}) { |
|
156
|
0
|
|
|
|
|
|
@list = map({"$directory/$_$suffix"} keys(%{$s->{l}})); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
} |
|
158
|
|
|
|
|
|
|
else { |
|
159
|
0
|
|
|
|
|
|
@list = glob("$directory/*$suffix"); |
|
160
|
|
|
|
|
|
|
} |
|
161
|
0
|
|
|
|
|
|
foreach my $file (@list) { |
|
162
|
0
|
|
|
|
|
|
my $layer = $file; |
|
163
|
0
|
|
|
|
|
|
$layer =~ s#^$directory/*##; |
|
164
|
0
|
|
|
|
|
|
$layer =~ s/$suffix$//; |
|
165
|
0
|
0
|
0
|
|
|
|
$n->{l} && ($n->{l}{$layer} && next); |
|
166
|
|
|
|
|
|
|
# print "$file -> $layer\n"; |
|
167
|
0
|
|
|
|
|
|
open(CIRCLESIN, $file); |
|
168
|
0
|
|
|
|
|
|
while(my $line = ) { |
|
169
|
0
|
|
|
|
|
|
chomp($line); |
|
170
|
0
|
0
|
|
|
|
|
$line || next; |
|
171
|
0
|
|
|
|
|
|
my($ids,$cord,$r,$co,$lt) = split(/\s*:\s*/, $line); |
|
172
|
0
|
0
|
0
|
|
|
|
$s->{c} && ($s->{c}{$co} || next); |
|
173
|
0
|
0
|
0
|
|
|
|
$n->{c} && ($n->{c}{$co} && next); |
|
174
|
|
|
|
|
|
|
# print "adding id: $ids\n"; |
|
175
|
0
|
|
|
|
|
|
my %addopts = ( |
|
176
|
|
|
|
|
|
|
layer=>$layer, |
|
177
|
|
|
|
|
|
|
color=>$co, |
|
178
|
|
|
|
|
|
|
linetype=>$lt, |
|
179
|
|
|
|
|
|
|
id=>$ids |
|
180
|
|
|
|
|
|
|
); |
|
181
|
0
|
|
|
|
|
|
my @pt = split(/\s*,\s*/, $cord); |
|
182
|
0
|
|
|
|
|
|
my $addr = $self->addcircle(\@pt, $r, {%addopts}); |
|
183
|
0
|
|
|
|
|
|
push(@addr_list, $addr); |
|
184
|
|
|
|
|
|
|
} # end while reading file |
|
185
|
0
|
|
|
|
|
|
close(CIRCLESIN); |
|
186
|
|
|
|
|
|
|
} # end foreach $file |
|
187
|
0
|
|
|
|
|
|
return(@addr_list); |
|
188
|
|
|
|
|
|
|
} # end subroutine load definition |
|
189
|
|
|
|
|
|
|
######################################################################## |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head2 save |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
$drw->save(); |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=cut |
|
196
|
|
|
|
|
|
|
sub save { |
|
197
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
198
|
0
|
|
|
|
|
|
my ($directory, $opts) = @_; |
|
199
|
0
|
|
|
|
|
|
my %opts = %$opts; |
|
200
|
0
|
0
|
|
|
|
|
if(-e $directory) { |
|
201
|
0
|
0
|
|
|
|
|
(-d $directory) or croak("$directory is not a directory"); |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
else { |
|
204
|
0
|
0
|
|
|
|
|
mkdir($directory) or croak("could not create $directory"); |
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
# does the new .circ file smash the old? |
|
207
|
0
|
|
|
|
|
|
my $suffix = $opts->{suffix}; |
|
208
|
0
|
0
|
|
|
|
|
if(my $inf = $self->pingcirc($directory)) { |
|
209
|
0
|
0
|
|
|
|
|
$suffix || ($suffix = $inf->{suffix}); |
|
210
|
|
|
|
|
|
|
} |
|
211
|
0
|
0
|
|
|
|
|
if($opts{type} =~ m/(\..*)$/) { |
|
212
|
0
|
|
|
|
|
|
$suffix = $1; |
|
213
|
|
|
|
|
|
|
} |
|
214
|
0
|
0
|
|
|
|
|
$suffix || die "need suffix\n"; |
|
215
|
0
|
|
|
|
|
|
$opts{suffix} = $suffix; |
|
216
|
0
|
|
|
|
|
|
$self->write_circdata($directory, \%opts); |
|
217
|
0
|
|
|
|
|
|
my ($s, $n) = check_select($opts); |
|
218
|
0
|
|
|
|
|
|
foreach my $layer ($self->getLayerList()) { |
|
219
|
0
|
0
|
0
|
|
|
|
$s->{l} && ($s->{l}{$layer} || next); |
|
220
|
0
|
0
|
0
|
|
|
|
$n->{l} && ($n->{l}{$layer} && next); |
|
221
|
0
|
|
|
|
|
|
my $outfile = "$directory/$layer$suffix"; |
|
222
|
|
|
|
|
|
|
# print "out to $outfile\n"; |
|
223
|
0
|
0
|
|
|
|
|
open(CIRCLESOUT, ">$outfile") or |
|
224
|
|
|
|
|
|
|
croak "cannot open $outfile for write\n"; |
|
225
|
0
|
|
|
|
|
|
foreach my $circ ($self->getAddrByType($layer, "circles")) { |
|
226
|
0
|
|
|
|
|
|
my $obj = $self->getobj($circ); |
|
227
|
0
|
|
|
|
|
|
print CIRCLESOUT "$circ->{id}:" . |
|
228
|
0
|
|
|
|
|
|
join(",", @{$obj->{pt}}) . ":" . |
|
229
|
|
|
|
|
|
|
"$obj->{rad}:$obj->{color}:$obj->{linetype}\n"; |
|
230
|
0
|
0
|
|
|
|
|
$opts->{kok} && $self->remove($circ); |
|
231
|
|
|
|
|
|
|
} |
|
232
|
0
|
|
|
|
|
|
close(CIRCLESOUT); |
|
233
|
|
|
|
|
|
|
} |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
} # end subroutine save definition |
|
236
|
|
|
|
|
|
|
######################################################################## |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=head2 pingcirc |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
Returns a hash reference for colon-separated key-value pairs in the |
|
241
|
|
|
|
|
|
|
".circ_data" file which is found inside of $directory. If the file is |
|
242
|
|
|
|
|
|
|
not found, returns undef. |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
The key may not contain colons. Colons in values will be preserved |
|
245
|
|
|
|
|
|
|
as-is. |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
$drw->pingcirc($directory); |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=cut |
|
250
|
|
|
|
|
|
|
sub pingcirc { |
|
251
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
252
|
0
|
|
|
|
|
|
my ($directory) = @_; |
|
253
|
0
|
0
|
|
|
|
|
open(TAG, "$directory/$circtag") or return(); |
|
254
|
0
|
|
|
|
|
|
my %info; |
|
255
|
0
|
|
|
|
|
|
foreach my $line () { |
|
256
|
0
|
|
|
|
|
|
$line =~ s/\s+$//; |
|
257
|
|
|
|
|
|
|
# keys may not contain colons, but values can |
|
258
|
|
|
|
|
|
|
# whitespace around first colon is optional |
|
259
|
0
|
|
|
|
|
|
my ($key, $val) = split(/\s*:\s*/, $line, 2); |
|
260
|
0
|
|
|
|
|
|
$info{$key} = $val; |
|
261
|
|
|
|
|
|
|
} |
|
262
|
0
|
|
|
|
|
|
close(TAG); |
|
263
|
0
|
|
|
|
|
|
return(\%info); |
|
264
|
|
|
|
|
|
|
} # end subroutine pingcirc definition |
|
265
|
|
|
|
|
|
|
######################################################################## |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=head2 write_circdata |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
$drw->write_circdata($directory, \%options); |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=cut |
|
272
|
|
|
|
|
|
|
sub write_circdata { |
|
273
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
274
|
0
|
|
|
|
|
|
my ($directory, $opts) = @_; |
|
275
|
0
|
|
|
|
|
|
my $circfile = "$directory/$circtag"; |
|
276
|
|
|
|
|
|
|
# maybe load the existing one first and then over-write it? |
|
277
|
0
|
|
|
|
|
|
my $existing = $self->pingcirc($directory); |
|
278
|
0
|
|
|
|
|
|
my %info; |
|
279
|
0
|
0
|
|
|
|
|
$existing && (%info = %$existing); |
|
280
|
0
|
0
|
|
|
|
|
if($opts->{info}) { |
|
281
|
0
|
|
|
|
|
|
foreach my $key (%{$opts->{info}}) { |
|
|
0
|
|
|
|
|
|
|
|
282
|
0
|
|
|
|
|
|
$info{$key} = $opts->{info}{$key}; |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
} |
|
285
|
0
|
|
|
|
|
|
$info{suffix} = $opts->{suffix}; |
|
286
|
0
|
0
|
|
|
|
|
open(CDATA, ">$circfile") or croak "cannot open $circfile for write"; |
|
287
|
0
|
|
|
|
|
|
foreach my $key (keys(%info)) { |
|
288
|
0
|
|
|
|
|
|
print CDATA "$key:$info{$key}\n"; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
0
|
|
|
|
|
|
close(CDATA); |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
} # end subroutine write_circdata definition |
|
293
|
|
|
|
|
|
|
######################################################################## |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
1; |