| ︙ | | |
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
-
+
|
The **abc2svg** core is based on the
[abcm2ps](https://github.com/lewdlime/abcm2ps) C code
which requires compilation on every operating system.
The **abc2svg** scripts can run in any system with no compilation on
any platform that contains an internet browser. This includes MS-Windows,
Apple, and Unix-like systems (Linux, BSD...) as well as portable devices
such as cell phones and iPads.
such as cell phones and tablets.
A description of the ABC parameters that relate to both abcm2ps
and abc2svg can be found [here][1].
[1]: http://moinejf.free.fr/abcm2ps-doc/index.html "abc2svg documentation"
### 1. Web browser usage
|
| ︙ | | |
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
-
+
-
+
-
+
|
search on the internet the name of the browser and keywords such as
'bookmarklet' and 'javascript in url'). To edit the URL, extract
the javascript code
by right clicking on one of the bookmarklets below and selecting
copy url. Then, paste this code into the URL of your new bookmark
in your library.
To use a abc2svg bookmarklet, first load an ABC file into your
To use a abc2svg bookmarklet, first, load an ABC file into your
browser either from a web site of from a file on your system.
Once you see the textual abc code, click on the bookmarklet
that you created. After a slight delay depending upon the
complexity of the abc code, it should be replaced by a music
representation or a list of the contents of the ABC file. Here
are two bookmarklets that you can try.
This
<a href="javascript:(function(){var%20s,n=2,d=document,b=d.body;d.head.innerHTML='<style>svg{display:block};@media print{body{margin:0;padding:0;border:0};.nop{display:none}}</style>\n';b.innerHTML='\n%25abc-2.2%25%3c!--\n'+b.textContent+'%25--%3e\n';function%20f(u){s=d.createElement('script');s.src='http://moinejf.free.fr/js/'+u;s.onload=function(){if(--n==0)dom_loaded()};d.head.appendChild(s)};f('abcweb-1.js');f('snd-1.js')})()"
<a href="javascript:(function(){var%20s,n=2,d=document,b=d.body;d.head.innerHTML='%3cstyle%3esvg{display:block};@media print{body{margin:0;padding:0;border:0};.nop{display:none}}%3c/style%3e\n';b.innerHTML='%3cscript type=%22text/vnd.abc%22%3e\n'+b.textContent+'%3c/script%3e\n';function%20f(u){s=d.createElement('script');s.src='http://moinejf.free.fr/js/'+u;s.onload=function(){if(--n==0)dom_loaded()};d.head.appendChild(s)};f('abcweb-1.js');f('snd-1.js')})()"
title="Copy me">first abc2svg bookmarklet</a>
renders all the music it finds in the page currently displayed.
Once the music is displayed, clicking inside a tune starts playing it
from the beginning.
Clicking on a particular note or rest starts playing from that point.
To print or convert the music to a PDF file,
simply click on the 'Print' button of the web browser.
(If the 'Print' button does not appear on your browser menu,
try right clicking on the web page.)
Alternatively, if your source contains many tunes, you can
use this
<a href="javascript:(function(){var%20s,n=2,d=document,b=d.body;d.head.innerHTML='<style>svg{display:block};@media print{body{margin:0;padding:0;border:0};.nop{display:none}}</style>\n';b.innerHTML='\n%25abc-2.2%25%3c!--\n'+b.textContent+'%25--%3e\n';function%20f(u){s=d.createElement('script');s.src='http://moinejf.free.fr/js/'+u;s.onload=function(){if(--n==0)dom_loaded()};d.head.appendChild(s)};f('abcweb1-1.js');f('snd-1.js')})()"
<a href="javascript:(function(){var%20s,n=2,d=document,b=d.body;d.head.innerHTML='%3cstyle%3esvg{display:block};@media print{body{margin:0;padding:0;border:0};.nop{display:none}}%3c/style%3e\n';b.innerHTML='%3cscript type=%22text/vnd.abc%22%3e\n'+b.textContent+'%3c/script%3e\n';function%20f(u){s=d.createElement('script');s.src='http://moinejf.free.fr/js/'+u;s.onload=function(){if(--n==0)dom_loaded()};d.head.appendChild(s)};f('abcweb1-1.js');f('snd-1.js')})()"
title="Copy me">second bookmarklet</a>.
The browser will list the titles of the tunes.
Clicking on a title displays the tune.
Playing and printing work in the same manner as above.
The generated pages contain a yellow menu in the top right corner which permits
you to return to the tune list or to modify the music. With this last option,
you can adjust the page size before printing, correct the ABC syntax or
|
| ︙ | | |
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
+
+
+
+
+
+
+
+
+
+
+
+
+
|
If your ABC files contain `%%abc-include`, then you must:
- load the ABC file using the browse button,
- click the include file name button,
- and load the include file using the same previous browse button.
Only one included file is allowed.
If you have installed abc2svg in a site of yours, you may put a file
**pref.js** with the abc2svg scripts. This file may contain various
javascript functions and also ABC parameters.
These parameters must be defined inside the following sequence:
if (typeof abc2svg == "undefined")
var abc2svg = {}
if (!abc2svg.a_inc)
abc2svg.a_inc = {}
abc2svg.a_inc["default.abc"] = `
.. put here the ABC parameters ..
`
If you have a US keyboard, its behaviour can be changed for easier music
entering by one of these bookmarklets:
<a href="javascript:(function(){if(typeof%20abc2svg.loadjs=='function'){abc2svg.loadjs('abckbd-1.js')}else{alert('use%20with%20abc2svg%20editor')}})()"
title="Copy me">keyboard 1</a>
and
<a href="javascript:(function(){if(typeof%20abc2svg.loadjs=='function'){abc2svg.loadjs('abckbd2-1.js')}else{alert('use%20with%20abc2svg%20editor')}})()"
|
| ︙ | | |
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
-
+
-
-
+
+
-
-
+
+
+
-
+
-
-
+
|
(Note that, in the example, the paths are relative - see why below.)
[4]: http://moinejf.free.fr/abcm2ps-doc/tabac.html "J'ai du bon tabac"
As it is apparent, HTML and ABC can be mixed in the same html file.
Both are rendered in the order you defined them.
You may also have noticed this CSS about SVG elements:
You may also have noticed this style about SVG elements:
` svg { display: block }`
This permits to have the music on separate vertical areas.
Without this CSS, the music is in-lined as in [this other example][5].
It puts the lines of music on vertical areas.
Without this style, the music is in-lined as in [this other example][5].
[5]: http://moinejf.free.fr/abcm2ps-doc/dansou-i.html "Tune index example"
Global ABC parameters may be added as `parameter=value` in the query string
of the URL of the page. The [following example][16] calls the same
"J'ai du bon tabac" with `pagescale=1.2` (giving `%%pagescale 1.2`).
[16]: http://moinejf.free.fr/abcm2ps-doc/tabac.html?pagescale=1.2 "J'ai du bon tabac"
In the above examples, all the ABC music is generated (displayed
and ready to be played) by means of the script **abcweb-1.js**.
If there is a large collection of tunes, it may be preferable to
link to the other script, **abcweb1-1.js**, which permits you
to select particular tune(s). Without an explicit
link to the other script, **abcweb1-1.js**, which offers a tune selection.
Without an explicit
selection (see below), a list of the tunes is displayed, and,
after a tune has been selected, the whole page is replaced by the music.
(The HTML code, if any, is not displayed.)
You can go back to the list of the tunes thanks to the menu
A menu on the top right corner of the screen
on the top right corner of the screen. Here is [a real example][6].
permits to get the tune list again. Here is [a real example][6].
[6]: http://moinejf.free.fr/abc/boyvin-2-2.html "J. Boyvin organ tunes"
As you may notice in the menu, the edition of the ABC content is proposed.
This permits, for example, to transpose the tunes.
This permits you, for example, to transpose the tunes.
This edition is done inside the browser, so, your changes will be lost
after leaving the page.
When accessing such pages, an external selection of the tunes
can be accomplished by ending the URL with the character '`#`'
followed by a [regular expression][7]
to be applied to the tune headers.
|
| ︙ | | |
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
|
#### 1.4 Installing abc2svg on your system or on your server
The **abc2svg** package on my server is still being tuned
which could change its behaviour at any unknown time; so you may
prefer to install and run it from your own system.
There are many ways to install abc2svg:
- [tarball][16] or [.zip archive][17] from my site
Both files contain the scripts that are generated from the source
when abc2svg is stable enough. The scripts are ready
to be used from the root directory.
[16]: http://moinejf.free.fr/abc2svg.tar.bz2 "tarball"
[17]: http://moinejf.free.fr/abc2svg.zip "ZIP file"
- [Guido Gonzato's page](http://abcplus.sourceforge.net/#abc2svg)
Guido maintains a ZIP archive of the abc2vg scripts after
each release of a new version (many thanks, Guido!).
You can just download and unzip this archive. **abc2svg** should
run immediately in your machine without connecting to my site.
In the same page, you can also find some binaries of QuickJS,
a fast javascript interpreter (see below).
- tarball
From the timeline in the [chisel repository][13], you can get a tarball
any version of the abc2svg source and install it in your system.
of any version of the abc2svg source and install it in your system.
The abc2svg scripts must then be built from the raw source files
described in the section 'Build' below.
The disadvantage of this approach is that if you want
to use an other or newer version you need to download a new tarball.
[13]: https://chiselapp.com/user/moinejf/repository/abc2svg/timeline
- fossil clone
If you can get the fossil program (one binary) for your system,
you may clone the chisel repository by
` fossil clone https://chiselapp.com/user/moinejf/repository/abc2svg abc2svg.fossil`
` fossil open abc2svg.fossil`
and get the abc2svg source files containing the last changes
between the official versions. Updating your files is done by
` fossil pull`
` fossil update`
Building the scripts is done in the same way as with a tarball.
The repository is presently over 34Mb.
The repository is presently over 50Mb.
For those unfamiliar with [fossil][14], it is an integrated
software management system similar to [git](https://git-scm.com/).
Chisel acts like a repository similar to [github](https://github.com/).
[14]: https://fossil-scm.org/home/doc/trunk/www/index.wiki
- npm
The scripts may be installed from the `npm` repository by:
` npm install abc2svg`
They are ready to run (web and shell with nodejs).
I upload a new npm version about once a month.
Using bookmarklets with a local installation does not work directly
because of a cross-domain security hole, but this is possible by running
a local HTTP server (you will also have to change the location
of the scripts in the bookmarklet code).
If you have write access on a remote server, you may put there
the abc2svg scripts. There is no automatic process to do that.
|
| ︙ | | |
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
|
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
-
-
+
+
-
+
-
|
#### 2.1 abc2svg shell scripts
As you have seen, printing the music can be done easily with any web browser.
You can automate the process of creating music sheets
with **abc2svg** using shell scripts running a Javascript interpreter.
The interfaces to the various scripts are different. Below you will
find various scripts that I had to built.
The interfaces to the various interpreters are different. Below you will
find the scripts I had to built.
- `abcqjs` with `qjs` [QuickJS by Fabrice Bellard and Charlie Gordon][10]
- `abcmjs` with `js78`, `js68`, `js60`, `js52` or `js24` (Mozilla JavaScript shell)
- `abcmjs` with `js78`, `js60`, `js52` or `js24` (Mozilla JavaScript shell)
- `abcjsc` with `jsc` (webkit2gtk)
- `abcnode` with `node` (nodeJS without module)
- `abc2svg` with `node` (nodeJS with modules)
[10]: https://bellard.org/quickjs/
Each script gets the abc2svg options and ABC files from the command line
and sends the generated file to `stdout` and possible errors to `stderr`.
The general syntax of the command line is:
` script [script.js] [options] ABC_file [[options] ABC_file]* [options]`
|
| ︙ | | |
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
|
-
+
-
-
-
-
-
-
+
+
-
|
This script just outputs the abc2svg parameters.
#### 2.3 PDF generation
`abctopdf` is a shell script which converts ABC to PDF using one of the
previous shell scripts and, either a chrome/chromium compatible web browser
(settable by the environment variable 'BROWSER'),
or the program [weasyprint](https://weasyprint.org/) or
or the program [weasyprint](https://weasyprint.org/).
the program `rsvg-convert`.
With `rsvg-convert`, the used music font must be installed and defined by
`%%musicfont <fontname>`.
Note also that, with `weasyprint` or `rsvg-convert`, the paper size is
forced to A4. Instructions for changing this size may be found in the
Note also that, with `weasyprint`, the paper size is forced to A4.
Instructions for changing this size may be found in the script source.
script source.
The output PDF document may be specified by the command line argument `-o`
(default `abc.pdf`).
Example:
` abctopdf my_file.abc -o my_file.pdf`
|
| ︙ | | |
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
|
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
|
-
+
+
-
+
-
-
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
|
- The music is displayed as SVG images. There is one image per
music line / text block.
If you want to move these images to some other files,
each one must contain the full CSS and defs. For that, insert
` %%fullsvg x`
in the ABC file before rendering (see the
[fullsvg documentation](http://moinejf.free.fr/abcm2ps-doc/fullsvg.xhtml)
[fullsvg documentation](http://moinejf.free.fr/abcm2ps-doc/fullsvg.html)
for more information).
- Playing uses the HTML5 audio and/or the midi APIs.
For audio, by default, abc2svg uses a sound font (format SF2)
which is split into one file
per instrument. This sound font is stored in the subdirectory `Scc1t2/`.
Each instrument file is a base64 encoded javascript array.
Other sound fonts may be used. Some of them are stored in the subdirectory
Other sound fonts may be used. Some of them are stored in the subdirectory
`sf2/` (`AWE_ROM_gm` and `2MBGMGS`). Two formats are supported: raw SF2 and
SF2 wrapped into javascript (the raw SF2 files can be loaded
only when they are in the same HTTP domain).
The shell script `sf.sh` (in `sf2/`) may be used to create the javacript files
from raw SF2 files.
The sound font to be used for playing may be defined in the ABC code
from raw SF2 files.
The sound font to be used for playing may be defined in the ABC code
by the command `%%soundfont`. E.g.:
` %%soundfont http://moinejf.free.fr/js/sf2/AWE_ROM_gm.js`
- The names of the abc2svg scripts have a suffix which is the version of
the core interface (actually '`-1`').
#### 4.3 More about the web scripts
Here are the scripts which are used in a web context:
- `abcweb-1.js`
This script replaces the ABC or MEI sequences found in the (X)HTML file
by SVG images of the music.
The ABC sequences are searched:
- first inside <script> elements with a type
["text/vnd.abc"](https://www.iana.org/assignments/media-types/text/vnd.abc)
(the script tag is removed from the page),
(the script tag is replaced by a <div>),
- or inside (X)HTML elements with a class `abc` (lower case letters),
- otherwise on `X:` or `%abc-` at start of line up to a XML tag at start of line.
When a ABC sequence is not included in a <script> and when it contains
the characters '<', '>' or '&',
it must be enclosed in a XML comment or in a CDATA
(%<![CDATA[ .. %]]> - the comment or CDATA must be in a ABC comment).
See the
[%%beginml documentation](http://moinejf.free.fr/abcm2ps-doc/beginml.xhtml)
(%<![CDATA[ .. %]]> - the comment or CDATA must be in a ABC comment).
When using <script>, it is possible to set abc2svg parameters via CSS.
For that, the <style> in the HTML <head> may contain custom
properties (properties starting with '--') and these properties are converted
to abc2svg parameters (starting with '%%') before the ABC sequence.
For instance, in the (<head>) <style> element, you can put:
` .parm {--pagewidth:30cm; --bgcolor : yellow}`
and in some <script ..vnd.abc..>, you set the class:
` <script class="parm" type="text/vnd.abc">`
This defines the page width and the background color of the generated music.
See the
[%%beginml documentation](http://moinejf.free.fr/abcm2ps-doc/beginml.html)
for an example, and here is [how to put inline music in HTML][15].
Playing and highlighting the played notes may be offered loading
the script `snd-1.js` (see below).
[15]: http://moinejf.free.fr/abcm2ps-doc/inline.html "abc2svg - inline music"
This script also accepts a parameter `with_source`.
When this parameter is set, the music source is included before the
SVG images of the music. An argument `nohead` prevents displaying
the source of the first music sequence. The music source is displayed
in a <pre> element of class `source`. The SVG's are included
in a <div> of the same class `source`.
The source may be displayed either above (default) or
at the left side of the music (using a style as
`.source{display: inline-block; vertical-align: top}`).
See the source of
[abcm2ps/abc2svg features](http://moinejf.free.fr/abcm2ps-doc/features.html)
for an example.
The music source may be editable.
To change it, the script contains two functions:
- `abc2svg.get_music` returns the source of the music sequence
(in <script> type "text/vnd.abc", class="abc" or inlined ABC)
Its argument is the HTML <div> element that contains the music.
- `abc2svg.set_music` has two arguments, the HTML <div> element
and the new source of the music.
It generates and replaces the music in the <div>.
- `abcweb1-1.js`
The page body is analyzed as a ABC file and its content is
replaced by music as SVG images.
If the page contains reserved XML characters ('<', '>' and '&'),
the ABC code must be enclosed in a
` <script type="text/vnd.abc"> .. </script>`
sequence.
When there are many tunes in the file, the script displays a list
of the tunes. The list step may be bypassed when the URL of the file
contains a regular expression in the 'hash' value ('#' followed by
a string at the end of the URL).
This string does a
[%%select](http://moinejf.free.fr/abcm2ps-doc/select.xhtml).
When one or many tunes are displayed, a menu in the top/right corner
offers to go back to the tune list or to modify the ABC source.
- `snd-1.js`
This script may be used with `abcweb-1.js` or `abcweb1-1.js`
to play the rendered ABC music.
- `abcdoc-1.js`
This script is mainly used for ABC documentation.
It lets the ABC source sequences in the page before the SVG images.
See the source of
[abcm2ps/abc2svg features](http://moinejf.free.fr/abcm2ps-doc/features.html)
for an example.
### 5. MEI support
As an experimental feature, an extended core `mei2svg-1.js` may be generated.
This one may handle both the ABC and
[MEI](https://music-encoding.org/ "Music Encoding Initiative")
notations.
|
| ︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - abc2svg.js
//
// Copyright (C) 2014-2021 Jean-Francois Moine
// Copyright (C) 2014-2022 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
+
|
abc2svg.C = {
BLEN: 1536,
// symbol types
BAR: 0,
CLEF: 1,
CUSTOS: 2,
SM: 3, // sequence marker (transient)
GRACE: 4,
KEY: 5,
METER: 6,
MREST: 7,
NOTE: 8,
PART: 9,
REST: 10,
|
| ︙ | | |
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
-
+
|
SL_ALI_MSK: 0x70, // align
SL_ALIGN: 0x10,
SL_CENTER: 0x20,
SL_CLOSE: 0x40
};
// !! tied to the symbol types in abc2svg.js !!
abc2svg.sym_name = ['bar', 'clef', 'custos', '', 'grace',
abc2svg.sym_name = ['bar', 'clef', 'custos', 'smark', 'grace',
'key', 'meter', 'Zrest', 'note', 'part',
'rest', 'yspace', 'staves', 'Break', 'tempo',
'', 'block', 'remark']
// key table - index = number of accidentals + 7
abc2svg.keys = [
new Int8Array([-1,-1,-1,-1,-1,-1,-1 ]), // 7 flat signs
|
| ︙ | | |
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
-
-
-
-
-
-
+
+
+
+
+
+
-
+
|
// C D
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
// E F G
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4,
// A B
5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6 ])
abc2svg.b40_a = new Int8Array( // base-40 to accidental
// C D
[-2, -1, 0, 1, 2, 0, -2, -1, 0, 1, 2, 0,
// E F G
-2, -1, 0, 1, 2, -2, -1, 0, 1, 2, 0, -2, -1, 0, 1, 2, 0,
// A B
-2, -1, 0, 1, 2, 0, -2, -1, 0, 1, 2 ])
// C D
[-2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3,
// E F G
-2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2, -3,
// A B
-2, -1, 0, 1, 2, -3, -2, -1, 0, 1, 2 ])
abc2svg.b40_m = new Int8Array( // base-40 to midi
// C D
[-2, -1, 0, 1, 2, 0, 0, 1, 2, 3, 4, 0,
// E F G
2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 0, 5, 6, 7, 8, 9, 0,
// A B
7, 8, 9, 10, 11, 0, 9, 10, 11, 12, 13 ])
abc2svg.b40k = new Int8Array( // base-40 interval to possible transposition
// C D
[36, 1, 2, 3, 8, 2, 2, 7, 8,13,14, 2,
// 37
// E F G
8,13,14,19,20,13,14,19,20,25, 2,19,24,25,30,31, 2,
// 20
// A B
25,30,31,36,37, 2,31,36,37,38, 3 ])
25,30,31,36,37, 2,31,36,37, 2, 3 ])
// 2
abc2svg.b40sf = new Int8Array( // base-40 interval to key signature
// C D
[-2,-7, 0, 7, 2, 88, 0,-5, 2,-3, 4, 88,
// E F G
2,-3, 4,-1, 6,-3, 4,-1, 6, 1,88,-1,-6, 1,-4, 3,88,
// A B
|
| ︙ | | |
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
"aug7": "+7",
"7+5": "+7",
"7#5": "+7",
"sus": "sus4",
"7sus": "7sus4"
} // ch_alias
// extract one of the chord symbols
// With chords as "xxx(yyy)" or "[yyy];xxx"
// (!sel - default) returns "xxx" and (sel) returns "yyy"
abc2svg.cs_sel0 = /[\[(].*[\])]/g
abc2svg.cs_sel1 = /.*[\[(]|[\])].*/g
abc2svg.cs_filter = function(a_cs, sel) {
var i, cs,
tcs = ""
for (i = 0; i < a_cs.length; i++) {
cs = a_cs[i]
if (cs.type == 'g')
tcs += cs.text
}
return tcs.replace(sel ? abc2svg.cs_sel1 : abc2svg.cs_sel0, '')
} // cs_filter()
// font weight
// reference:
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
abc2svg.ft_w = {
thin: 100,
extralight: 200,
light: 300,
|
| ︙ | | |
| ︙ | | |
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
-
|
gmark: "3 grm 6 5 5",
wedge: "0 wedge 8 3 3", // (staccatissimo or spiccato)
longphrase: "3 lphr 0 1 1",
mediumphrase: "3 mphr 0 1 1",
shortphrase: "3 sphr 0 1 1",
turnx: "3 turnx 5,5 6 6",
invertedturn: "3 turn 5,5 6 6",
invertedturnx: "3 turnx 5,5 6 6",
"0": "3 fng 5,5 3 3 0",
"1": "3 fng 5,5 3 3 1",
"2": "3 fng 5,5 3 3 2",
"3": "3 fng 5,5 3 3 3",
"4": "3 fng 5,5 3 3 4",
"5": "3 fng 5,5 3 3 5",
plus: "3 dplus 7 3 3",
|
| ︙ | | |
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
-
+
-
+
-
-
-
-
+
+
+
+
|
dacoda: "5 dacs 16 20 20 Da Coda",
"D.C.": "5 dcap 16 10 10",
"D.S.": "5 dsgn 16 10 10",
"D.C.alcoda": "5 dacs 16 38 38 D.C. al Coda",
"D.S.alcoda": "5 dacs 16 38 38 D.S. al Coda",
"D.C.alfine": "5 dacs 16 38 38 D.C. al Fine",
"D.S.alfine": "5 dacs 16 38 38 D.S. al Fine",
fermata: "5 hld 12 7 7",
fermata: "3 hld 12 7 7",
fine: "5 dacs 16 10 10 Fine",
invertedfermata: "7 hld 12 7 7",
invertedfermata: "4 hld 12 7 7",
segno: "5 sgno 22 8 8",
f: "6 f 18 4 4",
ff: "6 ff 18 6 6",
fff: "6 fff 18 9 9",
ffff: "6 ffff 18 12 12",
mf: "6 mf 18 9 9",
mp: "6 mp 18 10 10",
p: "6 p 18 5 5",
pp: "6 pp 18 9 9",
ppp: "6 ppp 18 13 13",
pppp: "6 pppp 18 17 17",
pralltriller: "3 umrd 4,4 5 5",
sfz: "6 sfz 18 8 8",
ped: "4 ped 18 6 10",
"ped-up": "4 pedoff 12 4 4",
"ped(": "4 lped 20 5 5",
"ped)": "4 lped 20 5 5",
ped: "7 ped 18 6 10",
"ped-up": "7 pedoff 12 4 4",
"ped(": "7 lped 20 5 5",
"ped)": "7 lped 20 5 5",
"crescendo(": "6 cresc 18 0 0",
"crescendo)": "6 cresc 18 0 0",
"<(": "6 cresc 18 0 0",
"<)": "6 cresc 18 0 0",
"diminuendo(": "6 dim 18 0 0",
"diminuendo)": "6 dim 18 0 0",
">(": "6 dim 18 0 0",
|
| ︙ | | |
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
-
-
-
+
+
+
+
|
function up3(s, pos) {
switch (pos & 0x07) {
case C.SL_ABOVE:
return 1 // true
case C.SL_BELOW:
return 0 // false
}
if (s.multi)
return s.multi > 0
return 1 // true
// if (s.multi)
// return s.multi > 0
// return 1 // true
return !s.second
} // up3()
// - of the dynamic and volume marks
function up6(s, pos) {
switch (pos & 0x07) {
case C.SL_ABOVE:
return true
|
| ︙ | | |
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
|
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
|
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
|
else if (dd.ty == '_')
up = 0
else if (s.multi)
up = s.multi > 0
else
up = s.stem < 0
y = up ? s.ymx : s.ymn
if (y > -6 && y < 30) {
if (y > 0 && y < 24) {
y = (((y + 9) / 6) | 0) * 6 - 6 // between lines
}
if (up) {
y += dd.hd
s.ymx = y + dd.h
} else if (dd.name[0] == 'w') { // wedge (no descent)
de.inv = true
y -= dd.h
s.ymn = y
} else {
y -= dd.h
s.ymn = y - dd.hd
}
de.y = y
if (s.type == C.NOTE)
de.x += s.notes[s.stem >= 0 ? 0 : s.nhd].shhd
if (dd.name[0] == 'd' /* if dot decoration */
&& s.nflags >= -1) { /* on stem */
if (dd.name[0] == 'd') { // if dot (staccato)
if (!(s.beam_st && s.beam_end)) { // if in a beam sequence
if (up) {
if (s.stem > 0)
de.x += 3.5 // stem_xoff
} else {
if (s.stem < 0)
de.x -= 3.5
}
} else {
if (up && s.stem > 0) {
y = s.y + (y - s.y) * .6
if (y >= 27) {
de.y = y // put the dot a bit lower
s.ymx = de.y + dd.h
}
}
}
}
}
/* 6: dynamic marks */
function d_pf(de) {
var dd2, x2, x, up,
s = de.s,
|
| ︙ | | |
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
|
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
|
-
+
|
if (x2 > x)
x = x2
}
}
}
de.x = x;
de.y = y_get(s.st, up, x, de.val)
de.y = y_get(s.st, up, x - dd.wl, de.val)
if (!up)
de.y -= dd.h
else
de.y += dd.hd
/* (y_set is done later in draw_deco_staff) */
}
|
| ︙ | | |
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
|
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
|
-
-
|
|| dd.glyph == "accent"
|| dd.glyph == "roll")
de.inv = 1
s.ymn = y - dd.hd
}
}
if (dd.func != 6) { // if not d_pf
if (y >= stafft)
y_set(s.st, 1, x - dd.wl, w, y + dd.h)
else if (y <= staffb)
y_set(s.st, 0, x - dd.wl, w, y - dd.hd)
}
de.x = x;
de.y = y
}
// add a decoration
/* syntax:
|
| ︙ | | |
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
|
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
|
-
+
-
-
-
-
+
+
+
|
if (dd)
return dd
if ("<>^_@".indexOf(nm[0]) >= 0 // if position
&& !/^([>^]|[<>]\d?[()])$/.test(nm)) {
ty = nm[0]
if (ty == '@') {
p = nm.match(/@([-\d]+),([-\d]+)/)
if (!p) {
if (p)
error(1, s, "Bad position in !$1!", nm)
return
}
ty = p[0]
ty = p[0]
else
ty = '' // accept decorations starting with '@'
}
dd = deco_def(nm, nm.replace(ty, ''))
} else {
dd = deco_def(nm)
}
if (!dd)
return
|
| ︙ | | |
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
|
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
|
-
+
|
ix: a_de.length,
defl: {},
x: x,
y: y,
pos: pos
// dy: 0
}
if (dd.name.indexOf("invert") == 0)
if (dd.name.indexOf("inverted") >= 0)
de.inv = 1
if (s.type == C.BAR && !dd.ty)
de.x -= s.wl / 2 - 2
a_de.push(de)
if (dd.dd_en) {
de.ldst = true
} else if (dd.dd_st) {
|
| ︙ | | |
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
|
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
|
-
+
|
create_dh(s, m)
}
}
} // create_all()
// link the long decorations
function ll_deco() {
var i, j, de, de2, dd, dd2, v, s, st,
var i, j, de, de2, de3, dd, dd2, v, s, st,
n_de = a_de.length
// add ending decorations
for (i = 0; i < n_de; i++) {
de = a_de[i]
if (!de.ldst) // not the start of long decoration
continue
|
| ︙ | | |
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
|
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
|
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
|
if (de.m != undefined)
de2.m = de.m;
a_de.push(de2)
}
de2.start = de;
de2.defl.nost = de.defl.nost
// handle same numbered decoration at a same time
j = dd.name.slice(-1)
if (j >= '0' && j <= '9'
&& i > 0
&& a_de[i - 1].s.time == de.s.time
// handle same decoration ending at a same time
j = i
while (--j >= 0) {
de3 = a_de[j]
if (!de3.start)
continue
if (de3.s.time < s.time)
&& a_de[i - 1].dd.name.slice(0, -2) ==
dd.name.slice(0, -2))
de2.prev = a_de[i - 1]
break
if (de3.dd.name == de2.dd.name) {
de2.prev = de3
break
}
}
}
// add starting decorations
for (i = 0; i < n_de; i++) {
de2 = a_de[i]
if (!de2.lden // not the end of long decoration
|| de2.start) // start already found
|
| ︙ | | |
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
|
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
|
-
+
|
nd = a_de.length
/* draw the repeat brackets */
function draw_repbra(p_voice) {
var s, s1, x, y, y2, i, p, w, wh, first_repeat;
// search the max y offset of the line
y = staff_tb[p_voice.st].topbar + 25 // 20 (vert bar) + 5 (room)
y = staff_tb[p_voice.st].topbar + 15 // 10 (vert bar) + 5 (room)
for (s = p_voice.sym; s; s = s.next) {
if (s.type != C.BAR)
continue
if (!s.rbstart || s.norepbra)
continue
/*fixme: line cut on repeat!*/
if (!s.next)
|
| ︙ | | |
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
|
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
|
-
+
-
+
|
}
y2 = y_get(p_voice.st, true, s1.x, s.x - s1.x) + 2
if (y < y2)
y = y2
// have room for the vertical lines and the repeat numbers
if (s1.rbstart == 2) {
y2 = y_get(p_voice.st, true, s1.x, 3) + 20
y2 = y_get(p_voice.st, true, s1.x, 3) + 10
if (y < y2)
y = y2
}
if (s.rbstop == 2) {
y2 = y_get(p_voice.st, true, s.x - 3, 3) + 20
y2 = y_get(p_voice.st, true, s.x - 3, 3) + 10
if (y < y2)
y = y2
}
if (s1.text) {
wh = strwh(s1.text);
y2 = y_get(p_voice.st, true, s1.x + 4, wh[0]) +
wh[1]
|
| ︙ | | |
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
|
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
|
-
+
-
+
-
+
-
+
-
+
|
w = 12
else if (s.bar_type[0] != ':')
// || s.bar_type == "]")
w = 0 /* explicit repeat end */
else
w = 8
} else {
w = s.rbstop ? 0 : 8
w = (s.rbstop && !s.rbstart) ? 0 : 8
}
w = (s.x - x - w) // / staff_tb[p_voice.st].staffscale;
if (!s.next // 2nd ending at end of line
&& !s.rbstop
&& !p_voice.bar_start) { // continue on next line
p_voice.bar_start = _bar(s)
p_voice.bar_start.bar_type = ""
p_voice.bar_start.rbstart = 1
}
if (s1.text)
xy_str(x + 4, y2 - gene.curfont.size - 3,
xy_str(x + 4, y2 - gene.curfont.size,
s1.text);
xypath(x, y2);
if (s1.rbstart == 2)
output += 'm0 20v-20';
output += 'm0 10v-10';
output+= 'h' + w.toFixed(1)
if (s.rbstop == 2)
output += 'v20';
output += 'v10';
output += '"/>\n';
y_set(s1.st, true, x, w, y + 2)
if (s.rbstart)
s = s.prev
s = s.prev.prev
}
} // draw_repbra()
/* create the decorations tied to the staves */
for (i = 0; i <= nstaff; i++)
minmax[i] = {
ymin: 0,
|
| ︙ | | |
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
|
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
|
-
+
|
}
draw_all_chsy() // draw all chord symbols
/* draw the repeat brackets */
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (p_voice.second || !p_voice.sym)
if (p_voice.second || !p_voice.sym || p_voice.ignore)
continue
draw_repbra(p_voice)
}
}
/* -- draw the measure bar numbers -- */
/* (scaled delayed output) */
|
| ︙ | | |
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
|
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
|
-
+
|
bar_num = gene.nbar
if (bar_num > 1) {
if (cfmt.measurenb == 0) {
any_nb = true;
y = y_get(st, true, 0, 20)
if (y < staff_tb[st].topbar + 14)
y = staff_tb[st].topbar + 14;
xy_str(0, y, bar_num.toString());
xy_str(0, y - gene.curfont.size * .2, bar_num.toString())
y_set(st, true, 0, 20, y + gene.curfont.size + 2)
} else if (bar_num % cfmt.measurenb == 0) {
for ( ; ; s = s.ts_next) {
switch (s.type) {
case C.CLEF:
case C.KEY:
case C.METER:
|
| ︙ | | |
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
|
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
|
-
-
+
+
-
-
+
+
|
if (s.type != C.BAR || !s.bar_num) {
any_nb = true;
w = w0
if (bar_num >= 10)
w *= bar_num >= 100 ? 3 : 2
if (gene.curfont.pad)
w += gene.curfont.pad * 2
x = s.x - s.wl + 2 // if clef, shift a bit
y = y_get(st, true, x, w)
x = s.x - s.wl - w
y = y_get(st, true, x, w) + 5
if (y < staff_tb[st].topbar + 6)
y = staff_tb[st].topbar + 6;
y += 2 + gene.curfont.pad
xy_str(x, y, bar_num.toString())
y += gene.curfont.pad
xy_str(x, y - gene.curfont.size * .2, bar_num.toString())
y += gene.curfont.size + gene.curfont.pad
y_set(st, true, x, w, y);
// s.ymx = y
}
}
}
|
| ︙ | | |
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
|
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
|
-
+
|
y = s.next.ys - gene.curfont.size
} else {
if (y < s.next.y)
y = s.next.y
}
}
y += 2 + gene.curfont.pad
xy_str(x, y, bar_num.toString())
xy_str(x, y - gene.curfont.size * .2, bar_num.toString())
y += gene.curfont.size + gene.curfont.pad
y_set(st, true, x, w, y);
// s.ymx = y
}
gene.nbar = bar_num
if (font_size)
|
| ︙ | | |
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
|
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
|
-
-
|
s.ymn = (dosh & 1) ? h : y;
s.ymx = s.ymn + 14;
anno_start(s)
}
writempo(s, s.x - 16, (dosh & 1) ? h : y);
anno_stop(s);
dosh >>= 1
while (s.ts_next && s.ts_next.type == C.TEMPO)
s = s.ts_next
}
}
/* then, put the parts */
/*fixme: should reduce vertical space if parts don't overlap tempo...*/
ymin = staff_tb[st].topbar + 6
for (s = tsfirst; s; s = s.ts_next) {
|
| ︙ | | |
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
|
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
|
-
+
|
s2.v = s.v
s2.st = s2.wl = 0
s2.wr = strwh(s2.text)[0]
s2.ymn = -ht
s2.ymx = s2.ymn + h
anno_start(s2)
}
xy_str(s2.x, 2 - ht, s2.text)
xy_str(s2.x, 2 - ht + gene.curfont.size * .22, s2.text)
anno_stop(s2)
}
}
return dy /= staff_tb[0].staffscale
}
|
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - draw.js - draw functions
//
// Copyright (C) 2014-2022 Jean-Francois Moine
// Copyright (C) 2014-2023 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
-
+
|
STEM_CH_MIN = 14, /* min stem height for chords under beams */
STEM_CH_MIN2 = 10, /* ... for notes with two beams */
STEM_CH_MIN3 = 9, /* ... for notes with three beams */
STEM_CH_MIN4 = 9, /* ... for notes with four beams */
BEAM_DEPTH = 3.2, /* width of a beam stroke */
BEAM_OFFSET = .25, /* pos of flat beam relative to staff line */
BEAM_SHIFT = 5, /* shift of second and third beams */
BEAM_STUB = 8, /* length of stub for flag under beam */
BEAM_STUB = 7, /* length of stub for flag under beam */
SLUR_SLOPE = .5, /* max slope of a slur */
GSTEM = 15, /* grace note stem length */
GSTEM_XOFF = 2.3 /* x offset for grace note stem */
var cache,
anno_a = [] // symbols with annotations
|
| ︙ | | |
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
+
+
-
+
|
/* have room for the symbols in the staff */
max_stem_err = 0; /* check stem lengths */
s = s1
if (two_dir) { /* 2 directions */
/*fixme: more to do*/
ys = ((s1.grace ? 3.5 : BEAM_SHIFT) * (nflags - 1) +
BEAM_DEPTH) * .5
if (s1.nflags == s2.nflags)
;
if (s1.stem != s2.stem && s1.nflags < s2.nflags)
else if (s1.stem != s2.stem && s1.nflags < s2.nflags)
b += ys * s2.stem
else
b += ys * s1.stem
} else if (!s1.grace) { /* normal notes */
var beam_h = BEAM_DEPTH + BEAM_SHIFT * (nflags - 1)
//--fixme: added for abc2svg
while (s.ts_prev
|
| ︙ | | |
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
+
+
|
/* have room for the gracenotes, bars and clefs */
/*fixme: test*/
if (!two_staves && !two_dir)
for (s = s1.next; ; s = s.next) {
switch (s.type) {
case C.REST: /* cannot move rests in multi-voices */
if (!s.multi)
break
g = s.ts_next
if (!g || g.st != st
|| (g.type != C.NOTE && g.type != C.REST))
break
//fixme:too much vertical shift if some space above the note
//fixme:this does not fix rest under beam in second voice (ts_prev)
/*fall thru*/
|
| ︙ | | |
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
|
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
|
-
+
+
+
+
+
+
-
-
+
+
+
-
+
|
bm.nflags = nflags
return true
}
/* -- draw the beams for one word -- */
/* (the staves are defined) */
function draw_beams(bm) {
var s, i, beam_dir, shift, bshift, bstub, bh, da,
var s, i, beam_dir, shift, bshift, bstub, bh, da, bd,
k, k1, k2, x1,
s1 = bm.s1,
s2 = bm.s2
/* -- draw a single beam -- */
function draw_beam(x1, x2, dy, h, bm,
n) { /* beam number (1..n) */
var y1, dy2,
s = bm.s1,
nflags = s.nflags
if (s.ntrem)
nflags -= s.ntrem
if (s.trem2 && n > nflags) {
if (s.dur >= C.BLEN / 2) {
x1 = s.x + 6;
x2 = bm.s2.x - 6
} else if (s.dur < C.BLEN / 4) {
var dx = x2 - x1
if (dx < 16) {
x1 += dx / 4
x2 -= dx / 4
} else {
x1 += 5;
x2 -= 6
x1 += 5
x2 -= 6
}
}
}
y1 = bm.a * x1 + bm.b - dy;
x2 -= x1;
x2 /= stv_g.scale;
dy2 = bm.a * x2
dy2 = bm.a * x2 * stv_g.scale
xypath(x1, y1, true);
output += 'l' + x2.toFixed(1) + ' ' + (-dy2).toFixed(1) +
'v' + h.toFixed(1) +
'l' + (-x2).toFixed(1) + ' ' + dy2.toFixed(1) +
'z"/>\n'
} // draw_beam()
|
| ︙ | | |
501
502
503
504
505
506
507
508
509
510
511
512
513
514
|
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
|
+
|
bh = BEAM_DEPTH
} else {
bshift = 3.5;
bstub = 3.2;
shift = .29;
bh = 1.8
}
bh /= stv_g.scale
/*fixme: quick hack for stubs at end of beam and different stem directions*/
beam_dir = s1.stem
if (s1.stem != s2.stem
&& s1.nflags < s2.nflags)
beam_dir = s2.stem
if (beam_dir < 0)
|
| ︙ | | |
580
581
582
583
584
585
586
587
588
589
590
591
592
593
|
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
|
+
|
break
s = k
}
k2 = s
while (k2.type != C.NOTE)
k2 = k2.prev;
x1 = k1.xs
bd = beam_dir
if (k1 == k2) {
if (k1 == s1) {
x1 += bstub
} else if (k1 == s2) {
x1 -= bstub
} else if (k1.beam_br1
|| (k1.beam_br2
|
| ︙ | | |
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
|
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
|
+
+
+
+
-
+
+
-
+
|
|| (k1.nflags == k.nflags
&& k1.dots < k.dots))
x1 += bstub
else
x1 -= bstub
}
}
if (k1.stem != beam_dir) {
bd = k1.stem
k1.ys = bm.a * k1.xs + bm.b
- staff_tb[k1.st].y - bh
}
}
}
draw_beam(x1, k2.xs,
shift * beam_dir,
shift * bd,
bh, bm, i)
if (s == s2)
break
}
}
if (s1.tmp)
unlksym(s1)
|
| ︙ | | |
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
|
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
|
flat2 = new Int8Array([-12, 9, -12, 9, -12, 9])
Abc.prototype.draw_keysig = function(x, s) {
var old_sf = s.k_old_sf,
st = s.st,
staffb = staff_tb[st].y,
i, shift, p_seq,
clef_ix = s.k_y_clef
clef_ix = s.k_y_clef,
a_acc = s.k_a_acc // accidental list [pit, acc]
// set the accidentals when K: with modified accidentals
function set_k_acc(a_acc, sf) {
var i, j, n, nacc, p_acc,
accs = [],
pits = []
if (sf > 0) {
for (nacc = 0; nacc < sf; nacc++) {
accs[nacc] = 1 // sharp
pits[nacc] = [26, 23, 27, 24, 21, 25, 22][nacc]
}
} else {
for (nacc = 0; nacc < -sf; nacc++) {
accs[nacc] = -1 // flat
pits[nacc] = [22, 25, 21, 24, 20, 23, 26][nacc]
}
}
n = a_acc.length
for (i = 0; i < n; i++) {
p_acc = a_acc[i]
for (j = 0; j < nacc; j++) {
if (pits[j] == p_acc.pit) {
accs[j] = p_acc.acc
break
}
}
if (j == nacc) {
accs[j] = p_acc.acc
pits[j] = p_acc.pit
nacc++
}
}
for (i = 0; i < nacc; i++) {
p_acc = a_acc[i]
if (!p_acc)
p_acc = a_acc[i] = {}
p_acc.acc = accs[i]
p_acc.pit = pits[i]
}
} // set_k_acc()
// ---- draw_keysig ---
if (clef_ix & 1)
clef_ix += 7;
clef_ix /= 2
while (clef_ix < 0)
clef_ix += 7;
clef_ix %= 7
/* normal accidentals */
if (a_acc && !s.exp) // if added accidentals
set_k_acc(a_acc, s.k_sf) // merge them into the key
if (!s.k_a_acc) {
if (!a_acc) {
/* put neutrals if 'accidental cancel' */
if (s.fmt.cancelkey || s.k_sf == 0) {
/* when flats to sharps, or sharps to flats, */
if (s.k_sf == 0
|| old_sf * s.k_sf < 0) {
|
| ︙ | | |
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
|
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
|
+
+
+
+
-
+
-
+
-
-
+
+
|
x += 2
for (; i < old_sf; i++) {
xygl(x, staffb + shift, "acc3");
shift += p_seq[i];
x += 5.5
}
}
if (s.k_bagpipe == 'p') { // K:Hp - add the g natural
xygl(x, staffb + 27, "acc3")
x += 5.5
}
}
/* new flats */
if (s.k_sf < 0) {
shift = flat_cl[clef_ix];
p_seq = shift < 18 ? flat1 : flat2
for (i = 0; i > s.k_sf; i--) {
xygl(x, staffb + shift, "acc-1");
shift += p_seq[-i];
x += 5.5
}
if (s.fmt.cancelkey && i > old_sf) {
x += 2
for (; i > old_sf; i--) {
xygl(x, staffb + shift, "acc3");
shift += p_seq[-i];
x += 5.5
}
}
}
} else if (s.k_a_acc.length) {
} else if (a_acc.length) {
/* explicit accidentals */
var acc,
last_acc = s.k_a_acc[0].acc,
last_acc = a_acc[0].acc,
last_shift = 100,
s2 = {
st: st,
nhd: 0,
notes: [{}]
}
for (i = 0; i < s.k_a_acc.length; i++) {
acc = s.k_a_acc[i];
for (i = 0; i < a_acc.length; i++) {
acc = a_acc[i];
shift = (s.k_y_clef // clef shift
+ acc.pit - 18) * 3
while (shift < -3) // let the accidentals inside the staff
shift += 21
while (shift > 27)
shift -= 21
if (i != 0
|
| ︙ | | |
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
|
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
|
-
+
+
+
+
+
+
+
+
+
-
+
-
+
|
set_color();
anno_a.push(s)
}
// -- draw a multi-measure rest --
// (the staves are defined)
function draw_mrest(s) {
var x1, x2,
var x1, x2, prev,
p_st = staff_tb[s.st],
y = p_st.y + (p_st.topbar + p_st.botbar) / 2,
p = s.nmes.toString()
if (!s.next) {
error(1, s, "Lack of bar after multi-measure rest")
return
}
set_scale(s)
prev = s // search the start of the previous time sequence
while (!prev.seqst)
prev = prev.ts_prev
prev = prev.ts_prev
while (!prev.seqst)
prev = prev.ts_prev
x1 = s.prev.x + 20
x1 = prev.x + 20
x2 = s.next.x - 20
s.x = (x1 + x2) / 2
anno_start(s)
out_XYAB('<path d="mX Y', x1 + .6, y - 2.7)
output += 'v2.7h-1.4v-10.8h1.4v2.7h'
+ (x2 - x1 - 2.8).toFixed(1)
+ ((x2 - x1 - 2.8) / stv_g.scale).toFixed(1)
+ 'v-2.7h1.4v10.8h-1.4v-2.7z"/>\n'
out_XYAB('<text x ="X" y="Y" text-anchor="middle">A</text>\n',
s.x, y + 22, m_gl(p))
anno_a.push(s)
} // draw_mrest()
function grace_slur(s) {
|
| ︙ | | |
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
|
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
|
-
-
+
+
|
}
// draw a slur between two chords / notes
/* (the staves are not yet defined) */
/* (delayed output) */
/* (not a pretty routine, this) */
function draw_slur(path, // list of symbols under the slur
not1, // note if start on a note head
sl) { // ending variables: type, note, end on a note
sl) { // slur variables: type, end symbol, note
var i,
k, g, x1, y1, x2, y2, height, addy,
a, y, z, h, dx, dy,
ty = sl.ty,
dir = (ty & 0x07) == C.SL_ABOVE ? 1 : -1,
n = path.length,
i1 = 0,
i2 = n - 1,
not1 = sl.nts, // if the slur start on a note
k1 = path[0],
k2 = path[i2]
/*fixme: if two staves, may have upper or lower slur*/
var nn = 1,
upstaff = k1.st,
|
| ︙ | | |
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
|
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
|
-
-
+
+
|
} else {
y1 = k1.y - 8
}
}
}
}
if (sl.is_note) { // end on a note
y2 = 3 * (sl.note.pit - 18) + 2 * dir
if (sl.nte) { // slur ending on a note
y2 = 3 * (sl.nte.pit - 18) + 2 * dir
x2 -= 3
} else { // end on a chord
y2 = dir > 0 ? k2.ymx + 2 : k2.ymn - 2
if (k2.type == C.NOTE) {
if (dir > 0) {
if (k2.stem > 0) {
x2 += 1
|
| ︙ | | |
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
|
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
|
-
+
|
y = a * k.x + addy
if (k.ymx < y)
k.ymx = y
else if (k.ymn > y)
k.ymn = y
if (i == i2 - 1) {
dx = x2
if (k2.sl1)
if (sl.nte)
dx -= 5;
if (i)
y -= height / 3
} else {
dx = path[i + 1].x
}
if (i != 0)
|
| ︙ | | |
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
|
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
|
-
+
-
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
|
/* -- draw the slurs between 2 symbols --*/
function draw_slurs(s, last) {
var gr1, i, m, note, sls, nsls
// draw a slur knowing the start and stop elements
function draw_sls(s, // start symbol
sl, // stop note
sl) { // slur variables
snote) { // optional start note
var k, v, i, dir,
var k, v, i, dir, s3,
path = [],
enote = sl.note,
s2 = sl.se // slur end
s2 = enote.s // end of slur
if (last && s2.time > last.time)
return // will be drawn next time
// handle slurs without start or end
switch (sl.loc) {
case 'i': // no start
s3 = s.ts_prev
for (s = s3; s; s = s.ts_prev) {
if (s.dur) {
if (s.v == s2.v) {
s3 = s
break
}
if (s.st == s2.st) {
s3 = s
continue
} else if (!s3) {
s3 = s
}
} else if (!s3) {
s3 = s
}
}
s = s3
break
case 'o': // no end
for (s3 = s; s3.ts_next; s3 = s3.ts_next)
;
s2 = s3
for (; s3; s3 = s3.ts_prev) {
if (s3.v == s.v) {
s2 = s3
break
}
if (s3.st == s.st)
s2 = s3
if (s3.ts_prev.time != s2.time)
break
}
break
}
// if the slur continues on the next music line,
// stop it on the invisible bar at end of current line
// stop it at the end of the current line
if (tsnext && s2.time >= tsnext.time) {
if (s2.grace && s2.time == tsnext.time) {
for (s3 = tsnext; s3 && s3.time == s2.time; s3 = s3.ts_next) {
if (s3.type == C.GRACE)
//fixme: check if s2 in the grace notes
break
}
if (s3.type == C.GRACE)
s3 = null
}
if (!s2.grace || s2.time == tsnext.time || !s3) {
s.p_v.sls.push(sl); // continuation on next line
s2 = s.p_v.s_next.prev // one voice
while (s2.next)
s2 = s2.next; // search the ending bar
sl = Object.create(sl); // new slur
sl.note = {
s: s2
}
}
}
// set the slur position
switch (sl.ty & 0x07) {
case C.SL_ABOVE: dir = 1; break
case C.SL_BELOW: dir = -1; break
default:
|
| ︙ | | |
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
|
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
|
-
+
+
|
s = s.next
else
s = s.ts_next
}
if (!s2.grace) { // if end on a normal note
while (s) {
if (s.v == v)
if (s.v == v
&& !s.invis)
path.push(s)
if (s == s2)
break
s = s.ts_next
}
} else if (s.grace) { // if start/end in the same sequence
while (1) {
|
| ︙ | | |
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
|
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
|
-
+
-
+
|
s = s.next
}
}
// if some nested slurs/tuplets, draw them
for (i = 1; i < path.length - 1; i++) {
s = path[i]
if (s.sls || s.sl1)
if (s.sls)
draw_slurs(s, last)
if (s.tp)
draw_tuplet(s)
}
draw_slur(path, snote, sl)
draw_slur(path, sl)
return 1 // slur drawn, remove it
} // draw_sls()
// code of draw_slurs()
while (1) {
if (!s || s == last) {
if (!gr1 // if end of grace notes
|
| ︙ | | |
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
|
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
+
-
+
|
for (i = 0; i < sls.length; i++) {
if (!draw_sls(s, sls[i]))
nsls.push(sls[i])
}
if (nsls.length)
s.sls = nsls
}
if (s.sl1) { // slurs from the note heads
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m]
if (note.sls) {
sls = note.sls
note.sls = null
nsls = []
for (i = 0; i < sls.length; i++) {
if (!draw_sls(s, sls[i], note))
nsls.push(sls[i])
}
if (nsls.length)
note.sls = nsls
}
}
}
s = s.next
}
}
/* -- draw a tuplet -- */
/* (the staves are not yet defined) */
/* (delayed output) */
/* See http://moinejf.free.fr/abcm2ps-doc/tuplets.html
* for the value of 'tp.f' */
function draw_tuplet(s1) {
var s2, s3, g, upstaff, nb_only,
x1, x2, y1, y2, xm, ym, a, s0, yy, yx, dy, a, dir, r, w,
x1, x2, y1, y2, xm, ym, a, s0, yy, yx, dy, a, dir, r,
tp = s1.tp.shift() // tuplet parameters
if (!s1.tp.length)
delete s1.tp // last tuplet
// treat the slurs and the nested tuplets
upstaff = s1.st
set_dscale(s1.st)
for (s2 = s1; s2; s2 = s2.next) {
switch (s2.type) {
case C.GRACE:
if (!s2.sl1)
continue
for (g = s2.extra; g; g = g.next) {
if (g.sls || g.sl1)
if (g.sls)
draw_slurs(g)
}
// fall thru
default:
continue
case C.NOTE:
case C.REST:
break
}
if (s2.sls || s2.sl1)
if (s2.sls)
draw_slurs(s2)
if (s2.st < upstaff)
upstaff = s2.st
if (s2.tp)
draw_tuplet(s2)
if (s2.tpe)
break
|
| ︙ | | |
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
|
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
|
-
+
-
+
-
+
|
error(1, s1, "No end of tuplet in this music line")
return
}
dir = tp.f[3] // 'where'
if (!dir) { // if auto
s3 = s1
while (s3.type != C.NOTE)
while (s3 && !s3.stem) // (may have tuplets of rests!)
s3 = s3.next
dir = s3.stem > 0 ? C.SL_ABOVE : C.SL_BELOW
dir = (s3 && s3.stem < 0) ? C.SL_BELOW : C.SL_ABOVE
}
if (s1 == s2 // tuplet with 1 note (!)
|| tp.f[1] == 2) { // what == nothing
nb_only = true
} else if (tp.f[1] == 1) { /* 'what' == slur */
nb_only = true;
draw_slur([s1, s2], null, {ty: dir})
draw_slur([s1, s2], {ty: dir})
} else {
/* search if a bracket is needed */
if (tp.f[0] != 2 // if 'when' != always
&& s1.type == C.NOTE && s2.type == C.NOTE) {
nb_only = true
for (s3 = s1; ; s3 = s3.next) {
|
| ︙ | | |
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
|
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
|
+
|
a = s0
} else {
if (a > 0)
a = 0
else if (a < s0)
a = s0
}
a = s1.fmt.beamslope * a / (s1.fmt.beamslope + Math.abs(a))
if (a * a < .1 * .1)
a = 0
/* shift up bracket if needed */
dy = 0
for (s3 = s1; ; s3 = s3.next) {
if (!s3.dur /* not a note or a rest */
|
| ︙ | | |
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
|
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
|
-
-
+
|
/* shift the slurs / decorations */
ym += 6
for (s3 = s1; ; s3 = s3.next) {
if (s3.st == upstaff) {
yy = ym + (s3.x - xm) * a
if (s3.ymx < yy)
s3.ymx = yy
w = s3.next.x - s3.x - 10
y_set(upstaff, true, s3.x - w, w * 2, yy)
y_set(upstaff, true, s3.x - 3, 6, yy)
}
if (s3 == s2)
break
}
// below
} else { /* lower voice of the staff: the bracket is below the staff */
|
| ︙ | | |
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
|
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
|
-
-
-
+
|
/* shift the slurs / decorations */
ym -= 2
for (s3 = s1; ; s3 = s3.next) {
if (s3.st == upstaff) {
yy = ym + (s3.x - xm) * a
if (s3.ymn > yy)
s3.ymn = yy;
w = s3.next.x - s3.x - 10
if (s3.next)
y_set(upstaff, false, s3.x - w, w * 2, yy)
y_set(upstaff, false, s3.x - 3, 6, yy)
}
if (s3 == s2)
break
}
} /* lower voice */
if (tp.f[2] == 1) { /* if 'which' == none */
|
| ︙ | | |
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
|
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
|
-
-
+
|
/* -- draw the symbols near the notes -- */
/* (the staves are not yet defined) */
/* order:
* - scaled
* - beams
* - decorations near the notes
* - measure bar numbers
* - decorations tied to the notes
* - tuplets and slurs
* - not scaled
* - measure numbers
* - lyrics
* - staff decorations
* - chord symbols
* - repeat brackets
* The buffer output is delayed until the definition of the staff system
*/
function draw_sym_near() {
var p_voice, p_st, s, v, st, y, g, w, i, st, dx, top, bot, ymn, slur,
var p_voice, p_st, s, v, st, y, g, w, i, st, dx, top, bot, ymn,
output_sav = output;
// set the staff offsets of a beam
function set_yab(s1, s2) {
var y,
k = realwidth / YSTEP,
i = (s1.x / k) | 0,
|
| ︙ | | |
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
|
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
|
-
-
-
-
+
|
var bm = {},
first_note = true;
p_voice = voice_tb[v]
for (s = p_voice.sym; s; s = s.next) {
switch (s.type) {
case C.GRACE:
slur = 0
for (g = s.extra; g; g = g.next) {
if (g.beam_st && !g.beam_end) {
self.calculate_beam(bm, g)
if (bm.s2)
set_yab(g, bm.s2)
}
if (g.sls || g.sl1)
slur++
}
if (!s.p_v.ckey.k_bagpipe // no slur when bagpipe
&& s.fmt.graceslurs
&& !s.gr_shift // tied to previous note
&& !slur // explicit slur
&& !s.sl1 // explicit slur
&& !s.ti1 // some tie
&& s.next
&& s.next.type == C.NOTE)
grace_slur(s)
break
}
}
|
| ︙ | | |
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
|
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
|
-
-
-
-
+
+
+
+
-
-
-
+
+
-
-
-
+
-
-
-
+
|
}
dx += s.notes[0].shhd;
y_set(s.st, false, s.x + dx, w, s.ymn)
}
/* have room for the accidentals */
if (s.notes[s.nhd].acc) {
y = s.y + 8
if (s.ymx < y)
s.ymx = y;
y_set(s.st, true, s.x, 0, y)
y = 3 * (s.notes[s.nhd].pit - 18)
+ (s.notes[s.nhd].acc == -1 // flat
? 11 : 10)
y_set(s.st, true, s.x - 10, 10, y)
}
if (s.notes[0].acc) {
y = s.y
if (s.notes[0].acc == 1 // sharp
|| s.notes[0].acc == 3) // natural
y = 3 * (s.notes[0].pit - 18)
- (s.notes[0].acc == -1 // flat
y -= 7
else
y -= 5
? 5 : 10)
if (s.ymn > y)
s.ymn = y;
y_set(s.st, false, s.x, 0, y)
y_set(s.st, false, s.x - 10, 10, y)
}
}
draw_deco_note()
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
|
| ︙ | | |
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
|
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
|
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
|
set_dscale(-1);
output = output_sav
}
/* -- draw the name/subname of the voices -- */
function draw_vname(indent, stl) {
var p_voice, n, st, v, a_p, p, y, name_type, h, h2,
var p_voice, n, st, v, a_p, p, y, h, h2,
staff_d = []
for (st = stl.length; st >= 0; st--) {
if (stl[st])
break
}
if (st < 0)
return
// check if full or sub names
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (!p_voice.sym || !cur_sy.voices[v])
if (!cur_sy.voices[v])
continue
st = cur_sy.voices[v].st
if (!stl[st])
continue
if (p_voice.new_name) {
name_type = 2
break
}
if (p_voice.snm)
name_type = 1
}
if (!name_type)
return
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (!p_voice.sym || !cur_sy.voices[v])
continue
st = cur_sy.voices[v].st
if (!stl[st])
if (!gene.vnt)
continue
if (p_voice.new_name)
delete p_voice.new_name;
p = name_type == 2 ? p_voice.nm : p_voice.snm
p = gene.vnt == 2 ? p_voice.nm : p_voice.snm
if (!p)
continue
delete p_voice.new_name
if (!staff_d[st])
staff_d[st] = p
else
staff_d[st] += "\n" + p
}
if (!staff_d.length)
return
|
| ︙ | | |
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
|
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
|
-
-
-
-
-
+
-
+
+
+
+
|
y = val
}
// }
/* draw the parts and tempo indications if any */
y += draw_partempo(st, y)
if (!gene.st_print[st]) {
p_staff.y = -y
return y
}
/* set the vertical offset of the 1st staff */
y *= p_staff.staffscale;
staffsep = fmt.staffsep * .5 +
p_staff.topbar * p_staff.staffscale
if (y < staffsep)
y = staffsep
if (y < p_staff.ann_top) // absolute annotation
y = p_staff.ann_top;
p_staff.y = -y;
/* set the offset of the other staves */
for (prev_staff = 0; prev_staff < st; prev_staff++)
prev_staff = st
staff_tb[prev_staff].y = -y
if (!gene.st_print[st]) // no staff
return y
var sy_staff_prev = sy.staves[prev_staff]
for (st++; st <= nstaff; st++) {
if (!gene.st_print[st])
continue
p_staff = staff_tb[st]
staffsep = sy_staff_prev.sep || cfmt.sysstaffsep;
maxsep = sy_staff_prev.maxsep || cfmt.maxsysstaffsep;
|
| ︙ | | |
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
|
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
|
+
-
+
|
dy = staffsep;
maxsep += p_staff.topbar * p_staff.staffscale
if (dy > maxsep)
dy = maxsep;
y += dy;
p_staff.y = -y;
while (!gene.st_print[++prev_staff])
prev_staff = st;
staff_tb[prev_staff].y = -y
while (1) {
sy_staff_prev = sy.staves[prev_staff]
if (sy_staff_prev)
break
sy = sy.next
}
}
|
| ︙ | | |
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
|
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
|
-
|
// return the height of the whole staff system
return y + dy
}
/* -- draw the staff systems and the measure bars -- */
function draw_systems(indent) {
var s, s2, st, x, x2, res, sy,
staves_bar, bar_force,
xstaff = [],
stl = [], // all staves in the line
bar_bot = [],
bar_height = [],
ba = [], // bars [symbol, bottom, height]
sb = "",
thb = ""
|
| ︙ | | |
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
|
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
|
-
+
-
+
+
-
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
dy = (cur_sy.staves[st].flags & STOP_BAR) ?
0 : bar_bot[st]
}
} // bar_set()
/* -- draw a staff -- */
function draw_staff(st, x1, x2) {
var w, ws, i, dy, ty,
var w, i, dy, ty,
y = 0,
ln = "",
stafflines = staff_tb[st].stafflines,
l = stafflines.length
l = stafflines.length,
il = 6 * staff_tb[st].staffscale // interline
if (!/[\[|]/.test(stafflines))
return // no line
w = x2 - x1;
set_sscale(st);
set_sscale(-1)
ws = w / stv_g.scale
// check if default staff
if (cache && cache.st_l == stafflines
&& cache.st_ws == (ws | 0)) {
&& cache.st_w == (w | 0)) {
xygl(x1, staff_tb[st].y, 'stdef' + cfmt.fullsvg)
return
}
for (i = 0; i < l; i++, y -= 6) {
for (i = 0; i < l; i++, y -= il) {
if (stafflines[i] == '.')
continue
dy = 0
for (; i < l; i++, y -= 6, dy -= 6) {
for (; i < l; i++, y -= il, dy -= il) {
switch (stafflines[i]) {
case '.':
case '-':
continue
case ty:
ln += 'm-' + ws.toFixed(1) +
ln += 'm-' + w.toFixed(1) +
' ' + dy +
'h' + ws.toFixed(1);
'h' + w.toFixed(1);
dy = 0
continue
}
if (ty != undefined)
ln += '"/>\n';
ty = stafflines[i]
ln += '<path class="' +
(ty == '[' ? 'slthW' : 'slW') +
'" d="m0 ' + y + 'h' + ws.toFixed(1);
'" d="m0 ' + y + 'h' + w.toFixed(1);
dy = 0
}
ln += '"/>'
}
y = staff_tb[st].y
if (!cache
&& w > get_lwidth() - 10) {
cache = {
st_l: stafflines,
st_ws: ws | 0
st_w: w | 0
}
i = 'stdef' + cfmt.fullsvg;
if (ln.indexOf('<path', 1) < 0)
glyphs[i] = ln.replace('path', 'path id="' + i + '"')
else
glyphs[i] = '<g id="' + i + '">\n' + ln + '\n</g>';
xygl(x1, y, i)
|
| ︙ | | |
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
|
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
|
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
-
-
+
+
-
-
+
-
-
+
|
}
} // hl_rest()
// ---- draw_systems() ----
/* draw the staff, skipping the staff breaks */
for (st = 0; st <= nstaff; st++) {
xstaff[st] = !cur_sy.st_print[st] ? -1 : 0;
stl[st] = cur_sy.st_print[st] // staff in the line
stl[st] = gene.st_print[st] || cur_sy.st_print[st] // staff in the line
xstaff[st] = !stl[st] ? -1 : 0;
}
bar_set();
draw_lstaff(0)
for (s = tsfirst; s; s = s.ts_next) {
if (bar_force && s.time != bar_force) {
bar_force = 0
for (st = 0; st <= nstaff; st++) {
if (!cur_sy.st_print[st])
xstaff[st] = -1
}
bar_set()
}
switch (s.type) {
case C.STAVES:
staves_bar = s.ts_prev.type == C.BAR ? s.ts_prev.x : 0
if (!staves_bar) {
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.time != s.time)
break
switch (s2.type) {
case C.BAR:
case C.CLEF:
case C.KEY:
case C.METER:
staves_bar = s2.x
continue
}
break
}
if (!s2)
staves_bar = realwidth;
}
sy = s.sy
for (st = 0; st <= nstaff; st++) {
x = xstaff[st]
if (x < 0) { // no staff yet
if (sy.st_print[st]) {
if (s.ts_prev.bar_type)
xstaff[st] = s.ts_prev.x
else if (s.ts_next.bar_type)
xstaff[st] = staves_bar ?
staves_bar : (s.x - s.wl - 2)
xstaff[st] = s.x
else
xstaff[st] = s.ts_prev.x
+ s.ts_prev.wr
stl[st] = true
}
continue
}
if (sy.st_print[st] // if not staff stop
&& cur_sy.staves[st]
&& sy.staves[st].stafflines ==
cur_sy.staves[st].stafflines)
continue
if (staves_bar) {
x2 = staves_bar;
if (s.ts_prev.bar_type) {
x2 = s.ts_prev.x
bar_force = s.time
} else {
x2 = s.x - s.wl - 2;
x2 = (s.ts_prev.x + s.x) / 2
xstaff[st] = -1
}
draw_staff(st, x, x2)
if (sy.st_print[st])
xstaff[st] = x2
xstaff[st] = sy.st_print[st] ? x2 : -1
}
cur_sy = sy;
bar_set()
continue
case C.BAR: // display the bars after the staves
if (s.invis || !s.bar_type
|| !cur_sy.st_print[s.st])
|
| ︙ | | |
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
|
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
|
-
-
|
// s.invis = true
// break
}
}
// draw the end of the staves
for (st = 0; st <= nstaff; st++) {
if (bar_force && !cur_sy.st_print[st])
continue
x = xstaff[st]
if (x < 0 || x >= realwidth)
continue
draw_staff(st, x, realwidth)
}
// the ledger lines
|
| ︙ | | |
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
|
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
|
-
+
|
draw_note(s, !bm.s2);
anno_a.push(s)
}
if (s == bm.s2)
bm.s2 = null
break
case C.REST:
if (!staff_tb[st].topbar)
if (!gene.st_print[st])
break
draw_rest(s);
break
case C.BAR:
break /* drawn in draw_systems */
case C.CLEF:
if (s.time >= staff_tb[st].clef.time)
|
| ︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - format.js - formatting functions
//
// Copyright (C) 2014-2021 Jean-Francois Moine
// Copyright (C) 2014-2022 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
+
-
+
|
musicspace: 6,
// notespacingfactor: "1.3, 38",
partsfont: {name: txt_ff, size: 15},
parskipfac: .4,
partsspace: 8,
// pageheight: 29.7 * CM,
pagewidth: 21 * CM,
"propagate-accidentals": "o", // octave
printmargin: 0,
rightmargin: 1.4 * CM,
rbmax: 4,
rbmin: 2,
repeatfont: {name: txt_ff, size: 13},
repeatfont: {name: txt_ff, size: 9},
scale: 1,
slurheight: 1.0,
spatab: // spacing table (see "notespacingfactor" and set_space())
new Float32Array([ // default = "1.3, 38"
10.2, 13.3, 17.3, 22.48, 29.2,
38,
49.4, 64.2, 83.5, 108.5]),
|
| ︙ | | |
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
-
+
+
|
tupletfont: {name: txt_ff, style: "italic", size: 12},
vocalfont: {name: txt_ff, weight: "bold", size: 13},
vocalspace: 10,
voicefont: {name: txt_ff, weight: "bold", size: 13},
// voicescale: 1,
writefields: "CMOPQsTWw",
wordsfont: {name: txt_ff, size: 16},
wordsspace: 5
wordsspace: 5,
"writeout-accidentals": "n"
}
// parameters that are used in the symbols
var sfmt = {
bardef: true,
barsperstaff: true,
beamslope: true,
|
| ︙ | | |
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
-
+
|
return
}
font_scale_tb[a[0]] = scale
}
// set the width factor of a font
function set_font_fac(font) {
var scale = font_scale_tb[font.name]
var scale = font_scale_tb[font.fname || font.name]
if (!scale)
scale = 1.1;
font.swfac = font.size * scale
}
// %%xxxfont fontname|* [encoding] [size|*]
|
| ︙ | | |
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
+
+
-
+
|
font = {
pad: 0
}
} else {
font = {
name: font.name,
size: font.size,
weight: font.weight,
style: font.style,
box: font.box,
pad: font.pad || 0
}
}
cfmt[xxxfont] = font;
// fill the values
a = p.match(/\s+(no)?box(\s|$)/)
if (a) { // if box
if (a[1]) {
font.box = false // nobox
font.pad = 0
} else {
font.box = true
font.pad = font.size * .4 - 3
font.pad = 2.5
}
p = p.replace(a[0], a[2])
}
a = p.match(/\s+padding=([\d.]+)(\s|$)/)
if (a) { // if padding
font.pad = a[1] ? +a[1] : 0
p = p.replace(a[0], a[2])
|
| ︙ | | |
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
+
+
|
a = p.match(/\s+([0-9.]+|\*)$/)
if (a) {
if (a[1] != "*")
font.size = +a[1]
p = p.replace(a[0], "")
}
font.fname = p // full name for scale factor
// accept url(...) as the font name
if (p[0] == 'u' && p.slice(0, 4) == "url(") {
n = p.indexOf(')', 1)
if (n < 0) {
syntax(1, "No end of url in font family")
return
}
|
| ︙ | | |
296
297
298
299
300
301
302
303
304
305
306
307
308
309
|
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
|
+
+
+
+
|
}
// extract the font attributes
a = p.match(/[- ]?[nN]ormal/)
if (a) {
font.normal = true
p = p.replace(a[0], '')
if (font.weight)
font.weight = null
if (font.style)
font.style = null
}
// font weight
a = p.match(abc2svg.ft_re)
if (a) {
font.weight = abc2svg.ft_w[a[0].replace(/[ -]/, '')
.toLowerCase()]
|
| ︙ | | |
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
+
+
-
-
-
+
|
default:
//hack: the font "Figurato" is used for figured bass
if (p.indexOf("Fig") > 0)
font.figb = true
break
}
}
font.name = p
if (font.size)
set_font_fac(font)
else
font.swfac = 0
font.name = p
}
// get a length with a unit - return the number of pixels
function get_unit(param) {
var v = param.toLowerCase().match(/([\d.]+)(.*)/)
var v = param.toLowerCase().match(/(-?[\d.]+)(.*)/)
if (!v)
return NaN
v[1] = +v[1]
switch (v[2]) {
case "cm":
return v[1] * CM
|
| ︙ | | |
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
|
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
|
+
+
-
+
|
}
}
}
// set a voice specific parameter
function set_v_param(k, v) {
k = [k + '=', v]
if (parse.state < 3)
memo_kv_parm(curvoice ? curvoice.id : '*', k)
if (curvoice)
else if (curvoice)
set_kv_parm(k)
else
memo_kv_parm('*', k)
}
function set_page() {
if (!img.chg)
|
| ︙ | | |
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
|
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
|
+
+
|
break
}
cfmt[cmd] = v
break
case "abc-version":
case "bgcolor":
case "fgcolor":
case "propagate-accidentals":
case "titleformat":
case "writeout-accidentals":
cfmt[cmd] = param
break
case "beamslope":
case "breaklimit": // float values
case "lineskipfac":
case "maxshrink":
case "pagescale":
|
| ︙ | | |
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
|
572
573
574
575
576
577
578
579
580
581
582
583
584
585
|
-
|
case "flatbeams":
case "graceslurs":
case "graceword":
case "hyphencont":
case "keywarn":
case "linewarn":
case "quiet":
case "singleline":
case "squarebreve":
case "splittune":
case "straightflags":
case "stretchstaff":
case "timewarn":
case "titlecaps":
case "titleleft":
|
| ︙ | | |
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
|
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
|
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
|
}
if (parse.ufmt)
cfmt[cmd] = new Float32Array(3)
for (i = 0; i < 3; i++)
cfmt[cmd][i] = +v[i]
break
case "tuplets":
cfmt[cmd] = param.split(/\s+/);
v = cfmt[cmd][3]
if (v // if 'where'
&& (posval[v])) // translate the keyword
cfmt[cmd][3] = posval[v]
v = param.split(/\s+/)
f = v[3]
if (f) // if 'where'
f = posval[f] // translate the keyword
if (f)
v[3] = f
if (curvoice)
curvoice.tup = v
else
cfmt[cmd] = v
break
case "infoname":
set_infoname(param)
break
case "notespacingfactor":
v = param.match(/([.\d]+)[,\s]*(\d+)?/)
if (v) {
|
| ︙ | | |
723
724
725
726
727
728
729
730
731
732
733
734
735
736
|
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
cfmt.sound = "play" // without clef
break
case "pos":
cmd = param.match(/(\w*)\s+(.*)/)
if (!cmd || !cmd[2]) {
syntax(1, "Error in %%pos")
break
}
if (cmd[1].slice(0, 3) == 'tup' // special case for %%pos tuplet
&& curvoice) { // inside tune
if (!curvoice.tup)
curvoice.tup = cfmt.tuplets
else
curvoice.tup = Object.create(curvoice.tup)
v = posval[cmd[2]]
switch (v) {
case C.SL_ABOVE:
curvoice.tup[3] = 1
break
case C.SL_BELOW:
curvoice.tup[3] = 2
break
case C.SL_HIDDEN:
curvoice.tup[2] = 1
break
}
break
}
set_pos(cmd[1], cmd[2])
break
case "sounding-score":
if (cfmt.sound != "play")
cfmt.sound = "sounding"
break
|
| ︙ | | |
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
|
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
|
+
-
+
|
cfmt.rightmargin = v;
img.chg = true
break
case "textoption":
cfmt[cmd] = get_textopt(param)
break
case "dynalign":
case "singleline":
case "stretchlast":
case "titletrim":
v = +param
if (isNaN(v))
v = get_bool(param) ? 0 : 1
if (cmd[0] == 's') { // stretchlast
if (cmd[1] == 't') { // stretchlast
if (v < 0 || v > 1) {
syntax(1, errs.bad_val, '%%' + cmd)
break
}
}
cfmt[cmd] = v
break
|
| ︙ | | |
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
|
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
|
-
+
-
+
|
if (font.src)
add_fstyle("@font-face{\n\
font-family:" + font.name + ";\n\
src:" + font.src + "}")
if (font == cfmt.musicfont) // add more music font style
add_fstyle(".f" + font.fid
+ (cfmt.fullsvg || "")
+ ' text,tspan{fill:currentColor;white-space:pre}')
+ ' text,tspan{white-space:pre}')
}
}
// get the font of the 'xxxfont' parameter
function get_font(fn) {
var font, font2, fid, st
fn += "font"
font = cfmt[fn]
if (!font) {
syntax(1, "Unknown font $1", '$' + fn[1]);
syntax(1, "Unknown font $1", fn)
return gene.curfont
}
if (!font.name || !font.size) { // if incomplete user font
font2 = Object.create(gene.deffont)
if (font.name)
font2.name = font.name
|
| ︙ | | |
| ︙ | | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
-
+
|
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>.
// -- parse a chord symbol / annotation --
// the result is added in the global variable a_gch
// 'type' may be a single '"' or a string '"xxx"' created by U:
function parse_gchord(type) {
var c, text, gch, x_abs, y_abs, type,
var c, text, gch, x_abs, y_abs,
i, j, istart, iend,
ann_font = get_font("annotation"),
h_ann = ann_font.size,
line = parse.line
function get_float() {
var txt = ''
|
| ︙ | | |
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
-
+
+
|
i = ++line.index // search the ending double quote
while (1) {
j = line.buffer.indexOf('"', i)
if (j < 0) {
syntax(1, "No end of chord symbol/annotation")
return
}
if (line.buffer[j - 1] != '\\')
if (line.buffer[j - 1] != '\\'
|| line.buffer[j - 2] == '\\') // (string ending with \\")
break
i = j + 1
}
text = cnv_escape(line.buffer.slice(line.index, j))
line.index = j
iend = parse.bol + line.index + 1
}
|
| ︙ | | |
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
-
|
y_abs = 0
} else {
y_abs = get_float()
if (c != ' ')
i--
}
gch.x = x_abs;
y_abs -= h_ann * .3 // center vertically
gch.y = y_abs
break
case '^':
gch.pos = C.SL_ABOVE
// fall thru
case '_':
if (c == '_')
|
| ︙ | | |
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
-
+
+
+
|
while (1) {
c = text[i]
if (!c)
break
switch (c) {
case '\\':
c = text[++i]
if (!c || c == 'n')
if (c == 'n')
break
gch.text += '\\'
if (!c)
break
default:
gch.text += c;
i++
continue
case '&': /* skip "&xxx;" */
while (1) {
gch.text += c;
|
| ︙ | | |
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
|
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
-
-
-
|
}
}
// transpose a chord symbol
var note_names = "CDEFGAB",
acc_name = ["bb", "b", "", "#", "##"]
function gch_tr1(p, transp) {
function gch_tr1(p) {
var i, o, n, a, ip, b40,
tr = curvoice.tr_sco,
csa = p.split('/')
for (i = 0; i < csa.length; i++) { // main and optional bass
p = csa[i];
o = p.search(/[A-G]/)
if (o < 0)
continue // strange chord symbol!
ip = o + 1
a = 0
while (p[ip] == '#' || p[ip] == '\u266f') {
a++;
ip++
}
while (p[ip] == 'b' || p[ip] == '\u266d') {
a--;
ip++
}
n = note_names.indexOf(p[o]) + 16
b40 = (abc2svg.pab40(n, a) + transp + 200) % 40
b40 = (abc2svg.pab40(n, a) + tr + 200) % 40
b40 = abc2svg.b40k[b40]
csa[i] = p.slice(0, o) +
note_names[abc2svg.b40_p[b40]] +
acc_name[abc2svg.b40_a[b40] + 2] +
p.slice(ip)
}
return csa.join('/')
} // gch_tr1
function gch_transp(s) {
var gch,
i = s.a_gch.length
while (--i >= 0) {
gch = s.a_gch[i]
if (gch.type == 'g')
gch.text = gch_tr1(gch.text, curvoice.vtransp)
}
}
// parser: add the parsed list of chord symbols and annotations
// to the symbol (note, rest or bar)
// and transpose the chord symbols
function csan_add(s) {
var i, gch
// there cannot be chord symbols on measure bars
if (s.type == C.BAR) {
for (i = 0; i < a_gch.length; i++) {
if (a_gch[i].type == 'g') {
syntax(1,
error(1, s,
"There cannot be chord symbols on measure bars")
a_gch.splice(i)
}
}
}
if (curvoice.tr_sco) {
for (i = 0; i < a_gch.length; i++) {
gch = a_gch[i]
if (gch.type == 'g')
gch.text = gch_tr1(gch.text)
}
}
if (s.a_gch)
s.a_gch = s.a_gch.concat(a_gch)
else
s.a_gch = a_gch
a_gch = null
if (curvoice.vtransp)
gch_transp(s)
} // csan_add
// generator: build the chord symbols / annotations
// (possible hook)
Abc.prototype.gch_build = function(s) {
/* split the chord symbols / annotations
|
| ︙ | | |
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
-
-
|
return "𝄫"
});
} else {
if (gch.type == '@'
&& !user.anno_start && !user.anno_stop) {
set_font(gch.font)
gch.text = str2svg(gch.text)
gch.text.wh = [0, 0]
continue /* no width */
}
}
/* set the offsets and widths */
set_font(gch.font);
gch.text = str2svg(gch.text)
wh = gch.text.wh
wh[1] += gch.font.pad * 2
switch (gch.type) {
case '@':
break
case '^': /* above */
case '_': /* below */
xspc = wh[0] * GCHPRE
if (xspc > 8)
|
| ︙ | | |
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
|
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
|
-
+
-
+
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
+
-
+
-
+
+
+
+
+
+
+
+
+
|
if (s.invis && s.play) // play sequence: no chord nor annotation
return
var y2,
an = s.a_gch[i],
h = an.text.wh[1],
pad = an.font.pad,
w = an.text.wh[0] + pad * 2,
dy = 0
dy = h * .22 // descent
if (an.font.figb) {
h *= 2.4
dy = an.font.size * 1.3
dy += an.font.size * 1.3
}
switch (an.type) {
case '_': // below
y -= h + pad
y_set(s.st, 0, x, w, y - pad)
break
case '^': // above
y = y_get(s.st, 1, x, w)
y += pad
y_set(s.st, 1, x, w, y + h + pad)
break
case '<': // left
case '>': // right
if (an.type == '<') {
/*fixme: what symbol space?*/
if (s.notes[0].acc)
x -= s.notes[0].shac
x -= pad
} else {
if (s.xmx)
x += s.xmx
if (s.dots)
x += 1.5 + 3.5 * s.dots
x += pad
}
y += (s.type == C.NOTE ?
(((s.notes[s.nhd].pit + s.notes[0].pit) >> 1) -
18) * 3 :
12) // fixed offset on rests and bars
- h / 2
if (y > 24)
y_set(s.st, 1, x, w, y + h + pad)
if (y < 0)
y_set(s.st, 0, x, w, y - pad)
break
default: // chord symbol
if (y >= 0) {
if (y >= 0)
y += pad
y_set(s.st, 1, x, w, y + h + pad)
} else {
else
y -= h + pad
y_set(s.st, 0, x, w, y - pad)
}
break
case '@': // absolute
y += (s.type == C.NOTE ?
(((s.notes[s.nhd].pit + s.notes[0].pit) >> 1) -
18) * 3 :
12) // fixed offset on rests and bars
+ h * .2
- h / 2
if (y > 0) {
y2 = y + h * .8
y2 = y + h + pad + 2
if (y2 > staff_tb[s.st].ann_top)
staff_tb[s.st].ann_top = y2
} else {
y2 = y
y2 = y - 2
if (y2 < staff_tb[s.st].ann_bot)
staff_tb[s.st].ann_bot = y2
}
break
}
if (an.type != '@') {
if (y > 24)
y_set(s.st, 1, x, w, y + h + pad + 2)
else if (y < 0)
y_set(s.st, 0, x, w, y - pad)
}
use_font(an.font)
set_font(an.font)
set_dscale(s.st)
if (user.anno_start)
user.anno_start("annot", an.istart, an.iend,
x - 2, y + h + 2, w + 4, h + 4, s)
xy_str(x, y + dy, an.text)
|
| ︙ | | |
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
|
-
+
|
if (!an)
continue
if (an.pos == C.SL_ABOVE) {
x = s.x + an.x
w = an.text.wh[0]
if (w && x + w > realwidth)
x = realwidth - w // let the text in the page
y = y_get(s.st, 1, x, w) // y / staff
y = y_get(s.st, 1, x, w) + 2 // y / staff
if (an.type == 'g' && y < minmax[s.st].yup)
y = minmax[s.st].yup
} else if (an.pos == C.SL_BELOW
|| an.pos == C.SL_HIDDEN) {
continue
} else {
x = s.x + an.x
|
| ︙ | | |
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
|
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
|
-
+
|
if (!an
|| an.pos != C.SL_BELOW)
continue
x = s.x + an.x
w = an.text.wh[0]
if (w && x + w > realwidth) // let the text inside the page
x = realwidth - w
y = y_get(s.st, 0, x, w) // y / staff
y = y_get(s.st, 0, x, w) - 2 // y / staff
if (an.type == 'g' && y > minmax[s.st].ydn)
y = minmax[s.st].ydn
self.draw_gchord(i, s, x, y)
}
} // set_an_yl()
// get the number of chord symbols / annotations
|
| ︙ | | |
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
|
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
|
-
+
-
+
|
if (i > n_an)
n_an = i
while (--i >= 0) {
if (an[i].type == 'g') {
an = an[i]
w = an.text.wh[0]
if (an.pos == C.SL_ABOVE) {
y = y_get(s.st, true, s.x, w)
y = y_get(s.st, true, s.x, w) + 2
if (y > minmax[s.st].yup)
minmax[s.st].yup = y
} else if (an.pos == C.SL_BELOW) {
y = y_get(s.st, false, s.x, w)
y = y_get(s.st, false, s.x, w) - 2
if (y < minmax[s.st].ydn)
minmax[s.st].ydn = y
}
break
}
}
}
|
| ︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - music.js - music generation
//
// Copyright (C) 2014-2022 Jean-Francois Moine
// Copyright (C) 2014-2023 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
-
-
+
|
if (p1 > ps + 4) { // if interval greater than a sixth
if (dx1 > dx2)
dx2 = dx1 // align the accidentals
notes[i1].shac = notes[i2].shac = dx2
} else {
notes[i1].shac = dx1
if (p1 != ps)
dx1 += 7 // (there is a shift of a head when unison)
dx1 += 7
notes[i2].shac = dx2 = dx1
}
dx2 += 7
// shift the remaining accidentals
for (i = i1; --i > i2; ) { // from top to bottom
acc = notes[i].acc
|
| ︙ | | |
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
-
-
+
+
+
+
|
continue
}
dx_head = dx_tb[s.head]
// build a pseudo chord and shift the accidentals
notes = []
for ( ; s != s2; s = s.ts_next)
Array.prototype.push.apply(notes, s.notes)
for ( ; s != s2; s = s.ts_next) {
if (!s.invis)
Array.prototype.push.apply(notes, s.notes)
}
notes.sort(abc2svg.pitcmp)
acc_shift(notes, dx_head)
}
}
// link a symbol before an other one
function lkvsym(s, next) { // voice linkage
|
| ︙ | | |
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
|
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
|
-
+
|
}
switch (s.type) {
case C.NOTE:
case C.REST:
/* set the note widths */
s.wr = wlnote = hw_tb[s.head]
s.wr = wlnote = s.invis ? 0 : hw_tb[s.head]
/* room for shifted heads and accidental signs */
if (s.xmx > 0)
s.wr += s.xmx + 4;
for (s2 = s.prev; s2; s2 = s2.prev) {
if (w_tb[s2.type])
break
|
| ︙ | | |
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
|
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
|
-
-
+
-
-
+
+
-
-
-
+
+
+
+
+
|
wlw = 14
}
break
case C.CLEF: /* extra space at start of line */
if (s2.second
|| s2.clef_small)
break
wlw += 8
break
// fall thru
case C.KEY:
/* case C.METER: */
wlw += 4
case C.METER:
wlw += 3
break
}
}
/* leave room for guitar chord */
if (s.a_gch)
wlw = gchord_width(s, wlnote, wlw)
// ignore the lyrics for now
/* if preceeded by a grace note sequence, adjust */
if (s2 && s2.type == C.GRACE)
s.wl = wlnote - 4.5
else
if (s.prev && s.prev.type == C.GRACE) {
s.prev.wl += wlnote - 4.5
s.wl = s.prev.wl
} else {
s.wl = wlw
}
return
case C.SPACE:
xx = s.width / 2;
s.wr = xx
if (s.a_gch)
xx = gchord_width(s, xx, xx)
if (s.a_dd)
|
| ︙ | | |
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
|
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
|
-
+
-
-
-
+
+
+
+
|
&& s.next.type != C.METER)
s.wr = 7
else
s.wr = 5
// s.notes[0].shhd = (w - 5) * -.5
/* if preceeded by a grace note sequence, adjust */
for (s2 = s.prev; s2; s2 = s2.prev) {
s2 = s.prev
if (w_tb[s2.type]) {
if (s2.type == C.GRACE)
s.wl -= 6
if (s2 && s2.type == C.GRACE)
s.wl -= 6
for ( ; s2; s2 = s2.prev) {
if (w_tb[s2.type]) {
if (s2.type == C.STBRK)
s.wl -= 12
break
}
}
if (s.a_dd)
|
| ︙ | | |
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
|
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
|
-
+
-
-
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
|
case C.CLEF:
// (there may be invisible clefs in empty staves)
if (s.invis) {
s.wl = s.wr = 1 // (!! not 0 !!)
return
}
s.wl = s.clef_small ? 11 : 12
s.wr = s.clef_small ? 10 : 12
s.wr = s.clef_small ? 8 : 13
if (s.prev && s.prev.type == C.STBRK) {
s.wl -= 6
delete s.next.clef_small
}
if (s.next && s.next.type == C.BAR)
s.wr -= 4
return
case C.KEY:
if (s.invis) { // if no accidental
s.wl = s.wr = 0 // no width
return
}
s.wl = 3;
esp = 4
s.wl = 0
esp = 3
if (!s.k_a_acc) {
n1 = s.k_sf /* new key sig */
if (s.k_old_sf && (s.fmt.cancelkey || n1 == 0))
n2 = s.k_old_sf /* old key */
else
n2 = 0
if (n1 * n2 >= 0) { /* if no natural */
if (n1 < 0)
n1 = -n1
if (n2 < 0)
n2 = -n2
if (n2 > n1)
n1 = n2
} else {
n1 -= n2
if (n1 < 0)
n1 = -n1;
esp += 3 /* see extra space in draw_keysig() */
}
} else {
n1 = n2 = s.k_a_acc.length
if (s.k_bagpipe == 'p') // K:Hp - add the g natural
n1++
if (s.k_a_acc) {
n2 = s.k_a_acc.length
if (s.exp)
n1 = n2 // no key signature
else
n1 += n2
if (n2)
last_acc = s.k_a_acc[0].acc
for (i = 1; i < n2; i++) {
acc = s.k_a_acc[i]
if (acc.pit > s.k_a_acc[i - 1].pit + 6
|| acc.pit < s.k_a_acc[i - 1].pit - 6)
n1-- // no clash
else if (acc.acc != last_acc)
esp += 3;
last_acc = acc.acc
}
}
if (!n1)
break // no width
s.wr = 5.5 * n1 + esp
if (s.prev && !s.prev.bar_type)
s.wl += 2
return
case C.METER:
wlw = 0;
s.x_meter = []
if (!s.a_meter.length)
break // no width
wlw = 0
for (i = 0; i < s.a_meter.length; i++) {
meter = s.a_meter[i]
switch (meter.top[0]) {
case 'C':
case 'c':
case 'o':
s.x_meter[i] = wlw + 6;
|
| ︙ | | |
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
|
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
|
-
-
+
+
|
break
}
}
s.x_meter[i] = wlw + w / 2
wlw += w
}
}
s.wl = 0;
s.wr = wlw + 6
s.wl = 1
s.wr = wlw + 7
return
case C.MREST:
s.wl = 6;
s.wr = 66
return
case C.GRACE:
if (s.invis)
|
| ︙ | | |
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
|
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
|
-
+
|
while (!s.dur) {
switch (s.type) {
case C.BAR:
// (hack to have quite the same note widths between measures)
if (!s.next)
space *= .9
return space * .9 - 7
return space * .9 - 3
case C.CLEF:
return space - s.wl - s.wr
case C.BLOCK: // no space
case C.REMARK:
case C.STAVES:
case C.TEMPO:
s = s.ts_next
|
| ︙ | | |
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
|
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
|
-
+
+
-
+
-
+
+
-
-
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
-
+
-
+
|
prev: s,
fmt: s.fmt
}
} // _bar()
// create an invisible bar for end of music lines
function add_end_bar(s) {
var b = _bar(s)
var b = _bar(s),
sn = s.ts_next // start of next line
b.wl = 0
b.wr = 0
b.ts_prev = s
b.next = s.next
b.ts_next = s.ts_next
b.shrink = s.wr + 3
b.shrink = s.type == C.STBRK ? 0 : (s.wr + 3)
if (s.next) // (must not be the end of the voice)
s.next.prev = b
// if (s.ts_next)
s.ts_next.ts_prev = b
s.next = s.ts_next = b
b.space = set_space(b, s.time + s.dur * .4)
b.space = sn.space * .9 - 3
return b
}
/* -- set the width and space of all symbols -- */
// this function is called once for the whole tune
// and once more for each new music line
function set_allsymwidth() {
var val, st, s_chs, stup,
function set_allsymwidth(first) {
var val, st, s_chs, stup, itup,
s = tsfirst,
s2 = s,
xa = 0,
xl = [],
wr = [],
maxx = xa,
tim = s.time
/* loop on all symbols */
while (1) {
itup = 0
do {
if ((s.a_gch || s.a_ly) && !s_chs)
s_chs = s;
self.set_width(s);
st = s.st
if (xl[st] == undefined)
xl[st] = 0
if (wr[st] == undefined)
wr[st] = 0;
val = xl[st] + wr[st] + s.wl
if (val > maxx)
maxx = val
if (s.dur && s.dur != s.notes[0].dur // if in tuplet
&& first) // (first time only)
itup = 1
s = s.ts_next
} while (s && !s.seqst);
// set the spaces of the time sequence
s2.shrink = maxx - xa
s2.space = s2.ts_prev ? set_space(s2, tim) : 0
// adjust the spacing when after a spacer (y)
if (s2.space == 0 && s2.ts_prev
&& s2.ts_prev.type == C.SPACE && s2.ts_prev.seqst)
s2.space = s2.ts_prev.space /= 2
if (s2.dur && s2.dur != s2.notes[0].dur) {
if (!stup) {
if (itup) {
if (!stup)
stup = s2
while (stup.prev
&& stup.prev.dur
&& stup.prev.dur != stup.prev.notes[0].dur)
stup = stup.prev
while (!stup.seqst)
stup = stup.ts_prev
}
} else if (stup && stup.v == s2.v) {
set_sp_tup(stup, s2)
stup = null
}
if (!s2.shrink) {
if (!s2.shrink && !s2.space && s2.type == C.CLEF) {
if (!s2.space && s2.type == C.CLEF
&& !s2.ts_prev.bar_type) {
delete s2.seqst; /* no space */
s2.time = tim
} else if (s2.dur) {
s2.shrink = 10 // cannot be null
}
}
tim = s2.time
if (!s)
break
// update the min left space per staff
for (st = 0; st < wr.length; st++)
wr[st] = 0;
xa = maxx
do {
st = s2.st;
xl[st] = xa
if (s2.wr > wr[st])
wr[st] = s2.wr
s2 = s2.ts_next
} while (!s2.seqst)
}
if (stup)
set_sp_tup(stup, s2)
// let the chord symbols at the same offset
// and adjust the spacing due to the lyrics
if (s_chs)
if (first && s_chs)
set_w_chs(s_chs)
}
// insert a rest, this one replacing a sequence or a measure
function to_rest(so) {
var s = clone(so)
s.prev.next = so.ts_prev = so.prev = s.ts_prev.ts_next = s
s.next = s.ts_next = so
so.seqst = false
so.invis = so.play = true
s.type = C.REST
// just keep nl and seqst
delete s.in_tuplet
delete s.sl1
delete s.tp
delete s.a_dd
delete s.a_gch
delete s.sls
//fixme: what if chord / slur in notes / ... ?
/*fixme: should set many parameters for set_width*/
// set_width(s)
return s
|
| ︙ | | |
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
|
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
|
-
+
|
/* -- define the beginning of a new music line -- */
function set_nl(s) { // s = start of line
var p_voice, done, tim, ptyp
// divide the left repeat (|:) or variant bars (|1)
// the new bars go in the next line
function bardiv(so) { // start of next line
var s, s1, s2, t1, t2, i, noseq
var s, s1, s2, t1, t2, i
function new_type(s) {
var t = s.bar_type.match(/(:*)([^:]*)(:*)/)
// [1] = starting ':'s, [2] = middle, [3] = ending ':'s
if (!t[3]) { // if start of variant
// |1 -> | [1
|
| ︙ | | |
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
|
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
|
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
-
-
+
+
+
-
+
-
-
+
-
-
-
|
}
} // new_typ()
s = so // start of sequence
while (s.ts_prev
&& s.ts_prev.time == so.time) {
s = s.ts_prev
if (s.bar_type)
if (s.bar_type) {
// if repeat variant, move the new line
if (s.bar_type[0] == '['
&& s.text
&& s.ts_next == so)
so = s
s1 = s // first previous bar
}
if (s.type == C.GRACE)
so = s // keep the grace notes in the next line
// if (s.type == C.GRACE)
// so = s // keep the grace notes in the next line
}
if (!s1)
return so
// search the insertion point in the new line
for (s = so; ; s = s.ts_next) {
switch (s.type) {
// default:
// if (w_tb[s.type])
// break
case C.KEY:
case C.METER:
case C.CLEF:
continue
}
break
}
if (s.bar_type)
noseq = 1
while (s1 != so) {
if (s1.bar_type
&& s1.next
&& (s1.bar_type.slice(-1) == ':'
|| s1.text)
&& s1.bar_type != ':') {
new_type(s1) // return t1 and t2
s2 = clone(s1)
s1.bar_type = t1
delete s1.rbstop
delete s1.a_gch
delete s1.a_gch
if (t1 == '|')
delete s1.rbstop // (needed for play variant)
s2.bar_type = t2
lkvsym(s2, s1.next) // voice
while (1) {
if (s.type != C.BAR
//fixme: pb if inverted voices
|| s.v > s2.v)
break
s = s.ts_next
}
lktsym(s2, s) // time
if (!noseq) {
if (s1.seqst)
noseq = 1
s2.seqst = true
s2.seqst = 1
s2.shrink = s2.wl + s2.prev.wr
s2.space = 0
}
if (s == so)
so = s2
if (s1.text) {
s2.invis = true
delete s1.text
delete s1.rbstart
}
|
| ︙ | | |
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
|
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
|
-
+
|
if (s.type != C.BAR)
add_end_bar(s)
} // set_eol()
// put the warning symbols
// the new symbols go in the previous line
function do_warn(s) { // start of next line
var s1, s2, s3
var s1, s2, s3, s4
// advance in the next line
for (s2 = s; s2; s2 = s2.ts_next) {
switch (s2.type) {
case C.KEY:
if (!s.fmt.keywarn
|| s2.invis)
|
| ︙ | | |
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
|
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
|
+
+
+
+
+
|
s1 = s.ts_prev
}
// fall thru
case C.CLEF:
if (!s2.prev) // start of voice
continue
if (s2.type == C.CLEF) {
if (s2.invis) // if 'K: clef=none' after bar
break
for (s1 = s.ts_prev; s1; s1 = s1.ts_prev) {
switch (s1.type) {
case C.BAR:
if (s1.bar_type[0] == ':')
break
// fall thru
case C.KEY:
case C.METER:
continue
}
break
}
}
|
| ︙ | | |
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
|
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
|
+
+
+
-
-
-
-
+
+
+
+
+
+
+
|
if (s1.v == s2.v)
break
}
lkvsym(s3, s1) // voice link
// care with spacing
if (s3.seqst) {
self.set_width(s3)
s3.shrink = s3.wl
s4 = s3.ts_prev
while (!s4.seqst)
if (s3.prev) // if not start of voice
s3.shrink += s3.prev.wr
s3.space = set_space(s3, s3.ts_prev.time)
s3.next.shrink = s3.wr + s3.next.wl
s4 = s4.ts_prev
s3.shrink += s4.wr
s3.space = 0
s4 = s3.ts_next
while (!s4.seqst)
s4 = s4.ts_next
s4.shrink = s3.wr + s4.wl
}
delete s3.part
continue
}
if (w_tb[s2.type])
break // symbol with a width
}
|
| ︙ | | |
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
|
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
|
-
+
-
+
-
+
|
}
/* -- search where to cut the lines according to the staff width -- */
function set_lines( s, /* first symbol */
next, /* symbol of the next line / null */
lwidth, /* w - (clef & key sig) */
indent) { /* for start of tune */
var first, s2, s3, s4, x, xmin, xmid, xmax, wwidth, shrink, space,
var first, s2, s3, s4, s5, x, xmin, xmid, xmax, wwidth, shrink, space,
nlines,
last = next ? next.ts_prev : null,
ws = get_width(s, next) // 2 widths: nice and shrinked
ws = get_width(s, next) // 2 widths: nice and shrunk
// take care of big key signatures at end of line
if (s.fmt.keywarn && next
&& next.type == C.KEY && !last.dur) {
ws[0] += next.wr
ws[1] += next.wr
}
// check if the symbols can enter in one line
if (ws[1] + indent < lwidth) {
if (ws[0] + indent < lwidth) {
if (next)
next = set_nl(next)
return next || last
}
/* loop on cutting the tune into music lines */
wwidth = ws[0] + indent
|
| ︙ | | |
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
|
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
|
-
-
-
+
+
+
|
s2 = s
if (s.x >= xmin)
break
}
s4 = s // keep first symbol with x greater than xmin
//fixme: can this occur?
if (s == next) {
if (next)
next = set_nl(next)
return next
if (s)
s = set_nl(s)
return s
}
/* try to cut on a measure bar */
s3 = null
for ( ; s != next; s = s.ts_next) {
x = s.x
if (!x)
|
| ︙ | | |
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
|
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
|
+
-
+
-
-
-
-
-
-
+
-
-
-
-
-
+
+
+
-
-
-
-
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
|
if (!s3) {
s = s4 // restart after xmin
var beam = 0,
bar_time = s2.time
xmax -= 8; // (left width of the inserted bar in set_allsymwidth)
s5 = s
for ( ; s != next; s = s.ts_next) {
if (s.dur) {
if (s.seqst) {
if (!s.beam_end)
beam |= 1 << s.v
else
beam &= ~(1 << s.v)
}
x = s.x
x = s.x
if (!x)
continue
if (x + s.wr >= xmax)
break
if (beam || s.in_tuplet)
if (x + s.wr >= xmax)
break
if (!beam && !s.in_tuplet
continue
if (s3 && s.x >= xmid) {
if (xmid - s3.x > s.x - xmid
|| (s.dur
&& (xmid - s5.x > x - xmid
|| (s.time - bar_time)
&& (s.time + s.dur - bar_time)
% (C.BLEN / 4) == 0))
s3 = s
}
break
}
s3 = s
if (s.beam_st)
beam |= 1 << s.v
if (s.beam_end)
beam &= ~(1 << s.v)
s5 = s // start of new time sequence
}
if (s3) {
do { // cut on the previous sequence
s3 = s3.ts_prev
} while (!s3.seqst)
}
}
// cut anyhere
if (!s3) {
s3 = s = s4
for ( ; s != next; s = s.ts_next) {
x = s.x
if (!x)
continue
if (x + s.wr >= xmax)
break
if (s3 && s.x >= xmid) {
if (xmid - s3.x > s.x - xmid)
if (s3 && x >= xmid) {
if (xmid - s3.x > x - xmid)
s3 = s
break
}
s3 = s
}
}
s = s3
|
| ︙ | | |
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
|
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
|
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
-
-
-
+
+
|
wwidth -= s.x - first.x;
indent = 0
}
return s
}
/* -- cut the tune into music lines -- */
function cut_tune(lwidth, indent) {
var s2, i,
function cut_tune(lwidth, lsh) {
var s2, i, mc,
//fixme: not usable yet
// pg_sav = {
// leftmargin: cfmt.leftmargin,
// rightmargin: cfmt.rightmargin,
// pagewidth: cfmt.pagewidth,
// scale: cfmt.scale
// },
pg_sav = { // save the page parameters
leftmargin: cfmt.leftmargin,
rightmargin: cfmt.rightmargin,
pagewidth: cfmt.pagewidth,
scale: cfmt.scale
},
indent = lsh[0] - lsh[1], // extra width of the first line
ckw = get_ck_width(), // width of the starting symbols
s = tsfirst
// take care of the voice subnames
if (indent) {
i = set_indent()
lwidth -= i;
indent -= i;
}
lwidth -= lsh[1] // width of the lines
if (cfmt.indent && cfmt.indent > lsh[0])
indent += cfmt.indent
/* adjust the line width according to the starting clef
// adjust the line width according to the starting symbols
* and key signature */
/*fixme: may change in the tune*/
i = get_ck_width();
lwidth -= i[0];
indent += i[1]
lwidth -= ckw[0]
indent += ckw[1]
if (cfmt.custos && voice_tb.length == 1)
lwidth -= 12
/* if asked, count the measures and set the EOLNs */
i = s.fmt.barsperstaff
if (i) {
|
| ︙ | | |
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
|
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
|
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
|
i = s.fmt.barsperstaff
}
}
/* cut at explicit end of line, checking the line width */
s2 = s
for ( ; s; s = s.ts_next) {
//fixme: not usable yet
// if (s.type == C.BLOCK) {
// switch (s.subtype) {
// case "leftmargin":
// case "rightmargin":
// case "pagescale":
// case "pagewidth":
// case "scale":
// case "staffwidth":
// set_format(s.subtype, s.param)
// break
if (s.type == C.BLOCK) {
switch (s.subtype) {
case "leftmargin":
case "rightmargin":
case "pagescale":
case "pagewidth":
case "scale":
case "staffwidth":
if (!s.soln)
self.set_format(s.subtype, s.param)
break
// }
// continue
// }
case "mc_start":
mc = {
lm: cfmt.leftmargin,
rm: cfmt.rightmargin
}
break
case "mc_new":
case "mc_end":
cfmt.leftmargin = mc.lm
cfmt.rightmargin = mc.rm
img.chg = 1 //true
break
}
}
if (!s.ts_next) {
s = null
} else if (!s.soln) {
continue
} else {
s.soln = false
if (s.time == s2.time)
continue // empty music line!
while (!s.seqst)
s = s.ts_prev
}
set_page()
lwidth = get_lwidth() - lsh[1] - ckw[0]
s2 = set_lines(s2, s, lwidth, indent)
if (!s2)
break
//--fixme
// s = s2.ts_prev; // don't miss an eoln
s = s2
s = s2.type == C.BLOCK
? s2.ts_prev // don't miss a parameter
: s
indent = 0
}
//fixme: not usable yet
// // restore the page parameters at start of line
// cfmt.leftmargin = pg_sav.leftmargin;
// cfmt.rightmargin = pg_sav.rightmargin;
// cfmt.pagewidth = pg_sav.pagewidth;
// cfmt.scale = pg_sav.scale
// restore the page parameters at start of line
cfmt.leftmargin = pg_sav.leftmargin
cfmt.rightmargin = pg_sav.rightmargin
cfmt.pagewidth = pg_sav.pagewidth
cfmt.scale = pg_sav.scale
img.chg = 1
set_page()
}
/* -- set the y values of some symbols -- */
function set_yval(s) {
//fixme: staff_tb is not yet defined
// var top = staff_tb[s.st].topbar
// var bot = staff_tb[s.st].botbar
|
| ︙ | | |
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
|
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
|
-
+
-
|
}
/* go backwards and search where to insert a clef change */
s3 = s
for (s2 = s.ts_prev; s2 != s_last_chg; s2 = s2.ts_prev) {
if (s2.st != st)
continue
if (s2.type == C.BAR
if (s2.type == C.BAR) {
&& s2.v == s.v) {
s3 = s2.bar_type[0] != ':' ? s2 : s2.next
break
}
if (s2.type != C.NOTE)
continue
/* have a 2nd choice on beam start */
|
| ︙ | | |
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
|
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
}
staff_tb[st] = {
output: "",
sc_out: ""
}
}
// set the starting clefs of the staves
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (!sy.voices[v])
continue
st = sy.voices[v].st
if (!sy.voices[v].second) { // main voices
sy.staves[st].staffnonote = p_voice.staffnonote
if (p_voice.staffscale)
sy.staves[st].staffscale = p_voice.staffscale
if (sy.voices[v].sep)
sy.staves[st].sep = sy.voices[v].sep
if (sy.voices[v].maxsep)
sy.staves[st].maxsep = sy.voices[v].maxsep;
if (!p_voice.clef.clef_auto)
delete staff_clef[st].autoclef
}
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (!sy.voices[v]
|| sy.voices[v].second) // main voices
continue
st = sy.voices[v].st;
s = p_voice.clef
if (staff_clef[st].autoclef) {
s.clef_type = set_auto_clef(st,
tsfirst,
s.clef_type);
s.clef_line = s.clef_type == 't' ? 2 : 4
}
staff_clef[st].clef = staff_tb[st].clef = s
}
for (st = 0; st <= sy.nstaff; st++)
mid[st] = (sy.staves[st].stafflines.length - 1) * 3
for (s = tsfirst; s; s = s.ts_next) {
if (s.repeat_n)
set_repeat(s)
|
| ︙ | | |
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
|
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
|
-
+
|
new_line = new_type == 't' ? 2 : 4
} else {
new_type = s2.clef_type;
new_line = s2.clef_line
}
if (!staff_clef[st].clef) { // new staff
if (s2.clef_auto) {
if (s2.type != 'a')
if (s2.clef_type != 'a')
p_voice.clef =
clone(p_voice.clef);
p_voice.clef.clef_type = new_type;
p_voice.clef.clef_line = new_line
}
staff_tb[st].clef =
staff_clef[st].clef = p_voice.clef
|
| ︙ | | |
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
|
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
|
-
+
|
}
/* upper and lower space needed by rests */
var rest_sp = [
[18, 18],
[12, 18],
[12, 12],
[0, 12],
[6, 12],
[6, 8],
[10, 10], /* crotchet */
[6, 4],
[10, 0],
[10, 4],
[10, 10]
]
|
| ︙ | | |
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
|
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
|
-
+
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
|
p_v.last_sym = s;
lktsym(s, last_s)
}
/* -- init the symbols at start of a music line -- */
function init_music_line() {
var p_voice, s, s1, s2, s3, last_s, v, st, shr, shrmx, shl, fmt,
var p_voice, s, s1, s2, s3, last_s, v, st, shr, shrmx, shl,
shlp, p_st, top,
nv = voice_tb.length
nv = voice_tb.length,
fmt = tsfirst.fmt
/* initialize the voices */
for (v = 0; v < nv; v++) {
if (!cur_sy.voices[v])
continue
p_voice = voice_tb[v];
p_voice.st = cur_sy.voices[v].st
p_voice.second = cur_sy.voices[v].second;
p_voice.last_sym = p_voice.sym;
/* move the voice to a printed staff */
st = cur_sy.voices[v].st
while (st <= nstaff && !cur_sy.st_print[st])
st++
if (st > nstaff)
continue // no printed staff
p_voice.st = st
if (!p_voice.second) {
staff_tb[st].key = p_voice.ckey
staff_tb[st].meter = p_voice.meter
}
}
// move the first clefs, key signatures and time signatures
// to the staves
s = tsfirst
for (s = p_voice.sym; s && s.time == tsfirst.time; s = s.next) {
fmt = s.fmt
while (s) {
switch (s.type) {
case C.CLEF:
case C.KEY:
case C.METER:
switch (s.type) {
case C.CLEF:
staff_tb[s.st].clef = s
|
| ︙ | | |
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
|
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
|
-
+
|
break
}
unlksym(s)
// fall thru
case C.TEMPO:
case C.BLOCK:
case C.REMARK:
s = s.ts_next
continue
}
break
}
}
// generate the starting clefs, key signatures and time signatures
// add a clef at start of the main voices
last_s = tsfirst
for (v = 0; v < nv; v++) {
|
| ︙ | | |
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
|
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
|
-
+
-
-
+
-
-
+
+
+
|
s.ts_prev = null
if (!s.ts_prev) {
tsfirst = s;
} else {
s.ts_prev.ts_next = s
delete s.seqst
}
if (last_s) {
if (last_s)
last_s.ts_prev = s
if (last_s.type == C.CLEF)
delete last_s.seqst
delete s.clef_small;
}
delete s.clef_small;
delete s.part
s.second = cur_sy.voices[v].second
// (fixme: needed for sample5 X:3 Fugue & staffnonote.xhtml)
if (!cur_sy.st_print[st])
s.invis = true
s.fmt = fmt
}
/* add keysig */
for (v = 0; v < nv; v++) {
if (!cur_sy.voices[v]
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st])
continue
p_voice = voice_tb[v]
s2 = p_voice.ckey
if (s2.k_sf || s2.k_a_acc) {
s = clone(s2)
new_sym(s, p_voice, last_s)
delete s.invis
delete s.part
s.k_old_sf = s2.k_sf // no key cancel
s.fmt = fmt
}
}
/* add time signature (meter) if needed */
if (insert_meter) {
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v];
s2 = p_voice.meter
if (!cur_sy.voices[v]
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st])
// || !s2.a_meter.length)
continue
s = clone(s2)
new_sym(s, p_voice, last_s)
delete s.part
s.fmt = fmt
}
insert_meter = false // no meter any more
}
// add an invisible bar for the various continued elements
for (v = 0; v < nv; v++) {
|
| ︙ | | |
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
|
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
+
-
-
-
-
-
+
-
-
-
|
}
// compute the spacing of the added symbols
self.set_pitch(last_s);
s = tsfirst
s.seqst = true
shlp = 0
while (1) {
s2 = s;
shl = shrmx = 0
do {
self.set_width(s);
shr = s.wl + shlp
if (shr > shrmx)
shrmx = shr;
if (s.wr > shl)
shl = s.wr // left width for next symbol
s = s.ts_next
} while (s != last_s && !s.seqst);
s2.shrink = shrmx;
s2.space = 0
if (s == last_s)
break
shlp = shl
}
for (s = last_s; s.ts_next && !s.ts_next.seqst; s = s.ts_next)
;
// update the spacing before the first old time sequence
shr = 0
if (last_s.type == C.BAR && s2.type == C.CLEF)
s2 = s.ts_next
s.ts_next = null
shl += 4 // (see set_width)
do {
self.set_width(s)
set_allsymwidth()
if (s.a_ly)
ly_set(s)
if (shr < s.wl)
shr = s.wl;
s = s.ts_next
s.ts_next = s2
} while (s && !s.seqst);
last_s.shrink = shl + shr
last_s.space = 0
} // init_music_line()
// check if the tune ends on a measure bar
function check_end_bar() {
var s2,
s = tsfirst
while (s.ts_next)
|
| ︙ | | |
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
|
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
// and sort the pitches in the chords
// and build the chord symbols / annotations
// this function is called only once per tune
function set_words(p_voice) {
var s, s2, nflags, lastnote, res,
start_flag = true,
pitch = 127 /* no note */
// adjust the duration of the notes in a decoration !trem1..4!
function trem_adj(s) {
s.prev.trem2 = true
s.prev.head = ++s.head
if (--s.nflags > 0) {
s.nflags += s.ntrem
} else {
if (s.nflags <= -2) {
s.stemless = true
s.prev.stemless = true
}
s.nflags = s.ntrem
}
s.prev.nflags = s.nflags
} // trem_adj()
for (s = p_voice.sym; s; s = s.next) {
if (s.type == C.NOTE) {
pitch = s.notes[0].pit
break
}
}
|
| ︙ | | |
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
|
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
|
-
+
+
+
+
+
+
+
+
+
|
start_flag = true
if (!s.next && s.prev
&& !s.invis
&& s.prev.head == C.OVALBARS)
s.prev.head = C.SQUARE
break
case C.GRACE:
for (s2 = s.extra; s2; s2 = s2.next)
for (s2 = s.extra; s2; s2 = s2.next) {
s2.notes.sort(abc2svg.pitcmp)
res = identify_note(s2, s2.dur_orig)
s2.head = res[0]
s2.dots = res[1]
s2.nflags = res[2]
if (s2.trem2
&& (!s2.next || s2.next.trem2))
trem_adj(s2)
}
break
case C.NOTE:
case C.REST:
res = identify_note(s, s.dur_orig);
s.head = res[0];
s.dots = res[1];
s.nflags = res[2]
|
| ︙ | | |
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
|
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
|
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
|
s.nflags += s.ntrem
else
s.nflags = s.ntrem
}
if (s.next && s.next.trem2)
break
if (s.trem2) {
s.prev.trem2 = true;
s.prev.nflags = --s.nflags;
s.prev.head = ++s.head
if (s.nflags > 0) {
s.nflags += s.ntrem;
} else {
if (s.nflags <= -2) {
s.stemless = true;
s.prev.stemless = true
}
s.nflags = s.ntrem
trem_adj(s)
}
s.prev.nflags = s.nflags
break
}
nflags = s.nflags
if (s.ntrem)
nflags += s.ntrem
if (s.type == C.REST && s.beam_end
&& !s.beam_on) {
s.beam_end = false;
// s.beam_end = false;
start_flag = true
}
if (start_flag
|| nflags <= 0) {
if (lastnote) {
lastnote.beam_end = true;
lastnote = null
|
| ︙ | | |
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
|
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
|
+
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
-
-
+
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
-
-
+
+
+
|
set_ottava();
// set the clefs and adjust the pitches of all symbol
set_clefs();
self.set_pitch(null)
}
// get the left offsets of the first and other staff systems
/* -- return the left indentation of the staves -- */
function set_indent(first) {
var st, v, w, p_voice, p, i, j, font,
nv = voice_tb.length,
// return [lsh1, lsho]
function get_lshift() {
var st, v, p_v, p1, po, fnt, w,
sy = cur_sy,
lsh1 = 0,
lsho = 0,
nv = voice_tb.length
maxw = 0
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
// get the max width of a voice name/subname
if (!cur_sy.voices[v])
continue
function get_wx(p, wx) {
st = cur_sy.voices[v].st
// if (!cur_sy.st_print[st])
// continue
p = ((first || p_voice.new_name) && p_voice.nm) ?
p_voice.nm : p_voice.snm
if (!p)
var w, j,
continue
if (!font) {
set_font("voice");
font = gene.curfont
}
i = 0
i = 0
p += '\n'
while (1) {
j = p.indexOf("\n", i)
if (j < 0)
w = strwh(p.slice(i))
else
w = strwh(p.slice(i, j))
break
w = strwh(p.slice(i, j))[0] + 12
w = w[0]
if (w > maxw)
maxw = w
if (w > wx)
wx = w
if (j < 0)
break
i = j + 1
}
return wx
} // get_wx()
}
if (font)
maxw += 4 * cwidf(' ');
w = .5 // (width of left bar)
for (st = 0; st <= cur_sy.nstaff; st++) {
if (cur_sy.staves[st].flags
& (OPEN_BRACE2 | OPEN_BRACKET2)) {
w = 12
break
}
if (cur_sy.staves[st].flags & (OPEN_BRACE | OPEN_BRACKET))
w = 6
}
maxw += w
for (v = 0; v < nv; v++) {
p_v = voice_tb[v]
p1 = p_v.nm
po = p_v.snm
if ((p1 || po) && !fnt) {
set_font("voice")
fnt = gene.deffont
}
if (p1) {
w = get_wx(p1, lsh1)
if (w > lsh1)
lsh1 = w
}
if (po) {
w = get_wx(po, lsho)
if (w > lsho)
lsho = w
}
}
// add the width of the braces/brackets
w = 0
while (sy) {
for (st = 0; st <= sy.nstaff; st++) {
if (sy.staves[st].flags
& (OPEN_BRACE2 | OPEN_BRACKET2)) {
w = 12
break
}
if (sy.staves[st].flags & (OPEN_BRACE | OPEN_BRACKET))
w = 6
}
if (w == 12)
break
sy = sy.next
}
lsh1 += w
lsho += w
return [lsh1, lsho]
} // get_lshift()
/* -- return the left indentation of the staves -- */
if (first) // if %%indent
maxw += cfmt.indent
return maxw
function set_indent(lsh) {
var st, v, w, p_voice, p, i, j, font,
vnt = 0,
nv = voice_tb.length
// name or subname?
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
if (!cur_sy.voices[v]
|| !gene.st_print[p_voice.st])
continue
if (p_voice.new_name) {
vnt = 2 // full name
break
}
if (p_voice.snm)
vnt = 1 // subname
}
gene.vnt = vnt // voice name type for draw
return vnt == 2 ? lsh[0] : lsh[1]
}
/* -- decide on beams and on stem directions -- */
/* this routine is called only once per tune */
function set_beams(sym) {
var s, t, g, beam, s_opp, n, m, mid_p, pu, pd,
laststem = -1
for (s = sym; s; s = s.next) {
if (s.type != C.NOTE) {
if (s.type != C.GRACE)
continue
g = s.extra
if (g.stem == 2) { /* opposite gstem direction */
s_opp = s
continue
}
if (!s.stem
if (!s.stem)
&& (s.stem = s.multi) == 0)
s.stem = 1
s.stem = s.multi || 1
for (; g; g = g.next) {
g.stem = s.stem;
g.multi = s.multi
}
continue
}
if (!s.stem /* if not explicitly set */
&& (s.stem = s.multi) == 0) { /* and alone on the staff */
if (!s.stem && s.multi)
s.stem = s.multi
if (!s.stem) { // if note alone on the staff
mid_p = s.mid / 3 + 18
/* notes in a beam have the same stem direction */
if (beam) {
s.stem = laststem
} else if (s.beam_st && !s.beam_end) { // beam start
beam = true;
|
| ︙ | | |
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
|
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
|
-
+
-
-
-
-
-
-
+
+
|
}
}
/* -- set the stem height -- */
/* this routine is called only once per tune */
// (possible hook)
Abc.prototype.set_stems = function() {
var s, s2, g, slen, scale,ymn, ymx, nflags, ymin, ymax, res
var s, s2, g, slen, scale,ymn, ymx, nflags, ymin, ymax
for (s = tsfirst; s; s = s.ts_next) {
if (s.type != C.NOTE) {
if (s.type != C.GRACE)
continue
ymin = ymax = s.mid
for (g = s.extra; g; g = g.next) {
res = identify_note(s, g.dur);
g.head = res[0];
g.dots = res[1];
g.nflags = res[2];
slen = GSTEM
if (g.nflags > 1)
slen += 1.2 * (g.nflags - 1);
ymn = 3 * (g.notes[0].pit - 18);
ymx = 3 * (g.notes[g.nhd].pit - 18)
if (s.stem >= 0) {
g.y = ymn;
g.ys = ymx + slen;
ymx = Math.round(g.ys)
} else {
g.y = ymx;
g.ys = ymn - slen;
ymn = Math.round(g.ys)
}
ymx += 2;
ymn -= 2
ymx += 4
ymn -= 4
if (ymn < ymin)
ymin = ymn
else if (ymx > ymax)
ymax = ymx;
g.ymx = ymx;
g.ymn = ymn
}
|
| ︙ | | |
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
|
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
-
+
-
|
if (s.notes[s.nhd].tie)
ymx += 3;
s.ymx = ymx + 4
}
}
}
/* -- move the symbols of an empty staff to the next one -- */
function sym_staff_move(st) {
for (var s = tsfirst; s; s = s.ts_next) {
if (s.nl)
break
if (s.st == st
&& s.type != C.CLEF) {
s.st++;
s.invis = true
}
}
}
// generate a block symbol
var blocks = [] // array of delayed block symbols
// (possible hook)
Abc.prototype.block_gen = function(s) {
switch (s.subtype) {
case "leftmargin":
case "rightmargin":
case "pagescale":
case "pagewidth":
case "scale":
case "staffwidth":
self.set_format(s.subtype, s.param)
break
case "mc_start": // multicol start
multicol = {
posy: posy,
maxy: posy,
lmarg: cfmt.leftmargin,
rmarg: cfmt.rightmargin
lm: cfmt.leftmargin,
rm: cfmt.rightmargin,
w: cfmt.pagewidth,
sc: cfmt.scale
}
break
case "mc_new": // multicol new
if (!multicol) {
error(1, s, "%%multicol new without start")
break
}
if (posy > multicol.maxy)
multicol.maxy = posy
cfmt.leftmargin = multicol.lmarg
cfmt.rightmargin = multicol.rmarg
cfmt.leftmargin = multicol.lm
cfmt.rightmargin = multicol.rm
img.chg = true
set_page()
cfmt.pagewidth = multicol.w
cfmt.scale = multicol.sc
posy = multicol.posy
img.chg = 1 //true
break
case "mc_end": // multicol end
if (!multicol) {
error(1, s, "%%multicol new without start")
break
}
if (posy < multicol.maxy)
posy = multicol.maxy
cfmt.leftmargin = multicol.lmarg
cfmt.rightmargin = multicol.rmarg
cfmt.leftmargin = multicol.lm
cfmt.rightmargin = multicol.rm
cfmt.pagewidth = multicol.w
cfmt.scale = multicol.sc
multicol = undefined
blk_flush()
img.chg = true
img.chg = 1 //true
set_page()
break
case "ml":
blk_flush()
user.img_out(s.text)
break
case "newpage":
if (!user.page_format)
|
| ︙ | | |
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
|
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
write_title(s.text, true)
break
case "vskip":
vskip(s.sk);
break
}
}
// -- move some symbols of an empty staff to the next one --
function sym_staff_move(st) {
for (var s = tsfirst; s; s = s.ts_next) {
if (s.nl)
break
if (s.st == st
&& s.type != C.CLEF) {
s.st++
if (s.type != C.TEMPO)
s.invis = true
}
}
} // sym_staff_move()
/* -- define the start and end of a piece of tune -- */
/* tsnext becomes the beginning of the next line */
function set_piece() {
var s, last, p_voice, st, v, nv, tmp,
non_empty = [],
non_empty_gl = [],
|
| ︙ | | |
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
|
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
|
-
-
-
-
|
// ledger lines
// index = line number
// values = [x symbol, x start, x stop]
p_staff.hlu = [] // above the staff
p_staff.hld = [] // under the staff
if (!non_empty_gl[st]) {
p_staff.botbar = p_staff.topbar = 0
continue
}
l = p_staff.stafflines.length;
p_staff.topbar = 6 * (l - 1)
for (i = 0; i < l - 1; i++) {
switch (p_staff.stafflines[i]) {
case '.':
case '-':
|
| ︙ | | |
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
|
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
|
+
+
|
p_staff.topbar += 6
} else { // no line: big bar
p_staff.botbar -= 12;
p_staff.topbar += 12
continue // no helper line
}
}
if (!non_empty_gl[st])
continue
// define the helper lines
p_staff.hll = 17 + i * 2 // pitch of lowest note
// without helper line
// ('D' when standard staff)
p_staff.hlmap = new Int8Array(new Array((l - i + 1) * 2))
for (j = 1; i < l; i++, j += 2) {
|
| ︙ | | |
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
|
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
|
-
+
-
-
+
-
+
|
/* set the last empty staves */
set_brace()
sy.st_print = new Uint8Array(non_empty);
/* define the offsets of the measure bars */
set_top_bot()
/* move the symbols of the empty staves to the next staff */
// move the symbols of the empty staves to the next staff
//fixme: could be optimized (use a old->new staff array)
for (st = 0; st < nstaff; st++) {
if (!non_empty_gl[st])
sym_staff_move(st)
}
/* let the last empty staff have a full height */
// set a null height if the last staff is empty
if (!non_empty_gl[nstaff])
staff_tb[nstaff].topbar = 0;
staff_tb[nstaff].topbar = 0
/* initialize the music line */
init_music_line();
// keep the array of the staves to be printed
gene.st_print = new Uint8Array(non_empty_gl)
|
| ︙ | | |
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
|
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
|
-
+
-
+
-
+
-
-
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
|
}
tsfirst = null /* no more notes */
}
/* -- generate the music -- */
// (possible hook)
Abc.prototype.output_music = function() {
var v, lwidth, indent, line_height, ts1st, tslast, p_v,
var v, lwidth, indent, lsh, line_height, ts1st, tslast, p_v,
nv = voice_tb.length
set_global()
if (nv > 1) // if many voices
self.set_stem_dir() // set the stems direction in 'multi'
for (v = 0; v < nv; v++)
set_beams(voice_tb[v].sym); /* decide on beams */
self.set_stems() // set the stem lengths
gen_init() // output the blocks and define the page layout
if (!tsfirst)
return
set_acc_shft() // set the horizontal offset of accidentals
if (nv > 1) { // if many voices
set_rest_offset(); /* set the vertical offset of rests */
set_overlap(); /* shift the notes on voice overlap */
}
set_allsymwidth(); /* set the width of all symbols */
set_allsymwidth(1) // set the width of all symbols
indent = set_indent(true)
lsh = get_lshift()
/* if single line, adjust the page width */
if (cfmt.singleline) {
v = get_ck_width();
lwidth = indent + v[0] + v[1] + get_width(tsfirst, null)[0];
img.width = lwidth * cfmt.scale + img.lm + img.rm + 2
lwidth = lsh[0] + v[0] + v[1] + get_width(tsfirst, null)[0]
v = cfmt.singleline == 2 // if as wide as the page width
? get_lwidth() : lwidth
if (v > lwidth)
lwidth = v
else
img.width = lwidth * cfmt.scale + img.lm + img.rm + 2
} else {
/* else, split the tune into music lines */
lwidth = get_lwidth();
cut_tune(lwidth, indent)
cut_tune(lwidth, lsh)
}
// save symbol pointers for play
ts1st = tsfirst
v = nv
while (--v >= 0)
voice_tb[v].osym = voice_tb[v].sym
spf_last = 0 // last spacing factor
while (1) { /* loop per music line */
set_piece();
indent = set_indent(lsh)
if (!line_height
&& cfmt.indent
&& indent < cfmt.indent)
indent = cfmt.indent
self.set_sym_glue(lwidth - indent)
if (realwidth) {
if (indent)
posx += indent;
draw_sym_near(); // delayed output
line_height = set_staff();
draw_systems(indent);
draw_all_sym();
delayed_update();
//fixme: KO if at start of tune (the header is generated)
if (output) // if some music
vskip(line_height)
vskip(line_height)
if (indent)
posx -= indent;
while (blocks.length)
self.block_gen(blocks.shift())
}
blk_flush()
while (blocks.length)
self.block_gen(blocks.shift())
if (tslast)
tslast.ts_next.ts_prev = tslast
if (!tsnext)
break
tsnext.ts_prev.ts_next = // (restore for play)
tsfirst = tsnext
// next line
gen_init()
if (!tsfirst)
break
tslast = tsfirst.ts_prev
tsfirst.ts_prev = null;
set_sym_line();
lwidth = get_lwidth() // the image size may have changed
indent = set_indent()
}
// restore for play
tsfirst = ts1st
v = nv
while (--v >= 0) {
p_v = voice_tb[v]
if (p_v.sym && p_v.s_prev)
p_v.sym.prev = p_v.s_prev
p_v.sym = p_v.osym
}
}
|
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - parse.js - ABC parse
//
// Copyright (C) 2014-2021 Jean-Francois Moine
// Copyright (C) 2014-2023 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
return
}
pit[i] = abc2svg.pab40(note.pit, note.acc)
}
}
return pit[1] - pit[0]
}
// transpose a note for the score
// Return the transposed real accidental
function nt_trans(nt,
a) { // real accidental
var ak, an, d, b40, n
if (typeof a == "object") { // if microtonal accidental
n = a[0] // numerator
d = a[1] // denominator
a = n > 0 ? 1 : -1 // base accidental for transpose
}
b40 = abc2svg.pab40(nt.pit, a)
+ curvoice.tr_sco // base-40 transposition
nt.pit = abc2svg.b40p(b40) // new pitch
an = abc2svg.b40a(b40) // new accidental
if (!d) { // if not a microtonal accidental
if (an == -3) // if triple sharp/flat
return an
a = an
if (nt.acc) { // if old accidental
if (!a)
a = 3 // required natural
} else {
if (!curvoice.ckey.k_none) // if normal key
a = 0 // no accidental
}
nt.acc = a
return an
}
// set the microtonal accidental after transposition
switch (a) {
case -2:
if (n > 0)
n -= d * 2
else
n -= d
break
case -1:
if (n > 0)
n -= d
break
case 0:
case 3:
if (n > 0)
n -= d
else
n += d
break
case 1:
if (n < 0)
n += d
break
case 2:
if (n < 0)
n += d * 2
else
n += d
break
}
nt.acc = [n, d]
return an
} // nt_trans()
// set the linebreak character
function set_linebreak(param) {
var i, item
for (i = 0; i < 128; i++) {
if (char_tb[i] == "\n")
|
| ︙ | | |
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
-
+
+
|
sym_link(s)
return s
}
// set the voice parameters
// (possible hook)
Abc.prototype.set_vp = function(a) {
var s, item, pos, val, clefpit, tr_p
var s, item, pos, val, clefpit,
tr_p = 0
while (1) {
item = a.shift()
if (!item)
break
if (item.slice(-1) == '='
&& !a.length) {
|
| ︙ | | |
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
|
-
+
+
-
+
+
-
-
+
+
|
// (instrument=M == instrument=M/M)
item = a.shift()
val = item.indexOf('/')
if (val < 0) {
val = get_interval('c' + item)
if (val == undefined)
break
curvoice.sndtran = val
curvoice.sound = val
tr_p |= 2
val = 0
} else {
val = get_interval('c' + item.slice(val + 1))
if (val == undefined)
break
curvoice.sndtran = val
curvoice.sound = val
tr_p |= 2
val = get_interval(item.replace('/', ''))
if (val == undefined)
break
}
curvoice.transp = cfmt.sound ? curvoice.sndtran : val
tr_p = 1
curvoice.score = cfmt.sound ? curvoice.sound : val
tr_p |= 1
break
case "map=": // %%voicemap
curvoice.map = a.shift()
break
case "name=":
case "nm=":
curvoice.nm = a.shift()
|
| ︙ | | |
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
|
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
|
-
-
+
+
-
-
+
+
-
+
-
-
+
+
|
// score=MN
// (score=M == score=Mc)
item = a.shift()
if (cfmt.sound)
break
val = get_interval(item, true)
if (val != undefined) {
curvoice.transp = val
tr_p = 1
curvoice.score = val
tr_p |= 1
}
break
case "shift=":
if (cfmt.nedo) {
syntax(1, errs.notransp)
break
}
val = get_interval(a.shift())
if (val != undefined) {
curvoice.shift = curvoice.sndsh = val
tr_p = 1
curvoice.shift = val
tr_p = 3
}
break
case "sound=":
if (cfmt.nedo) {
syntax(1, errs.notransp)
break
}
// concert-score display: apply sound=
// sounding-score display: apply sound= only if M != c/C
// sound: apply sound=
val = get_interval(a.shift())
if (val == undefined)
break
curvoice.sndtran = val
curvoice.sound = val
if (cfmt.sound)
curvoice.transp = val
tr_p = 1
curvoice.score = val
tr_p |= 2
break
case "subname=":
case "sname=":
case "snm=":
curvoice.snm = a.shift()
if (curvoice.snm[0] == '"')
curvoice.snm = curvoice.snm.slice(1, -1);
|
| ︙ | | |
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
|
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
|
-
+
-
-
+
+
|
syntax(1, errs.notransp)
break
}
val = get_transp(a.shift())
if (val == undefined) {
syntax(1, errs.bad_transp)
} else {
curvoice.sndtran = val
curvoice.sound = val
if (cfmt.sound)
curvoice.transp = val
tr_p = 1
curvoice.score = val
tr_p = 2
}
break
default:
switch (item.slice(0, 4)) {
case "treb":
case "bass":
case "alto":
|
| ︙ | | |
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
|
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
|
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
|
s = new_clef(s)
if (s) {
if (clefpit)
s.clefpit = clefpit
get_clef(s)
}
}
// if transposition
if (tr_p)
set_transp()
if (tr_p) {
curvoice.tr_p = tr_p // keep this key signature
tr_p = (curvoice.score | 0)
+ (curvoice.shift | 0)
+ (cfmt.transp | 0)
if (tr_p)
curvoice.tr_sco = tr_p // b40 interval
else if (curvoice.tr_sco)
curvoice.tr_sco = 0
tr_p = (curvoice.sound | 0) + (curvoice.shift | 0)
if (tr_p)
curvoice.tr_snd = abc2svg.b40m(tr_p + 122) - 36
// semi-tone interval
else if (curvoice.tr_snd)
curvoice.tr_snd = 0
}
} // set_vp()
// set the K: / V: parameters
function set_kv_parm(a) { // array of items
if (!curvoice.init) { // add the global parameters if not done yet
curvoice.init = true
if (info.V) {
if (info.V['*'])
a = info.V['*'].concat(a)
if (info.V[curvoice.id])
a = info.V[curvoice.id].concat(a)
if (info.V[curvoice.id])
a = info.V[curvoice.id].concat(a)
if (info.V['*'])
a = info.V['*'].concat(a)
}
}
if (a.length)
self.set_vp(a)
} // set_kv_parm()
// memorize the K:/V: parameters
|
| ︙ | | |
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
|
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
|
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
|
else
info.V[vid] = a
}
// K: key signature
// return the key and the voice/clef parameters
function new_key(param) {
var i, clef, key_end, c, tmp, exp,
var i, key_end, c, tmp, note,
sf = "FCGDAEB".indexOf(param[0]) - 1,
mode = 0,
s = {
type: C.KEY,
dur: 0
}
// set the accidentals when K: with modified accidentals
function set_k_acc(s, sf) {
var i, j, n, nacc, p_acc,
accs = [],
pits = []
if (sf > 0) {
for (nacc = 0; nacc < sf; nacc++) {
accs[nacc] = 1; // sharp
pits[nacc] = [26, 23, 27, 24, 21, 25, 22][nacc]
}
} else {
for (nacc = 0; nacc < -sf; nacc++) {
accs[nacc] = -1; // flat
pits[nacc] = [22, 25, 21, 24, 20, 23, 26][nacc]
}
}
n = s.k_a_acc.length
for (i = 0; i < n; i++) {
p_acc = s.k_a_acc[i]
for (j = 0; j < nacc; j++) {
if (pits[j] == p_acc.pit) {
accs[j] = p_acc.acc
break
}
}
if (j == nacc) {
accs[j] = p_acc.acc;
pits[j] = p_acc.pit
nacc++
}
}
for (i = 0; i < nacc; i++) {
p_acc = s.k_a_acc[i]
if (!p_acc)
p_acc = s.k_a_acc[i] = {}
p_acc.acc = accs[i];
p_acc.pit = pits[i]
}
} // set_k_acc()
// code of new_key()
set_ref(s);
// tonic
i = 1
if (sf < -1) {
switch (param[0]) {
case 'H': // bagpipe
|
| ︙ | | |
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
|
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
|
-
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
|
param = param.replace(/\w+\s*/, '')
// [exp] accidentals
if (param.indexOf("exp ") == 0) {
param = param.replace(/\w+\s*/, '')
if (!param)
syntax(1, "No accidental after 'exp'");
exp = true
s.exp = 1 //true
}
c = param[0]
if (c == '^' || c == '_' || c == '=') {
s.k_a_acc = [];
tmp = new scanBuf;
tmp.buffer = param
do {
var note = parse_acc_pit(tmp)
note = parse_acc_pit(tmp)
if (!note)
break
s.k_a_acc.push(note);
c = param[tmp.index]
while (c == ' ')
c = param[++tmp.index]
} while (c == '^' || c == '_' || c == '=');
if (!exp)
set_k_acc(s, sf)
param = param.slice(tmp.index)
} else if (exp && param.indexOf("none") == 0) {
} else if (s.exp && param.indexOf("none") == 0) {
sf = 0
param = param.replace(/\w+\s*/, '')
}
}
if (sf < -7 || sf > 7) {
syntax(1, "Key with double sharps/flats")
if (sf > 7)
sf -= 12
else
sf += 12
}
s.k_sf = sf;
// set the map of the notes with accidentals
s.k_map = s.k_bagpipe && !sf
? abc2svg.keys[9] // implicit F# and C#
: abc2svg.keys[sf + 7]
if (s.k_a_acc) {
s.k_map = []
s.k_map = new Int8Array(s.k_map)
i = s.k_a_acc.length
while (--i >= 0) {
note = s.k_a_acc[i]
s.k_map[(note.pit + 19) % 7] = note.acc
}
} else {
s.k_map = s.k_bagpipe && !sf
? abc2svg.keys[9] // implicit F# and C#
: abc2svg.keys[sf + 7]
}
s.k_mode = mode
// key note as base-40
s.k_b40 = [1,24,7,30,13,36,19, 2 ,25,8,31,14,37,20,3][sf + 7]
return [s, info_split(param)]
|
| ︙ | | |
887
888
889
890
891
892
893
894
895
896
897
898
899
900
|
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
|
+
+
+
+
|
if (p[i] == '=') {
val = p.substring(++i).match(/^(\d+)\/(\d+)$/)
if (!val) {
syntax(1, "Bad duration '$1' in M:", p.substring(i))
return
}
wmeasure = C.BLEN * val[1] / val[2]
}
if (!wmeasure) {
syntax(1, errs.bad_val, 'M:')
return
}
s.wmeasure = wmeasure
if (cfmt.writefields.indexOf('M') < 0)
s.a_meter = []
if (parse.state != 3) {
|
| ︙ | | |
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
|
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
|
-
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
|
if (!s.tempo || isNaN(s.tempo)) {
syntax(1, "Bad tempo value")
return
}
}
}
if (parse.state < 2) { // if in tune header
if (parse.state < 2 // if in tune header
|| (!curvoice.time && !glovar.tempo)) {
info.Q = txt
glovar.tempo = s
return
}
if (!curvoice.time)
var tim = curvoice.time
glovar.tempo = s
else
sym_link(s)
if (!glovar.tempo)
syntax(0, "No previous tempo")
if (!parse.ctrl)
parse.ctrl = {}
if (!parse.ctrl[tim])
parse.ctrl[tim] = {}
parse.ctrl[tim].tempo = s
s.v = par_sy.top_voice
s.p_v = voice_tb[s.v]
s.fmt = cfmt
s.st = s.p_v.st
s.time = tim
}
// treat the information fields which may embedded
function do_info(info_type, text) {
var s, d1, d2, a, vid
var s, d1, d2, a, vid, tim, v, p_v
// skip this line if the current voice is ignored
// but keep the time related definitions
if (curvoice && curvoice.ignore
&& info_type != 'V')
return
if (curvoice && curvoice.ignore) {
switch (info_type) {
default:
return
case 'P':
case 'Q':
case 'V':
break
}
}
switch (info_type) {
// info fields in any state
case 'I':
self.do_pscom(text)
break
|
| ︙ | | |
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
|
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
|
-
-
-
+
+
+
-
-
+
-
+
+
+
+
+
+
+
+
+
|
case 'P':
if (!parse.state)
break
if (parse.state == 1) {
info.P = text
break
}
if (!parse.part)
parse.part = {}
if (parse.part[curvoice.time]) // P: already defined
// memorize the part in the control
tim = curvoice.time
break
s = {
text: text,
time: curvoice.time
time: tim
}
set_ref(s)
if (cfmt.writefields.indexOf(info_type) < 0)
s.invis = true
parse.part[curvoice.time] = s
if (!parse.ctrl)
parse.ctrl = {}
if (!parse.ctrl[tim])
parse.ctrl[tim] = {}
parse.ctrl[tim].part = s
s.v = par_sy.top_voice
s.p_v = voice_tb[s.v]
s.fmt = cfmt
s.st = s.p_v.st
break
case 'Q':
if (!parse.state)
break
new_tempo(text)
break
case 'V':
|
| ︙ | | |
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
|
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
|
-
-
+
|
delete s.text
}
curvoice.tie_s_rep = null // no tie anymore on new variant
}
// handle the accidentals (ties and repeat)
if (s.text) {
s.rbstop = 2;
s.rbstart = 2
s.rbstart = s.rbstop = 2
if (s.text[0] == '1') {
curvoice.tie_s_rep = curvoice.tie_s
if (curvoice.acc_tie)
curvoice.acc_tie_rep = curvoice.acc_tie.slice()
else if (curvoice.acc_tie_rep)
curvoice.acc_tie_rep = null
} else {
|
| ︙ | | |
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
|
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
|
-
|
}
}
}
/* set some flags */
switch (bar_type) {
case "[":
s.rbstop = 2
case "[]":
case "[|]":
s.invis = true;
bar_type = s.rbstart ? "[" : "[]"
break
case ":|:":
case ":||:":
|
| ︙ | | |
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
|
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
|
-
+
|
return a_vf
}
// split an info string
function info_split(text) {
if (!text)
return []
var a = text.match(/[^\s"=]+=?|"[^"]+"/g) // "
var a = text.match(/[^\s"=]+=?|"[^"]*"/g) // "
if (!a) {
//fixme: bad error text
syntax(1, "Unterminated string")
return []
}
return a
}
|
| ︙ | | |
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
|
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
|
-
+
|
if (!res[0])
return [1, 1];
num = res[1] || 1;
den = res[3] || 1
if (!res[3])
den *= 1 << res[2].length;
line.index = reg_dur.lastIndex
return [num, den]
return [+num, +den]
}
// parse the note accidental and pitch
function parse_acc_pit(line) {
var note, acc, pit, d, nd,
c = line.char()
|
| ︙ | | |
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
|
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
|
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
|
line.index++
return ty + C.SL_BELOW
}
return ty + C.SL_AUTO
}
// on end of slur, create the slur
function slur_add(enote, e_is_note) {
var i, s, sl, snote, s_is_note
function slur_add(s, nt) { // nt = note if slur ending on note
var i, s2, sl
// go back and find the last start of slur
for (i = curvoice.sls.length; --i >= 0; ) {
sl = curvoice.sls[i]
snote = sl.note
s_is_note = sl.is_note
delete sl.is_note
// the slur must not start and stop on a same symbol
if (snote.s != enote.s) {
sl.note = enote
if (e_is_note)
sl.is_note = e_is_note
s = s_is_note ? snote : snote.s
if (!s.sls)
s.sls = [];
s.sls.push(sl)
if (sl.ss == s)
continue
curvoice.sls.splice(i, 1)
sl.se = s // ending symbol
if (nt)
sl.nte = nt
s2 = sl.ss // start of slur
if (!s2.sls)
s2.sls = []
s2.sls.push(sl)
curvoice.sls.splice(i, 1)
// set a flag on the start symbol if slur from a note
if (s_is_note)
snote.s.sl1 = true
// set a flag if the slur starts on a grace note
if (sl.grace)
sl.grace.sl1 = true
// set a flag if the slur starts on a grace note
if (sl.grace)
sl.grace.sl1 = true
// set a flag if the slur ends on a grace note
if (enote.s.grace)
enote.s.sl2 = true
return
}
}
return
}
if (enote.grace) {
error(1, enote.s, errs.bad_slur_end)
return
}
// the lack of a starting slur may be due to a repeat
for (s = enote.s.prev; s; s = s.prev) {
if (s.type == C.BAR
&& s.bar_type[0] == ':'
&& s.text) {
if (!s.sls)
s.sls = [];
s.sls.push({
for (s2 = s.prev; s2; s2 = s2.prev) {
if (s2.type == C.BAR
&& s2.bar_type[0] == ':'
&& s2.text) {
if (!s2.sls)
s2.sls = [];
s2.sls.push({
note: enote,
//fixme: should go back to the bar "|1" and find the slur type...
ty: C.SL_AUTO
ty: C.SL_AUTO,
ss: s2,
se: s
})
if (e_is_note)
s.sls[s.sls.length - 1].is_note = e_is_note
if (nt)
s2.sls[s2.sls.length - 1].nte = nt
return
}
}
syntax(1, "End of slur without start")
// syntax(1, "End of slur without start")
if (!s.sls)
s.sls = [];
s.sls.push({
ty: C.SL_AUTO,
se: s,
loc: 'i' // no slur start
})
if (nt)
s.sls[s.sls.length - 1].nte = nt
}
// convert a diatonic pitch and accidental to a MIDI pitch with cents
function pit2mid(pit, acc) {
var p = [0, 2, 4, 5, 7, 9, 11][pit % 7], // chromatic pitch
o = ((pit / 7) | 0) * 12, // octave
p0, p1, s, b40
|
| ︙ | | |
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
|
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
|
+
|
if (!not1.tie_ty)
continue
if (not1.midi == mid
&& (!se
|| !not1.tie_e)) { // (if unison)
not2.tie_s = not1
not2.s = s
delete not2.acc // (if transposing)
if (se) {
not1.tie_e = not2
not1.s = tie_s
}
nt++
break
}
|
| ︙ | | |
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
|
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
|
+
|
s.ti2 = true
} // do_ties()
// (possible hook)
Abc.prototype.new_note = function(grace, sls) {
var note, s, in_chord, c, dcn, type, tie_s, acc_tie,
i, n, s2, nd, res, num, dur, apit, div, ty,
dpit = 0,
sl1 = [],
line = parse.line,
a_dcn_sav = a_dcn // save parsed decoration names
a_dcn = []
parse.stemless = false;
s = {
|
| ︙ | | |
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
|
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
|
+
+
+
+
|
switch (c) {
case 'X':
s.invis = true
case 'Z':
s.type = C.MREST;
c = line.next_char()
s.nmes = (c > '0' && c <= '9') ? line.get_int() : 1;
if (curvoice.wmeasure == 1) {
error(1, s, "multi-measure rest, but no measure!")
return
}
s.dur = curvoice.wmeasure * s.nmes
// ignore if in second voice
if (curvoice.second) {
delete curvoice.eoln // ignore the end of line
curvoice.time += s.dur
return //null
|
| ︙ | | |
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
|
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
|
-
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
+
-
-
+
-
-
-
+
+
+
+
|
s.grace ? C.BLEN / 4 :
curvoice.ulen < 0 ?
C.BLEN :
curvoice.ulen)
if (!note)
return //null
// transpose
if (curvoice.octave)
note.pit += curvoice.octave * 7
// get the real accidental
apit = note.pit + 19 // pitch from C-1
i = note.acc
// get the explicit or implicit accidental
if (i) {
curvoice.acc[apit] = i
} else {
i = curvoice.acc[apit]
if (!i) {
if (cfmt["propagate-accidentals"][0] == 'p')
i = curvoice.acc[apit % 7]
else
i = curvoice.acc[apit]
if (!i && acc_tie)
i = acc_tie[apit]
if (!i)
i = curvoice.ckey.k_map[apit % 7] || 0
}
if (i) {
if (cfmt["propagate-accidentals"][0] == 'p')
curvoice.acc[apit % 7] = i
else if (cfmt["propagate-accidentals"][0] != 'n')
curvoice.acc[apit] = i
}
if (acc_tie && acc_tie[apit])
i = acc_tie[apit] // tied note
// map
if (curvoice.map
&& maps[curvoice.map])
set_map(note, i)
// set the MIDI pitch
if (!note.midi) // if not map play
if (!note.midi) // if not map play
note.midi = pit2mid(apit, i)
// transpose
if (curvoice.tr_sco) {
i = nt_trans(note, i)
if (i == -3) { // if triple sharp/flat
error(1, s, "triple sharp/flat")
i = note.acc > 0 ? 1 : -1
note.pit += i
note.acc = i
}
dpit = note.pit + 19 - apit
}
if (curvoice.ckey.k_sndtran)
note.midi += abc2svg.b40m(curvoice.ckey.k_sndtran +
122) - 36
if (curvoice.tr_snd)
note.midi += curvoice.tr_snd
//fixme: does not work if transposition
if (i) {
switch (cfmt["writeout-accidentals"][1]) {
case 'd': // added
s2 = curvoice.ckey
if (!s2.k_a_acc)
break
for (n = 0; n < s2.k_a_acc.length; n++) {
if ((s2.k_a_acc[n].pit - note.pit)
% 7 == 0) {
note.acc = i
break
}
}
break
case 'l': // all
note.acc = i
break
}
}
// starting slurs
if (sl1.length) {
while (1) {
i = sl1.shift()
if (!i)
break
curvoice.sls.push({
is_note: true,
note: note,
ty: i
ty: i,
ss: s,
nts: note // starting note
})
}
note.s = s; // link the note to the chord
}
if (a_dcn.length)
if (a_dcn.length) {
s.time = curvoice.time // (needed for !tie)!
dh_cnv(s, note)
}
s.notes.push(note)
if (!in_chord)
break
// in chord: get the ending slurs and the ties
c = line.char()
while (1) {
switch (c) {
case ')':
note.s = s
slur_add(note, true)
slur_add(s, note)
c = line.next_char()
continue
case '-':
note.tie_ty = parse_vpos()
note.s = s
curvoice.tie_s = s
s.ti1 = true
if (curvoice.acc[apit]
|| (acc_tie
&& acc_tie[apit])) {
if (!curvoice.acc_tie)
curvoice.acc_tie = []
curvoice.acc_tie[apit] =
curvoice.acc[apit] ||
acc_tie[apit]
i = curvoice.acc[apit]
if (acc_tie && acc_tie[apit])
i = acc_tie[apit]
curvoice.acc_tie[apit] = i
}
c = line.char()
continue
case '.':
c = line.next_char()
switch (c) {
case '-':
|
| ︙ | | |
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
|
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
|
-
-
-
+
+
+
+
|
// handle the starting slurs
if (sls.length) {
while (1) {
i = sls.shift()
if (!i)
break
s.notes[0].s = s
curvoice.sls.push({
note: s.notes[0],
ty: i
ty: i,
ss: s
// no starting note
})
if (grace)
curvoice.sls[curvoice.sls.length - 1].grace =
grace
}
}
// the duration of the chord is the duration of the 1st note
s.dur_orig = s.notes[0].dur;
s.dur = s.notes[0].dur * curvoice.dur_fact
break
}
if (s.grace && s.type != C.NOTE) {
syntax(1, errs.bad_grace)
return //null
}
if (s.notes) { // if note or rest
|
| ︙ | | |
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
|
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
|
+
-
-
-
+
+
+
+
|
s.notes[i].s = s
}
curvoice.tie_s = grace || s
curvoice.tie_s.ti1 = true
for (i = 0; i <= s.nhd; i++) {
note = s.notes[i]
apit = note.pit + 19 // pitch from C-1
- dpit // (if transposition)
if (curvoice.acc[apit]
|| (acc_tie
&& acc_tie[apit])) {
if (!curvoice.acc_tie)
curvoice.acc_tie = []
curvoice.acc_tie[apit] =
curvoice.acc[apit] ||
acc_tie[apit]
n = curvoice.acc[apit]
if (acc_tie && acc_tie[apit])
n = acc_tie[apit]
curvoice.acc_tie[apit] = n
}
}
c = line.char()
continue
}
break
}
|
| ︙ | | |
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
|
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
|
+
-
+
+
+
-
+
+
+
-
+
+
|
s.stemless = true
s.iend = parse.bol + line.index
return s
}
// adjust the duration of the elements in a tuplet
function tp_adj(s, fact) {
var d,
var tim = s.time
tim = s.time,
to = curvoice.time - tim, // previous delta time
tt = to * fact // new delta time
curvoice.time = tim + (curvoice.time - tim) * fact
curvoice.time = tim + tt
while (1) {
//fixme: tuplets in grace notes?
s.in_tuplet = true
if (!s.grace) {
s.time = tim
if (s.dur) {
d = Math.round(s.dur * tt / to) // new duration
to -= s.dur // old remaining time
s.dur *= fact
s.dur = d
tt -= s.dur // new remaining time
tim += s.dur
}
}
if (!s.next) {
if (s.tpe)
s.tpe++
else
|
| ︙ | | |
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
|
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
|
+
-
|
line = parse.line,
i = line.index, // in case no deco end
dcn = ""
while (1) {
c = line.next_char()
if (!c) {
line.index = i
syntax(1, "No end of decoration")
line.index = i;
return
}
if (c == '!')
break
dcn += c
}
if (ottava[dcn] != undefined) {
|
| ︙ | | |
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
|
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
|
-
-
-
-
-
-
-
-
-
-
-
-
-
|
var c, idx, type, k, s, dcn, i, n, text, note
while (1) {
c = line.char()
if (!c)
break
// skip definitions if the current voice is ignored
if (curvoice.ignore) {
while (1) {
if (c == '['
&& line.buffer[line.index + 1] == 'V'
&& line.buffer[line.index + 2] == ':')
break // [V:nn] found
c = line.next_char()
if (!c)
return
}
}
// check if start of a macro
if (!in_mac && maci[c]) {
n = undefined
for (k in mac) {
if (!mac.hasOwnProperty(k)
|| k[0] != c)
continue
|
| ︙ | | |
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
|
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
|
-
+
-
+
|
if (c > '0' && c <= '9') { // tuplet
if (grace) {
syntax(1, errs.bad_grace)
break
}
var pplet = line.get_int(),
qplet = qplet_tb[pplet],
rplet = pplet,
rplet = pplet
c = line.char()
c = line.char()
if (c == ':') {
c = line.next_char()
if (c > '0' && c <= '9') {
qplet = line.get_int();
c = line.char()
}
if (c == ':') {
|
| ︙ | | |
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
|
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
|
}
}
if (qplet == 0 || qplet == undefined)
qplet = (curvoice.wmeasure % 9) == 0 ?
3 : 2;
if (tpn < 0)
tpn = tp.length // new tuplet
c = cfmt.tuplets
if (curvoice.pos.tup) {
c = Object.create(c)
switch (curvoice.pos.tup & 0x07) {
case C.SL_ABOVE:
c[3] = 1
break
case C.SL_BELOW:
c[3] = 2
break
case C.SL_HIDDEN:
c[2] = 1
break
}
}
tp.push({
p: pplet,
q: qplet,
r: rplet,
ro: rplet,
f: c
f: curvoice.tup || cfmt.tuplets
})
continue
}
if (c == '&') { // voice overlay start
if (grace) {
syntax(1, errs.bad_grace)
break
|
| ︙ | | |
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
|
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
|
-
-
+
|
break
}
}
if (!s) {
syntax(1, errs.bad_char, c)
break
}
s.notes[0].s = s
slur_add(s.notes[0])
slur_add(s)
break
case '!': // start of decoration
if (type.length > 1) // decoration letter
a_dcn.push(type.slice(1, -1))
else
get_deco() // (line -> a_dcn)
break
|
| ︙ | | |
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
|
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
|
+
+
+
+
|
if (grace) {
syntax(1, errs.bar_grace)
break
}
new_bar()
continue
case '}':
if (curvoice.ignore) {
grace = null
break
}
s = curvoice.last_note
if (!grace || !s) {
syntax(1, errs.bad_char, c)
break
}
if (a_dcn.length)
syntax(1, "Decoration ignored");
|
| ︙ | | |
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
|
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
|
-
-
-
-
|
if (tp.length) {
parse.tp = tp
parse.tps = tps
parse.tpn = tpn
}
if (sls.length)
syntax(1, "Start of slur without note")
if (a_dcn.length) {
syntax(1, "Decoration without symbol")
a_dcn = []
}
if (grace) {
syntax(1, "No end of grace note sequence");
curvoice.last_sym = grace.prev;
curvoice.last_note = last_note_sav
if (grace.prev)
grace.prev.next = null
}
if (!no_eol && !cfmt.barsperstaff && !vover
&& char_tb['\n'.charCodeAt(0)] == '\n')
curvoice.eoln = true
if (curvoice.eoln && cfmt.breakoneoln && curvoice.last_note)
curvoice.last_note.beam_end = true
}
|
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - subs.js - text output
//
// Copyright (C) 2014-2021 Jean-Francois Moine
// Copyright (C) 2014-2022 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
|
}
// return the character width with the current font
function cwidf(c) {
return cwid(c) * gene.curfont.swfac
}
// estimate the width and height of a string ..
var strwh
(function() {
var strwh = typeof document != "undefined" ?
if (typeof document != "undefined") {
// .. by the browser
(function() {
// (re)create a text element
var el = document.createElement('text')
el.style.position = 'absolute'
el.style.top = '-1000px'
el.style.padding = '0'
document.body.appendChild(el)
return function(str) {
// create a text element if not done yet
var el = abc2svg.eltxt
// change the function
strwh = function(str) {
if (str.wh)
return str.wh
if (!el) {
el = document.createElement('text')
el.style.position = 'absolute'
el.style.top = '-1000px'
el.style.padding = '0'
document.body.appendChild(el)
abc2svg.eltxt = el // reused after new Abc()
}
if (str.wh)
return str.wh
var c,
font = gene.curfont,
h = font.size,
w = 0,
n = str.length,
i0 = 0,
i = 0
|
| ︙ | | |
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
-
+
-
+
|
case '&': return "&"
}
return c // &xxx;
})
while (1) {
i = str.indexOf('$', i)
if (i < 0)
if (i >= 0) {
break
c = str[i + 1]
if (c == '0') {
font = gene.deffont
} else if (c >= '1' && c <= '9') {
font = get_font("u" + c)
} else {
i++
continue
}
el.innerHTML = str.slice(i0, i);
c = str[i + 1]
if (c == '0') {
font = gene.deffont
} else if (c >= '1' && c <= '9') {
font = get_font("u" + c)
} else {
i++
continue
}
}
el.innerHTML = str.slice(i0, i >= 0 ? i : undefined)
w += el.clientWidth
//fixme: bad result if space(s) at end of string
if (font.size > h)
h = font.size;
//fixme: bad width if space(s) at end of string
if (el.clientHeight > h)
h = el.clientHeight
if (i < 0)
break
el.style.font = style_font(font).slice(5);
i += 2;
i0 = i
}
el.innerHTML = str.slice(i0);
w += el.clientWidth;
return [w, h]
}
})() :
} else {
// .. by internal tables
function(str) {
strwh = function(str) {
var font = gene.curfont,
swfac = font.swfac,
h = font.size,
w = 0,
i, j, c,
n = str.length
|
| ︙ | | |
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
-
+
+
+
-
-
-
+
+
+
+
+
+
-
+
|
c = 'a' // XML character reference
}
break
}
w += cwid(c) * swfac
}
return [w, h]
}
}
}
})()
// convert a string to a SVG text, handling the font changes
// The string size is memorized into the String.
function str2svg(str) {
// check if the string is already converted
if (typeof str == "object")
return str
var o, n_font, wh,
o_font = gene.curfont,
c_font = o_font
var n_font, wh,
o_font = gene.deffont,
c_font = gene.curfont,
o = ""
// start a '<tspan>' element
function tspan(nf, of) {
var cl
if (nf.class
&& nf.name == of.name
&& nf.size == of.size
&& nf.weight == of.weight
&& nf.style == of.style)
cl = nf.class // change only the class
else
cl = font_class(nf)
return '<tspan\n\tclass="' + cl + '">'
} // tspan()
if (c_font != o_font)
o = tspan(c_font, o_font)
o = str.replace(/<|>|&[^&\s]*?;|&|\$./g, function(c){
o += str.replace(/<|>|&[^&\s]*?;|&|\$./g, function(c){
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
default:
if (c[0] != '$')
break
|
| ︙ | | |
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
|
-
+
-
-
+
+
-
+
|
str, // string or object String with attribute 'wh'
action, // default: align left
w, // needed for justify
wh) { // optional [width, height]
if (!wh)
wh = str.wh || strwh(str)
output += '<text class="' + font_class(gene.curfont)
output += '<text class="' + font_class(gene.deffont)
if (action != 'j' && str.length > 5
&& gene.curfont.wadj)
output += '" lengthAdjust="' + gene.curfont.wadj +
&& gene.deffont.wadj)
output += '" lengthAdjust="' + gene.deffont.wadj +
'" textLength="' + wh[0].toFixed(1);
output += '" x="';
out_sxsy(x, '" y="', y + wh[1] * .2) // a bit upper for the descent
out_sxsy(x, '" y="', y)
switch (action) {
case 'c':
x -= wh[0] / 2;
output += '" text-anchor="middle">'
break
case 'j':
output += '" textLength="' + w.toFixed(1) + '">'
|
| ︙ | | |
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
|
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
|
+
-
+
-
+
-
+
+
-
+
-
-
+
|
if (i == text.length)
break
} else {
if (i < 0)
str = text.slice(j)
else
str = text.slice(j, i)
ww = strwh(str)
vskip(strwh(str)[1] * cfmt.lineskipfac
vskip(ww[1] * cfmt.lineskipfac
+ font.pad * 2)
xy_str(x, font.pad, str, action)
xy_str(x, font.pad + ww[1] * .2, str, action)
if (i < 0)
break
}
j = i + 1
}
vskip(parskip);
blk_flush()
break
case 'f':
case 'j':
j = 0
while (1) {
i = text.indexOf('\n\n', j)
if (i < 0)
words = text.slice(j)
else
words = text.slice(j, i);
words = words.split(/\s+/);
w = k = wh = 0
for (j = 0; j < words.length; j++) {
ww = strwh(words[j])
ww = strwh(words[j] + ' ') //
w += ww[0]
if (w >= strlw) {
vskip(wh * cfmt.lineskipfac)
xy_str(0, ww[1] * .2,
xy_str(0, 0, words.slice(k, j).join(' '),
words.slice(k, j).join(' '),
action, strlw)
k = j;
w = ww[0]
wh = 0
}
w += cwidf(' ')
if (ww[1] > wh)
wh = ww[1]
}
if (w != 0) { // last line
vskip(wh * cfmt.lineskipfac)
xy_str(0, 0, words.slice(k).join(' '))
xy_str(0, ww[1] * .2, words.slice(k).join(' '))
}
vskip(parskip);
blk_flush()
if (i < 0)
break
while (text[i + 2] == '\n') {
vskip(lineskip);
|
| ︙ | | |
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
|
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
|
+
-
+
-
+
|
break
}
k = i
while (p[i] == ' ')
i++
}
var y = gene.curfont.size * .22 // descent
if (k != 0)
xy_str(x, 0, p.slice(0, k), 'r')
xy_str(x, y, p.slice(0, k), 'r')
if (i < p.length)
xy_str(x + 5, 0, p.slice(i), 'l')
xy_str(x + 5, y, p.slice(i), 'l')
} // put_wline()
set_font("words")
vskip(cfmt.wordsspace)
svg_flush()
// estimate the width of the lines
|
| ︙ | | |
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
|
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
|
-
+
|
P: "parts",
Q: "tempo",
R: "info",
T: "title",
X: "title"
}
function write_headform(lwidth) {
var c, font, font_name, align, x, y, sz,
var c, font, font_name, align, x, y, sz, w,
info_val = {},
info_font = Object.create(info_font_init),
info_sz = {
A: cfmt.infospace,
C: cfmt.composerspace,
O: cfmt.composerspace,
R: cfmt.infospace
|
| ︙ | | |
| ︙ | | |
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
-
+
|
style = '\
\n.stroke{stroke:currentColor;fill:none}\
\n.bW{stroke:currentColor;fill:none;stroke-width:1}\
\n.bthW{stroke:currentColor;fill:none;stroke-width:3}\
\n.slW{stroke:currentColor;fill:none;stroke-width:.7}\
\n.slthW{stroke:currentColor;fill:none;stroke-width:1.5}\
\n.sW{stroke:currentColor;fill:none;stroke-width:.7}\
\n.box{outline: 1px solid black;outline-offset: 1px}',
\n.box{outline:1px solid black;outline-offset:1px}',
font_style = '',
posx = cfmt.leftmargin / cfmt.scale, // default x offset of the images
posy = 0, // y offset in the block
img = { // image
width: cfmt.pagewidth, // width
lm: cfmt.leftmargin, // left and right margins
rm: cfmt.rightmargin
|
| ︙ | | |
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
|
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
-
+
-
|
output += 'transform="translate(0,' +
(posy - stv_g.dy).toFixed(1) +
') scale(' + stv_g.scale.toFixed(2) + ')"'
}
if (stv_g.color) {
if (stv_g.scale != 1)
output += ' ';
output += 'color="' + stv_g.color +
output += 'color="' + stv_g.color + '"'
'" fill="' + stv_g.color + '"'
}
output += ">\n";
stv_g.started = true
}
/* set the color */
function set_color(color) {
|
| ︙ | | |
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
+
+
+
+
+
|
stv_g.v = s.v;
set_g()
}
// -- set the staff output buffer and scale when delayed output
function set_dscale(st, no_scale) {
if (output) {
if (stv_g.started) { // close the previous sequence
stv_g.started = false
glout()
output += "</g>\n"
}
if (stv_g.st < 0) {
staff_tb[0].output += output
} else if (stv_g.scale == 1) {
staff_tb[stv_g.st].output += output
} else {
staff_tb[stv_g.st].sc_out += output
}
|
| ︙ | | |
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
|
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
|
-
+
|
n = ((w - 15) / d) | 0
else
n = 0;
x += (w - d * n - 5) / 2;
out_XYAB('<path class="stroke" stroke-width="1.2"\n\
stroke-dasharray="5,A"\n\
d="mX YhB"/>\n',
x, y + 6, // set the line a bit upper
x, y + 4, // set the line a bit upper
Math.round((d - 5) / stv_g.scale), d * n + 5)
}
// stem [and flags]
function out_stem(x, y, h, grace,
nflags, straight) { // optional
//fixme: dx KO with half note or longa
var dx = grace ? GSTEM_XOFF : 3.5,
|
| ︙ | | |
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
|
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
|
-
+
|
// tuplet bracket with number - the staves are not defined
function out_tubrn(x, y, dx, dy, up, str) {
var dxx,
sw = str.length * 10,
h = up ? -3 : 3;
set_font("tuplet")
xy_str(x + dx / 2, y + dy / 2 - gene.curfont.size * .5 + 2,
xy_str(x + dx / 2, y + dy / 2 - gene.curfont.size * .1,
str, 'c')
dx /= stv_g.scale
if (!up)
y += 6;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
dxx = dx - sw + 1
|
| ︙ | | |
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
|
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
|
-
+
|
out_sxsy(x, ' ', y - h);
output += 'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) + '"/>\n'
}
// underscore line
function out_wln(x, y, w) {
out_XYAB('<path class="stroke" stroke-width="0.8" d="mX YhF"/>\n',
x, y + 3, w)
x, y + 1, w)
}
// decorations with string
var deco_str_style = {
crdc: {
dx: 0,
dy: 5,
|
| ︙ | | |
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
|
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
|
+
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
-
+
+
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
-
+
-
-
|
if (deco_val_tb[name])
deco_val_tb[name](x, y, val, defl)
else
error(1, null, "No function for decoration '$1'", name)
}
function out_glisq(x2, y2, de) {
var ar, a, len,
var de1 = de.start,
de1 = de.start,
x1 = de1.x,
y1 = de1.y + staff_tb[de1.st].y,
dx = x2 - x1,
dy = self.sh(y1 - y2)
if (!stv_g.g)
dx /= stv_g.scale
ar = Math.atan2(y1 - y2, x2 - x1),
a = ar / Math.PI * 180,
len = (x2 - x1) / Math.cos(ar);
ar = Math.atan2(dy, dx)
a = ar / Math.PI * 180
len = (dx - (de1.s.dots ? 13 + de1.s.xmx : 8)
- 8 - (de.s.notes[0].shac || 0))
/ Math.cos(ar)
g_open(x1, y1, a);
x1 = de1.s.dots ? 13 + de1.s.xmx : 8;
len = (len - x1 - 6) / 6 | 0
len = len / 6 | 0
if (len < 1)
len = 1
while (--len >= 0) {
xygl(x1, 0, "ltr");
x1 += 6
}
g_close()
}
function out_gliss(x2, y2, de) {
var ar, a, len,
var de1 = de.start,
de1 = de.start,
x1 = de1.x,
y1 = de1.y + staff_tb[de1.st].y,
dx = x2 - x1,
dy = self.sh(y1 - y2)
if (!stv_g.g)
dx /= stv_g.scale
ar = -Math.atan2(y2 - y1, x2 - x1),
a = ar / Math.PI * 180,
len = (x2 - x1) / Math.cos(ar);
ar = Math.atan2(dy, dx)
a = ar / Math.PI * 180
len = (dx - (de1.s.dots ? 13 + de1.s.xmx : 8)
- 8 - (de.s.notes[0].shac || 0))
/ Math.cos(ar)
g_open(x1, y1, a);
x1 = de1.s.dots ? 13 + de1.s.xmx : 8;
xypath(de1.s.dots ? 13 + de1.s.xmx : 8, 0)
len -= x1 + 8;
xypath(x1, 0);
output += 'h' + len.toFixed(1) + '" stroke-width="1"/>\n';
g_close()
}
var deco_l_tb = {
glisq: out_glisq,
gliss: out_gliss
|
| ︙ | | |
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
|
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
|
-
+
-
+
|
bh = gene.curfont.size + 4
}
//fixme: xy_str() cannot be used because <tspan> in s.tempo_str
//fixme: then there cannot be font changes by "$n" in the Q: texts
output += '<text class="' + font_class(gene.curfont) +
'" x="'
out_sxsy(x, '" y="', y + gene.curfont.size * .2)
out_sxsy(x, '" y="', y + gene.curfont.size * .22)
output += '">' + s.tempo_str + '</text>\n'
if (bh) {
gene.curfont.box = true
output += '<rect class="stroke" x="'
out_sxsy(x - 2, '" y="', y + bh - 1)
output += '" width="' + (s.tempo_wh[0] + 2).toFixed(1) +
output += '" width="' + (s.tempo_wh[0] + 4).toFixed(1) +
'" height="' + bh.toFixed(1) +
'"/>\n'
}
// don't display anymore
s.invis = true
} // writempo()
|
| ︙ | | |
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
|
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
|
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
|
function svg_flush() {
if (multicol || !output || !user.img_out || posy == 0)
return
var i, font,
head = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"\n\
xmlns:xlink="http://www.w3.org/1999/xlink"\n\
color="',
fill="currentColor" stroke-width=".7"',
g = ''
glout()
if (cfmt.fgcolor)
head += cfmt.fgcolor + '" fill="' + cfmt.fgcolor + '"'
else
head += 'black"';
head += ' stroke-width=".7"'
if (cfmt.bgcolor)
head += ' style="background-color: ' + cfmt.bgcolor + '"';
font = get_font("music")
head += ' class="' + font_class(font) +
' tune' + tunes.length + '"\n' // tune index for play
posy *= cfmt.scale
if (user.imagesize) {
head += user.imagesize +
' viewBox="0 0 ' + img.width.toFixed(0) + ' ' +
posy.toFixed(0) + '">\n'
} else {
head += ' viewBox="0 0 ' + img.width.toFixed(0) + ' ' +
posy.toFixed(0) +
'" width="' + img.width.toFixed(0) +
'px" height="' + posy.toFixed(0) + 'px">\n'
}
head += fulldefs
if (style || font_style)
head += '<style>' + font_style + style + '\n</style>\n'
if (style || font_style) {
head += '<style>' + font_style
if (cfmt.fgcolor || cfmt.bgcolor) {
head += '\n.f' + font.fid + (cfmt.fullsvg || '')
+ '{'
+ (cfmt.fgcolor ? ('color:' + cfmt.fgcolor + ';')
: '')
+ (cfmt.bgcolor ? ('background-color:' + cfmt.bgcolor)
: '')
+ '}'
}
head += style + '\n</style>\n'
}
if (defs)
head += '<defs>' + defs + '\n</defs>\n'
// if %%pagescale != 1, do a global scale
// (with a container: transform scale in <svg> does not work
// the same in all browsers)
|
| ︙ | | |
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
|
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
|
-
+
|
'<div class="nobrk newpage">')
blkdiv = -1 // block started
}
user.img_out(head + output + g + "</svg>");
output = ""
font_style = ''
if (cfmt.fullsvg && typeof document == "undefined") {
if (cfmt.fullsvg) {
defined_glyph = {}
for (i = 0; i < font_tb.length; i++)
font_tb[i].used = false
} else {
style = '';
fulldefs = ''
}
|
| ︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - tune.js - tune generation
//
// Copyright (C) 2014-2022 Jean-Francois Moine
// Copyright (C) 2014-2023 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
+
+
-
+
+
-
-
-
-
-
-
|
for (opt in parse.tune_v_opts) {
if (parse.tune_v_opts.hasOwnProperty(opt))
vfilt(parse.tune_v_opts[opt], opt)
}
}
/* -- link a ABC symbol into the current voice -- */
// if a voice is ignored (not in %%staves) don't link the symbol
// but update the time for P: and Q:
function sym_link(s) {
var tim = curvoice.time
if (!s.fname)
set_ref(s)
parse.last_sym = s
if (!curvoice.ignore) {
s.prev = curvoice.last_sym
if (curvoice.last_sym)
curvoice.last_sym.next = s
else
curvoice.sym = s
}
curvoice.last_sym = s
s.v = curvoice.v;
s.p_v = curvoice;
s.st = curvoice.cst;
s.time = tim
if (s.dur && !s.grace)
curvoice.time += s.dur;
parse.ufmt = true
s.fmt = cfmt // global parameters
s.pos = curvoice.pos
if (curvoice.second)
s.second = true
if (curvoice.floating)
s.floating = true
if (curvoice.eoln) {
s.soln = true
curvoice.eoln = false
}
if (parse.part && parse.part[tim]) {
if (!parse.part[tim].done) {
s.part = parse.part[tim]
parse.part[tim].done = true
}
}
}
/* -- add a new symbol in a voice -- */
function sym_add(p_voice, type) {
var s = {
type:type,
dur:0
|
| ︙ | | |
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
-
-
+
+
-
+
|
/* -- sort all symbols by time and vertical sequence -- */
// weight of the symbols !! depends on the symbol type !!
var w_tb = new Uint8Array([
5, // bar
1, // clef
8, // custos
0, // (free)
4, // grace
6, // sm (sequence marker, after bar)
0, // grace (must be null)
2, // key
3, // meter
9, // mrest
9, // note
0, // part
9, // rest
4, // space
4, // space (before bar)
0, // staves
7, // stbrk
0, // tempo
0, // (free)
0, // block
0 // remark
])
|
| ︙ | | |
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
sy: sy,
next: p_voice.sym,
seqst: true
}
if (!p_voice.sym)
return
// check if different bars at the same time
function b_chk() {
var ir, bt, s, s2, v
ir = 0
bt = ""
while (1) {
v = vn[ir++]
if (v == undefined)
break
s = vtb[v]
if (!s || !s.bar_type || s.invis)
continue
if (!bt) {
bt = s.bar_type
continue
}
if (s.bar_type != bt)
break
}
if (!v)
return // no problem
if (bt == "::" || bt == ":|") {
ir = 0
while (1) {
v = vn[ir++]
if (v == undefined)
break
s = vtb[v]
if (!s || s.invis
|| s.bar_type != "::")
continue
s2 = clone(s)
s.bar_type = ":|"
s2.bar_type = "|:"
s2.next = s.next
s2.prev = s
s.next = s2
}
} else {
error(2, s, "Different bars $1 and $2",
bt, s.bar_type)
}
} // b_chk()
prev.fmt = fmt = p_voice.sym.fmt // starting format
// set the first symbol of each voice
for (v = 0; v < nv; v++) {
s = voice_tb[v].sym
vtb[v] = s
|
| ︙ | | |
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
|
else
p_voice.last_sym = s
s.prev.next = s
s.fmt = fmt
glovar.tempo = null
vtb[v] = s
}
// if only one voice, quickly create the time links
if (nv == 1) {
s = tsfirst
s.ts_next = s.next
while (1) {
s = s.next
if (!s)
return
s.ts_prev = s.prev
s.ts_next = s.next
if (s.time != s.prev.time
|| w_tb[s.prev.type]
|| s.type == C.GRACE && s.prev.type == C.GRACE)
s.seqst = 1 //true
}
// not reached
}
// loop on the symbols of all voices
while (1) {
if (new_sy) {
sy = new_sy;
new_sy = null;
vn = []
vn.length = 0
for (v = 0; v < nv; v++) {
if (!sy.voices[v])
continue
vn[sy.voices[v].range] = v
}
}
/* search the min time and symbol weight */
wmin = time = 10000000 // big int
ir = 0
while (1) {
v = vn[ir++]
if (v == undefined)
break
s = vtb[v]
if (!s || s.time > time)
continue
w = w_tb[s.type]
if (s.type == C.GRACE && s.next && s.next.type == C.GRACE)
w--
if (s.time < time) {
time = s.time;
wmin = w
} else if (w < wmin) {
wmin = w
}
}
if (wmin > 127)
break // done
// check the type of the measure bars
if (wmin == 5) // weight of bars
b_chk()
/* link the vertical sequence */
ir = 0
while (1) {
v = vn[ir++]
if (v == undefined)
break
s = vtb[v]
if (!s || s.time != time
|| w_tb[s.type] != wmin)
if (!s)
continue
w = w_tb[s.type]
if (s.type == C.GRACE && s.next && s.next.type == C.GRACE)
w--
if (s.time != time
|| w != wmin)
continue
if (s.type == C.STAVES)
new_sy = s.sy
if (fl) {
fl = 0;
s.seqst = true
}
|
| ︙ | | |
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
|
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
|
-
-
+
+
-
-
-
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
p_voice = voice_tb[v]
if (!sys_chg) { // if not %%score
delete p_voice.eoln
while (1) { // set the end of slurs
sl = p_voice.sls.shift()
if (!sl)
break
s = sl.note.s
for (s2 = s.next; s2; s2 = s2.next) {
s = sl.ss
// error(1, s, "Lack of ending slur(s)")
if (s2.bar_type && s2.bar_type[0] == ':')
break
}
if (s2) {
if (!s.sls)
s.sls = []
sl.loc = 'o' // no slur end
s.sls.push({
s.sls.push(sl)
ty: sl.ty,
note: {s: s2}
})
} else {
error(1, s, "Lack of ending slur(s)")
}
}
} // not %%score
for (s = p_voice.sym; s; s = s.next) {
if (s.time >= staves_found)
break
}
for ( ; s; s = s.next) {
switch (s.type) {
case C.GRACE:
// with w_tb[C.BAR] = 4 and w_tb[C.GRACE] = 3,
// the grace notes go after the bar;
// if before a bar, change the grace time
if (s.next && s.next.type == C.BAR)
s.time--
// if the symbol has a sequence weight smaller than the bar one
// and if there a time skip,
// add an invisible bar before it
if (w_tb[s.type] < 5
&& s.type != C.STAVES
&& s.type != C.CLEF
&& s.time // not at start of tune
&& (!s.prev || s.time > s.prev.time + s.prev.dur)) {
s2 = {
type: C.BAR,
bar_type: "[]",
v: s.v,
p_v: s.p_v,
st: s.st,
time: s.time,
dur:0,
next: s,
prev: s.prev,
fmt: s.fmt,
invis: 1
}
if (s.prev)
s.prev.next = s2
else
voice_tb[s.v].sym = s2
s.prev = s2
}
switch (s.type) {
case C.GRACE:
if (!cfmt.graceword)
continue
for (s2 = s.next; s2; s2 = s2.next) {
switch (s2.type) {
case C.SPACE:
continue
case C.NOTE:
|
| ︙ | | |
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
|
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
par_sy.next = sy_new;
par_sy = sy_new
}
/* -- set the bar numbers -- */
// (possible hook)
Abc.prototype.set_bar_num = function() {
var s, s2, tim, rep_tim, k, n,
var s, s2, rep_tim, k, n, nu, txt,
tim = 0, // time of the previous bar
bar_num = gene.nbar,
bar_tim = 0, // time of previous repeat variant
ptim = 0, // time of previous bar
wmeasure = voice_tb[cur_sy.top_voice].meter.wmeasure
// check the measure duration
function check_meas() {
var s3
if (tim > ptim + wmeasure
&& s.prev.type != C.MREST)
return 1 //true
// the measure is too short,
// check if there is a bar a bit further
for (s3 = s.next; s3 && s3.time == s.time; s3 = s3.next)
;
for ( ; s3 && !s3.bar_type; s3 = s3.next)
;
return s3 && (s3.time - bar_tim) % wmeasure
}
// don't count a bar at start of tune
for (s = tsfirst; ; s = s.ts_next) {
if (!s)
return
switch (s.type) {
case C.METER:
|
| ︙ | | |
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
|
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
|
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
-
+
-
-
+
+
+
-
-
+
+
-
+
-
-
+
|
}
break
}
}
// set the measure number on the top bars
for ( ; s; s = s.ts_next) {
if (!s.seqst)
continue
switch (s.type) {
case C.METER:
if (s.time == bar_tim)
break // already seen
if (wmeasure != 1) // if not M:none
bar_num += (s.time - bar_tim) / wmeasure
bar_tim = s.time
wmeasure = s.wmeasure
break
case C.BAR:
if (s.invis)
break
if (s.time <= tim)
break // already seen
tim = s.time
nu = 1 //true // no num update
txt = ""
for (s2 = s; s2; s2 = s2.next) {
if (s2.time > tim || s2.dur)
break
if (!s2.bar_type)
continue
if (s2.bar_type != '[')
nu = 0 //false // do update
if (s2.text)
txt = s2.text
}
if (s.bar_num) {
bar_num = s.bar_num // (%%setbarnb)
ptim = bar_tim = tim
continue
}
if (wmeasure == 1) { // if M:none
if (s.bar_dotted)
continue
if (s.text) {
if (txt) {
if (!cfmt.contbarnb) {
if (s.text[0] == '1')
if (txt[0] == '1')
rep_tim = bar_num
else
bar_num = rep_tim
}
}
if (!nu)
s.bar_num = ++bar_num
s.bar_num = ++bar_num
continue
}
n = bar_num + (tim - bar_tim) / wmeasure
k = n - (n | 0)
if (cfmt.checkbars
&& ((k && !s.bar_dotted && s.next)
|| (tim > ptim + wmeasure && s.prev.type != C.MREST)))
&& k
&& check_meas())
error(0, s, "Bad measure duration")
if (tim > ptim + wmeasure) { // if more than one measure
n |= 0
k = 0
bar_tim = tim // re-synchronize
bar_num = n
}
if (s.text) {
if (s.text[0] == '1') {
if (txt) {
if (txt[0] == '1') {
if (cfmt.contbarnb)
rep_tim = bar_tim + k * wmeasure
else
rep_tim = tim
if (!k)
if (!nu)
s.bar_num = n
} else {
if (cfmt.contbarnb)
bar_tim = rep_tim
else
bar_tim += tim - rep_tim
n = bar_num + (tim - bar_tim) / wmeasure
if (n == (n | 0))
s.bar_num = n
}
} else {
if (k)
n -= k
n |= 0
s.bar_num = n
}
if (!k)
ptim = tim
break
}
}
|
| ︙ | | |
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
|
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
|
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
+
+
-
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
+
|
}
map[2] = a[i]
break
}
}
}
// set the transposition in the previous or first key signature
// set the transposition in the first key signature or in a new key
function set_transp() {
var s, transp, sndtran
var s
if (curvoice.ckey.k_bagpipe || curvoice.ckey.k_drum)
return
if (cfmt.transp && curvoice.shift) // if %%transpose and shift=
syntax(0, "Mix of old and new transposition syntaxes");
if (cfmt.transp != undefined
|| curvoice.transp != undefined
|| curvoice.shift != undefined)
transp = (cfmt.transp || 0) + // %%transpose
(curvoice.transp || 0) + // score= / sound= / instrument=
(curvoice.shift || 0) // shift=
if (curvoice.sndtran != undefined
|| curvoice.sndsh != undefined)
sndtran = (curvoice.sndtran || 0) +
(curvoice.sndsh || 0)
if (transp == undefined) {
if (sndtran == undefined)
return
} else {
curvoice.vtransp = transp
}
if (is_voice_sig()) { // if no symbol yet
curvoice.okey.fmt = cfmt
curvoice.key = s = clone(curvoice.okey)
} else {
s = curvoice.last_sym
s = clone(curvoice.ckey)
while (1) { // set the transposition in the previous K:
if (s.type == C.KEY)
break
s = s.prev
s.k_old_sf = s.k_sf
if (!s) {
s = curvoice.key // first key
break
}
sym_link(s)
}
}
}
if (transp != undefined)
s.k_transp = transp
delete s.invis // needed if K:C/none at start of tune
key_transp(s)
if (sndtran != undefined)
s.k_sndtran = sndtran
curvoice.ckey = clone(s)
if (curvoice.key.k_none)
s.k_sf = 0
}
/* transpose a note / chord */
function note_transp(s, sk, note) {
var ak, an, d, b40,
n = note.pit,
a = note.acc
// set the control values (P: and Q:)
if (typeof a == "object") {
d = a[1]
a = a[0]
if (d != 2) {
error(1, s, "Microtone transposition not coded")
return
}
}
if (!a && sk.k_a_acc) // if accidental list
a = sk.k_map[(n + 19) % 7] // invisible accidental
function set_ctrl() {
b40 = abc2svg.pab40(n, a) + sk.k_transp // base-40 transposition
var s, tim, e
note.pit = abc2svg.b40p(b40) // new pitch
if (!a) { // if no old accidental
if (!sk.k_a_acc // if no accidental list
&& !sk.k_none) // and normal key
return // same accidental (in the key)
}
an = abc2svg.b40a(b40) // new accidental
if (a) {
if (sk.k_a_acc) { // if accidental list
ak = sk.k_map[(note.pit + 19) % 7]
if (ak == an)
an = 0 // accidental in the key
}
if (!an)
an = 3
} else if (sk.k_none) { // if no key
if (acc_same_pitch(s, note.pit)) // and accidental from previous notes
return // no change
} else if (sk.k_a_acc) { // if accidental list
if (acc_same_pitch(s, note.pit)) // and accidental from previous notes
return // no change
ak = sk.k_map[(note.pit + 19) % 7]
if (ak)
an = 3 // natural
} else {
return // same accidental (in the key)
}
if (d && an != a) {
for (tim in parse.ctrl) {
// if (!parse.ctrl.hasOwnProperty(tim))
switch (Number(a)) {
case -3:
// continue
switch (an) {
case -2:
an = -1
e = parse.ctrl[tim]
break
case 3: // natural
an = -3
s = tsfirst
note.pit++
break
case 2:
an = -1
while (s.next && s.next.time < tim)
s = s.next
break
}
break
case -1:
while (s && s.time < tim)
switch (an) {
case -2:
an = -3
s = s.ts_next
break
case 3: // natural
an = 1
if (!s) {
break
}
break
case 1:
//fixme: insert at the end
switch (an) {
case -1:
} else {
an = -3
break
case 3: // natural
an = -1
break
case 2:
an = 3
break
}
break
case 3:
switch (an) {
case -1:
an = 1
break
case 1:
an = 1
note.pit++
break
}
break
}
}
note.acc = d ? [an, d] : an
}
// put the P: and/or Q: on a note or rest
// adjust the pitches according to the transposition(s)
function pit_adj() {
var i, p_v, s, sk, g,
nv = voice_tb.length
while (--nv >= 0) {
p_v = voice_tb[nv]
if (p_v.vtransp == undefined)
continue // no transposition in this voice
if (p_v.key.k_transp) {
sk = p_v.key
key_transp(sk)
sk.k_old_sf = sk.k_sf // no natural
} else {
sk = null
}
s = p_v.sym
while (s) {
// search a transposing key signature
if (!sk) {
while (s.time == tim && s.ts_next
&& !s.dur)
s = s.ts_next
if (e.part) {
for (; s; s = s.next) {
if (s.type == C.KEY
// if (s.time != tim) {
&& s.k_transp)
break
}
}
// transpose
for (; s; s = s.next) {
// // fixme: insert a part (?)
// }
s.part = e.part
switch (s.type) {
case C.GRACE:
for (g = s.extra; g; g = g.next) {
for (i = 0; i <= g.nhd; i++)
note_transp(g, sk, g.notes[i])
}
}
continue
case C.NOTE:
for (i = 0; i <= s.nhd; i++)
note_transp(s, sk, s.notes[i])
continue
case C.KEY:
if (sk)
s.k_sf = sk.k_sf
if (e.tempo) {
lkvsym(e.tempo, s)
key_transp(s)
if (!s.k_transp) // end of transposition
break
sk = s
lktsym(e.tempo, s)
default:
continue
}
}
break
}
}
sk = null
}
}
}
} // pit_adj()
} // set_ctrl()
// get a abcm2ps/abcMIDI compatible transposition value as a base-40 interval
// The value may be
// - [+|-]<number of semitones>[s|f]
// - <note1>[<note2>] % <note2> default is 'c'
function get_transp(param) {
if (param[0] == '0')
|
| ︙ | | |
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
|
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
|
-
+
|
} // get_transp()
/* -- process a pseudo-comment (%% or I:) -- */
// (possible hook)
Abc.prototype.do_pscom = function(text) {
var h1, val, s, cmd, param, n, k, b
cmd = text.match(/(\w|-)+/)
cmd = text.match(/[^\s]+/)
if (!cmd)
return
cmd = cmd[0];
// ignore the command if the voice is ignored,
// but not if %%score/%%staves!
if (curvoice && curvoice.ignore) {
|
| ︙ | | |
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
|
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
|
-
-
+
+
-
-
-
+
-
-
-
-
-
-
+
-
+
+
-
-
-
-
-
-
-
-
+
+
+
|
if (parse.state >= 2) {
curvoice = voice_tb[0]
s = new_block("mc_" + param)
break
}
switch (param) {
case "start":
multicol = {
maxy: 0,
self.block_gen({
subtype: "mc_start"
lmarg: cfmt.leftmargin,
rmarg: cfmt.rightmargin
}
})
break
case "new":
if (!multicol) {
syntax(1, "%%multicol new without start")
break
}
if (posy > multicol.maxy)
multicol.maxy = posy;
cfmt.leftmargin = multicol.lmarg;
cfmt.rightmargin = multicol.rmarg;
img.chg = true;
set_page();
self.block_gen({
posy = 0
subtype: "mc_new"
})
break
case "end":
if (!multicol) {
syntax(1, "%%multicol end without start")
break
}
if (posy < multicol.maxy)
posy = multicol.maxy;
cfmt.leftmargin = multicol.lmarg;
cfmt.rightmargin = multicol.rmarg;
multicol = undefined;
blk_flush();
img.chg = true;
set_page()
self.block_gen({
subtype: "mc_end"
})
break
default:
syntax(1, "Unknown keyword '$1' in %%multicol", param)
break
}
return
case "ottava":
|
| ︙ | | |
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
|
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
|
case 0:
cfmt.transp = 0
// fall thru
case 1:
cfmt.transp = (cfmt.transp || 0) + val
return
}
for (s = curvoice.last_sym; s; s = s.prev) {
switch (s.type) {
case C.NOTE: // insert a key
s = clone(curvoice.okey);
s.k_old_sf = curvoice.ckey.k_sf;
sym_link(s)
break
case C.KEY:
break
default:
continue
}
break
}
curvoice.transp = val
curvoice.tr_sco = val
set_transp()
return
case "tune":
//fixme: to do
return
case "user":
set_user(param)
|
| ︙ | | |
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
|
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
|
-
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
+
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
+
|
}
write_text(text, action)
break
}
}
/* -- generate a piece of tune -- */
function generate(in_mc) {
function generate() {
var s, v, p_voice;
if (a_dcn.length) {
syntax(1, "Decoration without symbol")
a_dcn = []
}
if (parse.tp) {
syntax(1, "No end of tuplet")
s = parse.tps
if (s)
delete s.tp
delete parse.tp
}
if (vover) {
syntax(1, "No end of voice overlay");
get_vover(vover.bar ? '|' : ')')
}
voice_adj();
sort_all() /* define the time / vertical sequences */
if (!tsfirst)
if (tsfirst) {
return
if (user.anno_start)
anno_start = a_start
if (user.anno_stop)
anno_stop = a_stop
self.set_bar_num()
pit_adj()
if (info.P)
tsfirst.parts = info.P // for play
if (parse.ctrl)
set_ctrl() // set control values
// give the parser result to the application
if (user.get_abcmodel)
user.get_abcmodel(tsfirst, voice_tb, abc2svg.sym_name, info)
if (user.img_out) // if SVG generation
self.output_music()
} // (tsfirst)
// finish the generation
set_page() // the page layout may have changed
if (info.W)
put_words(info.W)
put_history()
parse.state = 0 // file header
blk_flush() // (force end of block)
if (tsfirst) // if non void, keep tune data for upper layers
if (tsfirst) { // if non void, keep tune data for upper layers
tunes.push([tsfirst, voice_tb, info, cfmt])
tsfirst = null
// if inside multicol, reset the parser
if (!in_mc)
return
voice_tb = Object.create(voice_tb)
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
p_voice.time = 0;
p_voice.sym = p_voice.last_sym = null;
// p_voice.st = cur_sy.voices[v].st;
// p_voice.second = cur_sy.voices[v].second;
// p_voice.clef.time = 0;
delete p_voice.have_ly;
p_voice.sls = [];
p_voice.hy_st = 0;
delete p_voice.bar_start
}
staves_found = 0 // (for compress/dup the voices)
}
// transpose a key
//fixme: transpose of the accidental list is not done
function key_transp(sk) {
if (sk.k_a_acc || sk.k_none) // same displayed key
function key_transp(s) {
if (s.k_none) // no key
return
var d,
k_b40 = sk.k_b40,
n_b40 = (k_b40 + 200 + sk.k_transp) % 40
var n, a_acc,
b40 = (s.k_b40 + 200 + curvoice.tr_sco) % 40,
d = abc2svg.b40k[n_b40] - n_b40
d = abc2svg.b40k[b40] - b40
if (d) {
if (sk.k_transp > 0)
sk.k_transp += d
if (curvoice.tr_sco > 0)
curvoice.tr_sco -= d
else
sk.k_transp -= d
n_b40 += d
curvoice.tr_sco += d
b40 += d
}
sk.k_b40 = n_b40
s.k_b40 = b40
var sf = abc2svg.b40sf[n_b40]
s.k_sf = abc2svg.b40sf[b40]
sk.k_old_sf = sk.k_sf
sk.k_sf = sf
sk.k_map = abc2svg.keys[sf + 7] // map of the notes with accidentals
}
// transpose the accidental list
/*
* for transpose purpose, check if a pitch is already in the measure or
* if it is tied from a previous note, and return the associated accidental
*/
function acc_same_pitch(s, pit) {
var i,
time = s.time
for (s = s.prev; s; s = s.prev) {
switch (s.type) {
case C.BAR:
if (s.time < time)
return //undefined // no same pitch
while (1) {
s = s.prev
if (!s)
return //undefined
if (!s.k_a_acc)
return
if (s.type == C.NOTE) {
if (s.time + s.dur == time)
break
a_acc = []
return //undefined
}
if (s.time < time)
return //undefined
}
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].pit == pit
&& s.notes[i].tie_ty)
for (n = 0; n < s.k_a_acc.length; n++) {
b40 = abc2svg.pab40(s.k_a_acc[n].pit, s.k_a_acc[n].acc)
+ curvoice.tr_sco
return s.notes[i].acc
}
return //undefined
case C.NOTE:
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].pit == pit)
return s.notes[i].acc
}
a_acc[n] = {
pit: abc2svg.b40p(b40),
acc: abc2svg.b40a(b40) || 3
}
break
}
}
}
return //undefined
s.k_a_acc = a_acc
}
/* -- get staves definition (%%staves / %%score) -- */
function get_staves(cmd, parm) {
var s, p_voice, p_voice2, i, flags, v, vid, a_vf,
st, range,
nv = voice_tb.length,
|
| ︙ | | |
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
|
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
|
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
|
voice_tb.push(p_voice)
return p_voice
} // clone_voice()
/* -- get a voice overlay -- */
function get_vover(type) {
var p_voice2, p_voice3, range, s, time, v, v2, v3,
var p_voice2, p_voice3, range, s, time, v, v2, v3, s2
line = parse.line
/* treat the end of overlay */
if (type == '|'
|| type == ')') {
if (!curvoice.last_note) {
syntax(1, errs.nonote_vo)
if (vover) {
curvoice = vover.p_voice
vover = null
}
return
}
curvoice.last_note.beam_end = true
if (!vover) {
syntax(1, "Erroneous end of voice overlay")
return
}
if (curvoice.time != vover.p_voice.time) {
if (!curvoice.ignore)
syntax(1, "Wrong duration in voice overlay");
if (curvoice.time > vover.p_voice.time)
vover.p_voice.time = curvoice.time
}
curvoice.acc = [] // no accidental anymore
// if the last symbols are spaces, move them to the main voice
p_voice2 = vover.p_voice // main voice
s = curvoice.last_sym
if (s.type == C.SPACE && p_voice2.last_sym.type != C.SPACE) {
s.p_v = p_voice2
s.v = s.p_v.v
while (s.prev.type == C.SPACE) {
s = s.prev
s.p_v = p_voice2
s.v = s.p_v.v
}
s2 = s.prev
s2.next = null
s.prev = p_voice2.last_sym
s.prev.next = s
p_voice2.last_sym = curvoice.last_sym
curvoice.last_sym = s2
}
curvoice = vover.p_voice;
curvoice = p_voice2
vover = null
return
}
/* treat the full overlay start */
if (type == '(') {
if (vover) {
|
| ︙ | | |
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
|
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
|
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
+
-
+
-
+
-
+
+
|
curvoice.last_note.beam_end = true;
p_voice2 = curvoice.voice_down
if (!p_voice2) {
p_voice2 = clone_voice(curvoice.id + 'o');
curvoice.voice_down = p_voice2;
p_voice2.time = 0;
p_voice2.second = true;
p_voice2.last_note = null
v2 = p_voice2.v;
if (par_sy.voices[curvoice.v]) { // if voice in the staff system
par_sy.voices[v2] = {
st: curvoice.st,
second: true
}
range = par_sy.voices[curvoice.v].range
for (v = 0; v < par_sy.voices.length; v++) {
if (par_sy.voices[v]
&& par_sy.voices[v].range > range)
par_sy.voices[v].range++
}
par_sy.voices[v2].range = range + 1
}
}
p_voice2.ulen = curvoice.ulen
p_voice2.dur_fact = curvoice.dur_fact
p_voice2.acc = [] // no accidental
if (!vover) { /* first '&' in a measure */
time = p_voice2.time
if (curvoice.ignore)
s = null
else
for (s = curvoice.last_sym; /*s*/; s = s.prev) {
if (s.type == C.BAR
|| s.time <= time) /* (if start of tune) */
break
}
vover = {
bar: (s && s.bar_type) ? s.bar_type : '|',
p_voice: curvoice,
time: s.time
time: s ? s.time : curvoice.time
}
} else {
if (curvoice != vover.p_voice
&& curvoice.time != vover.p_voice.time) {
syntax(1, "Wrong duration in voice overlay")
if (curvoice.time > vover.p_voice.time)
vover.p_voice.time = curvoice.time
}
}
p_voice2.time = vover.time;
curvoice = p_voice2
// add a bar at start of the measure overlay
// (needed for sort_all() in case of spaces - 'y')
if (vover.bar && vover.time) {
sym_link({
type: C.BAR,
bar_type: vover.bar,
invis: 1,
dur: 0,
multi: 0
})
}
}
// check if a clef, key or time signature may go at start of the current voice
function is_voice_sig() {
var s
if (!curvoice.last_sym)
return true
if (curvoice.time)
return false
if (curvoice.time)
return false
if (!curvoice.last_sym)
return true
for (s = curvoice.last_sym; s; s = s.prev)
if (w_tb[s.type])
return false
return true
}
// treat a clef found in the tune body
function get_clef(s) {
if (!curvoice.time // (force a clef when new voice)
if (is_voice_sig()) {
&& is_voice_sig()) {
curvoice.clef = s
s.fmt = cfmt
return
}
// clef change
sym_link(s);
s.clef_small = true
// move the clef before a (not right repeat) bar
var s2 = s.prev
if (!s.invis // if not 'K: clef=none'
if (s2 && s2.type == C.BAR
&& s2 && s2.type == C.BAR
&& s2.bar_type[0] != ':') {
s.next = s2
s.prev = s2.prev
if (s.prev)
s.prev.next = s
s2.prev = s
s2.next = null
curvoice.last_sym = s2
if (s.soln) {
delete s.soln
curvoice.eoln = true
}
}
}
// treat K: (kp = key signature + parameters)
function get_key(parm) {
var v, p_voice, s, transp, sndtran,
var v, p_voice, transp, sndtran, tr_p, nt,
// [s_key, a] = new_key(parm) // KO with nodejs
a = new_key(parm),
s_key = a[0];
s_key = a[0],
s = s_key
a = a[1]
if (parse.state == 1) { // in tune header (first K:)
if (s_key.k_sf == undefined && !s_key.k_a_acc) { // empty K:
s_key.k_sf = 0;
s_key.k_none = true
|
| ︙ | | |
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
|
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
|
-
-
-
-
-
-
+
+
+
+
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
-
-
-
+
+
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
-
+
-
|
if (!glovar.ulen)
glovar.ulen = C.BLEN / 8;
if (a.length) {
memo_kv_parm('*', a)
a = ''
}
goto_tune()
parse.state = 3 // in tune body
}
set_kv_parm(a)
if (!curvoice.ckey.k_bagpipe && !curvoice.ckey.k_drum
} else {
set_kv_parm(a)
}
&& (cfmt.transp != undefined
|| curvoice.transp != undefined
tr_p = curvoice.tr_p // transposition change 1=sco, 2=snd
|| curvoice.shift != undefined))
transp = (cfmt.transp || 0) +
(curvoice.transp || 0) +
curvoice.tr_p = 0
(curvoice.shift || 0)
if (curvoice.sndtran != undefined
|| curvoice.sndsh != undefined)
sndtran = (curvoice.sndtran || 0) +
(curvoice.sndsh || 0)
if (s_key.k_sf == undefined) {
if (!s_key.k_a_acc
if (s.k_sf == undefined) { // if no key
if (!s.k_a_acc // if no accidental list
&& transp == undefined) {
if (sndtran == undefined)
return // not a key signature
&& !(tr_p & 1)) // and no score transposition
return // not a key signature
s_key.invis = true // play only
}
s_key.k_sf = curvoice.okey.k_sf
s_key.k_sf = curvoice.okey.k_sf // set the same key
s_key.k_b40 = curvoice.okey.k_b40
}
curvoice.okey = clone(s_key)
if (transp != undefined) {
curvoice.vtransp = transp;
s_key.k_transp = transp
}
if (sndtran != undefined)
s_key.k_sndtran = sndtran
if (curvoice.tr_sco) // if transpose score
key_transp(s)
curvoice.okey = clone(s_key)
s_key.k_old_sf = curvoice.ckey.k_sf; // memorize the key changes
s_key.k_old_sf = curvoice.ckey.k_sf // memorize the key changes
if ((!s_key.k_a_acc || !s_key.k_a_acc.length)
&& !s_key.k_sf && !s_key.k_old_sf)
s_key.invis = true // don't display the key signature
if (!s_key.k_b40)
s_key.k_b40 = curvoice.ckey.k_b40
curvoice.ckey = s_key
if (is_voice_sig()) {
s_key.fmt = cfmt
curvoice.key = clone(s_key)
if (s_key.k_none)
curvoice.key.k_sf = 0
} else {
sym_link(s_key) // (don't move the key)
|
| ︙ | | |
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
|
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
|
+
|
if (!p_voice.time) { // if no symbol yet
p_voice.id = id
delete p_voice.init // reload the global attributes
if (cfmt.transp // != undefined
&& parse.state >= 2) {
p_v_sav = curvoice;
curvoice = p_voice;
curvoice.tr_sco = cfmt.transp
set_transp();
curvoice = p_v_sav
}
return p_voice // default voice
}
}
for (v = 0; v < n; v++) {
|
| ︙ | | |
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
|
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
|
+
+
+
+
+
+
+
|
bol: parse.iend
}
if (parse.file[curvoice.clone.bol - 1] != ']')
curvoice.clone.bol++ // start of new line
}
set_kv_parm(a)
if (curvoice.tr_p) {
curvoice.tr_p = 0
set_transp()
}
v = curvoice.v
if (curvoice.new) { // if new voice
delete curvoice.new
if (staves_found < 0) { // if no %%score/%%staves
curvoice.st = curvoice.cst = ++nstaff;
par_sy.nstaff = nstaff;
par_sy.voices[v] = {
st: nstaff,
range: v
}
par_sy.staves[nstaff] = {
stafflines: curvoice.stafflines || "|||||",
staffscale: 1
}
} else if (!par_sy.voices[v]) {
curvoice.ignore = 1 // voice not declared in %%staves
return
}
}
if (!curvoice.filtered
&& par_sy.voices[v]
&& (parse.voice_opts
|| parse.tune_v_opts)) {
|
| ︙ | | |
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
|
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
|
+
+
|
write_heading();
if (glovar.new_nbar) {
gene.nbar = glovar.new_nbar // measure numbering
glovar.new_nbar = 0
} else {
gene.nbar = 1
}
parse.state = 3 // in tune body
// if no voice yet, create the default voice
if (!voice_tb.length) {
get_voice("1");
curvoice.clef.istart = curvoice.key.istart;
curvoice.clef.iend = curvoice.key.iend;
// nstaff = 0;
|
| ︙ | | |
| ︙ | | |
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
-
+
|
Layer: 0 1 "Back" 1
Layer: 1 0 "Fore" 0
XUID: [1021 296 1430826605 13506888]
OS2Version: 0
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 0
CreationTime: 1433498007
ModificationTime: 1644676399
ModificationTime: 1654926804
PfmFamily: 17
TTFWeight: 400
TTFWidth: 5
LineGap: 92
VLineGap: 92
Panose: 2 0 5 3 0 0 0 0 0 0
OS2TypoAscent: 0
|
| ︙ | | |
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
-
+
|
Encoding: Custom
Compacted: 1
UnicodeInterp: none
NameList: Adobe Glyph List
DisplaySize: -96
AntiAlias: 1
FitToEm: 1
WinInfo: 80 8 2
WinInfo: 0 8 2
BeginPrivate: 0
EndPrivate
TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
BeginChars: 143 143
StartChar: .nodef
Encoding: 0 0 0
|
| ︙ | | |
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
|
203 2 167 51 167 91 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE048
Encoding: 10 57416 10
Width: 862
Flags: MW
Width: 954
Flags: HMW
LayerCount: 2
Fore
SplineSet
472 596 m 1
512 596 l 1
512 459 l 1
625 448 715 344 724 216 c 1
862 216 l 1
862 176 l 1
724 176 l 1
452 866 m 1
504 866 l 1
504 695 l 1
653 680 772 545 784 374 c 1
956 374 l 1
956 322 l 1
784 322 l 1
772 153 653 16 504 1 c 1
504 -170 l 1
452 -170 l 1
452 1 l 1
303 16 184 153 172 322 c 1
-0 322 l 1
715 48 625 -56 512 -67 c 1
512 -204 l 1
472 -204 l 1
472 -67 l 1
-0 374 l 1
172 374 l 1
184 548 303 680 452 695 c 1
359 -56 269 48 260 176 c 1
122 176 l 1
122 216 l 1
260 216 l 1
452 866 l 1
452 322 m 1
304 322 l 1
269 348 359 448 472 459 c 1
472 596 l 1
309 136 373 69 452 58 c 1
472 176 m 1
360 176 l 1
364 35 412 -16 472 -24 c 1
472 176 l 1
512 176 m 1
512 -24 l 1
572 -16 620 35 624 176 c 1
512 176 l 1
512 216 m 1
624 216 l 1
452 322 l 1
504 322 m 1
504 58 l 1
583 69 647 134 652 322 c 1
504 322 l 1
504 374 m 1
652 374 l 1
647 563 583 627 504 638 c 1
504 374 l 1
452 374 m 1
452 640 l 1
620 358 572 408 512 416 c 1
512 216 l 1
472 216 m 1
472 417 l 1
412 409 364 361 360 216 c 1
472 216 l 1
373 629 309 565 304 374 c 1
452 374 l 1
EndSplineSet
Validated: 1
EndChar
StartChar: uniE050
Encoding: 11 57424 11
Width: 779
|
| ︙ | | |
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
|
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
|
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
+
|
Encoding: 19 57470 19
Width: 360
Flags: HMW
LayerCount: 2
Fore
SplineSet
212 -1 m 0
166 -1 150 22 150 54 c 0
150 73 158 87 174 87 c 0
189 87 201 79 201 60 c 0
201 45 183 39 183 25 c 0
183 13 200 11 212 11 c 0
171 -1 150 17 150 54 c 0
150 75 159 87 174 87 c 0
191 87 201 77 201 60 c 0
201 53 196 47 192 42 c 0
188 37 183 32 183 25 c 0
183 16 193 11 212 11 c 0
243 11 279 66 279 112 c 0
279 131 272 140 249 140 c 0
217 140 201 115 189 115 c 0
279 132 271 140 249 140 c 0
238 140 229 134 219 128 c 0
209 122 200 115 189 115 c 0
180 115 178 118 178 130 c 0
178 140 198 196 216 236 c 24
219 242 224 247 231 247 c 0
273 248 297 248 339 248 c 0
347 248 359 250 359 241 c 0
359 229 349 222 337 218 c 0
300 205 276 201 239 193 c 0
224 190 224 186 222 174 c 0
220 164 220 157 233 161 c 0
220 243 225 247 231 247 c 0
266 248 284 248 339 248 c 0
358 248 359 248 359 241 c 0
359 231 352 223 337 218 c 0
309 208 308 208 239 193 c 0
226 190 224 189 222 174 c 0
219 161 222 158 233 161 c 0
241 163 250 164 259 164 c 0
305 164 326 135 326 96 c 0
326 39 269 -1 212 -1 c 0
301 164 326 139 326 96 c 0
326 43 274 -1 212 -1 c 0
9 0 m 0
-2.48824948263 1.68260667765e-07 -3.48824945257 18.0000001683 9 18 c 0
12 17.9999999596 14 18 18 18 c 0
27 18 39 19 43 30 c 0
62 75 65 84 84 134 c 0
89 147 90 155 78 155 c 0
69 155 66 152 61 146 c 0
54 138 46 133 36 138 c 0
25 144 34 153 41 162 c 0
76 207 112 259 125 259 c 0
140 259 150 246 165 246 c 0
168 246 172 247 175 248 c 0
191 253 196 249 192 238 c 0
155 148 122 67 111 36 c 0
-3 0 -3 18 9 18 c 0
12 18 14 18 18 18 c 0
32 18 40 22 43 30 c 0
44 31 44 33 45 34 c 0
58 65 58 65 81 126 c 0
82 129 83 131 84 134 c 0
90 150 88 155 78 155 c 0
70 155 67 153 61 146 c 0
52 136 45 134 36 138 c 0
28 143 28 146 41 162 c 0
51 174 59 186 66 195 c 0
111 253 116 259 120 259 c 0
121 259 121 259 122 259 c 0
123 259 124 259 125 259 c 0
133 259 139 255 145 252 c 0
151 249 157 246 165 246 c 0
168 246 171 247 175 248 c 0
190 253 196 249 192 238 c 0
144 121 120 62 111 36 c 0
109.509271996 31.8259615875 108.551888787 28.5408311683 108.551888787 25.9855943378 c 0
108.551888787 19.9703983902 113.857348821 18 130 18 c 4
137.838821814 18 142.400463498 13.0842298053 142.400463498 8.39053563394 c 0
142.400463498 4.10259784076 138.593413823 -8.881784197e-16 130 0 c 0
109 31 109 28 109 26 c 0
109 20 114 18 130 18 c 0
137 18 142 13 142 8 c 0
142 3 138 0 130 0 c 0
115 0 103 0 91 -0 c 0
79 -0 67 0 52 -0 c 0
95.3333333333 0 76.6666666667 -3.45002388166e-07 52.3703703704 -3.45002388166e-07 c 0
40.2222222222 -3.45002388166e-07 26.6666666667 -2.58751791125e-07 9 0 c 0
38 0 25 0 9 0 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE080
Encoding: 20 57472 20
Width: 430
|
| ︙ | | |
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
|
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
|
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
|
Width: 400
Flags: HMW
LayerCount: 2
Fore
SplineSet
152 35 m 2
357 483 l 2
363.701063819 494.913002345 369.847754103 501.282269343 377.916665809 501.282269343 c 0
380.684870018 501.282269343 383.679314405 500.532624121 387 499 c 0
394.855750978 495.072124511 397.988581796 490.19966499 397.988581796 483.852591655 c 0
397.988581796 478.888330538 396.072124511 473.021998882 393 466 c 2
364 495 370 501 378 501 c 0
381 501 384 501 387 499 c 0
395 495 398 490 398 484 c 0
398 479 396 473 393 466 c 2
189 17 l 2
183.913450587 6.82690117401 177.770860973 -0.178077048204 169.421173872 -0.178077048204 c 0
166.280201006 -0.178077048204 162.826901174 0.813199329137 159 3 c 0
151.569978236 7.33417936247 147.973652542 13.5852067603 147.973652542 20.8036006853 c 0
147.973652542 25.2434131355 149.334179362 30.0491902446 152 35 c 2
184 7 178 -0 169 -0 c 0
166 -0 163 1 159 3 c 0
152 7 148 14 148 21 c 0
148 25 149 30 152 35 c 2
9 35 m 2
214 483 l 2
220.701063819 494.913002345 226.847754103 501.282269343 234.916665809 501.282269343 c 0
237.684870018 501.282269343 240.679314405 500.532624121 244 499 c 0
251.855750978 495.072124511 254.988581796 490.19966499 254.988581796 483.852591655 c 0
254.988581796 478.888330538 253.072124511 473.021998882 250 466 c 2
221 495 227 501 235 501 c 0
238 501 241 501 244 499 c 0
252 495 255 490 255 484 c 0
255 479 253 473 250 466 c 2
46 17 l 2
40.913450587 6.82690117401 34.7708609728 -0.178077048204 26.4211738717 -0.178077048204 c 0
23.2802010063 -0.178077048204 19.826901174 0.813199329137 16 3 c 0
8.56997823576 7.33417936247 4.97365254215 13.5852067603 4.97365254215 20.8036006853 c 0
4.97365254215 25.2434131355 6.33417936247 30.0491902446 9 35 c 2
41 7 35 -0 26 -0 c 0
23 -0 20 1 16 3 c 0
9 7 5 14 5 21 c 0
5 25 6 30 9 35 c 2
EndSplineSet
Validated: 1
EndChar
StartChar: uniE4E1
Encoding: 83 58593 83
Width: 130
Flags: HMW
LayerCount: 2
|
| ︙ | | |
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
|
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
|
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
|
Encoding: 101 58665 101
Width: 703
Flags: HMW
LayerCount: 2
Fore
SplineSet
522 40 m 0
524.179123831 39.0525548563 526.555731167 38.5988184777 529.0907001 38.5988184777 c 0
553.311569742 38.5988184777 591.989634802 80.0214592618 611 128 c 0
618.801273837 147.763227053 623.897664408 174.829638922 623.897664408 197.52305288 c 0
623.897664408 218.46369363 619.558131706 235.680764302 609 240 c 0
607.059714009 240.759242344 604.934395026 241.11995209 602.659464452 241.11995209 c 0
577.96754404 241.11995209 535.650235832 198.625589581 521 162 c 0
510.665333312 135.693575703 506.068143327 108.945807045 506.068143327 87.1471403297 c 0
506.068143327 62.5417301443 511.925393958 44.2419393862 522 40 c 0
524 39 526 39 529 39 c 0
553 39 592 80 611 128 c 0
619 148 624 175 624 198 c 0
624 219 620 236 609 240 c 0
607 241 605 241 603 241 c 0
578 241 536 199 521 162 c 0
511 136 506 109 506 87 c 0
506 62 512 44 522 40 c 0
197 40 m 0
199.179123831 39.0525548563 201.555731167 38.5988184777 204.0907001 38.5988184777 c 0
228.311569742 38.5988184777 266.989634802 80.0214592618 286 128 c 0
293.801273837 147.763227053 298.897664408 174.829638922 298.897664408 197.52305288 c 0
298.897664408 218.46369363 294.558131706 235.680764302 284 240 c 0
282.059714009 240.759242344 279.934395026 241.11995209 277.659464452 241.11995209 c 0
252.96754404 241.11995209 210.650235832 198.625589581 196 162 c 0
185.665333312 135.693575703 181.068143327 108.945807045 181.068143327 87.1471403297 c 0
181.068143327 62.5417301443 186.925393958 44.2419393862 197 40 c 0
199 39 201 39 204 39 c 0
228 39 267 80 286 128 c 0
294 148 299 175 299 198 c 0
299 219 295 236 284 240 c 0
282 241 280 241 278 241 c 0
253 241 211 199 196 162 c 0
186 136 181 109 181 87 c 0
181 62 187 44 197 40 c 0
200 0 m 0
183 0 173 6 153 32 c 1
108 -90 l 1
160 -90 l 2
175 -90 175 -120 160 -120 c 2
-65 -120 l 2
-79 -120 -80 -90 -65 -90 c 2
10 -90 l 1
114 195 l 2
115.167116963 197.917792406 120.420719938 212.754502351 120.420719938 224.605732511 c 0
120.420719938 233.06305846 117.745271893 240 109 240 c 0
115 198 120 213 120 225 c 0
120 233 118 240 109 240 c 0
83 240 72 207 28 135 c 0
21 124 -6 139 1 151 c 0
56 249 69 280 125 280 c 0
170 280 193 271 203 235 c 1
244 278 263 280 305 280 c 0
331 280 358 264 371 230 c 1
395 267 413 280 450 280 c 0
|
| ︙ | | |
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
|
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
|
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
|
1083 -90 l 1
1135 -90 l 2
1150 -90 1150 -120 1135 -120 c 2
910 -120 l 2
896 -120 895 -90 910 -90 c 2
985 -90 l 1
1089 195 l 2
1090.16711696 197.917792406 1095.42071994 212.754502351 1095.42071994 224.605732511 c 0
1095.42071994 233.06305846 1092.74527189 240 1084 240 c 0
1090 198 1095 213 1095 225 c 0
1095 233 1093 240 1084 240 c 0
1064 240 1053 221 1030 181 c 0
1030 181 1030 180 1030 180 c 0
1030 180 l 0
1030 87 949 0 850 0 c 0
833 0 823 6 803 32 c 1
758 -90 l 1
810 -90 l 2
825 -90 825 -120 810 -120 c 2
585 -120 l 2
571 -120 570 -90 585 -90 c 2
660 -90 l 1
764 195 l 2
765.167116963 197.917792406 770.420719938 212.754502351 770.420719938 224.605732511 c 0
770.420719938 233.06305846 767.745271893 240 759 240 c 0
765 198 770 213 770 225 c 0
770 233 768 240 759 240 c 0
739 240 728 221 705 181 c 0
705 181 705 180 705 180 c 0
705 180 l 0
705 87 624 0 525 0 c 0
508 0 498 6 478 32 c 1
433 -90 l 1
485 -90 l 2
500 -90 500 -120 485 -120 c 2
260 -120 l 2
246 -120 245 -90 260 -90 c 2
335 -90 l 1
439 195 l 2
440.167116963 197.917792406 445.420719938 212.754502351 445.420719938 224.605732511 c 0
445.420719938 233.06305846 442.745271893 240 434 240 c 0
440 198 445 213 445 225 c 0
445 233 443 240 434 240 c 0
414 240 403 221 380 181 c 0
380 181 380 180 380 180 c 0
380 180 l 0
380 87 299 0 200 0 c 0
1172 40 m 0
1174.17912383 39.0525548563 1176.55573117 38.5988184777 1179.0907001 38.5988184777 c 0
1203.31156974 38.5988184777 1241.9896348 80.0214592618 1261 128 c 0
1268.80127384 147.763227053 1273.89766441 174.829638922 1273.89766441 197.52305288 c 0
1273.89766441 218.46369363 1269.55813171 235.680764302 1259 240 c 0
1257.05971401 240.759242344 1254.93439503 241.11995209 1252.65946445 241.11995209 c 0
1227.96754404 241.11995209 1185.65023583 198.625589581 1171 162 c 0
1160.66533331 135.693575703 1156.06814333 108.945807045 1156.06814333 87.1471403297 c 0
1156.06814333 62.5417301443 1161.92539396 44.2419393862 1172 40 c 0
1174 39 1176 39 1179 39 c 0
1203 39 1242 80 1261 128 c 0
1269 148 1274 175 1274 198 c 0
1274 219 1270 236 1259 240 c 0
1257 241 1255 241 1253 241 c 0
1228 241 1186 199 1171 162 c 0
1161 136 1156 109 1156 87 c 0
1156 62 1162 44 1172 40 c 0
847 40 m 0
849.179123831 39.0525548563 851.555731167 38.5988184777 854.0907001 38.5988184777 c 0
878.311569742 38.5988184777 916.989634802 80.0214592618 936 128 c 0
943.801273837 147.763227053 948.897664408 174.829638922 948.897664408 197.52305288 c 0
948.897664408 218.46369363 944.558131706 235.680764302 934 240 c 0
932.059714009 240.759242344 929.934395026 241.11995209 927.659464452 241.11995209 c 0
902.96754404 241.11995209 860.650235832 198.625589581 846 162 c 0
835.665333312 135.693575703 831.068143327 108.945807045 831.068143327 87.1471403297 c 0
831.068143327 62.5417301443 836.925393958 44.2419393862 847 40 c 0
849 39 851 39 854 39 c 0
878 39 917 80 936 128 c 0
944 148 949 175 949 198 c 0
949 219 945 236 934 240 c 0
932 241 930 241 928 241 c 0
903 241 861 199 846 162 c 0
836 136 831 109 831 87 c 0
831 62 837 44 847 40 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE52A
Encoding: 102 58666 102
Width: 563
Flags: W
HStem: -120 30<-74.2249 10 108 169.668 250.775 335 433 494.668 575.775 660 758 819.668> 0 38.5988<191.014 237.319 516.014 562.319 841.014 887.319> 240 40<80.1149 147.5 239.117 318 404.386 472.5 564.117 643 729.386 797.5 889.117 973>
VStem: 120.421 60.6474<87.1471 224.606> 298.898 81.1023<108.679 217.246> 445.421 60.6474<87.1471 224.606> 623.898 81.1023<108.679 217.246> 770.421 60.6474<87.1471 224.606> 948.898 81.1023<108.462 239.669>
HStem: -120 30<-74.2249 10 108 169.668 250.775 335 433 494.668 575.775 660 758 819.668> 0 39<191.01 237.957 516.01 562.957 841.01 887.957> 240 40<80.1149 147.5 239.21 318 404.386 472.5 564.21 643 729.386 797.5 889.21 973>
VStem: 120 61<87 225> 299 81<108.679 217.246> 445 61<87 225> 624 81<108.679 217.246> 770 61<87 225> 949 81<108.469 239.676>
LayerCount: 2
Fore
SplineSet
850 0 m 0
833 0 823 6 803 32 c 1
758 -90 l 1
810 -90 l 2
825 -90 825 -120 810 -120 c 2
585 -120 l 2
571 -120 570 -90 585 -90 c 2
660 -90 l 1
764 195 l 2
765.167116963 197.917792406 770.420719938 212.754502351 770.420719938 224.605732511 c 0
770.420719938 233.06305846 767.745271893 240 759 240 c 0
765 198 770 213 770 225 c 0
770 233 768 240 759 240 c 0
739 240 728 221 705 181 c 0
705 181 705 180 705 180 c 0
705 180 l 0
705 87 624 0 525 0 c 0
508 0 498 6 478 32 c 1
433 -90 l 1
485 -90 l 2
500 -90 500 -120 485 -120 c 2
260 -120 l 2
246 -120 245 -90 260 -90 c 2
335 -90 l 1
439 195 l 2
440.167116963 197.917792406 445.420719938 212.754502351 445.420719938 224.605732511 c 0
445.420719938 233.06305846 442.745271893 240 434 240 c 0
440 198 445 213 445 225 c 0
445 233 443 240 434 240 c 0
414 240 403 221 380 181 c 0
380 181 380 180 380 180 c 0
380 180 l 0
380 87 299 0 200 0 c 0
183 0 173 6 153 32 c 1
108 -90 l 1
160 -90 l 2
175 -90 175 -120 160 -120 c 2
-65 -120 l 2
-79 -120 -80 -90 -65 -90 c 2
10 -90 l 1
114 195 l 2
115.167116963 197.917792406 120.420719938 212.754502351 120.420719938 224.605732511 c 0
120.420719938 233.06305846 117.745271893 240 109 240 c 0
115 198 120 213 120 225 c 0
120 233 118 240 109 240 c 0
83 240 72 207 28 135 c 0
21 124 -6 139 1 151 c 0
56 249 69 280 125 280 c 0
170 280 193 271 203 235 c 1
244 278 263 280 305 280 c 0
331 280 358 264 371 230 c 1
395 267 413 280 450 280 c 0
495 280 518 271 528 235 c 1
569 278 588 280 630 280 c 0
656 280 683 264 696 230 c 1
720 267 738 280 775 280 c 0
820 280 843 271 853 235 c 1
894 278 913 280 955 280 c 0
991 280 1030 248 1030 180 c 0
1030 87 949 0 850 0 c 0
847 40 m 0
849.179123831 39.0525548563 851.555731167 38.5988184777 854.0907001 38.5988184777 c 0
878.311569742 38.5988184777 916.989634802 80.0214592618 936 128 c 0
943.801273837 147.763227053 948.897664408 174.829638922 948.897664408 197.52305288 c 0
948.897664408 218.46369363 944.558131706 235.680764302 934 240 c 0
932.059714009 240.759242344 929.934395026 241.11995209 927.659464452 241.11995209 c 0
902.96754404 241.11995209 860.650235832 198.625589581 846 162 c 0
835.665333312 135.693575703 831.068143327 108.945807045 831.068143327 87.1471403297 c 0
831.068143327 62.5417301443 836.925393958 44.2419393862 847 40 c 0
849 39 851 39 854 39 c 0
878 39 917 80 936 128 c 0
944 148 949 175 949 198 c 0
949 219 945 236 934 240 c 0
932 241 930 241 928 241 c 0
903 241 861 199 846 162 c 0
836 136 831 109 831 87 c 0
831 62 837 44 847 40 c 0
522 40 m 0
524.179123831 39.0525548563 526.555731167 38.5988184777 529.0907001 38.5988184777 c 0
553.311569742 38.5988184777 591.989634802 80.0214592618 611 128 c 0
618.801273837 147.763227053 623.897664408 174.829638922 623.897664408 197.52305288 c 0
623.897664408 218.46369363 619.558131706 235.680764302 609 240 c 0
607.059714009 240.759242344 604.934395026 241.11995209 602.659464452 241.11995209 c 0
577.96754404 241.11995209 535.650235832 198.625589581 521 162 c 0
510.665333312 135.693575703 506.068143327 108.945807045 506.068143327 87.1471403297 c 0
506.068143327 62.5417301443 511.925393958 44.2419393862 522 40 c 0
524 39 526 39 529 39 c 0
553 39 592 80 611 128 c 0
619 148 624 175 624 198 c 0
624 219 620 236 609 240 c 0
607 241 605 241 603 241 c 0
578 241 536 199 521 162 c 0
511 136 506 109 506 87 c 0
506 62 512 44 522 40 c 0
197 40 m 0
199.179123831 39.0525548563 201.555731167 38.5988184777 204.0907001 38.5988184777 c 0
228.311569742 38.5988184777 266.989634802 80.0214592618 286 128 c 0
293.801273837 147.763227053 298.897664408 174.829638922 298.897664408 197.52305288 c 0
298.897664408 218.46369363 294.558131706 235.680764302 284 240 c 0
282.059714009 240.759242344 279.934395026 241.11995209 277.659464452 241.11995209 c 0
252.96754404 241.11995209 210.650235832 198.625589581 196 162 c 0
185.665333312 135.693575703 181.068143327 108.945807045 181.068143327 87.1471403297 c 0
181.068143327 62.5417301443 186.925393958 44.2419393862 197 40 c 0
199 39 201 39 204 39 c 0
228 39 267 80 286 128 c 0
294 148 299 175 299 198 c 0
299 219 295 236 284 240 c 0
282 241 280 241 278 241 c 0
253 241 211 199 196 162 c 0
186 136 181 109 181 87 c 0
181 62 187 44 197 40 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE52B
Encoding: 103 58667 103
Width: 703
Flags: HMW
LayerCount: 2
Fore
SplineSet
200 0 m 0
183 0 173 6 153 32 c 1
108 -90 l 1
160 -90 l 2
175 -90 175 -120 160 -120 c 2
-65 -120 l 2
-79 -120 -80 -90 -65 -90 c 2
10 -90 l 1
114 195 l 2
115.167116963 197.917792406 120.420719938 212.754502351 120.420719938 224.605732511 c 0
120.420719938 233.06305846 117.745271893 240 109 240 c 0
115 198 120 213 120 225 c 0
120 233 118 240 109 240 c 0
83 240 72 207 28 135 c 0
21 124 -6 139 1 151 c 0
56 249 69 280 125 280 c 0
170 280 193 271 203 235 c 1
244 278 263 280 305 280 c 0
331 280 358 264 371 230 c 1
395 267 413 280 450 280 c 0
495 280 518 271 528 235 c 1
569 278 588 280 630 280 c 0
666 280 705 248 705 180 c 0
705 87 624 0 525 0 c 0
508 0 498 6 478 32 c 1
433 -90 l 1
485 -90 l 2
500 -90 500 -120 485 -120 c 2
260 -120 l 2
246 -120 245 -90 260 -90 c 2
335 -90 l 1
439 195 l 2
440.167116963 197.917792406 445.420719938 212.754502351 445.420719938 224.605732511 c 0
445.420719938 233.06305846 442.745271893 240 434 240 c 0
440 198 445 213 445 225 c 0
445 233 443 240 434 240 c 0
414 240 403 221 380 181 c 0
380 181 380 180 380 180 c 0
380 180 l 0
380 87 299 0 200 0 c 0
197 40 m 0
199.179123831 39.0525548563 201.555731167 38.5988184777 204.0907001 38.5988184777 c 0
228.311569742 38.5988184777 266.989634802 80.0214592618 286 128 c 0
293.801273837 147.763227053 298.897664408 174.829638922 298.897664408 197.52305288 c 0
298.897664408 218.46369363 294.558131706 235.680764302 284 240 c 0
282.059714009 240.759242344 279.934395026 241.11995209 277.659464452 241.11995209 c 0
252.96754404 241.11995209 210.650235832 198.625589581 196 162 c 0
185.665333312 135.693575703 181.068143327 108.945807045 181.068143327 87.1471403297 c 0
181.068143327 62.5417301443 186.925393958 44.2419393862 197 40 c 0
199 39 201 39 204 39 c 0
228 39 267 80 286 128 c 0
294 148 299 175 299 198 c 0
299 219 295 236 284 240 c 0
282 241 280 241 278 241 c 0
253 241 211 199 196 162 c 0
186 136 181 109 181 87 c 0
181 62 187 44 197 40 c 0
522 40 m 0
524.179123831 39.0525548563 526.555731167 38.5988184777 529.0907001 38.5988184777 c 0
553.311569742 38.5988184777 591.989634802 80.0214592618 611 128 c 0
618.801273837 147.763227053 623.897664408 174.829638922 623.897664408 197.52305288 c 0
623.897664408 218.46369363 619.558131706 235.680764302 609 240 c 0
607.059714009 240.759242344 604.934395026 241.11995209 602.659464452 241.11995209 c 0
577.96754404 241.11995209 535.650235832 198.625589581 521 162 c 0
510.665333312 135.693575703 506.068143327 108.945807045 506.068143327 87.1471403297 c 0
506.068143327 62.5417301443 511.925393958 44.2419393862 522 40 c 0
524 39 526 39 529 39 c 0
553 39 592 80 611 128 c 0
619 148 624 175 624 198 c 0
624 219 620 236 609 240 c 0
607 241 605 241 603 241 c 0
578 241 536 199 521 162 c 0
511 136 506 109 506 87 c 0
506 62 512 44 522 40 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE52C
Encoding: 104 58668 104
Width: 811
|
| ︙ | | |
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
|
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
|
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
|
539 -90 l 1
591 -90 l 2
606 -90 606 -120 591 -120 c 2
366 -120 l 2
352 -120 351 -90 366 -90 c 2
441 -90 l 1
545 195 l 2
546.167116963 197.917792406 551.420719938 212.754502351 551.420719938 224.605732511 c 0
551.420719938 233.06305846 548.745271893 240 540 240 c 0
546 198 551 213 551 225 c 0
551 233 549 240 540 240 c 0
514 240 491 175 454 100 c 0
423 37 388 -10 323 -10 c 0
295.96461562 -10 276.685848474 4.31990873934 276.685848474 30.6552962356 c 0
276.685848474 38.4136929968 278.359032859 47.2149008096 282 57 c 2
296 -10 277 5 277 31 c 0
277 39 278 47 282 57 c 2
334 193 l 2
334.687448544 195.062345631 335.007330587 196.961328373 335.007330587 198.698285174 c 0
335.007330587 208.224115412 325.386390673 212.876768553 314.009865299 212.876768553 c 0
300.302784706 212.876768553 284.047157224 206.122608782 279 193 c 2
335 195 335 197 335 199 c 0
335 209 325 213 314 213 c 0
300 213 284 206 279 193 c 2
214 22 l 2
211 14 207 0 191 -1 c 2
153 0 l 2
134 -2 132 12 136 22 c 2
203 193 l 2
203.698722351 195.018531237 204.023750859 196.886379473 204.023750859 198.6021409 c 0
204.023750859 208.040661137 194.187819777 212.876768553 182.617370253 212.876768553 c 0
169.199127766 212.876768553 153.448127054 206.372675496 148 193 c 2
204 195 204 197 204 199 c 0
204 208 195 213 183 213 c 0
170 213 153 206 148 193 c 2
80 21 l 2
76 11 74 1 57 0 c 2
4 0 l 2
-6 0 0 18 4 26 c 2
70 193 l 2
77 211 69 221 60 221 c 0
42 221 35 210 -11 138 c 0
-18 127 -39 139 -33 151 c 0
3 216 36 280 86 280 c 0
128 280 145 266 152 240 c 1
170 260 194 280 224 280 c 0
254 280 273 263 278 240 c 1
292 259 322 280 349 280 c 0
382.297060451 280 409.658220776 253.618221661 409.658220776 218.530504648 c 0
409.658220776 210.41331474 408.193901764 201.830198995 405 193 c 2
382 280 410 254 410 219 c 0
410 211 408 202 405 193 c 2
358 68 l 2
355.211869734 60.3326417674 353.881302664 53.2726015335 353.881302664 47.6241881024 c 0
353.881302664 39.5840041338 356.577277218 34.4040367054 361.602949871 34.4040367054 c 0
363.177144158 34.4040367054 364.979913018 34.9122608557 367 36 c 0
355 60 354 54 354 48 c 0
354 40 357 34 362 34 c 0
364 34 365 35 367 36 c 0
389 48 418 94 429 119 c 0
628 40 m 0
630.179123831 39.0525548563 632.555731167 38.5988184777 635.0907001 38.5988184777 c 0
659.311569742 38.5988184777 697.989634802 80.0214592618 717 128 c 0
724.801273837 147.763227053 729.897664408 174.829638922 729.897664408 197.52305288 c 0
729.897664408 218.46369363 725.558131706 235.680764302 715 240 c 0
713.059714009 240.759242344 710.934395026 241.11995209 708.659464452 241.11995209 c 0
683.96754404 241.11995209 641.650235832 198.625589581 627 162 c 0
616.665333312 135.693575703 612.068143327 108.945807045 612.068143327 87.1471403297 c 0
612.068143327 62.5417301443 617.925393958 44.2419393862 628 40 c 0
630 39 632 39 635 39 c 0
659 39 698 80 717 128 c 0
725 148 730 175 730 198 c 0
730 219 726 236 715 240 c 0
713 241 711 241 709 241 c 0
684 241 642 199 627 162 c 0
617 136 612 109 612 87 c 0
612 62 618 44 628 40 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE52D
Encoding: 105 58669 105
Width: 351
|
| ︙ | | |
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
|
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
|
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
|
42 221 35 210 -11 138 c 0
-18 127 -39 139 -33 151 c 0
3 216 36 280 86 280 c 0
128 280 145 266 152 240 c 1
170 260 194 280 224 280 c 0
254 280 273 263 278 240 c 1
292 259 322 280 349 280 c 0
382.297060451 280 409.658220776 253.618221661 409.658220776 218.530504648 c 0
409.658220776 210.41331474 408.193901764 201.830198995 405 193 c 0
382 280 410 254 410 219 c 0
410 211 408 202 405 193 c 0
358 68 l 0
355.211869734 60.3326417674 353.881302664 53.2726015335 353.881302664 47.6241881024 c 0
353.881302664 39.5840041338 356.577277218 34.4040367054 361.602949871 34.4040367054 c 0
363.177144158 34.4040367054 364.979913018 34.9122608557 367 36 c 0
355 60 354 54 354 48 c 0
354 40 357 34 362 34 c 0
364 34 365 35 367 36 c 0
389 48 404 72 419 93 c 0
427 104 449 93 440 78 c 0
411 27 388 -10 323 -10 c 0
295.96461562 -10 276.685848474 4.31990873934 276.685848474 30.6552962356 c 0
276.685848474 38.4136929968 278.359032859 47.2149008096 282 57 c 0
296 -10 277 5 277 31 c 0
277 39 278 47 282 57 c 0
334 193 l 0
334.687448544 195.062345631 335.007330587 196.961328373 335.007330587 198.698285174 c 0
335.007330587 208.224115412 325.386390673 212.876768553 314.009865299 212.876768553 c 0
300.302784706 212.876768553 284.047157224 206.122608782 279 193 c 0
335 195 335 197 335 199 c 0
335 209 325 213 314 213 c 0
300 213 284 206 279 193 c 0
214 22 l 0
211 14 207 0 191 -1 c 1
153 0 l 16
134 -2 132 12 136 22 c 0
203 193 l 0
203.698722351 195.018531237 204.023750859 196.886379473 204.023750859 198.6021409 c 0
204.023750859 208.040661137 194.187819777 212.876768553 182.617370253 212.876768553 c 0
169.199127766 212.876768553 153.448127054 206.372675496 148 193 c 0
204 195 204 197 204 199 c 0
204 208 195 213 183 213 c 0
170 213 153 206 148 193 c 0
80 21 l 0
393 -160 m 0
353 -160 313 -135 313 -90 c 0
313 -55 330 -30 355 -30 c 0
380 -30 396 -45 396 -65 c 0
396 -75 389 -83 378 -90 c 0
368 -97 368 -100 368 -110 c 0
368 -120 378 -124 393 -124 c 0
456 -124 459 -35 526 230 c 1
507 230 508 230 473 230 c 0
460.239470207 230 453.992185238 240.421191718 453.992185238 250.625180963 c 0
453.992185238 260.412503619 459.73968741 270 471 270 c 0
460 230 454 241 454 251 c 0
454 261 460 270 471 270 c 0
502 270 504 270 536 270 c 1
564 374 647 440 713 440 c 0
753 440 793 415 793 370 c 0
793 335 776 310 751 310 c 0
726 310 710 325 710 345 c 0
710 355 717 363 728 370 c 0
739 377 738 380 738 390 c 0
738 400 728 404 713 404 c 0
671 404 661 332 648 270 c 1
675 270 672 270 702 270 c 0
715 270 721.5 260 721.5 250 c 0
721.5 240 715 230 702 230 c 0
715 270 722 260 722 250 c 0
722 240 715 230 702 230 c 0
676 230 672 230 639 230 c 1
596 -26 523 -160 393 -160 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE52F
|
| ︙ | | |
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
|
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
|
-
-
+
+
-
-
+
+
|
-130 -55 -113 -30 -88 -30 c 0
-63 -30 -47 -45 -47 -65 c 0
-47 -75 -54 -83 -65 -90 c 0
-75 -97 -75 -100 -75 -110 c 0
-75 -120 -65 -124 -50 -124 c 0
13 -124 16 -35 83 230 c 1
64 230 65 230 30 230 c 0
17.239470207 230 10.992185238 240.421191718 10.992185238 250.625180963 c 0
10.992185238 260.412503619 16.7396874095 270 28 270 c 0
17 230 11 241 11 251 c 0
11 261 17 270 28 270 c 0
59 270 61 270 93 270 c 1
121 374 204 440 270 440 c 0
310 440 350 415 350 370 c 0
350 335 333 310 308 310 c 0
283 310 267 325 267 345 c 0
267 355 274 363 285 370 c 0
296 377 295 380 295 390 c 0
295 400 285 404 270 404 c 0
228 404 218 333 205 271 c 1
360 270 l 1
388 374 471 440 537 440 c 0
577 440 617 415 617 370 c 0
617 335 600 310 575 310 c 0
550 310 534 325 534 345 c 0
534 355 541 363 552 370 c 0
563 377 562 380 562 390 c 0
562 400 552 404 537 404 c 0
495 404 485 332 472 270 c 1
499 270 496 270 526 270 c 0
539 270 545.5 260 545.5 250 c 0
545.5 240 539 230 526 230 c 0
539 270 546 260 546 250 c 0
546 240 539 230 526 230 c 0
500 230 496 230 463 230 c 1
420 -26 347 -160 217 -160 c 0
177 -160 137 -135 137 -90 c 0
137 -55 154 -30 179 -30 c 0
204 -30 220 -45 220 -65 c 0
220 -75 213 -83 202 -90 c 0
192 -97 192 -100 192 -110 c 0
|
| ︙ | | |
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
|
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
|
-
-
+
+
|
884 335 867 310 842 310 c 0
817 310 801 325 801 345 c 0
801 355 808 363 819 370 c 0
830 377 829 380 829 390 c 0
829 400 819 404 804 404 c 0
762 404 752 332 739 270 c 1
766 270 763 270 793 270 c 0
806 270 812.5 260 812.5 250 c 0
812.5 240 806 230 793 230 c 0
806 270 812 260 812 250 c 0
812 240 806 230 793 230 c 0
767 230 763 230 730 230 c 1
687 -26 614 -160 484 -160 c 0
444 -160 404 -135 404 -90 c 0
404 -55 421 -30 446 -30 c 0
471 -30 487 -45 487 -65 c 0
487 -75 480 -83 469 -90 c 0
459 -97 459 -100 459 -110 c 0
|
| ︙ | | |
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
|
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
|
-
-
+
+
|
-130 -55 -113 -30 -88 -30 c 0
-63 -30 -47 -45 -47 -65 c 0
-47 -75 -54 -83 -65 -90 c 0
-75 -97 -75 -100 -75 -110 c 0
-75 -120 -65 -124 -50 -124 c 0
13 -124 16 -35 83 230 c 1
64 230 65 230 30 230 c 0
17.239470207 230 10.992185238 240.421191718 10.992185238 250.625180963 c 0
10.992185238 260.412503619 16.7396874095 270 28 270 c 0
17 230 11 241 11 251 c 0
11 261 17 270 28 270 c 0
59 270 61 270 93 270 c 1
121 374 204 440 270 440 c 0
310 440 350 415 350 370 c 0
350 335 333 310 308 310 c 0
283 310 267 325 267 345 c 0
267 355 274 363 285 370 c 0
296 377 295 380 295 390 c 0
|
| ︙ | | |
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
|
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
|
-
-
+
+
|
1152 335 1135 310 1110 310 c 0
1085 310 1069 325 1069 345 c 0
1069 355 1076 363 1087 370 c 0
1098 377 1097 380 1097 390 c 0
1097 400 1087 404 1072 404 c 0
1030 404 1020 332 1007 270 c 1
1034 270 1031 270 1061 270 c 0
1074 270 1080.5 260 1080.5 250 c 0
1080.5 240 1074 230 1061 230 c 0
1074 270 1080 260 1080 250 c 0
1080 240 1074 230 1061 230 c 0
1035 230 1031 230 998 230 c 1
955 -26 882 -160 752 -160 c 0
712 -160 672 -135 672 -90 c 0
672 -55 689 -30 714 -30 c 0
739 -30 755 -45 755 -65 c 0
755 -75 748 -83 737 -90 c 0
727 -97 727 -100 727 -110 c 0
|
| ︙ | | |
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
|
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
|
-
-
+
+
|
-130 -55 -113 -30 -88 -30 c 0
-63 -30 -47 -45 -47 -65 c 0
-47 -75 -54 -83 -65 -90 c 0
-75 -97 -75 -100 -75 -110 c 0
-75 -120 -65 -124 -50 -124 c 0
13 -124 16 -35 83 230 c 1
64 230 65 230 30 230 c 0
17.239470207 230 10.992185238 240.421191718 10.992185238 250.625180963 c 0
10.992185238 260.412503619 16.7396874095 270 28 270 c 0
17 230 11 241 11 251 c 0
11 261 17 270 28 270 c 0
59 270 61 270 93 270 c 1
121 374 204 440 270 440 c 0
310 440 350 415 350 370 c 0
350 335 333 310 308 310 c 0
283 310 267 325 267 345 c 0
267 355 274 363 285 370 c 0
296 377 295 380 295 390 c 0
|
| ︙ | | |
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
|
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
|
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
|
60 34 69 30 85 30 c 0
113 30 140 45 140 70 c 0
140 100 120 107 94 124 c 0
61 145 30 167 30 200 c 0
30 247 70 280 130 280 c 0
175 280 218 253 218 220 c 0
218 199 202 180 180 180 c 0
163.575188443 180 145.315176651 194.681601887 145.315176651 213.518742217 c 0
145.315176651 218.765893239 146.732008255 224.335480975 150 230 c 1
164 180 145 195 145 214 c 0
145 219 147 224 150 230 c 1
142 240 133 250 120 250 c 0
101 250 80 239 80 220 c 0
80 193 127 175 150 160 c 0
184 137 200 120 200 90 c 0
200 26 156 0 80 0 c 0xd8
494 3 m 0
482 -6 470 16 481 26 c 0
655 217 l 0
647.065121876 221.231935 637.451249329 222.385713558 625.122178884 222.385713558 c 0
614.144520003 222.385713558 601.014276252 221.471008125 585 221 c 0
647 221 637 222 625 222 c 0
614 222 601 221 585 221 c 0
574 221 554 173 541 162 c 0
527 150 511 153 524 187 c 0
543 238 542 251 548 267 c 1
580.854598393 264.712654542 605.061346797 263.852204333 623.335584921 263.852204333 c 0
678.854023456 263.852204333 679.616120157 271.794054171 701.762784585 271.794054171 c 0
707.383128795 271.794054171 714.380713088 271.282571588 724 270 c 0
581 265 605 264 623 264 c 0
679 264 680 272 702 272 c 0
708 272 714 271 724 270 c 0
739 268 737 254 728 245 c 0
574 82 l 0
571.290722326 77.5296918374 570.067832218 74.1420610385 570.067832218 71.5487518924 c 0
570.067832218 54.9981455171 619.876699814 70.8006196048 651 44 c 0
571 78 570 75 570 72 c 0
570 55 620 71 651 44 c 0
660 36 672 52 668 64 c 0
661 84 629 65 629 100 c 0
629 115 645 130 661 130 c 0
681 130 699 117 699 75 c 0
699 35.6904170379 666.82658183 2.81551770962 623.631918047 2.81551770962 c 0
621.774432159 2.81551770962 619.896565457 2.87631094845 618 3 c 0
574.626134889 6.18925478761 553.222377354 17.5155864555 532.50873405 17.5155864555 c 0
520.748265557 17.5155864555 509.210259784 13.8644712743 494 3 c 0
699 36 667 3 624 3 c 0
622 3 620 3 618 3 c 0
575 6 554 18 533 18 c 0
521 18 509 14 494 3 c 0
182 -160 m 0
142 -160 102 -135 102 -90 c 0
102 -55 119 -30 144 -30 c 0
169 -30 185 -45 185 -65 c 0
185 -75 178 -83 167 -90 c 0
157 -97 165 -100 165 -110 c 0
165 -120 167 -124 182 -124 c 0
245 -124 248 -35 315 230 c 1
296 230 297 230 262 230 c 0
249.239470207 230 242.992185238 240.421191718 242.992185238 250.625180963 c 0
242.992185238 260.412503619 248.73968741 270 260 270 c 0
249 230 243 241 243 251 c 0
243 261 249 270 260 270 c 0
291 270 293 270 325 270 c 1
353 374 436 440 502 440 c 0
542 440 582 415 582 370 c 0
582 335 565 310 540 310 c 0
515 310 499 325 499 345 c 0
499 355 506 363 517 370 c 0
528 377 527 380 527 390 c 0
527 400 517 404 502 404 c 0
460 404 450 332 437 270 c 1
464 270 461 270 491 270 c 0
504 270 510.5 260 510.5 250 c 0
510.5 240 504 230 491 230 c 0
504 270 510 260 510 250 c 0
510 240 504 230 491 230 c 0
465 230 461 230 428 230 c 1
385 -26 312 -160 182 -160 c 0
EndSplineSet
Validated: 1
EndChar
StartChar: uniE566
|
| ︙ | | |
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
|
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
|
-
+
-
-
+
+
|
EndChar
StartChar: uniE650
Encoding: 124 58960 124
Width: 1037
Flags: W
HStem: -2 60<361.035 435.033 953.253 1010.82> 0 49<543.265 652.027> 286 36<514.943 580.797> 359 66<58.4784 125.129> 402 58<367.211 444.917> 607 32<177.106 261>
VStem: 0 57<406 505.924> 148 26<463.933 475.584> 200 67<410.241 442> 274.641 84.3586<205.588 329> 425 56<126.64 255.856> 452 64<466.983 558.522> 585 40<194.878 284.873> 675 60<72.5613 225.441> 887 59<79.8865 267.532> 952 60<-0.820206 56.8202>
VStem: 0 57<406 505.924> 148 26<463.933 475.584> 200 67<410.241 442> 275 84<205.648 329> 425 56<126.64 255.856> 452 64<466.983 558.522> 585 40<194.878 284.873> 675 60<72.5613 225.441> 887 59<79.8865 267.532> 952 60<-0.820206 56.8202>
LayerCount: 2
Fore
SplineSet
152 90 m 0x67ef
221.394397964 119.985233688 274.64143816 164.649883528 274.64143816 208.902553279 c 0
274.64143816 216.303422646 273.152138825 223.692769088 270 231 c 0
221 120 275 165 275 209 c 0
275 216 273 224 270 231 c 0
252 273 185 332 185 389 c 0
185 407 200 441 200 442 c 2
261 607 l 1
114 601 57 505 57 460 c 0x6fef
57 436 69 425 89 425 c 0
110 425 128 443 148 485 c 1
174 472 l 1
|
| ︙ | | |
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
|
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
|
-
-
+
+
|
437 460 452 482 452 510 c 0x2fdf
452 530 431 601 303 608 c 1
276 542 l 2
275 538 267 498 267 479 c 0
267 390 359 361 359 297 c 0
359 211 296 140 296 140 c 1
334 114 366 63 394 63 c 0
399 63 402.9375 62.625 406.671875 62.625 c 0
417.875 62.625 427.25 66 458 93 c 1
399 63 403 63 407 63 c 0
418 63 427 66 458 93 c 1
438 125 425 152 425 186 c 27
425 226 431 247 453 276 c 0
479 311 522 322 563 322 c 0
599 322 625 289 625 247 c 3
625 233 625 214 615 195 c 0
591 148 551 110 526 90 c 1
550 61 566 49 604 49 c 0x6fef
|
| ︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// abc2svg - grid.js - module to insert a chord grid before or after a tune
//
// Copyright (C) 2018-2021 Jean-Francois Moine
// Copyright (C) 2018-2022 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
-
+
|
var abc = this,
img, cls,
cfmt = abc.cfmt(),
grid = cfmt.grid
// generate the grid
function build_grid(s, font) {
var i, k, l, nr, bar, w, hr, x0, x, y, yl, ps,
var i, k, l, nr, bar, w, hr, x0, x, y, yl, ps, d,
lc = '',
chords = s.chords,
bars = s.bars,
parts = s.parts || [],
wmx = s.wmx,
cells = [],
nc = grid.n
|
| ︙ | | |
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
}
}
} else {
abc.set_font('grid')
abc.xy_str(x, y, cell[0])
}
} // build_cell()
// draw the horizontal lines
function draw_hl() {
var i, i1, j, x,
y = -1
for (i = 0; i <= nr + 1; i++) {
j = 0
i1 = i > 0 ? i - 1 : 0
while (1) {
while (j <= nc && !d[i1][j])
j++
if (j > nc)
break
x = wmx * j
while (j <= nc && d[i1][j])
j++
if (i && i1 < nr) {
while (j <= nc && d[i1 + 1][j])
j++
}
abc.out_svg('M')
abc.out_sxsy(x0 + x, ' ', y)
abc.out_svg('h' + (wmx * j - x).toFixed(1)+ '\n')
}
y -= hr
}
} // draw_hl()
// draw the vertical lines
function draw_vl() {
var i, i1, j, y,
x = x0
for (i = 0; i <= nc; i++) {
j = 0
i1 = i > 0 ? i - 1 : 0
while (1) {
while (j <= nr && !d[j][i1])
j++
if (j > nr)
break
y = hr * j
while (j <= nr && d[j][i1])
j++
abc.out_svg('M')
abc.out_sxsy(x, ' ', -y - .5)
abc.out_svg('v' + (hr * j - y + 1).toFixed(1) + '\n')
}
x += wmx
}
} // draw_vl()
// ------- build_grid() -------
// set some chords in each cell
set_chords()
// build the content of the cells
|
| ︙ | | |
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
-
+
+
+
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
-
|
nc /= 2;
w /= 2
}
// generate the cells
yl = -1
y = -1 + font.size * .6
nr = 0
nr = -1
x0 = (x0 / cfmt.scale - w) / 2
d = []
for (i = 0; i < cells.length; i++) {
if (i == 0
|| (grid.repbrk
&& (bars[i].slice(-1) == ':' || bars[i][0] == ':'))
|| parts[i]
|| k >= nc) {
y -= hr // new row
yl -= hr
x = x0 + wmx / 2
k = 0
nr++
d[nr] = []
}
d[nr][k] = 1
k++
build_cell(cells[i], x, y, yl, hr)
x += wmx
}
// draw the lines
abc.out_svg('<path class="stroke" stroke-width="1" d="\n')
y = -1
for (i = 0; i <= nr; i++) {
abc.out_svg('M')
abc.out_sxsy(x0, ' ', y)
abc.out_svg('h' + w.toFixed(1)+ '\n')
y -= hr
draw_hl()
}
x = x0
for (i = 0; i <= nc; i++) {
abc.out_svg('M')
abc.out_sxsy(x, ' ', -1)
abc.out_svg('v' + (hr * nr).toFixed(1) + '\n')
x += wmx
draw_vl()
}
abc.out_svg('"/>\n')
// show the repeat signs and the parts
y = -1 + font.size * .7
x = x0
for (i = 0; i < bars.length; i++) {
bar = bars[i]
|
| ︙ | | |
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
-
+
-
-
|
abc.out_svg('<text class="' + cls + '" x="')
abc.out_sxsy(x + 5, '" y="', y)
abc.out_svg('" style="font-weight:bold;font-size:' +
(font.size * 1.5).toFixed(1) + 'px">:</text>\n')
}
x += wmx
}
abc.vskip(hr * nr + 6)
abc.vskip(hr * (nr + 1) + 6)
} // build_grid()
// ----- block_gen() -----
var p_voice, n, font, f2
img = abc.get_img()
// set the text style
if (!cfmt.gridfont)
abc.param_set_font("gridfont", "serif 16")
font = abc.get_font('grid')
if (font.class)
font.class += ' mid'
else
font.class = 'mid'
cls = abc.font_class(font)
|
| ︙ | | |
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
|
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
}, // block_gen()
set_stems: function(of) {
var C = abc2svg.C,
abc = this,
tsfirst = abc.get_tsfirst(),
voice_tb = abc.get_voice_tb(),
grid = abc.cfmt().grid
cfmt = abc.cfmt(),
grid = cfmt.grid
// extract one of the chord symbols
// With chords as "[yyy];xxx"
// (!sel - default) returns "yyy" and (sel) returns "xxx"
function cs_filter(a_cs) {
var i, cs, t
for (i = 0; i < a_cs.length; i++) {
cs = a_cs[i]
if (cs.type != 'g')
continue
t = cs.text
if (cfmt.altchord) {
for (i++; i < a_cs.length; i++) {
cs = a_cs[i]
if (cs.type != 'g')
continue
t = cs.text
break
}
}
return t.replace(/\[|\]/g, '')
}
} // cs_filter()
function get_beat(s) {
var beat = C.BLEN / 4
if (!s.a_meter[0] || s.a_meter[0].top[0] == 'C'
|| !s.a_meter[0].bot)
return beat
|
| ︙ | | |
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
|
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
|
if (s.part)
parts[chords.length] = s.part.text
switch (s.type) {
case C.NOTE:
case C.REST:
if (!s.a_gch || chord[beat_i])
break
bt = abc2svg.cs_filter(s.a_gch,
bt = cs_filter(s.a_gch)
abc.cfmt().altchord)
if (!bt)
break
chord[beat_i] = bt
for (i = 0; i < s.a_gch.length; i++) {
if (s.a_gch[i].type == 'g')
break
}
abc.set_font(s.a_gch[i].font)
w = abc.strwh(bt)[0]
if (w > wmx)
wmx = w
w = abc.strwh(bt.replace(
/<[^>]+>/gm,''))
if (w[0] > wmx)
wmx = w[0]
bt = new String(bt)
bt.wh = w
chord[beat_i] = bt
break
case C.BAR:
i = s.bar_num // check if normal measure bar
bt = s.bar_type
while (s.ts_next && s.ts_next.time == s.time) {
if (s.ts_next.dur)
break
|
| ︙ | | |
437
438
439
440
441
442
443
444
445
446
447
448
449
450
|
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
|
+
+
+
|
dur: 0,
time: 0,
p_v: p_v,
v: p_v.v,
st: p_v.st
}
if (!cfmt.gridfont)
abc.param_set_font("gridfont", "serif 16")
abc.set_font('grid')
build_chords(s) // build the array of the chords
// and insert it in the tune
if (!s.chords) { // if no chord
;
} else if (grid.nomusic) { // if just the grid
this.set_tsfirst(s)
|
| ︙ | | |
1
2
3
4
5
6
7
8
9
10
|
1
2
3
4
5
6
7
8
9
10
|
-
+
|
// jianpu.js - module to output jiănpŭ (简谱) music sheets
//
// Copyright (C) 2020-2022 Jean-Francois Moine
// Copyright (C) 2020-2023 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
|
| ︙ | | |
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
+
-
+
|
cgd2cde: new Int8Array([0, -4, -1, -5, -2, -6, -3,
0, -4, -1, -5, -2, -6, -3, 0]),
acc2: new Int8Array([-2, -1, 3, 1, 2]),
acc_tb: ["\ue264", "\ue260", , "\ue262", "\ue263", "\ue261"],
// don't calculate the beams
calc_beam: function(of, bm, s1) {
if (!this.cfmt().jianpu)
if (!s1.p_v.jianpu)
return of(bm, s1)
// return 0
}, // calc_beam()
// change %%staves and %%score
do_pscom: function(of, p) {
if (this.cfmt().jianpu)
switch (p.match(/\w+/)[0]) {
case 'staves':
case 'score':
p = p.replace(/\(|\)/g, '')
break
}
of(p)
},
// adjust some symbols before the generation
output_music: function(of) {
var p_v, v,
var C = abc2svg.C,
C = abc2svg.C,
abc = this,
cur_sy = abc.get_cur_sy(),
voice_tb = abc.get_voice_tb()
// handle the overlay voices
function ov_def(v) {
var s1, tim,
s = p_v.sym
if (!abc.cfmt().jianpu) {
of()
return
}
while (s) {
s1 = s.ts_prev
if (!s.invis
&& s.dur
&& s1.v != v
&& s1.st == s.st // overlay start
&& s1.time == s.time) {
while (1) { // go back to the previous bar
if (!s1.prev
|| s1.prev.bar_type)
break
s1 = s1.prev
}
//add deco '{' on s1
while (!s1.bar_type) {
s1.dy = 14
s1.notes[0].pit = 30
s1 = s1.next
}
// add deco '}' on s1
while (1) {
s.dy = -14
s.notes[0].pit = 20
if (!s.next
|| s.next.bar_type
|| s.next.time >= s1.time)
break
s = s.next
}
}
s = s.next
}
} // ov_def()
// output the key and time signatures
function set_head() {
var v, p_v, mt, s2, sk, s,
var tsfirst = abc.get_tsfirst(),
p_v = voice_tb[0],
mt = p_v.meter.a_meter[0],
sk = p_v.key,
s2 = voice_tb[0].sym,
tsfirst = abc.get_tsfirst()
// search a jianpu voice
for (v = 0; v < voice_tb.length; v++) {
p_v = voice_tb[v]
if (p_v.jianpu)
break
}
if (v >= voice_tb.length)
return
mt = p_v.meter.a_meter[0]
sk = p_v.key
s2 = p_v.sym
s = {
type: C.BLOCK,
subtype: "text",
time: s2.time,
dur: 0,
v: 0,
p_v: p_v,
st: 0,
fmt: s2.fmt,
seqst: true,
text: (sk.k_mode + 1) + "=" +
(abc2svg.jianpu.k_tb[sk.k_sf + 7 +
abc2svg.jianpu.cde2fcg[sk.k_mode]]),
font: abc.get_font("text")
}
if (mt)
s.text += ' ' + (mt.bot ? (mt.top + '/' + mt.bot) : mt.top)
// insert the block after the first %%staves
s2 = tsfirst
s.next = s2.next
if (s.next)
s.next.prev = s
s2.prev = s
s.next = s2
voice_tb[0].sym = s
tsfirst.ts_prev = s
s.ts_next = tsfirst
s.prev = s2
s2.next = s
s.ts_next = s2.ts_next
s.ts_next.ts_prev = s
s.ts_prev = s2
s2.ts_next = s
abc.set_tsfirst(s)
} // set head()
// expand a long note/rest
function slice(s) {
var n, s2, s3
var n, s2, s3,
jn = s.type == C.REST ? 0 : 8 // '0' or '-'
if (s.dur >= C.BLEN)
n = 3
else if (s.dur == C.BLEN / 2)
n = 1
else
n = 2
s.notes[0].dur =
s.dur = s.dur_orig = C.BLEN / 4
delete s.fmr
while (--n >= 0) {
s2 = {
type: C.REST,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: C.BLEN / 4,
dur_orig: C.BLEN / 4,
fmt: s.fmt,
stem: 0,
multi: 0,
nhd: 0,
notes: [{
dur: s.dur,
pit: s.notes[0].pit,
jn: 8
jn: jn
}],
xmx: 0,
noplay: true,
time: s.time + C.BLEN / 4,
prev: s,
next: s.next
}
|
| ︙ | | |
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
|
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
-
+
-
+
-
+
-
+
+
+
-
-
+
-
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
+
-
-
+
+
-
+
|
break
}
}
s = s2
}
} // slice()
function set_note(s, sf) {
var i, m, note, p, pit, a, nn,
delta = abc2svg.jianpu.cgd2cde[sf + 7] - 2
s.stem = -1
s.stemless = true
if (s.sls) {
for (i = 0; i < s.sls.length; i++)
s.sls[i].ty = C.SL_ABOVE
}
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m]
// note head
p = note.pit
pit = p + delta
note.jn = ((pit + 77) % 7) + 1 // note number
// set a fixed offset to the note for the decorations
note.pit = 25 // "e"
note.jo = (pit / 7) | 0 // octave number
// accidentals
a = note.acc
if (a) {
nn = abc2svg.jianpu.cde2fcg[(p + 5 + 16 * 7) % 7] - sf
if (a != 3)
nn += a * 7
nn = ((((nn + 1 + 21) / 7) | 0) + 2 - 3 + 32 * 5) % 5
note.acc = abc2svg.jianpu.acc2[nn]
}
// set the slurs and ties up
if (note.sls) {
for (i = 0; i < note.sls.length; i++)
note.sls[i].ty = C.SL_ABOVE
}
if (note.tie_ty)
note.tie_ty = C.SL_ABOVE
}
// change the long notes
if (s.dur >= C.BLEN / 2
&& !s.invis)
slice(s)
// replace the staccato dot
if (s.a_dd) {
for (i = 0; i < s.a_dd.length; i++) {
if (s.a_dd[i].glyph == "stc") {
abc.deco_put("gstc", s)
s.a_dd[i] = s.a_dd.pop()
}
}
}
} // set_note()
function set_sym(p_v) {
var s, s2, note, pit, nn, p, a, m, i,
sf = p_v.key.k_sf,
var s, g,
sf = p_v.key.k_sf
delta = abc2svg.jianpu.cgd2cde[sf + 7] - 2
p_v.key.k_a_acc = [] // no accidental
delete p_v.key.k_a_acc // no accidental
// no (visible) clef
s = p_v.clef
s.invis = true
s.clef_type = 't'
s.clef_line = 2
// scan the voice
for (s = p_v.sym; s; s = s.next) {
s.st = p_v.st
switch (s.type) {
case C.CLEF:
s.invis = true
s.clef_type = 't'
s.clef_line = 2
// continue
default:
continue
case C.KEY:
delta = abc2svg.jianpu.cgd2cde[s.k_sf + 7] - 2
sf = s.k_sf
s.a_gch = [{
type: '@',
font: abc.get_font("annotation"),
wh: [10, 10],
x: -5,
y: 30,
y: 26,
text: (s.k_mode + 1) + "=" +
(abc2svg.jianpu.k_tb[s.k_sf + 7 +
(abc2svg.jianpu.k_tb[sf + 7 +
abc2svg.jianpu.cde2fcg[s.k_mode]])
}]
continue
case C.REST:
if (s.notes[0].jn)
continue
s.notes[0].jn = 0
if (s.dur >= C.BLEN / 2)
if (s.dur >= C.BLEN / 2
&& !s.invis)
slice(s)
continue
case C.NOTE: // change the notes
set_note(s, sf)
break
}
case C.GRACE:
s.stem = -1
s.stemless = true
for (g = s.extra; g; g = g.next)
if (s.sls) {
for (i = 0; i < s.sls.length; i++)
s.sls[i].ty = C.SL_ABOVE
}
set_note(g, sf)
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m]
break
// note head
p = note.pit
pit = p + delta
note.jn = ((pit + 77) % 7) + 1 // note number
// set a fixed offset to the note for the decorations
note.pit = 25 // "e"
note.jo = (pit / 7) | 0 // octave number
// accidentals
a = note.acc
if (a) {
nn = abc2svg.jianpu.cde2fcg[(p + 5 + 16 * 7) % 7] - sf
if (a != 3)
nn += a * 7
nn = ((((nn + 1 + 21) / 7) | 0) + 2 - 3 + 32 * 5) % 5
note.acc = abc2svg.jianpu.acc2[nn]
}
// set the slurs and ties up
if (note.sls) {
for (i = 0; i < note.sls.length; i++)
note.sls[i].ty = C.SL_ABOVE
}
if (note.tie_ty)
note.tie_ty = C.SL_ABOVE
}
// change the long notes
if (s.dur >= C.BLEN / 2)
slice(s)
// replace the staccato dot
if (s.a_dd) {
for (i = 0; i < s.a_dd.length; i++) {
if (s.a_dd[i].glyph == "stc") {
abc.deco_put("gstc", s)
s.a_dd[i] = s.a_dd.pop()
}
}
}
}
} // set_sym()
// -- output_music --
set_head()
for (v = 0; v < voice_tb.length; v++)
set_sym(voice_tb[v])
for (v = 0; v < voice_tb.length; v++) {
p_v = voice_tb[v]
if (p_v.jianpu) {
set_sym(p_v)
if (v > 0 && voice_tb[v - 1].st == p_v.st)
ov_def(v)
}
}
of()
}, // output_music()
draw_symbols: function(of, p_voice) {
var i, m, nl, note, s, s2, x, y,
var s, s2, nl, y,
C = abc2svg.C,
abc = this,
dot = "\ue1e7",
staff_tb = abc.get_staff_tb(),
out_svg = abc.out_svg,
out_sxsy = abc.out_sxsy,
xypath = abc.xypath
if (!abc.cfmt().jianpu) {
if (!p_voice.jianpu) {
of(p_voice)
return
}
// draw the duration lines under the notes
function draw_dur(s1, y, s2, n, nl) {
var s, s3
function draw_dur(s1, x, y, s2, n, nl) {
var s, s3,
sc = s1.grace ? .5 : 1
xypath(s1.x - 3, y + 5)
out_svg('h' + (s2.x - s1.x + 8).toFixed(1) + '"/>\n') // "
xypath(x - 3, y + 5)
out_svg('h' + ((s2.x - s1.x) / sc + 8).toFixed(1) + '"/>\n') // "
y -= 2.5
while (++n <= nl) {
s = s1
while (1) {
if (s.nflags && s.nflags >= n) {
s3 = s
while (s != s2) {
if (s.next.beam_br1
|| (s.next.beam_br2 && n > 2)
|| (s.next.nflags
&& s.next.nflags < n))
break
s = s.next
}
draw_dur(s3, y, s, n, nl)
draw_dur(s3, s3.x, y, s, n, nl)
}
if (s == s2)
break
s = s.next
}
}
} // draw_dur()
|
| ︙ | | |
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
|
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
|
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
|
out_mus(x - 1, ym, dot)
}
}
y += 20
}
} // draw_hd()
function draw_note(s) {
var sc = 1,
x = s.x,
y = staff_tb[s.st].y
// -- draw_symbols --
if (s.dy)
y += s.dy // voice overlay
if (s.grace) {
out_svg('<g transform="translate(')
out_sxsy(x, ',', y + 15) // (font height)
out_svg(') scale(.5)">\n')
abc.stv_g().g++ // in container
x = 0
y = 0
sc = .5
}
draw_hd(s, x, y)
if (s.nflags >= 0 && s.dots)
out_mus(x + 8 * sc, y + 13 * sc, dot)
if (s.grace) {
out_svg('</g>\n')
abc.stv_g().g--
}
} // draw_note()
// -- draw_symbols --
for (s = p_voice.sym; s; s = s.next) {
if (s.invis)
continue
switch (s.type) {
case C.METER:
abc.draw_meter(s)
break
case C.NOTE:
case C.REST:
x = s.x
y = staff_tb[s.st].y
draw_hd(s, x, y)
if (s.nflags >= 0 && s.dots)
draw_note(s)
break
case C.GRACE:
for (g = s.extra; g; g = g.next)
draw_note(g)
break
}
}
out_mus(x + 8, y + 13, dot)
if (s.nflags > 0) {
if (s.time == p_voice.sym.time)
s.beam_st = 1 // beam continuation
//fixme: ko with rests because no beam_st /_end
if (s.beam_st || s.type == C.REST) {
nl = s.nflags
s2 = s
while (1) {
if (s2.nflags && s2.nflags > nl)
nl = s2.nflags
if (s2.beam_end)
break
// draw the (pseudo) beams
for (s = p_voice.sym; s; s = s.next) {
if (s.invis)
continue
switch (s.type) {
case C.NOTE:
case C.REST:
nl = s.nflags
if (nl <= 0)
continue
y = staff_tb[s.st].y
s2 = s
while (s.next && s.next.nflags > 0) {
s = s.next
if (s.nflags > nl)
nl = s.nflags
if (s.beam_end)
break
if (!s2.next
|| !s2.next.nflags
|| s2.next.nflags <= 0)
break
s2 = s2.next
}
draw_dur(s, y, s2, 1, nl)
}
if (s.dy)
y += s.dy
draw_dur(s2, s2.x, y, s, 1, nl)
}
}
break
}
}
}, // draw_symbols()
// set some parameters
set_fmt: function(of, cmd, param) {
if (cmd == "jianpu") {
var cfmt = this.cfmt()
if (!this.get_bool(param))
return
cfmt.jianpu = true
cfmt.staffsep = 20
cfmt.sysstaffsep = 14
this.set_v_param("stafflines", "...")
this.set_v_param("jianpu", param)
cfmt.tuplets = [0, 1, 0, 1] // [auto, slur, number, above]
return
}
of(cmd, param)
}, // set_fmt()
// adjust some values
set_pitch: function(of, last_s) {
of(last_s)
if (!last_s
if (!last_s)
|| !this.cfmt().jianpu)
return // first time
var C = abc2svg.C
for (var s = this.get_tsfirst(); s; s = s.ts_next) {
if (!s.p_v.jianpu)
continue
switch (s.type) {
// draw the key signature only in the first voice
// and not at start of the staff
case C.KEY:
if (s.prev.type == C.CLEF
|| s.v != 0)
s.a_gch = null
break
// adjust the vertical spacing above the note heads
case C.NOTE:
s.ymx = 20 * s.nhd + 22
if (s.notes[s.nhd].jo > 2) {
s.ymx += 3
if (s.notes[s.nhd].jo > 3)
s.ymx += 2
}
s.ymn = 0 // bottom of line
break
}
}
}, // set_pitch()
set_vp: function(of, a) {
var i,
p_v = this.get_curvoice()
for (i = 0; i < a.length; i++) {
if (a[i] == "jianpu=") {
p_v.jianpu = this.get_bool(a[++i])
if (p_v.jianpu)
this.set_vp([
"staffsep=", "20",
"sysstaffsep=", "14",
"stafflines=", "...",
"tuplets=", "0 1 0 1"
// [auto, slur, number, above]
])
break
}
}
of(a)
}, // set_vp()
// set the width of some symbols
set_width: function(of, s) {
of(s)
if (!s.p_v // (if voice_tb[v].clef/key/meter)
if (!this.cfmt().jianpu)
|| !s.p_v.jianpu)
return
var w, m, note,
C = abc2svg.C
switch (s.type) {
case C.CLEF:
case C.KEY:
// case C.METER:
s.wl = s.wr = 0
s.wl = s.wr = .1 // (must not be null)
break
case C.NOTE:
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m]
if (note.acc && s.wl < 14) // room for the accidental
s.wl = 14
}
break
}
}, // set_width()
set_hooks: function(abc) {
abc.calculate_beam = abc2svg.jianpu.calc_beam.bind(abc, abc.calculate_beam)
abc.do_pscom = abc2svg.jianpu.do_pscom.bind(abc, abc.do_pscom)
abc.draw_symbols = abc2svg.jianpu.draw_symbols.bind(abc, abc.draw_symbols)
abc.output_music = abc2svg.jianpu.output_music.bind(abc, abc.output_music)
abc.set_format = abc2svg.jianpu.set_fmt.bind(abc, abc.set_format)
abc.set_pitch = abc2svg.jianpu.set_pitch.bind(abc, abc.set_pitch)
abc.set_vp = abc2svg.jianpu.set_vp.bind(abc, abc.set_vp)
abc.set_width = abc2svg.jianpu.set_width.bind(abc, abc.set_width)
// big staccato dot
abc.get_glyphs().gstc = '<circle id="gstc" cx="0" cy="-3" r="2"/>'
abc.get_decos().gstc = "0 gstc 5 1 1"
abc.add_style("\n.fj{font:15px sans-serif}")
|
| ︙ | | |
| ︙ | | |
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
+
-
-
+
-
-
-
+
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
|
// Syntax:
// %%strtab <string list> [diafret]
// <string list> is the list of the strings as ABC notes
// diafret indicates the instrument has diatonic frets
// The fret may be forced by a decoration format
// "!" digit "s!"
// where 'digit' is the string range in the string list (last string is '1')
//
// The command %%minfret permits to force upper frets.
// Syntax:
// %%minfret [ <string number> : <fret number> ]*
// Each command replaces the previous value.
//
// This module accepts Willem Vree's tablature syntax:
// https://wim.vree.org/svgParse/abc2xml.html#tab
abc2svg.strtab = {
// draw the tablature
draw_symbols: function(of, p_v) {
var s, m, not, stb, x, y,
var s, m, not, stb, x, y, g,
C = abc2svg.C,
abc = this
// draw the note heads
function draw_heads(stb, s) {
var m, not, x, y
for (m = 0; m <= s.nhd; m++) {
not = s.notes[m]
if (not.nb < 0)
continue
x = s.x - 3
if (not.nb >= 10)
x -= 3
y = 3 * (not.pit - 18)
abc.out_svg('<text class="bg' + abc.bgn +
'" x="')
abc.out_sxsy(x, '" y="', stb + y - 2.5)
abc.out_svg('">' + not.nb + '</text>\n')
}
} // draw_heads()
// draw the stems, flags and beams
function draw_stems(stb, s) {
if (!s.tabst)
return // don't draw any stem
var s1, s2, nfl, l,
y = stb + 3 * (s.notes[0].pit - 19) // -18) - 3
* s.p_v.staffscale,
h = (11 + 3 * (s.notes[0].pit - 18)) * s.p_v.staffscale
abc.out_svg('<path class="sW" d="M')
abc.out_sxsy(s.x, ' ', y)
abc.out_svg('v' + h.toFixed(1) +'"/>\n')
// draw the flag(s)
if (s.nflags <= 0
|| !s.beam_end) // inside beam
return
y -= h
if (s.beam_st) { // no beam
abc.out_svg('<text class="f'
+ abc.get_font('music').fid
+ '" transform="translate(')
abc.out_sxsy(s.x, ',', y)
abc.out_svg(') scale('
+ (s.grace ? '.5,.5' : '.7,.7') + ')">'
+ String.fromCharCode(0xe23f + 2 * s.nflags)
+ '</text>\n')
return
}
// draw the beam(s)
s2 = s
nfl = s.nflags
while (1) {
if (s.nflags > nfl)
nfl = s.nflags
if (s.beam_st)
break
s = s.prev
}
s1 = s
l = (s2.x - s1.x).toFixed(1)
abc.out_svg('<path d="M')
abc.out_sxsy(s1.x, ' ', y)
abc.out_svg('h' + l
+ 'v-3h-' + l
+ 'v3"/>\n')
if (nfl == 1)
return
//fixme: do more levels
y += 5
while (1) {
while (s.nflags < 2) {
s = s.next
if (s == s2)
break
}
if (s == s2)
break
s1 = s
while (s.next.nflags >= 2) {
s = s.next
if (s == s2)
break
}
l = (s.x - s1.x).toFixed(1)
abc.out_svg('<path d="M')
abc.out_sxsy(s1.x, ' ', y)
abc.out_svg('h' + l
+ 'v-3h-' + l
+ 'v3"/>\n')
if (s == s2)
break
s = s.next
if (s == s2)
break
}
} // draw_stems()
if (!p_v.tab) {
of(p_v)
return
}
// define the 'bgx' filter if not done yet
m = abc.cfmt().bgcolor || "white"
if (abc.bgt != m) {
if (!abc.bgn)
abc.bgn = 1
else
abc.bgn++
abc.bgt = m
abc.defs_add('\
<filter x="-0.1" y="0.2" width="1.2" height=".8" id="bg' + abc.bgn + '">\n\
<filter x="-0.1" y="0.1" width="1.2" height=".8" id="bg' + abc.bgn + '">\n\
<feFlood flood-color="' + m + '"/>\n\
<feComposite in="SourceGraphic" operator="over"/>\n\
</filter>')
abc.add_style('\n.bg' + abc.bgn + '{filter:url(#bg' + abc.bgn + ')}')
}
// adjust the symbol before generation
for (s = p_v.sym; s; s = s.next) {
switch (s.type) {
case C.KEY:
case C.METER:
case C.REST:
s.invis = true
break
case C.NOTE:
if (!s.stemless)
s.ys = -10
break
}
}
of(p_v)
abc.glout() // output the stems
// draw the note heads
stb = abc.get_staff_tb()[p_v.st].y
abc.out_svg('<g class="bn">\n')
// draw the stems and beams
abc.set_sscale(-1) // no scale
for (s = p_v.sym; s; s = s.next) {
if (s.type == C.NOTE) {
for (m = 0; m <= s.nhd; m++) {
not = s.notes[m]
switch (s.type) {
case C.GRACE:
for (g = s.extra; g; g = g.next)
draw_stems(stb, g)
if (not.nb < 0)
continue
break
x = s.x - 3
if (not.nb >= 10)
x -= 3
case C.NOTE:
y = 3 * (not.pit - 18)
abc.out_svg('<text class="bg' + abc.bgn +
'" x="')
abc.out_sxsy(x, '" y="', stb + y - 2.5)
draw_stems(stb, s)
abc.out_svg('">' + not.nb + '</text>\n')
}
break
}
}
// draw the note heads
abc.set_scale(p_v.sym) // (for draw_all_ties)
abc.out_svg('<g class="bn">\n')
for (s = p_v.sym; s; s = s.next) {
switch (s.type) {
case C.GRACE:
for (g = s.extra; g; g = g.next)
draw_heads(stb, g)
break
case C.NOTE:
draw_heads(stb, s)
break
}
}
abc.out_svg('</g>\n')
}, // draw_symbols()
// set a format parameter
set_fmt: function(of, cmd, parm) {
if (cmd == "strtab") {
if (!parm)
return
var p_v = this.get_curvoice()
if (!p_v) {
this.parse.tab = parm
return
}
this.set_v_param("clef", "tab")
if (parm.indexOf("diafret") >= 0) {
this.set_v_param("diafret", true)
parm = parm.replace(/\s*diafret\s*/, "")
}
this.set_v_param("strings", parm)
return
}
if (cmd == "minfret") {
this.set_v_param("minfret", parm)
return
}
of(cmd, parm)
}, // set_fmt()
// adjust the horizontal offset of the stems
set_width: function(of, s) {
var m, not,
abc = this,
C = abc2svg.C,
o = s.stem < 0 ? 3.5 : -2.5
of(s)
if (s.p_v && s.p_v.tab && s.type == C.NOTE && !s.stemless) {
for (m = 0; m <= s.nhd; m++)
s.notes[m].shhd = o
}
}, // set_width()
// change the notes when the global generation settings are done
set_stems: function(of) {
var p_v, i, m, nt, n, bi, bn, strss,
var p_v, i, m, nt, n, bi, bn, strss, g,
C = abc2svg.C,
abc = this,
s = abc.get_tsfirst(), // first symbol
strs = [], // notes per staff - index = staff
lstr = [] // lowest string per staff - index staff
// set a string (pitch) and a fret number
|
| ︙ | | |
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
|
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
-
-
+
-
-
-
+
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
|
nt.pit = i * 2 + 18
} else {
nt.nb = -1
nt.pit = 18
}
nt.acc = 0
nt.invis = true
if (!s.grace)
strss[i] = s.time + s.dur
if (s.nflags >= -1 && !s.stemless) {
strss[i] = s.time + s.dur
if (s.dur <= C.BLEN / 2 && !s.stemless) {
if (!lstr[st])
lstr[st] = [ 10 ]
if (lstr[st][0] > i) {
lstr[st][0] = i
lstr[st][1] = s
}
s.stemless = true
}
} // set_pit()
function set_notes(p_v, s) {
var i, bi, bn, nt, m, n, ns
s.stem = -1 // down stems
// handle the fret numbers as chord decoration
if (!s.nhd && s.a_dd) {
i = s.a_dd.length
while (--i >= 0) {
bi = strnum(s.a_dd[i].name)
if (bi >= 0) {
nt = s.notes[0]
set_pit(p_v, s, nt, bi)
break
}
}
}
delete s.a_dd
if (s.sls) { // set the slurs above the staff
for (i = 0; i < s.sls.length; i++) {
s.sls[i].ty &= ~0x07
s.sls[i].ty |= C.SL_ABOVE
}
}
ls: for (m = 0; m <= s.nhd; m++) {
nt = s.notes[m]
if (nt.sls) { // if start of slur
for (i = 0; i < nt.sls.length; i++) {
nt.sls[i].ty &= ~0x07
nt.sls[i].ty |= C.SL_ABOVE
}
}
if (nt.nb != undefined)
continue
if (nt.a_dd) {
i = nt.a_dd.length
while (--i >= 0) {
bi = strnum(nt.a_dd[i].name)
if (bi >= 0) {
set_pit(p_v, s, nt, bi)
delete nt.a_dd
continue ls
}
}
delete nt.a_dd
}
// search the best string
bn = 100
bi = -1
ns = i = p_v.tab.length
while (--i >= 0) {
if (strss[i] && strss[i] > s.time)
continue
n = (p_v.diafret ?
nt.pit : nt.midi) -
p_v.tab[i]
if (n >= 0 && n < bn
&& (!p_v.minfret
|| !p_v.minfret[ns - i]
|| n >= p_v.minfret[ns - i])) {
bi = i
bn = n
}
}
set_pit(p_v, s, nt, bi)
}
s.y = 3 * (nt.pit - 18)
s.ymn = 0 // don't get space below the tablature
} // set_notes()
// get the string number from the decoration
// format is either !<n>s! or !<n>!
function strnum(n) {
n = n.match(/^([1-9])s?$/)
return n ? p_v.tab.length - n[1] : -1
} // strnum()
// change the notes of the strings when a capo
p_v = abc.get_voice_tb()
for (n = 0; n < p_v.length; n++) {
if (!p_v[n].tab)
continue
m = p_v[n].capo
if (m) {
for (i = 0; i < p_v[n].tab.length; i++)
p_v[n].tab[i] += m
}
}
of() // do the normal work
// loop on the notes of the voices with a tablature
for ( ; s; s = s.ts_next) {
// let a stem on the lowest string
if (s.seqst || (s.ts_prev && s.ts_prev.type == C.GRACE)) {
for (i = 0; i < lstr.length; i++) {
if (lstr[i]) {
lstr[i][1].tabst = 1
lstr[i] = null
}
}
}
p_v = s.p_v
if (!p_v.tab)
continue
strss = strs[s.st]
if (!strss)
strss = strs[s.st] = []
switch (s.type) {
case C.KEY:
case C.REST:
case C.TIME:
s.invis = true
default:
delete s.a_dd
continue
case C.NOTE:
case C.GRACE:
break
}
if (p_v.pos.gst == C.SL_HIDDEN)
s.stem = -1 // down stems
s.sappo = 0
// handle the fret numbers as chord decoration
if (!s.nhd && s.a_dd) {
i = s.a_dd.length
for (g = s.extra; g; g = g.next) {
while (--i >= 0) {
bi = strnum(s.a_dd[i].name)
if (bi >= 0) {
nt = s.notes[0]
set_pit(p_v, s, nt, bi)
if (p_v.pos.gst == C.SL_HIDDEN)
g.stemless = true
set_notes(p_v, g)
break
}
}
}
delete s.a_dd
}
break
ls: for (m = 0; m <= s.nhd; m++) {
nt = s.notes[m]
if (nt.nb != undefined)
continue
if (nt.a_dd) {
i = nt.a_dd.length
while (--i >= 0) {
bi = strnum(nt.a_dd[i].name)
if (bi >= 0) {
set_pit(p_v, s, nt, bi)
delete nt.a_dd
continue ls
}
}
delete nt.a_dd
}
case C.NOTE:
// search the best string
bn = 100
bi = -1
i = p_v.tab.length
while (--i >= 0) {
if (strss[i] && strss[i] > s.time)
continue
n = (p_v.diafret ?
nt.pit : nt.midi) -
p_v.tab[i]
if (n >= 0 && n < bn) {
bi = i
bn = n
}
}
set_pit(p_v, s, nt, bi)
set_notes(p_v, s)
}
break
// put the stems on the lowest strings
if (!s.ts_next || s.ts_next.time != s.time) {
for (i = 0; i < lstr.length; i++) {
if (lstr[i]) {
delete lstr[i][1].stemless
lstr[i] = null
}
}
}
}
}
}
of()
}, // set_stems()
// get the parameters of the current voice
set_vp: function(of, a) {
var i, e, g, tab, strs, ok,
p_v = this.get_curvoice()
// convert a list of ABC notes into a list of MIDI pitches
function abc2tab(p) {
var i, c,
var i, c, a,
t = []
if (p_v.diafret) {
for (i = 0; i < p.length; i++) {
c = p[i]
c = "CDEFGABcdefgab".indexOf(c)
if (c < 0)
|
| ︙ | | |
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
|
+
+
+
+
+
+
+
+
+
+
-
+
|
}
}
t.push(c)
}
} else {
for (i = 0; i < p.length; i++) {
c = p[i]
switch (c) {
case '^':
case '_':
a = c == '^' ? 1 : -1
c = p[++i]
break
default:
a = 0
break
}
c = "CCDDEFFGGAABccddeffggaab".indexOf(c)
if (c < 0)
return // null
c += 60
c += 60 + a
while (1) {
if (p[i + 1] == "'") {
c += 12
i++
} else if (p[i + 1] == ",") {
c -= 12
i++
|
| ︙ | | |
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
|
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
|
}
} else {
while (1) {
str = a.shift()
if (!str)
break
p = "CCDDEFFGGAAB".indexOf(str[0])
if (p < 0)
return // undefined
o = str[1]
switch (o) {
case '#':
case 'b':
p += o == '#' ? 1 : -1
o = Number(str[2])
break
default:
o = Number(str[1])
if (p < 0 || isNaN(o))
return // null
o = Number(str[1])
break
}
if (isNaN(o))
return // undefined
t.push((o + 1) * 12 + p) // C4 = 60
}
}
return t
} // str2tab()
// convert the list of <string number> ':' <fret number>
function minfret(a) {
var sf,
sfa = a.split(' ')
p_v.minfret = {}
while (1) {
sf = sfa.shift()
if (!sf)
break
sf = sf.split(':')
if (sf.length != 2)
break //fixme: error
p_v.minfret[sf[0]] = sf[1]
}
} //minfret()
for (i = 0; i < a.length; i++) {
switch (a[i]) {
case "clef=":
e = a[i + 1]
if (e != "tab")
break
a.splice(i, 1)
// fall thru
case "tab":
a.splice(i, 1)
i--
ok = true
break
case "strings=":
strs = a[++i]
ok = true
break
case "nostems":
p_v.pos.stm = abc2svg.C.SL_HIDDEN
p_v.pos.gst = abc2svg.C.SL_HIDDEN
break
case "capo=":
p_v.capo = Number(a[++i])
break
case "diafret=":
i++
case "diafret":
p_v.diafret = true
break
case "minfret=":
minfret(a[++i])
break
}
}
// define the elements of the tablature
if (ok) {
if (!strs && this.parse.tab) { // if a global definition
strs = this.parse.tab
if (strs.indexOf("diafret") >= 0) {
p_v.diafret = true
strs = strs.replace(/\s*diafret\s*/, "")
}
}
if (strs) {
e = strs.slice(-1)
if (strs[1] >= '1' && strs[1] <= '9')
if (e >= '1' && e <= '9')
tab = str2tab(strs.split(',')) // W.V.'s syntax
else
tab = abc2tab(strs) // ABC syntax
if (!tab) {
this.syntax(1, "Bad strings in tablature")
ok = false
}
|
| ︙ | | |
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
|
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
|
-
+
-
+
|
a.push("clef=") // set the clef
g = this.get_glyphs()
if (tab.length == 3) {
a.push('"tab3"')
if (!g.tab3)
// SMuFL: -none-
g.tab3 = '<text id="tab3"\
x="-4,-4,-4" y="-4,3,10"\
x="-2,-2,-2" y="-4,3,10"\
style="font:bold 8px sans-serif">TAB</text>'
} else if (tab.length == 4) {
a.push('"tab4"')
if (!g.tab4)
// SMuFL: \ue06e
g.tab4 = '<text id="tab4"\
x="-4,-4,-4" y="-8,1,10"\
x="-3,-3,-3" y="-8,1,10"\
style="font:bold 12px sans-serif">TAB</text>'
} else if (tab.length == 5) {
a.push('"tab5"')
if (!g.tab5)
// SMuFL: -none-
g.tab5 = '<text id="tab5"\
x="-4,-4,-4" y="-11,-2,7"\
|
| ︙ | | |
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
|
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
|
-
-
+
|
of(a)
}, // set_vp()
set_hooks: function(abc) {
abc.draw_symbols = abc2svg.strtab.draw_symbols.bind(abc, abc.draw_symbols)
abc.set_format = abc2svg.strtab.set_fmt.bind(abc, abc.set_format);
abc.set_stems = abc2svg.strtab.set_stems.bind(abc, abc.set_stems)
abc.set_width = abc2svg.strtab.set_width.bind(abc, abc.set_width)
abc.set_vp = abc2svg.strtab.set_vp.bind(abc, abc.set_vp)
// define specific decorations used to force the string number
var decos = abc.get_decos()
decos["1s"] = "0 nul 0 0 0"
decos["2s"] = "0 nul 0 0 0"
decos["3s"] = "0 nul 0 0 0"
decos["4s"] = "0 nul 0 0 0"
decos["5s"] = "0 nul 0 0 0"
decos["6s"] = "0 nul 0 0 0"
if (!user.nul)
user.nul = function() {}
abc.add_style("\n.bn{font:bold 8px sans-serif}")
abc.add_style("\n.bn{font:bold 7px sans-serif}")
} // set_hooks()
} // strtab
abc2svg.modules.hooks.push(abc2svg.strtab.set_hooks)
abc2svg.modules.strtab.loaded = true
|