| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#======================================================================== |
|
2
|
|
|
|
|
|
|
# Kite::XML2PS |
|
3
|
|
|
|
|
|
|
# |
|
4
|
|
|
|
|
|
|
# DESCRIPTION |
|
5
|
|
|
|
|
|
|
# Perl module to convert a curve definition from OpenKite XML format |
|
6
|
|
|
|
|
|
|
# to PostScript, with automatic page tiling and registration mark |
|
7
|
|
|
|
|
|
|
# control. |
|
8
|
|
|
|
|
|
|
# |
|
9
|
|
|
|
|
|
|
# AUTHORS |
|
10
|
|
|
|
|
|
|
# Simon Stapleton wrote the original xml2ps.pl |
|
11
|
|
|
|
|
|
|
# utility which performs the XML -> PostScript conversion. |
|
12
|
|
|
|
|
|
|
# |
|
13
|
|
|
|
|
|
|
# Andy Wardley re-packaged it into a module for |
|
14
|
|
|
|
|
|
|
# integration into the Kite bundle. |
|
15
|
|
|
|
|
|
|
# |
|
16
|
|
|
|
|
|
|
# COPYRIGHT |
|
17
|
|
|
|
|
|
|
# Copyright (C) 2000 Simon Stapleton, Andy Wardley. All Rights Reserved. |
|
18
|
|
|
|
|
|
|
# |
|
19
|
|
|
|
|
|
|
# This module is free software; you can redistribute it and/or |
|
20
|
|
|
|
|
|
|
# modify it under the same terms as Perl itself. |
|
21
|
|
|
|
|
|
|
# |
|
22
|
|
|
|
|
|
|
# VERSION |
|
23
|
|
|
|
|
|
|
# $Id: XML2PS.pm,v 1.3 2000/10/17 12:19:28 abw Exp $ |
|
24
|
|
|
|
|
|
|
# |
|
25
|
|
|
|
|
|
|
#======================================================================== |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
package Kite::XML2PS; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
require 5.004; |
|
30
|
|
|
|
|
|
|
|
|
31
|
1
|
|
|
1
|
|
3703
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
47
|
|
|
32
|
1
|
|
|
1
|
|
436
|
use Kite::Base; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
28
|
|
|
33
|
1
|
|
|
1
|
|
543
|
use Kite::XML::Parser; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
use base qw( Kite::Base ); |
|
36
|
|
|
|
|
|
|
use vars qw( $VERSION $ERROR $DEBUG $PARAMS ); |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
$VERSION = sprintf("%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/); |
|
39
|
|
|
|
|
|
|
$DEBUG = 0 unless defined $DEBUG; |
|
40
|
|
|
|
|
|
|
$ERROR = ''; |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# define parameters for this class, used by Kite::Base init() method |
|
43
|
|
|
|
|
|
|
$PARAMS = { |
|
44
|
|
|
|
|
|
|
FILENAME => undef, |
|
45
|
|
|
|
|
|
|
TITLE => '', |
|
46
|
|
|
|
|
|
|
REGMARKS => 1, |
|
47
|
|
|
|
|
|
|
BORDER => 5, |
|
48
|
|
|
|
|
|
|
MAP => 1, |
|
49
|
|
|
|
|
|
|
}; |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
53
|
|
|
|
|
|
|
# init($config) |
|
54
|
|
|
|
|
|
|
# |
|
55
|
|
|
|
|
|
|
# Initialisation method called by the base class new() constructor |
|
56
|
|
|
|
|
|
|
# method. Calls the base class init() to set any parameters from the |
|
57
|
|
|
|
|
|
|
# $PARAMS hash and then calls process_file() to process the XML |
|
58
|
|
|
|
|
|
|
# file to generate internal PATH and IMAGE definitions. |
|
59
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub init { |
|
62
|
|
|
|
|
|
|
my ($self, $config) = @_; |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# call base class to read config params |
|
65
|
|
|
|
|
|
|
$self->SUPER::init($config) |
|
66
|
|
|
|
|
|
|
|| return undef; |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# process file |
|
69
|
|
|
|
|
|
|
$self->process_file() |
|
70
|
|
|
|
|
|
|
|| return undef; |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# OK |
|
73
|
|
|
|
|
|
|
return $self; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
78
|
|
|
|
|
|
|
# process_file() |
|
79
|
|
|
|
|
|
|
# process_file($filename) |
|
80
|
|
|
|
|
|
|
# |
|
81
|
|
|
|
|
|
|
# Processes the file specified as a parameter, or set internally as |
|
82
|
|
|
|
|
|
|
# the FILENAME item, reading the XML contained therein and generating |
|
83
|
|
|
|
|
|
|
# internal PATH and IMAGE definitions which can be retrieved via the |
|
84
|
|
|
|
|
|
|
# path() and image() methods (handled automatically by the base class |
|
85
|
|
|
|
|
|
|
# AUTOLOAD method). |
|
86
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub process_file { |
|
89
|
|
|
|
|
|
|
my $self = shift; |
|
90
|
|
|
|
|
|
|
my $file = @_ ? shift : $self->{ FILENAME }; |
|
91
|
|
|
|
|
|
|
my ($parser, $doc); |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
return $self->error('no filename specified') |
|
94
|
|
|
|
|
|
|
unless defined $file; |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# parse XML file, trapping any errors thrown via die() |
|
97
|
|
|
|
|
|
|
$parser = Kite::XML::Parser->new(); |
|
98
|
|
|
|
|
|
|
eval { |
|
99
|
|
|
|
|
|
|
$doc = $parser->parsefile($file); |
|
100
|
|
|
|
|
|
|
}; |
|
101
|
|
|
|
|
|
|
return $self->error($@) |
|
102
|
|
|
|
|
|
|
if $@; |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
my $path = 'newpath '; |
|
105
|
|
|
|
|
|
|
my $image = ''; |
|
106
|
|
|
|
|
|
|
my ($x, $y, $xt, $yt, $angle, $anglet); |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
$self->{ KITE } = $doc; |
|
109
|
|
|
|
|
|
|
$self->{ TITLE } ||= $doc->title(); |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# generate PS for each kite part |
|
112
|
|
|
|
|
|
|
foreach my $part (@{ $doc->part() }) |
|
113
|
|
|
|
|
|
|
{ |
|
114
|
|
|
|
|
|
|
$xt = $part->layout->x() || 0; |
|
115
|
|
|
|
|
|
|
$yt = $part->layout->y() || 0; |
|
116
|
|
|
|
|
|
|
$anglet = $part->layout->angle || 0; |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
$image .= "gsave $xt mm $yt mm translate $anglet rotate "; |
|
119
|
|
|
|
|
|
|
$path .= "$xt mm $yt mm translate $anglet rotate "; |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# add path segments as a series of PS moveto/lineto ops |
|
122
|
|
|
|
|
|
|
foreach my $curve (@{ $part->markup->curve }) |
|
123
|
|
|
|
|
|
|
{ |
|
124
|
|
|
|
|
|
|
$image .= "gsave "; |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
my $linetype = $curve->linetype || "normal"; |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
if ($linetype eq 'normal') { |
|
129
|
|
|
|
|
|
|
$image .= "0.5 setlinewidth "; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
elsif ($linetype eq 'heavy') { |
|
132
|
|
|
|
|
|
|
$image .= "0.75 setlinewidth "; |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
elsif ($linetype eq "light") { |
|
135
|
|
|
|
|
|
|
$image .= "0.25 setlinewidth "; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
elsif ($linetype eq "dotted") { |
|
138
|
|
|
|
|
|
|
$image .= "0.55 setlinewidth [3 5 1 5] 0 setdash "; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
my $incurve = undef; |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
foreach my $point (@{ $curve->point }) |
|
144
|
|
|
|
|
|
|
{ |
|
145
|
|
|
|
|
|
|
$x = $point->x; |
|
146
|
|
|
|
|
|
|
$y = $point->y; |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
if (defined $incurve) |
|
149
|
|
|
|
|
|
|
{ |
|
150
|
|
|
|
|
|
|
$image .= "$x mm $y mm lineto "; |
|
151
|
|
|
|
|
|
|
$path .= "$x mm $y mm lineto "; |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
else |
|
154
|
|
|
|
|
|
|
{ |
|
155
|
|
|
|
|
|
|
$image .= "newpath $x mm $y mm moveto "; |
|
156
|
|
|
|
|
|
|
$path .= "$x mm $y mm moveto "; |
|
157
|
|
|
|
|
|
|
$incurve = 1; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# add text using PS pathtext function |
|
162
|
|
|
|
|
|
|
foreach my $text (@{ $curve->text || [] }) |
|
163
|
|
|
|
|
|
|
{ |
|
164
|
|
|
|
|
|
|
my $font = $text->font || "Helvetica"; |
|
165
|
|
|
|
|
|
|
my $size = $text->size || "6"; |
|
166
|
|
|
|
|
|
|
$text = $text->char; |
|
167
|
|
|
|
|
|
|
for ($text) { # remove leading and trailing whitespace |
|
168
|
|
|
|
|
|
|
s/^\s*//; |
|
169
|
|
|
|
|
|
|
s/\s*$//; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
$image .= "gsave /$font findfont $size mm scalefont setfont "; |
|
172
|
|
|
|
|
|
|
$image .= "($text) 0 pathtext grestore "; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
$image .= "stroke grestore "; |
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# add transformations |
|
178
|
|
|
|
|
|
|
$path .= "$anglet neg rotate $xt neg mm $yt neg mm translate "; |
|
179
|
|
|
|
|
|
|
$image .= "grestore "; |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# save image and path definitions internally and return happy |
|
183
|
|
|
|
|
|
|
$self->{ IMAGE } = $image; |
|
184
|
|
|
|
|
|
|
$self->{ PATH } = $path; |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
return 1; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
191
|
|
|
|
|
|
|
# doc() |
|
192
|
|
|
|
|
|
|
# |
|
193
|
|
|
|
|
|
|
# Generate a complete PostScript document to print the kite parts, |
|
194
|
|
|
|
|
|
|
# with automatic multiple page tiling (page-size independant), |
|
195
|
|
|
|
|
|
|
# registration marks and many other glorious features. Returns the |
|
196
|
|
|
|
|
|
|
# generated PostScript as a string. |
|
197
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub doc { |
|
200
|
|
|
|
|
|
|
my $self = shift; |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
require Kite::PScript::Defs; |
|
203
|
|
|
|
|
|
|
require Template; |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
my $doc = $self->ps_template(); |
|
206
|
|
|
|
|
|
|
my $template = Template->new( POST_CHOMP => 1); |
|
207
|
|
|
|
|
|
|
my $vars = { |
|
208
|
|
|
|
|
|
|
defs => bless { }, 'Kite::PScript::Defs', |
|
209
|
|
|
|
|
|
|
}; |
|
210
|
|
|
|
|
|
|
my @keys = qw( kite title regmarks border map image path ); |
|
211
|
|
|
|
|
|
|
@$vars{ @keys } = @$self{ map { uc } @keys }; |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
my $out = ''; |
|
214
|
|
|
|
|
|
|
$template->process(\$doc, $vars, \$out) |
|
215
|
|
|
|
|
|
|
|| return $self->error($template->error()); |
|
216
|
|
|
|
|
|
|
return $out; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
220
|
|
|
|
|
|
|
# ps_template() |
|
221
|
|
|
|
|
|
|
# |
|
222
|
|
|
|
|
|
|
# Returns a Template Toolkit template for generating the PostScript. |
|
223
|
|
|
|
|
|
|
#------------------------------------------------------------------------ |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub ps_template { |
|
226
|
|
|
|
|
|
|
return <<'EOF'; |
|
227
|
|
|
|
|
|
|
[% USE fix = format('%.2f') -%] |
|
228
|
|
|
|
|
|
|
%!PS-Adobe-3.0 |
|
229
|
|
|
|
|
|
|
[% IF title %] |
|
230
|
|
|
|
|
|
|
%%Title: [% title %] |
|
231
|
|
|
|
|
|
|
[% END %] |
|
232
|
|
|
|
|
|
|
%%EndComments |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
[% defs.mm %] |
|
235
|
|
|
|
|
|
|
[% defs.lines %] |
|
236
|
|
|
|
|
|
|
[% defs.cross %] |
|
237
|
|
|
|
|
|
|
[% defs.dot %] |
|
238
|
|
|
|
|
|
|
[% defs.circle %] |
|
239
|
|
|
|
|
|
|
[% defs.crop %] |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
/border [% border %] mm def |
|
242
|
|
|
|
|
|
|
[% defs.clip +%] |
|
243
|
|
|
|
|
|
|
[% regmarks ? defs.reg : defs.noreg +%] |
|
244
|
|
|
|
|
|
|
[% defs.tiles +%] |
|
245
|
|
|
|
|
|
|
[% defs.tilemap +%] |
|
246
|
|
|
|
|
|
|
[% defs.pathtext %] |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
% define image, path and page procedures for tiling |
|
249
|
|
|
|
|
|
|
/tileimage { |
|
250
|
|
|
|
|
|
|
[% image %] |
|
251
|
|
|
|
|
|
|
} def |
|
252
|
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
/tilepath { |
|
254
|
|
|
|
|
|
|
[% path %] |
|
255
|
|
|
|
|
|
|
} def |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
/tilepage { |
|
258
|
|
|
|
|
|
|
regmarks |
|
259
|
|
|
|
|
|
|
[% IF title %] |
|
260
|
|
|
|
|
|
|
/Times-Roman findfont 24 scalefont setfont |
|
261
|
|
|
|
|
|
|
clipblx 3 mm add clipbly 3 mm add moveto |
|
262
|
|
|
|
|
|
|
([% title %]) show |
|
263
|
|
|
|
|
|
|
[% END %] |
|
264
|
|
|
|
|
|
|
[% " tilemap\n" IF map %] |
|
265
|
|
|
|
|
|
|
} def |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
tilepath tiles |
|
268
|
|
|
|
|
|
|
[% defs.dotiles %] |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
EOF |
|
271
|
|
|
|
|
|
|
} |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
1; |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
__END__ |