line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Games::Go::SGF2misc::SVG |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Author: Orien Vandenbergh |
4
|
|
|
|
|
|
|
# $Id: SVG.pm,v 1.1.1.1 2004/05/10 20:52:19 orien Exp $ |
5
|
|
|
|
|
|
|
# vi: fdm=marker fdl=0 |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
package Games::Go::SGF2misc::SVG; |
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
8990
|
use 5.006; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
53
|
|
10
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
49
|
|
11
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
37
|
|
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
1988
|
use Image::LibRSVG; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use XML::LibXML; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
require Exporter; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
19
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [qw( )] ); |
20
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
21
|
|
|
|
|
|
|
our @EXPORT = qw( ); |
22
|
|
|
|
|
|
|
our $VERSION = '1.00'; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# sub new() {{{ |
25
|
|
|
|
|
|
|
sub new() { |
26
|
|
|
|
|
|
|
my $class = shift; |
27
|
|
|
|
|
|
|
my $self = bless( { @_ }, $class ); |
28
|
|
|
|
|
|
|
$self->init(); |
29
|
|
|
|
|
|
|
return $self; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
# }}} |
32
|
|
|
|
|
|
|
# sub init() {{{ |
33
|
|
|
|
|
|
|
sub init() { |
34
|
|
|
|
|
|
|
my ($self) = @_; |
35
|
|
|
|
|
|
|
$self->{'imagesize'} = '3in' unless $self->{'imagesize'}; |
36
|
|
|
|
|
|
|
$self->{'boardsize'} = 19 unless $self->{'boardsize'}; |
37
|
|
|
|
|
|
|
$self->{'blocksize'} = 50; |
38
|
|
|
|
|
|
|
$self->{'virtualsize'} = $self->{'blocksize'} * $self->{'boardsize'}; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
$self->{'border'} = $self->{'blocksize'} / 2; |
41
|
|
|
|
|
|
|
$self->{'stonesize'} = $self->{'border'} - 2; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
$self->{'gobanColor'} = '#eeb14b' unless $self->{'gobancolor'}; |
44
|
|
|
|
|
|
|
$self->{'whiteColor'} = 'white' unless $self->{'whitecolor'}; |
45
|
|
|
|
|
|
|
$self->{'blackColor'} = 'black' unless $self->{'blackcolor'}; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
if (ref($self->{'gobanColor'}) eq 'ARRAY') { |
48
|
|
|
|
|
|
|
$self->{'gobanColor'} = sprintf('rgb(%d,%d,%d)', @{$self->{'gobanColor'}}); |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
if (ref($self->{'whiteColor'}) eq 'ARRAY') { |
51
|
|
|
|
|
|
|
$self->{'whiteColor'} = sprintf('rgb(%d,%d,%d)', @{$self->{'gobanColor'}}); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
if (ref($self->{'blackColor'}) eq 'ARRAY') { |
54
|
|
|
|
|
|
|
$self->{'blackColor'} = sprintf('rgb(%d,%d,%d)', @{$self->{'gobanColor'}}); |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
$self->{'document'} = XML::LibXML->createDocument(1.0, "UTF-8"); |
58
|
|
|
|
|
|
|
$self->{'svg'} = $self->{'document'}->createElement("svg"); |
59
|
|
|
|
|
|
|
$self->{'svg'}->setAttribute('xmlns','http://www.w3.org/2000/svg'); |
60
|
|
|
|
|
|
|
$self->{'svg'}->setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); |
61
|
|
|
|
|
|
|
$self->{'svg'}->setAttribute('width',$self->{'imagesize'}); |
62
|
|
|
|
|
|
|
$self->{'svg'}->setAttribute('height',$self->{'imagesize'}); |
63
|
|
|
|
|
|
|
$self->{'svg'}->setAttribute('viewBox',sprintf('0 0 %d %d', $self->{'virtualsize'}, $self->{'virtualsize'})); |
64
|
|
|
|
|
|
|
$self->{'svg'}->setAttribute('preserveAspectRatio','xMidYMid meet'); |
65
|
|
|
|
|
|
|
$self->{'document'}->setDocumentElement($self->{'svg'}); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
my $node; |
68
|
|
|
|
|
|
|
my $grad; |
69
|
|
|
|
|
|
|
my $defs = $self->{'svg'}->addNewChild(undef,'defs'); |
70
|
|
|
|
|
|
|
$defs->setAttribute('id','defs00001'); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# Gradients {{{ |
73
|
|
|
|
|
|
|
$grad = $defs->addNewChild(undef,'linearGradient'); |
74
|
|
|
|
|
|
|
$grad->setAttribute('id','BlackLinearGradient'); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$node = $grad->addNewChild(undef,'stop'); |
77
|
|
|
|
|
|
|
$node->setAttribute('offset', '0'); |
78
|
|
|
|
|
|
|
$node->setAttribute('style', 'stop-color:#888888;stop-opacity:1;'); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
$node = $grad->addNewChild(undef,'stop'); |
81
|
|
|
|
|
|
|
$node->setAttribute('offset', '1'); |
82
|
|
|
|
|
|
|
$node->setAttribute('style', 'stop-color:#000000;stop-opacity:1;'); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
$grad = $defs->addNewChild(undef,'linearGradient'); |
85
|
|
|
|
|
|
|
$grad->setAttribute('id','WhiteLinearGradient'); |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
$node = $grad->addNewChild(undef,'stop'); |
88
|
|
|
|
|
|
|
$node->setAttribute('offset', '0'); |
89
|
|
|
|
|
|
|
$node->setAttribute('style', 'stop-color:#ffffff;stop-opacity:1;'); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
$node = $grad->addNewChild(undef,'stop'); |
92
|
|
|
|
|
|
|
$node->setAttribute('offset', '1'); |
93
|
|
|
|
|
|
|
$node->setAttribute('style', 'stop-color:#dddddd;stop-opacity:1;'); |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'radialGradient'); |
96
|
|
|
|
|
|
|
$node->setAttribute('id', 'BlackRadialGradient'); |
97
|
|
|
|
|
|
|
$node->setAttribute('cx', '0.36437908'); |
98
|
|
|
|
|
|
|
$node->setAttribute('cy', '0.335985'); |
99
|
|
|
|
|
|
|
$node->setAttribute('fx', '0.36437908'); |
100
|
|
|
|
|
|
|
$node->setAttribute('fy', '0.335985'); |
101
|
|
|
|
|
|
|
$node->setAttribute('r', '0.55236467'); |
102
|
|
|
|
|
|
|
$node->setAttribute('xlink:href','#BlackLinearGradient'); |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'radialGradient'); |
105
|
|
|
|
|
|
|
$node->setAttribute('id', 'WhiteRadialGradient'); |
106
|
|
|
|
|
|
|
$node->setAttribute('cx', '0.36437908'); |
107
|
|
|
|
|
|
|
$node->setAttribute('cy', '0.335985'); |
108
|
|
|
|
|
|
|
$node->setAttribute('fx', '0.36437908'); |
109
|
|
|
|
|
|
|
$node->setAttribute('fy', '0.335985'); |
110
|
|
|
|
|
|
|
$node->setAttribute('r', '0.59236467'); |
111
|
|
|
|
|
|
|
$node->setAttribute('xlink:href','#WhiteLinearGradient'); |
112
|
|
|
|
|
|
|
# }}} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'circle'); |
115
|
|
|
|
|
|
|
$node->setAttribute('id','Stone'); |
116
|
|
|
|
|
|
|
$node->setAttribute('r',$self->{'stonesize'}); |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'circle'); |
119
|
|
|
|
|
|
|
$node->setAttribute('id', 'Hoshi'); |
120
|
|
|
|
|
|
|
$node->setAttribute('r',$self->{'blocksize'}/10); |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'circle'); |
123
|
|
|
|
|
|
|
$node->setAttribute('id', 'MarkerCircle'); |
124
|
|
|
|
|
|
|
$node->setAttribute('r',$self->{'stonesize'}/2); |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'rect'); |
127
|
|
|
|
|
|
|
$node->setAttribute('id', 'MarkerRectangle'); |
128
|
|
|
|
|
|
|
$node->setAttribute('x',0); |
129
|
|
|
|
|
|
|
$node->setAttribute('y',0); |
130
|
|
|
|
|
|
|
$node->setAttribute('width', $self->{'blocksize'}/2.5); |
131
|
|
|
|
|
|
|
$node->setAttribute('height',$self->{'blocksize'}/2.5); |
132
|
|
|
|
|
|
|
$node->setAttribute('transform',sprintf('translate(-%d,-%d)',$self->{'blocksize'}/5,$self->{'blocksize'}/5)); |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
my $pi = 3.1415927; |
135
|
|
|
|
|
|
|
my $b = ($self->{'blocksize'}/2) * sin($pi/3); |
136
|
|
|
|
|
|
|
my $c = ($self->{'blocksize'}/2) * cos($pi/3); |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
$node = $defs->addNewChild(undef,'polygon'); |
139
|
|
|
|
|
|
|
$node->setAttribute('id', 'MarkerTriangle'); |
140
|
|
|
|
|
|
|
$node->setAttribute('points',sprintf('0,-%f, -%f,%f %f,%f', 2*($b/3), $c,($b/3), $c,($b/3))); |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
# }}} |
143
|
|
|
|
|
|
|
# sub drawGoban() {{{ |
144
|
|
|
|
|
|
|
sub drawGoban() { |
145
|
|
|
|
|
|
|
my ($self) = shift; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
my $node; |
148
|
|
|
|
|
|
|
my $goban = $self->{'svg'}->addNewChild(undef,'g'); |
149
|
|
|
|
|
|
|
$goban->setAttribute('id','Goban'); |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
$node = $goban->addNewChild(undef,'rect'); |
152
|
|
|
|
|
|
|
$node->setAttribute('id','board'); |
153
|
|
|
|
|
|
|
$node->setAttribute('x','0'); |
154
|
|
|
|
|
|
|
$node->setAttribute('y','0'); |
155
|
|
|
|
|
|
|
$node->setAttribute('width',$self->{'virtualsize'}); |
156
|
|
|
|
|
|
|
$node->setAttribute('height',$self->{'virtualsize'}); |
157
|
|
|
|
|
|
|
$node->setAttribute('style',sprintf('fill:%s;',$self->{'gobanColor'})); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
$node = $goban->addNewChild(undef,'rect'); |
160
|
|
|
|
|
|
|
$node->setAttribute('id', 'border'); |
161
|
|
|
|
|
|
|
$node->setAttribute('x', $self->{'border'}); |
162
|
|
|
|
|
|
|
$node->setAttribute('y', $self->{'border'}); |
163
|
|
|
|
|
|
|
$node->setAttribute('width', $self->{'virtualsize'} - $self->{'blocksize'}); |
164
|
|
|
|
|
|
|
$node->setAttribute('height', $self->{'virtualsize'} - $self->{'blocksize'}); |
165
|
|
|
|
|
|
|
$node->setAttribute('style', 'stroke:black;stroke-width:3;fill-opacity:0;'); |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
foreach my $x (($self->{'border'} + $self->{'blocksize'})..$self->{'virtualsize'}-$self->{'blocksize'}) { |
168
|
|
|
|
|
|
|
next if (($x-$self->{'border'}) % $self->{'blocksize'}); |
169
|
|
|
|
|
|
|
$node = $goban->addNewChild(undef,'line'); |
170
|
|
|
|
|
|
|
#$node->setAttribute('id', 'border'); |
171
|
|
|
|
|
|
|
$node->setAttribute('x1', $x); |
172
|
|
|
|
|
|
|
$node->setAttribute('y1', $self->{'border'}); |
173
|
|
|
|
|
|
|
$node->setAttribute('x2', $x); |
174
|
|
|
|
|
|
|
$node->setAttribute('y2', $self->{'virtualsize'} - $self->{'border'}); |
175
|
|
|
|
|
|
|
$node->setAttribute('style', 'stroke:black;stroke-width:1;'); |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
$node = $goban->addNewChild(undef,'line'); |
178
|
|
|
|
|
|
|
#$node->setAttribute('id', 'border'); |
179
|
|
|
|
|
|
|
$node->setAttribute('x1', $self->{'border'}); |
180
|
|
|
|
|
|
|
$node->setAttribute('y1', $x); |
181
|
|
|
|
|
|
|
$node->setAttribute('x2', $self->{'virtualsize'} - $self->{'border'}); |
182
|
|
|
|
|
|
|
$node->setAttribute('y2', $x); |
183
|
|
|
|
|
|
|
$node->setAttribute('style', 'stroke:black;stroke-width:1;'); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
my %hoshi = ( 5 => [[2,2] ], |
186
|
|
|
|
|
|
|
7 => [[3,3] ], |
187
|
|
|
|
|
|
|
9 => [[2,2], [6,2], |
188
|
|
|
|
|
|
|
[4,4], |
189
|
|
|
|
|
|
|
[2,6], [6,6] ], |
190
|
|
|
|
|
|
|
11 => [[3,3], [7,3], |
191
|
|
|
|
|
|
|
[5,5], |
192
|
|
|
|
|
|
|
[3,7], [7,7] ], |
193
|
|
|
|
|
|
|
13 => [[2,2], [6,2], [10,2], |
194
|
|
|
|
|
|
|
[2,6], [6,6], [10,6], |
195
|
|
|
|
|
|
|
[2,10], [6,10], [10,10] ], |
196
|
|
|
|
|
|
|
19 => [[3,3], [9,3], [15,3], |
197
|
|
|
|
|
|
|
[3,9], [9,9], [15,9], |
198
|
|
|
|
|
|
|
[3,15], [9,15], [15,15] ], |
199
|
|
|
|
|
|
|
); |
200
|
|
|
|
|
|
|
foreach my $point (@{ $hoshi{$self->{'boardsize'}} }) { |
201
|
|
|
|
|
|
|
my $x = $self->{'border'}+($self->{'blocksize'}*$point->[0]); |
202
|
|
|
|
|
|
|
my $y = $self->{'border'}+($self->{'blocksize'}*$point->[1]); |
203
|
|
|
|
|
|
|
$node = $goban->addNewChild(undef,'use'); |
204
|
|
|
|
|
|
|
#$node->setAttribute('id', 'border'); |
205
|
|
|
|
|
|
|
$node->setAttribute('x', $x); |
206
|
|
|
|
|
|
|
$node->setAttribute('y', $y); |
207
|
|
|
|
|
|
|
$node->setAttribute('xlink:href', '#Hoshi'); |
208
|
|
|
|
|
|
|
$node->setAttribute('style', 'fill:black;'); |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
# }}} |
212
|
|
|
|
|
|
|
# sub calcXY {{{ |
213
|
|
|
|
|
|
|
sub calcXY { |
214
|
|
|
|
|
|
|
my $self = shift; |
215
|
|
|
|
|
|
|
my ($pos) = @_; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
my ($x,$y); |
218
|
|
|
|
|
|
|
if (ref($pos) eq 'ARRAY') { |
219
|
|
|
|
|
|
|
($x,$y) = @{ $pos }; |
220
|
|
|
|
|
|
|
} else { |
221
|
|
|
|
|
|
|
$pos = lc($pos); |
222
|
|
|
|
|
|
|
$pos =~ /([a-z])([a-z])/; |
223
|
|
|
|
|
|
|
($x,$y) = ((ord($1)-ord('a')),(ord($2)-ord('a'))); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
return ($self->{'border'}+($self->{'blocksize'}*$x),$self->{'border'}+($self->{'blocksize'}*$y)); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
# }}} |
229
|
|
|
|
|
|
|
# sub calcAA {{{ |
230
|
|
|
|
|
|
|
sub calcAA { |
231
|
|
|
|
|
|
|
my $self = shift; |
232
|
|
|
|
|
|
|
my ($pos) = @_; |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
my ($x,$y); |
235
|
|
|
|
|
|
|
if (ref($pos) eq 'ARRAY') { |
236
|
|
|
|
|
|
|
($x,$y) = @{ $pos }; |
237
|
|
|
|
|
|
|
$x = chr(ord('a')+$x); |
238
|
|
|
|
|
|
|
$y = chr(ord('a')+$y); |
239
|
|
|
|
|
|
|
return ($x.$y); |
240
|
|
|
|
|
|
|
} else { |
241
|
|
|
|
|
|
|
return lc($pos); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
# }}} |
245
|
|
|
|
|
|
|
# sub fetchGroup {{{ |
246
|
|
|
|
|
|
|
sub fetchGroup() { |
247
|
|
|
|
|
|
|
my $self = shift; |
248
|
|
|
|
|
|
|
my ($move) = @_; |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
my $id = sprintf('pos_%s', $move); |
251
|
|
|
|
|
|
|
my $node = $self->{'document'}->getElementsById($id); |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
if (not defined $node) { |
254
|
|
|
|
|
|
|
$node = $self->{'positions'}{$move}; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
if (not defined $node) { |
257
|
|
|
|
|
|
|
$node = $self->{'svg'}->addNewChild(undef,'g'); |
258
|
|
|
|
|
|
|
$node->setAttribute('id',sprintf('pos_%s',$move)); |
259
|
|
|
|
|
|
|
$node->setAttribute('transform',sprintf('translate(%d,%d)',$self->calcXY($move))); |
260
|
|
|
|
|
|
|
$self->{'positions'}{$move} = $node; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
return $node; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
#}}} |
266
|
|
|
|
|
|
|
# sub setLastMove {{{ |
267
|
|
|
|
|
|
|
sub setLastMove() { |
268
|
|
|
|
|
|
|
my $self = shift; |
269
|
|
|
|
|
|
|
my ($group) = @_; |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
my $node = $self->{'document'}->getElementsById("LastMoveMarker"); |
272
|
|
|
|
|
|
|
if ($node) { |
273
|
|
|
|
|
|
|
my $parent = $node->parentNode(); |
274
|
|
|
|
|
|
|
$parent->removeChild($node); |
275
|
|
|
|
|
|
|
} else { |
276
|
|
|
|
|
|
|
$node = $self->{'document'}->createElement('use'); |
277
|
|
|
|
|
|
|
$node->setAttribute('class','marker') |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
$group->addChild($node); |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
return $node; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
#}}} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
# sub placeStone {{{ |
286
|
|
|
|
|
|
|
sub placeStone { |
287
|
|
|
|
|
|
|
my $self = shift; |
288
|
|
|
|
|
|
|
my ($player, $move) = @_; |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
my ($x,$y) = $self->calcXY($move); |
291
|
|
|
|
|
|
|
my $loc = $self->calcAA($move); |
292
|
|
|
|
|
|
|
my $group = $self->fetchGroup($loc); |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
$group->setAttribute('transform',sprintf('translate(%d,%d)',$self->calcXY($move))); |
295
|
|
|
|
|
|
|
my $node = $group->addNewChild(undef,'use'); |
296
|
|
|
|
|
|
|
$node->setAttribute('xlink:href','#Stone'); |
297
|
|
|
|
|
|
|
$node->setAttribute('class','stone'); |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
if ( $player =~ /b/i ) { |
300
|
|
|
|
|
|
|
$group->setAttribute('class','black'); |
301
|
|
|
|
|
|
|
if ($self->{'useGradients'}) { |
302
|
|
|
|
|
|
|
$node->setAttribute('style','fill:url(#BlackRadialGradient);stroke:black;stroke-width:1;'); |
303
|
|
|
|
|
|
|
} else { |
304
|
|
|
|
|
|
|
$node->setAttribute('style','fill:black;stroke:black;stroke-width:1;'); |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
} else { |
307
|
|
|
|
|
|
|
$group->setAttribute('class','white'); |
308
|
|
|
|
|
|
|
if ($self->{'useGradients'}) { |
309
|
|
|
|
|
|
|
$node->setAttribute('style','fill:url(#WhiteRadialGradient);stroke:black;stroke-width:1;'); |
310
|
|
|
|
|
|
|
} else { |
311
|
|
|
|
|
|
|
$node->setAttribute('style','fill:white;stroke:black;stroke-width:1;'); |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
# }}} |
316
|
|
|
|
|
|
|
# sub addCircle {{{ |
317
|
|
|
|
|
|
|
sub addCircle { |
318
|
|
|
|
|
|
|
my $self = shift; |
319
|
|
|
|
|
|
|
my ($move) = @_; |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
my $loc = $self->calcAA($move); |
322
|
|
|
|
|
|
|
my $group = $self->fetchGroup($loc); |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
my $node = $group->addNewChild(undef,'use'); |
325
|
|
|
|
|
|
|
$node->setAttribute('xlink:href','#MarkerCircle'); |
326
|
|
|
|
|
|
|
$node->setAttribute('class', 'marker'); |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
my @attr = $group->attributes(); |
329
|
|
|
|
|
|
|
my $color = 'white'; |
330
|
|
|
|
|
|
|
foreach my $attr(@attr) { |
331
|
|
|
|
|
|
|
if (($attr->name() eq 'class') and ($attr->getValue() =~ /black/i)) { |
332
|
|
|
|
|
|
|
$color = 'black'; |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
if ($color eq 'black') { |
336
|
|
|
|
|
|
|
$node->setAttribute('style','stroke:white;stroke-width:2;fill-opacity:0;'); |
337
|
|
|
|
|
|
|
} else { |
338
|
|
|
|
|
|
|
$node->setAttribute('style','stroke:black;stroke-width:1;fill-opacity:0;'); |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
# }}} |
342
|
|
|
|
|
|
|
# sub addLetter {{{ |
343
|
|
|
|
|
|
|
sub addLetter { |
344
|
|
|
|
|
|
|
my $self = shift; |
345
|
|
|
|
|
|
|
my ($move,$text) = @_; |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
my $loc = $self->calcAA($move); |
348
|
|
|
|
|
|
|
my $group = $self->fetchGroup($loc); |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
my $node = $group->addNewChild(undef,'text'); |
351
|
|
|
|
|
|
|
#$node->setAttribute('x','0'); |
352
|
|
|
|
|
|
|
$node->setAttribute('class', 'marker'); |
353
|
|
|
|
|
|
|
$node->setAttribute('text-anchor','middle'); |
354
|
|
|
|
|
|
|
$node->setAttribute('alignment-baseline','middle'); |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
$text =~ /\s*(\w{1,3})/; |
357
|
|
|
|
|
|
|
my $letter = $1; |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
$node->setAttribute('font-size', $self->{'blocksize'} * 0.5); |
360
|
|
|
|
|
|
|
$node->setAttribute('y',$self->{'stonesize'}*0.46); |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
$node->appendText($letter); |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
my @attr = $group->attributes(); |
365
|
|
|
|
|
|
|
my $color = 'white'; |
366
|
|
|
|
|
|
|
foreach my $attr(@attr) { |
367
|
|
|
|
|
|
|
if (($attr->name() eq 'class') and ($attr->getValue() =~ /black/i)) { |
368
|
|
|
|
|
|
|
$color = 'black'; |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
if ($color eq 'black') { |
372
|
|
|
|
|
|
|
$node->setAttribute('fill', 'white'); |
373
|
|
|
|
|
|
|
#$node->setAttribute('style','stroke:white;stroke-width:2;fill-opacity:0;'); |
374
|
|
|
|
|
|
|
} else { |
375
|
|
|
|
|
|
|
$node->setAttribute('fill', 'black'); |
376
|
|
|
|
|
|
|
#$node->setAttribute('style','stroke:black;stroke-width:1;fill-opacity:0;'); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
# }}} |
380
|
|
|
|
|
|
|
# sub addSquare {{{ |
381
|
|
|
|
|
|
|
sub addSquare { |
382
|
|
|
|
|
|
|
my $self = shift; |
383
|
|
|
|
|
|
|
my ($move) = @_; |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
my $loc = $self->calcAA($move); |
386
|
|
|
|
|
|
|
my $group = $self->fetchGroup($loc); |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
my $node = $group->addNewChild(undef,'use'); |
389
|
|
|
|
|
|
|
$node->setAttribute('xlink:href','#MarkerRectangle'); |
390
|
|
|
|
|
|
|
$node->setAttribute('class', 'marker'); |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
my @attr = $group->attributes(); |
393
|
|
|
|
|
|
|
my $color = 'white'; |
394
|
|
|
|
|
|
|
foreach my $attr(@attr) { |
395
|
|
|
|
|
|
|
if (($attr->name() eq 'class') and ($attr->getValue() =~ /black/i)) { |
396
|
|
|
|
|
|
|
$color = 'black'; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
if ($color eq 'black') { |
400
|
|
|
|
|
|
|
$node->setAttribute('style','stroke:white;stroke-width:2;fill-opacity:0;'); |
401
|
|
|
|
|
|
|
} else { |
402
|
|
|
|
|
|
|
$node->setAttribute('style','stroke:black;stroke-width:1;fill-opacity:0;'); |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
# }}} |
406
|
|
|
|
|
|
|
# sub addTriangle {{{ |
407
|
|
|
|
|
|
|
sub addTriangle { |
408
|
|
|
|
|
|
|
my $self = shift; |
409
|
|
|
|
|
|
|
my ($move) = @_; |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
my $loc = $self->calcAA($move); |
412
|
|
|
|
|
|
|
my $group = $self->fetchGroup($loc); |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
my $node = $group->addNewChild(undef,'use'); |
415
|
|
|
|
|
|
|
$node->setAttribute('xlink:href','#MarkerTriangle'); |
416
|
|
|
|
|
|
|
$node->setAttribute('class', 'marker'); |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
my @attr = $group->attributes(); |
419
|
|
|
|
|
|
|
my $color = 'white'; |
420
|
|
|
|
|
|
|
foreach my $attr(@attr) { |
421
|
|
|
|
|
|
|
if (($attr->name() eq 'class') and ($attr->getValue() =~ /black/i)) { |
422
|
|
|
|
|
|
|
$color = 'black'; |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
if ($color eq 'black') { |
426
|
|
|
|
|
|
|
$node->setAttribute('style','stroke:white;stroke-width:2;fill-opacity:0;'); |
427
|
|
|
|
|
|
|
} else { |
428
|
|
|
|
|
|
|
$node->setAttribute('style','stroke:black;stroke-width:1;fill-opacity:0;'); |
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
# }}} |
432
|
|
|
|
|
|
|
# sub save {{{ |
433
|
|
|
|
|
|
|
sub save { |
434
|
|
|
|
|
|
|
my $self = shift; |
435
|
|
|
|
|
|
|
my ($filename) = @_; |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
open IMG, ">$filename" or die "Unable to open $filename: $!, stopped "; |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
print IMG $self->{'document'}->toString($self->{'pretty'}); |
440
|
|
|
|
|
|
|
close IMG; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
# }}} |
443
|
|
|
|
|
|
|
# sub export {{{ |
444
|
|
|
|
|
|
|
sub export { |
445
|
|
|
|
|
|
|
my $self = shift; |
446
|
|
|
|
|
|
|
my ($filename) = @_; |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
my $rsvg = new Image::LibRSVG(); |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
$rsvg->loadImageFromString( $self->{'document'}->toString() ); |
451
|
|
|
|
|
|
|
$rsvg->saveAs($filename); |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
# }}} |
454
|
|
|
|
|
|
|
# sub dump {{{ |
455
|
|
|
|
|
|
|
sub dump { |
456
|
|
|
|
|
|
|
my $self = shift; |
457
|
|
|
|
|
|
|
my ($format) = @_; |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
$format = 'svg' unless $format; |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
if ( $format =~ /png/i ) { |
462
|
|
|
|
|
|
|
return undef; |
463
|
|
|
|
|
|
|
# Image::LibRSVG doesn't support this yet. |
464
|
|
|
|
|
|
|
my $rsvg = new Image::LibRSVG; |
465
|
|
|
|
|
|
|
$rsvg->loadImageFromString( $self->{'document'}->toString() ); |
466
|
|
|
|
|
|
|
return $rsvg->getImageBitmap(); |
467
|
|
|
|
|
|
|
} else { |
468
|
|
|
|
|
|
|
return $self->{'document'}->toString($self->{'pretty'}); |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
} |
471
|
|
|
|
|
|
|
# }}} |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
__END__ |