| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#! perl |
|
2
|
|
|
|
|
|
|
|
|
3
|
8
|
|
|
8
|
|
156
|
use v5.26; |
|
|
8
|
|
|
|
|
36
|
|
|
4
|
8
|
|
|
8
|
|
64
|
use Object::Pad; |
|
|
8
|
|
|
|
|
22
|
|
|
|
8
|
|
|
|
|
163
|
|
|
5
|
8
|
|
|
8
|
|
1704
|
use utf8; |
|
|
8
|
|
|
|
|
23
|
|
|
|
8
|
|
|
|
|
141
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
my $dcache; # cache core grids |
|
8
|
|
|
|
|
|
|
my $pdf = ""; # for cache flush |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
class ChordPro::Output::PDF::StringDiagram; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
field $pr :param; |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
field $config; |
|
15
|
|
|
|
|
|
|
field $ps; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
field $gw; # width of a cell, pt |
|
18
|
|
|
|
|
|
|
field $gh; # height of a cell, pt |
|
19
|
|
|
|
|
|
|
field $lw; # fraction of cell width |
|
20
|
|
|
|
|
|
|
field $nutwidth; # width (in linewidth) of the top nut |
|
21
|
|
|
|
|
|
|
field $nw; # extra width for the top nut, pt |
|
22
|
|
|
|
|
|
|
field $vc; # cells, vertical |
|
23
|
|
|
|
|
|
|
field $strings; # number of strings |
|
24
|
|
|
|
|
|
|
field $hc; # cells, horizontal (= strings) |
|
25
|
|
|
|
|
|
|
field $dot; # dot size, fraction of cell width |
|
26
|
|
|
|
|
|
|
field $bsz; # barre size, fraction of dot |
|
27
|
|
|
|
|
|
|
field $bstyle; # barre style ("line", "arc") |
|
28
|
|
|
|
|
|
|
field $fsh; # show fingers (0, 1, "below") |
|
29
|
|
|
|
|
|
|
field $fg; # foreground color |
|
30
|
|
|
|
|
|
|
field $bg; # background color |
|
31
|
|
|
|
|
|
|
field $fbp; # fret base position ("left", "right") |
|
32
|
|
|
|
|
|
|
field $fbt; # fret base text ("%s" is default) |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
ADJUST { |
|
35
|
|
|
|
|
|
|
$config = $::config; |
|
36
|
|
|
|
|
|
|
$ps = $pr->{ps}; |
|
37
|
|
|
|
|
|
|
$strings = $config->diagram_strings; |
|
38
|
|
|
|
|
|
|
my $ctl = $ps->{diagrams}; |
|
39
|
|
|
|
|
|
|
$gw = $ctl->{width} || 6; |
|
40
|
|
|
|
|
|
|
$gh = $ctl->{height} || 6; |
|
41
|
|
|
|
|
|
|
$lw = ($ctl->{linewidth} || 0.10) * $gw; |
|
42
|
|
|
|
|
|
|
$nutwidth = $ctl->{nutwidth} || 1; |
|
43
|
|
|
|
|
|
|
$nw = ($nutwidth-1) * $lw; |
|
44
|
|
|
|
|
|
|
$vc = $ctl->{vcells} || 4; |
|
45
|
|
|
|
|
|
|
$hc = $strings; |
|
46
|
|
|
|
|
|
|
$dot = $ctl->{dotsize} * ( $gh < $gw ? $gh : $gw ); |
|
47
|
|
|
|
|
|
|
$bsz = $ctl->{barwidth} * $dot; |
|
48
|
|
|
|
|
|
|
$bstyle = $ctl->{barstyle} || "line"; |
|
49
|
|
|
|
|
|
|
$fsh = $ctl->{fingers} || 0; |
|
50
|
|
|
|
|
|
|
$fbp = $ctl->{fretbaseposition} || "left"; |
|
51
|
|
|
|
|
|
|
$fbt = $ctl->{fretbasetext} || "%s"; |
|
52
|
|
|
|
|
|
|
$dcache = {} if $pr->{pdf} ne $pdf; |
|
53
|
|
|
|
|
|
|
$pdf = $pr->{pdf}; |
|
54
|
|
|
|
|
|
|
} |
|
55
|
|
|
|
|
|
|
|
|
56
|
8
|
|
|
8
|
|
10541
|
use constant DIAG_DEBUG => 0; |
|
|
8
|
|
|
|
|
21
|
|
|
|
8
|
|
|
|
|
66880
|
|
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# The vertical space the diagram requires. |
|
59
|
24
|
|
|
24
|
0
|
51
|
method vsp0( $elt, $dummy = 0 ) { |
|
|
24
|
|
|
|
|
72
|
|
|
|
24
|
|
|
|
|
51
|
|
|
|
24
|
|
|
|
|
52
|
|
|
|
24
|
|
|
|
|
45
|
|
|
60
|
|
|
|
|
|
|
$ps->{fonts}->{diagram}->{size} * $ps->{spacing}->{diagramchords} |
|
61
|
|
|
|
|
|
|
+ $nutwidth * $lw + 0.40 * $gw |
|
62
|
|
|
|
|
|
|
+ $vc * $gh |
|
63
|
24
|
50
|
|
|
|
445
|
+ ( $fsh eq "below" ? $ps->{fonts}->{diagram}->{size} : 0 ) |
|
64
|
|
|
|
|
|
|
; |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# The advance height. |
|
68
|
48
|
|
|
48
|
0
|
93
|
method vsp1( $elt, $dummy = 0 ) { |
|
|
48
|
|
|
|
|
125
|
|
|
|
48
|
|
|
|
|
124
|
|
|
|
48
|
|
|
|
|
89
|
|
|
|
48
|
|
|
|
|
80
|
|
|
69
|
48
|
|
|
|
|
266
|
$ps->{diagrams}->{vspace} * $gh; |
|
70
|
|
|
|
|
|
|
} |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# The vertical space the diagram requires, including advance height. |
|
73
|
24
|
|
|
24
|
0
|
55
|
method vsp( $elt, $dummy = 0 ) { |
|
|
24
|
|
|
|
|
64
|
|
|
|
24
|
|
|
|
|
317
|
|
|
|
24
|
|
|
|
|
60
|
|
|
|
24
|
|
|
|
|
45
|
|
|
74
|
24
|
|
|
|
|
95
|
$self->vsp0($elt) + $self->vsp1($elt); |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# The horizontal space the diagram requires. |
|
78
|
24
|
|
|
24
|
0
|
67
|
method hsp0( $elt, $dummy = 0 ) { |
|
|
24
|
|
|
|
|
126
|
|
|
|
24
|
|
|
|
|
59
|
|
|
|
24
|
|
|
|
|
54
|
|
|
|
24
|
|
|
|
|
78
|
|
|
79
|
24
|
|
|
|
|
110
|
($strings - 1) * $gw; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# The advance width. |
|
83
|
24
|
|
|
24
|
0
|
45
|
method hsp1( $elt, $dummy = 0 ) { |
|
|
24
|
|
|
|
|
71
|
|
|
|
24
|
|
|
|
|
67
|
|
|
|
24
|
|
|
|
|
55
|
|
|
|
24
|
|
|
|
|
83
|
|
|
84
|
24
|
|
|
|
|
127
|
$ps->{diagrams}->{hspace} * $gw; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# The horizontal space the diagram requires, including advance width. |
|
88
|
0
|
|
|
0
|
0
|
0
|
method hsp( $elt, $dummy = 0 ) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
89
|
0
|
|
|
|
|
0
|
$self->hsp0($elt) + $self->hsp1($elt); |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# The actual draw method. |
|
93
|
48
|
|
|
48
|
0
|
119
|
method draw( $info, $x, $y, $dummy=0 ) { |
|
|
48
|
|
|
|
|
269
|
|
|
|
48
|
|
|
|
|
7989
|
|
|
|
48
|
|
|
|
|
101
|
|
|
|
48
|
|
|
|
|
105
|
|
|
|
48
|
|
|
|
|
108
|
|
|
|
48
|
|
|
|
|
84
|
|
|
94
|
48
|
50
|
|
|
|
169
|
return unless $info; |
|
95
|
|
|
|
|
|
|
|
|
96
|
48
|
|
|
|
|
206
|
my $font = $ps->{fonts}->{diagram}; |
|
97
|
|
|
|
|
|
|
|
|
98
|
48
|
|
|
|
|
191
|
my $xo = $self->diagram_xo($info); |
|
99
|
48
|
|
|
|
|
430
|
my @bb = $xo->bbox; |
|
100
|
48
|
|
|
|
|
2343
|
warn("BB [ @bb ] $x $y\n") if DIAG_DEBUG; |
|
101
|
|
|
|
|
|
|
$pr->{pdfgfx}->object( $xo, $x, |
|
102
|
|
|
|
|
|
|
|
|
103
|
48
|
|
|
|
|
764
|
$y - ($font->{size} * $ps->{spacing}->{diagramchords} + $dot + $lw) ); |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Draw name. |
|
106
|
48
|
|
|
|
|
25607
|
my $w = $gw * ($strings - 1); |
|
107
|
48
|
|
|
|
|
562
|
$pr->setfont($font); |
|
108
|
48
|
|
|
|
|
12432
|
my $name = $info->chord_display; |
|
109
|
|
|
|
|
|
|
$name = "$name" |
|
110
|
48
|
50
|
|
|
|
229
|
if $info->{diagram}; |
|
111
|
48
|
|
|
|
|
520
|
$pr->text( $name, $x + ($w - $pr->strwidth($name))/2, |
|
112
|
|
|
|
|
|
|
$y-$pr->font_bl($font));#+$font->{fd}->{ascender}/1000 ); |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# Returns the complete diagram as an xo. This includes the core grid, |
|
116
|
|
|
|
|
|
|
# finger/fret positions, open and muted string indicators. |
|
117
|
|
|
|
|
|
|
# The bounding box includes space form the open and muted string indicators |
|
118
|
|
|
|
|
|
|
# and dots on the first and last strings, even when absent. |
|
119
|
|
|
|
|
|
|
# The bbox includes basefret and fingers (below) if present. |
|
120
|
|
|
|
|
|
|
# Origin is top left of the grid. |
|
121
|
|
|
|
|
|
|
# Note that the chord name is not part of the diagram. |
|
122
|
|
|
|
|
|
|
|
|
123
|
48
|
|
|
48
|
0
|
102
|
method diagram_xo( $info ) { |
|
|
48
|
|
|
|
|
232
|
|
|
|
48
|
|
|
|
|
102
|
|
|
|
48
|
|
|
|
|
90
|
|
|
124
|
48
|
50
|
|
|
|
168
|
return unless $info; |
|
125
|
48
|
|
33
|
|
|
568
|
$fg = $info->{diagram} // $config->{pdf}->{theme}->{foreground}; |
|
126
|
48
|
|
|
|
|
160
|
$bg = $config->{pdf}->{theme}->{background}; |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# Set default options for safety if they have not already been set |
|
129
|
48
|
50
|
|
|
|
167
|
$fg = "black" if $fg eq "none"; |
|
130
|
48
|
50
|
|
|
|
195
|
$bg = "white" if $bg eq "none"; |
|
131
|
|
|
|
|
|
|
|
|
132
|
48
|
|
|
|
|
115
|
my $x = 0; |
|
133
|
48
|
|
|
|
|
199
|
my $w = $gw * ($strings - 1); |
|
134
|
48
|
|
50
|
|
|
296
|
my $baselabeloffset = $info->{baselabeloffset} || 0; |
|
135
|
48
|
|
|
|
|
153
|
my $basefretno = $info->{base} + $baselabeloffset; |
|
136
|
48
|
|
|
|
|
142
|
my $basefrettext=""; # for base label |
|
137
|
48
|
|
|
|
|
122
|
my $basefont; # for base label |
|
138
|
|
|
|
|
|
|
my $basesize; # for base label |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Get the core grid. |
|
141
|
48
|
|
|
|
|
308
|
my $xg = $self->grid_xo; |
|
142
|
48
|
|
|
|
|
385
|
my @xgbb = $xg->bbox; |
|
143
|
|
|
|
|
|
|
|
|
144
|
48
|
|
|
|
|
2245
|
my $xo = $pdf->xo_form; |
|
145
|
48
|
|
|
|
|
24072
|
my @bb = ( 0, |
|
146
|
|
|
|
|
|
|
0.77 * $dot + 2*$lw, |
|
147
|
|
|
|
|
|
|
$w + $dot/2, |
|
148
|
|
|
|
|
|
|
$xgbb[3] ); |
|
149
|
|
|
|
|
|
|
|
|
150
|
48
|
50
|
|
|
|
223
|
if ( $basefretno > 1 ) { |
|
151
|
0
|
|
|
|
|
0
|
$basefont = $ps->{fonts}->{diagram_base}->{fd}->{font}; |
|
152
|
0
|
|
|
|
|
0
|
$basesize = $gh/0.85; |
|
153
|
0
|
|
|
|
|
0
|
my $basefretformat = $fbt; |
|
154
|
0
|
0
|
|
|
|
0
|
$basefretformat = '%s' unless $basefretformat =~ /^[^%]*\%s[^%]*$/; |
|
155
|
0
|
|
|
|
|
0
|
$basefrettext = sprintf($basefretformat, $basefretno); |
|
156
|
|
|
|
|
|
|
|
|
157
|
0
|
0
|
|
|
|
0
|
if ( $fbp eq "left" ) { |
|
158
|
0
|
|
|
|
|
0
|
$bb[0] -= $basefont->width("xx$basefrettext") * $basesize; |
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
else { |
|
161
|
|
|
|
|
|
|
#fret base position on "right" side |
|
162
|
0
|
|
|
|
|
0
|
$bb[0] -= $dot/2; |
|
163
|
0
|
|
|
|
|
0
|
$bb[2] += $basefont->width("xx$basefrettext") * $basesize; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
else { |
|
167
|
48
|
|
|
|
|
185
|
$bb[0] -= $dot/2; |
|
168
|
|
|
|
|
|
|
} |
|
169
|
48
|
0
|
33
|
|
|
372
|
if ( $fsh eq "below" && $info->{fingers} ) { |
|
170
|
0
|
|
|
|
|
0
|
$bb[3] -= $gh + $lw; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
48
|
|
|
|
|
271
|
$xo->bbox(@bb); |
|
173
|
48
|
|
|
|
|
4979
|
$xo->line_width($lw); |
|
174
|
48
|
|
|
|
|
3124
|
$xo->stroke_color($fg); |
|
175
|
48
|
|
|
|
|
9063
|
$xo->fill_color($fg); |
|
176
|
|
|
|
|
|
|
|
|
177
|
48
|
|
|
|
|
7423
|
if ( DIAG_DEBUG ) { |
|
178
|
|
|
|
|
|
|
# Draw the grid. |
|
179
|
|
|
|
|
|
|
$xo->save; |
|
180
|
|
|
|
|
|
|
$xo->fill_color('yellow'); |
|
181
|
|
|
|
|
|
|
$xo->rectangle($xo->bbox)->fill; |
|
182
|
|
|
|
|
|
|
$xo->object( $xg, 0, 0, 1 ); |
|
183
|
|
|
|
|
|
|
$xo->fill_color('red'); |
|
184
|
|
|
|
|
|
|
my $lw = $lw/2; |
|
185
|
|
|
|
|
|
|
$xo->rectangle( -$lw, -$lw, $lw, $lw )->fill; |
|
186
|
|
|
|
|
|
|
$xo->restore; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
else { |
|
189
|
48
|
|
|
|
|
311
|
$xo->object( $xg, 0, 0, 1 ); |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# Draw extended nut if base = 1. |
|
193
|
48
|
50
|
|
|
|
18691
|
if ( $info->{base} <= 1 ) { |
|
194
|
48
|
50
|
|
|
|
187
|
if ( $nutwidth > 1 ) { |
|
195
|
48
|
|
|
|
|
269
|
for ( 0 .. $nutwidth-2 ) { |
|
196
|
192
|
|
|
|
|
15259
|
$xo->move( -$lw/2, -$_*$lw ); |
|
197
|
192
|
|
|
|
|
21303
|
$xo->hline( $w + $lw/2 ); |
|
198
|
|
|
|
|
|
|
} |
|
199
|
48
|
|
|
|
|
5020
|
$xo->stroke; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# Draw first fret number, if > 1. |
|
204
|
48
|
50
|
|
|
|
1784
|
if ( $basefretno > 1 ) { |
|
205
|
0
|
|
|
|
|
0
|
$xo->textstart; |
|
206
|
0
|
|
|
|
|
0
|
$xo->font( $basefont, $basesize ); |
|
207
|
|
|
|
|
|
|
|
|
208
|
0
|
0
|
|
|
|
0
|
if ( $fbp eq "left" ) { |
|
209
|
0
|
|
|
|
|
0
|
$xo->translate( -$basefont->width("x") * 0.85 * $basesize, |
|
210
|
|
|
|
|
|
|
-$nw - ($baselabeloffset+0.85)*$gh ); |
|
211
|
0
|
|
|
|
|
0
|
$xo->text( $basefrettext, align => "right" ); |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
else { |
|
214
|
|
|
|
|
|
|
#fret base position on "right" side |
|
215
|
0
|
|
|
|
|
0
|
$xo->translate( ($strings-1)*$gw + $basefont->width("x") * 0.85 * $basesize, |
|
216
|
|
|
|
|
|
|
-$nw - ($baselabeloffset+0.85)*$gh ); |
|
217
|
0
|
|
|
|
|
0
|
$xo->text( $basefrettext, align => "left" ); |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
|
|
220
|
0
|
|
|
|
|
0
|
$xo->textend; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
48
|
|
|
|
|
148
|
my $fingers; |
|
224
|
48
|
50
|
|
|
|
310
|
$fingers = $info->{fingers} if $fsh; |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# Bar detection. |
|
227
|
48
|
|
|
|
|
162
|
my $bar = {}; |
|
228
|
48
|
50
|
|
|
|
170
|
if ( $fingers ) { |
|
229
|
48
|
|
|
|
|
112
|
my %h; |
|
230
|
48
|
|
|
|
|
113
|
my $str = 0; |
|
231
|
48
|
|
|
|
|
117
|
my $got = 0; |
|
232
|
|
|
|
|
|
|
|
|
233
|
48
|
|
|
|
|
109
|
foreach ( @{ $fingers } ) { |
|
|
48
|
|
|
|
|
181
|
|
|
234
|
0
|
0
|
|
|
|
0
|
$str++, next unless $info->{frets}->[$str] > 0; |
|
235
|
0
|
0
|
|
|
|
0
|
if ( $bar->{$_} ) { |
|
236
|
|
|
|
|
|
|
# Same finger on multiple strings -> bar. |
|
237
|
0
|
|
|
|
|
0
|
$got++; |
|
238
|
0
|
|
|
|
|
0
|
$bar->{$_}->[-1] = $str; |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
else { |
|
241
|
|
|
|
|
|
|
# Register. |
|
242
|
0
|
|
|
|
|
0
|
$bar->{$_} = [ $_, $info->{frets}->[$str], $str, $str ]; |
|
243
|
|
|
|
|
|
|
} |
|
244
|
0
|
|
|
|
|
0
|
$str++; |
|
245
|
|
|
|
|
|
|
} |
|
246
|
|
|
|
|
|
|
|
|
247
|
48
|
50
|
|
|
|
201
|
if ( $got ) { |
|
248
|
0
|
|
|
|
|
0
|
$xo->save; |
|
249
|
|
|
|
|
|
|
|
|
250
|
0
|
0
|
|
|
|
0
|
if ( $bstyle eq "line" ) { |
|
251
|
0
|
|
|
|
|
0
|
$xo->line_width($bsz)->line_cap(0); |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
else { |
|
254
|
|
|
|
|
|
|
# bar in "arc" style. |
|
255
|
0
|
|
|
|
|
0
|
$xo->line_width($lw+0.2); |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
|
|
258
|
0
|
|
|
|
|
0
|
foreach ( sort keys %$bar ) { |
|
259
|
0
|
|
|
|
|
0
|
my @bi = @{ $bar->{$_} }; |
|
|
0
|
|
|
|
|
0
|
|
|
260
|
|
|
|
|
|
|
# $bi array description = [finger, fret, first_string, last_string]. |
|
261
|
|
|
|
|
|
|
|
|
262
|
0
|
0
|
|
|
|
0
|
if ( $bi[-2] == $bi[-1] ) { # not a bar |
|
263
|
0
|
|
|
|
|
0
|
delete $bar->{$_}; |
|
264
|
0
|
|
|
|
|
0
|
next; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
|
|
|
|
|
|
|
|
267
|
0
|
0
|
|
|
|
0
|
if ( $bstyle eq "line" ) { |
|
268
|
|
|
|
|
|
|
# Print the bar line. |
|
269
|
0
|
|
|
|
|
0
|
$x = $bi[2]*$gw; |
|
270
|
0
|
|
|
|
|
0
|
$xo->move( $x, -$nw -$bi[1]*$gh+$gh/2 ); |
|
271
|
0
|
|
|
|
|
0
|
$xo->hline( $x+($bi[3]-$bi[2])*$gw); |
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
else { |
|
274
|
|
|
|
|
|
|
# Print arcs for barre |
|
275
|
0
|
|
|
|
|
0
|
my $arcw = (($bi[3]-$bi[2])*$gw + 0.7*$gw)/2; |
|
276
|
0
|
|
|
|
|
0
|
my $arch = 0.4*$gw; |
|
277
|
0
|
|
|
|
|
0
|
my $arcy = -$nw -$bi[1]*$gh +$gh+0.25*$gh; |
|
278
|
0
|
|
|
|
|
0
|
my $arcx = $bi[2]*$gw - (0.7*$gw)/2; |
|
279
|
|
|
|
|
|
|
|
|
280
|
0
|
0
|
|
|
|
0
|
if ( $bi[1] == 1 ) { |
|
281
|
|
|
|
|
|
|
# Bar is on the first fret so bar arcs |
|
282
|
|
|
|
|
|
|
# must be drawn above the nut. |
|
283
|
0
|
|
|
|
|
0
|
$arcy += $nw; |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# Draw first arc. |
|
287
|
0
|
|
|
|
|
0
|
$xo->move( $arcx, $arcy ); |
|
288
|
0
|
|
|
|
|
0
|
$xo->arc( $arcx+$arcw, $arcy, $arcw, $arch, 180, 0 ); |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
# Draw second arc a little higher, this is |
|
291
|
|
|
|
|
|
|
# a fast way to have narrower corners look at the arc edge. |
|
292
|
0
|
|
|
|
|
0
|
$xo->move( $arcx, $arcy-0.8 ); |
|
293
|
0
|
|
|
|
|
0
|
$xo->arc( $arcx+$arcw, $arcy-0.8, $arcw, $arch, 180, 0 ); |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
0
|
$xo->stroke; |
|
297
|
0
|
|
|
|
|
0
|
$xo->fill; |
|
298
|
|
|
|
|
|
|
} |
|
299
|
0
|
|
|
|
|
0
|
$xo->stroke->restore; |
|
300
|
|
|
|
|
|
|
} |
|
301
|
|
|
|
|
|
|
} |
|
302
|
|
|
|
|
|
|
|
|
303
|
48
|
|
|
|
|
112
|
my $oflo; # to detect out of range frets |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# Color of the dots and numbers. |
|
306
|
48
|
|
|
|
|
133
|
my $fbg = ""; # numbers |
|
307
|
48
|
|
|
|
|
150
|
my $ffg = $fg; # dots |
|
308
|
|
|
|
|
|
|
# The numbercolor property of the chordfingers is used for the |
|
309
|
|
|
|
|
|
|
# color of the dot numbers. |
|
310
|
48
|
|
|
|
|
245
|
my $fcf = $ps->{fonts}->{chordfingers}; |
|
311
|
48
|
|
|
|
|
431
|
$fbg = $pr->_bgcolor($fcf->{numbercolor}); |
|
312
|
48
|
|
|
|
|
241
|
$ffg = $pr->_bgcolor($fcf->{color}); |
|
313
|
|
|
|
|
|
|
|
|
314
|
48
|
50
|
|
|
|
259
|
if ( $fsh ne "below" ) { |
|
315
|
|
|
|
|
|
|
# However, if none we should really use "background" color. |
|
316
|
48
|
50
|
|
|
|
212
|
$fbg = $bg if $fbg eq "none"; |
|
317
|
|
|
|
|
|
|
} |
|
318
|
|
|
|
|
|
|
else { |
|
319
|
|
|
|
|
|
|
# However, for "below" case if none or numbercolor equals background color we should really use "foreground". |
|
320
|
0
|
0
|
0
|
|
|
0
|
$fbg = $fg if ( $fbg eq "none") || ( $fbg eq $bg ); |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
48
|
|
|
|
|
158
|
$x = -$gw; |
|
324
|
48
|
|
|
|
|
194
|
for my $sx ( 0 .. $strings-1 ) { |
|
325
|
288
|
|
|
|
|
763608
|
$x += $gw; |
|
326
|
288
|
|
|
|
|
1230
|
my $fret = $info->{frets}->[$sx]; |
|
327
|
288
|
|
|
|
|
583
|
my $fing = -1; |
|
328
|
288
|
50
|
50
|
|
|
1761
|
$fing = $fingers->[$sx] // -1 if $fingers; |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# For bars in "line" style, only the first and last finger. |
|
331
|
288
|
50
|
33
|
|
|
1965
|
if ( $fing && $bar->{$fing} && $bstyle eq "line" ) { |
|
|
|
|
33
|
|
|
|
|
|
332
|
0
|
0
|
0
|
|
|
0
|
next unless $sx == $bar->{$fing}->[2] || $sx == $bar->{$fing}->[3]; |
|
333
|
|
|
|
|
|
|
} |
|
334
|
|
|
|
|
|
|
|
|
335
|
288
|
100
|
|
|
|
1092
|
if ( $fret > 0 ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
336
|
192
|
50
|
33
|
|
|
634
|
if ( $fret > $vc && !$oflo++ ) { |
|
337
|
0
|
|
|
|
|
0
|
warn("Diagram $info->{name}: ", |
|
338
|
|
|
|
|
|
|
"Fret position $fret exceeds diagram size $vc\n"); |
|
339
|
0
|
|
|
|
|
0
|
next; |
|
340
|
|
|
|
|
|
|
} |
|
341
|
192
|
|
|
|
|
909
|
$xo->fill_color($ffg); |
|
342
|
192
|
|
|
|
|
41213
|
$xo->circle( $x, -$nw - ($fret-0.5)*$gh, $dot/2 )->fill; |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
} |
|
345
|
|
|
|
|
|
|
elsif ( $fret < 0 ) { |
|
346
|
48
|
|
|
|
|
379
|
$xo->move( $x - $dot/3, 0.77 * $dot + $lw ); |
|
347
|
48
|
|
|
|
|
6402
|
$xo->line( $x + $dot/3, 0.1 * $gh + $lw ); |
|
348
|
48
|
|
|
|
|
5599
|
$xo->move( $x + $dot/3, 0.77 * $dot + $lw ); |
|
349
|
48
|
|
|
|
|
5578
|
$xo->line( $x - $dot/3, 0.1 * $gh + $lw ); |
|
350
|
48
|
|
|
|
|
5053
|
$xo->stroke; |
|
351
|
|
|
|
|
|
|
} |
|
352
|
|
|
|
|
|
|
elsif ( $info->{base} > 0 ) { |
|
353
|
48
|
|
|
|
|
409
|
$xo->circle( $x, 3.5*$gh/10 + $lw, $dot/3 )->stroke; |
|
354
|
|
|
|
|
|
|
} |
|
355
|
|
|
|
|
|
|
} |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
# Show the fingers, if any. |
|
358
|
48
|
50
|
33
|
|
|
189509
|
if ( $fingers && @$fingers ) { |
|
359
|
0
|
|
|
|
|
0
|
my ( $font, $size ); |
|
360
|
0
|
|
|
|
|
0
|
$font = "chordfingers"; |
|
361
|
0
|
|
|
|
|
0
|
$size = $dot; |
|
362
|
0
|
0
|
|
|
|
0
|
if ( $fsh eq "below" ) { |
|
363
|
0
|
|
0
|
|
|
0
|
$size = $ps->{fonts}->{$font}->{size} // "00"; |
|
364
|
0
|
0
|
|
|
|
0
|
$size = $dot if $size <= 0; |
|
365
|
|
|
|
|
|
|
} |
|
366
|
0
|
|
|
|
|
0
|
$font = $ps->{fonts}->{$font}->{fd}->{font}; |
|
367
|
0
|
|
|
|
|
0
|
warn("XXX ", $font->{' data'}->{fontname}, " $size\n") if DIAG_DEBUG; |
|
368
|
|
|
|
|
|
|
|
|
369
|
0
|
|
|
|
|
0
|
$x = -$gw; |
|
370
|
0
|
|
|
|
|
0
|
my $did = 0; |
|
371
|
0
|
|
|
|
|
0
|
for my $sx ( 0 .. $strings-1 ) { |
|
372
|
|
|
|
|
|
|
#when "below", chord fingers should be always drawn and not take into account the dot color |
|
373
|
0
|
0
|
0
|
|
|
0
|
last if ( $fsh ne "below" ) && ( $fbg eq $ffg ); |
|
374
|
0
|
|
|
|
|
0
|
$x += $gw; |
|
375
|
0
|
|
|
|
|
0
|
my $fret = $info->{frets}->[$sx]; |
|
376
|
0
|
0
|
|
|
|
0
|
next unless $fret > 0; |
|
377
|
0
|
|
|
|
|
0
|
my $fing = uc $fingers->[$sx]; |
|
378
|
0
|
0
|
|
|
|
0
|
next unless $fing =~ /^[1-9A-Z]$/; |
|
379
|
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
# For barre, only the first and last finger. |
|
381
|
0
|
0
|
0
|
|
|
0
|
if ( $bar->{$fing} && $fsh ne "below" ) { |
|
382
|
|
|
|
|
|
|
next unless ( $sx == $bar->{$fing}->[2] |
|
383
|
0
|
0
|
0
|
|
|
0
|
|| $sx == $bar->{$fing}->[3] ); |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
|
|
386
|
0
|
0
|
|
|
|
0
|
unless ( $did++ ) { |
|
387
|
0
|
0
|
|
|
|
0
|
if ( $fsh eq "below" ) { |
|
388
|
0
|
|
|
|
|
0
|
$size *= 1.4; |
|
389
|
|
|
|
|
|
|
} |
|
390
|
0
|
|
|
|
|
0
|
$xo->fill_color($fbg); |
|
391
|
0
|
|
|
|
|
0
|
$xo->textstart; |
|
392
|
0
|
|
|
|
|
0
|
$xo->font( $font, $size ); |
|
393
|
|
|
|
|
|
|
} |
|
394
|
0
|
0
|
|
|
|
0
|
if ( $fsh eq "below" ) { |
|
395
|
0
|
|
|
|
|
0
|
$xo->translate( $x, -$nw - $lw - ($vc+1)*$gh ); |
|
396
|
|
|
|
|
|
|
} |
|
397
|
|
|
|
|
|
|
else { |
|
398
|
0
|
|
|
|
|
0
|
$xo->translate( $x, -$nw - ($fret-0.5)*$gh - $dot/3 ); |
|
399
|
|
|
|
|
|
|
} |
|
400
|
0
|
|
|
|
|
0
|
$xo->text( $fing, align => "center" ); |
|
401
|
|
|
|
|
|
|
} |
|
402
|
0
|
0
|
|
|
|
0
|
$xo->textend if $did; |
|
403
|
|
|
|
|
|
|
} |
|
404
|
|
|
|
|
|
|
|
|
405
|
48
|
|
|
|
|
516
|
return $xo; |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
# The core grid. Just the horizontal and vertical lines, with a fitting |
|
409
|
|
|
|
|
|
|
# bounding box. Origin is (half linewidth from) top left. |
|
410
|
|
|
|
|
|
|
# Grid objects are cached globally. |
|
411
|
|
|
|
|
|
|
|
|
412
|
8
|
|
|
8
|
|
117
|
use constant DIAG_GRID_XO => 0; |
|
|
8
|
|
|
|
|
24
|
|
|
|
8
|
|
|
|
|
13076
|
|
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
method grid_xo { |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
return $dcache->{$gw,$gh,$lw,$nw,$fg,$vc,$hc} //= do { |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
my $w = $gw * ($hc - 1); |
|
419
|
|
|
|
|
|
|
my $h = $gh * $vc; |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
my $xo = $pdf->xo_form; |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
# Bounding box must take linewidth into account. |
|
424
|
|
|
|
|
|
|
# Origin is top left, so y runs negative. |
|
425
|
|
|
|
|
|
|
my $xp = DIAG_GRID_XO ? 2 : 0; |
|
426
|
|
|
|
|
|
|
my @bb = ( -$lw/2 - $xp, $lw/2 + $xp, |
|
427
|
|
|
|
|
|
|
$w + $lw/2 + $xp, -($vc * $gh + $nw) - $lw/2 - $xp ); |
|
428
|
|
|
|
|
|
|
$xo->bbox(@bb); |
|
429
|
|
|
|
|
|
|
$xo->line_width($lw); |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
if ( DIAG_GRID_XO ) { |
|
432
|
|
|
|
|
|
|
# Draw the grid. |
|
433
|
|
|
|
|
|
|
$xo->fill_color('yellow'); |
|
434
|
|
|
|
|
|
|
$xo->rectangle(@bb)->fill; |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# Draw additional nuts. |
|
437
|
|
|
|
|
|
|
if ( 0&& $nutwidth > 1 ) { |
|
438
|
|
|
|
|
|
|
for ( 0 .. $nutwidth-2 ) { |
|
439
|
|
|
|
|
|
|
$xo->stroke_color( $_ % 2 ? "#c0c0c0" : "#e0e0e0" ); |
|
440
|
|
|
|
|
|
|
$xo->move( -$lw/2, -$_*$lw ); |
|
441
|
|
|
|
|
|
|
$xo->hline( $w + $lw/2 )->stroke; |
|
442
|
|
|
|
|
|
|
} |
|
443
|
|
|
|
|
|
|
} |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
$xo->stroke_color($fg); |
|
447
|
|
|
|
|
|
|
for ( 0 .. $vc ) { |
|
448
|
|
|
|
|
|
|
$xo->move( -$lw/2, -$_*$gh - $nw); |
|
449
|
|
|
|
|
|
|
$xo->hline( $w + $lw/2 ); |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
for ( 0 .. $hc-1 ) { |
|
452
|
|
|
|
|
|
|
$xo->move( $_*$gw, $lw/2 ); |
|
453
|
|
|
|
|
|
|
$xo->vline( -($gh*$vc + $nw + $lw/2 ) ); |
|
454
|
|
|
|
|
|
|
} |
|
455
|
|
|
|
|
|
|
$xo->stroke; |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
if ( DIAG_GRID_XO ) { |
|
458
|
|
|
|
|
|
|
# Show origin. |
|
459
|
|
|
|
|
|
|
$xo->fill_color('red'); |
|
460
|
|
|
|
|
|
|
my $lw = $lw/2; |
|
461
|
|
|
|
|
|
|
$xo->rectangle( -$lw, -$lw, $lw, $lw )->fill; |
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
$xo; |
|
465
|
|
|
|
|
|
|
}; |
|
466
|
|
|
|
|
|
|
} |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
1; |