Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From 7190e10838e534a3 To 433944c7887548a5
|
2019-02-06
| ||
| 14:25 | batch: add 'abctopdf' ... (check-in: 2c9cf4bafe user: jef tags: trunk) | |
|
2019-02-01
| ||
| 15:55 | New release v1.19.1 ... (check-in: 433944c788 user: jef tags: trunk, v1.19.1) | |
| 14:01 | copyright update to 2019 ... (check-in: 83a7d2efe0 user: jef tags: trunk) | |
|
2018-06-21
| ||
| 08:33 | back to trunk ... (check-in: 68ef6ecf8e user: jef tags: trunk) | |
|
2018-05-28
| ||
| 07:26 | core: fix: accept 'exp' with bagpipe keys ... (check-in: 1909caa58f user: moinejf@free.fr tags: master) | |
|
2018-05-27
| ||
| 13:12 | New release v1.17.4 ... (check-in: 7190e10838 user: moinejf@free.fr tags: trunk, v1.17.4) | |
| 13:10 | core: remove useless double quotes ... (check-in: d41e047436 user: moinejf@free.fr tags: trunk) | |
Deleted .gitignore.
|
| < < < < < < < < < < |
Changes to README.md.
| ︙ | ︙ | |||
16 17 18 19 20 21 22 | **abc2svg** may be used in any web browser. The needed files are available in my site [http://moinejf.free.fr/js/](http://moinejf.free.fr/js). They are updated on release change. These files are: | | | | > > > > > > > > > > > > | | | | | > > | < | < < < < | | > < < | < | < | < | | 16 17 18 19 20 21 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 |
**abc2svg** may be used in any web browser.
The needed files are available in my site
[http://moinejf.free.fr/js/](http://moinejf.free.fr/js).
They are updated on release change.
These files are:
- `abc2svg-1.js`
This script is the **abc2svg** core.
It contains the ABC parser and the SVG generation engine.
It must be included in the (X)HTML header of the pages
where ABC rendering is needed (in `<script src=` tags).
- `abcemb-1.js`
This script is to be used with the core in (X)HTML files.
It replaces the ABC sequences by SVG images of the music
(the ABC sequences start on `X:` or `%abc` at start of line,
and stop on any ML tag).
See the
[%%beginml documentation](http://moinejf.free.fr/abcm2ps-doc/beginml.xhtml)
for an example.
When the URL of the (X)HTML file ends with '#' followed by a string,
only the first tune containing this string is displayed.
Note that, if the ABC sequence contains the characters '<', '>' or '&',
it must be enclosed in a XML comment (starting after the first `X:` or `%abc`).
- `abcemb2-1.js`
This script is also to be used with the core in (X)HTML files.
The differences with the previous script are
- the ABC sequences are replaced in HTML elements with the class `abc`,
- the string after '#' in the URL does a real %%select (i.e. this may
select many tunes),
- if the ABC sequences contain the characters '<', '>' or '&',
either these sequences must be enclosed in a XML comment, or the characters
must be replaced by their XML counterparts ('&lt;', '&gt;' or '&amp;').
- `abcdoc-1.js`
This script is also to be used in (X)HTML pages with the core.
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.xhtml)
for an example.
- `play-1.js`
This script may be used with `abcemb-1.js` for playing the
rendered ABC music.
See [this page](http://moinejf.free.fr/abcm2ps-doc/au_clair.xhtml)
for an example.
- `follow-1.js`
This script may be used after `play-1.js` for highlighting the notes
while playing.
See [this page](http://moinejf.free.fr/abcm2ps-doc/tabac.xhtml)
for an example.
- `edit-1.xhtml`
This is a simple web ABC editor/player.
When looking at a ABC file in a web browser, you may also use
this
<a href="javascript:(function(){d=document;b=d.body;b.innerHTML=%22\n%25abc-2.2\n%25%3c!--\n%22+b.textContent+%22%25--%3e\n%22;function%20f(u){s=d.createElement('script');s.setAttribute('src',u);b.appendChild(s);};f('http://moinejf.free.fr/js/abc2svg-1.js');f('http://moinejf.free.fr/js/abcemb-1.js');f('http://moinejf.free.fr/js/play-1.js');function%20t(){if(typeof%20dom_loaded=='function'){dom_loaded()}else{setTimeout(t,200)}};setTimeout(t,200)})();void(0)">bookmarklet</a>
and render the music
(create a bookmark and copy the link location into the address/location box).
##### Notes:
- The music is rendered 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)
for more information).
- Playing uses the HTML5 audio and/or midi APIs.
- With the editor, if you want to render ABC files
which contain `%%abc-include`, you must:
- load the ABC file from the browse button
- click in the include file name
- load the include file by the same browse button
Then, you may edit and save both files.
Rendering/playing is always done from the first ABC file.
There may be only one included file.
- The editor comes with different ways to enter the music from the keyboard.
If you have a US keyboard, you may try these bookmarklets:
<a href="javascript:(function(){if(typeof%20loadjs=='function'){loadjs('abckbd-1.js')}else{alert('use%20with%20abc2svg%20editor')}})();void(0)">keyboard 1</a>
and
<a href="javascript:(function(){if(typeof%20loadjs=='function'){loadjs('abckbd2-1.js')}else{alert('use%20with%20abc2svg%20editor')}})();void(0)">keyboard 2</a>
- The .js and .xhtml file names have a suffix which is the version of
the core interface (actually '`-1`').
### nodeJS usage
Installed via **npm**, the **abc2svg** package comes with the
command line (batch) programs `abc2svg` and `abc2odt`.
These ones may be used as **abcm2ps** to generate XHTML or ODT files.
|
| ︙ | ︙ | |||
125 126 127 128 129 130 131 |
```
abc2odt my_file.abc -o my_file.odt
```
### Build
If you want to build the **abc2svg** scripts in your machine,
| | | > > | > | < < | 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 |
```
abc2odt my_file.abc -o my_file.odt
```
### Build
If you want to build the **abc2svg** scripts in your machine,
you must first get the files from
[chisel](https://chiselapp.com/user/moinejf/repository/abc2svg),
either as a tarball or a Zip archive
(click `Timeline` and then in the top commit),
or by cloning the repository in some directory:
```
fossil clone https://chiselapp.com/user/moinejf/repository/abc2svg abc2svg.fossil
fossil open abc2svg.fossil
```
Then, building is done using the tool [ninja](https://ninja-build.org/)
or [samurai](https://github.com/michaelforney/samurai).
You may do it:
- without minification
This is interesting for debug purpose, the scripts being more human friendly.
|
| ︙ | ︙ | |||
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 |
file `font/abc2svg.sfd`. In this case, you will need both `base64` and `fontforge`,
and run
```
samu -v font.js
```
### Batch
After building the **abc2svg** scripts, you will be able to generate music
sheets from the command line as you did with `abcm2ps`, thanks to the
following shell scripts (the result goes to stdout):
- `abcjs24` with `js24` (Mozilla JavaScript shell - Spidermonkey)
- `abcjsc` with `jsc-1` (webkitgtk2)
- `abcnode` with `node` (nodeJS)
- `abcv8` with `d8` (Google libv8)
#### backend scripts
By default, the batch scripts generate (XHTML+SVG) files.
This output may be modified by backend scripts. These ones must appear
just after the command.
There are:
- `toabc.js`
This script outputs back the (selected) ABC tunes of the ABC source file.
Transposition is applied.
| > > > > | | < < | < | < < | < | < < | < | 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 |
file `font/abc2svg.sfd`. In this case, you will need both `base64` and `fontforge`,
and run
```
samu -v font.js
```
If you cannot or don't want to install `ninja` or `samurai`, you may build
the abc2svg files by `./build` which is a shell script.
### Batch
After building the **abc2svg** scripts, you will be able to generate music
sheets from the command line as you did with `abcm2ps`, thanks to the
following shell scripts (the result goes to stdout):
- `abcjs24` with `js24` (Mozilla JavaScript shell - Spidermonkey)
- `abcjs52` with `js52` (Mozilla JavaScript shell - Spidermonkey)
- `abcjsc` with `jsc-1` (webkitgtk2)
- `abcnode` with `node` (nodeJS)
- `abcv8` with `d8` (Google libv8)
#### backend scripts
By default, the batch scripts generate (XHTML+SVG) files.
This output may be modified by backend scripts. These ones must appear
just after the command.
There are:
- `toabc.js`
This script outputs back the (selected) ABC tunes of the ABC source file.
Transposition is applied.
The resulting file does not contain the formatting parameters.
Example:
`abcjs52 toabc.js my_file.abc --select X:2 > tune_2.abc`
- `toabw.js`
This script outputs a Abiword file (ABW+SVG) which may be read by some
word processors (abiword, libreoffice...) and converted to many other
formats by the batch function of abiword.
The abc2svg music font (`abc2svf.woff` or `abc2svg.ttf`) must be installed
in the local system for displaying and/or converting the .abw file.
Example:
`abcv8 toabw.js my_file.abc > my_file.abw`
- `toodt.js`
This script creates an Open Document (ODT+SVG) which may be read by most
word processors (abiword, libreoffice...).
It runs only with the npm script `abc2svg` and asks for the npm module
`jszip` to be installed.
The output ODT document may be specified by the command line argument `-o`
(default `abc.odt`).
Example:
`abc2svg toodt.js my_file.abc -o my_file.odt`
|
Added abc2svg.ttf.
cannot compute difference between binary files
Added abcjs52.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
#!/usr/bin/env js52
// abc2svg with js52 (Mozilla JavaScript shell - Spidermonkey
// packages: debian: libmozjs-52-dev, voidlinux: mozjs52)
loadRelativeToScript("abc2svg-1.js")
// interpreter specific functions
abc2svg.print = function(str) {
print(str)
}
abc2svg.printErr = function(str) {
printErr(str)
}
abc2svg.quit = function() {
quit(1)
}
abc2svg.readFile = function(fname) {
return read(fname)
}
abc2svg.loadjs = function(fn, relay, onerror) {
try {
loadRelativeToScript(fn)
if (relay)
relay()
} catch(e) {
if (onerror)
onerror()
else
printErr('Cannot read file ' + fn)
}
} // loadjs()
loadRelativeToScript("cmdline.js")
// main
var args = scriptArgs
if (/\.js$/.test(args[0])) {
load(args[0])
args.shift()
}
if (typeof abc2svg.abc_init != 'function')
loadRelativeToScript("toxhtml.js")
if (!args[0]) {
printErr('ABC translator with js52 (SpiderMonkey)\
and abc2svg-' + abc2svg.version + ' ' + abc2svg.vdate + '\n\
Usage:\n\
abcjs52 [script.js] [g_options] ABC_file [f_options] [ABC_file [f_options]]*\n\
Arguments:\n\
script.js generation script to load - default: toxhtml.js (XHTML+SVG)\n\
g_options global ABC options\n\
ABC_file ABC file\n\
f_options file options')
quit()
}
abc_cmd("abcjs52", args)
|
Changes to abcjsc.
1 | #!/bin/sh | | | | 1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/sh
# abc2svg with jsc (webkit2gtk)
progdir=`dirname $0`
exec jsc -e "var progdir='${progdir}/'
// function to do utf-8 work...
// uncommenting this function asks for also uncommenting its call in cmdline.js
//function utf_convert(fin) {
// var b1, b2,
// fout = ''
// for (var i = 0; i < fin.length; i++) {
|
| ︙ | ︙ | |||
49 50 51 52 53 54 55 |
load(progdir + 'cmdline.js')
function main(args) {
if (/\.js$/.test(args[0])) {
load(args[0])
args.shift()
}
| < < < | > > > > > | 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 |
load(progdir + 'cmdline.js')
function main(args) {
if (/\.js$/.test(args[0])) {
load(args[0])
args.shift()
}
if (!args[0]) {
print('ABC translator with jsc (webkit2gtk)\
and abc2svg-' + abc2svg.version + ' ' + abc2svg.vdate + '\n\
Usage:\n\
abcjsc [script.js] [g_options] ABC_file [f_options] [ABC_file [f_options]]*\n\
Arguments:\n\
script.js script to load - default: toxhtml.js (XHTML+SVG generation)\n\
g_options global ABC options\n\
ABC_file ABC file\n\
f_options file options')
quit()
}
if (typeof(abc2svg.abc_init) != 'function')
load(progdir + 'toxhtml.js')
abc_cmd('abcjsc', args)
}
if (typeof arguments == 'undefined')
var arguments = ''
main(arguments)
" -- "$@"
|
Changes to abcnode.
1 2 3 4 | #!/bin/sh # abc2svg with raw nodeJS progdir=`dirname $0` | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/bin/sh
# abc2svg with raw nodeJS
progdir=`dirname $0`
cat ${progdir}/abc2svg-1.js > /tmp/toto.js
case $1 in
*.js)
cat $1 >> /tmp/toto.js
shift
;;
esac
if ! grep 'abc2svg.abc_init =' "$1" > /dev/null; then
cat ${progdir}/toxhtml.js >> /tmp/toto.js
fi
cat <<EOF >> /tmp/toto.js
var progdir='${progdir}/'
// interpreter specific functions
|
| ︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
abc2svg.printErr('Cannot read file ' + fn)
}
}
// (this file is wrapped)
global.Abc = Abc
global.abc2svg = abc2svg
// main
var args = process.argv
if (!args[2]) {
abc2svg.print('ABC translator with nodeJS\
and abc2svg-' + abc2svg.version + ' ' + abc2svg.vdate + '\n\
Usage:\n\
abcnode [script.js] [g_options] ABC_file [f_options] [ABC_file [f_options]]*\n\
| > > > > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
abc2svg.printErr('Cannot read file ' + fn)
}
}
// (this file is wrapped)
global.Abc = Abc
global.abc2svg = abc2svg
EOF
cat ${progdir}/cmdline.js >> /tmp/toto.js
cat <<EOF >> /tmp/toto.js
// main
var args = process.argv
if (!args[2]) {
abc2svg.print('ABC translator with nodeJS\
and abc2svg-' + abc2svg.version + ' ' + abc2svg.vdate + '\n\
Usage:\n\
abcnode [script.js] [g_options] ABC_file [f_options] [ABC_file [f_options]]*\n\
|
| ︙ | ︙ |
Added build.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 | #!/bin/sh # simple build of abc2svg as a shell script MAJOR=1 out=abc2svg-$MAJOR.js VERSION=`grep '"version"' package.json|cut -d'"' -f4` DATE=`date '+%Y-%m-%d' -r package.json` cp core/license $out cat core/abc2svg.js core/deco.js core/draw.js\ font.js core/format.js core/front.js core/music.js core/parse.js core/subs.js\ core/svg.js core/tune.js core/lyrics.js core/gchord.js core/tail.js\ core/modules.js >> $out echo "abc2svg.version=\"$VERSION\";abc2svg.vdate=\"$DATE\"" >> $out cp modules/ambitus.js ambitus-$MAJOR.js cp modules/break.js break-$MAJOR.js cp modules/capo.js capo-$MAJOR.js cp modules/clip.js clip-$MAJOR.js cp modules/combine.js combine-$MAJOR.js cp modules/diag.js diag-$MAJOR.js cp modules/equalbars.js equalbars-$MAJOR.js cp modules/grid.js grid-$MAJOR.js cp modules/grid2.js grid2-$MAJOR.js cp modules/MIDI.js MIDI-$MAJOR.js cp modules/page.js page-$MAJOR.js cp modules/perc.js perc-$MAJOR.js cat modules/wps.js modules/psvg.js > psvg-$MAJOR.js cp modules/soloffs.js soloffs-$MAJOR.js cp modules/sth.js sth-$MAJOR.js cp modules/temper.js temper-$MAJOR.js cp editor/edit.css edit-$MAJOR.css cp util/abcdoc.js abcdoc-$MAJOR.js cp util/abcemb.js abcemb-$MAJOR.js cp util/abcemb2.js abcemb2-$MAJOR.js cp util/follow.js follow-$MAJOR.js cp util/json.js json-$MAJOR.js cp util/midi.js setmidi-$MAJOR.js cp util/toaudio.js toaudio-$MAJOR.js cat util/play.js util/toaudio.js util/toaudio5.js\ util/sf2-parser.js util/tomidi5.js > play-$MAJOR.js sed "s+@MAJOR@+$MAJOR+" editor/edit.xhtml > edit-$MAJOR.xhtml sed "s+@MAJOR@+$MAJOR+" editor/abckbd.js > abckbd-$MAJOR.js sed "s+@MAJOR@+$MAJOR+" editor/abckbd2.js > abckbd2-$MAJOR.js sed "s+@MAJOR@+$MAJOR+" editor/edit.js > edit-$MAJOR.js |
Changes to build.ninja.
1 2 3 4 5 6 7 8 9 10 11 | # rules for ninja (ninja-build) # 'uglifyjs' may be disabled running # NOMIN=1 ninja -v MAJOR=1 rule cp command = cp $in $out rule cpm | > > > | | > > | > > | | > | | | < < | | | > < < < < < < < < | < | | | | | | | | | | | | | | | | | | > | | | > | | > | > | | > | | | > | < | | | | | | | | | < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
# rules for ninja (ninja-build)
# 'uglifyjs' may be disabled running
# NOMIN=1 ninja -v
MAJOR=1
# ninja tool
tool=samu
rule cp
command = cp $in $out
rule cpm
command = sed "s+@MAJOR@+$MAJOR+" $in > $out
rule font
command = fontforge -c 'open("font/abc2svg.sfd").generate("abc2svg.ttf")';$
fontforge -c 'open("font/abc2svg.sfd").generate("abc2svg.woff")';$
echo "// abc2svg music font" > font.js;$
echo "var musicfont = 'url(\"data:application/x-font-ttf;base64,\\" >> font.js;$
base64 abc2svg.ttf | sed 's/$$/\\/' >> font.js;$
echo "\")'" >> font.js
rule jsc
command = VERSION=`grep '"version"' package.json|cut -d'"' -f4`;$
type fossil &> /dev/null;$
if [ $$? -eq 0 ]; then $
c=`fossil info | grep checkout:`;$
t=`fossil info | grep tags: | awk '{print $$NF}'`;$
if [ "$${t#v}" != "$$VERSION" ]; then $
VERSION="$${VERSION}-$$(echo $$c | cut -d' ' -f2 | cut -c1-10)";$
fi;$
DATE=`echo $$c | cut -d' ' -f3`;$
else $
DATE=`date '+%Y-%m-%d' -r package.json`;$
fi;$
cp core/license $out;$
if [ "x$$NOMIN" = "x" ]; then $
cat $in | uglifyjs >> $out;$
else $
cat $in >> $out;$
fi;$
echo "abc2svg.version=\"$$VERSION\";abc2svg.vdate=\"$$DATE\"" >> $out
rule jscu
command = cp core/license $out;$
if [ "x$$NOMIN" = "x" ]; then $
uglifyjs $in >> $out;$
else $
cat $in >> $out;$
fi
rule edit
command = if [ "x$$NOMIN" = "x" ]; then $
sed "s+@MAJOR@+$MAJOR+" $in | uglifyjs > $out;$
else $
sed "s+@MAJOR@+$MAJOR+" $in > $out;$
fi
# generate all Scc1t2/n.js from sf2-Scc1t2/n.sf2
rule sf
command = for f in sf2-Scc1t2/*.sf2; do $
instr=`basename $$f`;$
o=$${f#sf2-};$
o=$${o%.sf2}.js;$
if [ ! -r $$o -o $$f -nt $$o ]; then $
echo '// abc2svg sound font' > $$o;$
echo "abcsf2[$${instr%.sf2}] = '\\" >> $$o;$
base64 $$f | sed 's/$$/\\/' >> $$o;$
echo "'" >> $$o;$
fi;$
done
build font: font | font/abc2svg.sfd
build sf: sf | Scc1t2/
build abc2svg-$MAJOR.js: jsc core/abc2svg.js core/deco.js core/draw.js $
font.js core/format.js core/front.js core/music.js core/parse.js core/subs.js $
core/svg.js core/tune.js core/lyrics.js core/gchord.js core/tail.js $
core/modules.js | package.json
build ambitus-$MAJOR.js: jscu modules/ambitus.js
build break-$MAJOR.js: jscu modules/break.js
build capo-$MAJOR.js: jscu modules/capo.js
build clip-$MAJOR.js: jscu modules/clip.js
build combine-$MAJOR.js: jscu modules/combine.js
build diag-$MAJOR.js: jscu modules/diag.js
build equalbars-$MAJOR.js: jscu modules/equalbars.js
build grid-$MAJOR.js: jscu modules/grid.js
build grid2-$MAJOR.js: jscu modules/grid2.js
build MIDI-$MAJOR.js: jscu modules/MIDI.js
build page-$MAJOR.js: jscu modules/page.js
build perc-$MAJOR.js: jscu modules/perc.js
build psvg-$MAJOR.js: jscu modules/wps.js modules/psvg.js
build soloffs-$MAJOR.js: jscu modules/soloffs.js
build sth-$MAJOR.js: jscu modules/sth.js
build temper-$MAJOR.js: jscu modules/temper.js
build edit-$MAJOR.css: cp editor/edit.css
build abcdoc-$MAJOR.js: jscu util/abcdoc.js
build abcemb-$MAJOR.js: jscu util/abcemb.js
build abcemb2-$MAJOR.js: jscu util/abcemb2.js
build follow-$MAJOR.js: jscu util/follow.js
build json-$MAJOR.js: jscu util/json.js
build setmidi-$MAJOR.js: jscu util/midi.js
build toaudio-$MAJOR.js: jscu util/toaudio.js
build play-$MAJOR.js: jscu util/play.js util/toaudio.js $
util/toaudio5.js util/sf2-parser.js util/tomidi5.js
build edit-$MAJOR.xhtml: cpm editor/edit.xhtml
build abckbd-$MAJOR.js: edit editor/abckbd.js
build abckbd2-$MAJOR.js: edit editor/abckbd2.js
build edit-$MAJOR.js: edit editor/edit.js
build all: phony abc2svg-$MAJOR.js abcdoc-$MAJOR.js $
abcemb-$MAJOR.js abcemb2-$MAJOR.js json-$MAJOR.js setmidi-$MAJOR.js $
toaudio-$MAJOR.js play-$MAJOR.js psvg-$MAJOR.js $
ambitus-$MAJOR.js break-$MAJOR.js capo-$MAJOR.js clip-$MAJOR.js $
combine-$MAJOR.js diag-$MAJOR.js equalbars-$MAJOR.js grid-$MAJOR.js grid2-$MAJOR.js $
MIDI-$MAJOR.js page-$MAJOR.js perc-$MAJOR.js soloffs-$MAJOR.js sth-$MAJOR.js $
temper-$MAJOR.js edit-$MAJOR.css edit-$MAJOR.js edit-$MAJOR.xhtml $
abckbd-$MAJOR.js abckbd2-$MAJOR.js follow-$MAJOR.js
default all
# npm/fossil new release
rule version
command = npm version $out;$
tag=`ag '"version"' package.json|cut -d'"' -f4`;$
fossil commit -m "New release v$$tag" -tag v$$tag;$
$tool -v;$
npm publish
build minor: version
build patch: version
|
Changes to cmdline.js.
| ︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
abc2svg.abort(e)
}
} // do_file()
function abc_cmd(cmd, args) {
var arg, parm, fn;
// load 'default.abc'
try {
arg = user.read_file('default.abc');
abc.tosvg(cmd, arg)
} catch (e) {
}
| > > > > < < | 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 |
abc2svg.abort(e)
}
} // do_file()
function abc_cmd(cmd, args) {
var arg, parm, fn;
// initialize the backend
abc2svg.abc_init(args)
// load 'default.abc'
try {
arg = user.read_file('default.abc');
abc2svg.modules.load(arg)
abc.tosvg(cmd, arg)
} catch (e) {
}
while (1) {
arg = args.shift()
if (!arg)
break
if (arg[0] == "-") {
if (arg[1] == "-") {
parm = args.shift();
|
| ︙ | ︙ |
Changes to core/abc2svg.js.
1 2 | // abc2svg - abc2svg.js // | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// abc2svg - abc2svg.js
//
// Copyright (C) 2014-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
// start of the abc2svg object
var abc2svg = {
// constants
C: {
BLEN: 1536,
// symbol types
BAR: 0,
CLEF: 1,
CUSTOS: 2,
GRACE: 4,
KEY: 5,
METER: 6,
MREST: 7,
NOTE: 8,
PART: 9,
REST: 10,
SPACE: 11,
STAVES: 12,
STBRK: 13,
TEMPO: 14,
BLOCK: 16,
REMARK: 17,
// note heads
FULL: 0,
EMPTY: 1,
OVAL: 2,
OVALBARS: 3,
SQUARE: 4,
// slur/tie types (3 + 1 bits)
SL_ABOVE: 0x01,
SL_BELOW: 0x02,
SL_AUTO: 0x03,
SL_HIDDEN: 0x04,
SL_DOTTED: 0x08 // (modifier bit)
},
// start of the Abc object
Abc: function(user) {
"use strict";
// constants
var C = abc2svg.C;
// mask some unsafe functions
var require = empty_function,
system = empty_function,
write = empty_function,
XMLHttpRequest = empty_function;
// -- constants --
// staff system
var OPEN_BRACE = 0x01,
CLOSE_BRACE = 0x02,
OPEN_BRACKET = 0x04,
CLOSE_BRACKET = 0x08,
OPEN_PARENTH = 0x10,
CLOSE_PARENTH = 0x20,
STOP_BAR = 0x40,
FL_VOICE = 0x80,
OPEN_BRACE2 = 0x0100,
CLOSE_BRACE2 = 0x0200,
OPEN_BRACKET2 = 0x0400,
CLOSE_BRACKET2 = 0x0800,
MASTER_VOICE = 0x1000,
IN = 96, // resolution 96 PPI
CM = 37.8, // 1 inch = 2.54 centimeter
YSTEP = 256 /* number of steps for y offsets */
// error texts
var errs = {
bad_char: "Bad character '$1'",
bad_val: "Bad value in $1",
bar_grace: "Cannot have a bar in grace notes",
ignored: "$1: inside tune - ignored",
misplaced: "Misplaced '$1' in %%staves",
must_note: "!$1! must be on a note",
must_note_rest: "!$1! must be on a note or a rest",
nonote_vo: "No note in voice overlay",
not_enough_n: 'Not enough notes/rests for %%repeat',
not_enough_m: 'Not enough measures for %%repeat',
not_ascii: "Not an ASCII character"
}
var self = this, // needed for modules
glovar = {
meter: {
type: C.METER, // meter in tune header
wmeasure: 1, // no M:
a_meter: [] // default: none
}
},
info = {}, // information fields
mac = {}, // macros (m:)
maci = new Int8Array(128), // first letter of macros
|
| ︙ | ︙ |
Changes to core/deco.js.
1 2 | // abc2svg - deco.js - decorations // | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// abc2svg - deco.js - decorations
//
// Copyright (C) 2014-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
var dd_tb = {}, // definition of the decorations
a_de // array of the decoration elements
// decorations - populate with standard decorations
var decos = {
dot: "0 stc 5 1 1",
tenuto: "0 emb 5 3 3",
slide: "1 sld 3 7 0",
arpeggio: "2 arp 12 10 0",
|
| ︙ | ︙ | |||
51 52 53 54 55 56 57 | "1": "3 fng 8 3 3 1", "2": "3 fng 8 3 3 2", "3": "3 fng 8 3 3 3", "4": "3 fng 8 3 3 4", "5": "3 fng 8 3 3 5", plus: "3 dplus 7 3 3", "+": "3 dplus 7 3 3", | | | | | | | | | | | | | | | | | | > > | | | | | | | | | 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 |
"1": "3 fng 8 3 3 1",
"2": "3 fng 8 3 3 2",
"3": "3 fng 8 3 3 3",
"4": "3 fng 8 3 3 4",
"5": "3 fng 8 3 3 5",
plus: "3 dplus 7 3 3",
"+": "3 dplus 7 3 3",
accent: "3 accent 7 4 4",
">": "3 accent 7 4 4",
marcato: "3 marcato 9 3 3",
"^": "3 marcato 9 3 3",
mordent: "3 lmrd 10 5 5",
open: "3 opend 10 3 3",
snap: "3 snap 14 3 3",
thumb: "3 thumb 14 3 3",
dacapo: "3 dacs 16 20 20 Da Capo",
dacoda: "3 dacs 16 20 20 Da Coda",
"D.C.": "3 dcap 16 10 10",
"D.S.": "3 dsgn 16 10 10",
"D.C.alcoda": "3 dacs 16 38 38 D.C. al Coda",
"D.S.alcoda": "3 dacs 16 38 38 D.S. al Coda",
"D.C.alfine": "3 dacs 16 38 38 D.C. al Fine",
"D.S.alfine": "3 dacs 16 38 38 D.S. al Fine",
fine: "3 dacs 16 10 10 Fine",
turn: "3 turn 10 0 5",
"trill(": "3 ltr 8 0 0",
"trill)": "3 ltr 8 0 0",
f: "6 f 18 1 7",
ff: "6 ff 18 2 10",
fff: "6 fff 18 4 13",
ffff: "6 ffff 18 6 16",
mf: "6 mf 18 6 13",
mp: "6 mp 18 6 16",
p: "6 p 18 2 8",
pp: "6 pp 18 5 14",
ppp: "6 ppp 18 8 20",
pppp: "6 pppp 18 10 25",
pralltriller: "3 umrd 10 5 5",
sfz: "6 sfz 18 4 10",
ped: "4 ped 18 8 8",
"ped-up": "4 pedoff 18 8 8",
"ped(": "4 lped 20 1 1",
"ped)": "4 lped 20 1 1",
"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",
">)": "6 dim 18 0 0",
"-(": "8 gliss 0 0 0",
"-)": "8 gliss 0 0 0",
"~(": "8 glisq 0 0 0",
"~)": "8 glisq 0 0 0",
"8va(": "3 8va 10 0 0",
"8va)": "3 8va 10 0 0",
"8vb(": "4 8vb 10 0 0",
|
| ︙ | ︙ | |||
194 195 196 197 198 199 200 |
}
}
}
/* -- get the staff position of the dynamic and volume marks -- */
function up_p(s, pos) {
switch (pos) {
| | | | | | | | | | 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 |
}
}
}
/* -- get the staff position of the dynamic and volume marks -- */
function up_p(s, pos) {
switch (pos) {
case C.SL_ABOVE:
return true
case C.SL_BELOW:
return false
}
if (s.multi && s.multi != 0)
return s.multi > 0
if (!s.p_v.have_ly)
return false
/* above if the lyrics are below the staff */
return s.pos.voc != C.SL_ABOVE
}
/* -- drawing functions -- */
/* 2: special case for arpeggio */
function d_arp(de) {
var m, h, dx,
s = de.s,
dd = de.dd,
xc = 5
if (s.type == C.NOTE) {
for (m = 0; m <= s.nhd; m++) {
if (s.notes[m].acc) {
dx = 5 + s.notes[m].shac
} else {
dx = 6 - s.notes[m].shhd
switch (s.head) {
case C.SQUARE:
dx += 3.5
break
case C.OVALBARS:
case C.OVAL:
dx += 2
break
}
}
if (dx > xc)
xc = dx
}
}
h = 3 * (s.notes[s.nhd].pit - s.notes[0].pit) + 4;
m = dd.h /* minimum height */
if (h < m)
h = m;
de.has_val = true;
de.val = h;
// de.x = s.x - xc;
de.x -= xc;
de.y = 3 * (s.notes[0].pit - 18) - 3
}
// special case for long dynamic decorations
function d_cresc(de) {
if (de.ldst) // skip start of deco
return
var s, dd, dd2, up, x, dx, x2, i,
s2 = de.s,
de2 = de.start, /* start of the deco */
de2_prev, de_next;
|
| ︙ | ︙ | |||
348 349 350 351 352 353 354 | } if (up) s.ymx = y + dd.h else s.ymn = y; de.y = y // de.x = s.x + s.notes[s.stem >= 0 ? 0 : s.nhd].shhd | | | > > > > > > > > | 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 |
}
if (up)
s.ymx = y + dd.h
else
s.ymn = y;
de.y = y
// de.x = s.x + s.notes[s.stem >= 0 ? 0 : s.nhd].shhd
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 (up) {
if (s.stem > 0)
de.x += 3.5 // stem_xoff
} else {
if (s.stem < 0)
de.x -= 3.5
}
}
}
/* 6: dynamic marks */
function d_pf(de) {
var dd2, x2, x, up,
s = de.s,
dd = de.dd,
de_prev;
// don't treat here the long decorations
if (de.ldst) // if long deco start
return
if (de.start) { // if long decoration
d_cresc(de)
return
}
de.val = dd.wl + dd.wr;
up = up_p(s, s.pos.vol)
if (up)
de.up = true;
x = s.x - dd.wl
if (de.ix > 0) {
|
| ︙ | ︙ | |||
408 409 410 411 412 413 414 |
for (m = 0; m <= s.nhd; m++) {
if (s.notes[m].acc) {
dx = 4 + s.notes[m].shac
} else {
dx = 5 - s.notes[m].shhd
switch (s.head) {
| | | | | | > | | | | 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 |
for (m = 0; m <= s.nhd; m++) {
if (s.notes[m].acc) {
dx = 4 + s.notes[m].shac
} else {
dx = 5 - s.notes[m].shhd
switch (s.head) {
case C.SQUARE:
dx += 3.5
break
case C.OVALBARS:
case C.OVAL:
dx += 2
break
}
}
if (s.notes[m].pit <= yc + 3 && dx > xc)
xc = dx
}
// de.x = s.x - xc;
de.x -= xc;
de.y = 3 * (yc - 18)
}
// special case for long decoration
function d_trill(de) {
if (de.ldst)
return
var up, y, w, tmp,
dd = de.dd,
s2 = de.s,
st = s2.st,
s = de.start.s,
x = s.x
if (de.prev) { // hack 'tr~~~~~'
x = de.prev.x + 10;
y = de.prev.y
}
de.st = st
if (dd.func != 4) { // if not below
switch (dd.glyph) {
case "8va":
case "15ma":
up = 1
break
default:
up = s2.multi >= 0
break
}
}
if (de.defl.noen) { /* if no decoration end */
w = de.x - x
if (w < 20) {
x = de.x - 20 - 3;
w = 20
}
} else {
w = s2.x - x - 6
if (s2.type == C.NOTE)
w -= 6
if (w < 20) {
x -= (20 - w) * .5;
w = 20
}
}
dd = de.dd;
|
| ︙ | ︙ | |||
519 520 521 522 523 524 525 |
if (s.nhd)
x += s.notes[s.stem >= 0 ? 0 : s.nhd].shhd;
up = -1
if (dd.func == 4) { // below
up = 0
} else if (s.pos) {
switch (s.pos.orn) {
| | | | | | | | | | 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 |
if (s.nhd)
x += s.notes[s.stem >= 0 ? 0 : s.nhd].shhd;
up = -1
if (dd.func == 4) { // below
up = 0
} else if (s.pos) {
switch (s.pos.orn) {
case C.SL_ABOVE:
up = 1
break
case C.SL_BELOW:
up = 0
break
}
}
switch (dd.glyph) {
case "accent":
case "roll":
if (!up
|| (up < 0
&& (s.multi < 0
|| (!s.multi && s.stem > 0)))) {
yc = y_get(s.st, false, s.x - dd.wl, w) - 2
if (yc > staffb)
yc = staffb;
yc -= dd.h;
y_set(s.st, false, s.x, 0, yc);
inv = true;
s.ymn = yc
} else {
yc = y_get(s.st, true, s.x - dd.wl, w) + 2
if (yc < stafft)
yc = stafft;
y_set(s.st, true, s.x - dd.wl, w, yc + dd.h);
s.ymx = yc + dd.h
}
break
case "brth":
case "lphr":
case "mphr":
case "sphr":
yc = stafft + 1
if (dd.glyph == "brth" && yc < s.ymx)
yc = s.ymx
for (s = s.ts_next; s; s = s.ts_next)
if (s.seqst)
break
x += ((s ? s.x : realwidth) - x) * .45
break
default:
if (dd.name.indexOf("invert") == 0)
inv = true
if (dd.name != "invertedfermata"
&& (up > 0
|| (up < 0 && s.multi >= 0))) {
yc = y_get(s.st, true, s.x - dd.wl, w) + 2
if (yc < stafft)
yc = stafft;
y_set(s.st, true, s.x - dd.wl, w, yc + dd.h);
s.ymx = yc + dd.h
} else {
yc = y_get(s.st, false, s.x - dd.wl, w) - 2
if (yc > staffb)
yc = staffb;
yc -= dd.h;
y_set(s.st, false, s.x - dd.wl, w, yc)
if (dd.name == "fermata")
inv = true;
s.ymn = yc
|
| ︙ | ︙ | |||
646 647 648 649 650 651 652 653 654 655 656 657 658 659 |
return //undefined
}
if ((c_func < 0 || c_func > 10)
&& (c_func < 32 || c_func > 41)) {
error(1, null, "%%deco: bad C function index '$1'", c_func)
return //undefined
}
if (h < 0 || wl < 0 || wr < 0) {
error(1, null, "%%deco: cannot have a negative value '$1'", text)
return //undefined
}
if (h > 50 || wl > 80 || wr > 80) {
error(1, null, "%%deco: abnormal h/wl/wr value '$1'", text)
return //undefined
| > > > > > | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
return //undefined
}
if ((c_func < 0 || c_func > 10)
&& (c_func < 32 || c_func > 41)) {
error(1, null, "%%deco: bad C function index '$1'", c_func)
return //undefined
}
if (c_func == 5) // old !trill(!
c_func = 3
if (c_func == 7) // old !cresc(!
c_func = 6
if (h < 0 || wl < 0 || wr < 0) {
error(1, null, "%%deco: cannot have a negative value '$1'", text)
return //undefined
}
if (h > 50 || wl > 80 || wr > 80) {
error(1, null, "%%deco: abnormal h/wl/wr value '$1'", text)
return //undefined
|
| ︙ | ︙ | |||
685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
if (dd.func == 6 && dd.str == undefined)
dd.str = dd.name
// link the start and end of long decorations
c = dd.name.slice(-1)
if (c == '(' ||
(c == ')' && dd.name.indexOf('(') < 0)) {
name2 = dd.name.slice(0, -1) + (c == '(' ? ')' : '(');
dd2 = dd_tb[name2]
if (dd2) {
if (c == '(') {
dd.dd_en = dd2;
dd2.dd_st = dd
} else {
| > | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
if (dd.func == 6 && dd.str == undefined)
dd.str = dd.name
// link the start and end of long decorations
c = dd.name.slice(-1)
if (c == '(' ||
(c == ')' && dd.name.indexOf('(') < 0)) {
dd.str = null; // (no string)
name2 = dd.name.slice(0, -1) + (c == '(' ? ')' : '(');
dd2 = dd_tb[name2]
if (dd2) {
if (c == '(') {
dd.dd_en = dd2;
dd2.dd_st = dd
} else {
|
| ︙ | ︙ | |||
721 722 723 724 725 726 727 |
if (!dd)
continue
}
/* special decorations */
switch (dd.func) {
case 0: // near
| | | | | 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 |
if (!dd)
continue
}
/* special decorations */
switch (dd.func) {
case 0: // near
if (s.type == C.BAR && dd.name == "dot") {
s.bar_dotted = true
break
}
// fall thru
case 1: // slide
case 2: // arp
// if (s.type != C.NOTE && s.type != C.REST) {
if (!s.notes) {
error(1, s,
errs.must_note_rest, dd.name)
continue
}
break
case 8: // gliss
if (s.type != C.NOTE) {
error(1, s,
errs.must_note, dd.name)
continue
}
note = s.notes[s.nhd] // move to the upper note of the chord
if (!note.a_dcn)
note.a_dcn = []
|
| ︙ | ︙ | |||
775 776 777 778 779 780 781 | s.color = dd.name } continue case 32: /* invisible */ s.invis = true continue case 33: /* beamon */ | | | | | < < < < < < < < < < < < < | < | | < < < < | | 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 |
s.color = dd.name
}
continue
case 32: /* invisible */
s.invis = true
continue
case 33: /* beamon */
if (s.type != C.BAR) {
error(1, s, "!beamon! must be on a bar")
continue
}
s.beam_on = true
continue
case 34: /* trem1..trem4 */
if (s.type != C.NOTE
|| !prev
|| prev.type != C.NOTE
|| s.dur != prev.dur) {
error(1, s,
"!$1! must be on the last of a couple of notes",
dd.name)
continue
}
s.trem2 = true;
s.beam_end = true;
// s.beam_st = false;
prev.beam_st = true;
// prev.beam_end = false;
s.ntrem = prev.ntrem = Number(dd.name[4]);
for (j = 0; j <= s.nhd; j++)
s.notes[j].dur *= 2;
for (j = 0; j <= prev.nhd; j++)
prev.notes[j].dur *= 2
continue
case 35: /* xstem */
if (s.type != C.NOTE) {
error(1, s, "!xstem! must be on a note")
continue
}
s.xstem = true;
continue
case 36: /* beambr1 / beambr2 */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, dd.name)
continue
}
if (dd.name[6] == '1')
s.beam_br1 = true
else
s.beam_br2 = true
continue
case 37: /* rbstop */
s.rbstop = 1 // open
continue
case 38: /* /, // and /// = tremolo */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, dd.name)
continue
}
s.trem1 = true;
s.ntrem = dd.name.length /* 1, 2 or 3 */
continue
case 39: /* beam-accel/beam-rall */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, dd.name)
continue
}
s.feathered_beam = dd.name[5] == 'a' ? 1 : -1;
continue
case 40: /* stemless */
s.stemless = true
|
| ︙ | ︙ | |||
901 902 903 904 905 906 907 | if (wl < 7) wl = 7 break case 2: /* arpeggio */ if (wl < 14) wl = 14 break | > > > > > > > > > | > | > | | 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 |
if (wl < 7)
wl = 7
break
case 2: /* arpeggio */
if (wl < 14)
wl = 14
break
case 3:
switch (dd.glyph) {
case "brth":
case "lphr":
case "mphr":
case "sphr":
if (s.wr < 20)
s.wr = 20
break
}
break
}
}
if (wl != 0 && s.prev && s.prev.type == C.BAR)
wl -= 3
return wl
}
/* -- draw the decorations -- */
/* (the staves are defined) */
function draw_all_deco() {
|
| ︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 |
uf = user[f]
if (uf && typeof(uf) == "function") {
uf(x, y, de)
continue
}
// check if user PS definition
| | | 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 |
uf = user[f]
if (uf && typeof(uf) == "function") {
uf(x, y, de)
continue
}
// check if user PS definition
if (self.psdeco(f, x, y, de))
continue
anno_start(s, 'deco')
// if (de.flags.grace) {
// g_open(x, y, 0, .7, de.inv ? -.7 : 0);
// x = y = 0
// } else
|
| ︙ | ︙ | |||
1060 1061 1062 1063 1064 1065 1066 | a_de = new_de } /* -- create the decorations and define the ones near the notes -- */ /* (the staves are not yet defined) */ /* (delayed output) */ /* this function must be called first as it builds the deco element table */ | < < | 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 |
a_de = new_de
}
/* -- create the decorations and define the ones near the notes -- */
/* (the staves are not yet defined) */
/* (delayed output) */
/* this function must be called first as it builds the deco element table */
function draw_deco_near() {
var s, g
// update starting old decorations
function ldeco_update(s) {
var i, de,
// x = s.ts_prev.x + s.ts_prev.wr
|
| ︙ | ︙ | |||
1096 1097 1098 1099 1100 1101 1102 |
/* check if hidden */
switch (dd.func) {
default:
pos = 0
break
case 3: /* d_upstaff */
case 4:
| < < < < < < < < < < < < < < < < < < | | 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 |
/* check if hidden */
switch (dd.func) {
default:
pos = 0
break
case 3: /* d_upstaff */
case 4:
pos = s.pos.orn
break
case 6: /* d_pf */
pos = s.pos.vol
break
case 7: /* d_cresc */
pos = s.pos.dyn
break
}
if (pos == C.SL_HIDDEN)
continue
de = {
s: s,
dd: dd,
st: s.st,
ix: a_de.length,
|
| ︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 |
de2.start = de
}
} // ll_deco
// update the long decorations started in the previous line
for (s = tsfirst ; s; s = s.ts_next) {
switch (s.type) {
| | | | | | | | | | | 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 |
de2.start = de
}
} // ll_deco
// update the long decorations started in the previous line
for (s = tsfirst ; s; s = s.ts_next) {
switch (s.type) {
case C.CLEF:
case C.KEY:
case C.METER:
continue
}
break
}
if (a_de.length != 0)
ldeco_update(s)
for ( ; s; s = s.ts_next) {
switch (s.type) {
case C.BAR:
case C.MREST:
case C.NOTE:
case C.REST:
case C.SPACE:
break
case C.GRACE:
for (g = s.extra; g; g = g.next)
create_all(g)
default:
continue
}
create_all(s)
}
|
| ︙ | ︙ | |||
1378 1379 1380 1381 1382 1383 1384 |
/* draw the repeat brackets */
function draw_repbra(p_voice) {
var s, s1, y, y2, i, p, w, wh, first_repeat;
/* search the max y offset */
y = staff_tb[p_voice.st].topbar + 25 // 20 (vert bar) + 5 (room)
for (s = p_voice.sym; s; s = s.next) {
| | | 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 |
/* draw the repeat brackets */
function draw_repbra(p_voice) {
var s, s1, y, y2, i, p, w, wh, first_repeat;
/* search the max y offset */
y = staff_tb[p_voice.st].topbar + 25 // 20 (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)
break
if (!first_repeat) {
|
| ︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 | break } if (s1 == s) break x = s1.x // if (s1.bar_type[0] == ":") // x -= 4; | | | 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 |
break
}
if (s1 == s)
break
x = s1.x
// if (s1.bar_type[0] == ":")
// x -= 4;
if (s.type != C.BAR) {
w = s.rbstop ? 0 : s.x - realwidth + 4
} else if ((s.bar_type.length > 1 // if complex bar
&& s.bar_type != "[]")
|| s.bar_type == "]") {
// if (s.bar_type == "]")
// s.invis = true
//fixme:%%staves: cur_sy moved?
|
| ︙ | ︙ | |||
1462 1463 1464 1465 1466 1467 1468 |
}
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 = clone(s);
| | | | | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 |
}
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 = clone(s);
p_voice.bar_start.type = C.BAR;
p_voice.bar_start.bar_type = ""
delete p_voice.bar_start.text;
p_voice.bar_start.rbstart = 1
delete p_voice.bar_start.a_gch
}
if (s1.text)
xy_str(x + 4, y2 - gene.curfont.size - 3,
s1.text);
xypath(x, y2);
if (s1.rbstart == 2)
output += 'm0 20v-20';
output+= 'h' + w.toFixed(1)
if (s.rbstop == 2)
output += 'v20';
output += '"/>\n';
y_set(s1.st, true, x, w, y + 2)
if (s.rbstart)
s = s.prev
|
| ︙ | ︙ | |||
1580 1581 1582 1583 1584 1585 1586 | bot = staff_tb[i].botbar; if (minmax[i].ymin > bot - 4) minmax[i].ymin = bot - 4 top = staff_tb[i].topbar; if (minmax[i].ymax < top + 4) minmax[i].ymax = top + 4 } | | | | > < < < | | < < < < < | | | | | < | > < < | | | | > | < < | | | | < < < > > > | 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 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 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 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 |
bot = staff_tb[i].botbar;
if (minmax[i].ymin > bot - 4)
minmax[i].ymin = bot - 4
top = staff_tb[i].topbar;
if (minmax[i].ymax < top + 4)
minmax[i].ymax = top + 4
}
set_dscale(-1) /* restore the scale parameters */
for (s = first_gchord; s; s = s.ts_next) {
if (!s.a_gch)
continue
self.draw_gchord(s, minmax[s.st].ymin, minmax[s.st].ymax)
}
}
/* draw the repeat brackets */
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (p_voice.second || !p_voice.sym)
continue
draw_repbra(p_voice)
}
}
/* -- draw the measure bar numbers -- */
/* (scaled delayed output) */
function draw_measnb() {
var s, st, bar_num, x, y, w, any_nb, font_size, w0,
sy = cur_sy
/* search the top staff */
for (st = 0; st <= nstaff; st++) {
if (sy.st_print[st])
break
}
if (st > nstaff)
return /* no visible staff */
set_dscale(st)
/* leave the measure numbers as unscaled */
if (staff_tb[st].staffscale != 1) {
font_size = get_font("measure").size;
param_set_font("measurefont", "* " +
(font_size / staff_tb[st].staffscale).toString())
}
set_font("measure");
w0 = cwidf('0'); // (greatest) width of a number
s = tsfirst; /* clef */
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());
y_set(st, true, 0, 20, y + gene.curfont.size + 2)
} else if (bar_num % cfmt.measurenb == 0) {
for ( ; ; s = s.ts_next) {
if (!s.dur)
continue
break
}
while (s.st != st)
s = s.ts_next
// don't display the number twice
if (s.type != C.BAR || !s.bar_num) {
// if (s.prev && s.prev.type != C.CLEF)
// s = s.prev;
x = s.x - s.wl;
any_nb = true;
w = w0
if (bar_num >= 10)
w *= bar_num >= 100 ? 3 : 2
if (gene.curfont.box)
w += 4;
y = y_get(st, true, x, w)
if (y < staff_tb[st].topbar + 6)
y = staff_tb[st].topbar + 6;
y += 2;
xy_str(x, y, bar_num.toString())
if (gene.curfont.box) {
y += 2;
w += 3
}
y += gene.curfont.size;
y_set(st, true, x, w, y);
s.ymx = y
}
}
}
for ( ; s; s = s.ts_next) {
switch (s.type) {
case C.STAVES:
sy = s.sy
for (st = 0; st < nstaff; st++) {
if (sy.st_print[st])
break
}
set_dscale(st)
continue
default:
continue
case C.BAR:
if (!s.bar_num)
continue
break
}
bar_num = s.bar_num
if (cfmt.measurenb == 0
|| (bar_num % cfmt.measurenb) != 0
|| !s.next
|| s.bar_mrep)
continue
if (!any_nb)
any_nb = true;
w = w0
if (bar_num >= 10)
w *= bar_num >= 100 ? 3 : 2
x = s.x - w * .4;
y = y_get(st, true, x, w)
if (y < staff_tb[st].topbar + 3)
y = staff_tb[st].topbar + 3
if (s.next.type == C.NOTE) {
if (s.next.stem > 0) {
if (y < s.next.ys - gene.curfont.size)
y = s.next.ys - gene.curfont.size
} else {
if (y < s.next.y)
y = s.next.y
}
}
y += 2;
if (gene.curfont.box) {
y += 2;
w += 3
}
xy_str(x, y, bar_num.toString())
y += gene.curfont.size;
if (gene.curfont.box)
y += 2;
y_set(st, true, x, w, y);
s.ymx = y
}
gene.nbar = bar_num
if (font_size)
param_set_font("measurefont", "* " + font_size.toString());
|
| ︙ | ︙ | |||
1753 1754 1755 1756 1757 1758 1759 |
// // protection against end of container
// if (stv_g.started) {
// output += "</g>\n";
// stv_g.started = false
// }
out_XYAB('<g transform="translate(X,Y) scale(F)">\n',
| | | | | | | | | < | < | < | | < | | | > > > > | | < < < | < < | < < < | | < < < | | > > | > > | | > > > > > > > > | | > > | | | | | > > | < < < | | 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 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 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 |
// // protection against end of container
// if (stv_g.started) {
// output += "</g>\n";
// stv_g.started = false
// }
out_XYAB('<g transform="translate(X,Y) scale(F)">\n',
x + 4, y + 4, sc)
switch (head) {
case C.OVAL:
p = "HD"
break
case C.EMPTY:
p = "Hd"
break
default:
p = "hd"
break
}
xygl(-posx, posy, p);
dx = 4
if (dots) {
dotx = 9
if (nflags > 0)
dotx += 4
switch (head) {
case C.SQUARE:
dotx += 3
break
case C.OVALBARS:
case C.OVAL:
dotx += 2
break
case C.EMPTY:
dotx += 1
break
}
dx = dotx * dots;
dotx -= posx
while (--dots >= 0) {
xygl(dotx, posy, "dot");
dotx += 3.5
}
}
if (dur < C.BLEN) {
if (nflags <= 0) {
out_stem(-posx, posy, 21) // stem height
} else {
out_stem(-posx, posy, 21, false, nflags)
if (dx < 6)
dx = 6
}
}
output += '</g>\n'
return (dx + 15) * sc
}
/* -- estimate the tempo width -- */
function tempo_width(s) {
var w = 0;
if (s.tempo_wh1)
w = s.tempo_wh1[0]
if (s.tempo_wh0)
w += s.tempo_wh0[0]
if (s.tempo_wh2)
w += s.tempo_wh2[0]
return w
}
/* - output a tempo --*/
function write_tempo(s, x, y) {
var j, dx, bx, bh,
sc = .6 * gene.curfont.size / 15.0; //fixme: 15.0 = initial tempofont
set_font("tempo")
if (gene.curfont.box) {
gene.curfont.box = false
bx = x
}
if (s.tempo_str1) {
xy_str(x, y, s.tempo_str1, null, null, s.tempo_wh1);
x += s.tempo_wh1[0] + 3
}
if (s.tempo_notes) {
for (j = 0; j < s.tempo_notes.length; j++)
x += draw_notempo(s, x, y, s.tempo_notes[j], sc);
xy_str(x, y, s.tempo_str0, null, null, s.tempo_wh0);
x += s.tempo_wh0[0]
if (s.tempo)
x += 5
else
x += draw_notempo(s, x, y, s.new_beat, sc)
}
if (s.tempo_str2)
xy_str(x, y, s.tempo_str2, null, null, s.tempo_wh2)
if (bx) {
gene.curfont.box = true
if (s.tempo_str2)
x += s.tempo_wh2[0] + 3;
bh = gene.curfont.size + 4;
output += '<rect class="stroke" x="';
out_sxsy(bx - 2, '" y="', y + bh - 1);
output += '" width="' + (x - bx + 2).toFixed(1) +
'" height="' + bh.toFixed(1) +
'"/>\n'
}
// don't display anymore
s.del = true
}
/* -- draw the parts and the tempo information -- */
/* (the staves are being defined) */
function draw_partempo(st, top) {
var s, some_part, some_tempo, h, w, y,
dy = 0, /* put the tempo indication at top */
ht = 0
/* get the minimal y offset */
var ymin = staff_tb[st].topbar + 8,
dosh = 0,
shift = 1,
x = -100 // (must be negative for %%soloffs)
for (s = tsfirst; s; s = s.ts_next) {
if (s.type != C.TEMPO || s.del)
continue
if (!some_tempo)
some_tempo = s;
w = tempo_width(s);
if (s.time == 0 && s.x > 40) // at start of tune and no %%soloffs,
s.x = 40; // shift the tempo over the key signature
y = y_get(st, true, s.x - 16, w)
if (y > ymin)
ymin = y
if (x >= s.x - 16 && !(dosh & (shift >> 1)))
dosh |= shift;
shift <<= 1;
x = s.x - 16 + w
}
if (some_tempo) {
set_sscale(-1);
set_font("tempo");
ht = gene.curfont.size + 2;
y = 2 - ht;
h = y - ht
if (dosh != 0)
ht *= 2
if (top < ymin + ht)
dy = ymin + ht - top
/* draw the tempo indications */
for (s = some_tempo; s; s = s.ts_next) {
if (s.type != C.TEMPO
|| s.del) // (displayed by %%titleformat)
continue
if (user.anno_start || user.anno_stop) {
s.wl = 16;
s.wr = 30;
s.ymn = (dosh & 1) ? h : y;
s.ymx = s.ymn + 14;
anno_start(s)
}
write_tempo(s, s.x - 16, (dosh & 1) ? h : y);
anno_stop(s);
dosh >>= 1
}
}
/* 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) {
if (s.type != C.PART)
continue
if (!some_part) {
some_part = s;
set_font("parts");
h = gene.curfont.size + 2
/* + cfmt.partsspace ?? */
}
w = strwh(s.text)[0];
y = y_get(st, true, s.x - 10, w + 3)
if (ymin < y)
ymin = y
}
if (some_part) {
set_sscale(-1)
if (gene.curfont.box)
h += 2
if (top < ymin + h + ht)
dy = ymin + h + ht - top
for (s = some_part; s; s = s.ts_next) {
if (s.type != C.PART)
continue
s.x -= 10;
if (user.anno_start || user.anno_stop) {
w = strwh(s.text)[0];
s.wl = 0;
s.wr = w;
s.ymn = -ht - h;
s.ymx = s.ymn + h;
anno_start(s)
}
xy_str(s.x, 2 - ht - h, s.text);
anno_stop(s)
}
}
return dy
}
|
Changes to core/draw.js.
1 2 | // abc2svg - draw.js - draw functions // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - draw.js - draw functions // // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
89 90 91 92 93 94 95 96 |
var min_tb = [
[STEM_MIN, STEM_MIN,
STEM_MIN2, STEM_MIN3, STEM_MIN4, STEM_MIN4],
[STEM_CH_MIN, STEM_CH_MIN,
STEM_CH_MIN2, STEM_CH_MIN3, STEM_CH_MIN4, STEM_CH_MIN4]
]
function calculate_beam(bm, s1) {
| > | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
var min_tb = [
[STEM_MIN, STEM_MIN,
STEM_MIN2, STEM_MIN3, STEM_MIN4, STEM_MIN4],
[STEM_CH_MIN, STEM_CH_MIN,
STEM_CH_MIN2, STEM_CH_MIN3, STEM_CH_MIN4, STEM_CH_MIN4]
]
// (possible hook)
function calculate_beam(bm, s1) {
var s, s2, g, notes, nflags, st, v, two_staves, two_dir,
x, y, ys, a, b, stem_err, max_stem_err,
p_min, p_max, s_closest,
stem_xoff, scale,
visible, dy
if (!s1.beam_st) { /* beam from previous music line */
s = sym_dup(s1);
|
| ︙ | ︙ | |||
118 119 120 121 122 123 124 |
/* search last note in beam */
notes = nflags = 0; /* set x positions, count notes and flags */
two_staves = two_dir = false;
st = s1.st;
v = s1.v;
stem_xoff = s1.grace ? GSTEM_XOFF : 3.5
for (s2 = s1; ;s2 = s2.next) {
| | | | 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 |
/* search last note in beam */
notes = nflags = 0; /* set x positions, count notes and flags */
two_staves = two_dir = false;
st = s1.st;
v = s1.v;
stem_xoff = s1.grace ? GSTEM_XOFF : 3.5
for (s2 = s1; ;s2 = s2.next) {
if (s2.type == C.NOTE) {
if (s2.nflags > nflags)
nflags = s2.nflags;
notes++
if (s2.st != st)
two_staves = true
if (s2.stem != s1.stem)
two_dir = true
if (!visible && !s2.invis
&& (!s2.stemless || s2.trem2))
visible = true
if (s2.beam_end)
break
}
if (!s2.next) { /* beam towards next music line */
for (; ; s2 = s2.prev) {
if (s2.type == C.NOTE)
break
}
s = sym_dup(s2);
s.next = s2.next
if (s.next)
s.next.prev = s;
s2.next = s;
|
| ︙ | ︙ | |||
175 176 177 178 179 180 181 |
if (staff_tb[st].y == 0) { /* staves not defined */
if (two_staves)
return false
} else { /* staves defined */
// if (!two_staves && !s1.grace) {
if (!two_staves) {
bm.s1 = s1; /* beam already calculated */
| | | | 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 |
if (staff_tb[st].y == 0) { /* staves not defined */
if (two_staves)
return false
} else { /* staves defined */
// if (!two_staves && !s1.grace) {
if (!two_staves) {
bm.s1 = s1; /* beam already calculated */
bm.a = (s1.ys - s2.ys) / (s1.xs - s2.xs);
bm.b = s1.ys - s1.xs * bm.a + staff_tb[st].y;
bm.nflags = nflags
return true
}
}
s_closest = s1;
p_min = 100;
p_max = 0
for (s = s1; ; s = s.next) {
if (s.type != C.NOTE)
continue
if ((scale = s.p_v.scale) == 1)
scale = staff_tb[s.st].staffscale
if (s.stem >= 0) {
x = stem_xoff + s.notes[0].shhd
if (s.notes[s.nhd].pit > p_max) {
p_max = s.notes[s.nhd].pit;
|
| ︙ | ︙ | |||
229 230 231 232 233 234 235 |
if (a != 0) {
if (a > 0)
a = BEAM_SLOPE * a / (BEAM_SLOPE + a) // max steepness for beam
else
a = BEAM_SLOPE * a / (BEAM_SLOPE - a);
}
| > | | < | | | | 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 |
if (a != 0) {
if (a > 0)
a = BEAM_SLOPE * a / (BEAM_SLOPE + a) // max steepness for beam
else
a = BEAM_SLOPE * a / (BEAM_SLOPE - a);
}
// pivot around the middle of the beam
b = (y + s2.ys + staff_tb[s2.st].y) / 2 - a * (s2.xs + s1.xs) / 2
/*fixme: have a look again*/
/* 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.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
&& s.ts_prev.type == C.NOTE
&& s.ts_prev.time == s.time
&& s.ts_prev.x > s1.xs)
s = s.ts_prev
for (; s && s.time <= s2.time; s = s.ts_next) {
if (s.type != C.NOTE
|| s.invis
|| (s.st != st
&& s.v != v)) {
continue
}
x = s.v == v ? s.xs : s.x;
ys = a * x + b - staff_tb[s.st].y
|
| ︙ | ︙ | |||
336 337 338 339 340 341 342 |
if (max_stem_err > 0) /* shift beam if stems too short */
b += s1.stem * max_stem_err
/* have room for the gracenotes, bars and clefs */
/*fixme: test*/
if (!two_staves && !two_dir)
for (s = s1.next; ; s = s.next) {
| < | | | | | | 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 |
if (max_stem_err > 0) /* shift beam if stems too short */
b += s1.stem * max_stem_err
/* 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 */
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*/
case C.BAR:
if (s.invis)
break
/*fall thru*/
case C.CLEF:
y = a * s.x + b
if (s1.stem > 0) {
y = s.ymx - y
+ BEAM_DEPTH + BEAM_SHIFT * (nflags - 1)
+ 2
if (y > 0)
b += y
} else {
y = s.ymn - y
- BEAM_DEPTH - BEAM_SHIFT * (nflags - 1)
- 2
if (y < 0)
b += y
}
break
case C.GRACE:
for (g = s.extra; g; g = g.next) {
y = a * g.x + b
if (s1.stem > 0) {
y = g.ymx - y
+ BEAM_DEPTH + BEAM_SHIFT * (nflags - 1)
+ 2
if (y > 0)
|
| ︙ | ︙ | |||
395 396 397 398 399 400 401 |
if (a == 0) /* shift flat beams onto staff lines */
b += b_pos(s1.grace, s1.stem, nflags, b - staff_tb[st].y)
/* adjust final stems and rests under beam */
for (s = s1; ; s = s.next) {
switch (s.type) {
| | | | | | 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 |
if (a == 0) /* shift flat beams onto staff lines */
b += b_pos(s1.grace, s1.stem, nflags, b - staff_tb[st].y)
/* adjust final stems and rests under beam */
for (s = s1; ; s = s.next) {
switch (s.type) {
case C.NOTE:
s.ys = a * s.xs + b - staff_tb[s.st].y
if (s.stem > 0) {
s.ymx = s.ys + 2.5
//fixme: hack
if (s.ts_prev
&& s.ts_prev.stem > 0
&& s.ts_prev.st == s.st
&& s.ts_prev.ymn < s.ymx
&& s.ts_prev.x == s.x
&& s.notes[0].shhd == 0) {
s.ts_prev.x -= 3; /* fix stem clash */
s.ts_prev.xs -= 3
}
} else {
s.ymn = s.ys - 2.5
}
break
case C.REST:
y = a * s.x + b - staff_tb[s.st].y
dy = BEAM_DEPTH + BEAM_SHIFT * (nflags - 1)
+ (s.head != C.FULL ? 4 : 9)
if (s1.stem > 0) {
y -= dy
if (s1.multi == 0 && y > 12)
y = 12
if (s.y <= y)
break
} else {
y += dy
if (s1.multi == 0 && y < 12)
y = 12
if (s.y >= y)
break
}
if (s.head != C.FULL)
y = (((y + 3 + 12) / 6) | 0) * 6 - 12;
s.y = y
break
}
if (s == s2)
break
}
|
| ︙ | ︙ | |||
467 468 469 470 471 472 473 |
var y1, dy2,
s = bm.s1,
nflags = s.nflags
if (s.ntrem)
nflags -= s.ntrem
if (s.trem2 && n > nflags) {
| | | | | | | 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 |
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) {
x1 += 5;
x2 -= 6
}
}
y1 = bm.a * x1 + bm.b - dy;
x2 -= x1;
//--fixme: scale (bm.a already scaled!)
x2 /= stv_g.scale;
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()
anno_start(s1, 'beam')
/*fixme: KO if many staves with different scales*/
// set_scale(s1)
if (!s1.grace) {
|
| ︙ | ︙ | |||
515 516 517 518 519 520 521 |
if (beam_dir < 0)
bh = -bh;
/* make first beam over whole word and adjust the stem lengths */
draw_beam(s1.xs - shift, s2.xs + shift, 0, bh, bm, 1);
da = 0
for (s = s1; ; s = s.next) {
| | | 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 |
if (beam_dir < 0)
bh = -bh;
/* make first beam over whole word and adjust the stem lengths */
draw_beam(s1.xs - shift, s2.xs + shift, 0, bh, bm, 1);
da = 0
for (s = s1; ; s = s.next) {
if (s.type == C.NOTE
&& s.stem != beam_dir)
s.ys = bm.a * s.xs + bm.b
- staff_tb[s.st].y
+ bshift * (s.nflags - 1) * s.stem
- bh
if (s == s2)
break
|
| ︙ | ︙ | |||
543 544 545 546 547 548 549 |
/* other beams with two or more flags */
shift = 0
for (i = 2; i <= bm.nflags; i++) {
shift += bshift
if (da != 0)
bm.a += da
for (s = s1; ; s = s.next) {
| | | | | | | | 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 605 606 607 608 609 610 611 612 613 |
/* other beams with two or more flags */
shift = 0
for (i = 2; i <= bm.nflags; i++) {
shift += bshift
if (da != 0)
bm.a += da
for (s = s1; ; s = s.next) {
if (s.type != C.NOTE
|| s.nflags < i) {
if (s == s2)
break
continue
}
if (s.trem1
&& i > s.nflags - s.ntrem) {
x1 = (s.dur >= C.BLEN / 2) ? s.x : s.xs;
draw_beam(x1 - 5, x1 + 5,
(shift + 2.5) * beam_dir,
bh, bm, i)
if (s == s2)
break
continue
}
k1 = s
while (1) {
if (s == s2)
break
k = s.next
if (k.type == C.NOTE || k.type == C.REST) {
if (k.trem1){
if (k.nflags - k.ntrem < i)
break
} else if (k.nflags < i) {
break
}
}
if (k.beam_br1
|| (k.beam_br2 && i > 2))
break
s = k
}
k2 = s
while (k2.type != C.NOTE)
k2 = k2.prev;
x1 = k1.xs
if (k1 == k2) {
if (k1 == s1) {
x1 += bstub
} else if (k1 == s2) {
x1 -= bstub
} else if (k1.beam_br1
|| (k1.beam_br2
&& i > 2)) {
x1 += bstub
} else {
k = k1.next
while (k.type != C.NOTE)
k = k.next
if (k.beam_br1
|| (k.beam_br2 && i > 2)) {
x1 -= bstub
} else {
k1 = k1.prev
while (k1.type != C.NOTE)
k1 = k1.prev
if (k1.nflags < k.nflags
|| (k1.nflags == k.nflags
&& k1.dots < k.dots))
x1 += bstub
else
x1 -= bstub
|
| ︙ | ︙ | |||
678 679 680 681 682 683 684 | break } if (i == j && l == 0) return yb = staff_tb[j].y + staff_tb[j].botbar * staff_tb[j].staffscale; h = staff_tb[i].y + staff_tb[i].topbar * staff_tb[i].staffscale - yb; xypath(x, yb); | | | < | < | < < < < | | < < < < < < < < < < < < < < < < | | < | < < < | 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 |
break
}
if (i == j && l == 0)
return
yb = staff_tb[j].y + staff_tb[j].botbar * staff_tb[j].staffscale;
h = staff_tb[i].y + staff_tb[i].topbar * staff_tb[i].staffscale - yb;
xypath(x, yb);
output += "v" + (-h).toFixed(1) + '"/>\n'
for (i = 0; i <= nst; i++) {
if (cur_sy.staves[i].flags & OPEN_BRACE)
draw_sysbra(x, i, CLOSE_BRACE)
if (cur_sy.staves[i].flags & OPEN_BRACKET)
draw_sysbra(x, i, CLOSE_BRACKET)
if (cur_sy.staves[i].flags & OPEN_BRACE2)
draw_sysbra(x - 6, i, CLOSE_BRACE2)
if (cur_sy.staves[i].flags & OPEN_BRACKET2)
draw_sysbra(x - 6, i, CLOSE_BRACKET2)
}
}
/* -- draw the time signature -- */
function draw_meter(x, s) {
if (!s.a_meter)
return
var dx, i, j, meter,
st = s.st,
p_staff = staff_tb[st],
y = p_staff.y;
// adjust the vertical offset according to the staff definition
if (p_staff.stafflines != '|||||')
y += (p_staff.topbar + p_staff.botbar) / 2 - 12 // bottom
for (i = 0; i < s.a_meter.length; i++) {
meter = s.a_meter[i];
x = s.x + s.x_meter[i]
if (meter.bot) {
out_XYAB('\
<g transform="translate(X,Y)" text-anchor="middle">\n\
<text y="-12">A</text>\n\
<text>B</text>\n\
</g>\n', x, y + 6, m_gl(meter.top), m_gl(meter.bot))
} else {
out_XYAB('\
<text x="X" y="Y" text-anchor="middle">A</text>\n',
x, y + 12, m_gl(meter.top))
}
}
}
/* -- draw an accidental -- */
function draw_acc(x, y, acc,
micro_n,
micro_d) {
|
| ︙ | ︙ | |||
810 811 812 813 814 815 816 | var sharp_cl = new Int8Array([24, 9, 15, 21, 6, 12, 18]), flat_cl = new Int8Array([12, 18, 24, 9, 15, 21, 6]), sharp1 = new Int8Array([-9, 12, -9, -9, 12, -9]), sharp2 = new Int8Array([12, -9, 12, -9, 12, -9]), flat1 = new Int8Array([9, -12, 9, -12, 9, -12]), flat2 = new Int8Array([-12, 9, -12, 9, -12, 9]) | | | | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 |
var sharp_cl = new Int8Array([24, 9, 15, 21, 6, 12, 18]),
flat_cl = new Int8Array([12, 18, 24, 9, 15, 21, 6]),
sharp1 = new Int8Array([-9, 12, -9, -9, 12, -9]),
sharp2 = new Int8Array([12, -9, 12, -9, 12, -9]),
flat1 = new Int8Array([9, -12, 9, -12, 9, -12]),
flat2 = new Int8Array([-12, 9, -12, 9, -12, 9])
function draw_keysig(x, s) {
if (s.k_none)
return
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
if (clef_ix & 1)
clef_ix += 7;
clef_ix /= 2
|
| ︙ | ︙ | |||
938 939 940 941 942 943 944 | return "[" + bar_type /* |::: -> [|::: */ case ":|": case "::|": case ":::|": return bar_type + "]" /* :..| -> :..|] */ case "::": return cfmt.dblrepbar /* :: -> double repeat bar */ | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < | 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 |
return "[" + bar_type /* |::: -> [|::: */
case ":|":
case "::|":
case ":::|":
return bar_type + "]" /* :..| -> :..|] */
case "::":
return cfmt.dblrepbar /* :: -> double repeat bar */
}
return bar_type
}
/* -- draw a rest -- */
/* (the staves are defined) */
var rest_tb = [
"r128", "r64", "r32", "r16", "r8",
"r4",
"r2", "r1", "r0", "r00"]
function draw_rest(s) {
var s2, i, j, x, y, dotx, yb, yt, head, bx,
p_staff = staff_tb[s.st]
/* if rest alone in the measure or measure repeat, center */
if (s.dur == s.p_v.meter.wmeasure
|| (s.rep_nb && s.rep_nb >= 0)) {
/* don't use next/prev: there is no bar in voice overlay */
s2 = s.ts_next
while (s2 && s2.time != s.time + s.dur)
|
| ︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 | x = s.x if (s.notes[0].shhd) x += s.notes[0].shhd * stv_g.scale } if (s.invis) return | | > | > > | | > > > > | > > | | | > | | | | | > | | 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 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 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 |
x = s.x
if (s.notes[0].shhd)
x += s.notes[0].shhd * stv_g.scale
}
if (s.invis)
return
yb = p_staff.y // bottom of staff
if (s.rep_nb) {
set_sscale(s.st);
anno_start(s);
if (p_staff.stafflines == '|||||')
yb += 12
else
yb += (p_staff.topbar + p_staff.botbar) / 2
if (s.rep_nb < 0) {
xygl(x, yb, "srep")
} else {
xygl(x, yb, "mrep")
if (s.rep_nb > 2 && s.v == cur_sy.top_voice) {
set_font("annotation");
if (gene.curfont.box) {
gene.curfont.box = false;
bx = true
}
xy_str(x, yb + p_staff.topbar - 9,
s.rep_nb.toString(), "c")
if (bx)
gene.curfont.box = true
}
}
anno_stop(s)
return
}
set_scale(s);
anno_start(s);
y = s.y;
i = 5 - s.nflags /* rest_tb index (5 = C_XFLAGS) */
if (i == 7 && y == 12
&& p_staff.stafflines.length <= 2)
y -= 6 /* semibreve a bit lower */
// draw the rest
xygl(x, y + yb, s.notes[0].head ? s.notes[0].head : rest_tb[i])
/* output ledger line(s) when greater than minim */
if (i >= 6) {
j = y / 6
switch (i) {
default:
switch (p_staff.stafflines[j + 1]) {
case '|':
case '[':
break
default:
xygl(x, y + 6 + yb, "hl1")
break
}
if (i == 9) { /* longa */
y -= 6;
j--
}
break
case 7: /* semibreve */
y += 6;
j++
case 6: /* minim */
break
}
switch (p_staff.stafflines[j]) {
case '|':
case '[':
break
default:
xygl(x, y + yb, "hl1")
break
}
}
if (s.dots) {
x += 8;
y += yb + 3
for (i = 0; i < s.dots; i++) {
xygl(x, y, "dot");
x += 3.5
}
}
anno_stop(s)
}
/* -- draw grace notes -- */
/* (the staves are defined) */
function draw_gracenotes(s) {
var yy, x0, y0, x1, y1, x2, y2, x3, y3, bet1, bet2,
dy1, dy2, g, last, note,
bm = {}
/* draw the notes */
// bm.s2 = undefined /* (draw flags) */
for (g = s.extra; g; g = g.next) {
if (g.beam_st && !g.beam_end) {
if (self.calculate_beam(bm, g))
draw_beams(bm)
}
anno_start(g);
draw_note(g, !bm.s2)
if (g == bm.s2)
bm.s2 = null /* (draw flags again) */
anno_stop(g)
|
| ︙ | ︙ | |||
1175 1176 1177 1178 1179 1180 1181 | /* slur */ //fixme: have a full key symbol in voice if (s.p_v.key.k_bagpipe /* no slur when bagpipe */ || !cfmt.graceslurs || s.slur_start /* explicit slur */ || !s.next | | | 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 |
/* slur */
//fixme: have a full key symbol in voice
if (s.p_v.key.k_bagpipe /* no slur when bagpipe */
|| !cfmt.graceslurs
|| s.slur_start /* explicit slur */
|| !s.next
|| s.next.type != C.NOTE)
return
last = g
if (last.stem >= 0) {
yy = 127
for (g = s.extra; g; g = g.next) {
if (g.y < yy) {
yy = g.y;
|
| ︙ | ︙ | |||
1263 1264 1265 1266 1267 1268 1269 | x1 = bet1 * x3 + (1 - bet1) * x0 - x0; y1 = bet1 * y3 + (1 - bet1) * y0 - dy1 - y0; x2 = bet2 * x3 + (1 - bet2) * x0 - x0; y2 = bet2 * y3 + (1 - bet2) * y0 - dy2 - y0; anno_start(s, 'slur'); xypath(x0, y0 + staff_tb[s.st].y); | | | | | 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 |
x1 = bet1 * x3 + (1 - bet1) * x0 - x0;
y1 = bet1 * y3 + (1 - bet1) * y0 - dy1 - y0;
x2 = bet2 * x3 + (1 - bet2) * x0 - x0;
y2 = bet2 * y3 + (1 - bet2) * y0 - dy2 - y0;
anno_start(s, 'slur');
xypath(x0, y0 + staff_tb[s.st].y);
output += 'c' + x1.toFixed(1) + ' ' + (-y1).toFixed(1) +
' ' + x2.toFixed(1) + ' ' + (-y2).toFixed(1) +
' ' + (x3 - x0).toFixed(1) + ' ' + (-y3 + y0).toFixed(1) + '"/>\n';
anno_stop(s, 'slur')
}
/* -- set the y offset of the dots -- */
function setdoty(s, y_tb) {
var m, m1, y
|
| ︙ | ︙ | |||
1307 1308 1309 1310 1311 1312 1313 |
}
}
}
// get the x and y position of a note head
// (when the staves are defined)
function x_head(s, note) {
| | | | 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 |
}
}
}
// get the x and y position of a note head
// (when the staves are defined)
function x_head(s, note) {
return s.x + note.shhd * stv_g.scale
}
function y_head(s, note) {
return staff_tb[s.st].y + 3 * (note.pit - 18)
}
/* -- draw m-th head with accidentals and dots -- */
/* (the staves are defined) */
// sets {x,y}_note
function draw_basic_note(x, s, m, y_tb) {
var i, k, p, yy, dotx, doty, inv,
old_color = false,
note = s.notes[m],
staffb = staff_tb[s.st].y, /* bottom of staff */
y = 3 * (note.pit - 18), /* note height on staff */
shhd = note.shhd * stv_g.scale,
x_note = x + shhd,
y_note = y + staffb
|
| ︙ | ︙ | |||
1372 1373 1374 1375 1376 1377 1378 |
i = p.indexOf('/')
if (i >= 0) { // stem dependant
if (s.stem >= 0)
p = p.slice(0, i)
else
p = p.slice(i + 1)
}
| | | | | | > | > > > > | | | > > > > | > > | 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 |
i = p.indexOf('/')
if (i >= 0) { // stem dependant
if (s.stem >= 0)
p = p.slice(0, i)
else
p = p.slice(i + 1)
}
} else if (s.type == C.CUSTOS) {
p = "custos"
} else {
switch (head) {
case C.OVAL:
p = "HD"
break
case C.OVALBARS:
if (s.head != C.SQUARE) {
p = "HDD"
break
}
// fall thru
case C.SQUARE:
if (nflags > -4) {
p = "breve"
} else {
p = "longa"
inv = s.stem > 0
}
/* don't display dots on last note of the tune */
if (!tsnext && s.next
&& s.next.type == C.BAR && !s.next.next)
dots = 0
break
case C.EMPTY:
p = "Hd" // white note
break
default: // black note
p = "hd"
break
}
}
if (note.color != undefined)
old_color = set_color(note.color)
else if (note.map && note.map[2])
old_color = set_color(note.map[2])
if (p) {
if (inv) {
g_open(x_note, y_note, 0, 1, -1);
x_note = y_note = 0
}
if (!self.psxygl(x_note, y_note, p))
xygl(x_note, y_note, p)
if (inv)
g_close()
}
/* draw the dots */
/*fixme: to see for grace notes*/
if (dots) {
dotx = x + (7.7 + s.xmx) * stv_g.scale
if (y_tb[m] == undefined) {
|
| ︙ | ︙ | |||
1447 1448 1449 1450 1451 1452 1453 |
}
/* -- draw a note or a chord -- */
/* (the staves are defined) */
function draw_note(s,
fl) { // draw flags
var s2, i, m, y, staffb, slen, c, hltype, nflags,
| | | < < | | | | > | > | | | 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 |
}
/* -- draw a note or a chord -- */
/* (the staves are defined) */
function draw_note(s,
fl) { // draw flags
var s2, i, m, y, staffb, slen, c, hltype, nflags,
x, y, note, x_hl,
y_tb = new Array(s.nhd + 1)
if (s.dots)
setdoty(s, y_tb)
note = s.notes[s.stem < 0 ? s.nhd : 0]; // master note head
x_hl = x = x_head(s, note);
staffb = staff_tb[s.st].y
/* output the ledger lines */
if (s.grace) {
hltype = "ghl"
} else {
hltype = "hl"
switch (s.head) {
case C.OVALBARS:
case C.OVAL:
x_hl = x - .3;
hltype = "hl1"
break
case C.SQUARE:
x_hl = x - 2;
hltype = "hl1"
break
}
}
draw_hl(x_hl, 3 * (s.notes[0].pit - 18), 3 * (s.notes[s.nhd].pit - 18),
s.st, hltype)
/* draw the stem and flags */
y = y_head(s, note)
if (!s.stemless) {
slen = s.ys - s.y;
nflags = s.nflags
|
| ︙ | ︙ | |||
1510 1511 1512 1513 1514 1515 1516 |
}
/* draw the tremolo bars */
if (fl && s.trem1) {
var ntrem = s.ntrem || 0,
x1 = x;
slen = 3 * (s.notes[s.stem > 0 ? s.nhd : 0].pit - 18)
| | | 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 |
}
/* draw the tremolo bars */
if (fl && s.trem1) {
var ntrem = s.ntrem || 0,
x1 = x;
slen = 3 * (s.notes[s.stem > 0 ? s.nhd : 0].pit - 18)
if (s.head == C.FULL || s.head == C.EMPTY) {
x1 += (s.grace ? GSTEM_XOFF : 3.5) * s.stem
if (s.stem > 0)
slen += 6 + 5.4 * ntrem
else
slen -= 6 + 5.4
} else {
if (s.stem > 0)
|
| ︙ | ︙ | |||
1554 1555 1556 1557 1558 1559 1560 | s = s.prev if (s.rbstart) return s } /* return a symbol of any voice starting before the start of the voice */ s = s.p_v.sym | | | | | | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 |
s = s.prev
if (s.rbstart)
return s
}
/* return a symbol of any voice starting before the start of the voice */
s = s.p_v.sym
while (s.type != C.CLEF)
s = s.ts_prev /* search a main voice */
if (s.next && s.next.type == C.KEY)
s = s.next
if (s.next && s.next.type == C.METER)
return s.next
return s
}
/* -- decide whether a slur goes up or down -- */
function slur_direction(k1, k2) {
var s, some_upstem, low
if (k1.grace && k1.stem > 0)
return -1
for (s = k1; ; s = s.next) {
if (s.type == C.NOTE) {
if (!s.stemless) {
if (s.stem < 0)
return 1
some_upstem = true
}
if (s.notes[0].pit < 22) /* if under middle staff */
low = true
|
| ︙ | ︙ | |||
1646 1647 1648 1649 1650 1651 1652 | var scale_y = stv_g.v ? stv_g.scale : 1 if (!dotted) output += '<path class="fill" d="M' else output += '<path class="stroke" stroke-dasharray="5,5" d="M'; out_sxsy(x1, ' ', y1); output += 'c' + | | | | | | | | | | | | | | | 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 |
var scale_y = stv_g.v ? stv_g.scale : 1
if (!dotted)
output += '<path class="fill" d="M'
else
output += '<path class="stroke" stroke-dasharray="5,5" d="M';
out_sxsy(x1, ' ', y1);
output += 'c' +
((xx1 - x1) / stv_g.scale).toFixed(1) + ' ' +
((y1 - yy1) / scale_y).toFixed(1) + ' ' +
((xx2 - x1) / stv_g.scale).toFixed(1) + ' ' +
((y1 - yy2) / scale_y).toFixed(1) + ' ' +
((x2 - x1) / stv_g.scale).toFixed(1) + ' ' +
((y1 - y2) / scale_y).toFixed(1)
if (!dotted)
output += '\n\tv' +
(-dz).toFixed(1) + 'c' +
((xx2 - dx - x2) / stv_g.scale).toFixed(1) + ' ' +
((y2 + dz - yy2 - dy) / scale_y).toFixed(1) + ' ' +
((xx1 + dx - x2) / stv_g.scale).toFixed(1) + ' ' +
((y2 + dz - yy1 - dy) / scale_y).toFixed(1) + ' ' +
((x1 - x2) / stv_g.scale).toFixed(1) + ' ' +
((y2 + dz - y1) / scale_y).toFixed(1);
output += '"/>\n'
}
/* -- check if slur sequence in a multi-voice staff -- */
function slur_multi(k1, k2) {
while (1) {
if (k1.multi) /* if multi voice */
|
| ︙ | ︙ | |||
1691 1692 1693 1694 1695 1696 1697 |
k, g, x1, y1, x2, y2, height, addy,
a, y, z, h, dx, dy, dir
while (k1.v != k2.v)
k1 = k1.ts_next
/*fixme: if two staves, may have upper or lower slur*/
switch (slur_type & 0x07) { /* (ignore dotted flag) */
| | | > | | 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 |
k, g, x1, y1, x2, y2, height, addy,
a, y, z, h, dx, dy, dir
while (k1.v != k2.v)
k1 = k1.ts_next
/*fixme: if two staves, may have upper or lower slur*/
switch (slur_type & 0x07) { /* (ignore dotted flag) */
case C.SL_ABOVE: dir = 1; break
case C.SL_BELOW: dir = -1; break
default:
dir = slur_multi(k1, k2)
if (!dir)
dir = slur_direction(k1, k2)
break
}
var nn = 1,
upstaff = k1.st,
two_staves = false
set_dscale(k1.st)
if (k1 != k2) {
k = k1.next
while (1) {
if (k.type == C.NOTE || k.type == C.REST) {
nn++
if (k.st != upstaff) {
two_staves = true
if (k.st < upstaff)
upstaff = k.st
}
}
|
| ︙ | ︙ | |||
1734 1735 1736 1737 1738 1739 1740 |
if (k1_o != k2) {
x2 = k2.x
if (k2.notes)
x2 += k2.notes[0].shhd
} else { /* (the slur starts on last note of the line) */
for (k = k2.ts_next; k; k = k.ts_next)
//fixme: must check if the staff continues
| | | | 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 |
if (k1_o != k2) {
x2 = k2.x
if (k2.notes)
x2 += k2.notes[0].shhd
} else { /* (the slur starts on last note of the line) */
for (k = k2.ts_next; k; k = k.ts_next)
//fixme: must check if the staff continues
if (k.type == C.STAVES)
break
x2 = k ? k.x : realwidth
}
if (m1 >= 0) {
y1 = 3 * (k1.notes[m1].pit - 18) + 5 * dir
} else {
y1 = dir > 0 ? k1.ymx + 2 : k1.ymn - 2
if (k1.type == C.NOTE) {
if (dir > 0) {
if (k1.stem > 0) {
x1 += 5
if (k1.beam_end
&& k1.nflags >= -1 /* if with a stem */
//fixme: check if at end of tuplet
&& !k1.in_tuplet) {
|
| ︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 |
}
}
}
if (m2 >= 0) {
y2 = 3 * (k2.notes[m2].pit - 18) + 5 * dir
} else {
y2 = dir > 0 ? k2.ymx + 2 : k2.ymn - 2
| | | 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 |
}
}
}
if (m2 >= 0) {
y2 = 3 * (k2.notes[m2].pit - 18) + 5 * dir
} else {
y2 = dir > 0 ? k2.ymx + 2 : k2.ymn - 2
if (k2.type == C.NOTE) {
if (dir > 0) {
if (k2.stem > 0) {
x2 += 1
if (k2.beam_st
&& k2.nflags >= -1
&& !k2.in_tuplet)
// || k2.ys > y2 - 3))
|
| ︙ | ︙ | |||
1824 1825 1826 1827 1828 1829 1830 |
// } else {
// y2 = k2.y - 8
}
}
}
}
| | | | | | | 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 |
// } else {
// y2 = k2.y - 8
}
}
}
}
if (k1.type != C.NOTE) {
y1 = y2 + 1.2 * dir;
x1 = k1.x + k1.wr * .5
if (x1 > x2 - 12)
x1 = x2 - 12
}
if (k2.type != C.NOTE) {
if (k1.type == C.NOTE)
y2 = y1 + 1.2 * dir
else
y2 = y1
if (k1 != k2)
x2 = k2.x - k2.wl * .3
}
if (nn >= 3) {
if (k1.next.type != C.BAR
&& k1.next.x < x1 + 48) {
if (dir > 0) {
y = k1.next.ymx - 2
if (y1 < y)
y1 = y
} else {
y = k1.next.ymn + 2
if (y1 > y)
y1 = y
}
}
if (k2.prev
&& k2.prev.type != C.BAR
&& k2.prev.x > x2 - 48) {
if (dir > 0) {
y = k2.prev.ymx - 2
if (y2 < y)
y2 = y
} else {
y = k2.prev.ymn + 2
|
| ︙ | ︙ | |||
1911 1912 1913 1914 1915 1916 1917 |
if (k1 != k2
&& k1.v == k2.v) {
addy = y1 - a * x1
for (k = k1.next; k != k2 ; k = k.next) {
if (k.st != upstaff)
continue
switch (k.type) {
| | | | | 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 |
if (k1 != k2
&& k1.v == k2.v) {
addy = y1 - a * x1
for (k = k1.next; k != k2 ; k = k.next) {
if (k.st != upstaff)
continue
switch (k.type) {
case C.NOTE:
case C.REST:
if (dir > 0) {
y = 3 * (k.notes[k.nhd].pit - 18) + 6
if (y < k.ymx)
y = k.ymx;
y -= a * k.x + addy
if (y > h)
h = y
} else {
y = 3 * (k.notes[0].pit - 18) - 6
if (y > k.ymn)
y = k.ymn;
y -= a * k.x + addy
if (y < h)
h = y
}
break
case C.GRACE:
for (g = k.extra; g; g = g.next) {
if (dir > 0) {
y = 3 * (g.notes[g.nhd].pit - 18) + 6
if (y < g.ymx)
y = g.ymx;
y -= a * g.x + addy
if (y > h)
|
| ︙ | ︙ | |||
1984 1985 1986 1987 1988 1989 1990 |
} else {
if (height > -.8 * y)
height = -.8 * y
}
height *= cfmt.slurheight;
// anno_start(k1_o, 'slur');
| | | 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 |
} else {
if (height > -.8 * y)
height = -.8 * y
}
height *= cfmt.slurheight;
// anno_start(k1_o, 'slur');
slur_out(x1, y1, x2, y2, dir, height, slur_type & C.SL_DOTTED);
// anno_stop(k1_o, 'slur');
/* have room for other symbols */
dx = x2 - x1;
a = (y2 - y1) / dx;
/*fixme: it seems to work with .4, but why?*/
addy = y1 - a * x1 + .4 * height
|
| ︙ | ︙ | |||
2013 2014 2015 2016 2017 2018 2019 | dx = k.next.x } if (k != k1) x1 = k.x; dx -= x1; y_set(upstaff, dir > 0, x1, dx, y) } | | | | | | | | | | | 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 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 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 |
dx = k.next.x
}
if (k != k1)
x1 = k.x;
dx -= x1;
y_set(upstaff, dir > 0, x1, dx, y)
}
return (dir > 0 ? C.SL_ABOVE : C.SL_BELOW) | (slur_type & C.SL_DOTTED)
}
/* -- draw the slurs between 2 symbols --*/
function draw_slurs(first, last) {
var s1, k, gr1, gr2, i, m1, m2, slur_type, cont,
s = first
while (1) {
if (!s || s == last) {
if (!gr1
|| !(s = gr1.next)
|| s == last)
break
gr1 = null
}
if (s.type == C.GRACE) {
gr1 = s;
s = s.extra
continue
}
if ((s.type != C.NOTE && s.type != C.REST
&& s.type != C.SPACE)
|| (!s.slur_start && !s.sl1)) {
s = s.next
continue
}
k = null; /* find matching slur end */
s1 = s.next
var gr1_out = false
while (1) {
if (!s1) {
if (gr2) {
s1 = gr2.next;
gr2 = null
continue
}
if (!gr1 || gr1_out)
break
s1 = gr1.next;
gr1_out = true
continue
}
if (s1.type == C.GRACE) {
gr2 = s1;
s1 = s1.extra
continue
}
if (s1.type == C.BAR
&& (s1.bar_type[0] == ':'
|| s1.bar_type == "|]"
|| s1.bar_type == "[|"
|| (s1.text && s1.text[0] != '1'))) {
k = s1
break
}
if (s1.type != C.NOTE && s1.type != C.REST
&& s1.type != C.SPACE) {
s1 = s1.next
continue
}
if (s1.slur_end || s1.sl2) {
k = s1
break
}
if (s1.slur_start || s1.sl1) {
if (gr2) { /* if in grace note sequence */
for (k = s1; k.next; k = k.next)
;
k.next = gr2.next
if (gr2.next)
gr2.next.prev = k;
// gr2.slur_start = C.SL_AUTO
k = null
}
draw_slurs(s1, last)
if (gr2
&& gr2.next) {
gr2.next.prev.next = null;
gr2.next.prev = gr2
|
| ︙ | ︙ | |||
2115 2116 2117 2118 2119 2120 2121 |
/* if slur in grace note sequence, change the linkages */
if (gr1) {
for (s1 = s; s1.next; s1 = s1.next)
;
s1.next = gr1.next
if (gr1.next)
gr1.next.prev = s1;
| | | | | | 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 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 |
/* if slur in grace note sequence, change the linkages */
if (gr1) {
for (s1 = s; s1.next; s1 = s1.next)
;
s1.next = gr1.next
if (gr1.next)
gr1.next.prev = s1;
gr1.slur_start = C.SL_AUTO
}
if (gr2) {
gr2.prev.next = gr2.extra;
gr2.extra.prev = gr2.prev;
gr2.slur_start = C.SL_AUTO
}
if (s.slur_start) {
slur_type = s.slur_start & 0x0f;
s.slur_start >>= 4;
m1 = -1
} else {
for (m1 = 0; m1 <= s.nhd; m1++)
if (s.notes[m1].sl1)
break
slur_type = s.notes[m1].sl1 & 0x0f;
s.notes[m1].sl1 >>= 4;
s.sl1--
}
m2 = -1;
cont = 0
if ((k.type == C.NOTE || k.type == C.REST || k.type == C.SPACE) &&
(k.slur_end || k.sl2)) {
if (k.slur_end) {
k.slur_end--
} else {
for (m2 = 0; m2 <= k.nhd; m2++)
if (k.notes[m2].sl2)
break
k.notes[m2].sl2--;
k.sl2--
}
} else {
if (k.type != C.BAR
|| (k.bar_type[0] != ':'
&& k.bar_type != "|]"
&& k.bar_type != "[|"
&& (!k.text || k.text[0] == '1')))
cont = 1
}
slur_type = draw_slur(s, k, m1, m2, slur_type)
|
| ︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 2202 |
lvl) { // nesting level
var s2, s3, g, upstaff, nb_only, some_slur,
x1, x2, y1, y2, xm, ym, a, s0, yy, yx, dy, a, b, dir,
p, q, r
// check if some slurs and treat the nested tuplets
upstaff = s1.st
for (s2 = s1; s2; s2 = s2.next) {
| > | | | 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 |
lvl) { // nesting level
var s2, s3, g, upstaff, nb_only, some_slur,
x1, x2, y1, y2, xm, ym, a, s0, yy, yx, dy, a, b, dir,
p, q, r
// check if some slurs and treat the nested tuplets
upstaff = s1.st
set_dscale(s1.st)
for (s2 = s1; s2; s2 = s2.next) {
if (s2.type != C.NOTE && s2.type != C.REST) {
if (s2.type == C.GRACE) {
for (g = s2.extra; g; g = g.next) {
if (g.slur_start || g.sl1)
some_slur = true
}
}
continue
}
|
| ︙ | ︙ | |||
2258 2259 2260 2261 2262 2263 2264 | s1.tp1 = 0 q = s1.tq1 } if (s1.tf[0] == 1) /* if 'when' == never */ return | | | | | | | | | | | | | 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 |
s1.tp1 = 0
q = s1.tq1
}
if (s1.tf[0] == 1) /* if 'when' == never */
return
dir = s1.tf[3] /* 'where' (C.SL_xxx) */
if (!dir)
dir = s1.stem > 0 ? C.SL_ABOVE : C.SL_BELOW
if (s1 == s2) { /* tuplet with 1 note (!) */
nb_only = true
} else if (s1.tf[1] == 1) { /* 'what' == slur */
nb_only = true;
draw_slur(s1, s2, -1, -1, dir)
} else {
/* search if a bracket is needed */
if (s1.tf[0] == 2 /* if 'when' == always */
|| s1.type != C.NOTE || s2.type != C.NOTE) {
nb_only = false
} else {
nb_only = true
for (s3 = s1; ; s3 = s3.next) {
if (s3.type != C.NOTE
&& s3.type != C.REST) {
if (s3.type == C.GRACE
|| s3.type == C.SPACE)
continue
nb_only = false
break
}
if (s3 == s2)
break
if (s3.beam_end) {
nb_only = false
break
}
}
if (nb_only
&& !s1.beam_st
&& !s1.beam_br1
&& !s1.beam_br2) {
for (s3 = s1.prev; s3; s3 = s3.prev) {
if (s3.type == C.NOTE
|| s3.type == C.REST) {
if (s3.nflags >= s1.nflags)
nb_only = false
break
}
}
}
if (nb_only && !s2.beam_end) {
for (s3 = s2.next; s3; s3 = s3.next) {
if (s3.type == C.NOTE
|| s3.type == C.REST) {
if (!s3.beam_br1
&& !s3.beam_br2
&& s3.nflags >= s2.nflags)
nb_only = false
break
}
}
|
| ︙ | ︙ | |||
2330 2331 2332 2333 2334 2335 2336 | xm = (s2.x + s1.x) / 2 if (s1 == s2) /* tuplet with 1 note */ a = 0 else a = (s2.ys - s1.ys) / (s2.x - s1.x); b = s1.ys - a * s1.x; yy = a * xm + b | | | 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 |
xm = (s2.x + s1.x) / 2
if (s1 == s2) /* tuplet with 1 note */
a = 0
else
a = (s2.ys - s1.ys) / (s2.x - s1.x);
b = s1.ys - a * s1.x;
yy = a * xm + b
if (dir == C.SL_ABOVE) {
ym = y_get(upstaff, 1, xm - 4, 8)
if (ym > yy)
b += ym - yy;
b += 2
} else {
ym = y_get(upstaff, 0, xm - 4, 8)
if (ym < yy)
|
| ︙ | ︙ | |||
2356 2357 2358 2359 2360 2361 2362 | xm -= 1.5 } ym = a * xm + b if (s1.tf[2] == 0) /* if 'which' == number */ out_bnum(xm, ym, p) else out_bnum(xm, ym, p + ':' + q) | | | | | 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 2316 2317 |
xm -= 1.5
}
ym = a * xm + b
if (s1.tf[2] == 0) /* if 'which' == number */
out_bnum(xm, ym, p)
else
out_bnum(xm, ym, p + ':' + q)
if (dir == C.SL_ABOVE) {
ym += 10
if (s3.ymx < ym)
s3.ymx = ym;
y_set(upstaff, true, xm - 3, 6, ym)
} else {
if (s3.ymn > ym)
s3.ymn = ym;
y_set(upstaff, false, xm - 3, 6, ym)
}
return
}
if (s1.tf[1] != 0) /* if 'what' != square */
error(2, s1, "'what' value of %%tuplets not yet coded")
/*fixme: two staves not treated*/
/*fixme: to optimize*/
dir = s1.tf[3] // 'where'
if (!dir)
dir = s1.multi >= 0 ? C.SL_ABOVE : C.SL_BELOW
if (dir == C.SL_ABOVE) {
/* sole or upper voice: the bracket is above the staff */
if (s1.st == s2.st) {
y1 = y2 = staff_tb[upstaff].topbar + 4
} else {
y1 = s1.ymx;
y2 = s2.ymx
|
| ︙ | ︙ | |||
2567 2568 2569 2570 2571 2572 2573 |
}
if (s3 == s2)
break
}
} /* lower voice */
if (s1.tf[2] == 1) { /* if 'which' == none */
| | | | | | 2493 2494 2495 2496 2497 2498 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 |
}
if (s3 == s2)
break
}
} /* lower voice */
if (s1.tf[2] == 1) { /* if 'which' == none */
out_tubr(x1, y1 + 4, x2 - x1, y2 - y1, dir == C.SL_ABOVE);
return
}
out_tubrn(x1, y1, x2 - x1, y2 - y1, dir == C.SL_ABOVE,
s1.tf[2] == 0 ? p.toString() : p + ':' + q);
yy = .5 * (y1 + y2)
if (dir == C.SL_ABOVE)
y_set(upstaff, true, xm - 3, 6, yy + 9)
else
y_set(upstaff, false, xm - 3, 6, yy)
}
/* -- draw the ties between two notes/chords -- */
function draw_note_ties(k1, k2, mhead1, mhead2, job) {
var i, dir, m1, m2, p, p2, y, st, k, x1, x2, h, sh, time
for (i = 0; i < mhead1.length; i++) {
m1 = mhead1[i];
p = k1.notes[m1].pit;
m2 = mhead2[i];
p2 = job != 2 ? k2.notes[m2].pit : p;
dir = (k1.notes[m1].ti1 & 0x07) == C.SL_ABOVE ? 1 : -1;
x1 = k1.x;
sh = k1.notes[m1].shhd /* head shift */
if (dir > 0) {
if (m1 < k1.nhd && p + 1 == k1.notes[m1 + 1].pit)
if (k1.notes[m1 + 1].shhd > sh)
sh = k1.notes[m1 + 1].shhd
|
| ︙ | ︙ | |||
2639 2640 2641 2642 2643 2644 2645 |
p = p2;
st = k2.st
break
/* case 2: * no ending note */
default:
if (k1 != k2) {
x2 -= k2.wl
| | | 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 |
p = p2;
st = k2.st
break
/* case 2: * no ending note */
default:
if (k1 != k2) {
x2 -= k2.wl
if (k2.type == C.BAR)
x2 += 5
} else {
time = k1.time + k1.dur
for (k = k1.ts_next; k; k = k.ts_next)
//(fixme: must check if the staff continues??)
if (k.time > time)
break
|
| ︙ | ︙ | |||
2662 2663 2664 2665 2666 2667 2668 |
x2 -= 3.5
} else {
x1 += 1.5;
x2 -= 1.5
}
y = 3 * (p - 18)
| < < < < < < < < < | | | 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 |
x2 -= 3.5
} else {
x1 += 1.5;
x2 -= 1.5
}
y = 3 * (p - 18)
h = (.04 * (x2 - x1) + 10) * dir;
// anno_start(k1, 'slur');
slur_out(x1, staff_tb[st].y + y,
x2, staff_tb[st].y + y,
dir, h, k1.notes[m1].ti1 & C.SL_DOTTED)
// anno_stop(k1, 'slur')
}
}
/* -- draw ties between neighboring notes/chords -- */
function draw_ties(k1, k2,
job) { // 0: normal
// 1: no starting note
// 2: no ending note
// 3: no start for clef or staff change
var k3, i, j, m1, pit, pit2, tie2,
mhead1 = [],
mhead2 = [],
mhead3 = [],
nh1 = k1.nhd,
time = k1.time + k1.dur
/* half ties from last note in line or before new repeat */
|
| ︙ | ︙ | |||
2709 2710 2711 2712 2713 2714 2715 |
}
/* set up list of ties to draw */
for (i = 0; i <= nh1; i++) {
if (!k1.notes[i].ti1)
continue
tie2 = -1;
| | | > | 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 |
}
/* set up list of ties to draw */
for (i = 0; i <= nh1; i++) {
if (!k1.notes[i].ti1)
continue
tie2 = -1;
pit = k1.notes[i].opit || k1.notes[i].pit
for (m1 = k2.nhd; m1 >= 0; m1--) {
pit2 = k2.notes[m1].opit || k2.notes[m1].pit
switch (pit2 - pit) {
case 1: /* maybe ^c - _d */
case -1: /* _d - ^c */
if (k1.notes[i].acc != k2.notes[m1].acc)
tie2 = m1
default:
continue
case 0:
|
| ︙ | ︙ | |||
2743 2744 2745 2746 2747 2748 2749 |
if (!mhead3.length)
return /* no bad tie */
k3 = k1.ts_next
while (k3 && k3.time < time)
k3 = k3.ts_next
while (k3 && k3.time == time) {
| | | > | | 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 |
if (!mhead3.length)
return /* no bad tie */
k3 = k1.ts_next
while (k3 && k3.time < time)
k3 = k3.ts_next
while (k3 && k3.time == time) {
if (k3.type != C.NOTE
|| k3.st != k1.st) {
k3 = k3.ts_next
continue
}
mhead1.length = 0;
mhead2.length = 0
for (i = mhead3.length; --i >= 0; ) {
j = mhead3[i];
pit = k1.notes[j].opit || k1.notes[j].pit
for (m1 = k3.nhd; m1 >= 0; m1--) {
pit2 = k3.notes[m1].opit || k3.notes[m1].pit
if (pit2 == pit) {
mhead1.push(j);
mhead2.push(m1);
mhead3[i] = mhead3.pop()
break
}
}
}
|
| ︙ | ︙ | |||
2786 2787 2788 2789 2790 2791 2792 |
time = s.time + s.dur;
st = s.st
for (s1 = s.ts_next; s1; s1 = s1.ts_next) {
if (s1.st != st)
continue
if (s1.time == time) {
| | | | | | | | | 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 |
time = s.time + s.dur;
st = s.st
for (s1 = s.ts_next; s1; s1 = s1.ts_next) {
if (s1.st != st)
continue
if (s1.time == time) {
if (s1.type == C.NOTE)
return s1
continue
}
if (s1.time > time)
return s // bad tie
}
return //null // no ending tie
}
/* -- draw all ties between neighboring notes -- */
function draw_all_ties(p_voice) {
var s1, s2, s3, clef_chg, time, s_rtie, s_tie, x, dx
function draw_ties_g(s1, s2, job) {
var g
if (s1.type == C.GRACE) {
for (g = s1.extra; g; g = g.next) {
if (g.ti1)
draw_ties(g, s2, job)
}
} else {
draw_ties(s1, s2, job)
}
} // draw_ties_g()
for (s1 = p_voice.sym; s1; s1 = s1.next) {
switch (s1.type) {
case C.CLEF:
case C.KEY:
case C.METER:
continue
}
break
}
s_rtie = p_voice.s_rtie /* tie from 1st repeat bar */
for (s2 = s1; s2; s2 = s2.next) {
if (s2.dur
|| s2.type == C.GRACE)
break
if (s2.type != C.BAR
|| !s2.text) // not a repeat bar
continue
if (s2.text[0] == '1') /* 1st repeat bar */
s_rtie = p_voice.s_tie
else
p_voice.s_tie = s_rtie
}
|
| ︙ | ︙ | |||
2855 2856 2857 2858 2859 2860 2861 |
// clef_chg = false
while (1) {
for (s1 = s2; s1; s1 = s1.next) {
if (s1.ti1)
break
if (!s_rtie)
continue
| | | | 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 |
// clef_chg = false
while (1) {
for (s1 = s2; s1; s1 = s1.next) {
if (s1.ti1)
break
if (!s_rtie)
continue
if (s1.type != C.BAR
|| !s1.text) // not a repeat bar
continue
if (s1.text[0] == '1') { /* 1st repeat bar */
s_rtie = null
continue
}
if (s1.bar_type == '|')
continue // not a repeat
for (s2 = s1.next; s2; s2 = s2.next)
if (s2.type == C.NOTE)
break
if (!s2) {
s1 = null
break
}
s_tie = clone(s_rtie);
s_tie.x = s1.x;
|
| ︙ | ︙ | |||
2887 2888 2889 2890 2891 2892 2893 |
/* search the end of the tie
* and notice the clef changes (may occur in an other voice) */
time = s1.time + s1.dur
for (s2 = s1.next; s2; s2 = s2.next) {
if (s2.dur)
break
| | | 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 |
/* search the end of the tie
* and notice the clef changes (may occur in an other voice) */
time = s1.time + s1.dur
for (s2 = s1.next; s2; s2 = s2.next) {
if (s2.dur)
break
if (s2.type == C.BAR && s2.text) { // repeat bar
if (s2.text[0] != '1')
break
s_rtie = s1 /* 1st repeat bar */
}
}
if (!s2) {
for (s2 = s1.ts_next; s2; s2 = s2.ts_next) {
|
| ︙ | ︙ | |||
2912 2913 2914 2915 2916 2917 2918 |
}
if (!s2) {
draw_ties_g(s1, null, 2);
p_voice.s_tie = s1
break
}
} else {
| | | | | 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 |
}
if (!s2) {
draw_ties_g(s1, null, 2);
p_voice.s_tie = s1
break
}
} else {
if (s2.type != C.NOTE
&& s2.type != C.BAR) {
error(1, s1, "Bad tie")
continue
}
if (s2.time != time) {
s3 = tie_comb(s1)
if (s3 == s1) {
error(1, s1, "Bad tie")
continue
}
s2 = s3
}
}
for (s3 = s1.ts_next; s3; s3 = s3.ts_next) {
if (s3.st != s1.st)
continue
if (s3.time > time)
break
if (s3.type == C.CLEF) {
clef_chg = true
continue
}
}
/* ties with clef or staff change */
if (clef_chg || s1.st != s2.st) {
|
| ︙ | ︙ | |||
2955 2956 2957 2958 2959 2960 2961 | s1.x += dx if (s1.x < s2.x - 24.) s1.x = s2.x - 24.; draw_ties(s1, s2, 3); s1.x = x continue } | | | 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 |
s1.x += dx
if (s1.x < s2.x - 24.)
s1.x = s2.x - 24.;
draw_ties(s1, s2, 3);
s1.x = x
continue
}
draw_ties_g(s1, s2, s2.type == C.NOTE ? 0 : 2)
}
p_voice.s_rtie = s_rtie
}
/* -- draw all phrasing slurs for one staff -- */
/* (the staves are not yet defined) */
function draw_all_slurs(p_voice) {
|
| ︙ | ︙ | |||
3000 3001 3002 3003 3004 3005 3006 | break s.notes[m2].sl2--; s.sl2-- } slur_type = slur_st & 0x0f; k = prev_scut(s); draw_slur(k, s, -1, m2, slur_type) | | | | 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 |
break
s.notes[m2].sl2--;
s.sl2--
}
slur_type = slur_st & 0x0f;
k = prev_scut(s);
draw_slur(k, s, -1, m2, slur_type)
if (k.type != C.BAR
|| (k.bar_type[0] != ':'
&& k.bar_type != "|]"
&& k.bar_type != "[|"
&& (!k.text || k.text[0] == '1')))
slur_st >>= 4
}
}
s = p_voice.sym
while (slur_st != 0) {
slur_type = slur_st & 0x0f;
slur_st >>= 4;
k = next_scut(s);
draw_slur(s, k, -1, -1, slur_type)
if (k.type != C.BAR
|| (k.bar_type[0] != ':'
&& k.bar_type != "|]"
&& k.bar_type != "[|"
&& (!k.text || k.text[0] == '1'))) {
if (!p_voice.slur_start)
p_voice.slur_start = 0;
p_voice.slur_start <<= 4;
|
| ︙ | ︙ | |||
3038 3039 3040 3041 3042 3043 3044 | * - beams * - decorations near the notes * - measure bar numbers * - n-plets * - decorations tied to the notes * - slurs * - not scaled | | | | | | | 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 3001 |
* - beams
* - decorations near the notes
* - measure bar numbers
* - n-plets
* - decorations tied to the notes
* - slurs
* - not scaled
* - chord symbols
* - staff decorations
* - lyrics
* - measure numbers
* 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, output_sav;
output_sav = output;
output = ""
/* calculate the beams but don't draw them (the staves are not yet defined) */
for (v = 0; v < voice_tb.length; v++) {
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:
for (g = s.extra; g; g = g.next) {
if (g.beam_st && !g.beam_end)
self.calculate_beam(bm, g)
}
break
case C.NOTE:
if ((s.beam_st && !s.beam_end)
|| (first_note && !s.beam_st)) {
first_note = false;
self.calculate_beam(bm, s)
}
break
}
}
}
/* initialize the min/max vertical offsets */
|
| ︙ | ︙ | |||
3098 3099 3100 3101 3102 3103 3104 |
draw_deco_near()
/* set the min/max vertical offsets */
for (s = tsfirst; s; s = s.ts_next) {
if (s.invis)
continue
switch (s.type) {
| | | | > > > | > > > | | 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 |
draw_deco_near()
/* set the min/max vertical offsets */
for (s = tsfirst; s; s = s.ts_next) {
if (s.invis)
continue
switch (s.type) {
case C.GRACE:
for (g = s.extra; g; g = g.next) {
y_set(s.st, true, g.x - 2, 4, g.ymx + 1);
y_set(s.st, false, g.x - 2, 4, g.ymn - 1)
}
continue
case C.MREST:
y_set(s.st, true, s.x + 16, 32, s.ymx + 2)
continue
default:
y_set(s.st, true, s.x - s.wl, s.wl + s.wr, s.ymx + 2);
y_set(s.st, false, s.x - s.wl, s.wl + s.wr, s.ymn - 2)
continue
case C.NOTE:
break
}
// (permit closer staves)
if (s.stem > 0) {
if (s.stemless) {
dx = -5;
w = 10
} else if (s.beam_st) {
dx = 3;
w = s.beam_end ? 4 : 10
} else {
dx = -8;
w = s.beam_end ? 11 : 16
}
y_set(s.st, true, s.x + dx, w, s.ymx);
y_set(s.st, false, s.x - s.wl, s.wl + s.wr, s.ymn)
} else {
y_set(s.st, true, s.x - s.wl, s.wl + s.wr, s.ymx);
if (s.stemless) {
dx = -5;
w = 10
} else if (s.beam_st) {
dx = -6;
w = s.beam_end ? 4 : 10
} else {
dx = -8;
w = s.beam_end ? 5 : 16
}
dx += s.notes[0].shhd;
|
| ︙ | ︙ | |||
3170 3171 3172 3173 3174 3175 3176 |
continue
set_color(s.color);
st = p_voice.st;
// if (st == undefined) {
//error(1, s, "BUG: no staff for voice " + p_voice.id)
// continue
// }
| < | 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 |
continue
set_color(s.color);
st = p_voice.st;
// if (st == undefined) {
//error(1, s, "BUG: no staff for voice " + p_voice.id)
// continue
// }
/* draw the tuplets near the notes */
for ( ; s; s = s.next) {
if (s.tp0)
draw_tuplet(s, 0)
}
draw_all_slurs(p_voice)
|
| ︙ | ︙ | |||
3200 3201 3202 3203 3204 3205 3206 | if (top > p_st.top[i]) p_st.top[i] = top if (bot < p_st.bot[i]) p_st.bot[i] = bot } } | | > > < < < | 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 |
if (top > p_st.top[i])
p_st.top[i] = top
if (bot < p_st.bot[i])
p_st.bot[i] = bot
}
}
set_color();
draw_deco_note()
if (cfmt.measurenb >= 0)
draw_measnb();
draw_deco_staff();
/* if any lyric, draw them now as unscaled */
set_dscale(-1)
// set_sscale(-1)
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (p_voice.have_ly) {
draw_all_lyrics()
break
}
}
set_dscale(-1);
output = output_sav
}
/* -- draw the name/subname of the voices -- */
function draw_vname(indent) {
var p_voice, n, st, v, a_p, p, y, name_type,
|
| ︙ | ︙ | |||
3410 3411 3412 3413 3414 3415 3416 |
/* output the staff offsets */
for (st = 0; st <= nstaff; st++) {
p_staff = staff_tb[st];
dy = p_staff.y
if (p_staff.staffscale != 1) {
p_staff.scale_str =
'transform="translate(0,' +
| | | 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 |
/* output the staff offsets */
for (st = 0; st <= nstaff; st++) {
p_staff = staff_tb[st];
dy = p_staff.y
if (p_staff.staffscale != 1) {
p_staff.scale_str =
'transform="translate(0,' +
(posy - dy).toFixed(1) + ') ' +
'scale(' + p_staff.staffscale.toFixed(2) + ')"'
}
}
if (mbot == 0) {
for (st = nstaff; st >= 0; st--) {
if (gene.st_print[st])
|
| ︙ | ︙ | |||
3437 3438 3439 3440 3441 3442 3443 |
// return the height of the whole staff system
return y + dy
}
/* -- draw the staff systems and the measure bars -- */
function draw_systems(indent) {
| | | > > > > > | 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 |
// 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 = [],
bar_bot = [],
bar_height = [],
sb = [],
db = [],
thb = [],
gl = [],
rn = []
/* -- set the bottom and height of the measure bars -- */
function bar_set() {
var st, staffscale, top, bot,
dy = 0
for (st = 0; st <= cur_sy.nstaff; st++) {
|
| ︙ | ︙ | |||
3470 3471 3472 3473 3474 3475 3476 |
} // bar_set()
/* -- draw a staff -- */
function draw_staff(st, x1, x2) {
var w, ws, i, dy, ty,
y = 0,
ln = "",
| | | 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 |
} // bar_set()
/* -- draw a staff -- */
function draw_staff(st, x1, x2) {
var w, ws, i, dy, ty,
y = 0,
ln = "",
stafflines = cur_sy.staves[st].stafflines,
l = stafflines.length
if (!/[\[|]/.test(stafflines))
return // no line
w = x2 - x1;
set_sscale(st);
ws = w / stv_g.scale
|
| ︙ | ︙ | |||
3494 3495 3496 3497 3498 3499 3500 |
dy = 0
for (; i < l; i++, y -= 6, dy -= 6) {
switch (stafflines[i]) {
case '.':
case '-':
continue
case ty:
| | | | | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | | | > | | | | | > > > > > | < | < < < < < < < < < < < < | < < < | | | | | 3422 3423 3424 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 3498 3499 3500 3501 3502 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 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 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 |
dy = 0
for (; i < l; i++, y -= 6, dy -= 6) {
switch (stafflines[i]) {
case '.':
case '-':
continue
case ty:
ln += 'm-' + ws.toFixed(1) +
' ' + dy +
'h' + ws.toFixed(1);
dy = 0
continue
}
if (ty != undefined)
ln += '"/>\n';
ty = stafflines[i]
ln += '<path class="stroke ' +
(ty == '[' ? 'slthW' : 'slW') +
'" d="m0 ' + y + 'h' + ws.toFixed(1);
dy = 0
}
ln += '"/>\n'
}
y = staff_tb[st].y
if (!cache
&& w == get_lwidth()) {
cache = {
st_l: stafflines,
st_ws: ws
}
i = 'stdef' + cfmt.fullsvg;
glyphs[i] = '<g id="' + i + '">\n' + ln + '</g>';
xygl(x1, y, i)
return
}
out_XYAB('<g transform="translate(X, Y)">\n' + ln + '</g>\n', x1, y)
} // draw_staff()
// draw a measure bar
function draw_bar(s, bot, h) {
var i, s2, yb,
bar_type = s.bar_type,
st = s.st,
p_staff = staff_tb[st],
x = s.x
// don't put a line between the staves if there is no bar above
if (st != 0
&& s.ts_prev
//fixme: 's.ts_prev.st != st - 1' when floating voice in lower staff
// && (s.ts_prev.type != C.BAR || s.ts_prev.st != st - 1))
&& s.ts_prev.type != C.BAR)
h = p_staff.topbar * p_staff.staffscale;
s.ymx = s.ymn + h;
set_sscale(-1);
anno_start(s)
// compute the middle vertical offset of the staff
yb = p_staff.y + 12;
if (p_staff.stafflines != '|||||')
yb += (p_staff.topbar + p_staff.botbar) / 2 - 12 // bottom
// if measure repeat, draw the '%' like glyphs
if (s.bar_mrep) {
set_sscale(st)
if (s.bar_mrep == 1) {
for (s2 = s.prev; s2.type != C.REST; s2 = s2.prev)
;
gl.push([s2.x, yb, st, "mrep"])
} else {
gl.push([x, yb, st, "mrep2"])
if (s.v == cur_sy.top_voice)
rn.push([x, yb + p_staff.topbar - 9,
st, s.bar_mrep.toString()])
}
}
if (bar_type == '||:')
bar_type = '[|:'
for (i = bar_type.length; --i >= 0; ) {
switch (bar_type[i]) {
case "|":
if (s.bar_dotted)
db.push(new Float32Array([x, bot, h,
p_staff.staffscale]))
else
sb.push(new Float32Array([x, bot, h]))
break
default:
// case "[":
// case "]":
x -= 3;
thb.push(new Float32Array([x + 1.5, bot, h]))
break
case ":":
x -= 2;
gl.push([x + 1, yb - 12, st, "rdots"])
break
}
x -= 3
}
set_sscale(-1);
anno_stop(s)
} // draw_bar()
// output all the bars
function out_bars() {
var i, b, w, bx,
l = sb.length;
set_sscale(-1)
if (l) { // single bars [x, y, h]
output += '<path class="stroke bW" d="'
for (i = 0; i < l; i++) {
b = sb[i];
out_XYAB('MX Yv-F', b[0], b[1], b[2])
}
output += '"/>\n'
}
l = db.length
if (l) { // dotted bars [x, y, h, scale]
for (i = 0; i < l; i++) {
b = db[i];
w = (5 * b[3]).toFixed(1);
out_XYAB('<path class="stroke bW" ' +
'stroke-dasharray="' + w + ',' + w + '" d="' +
'MX Yv-F"/>\n', b[0], b[1], b[2])
}
}
l = thb.length
if (l) { // thick bars [x, y, h]
output += '<path class="stroke bthW" d="'
for (i = 0; i < l; i++) {
b = thb[i];
out_XYAB('MX Yv-F', b[0], b[1], b[2])
}
output += '"/>\n'
}
l = gl.length
if (l) { // glyphs [x, y, staff, glyph]
for (i = 0; i < l; i++) {
b = gl[i];
set_sscale(b[2]);
xygl(b[0], b[1], b[3])
}
}
l = rn.length
if (l) { // repeat number [x, y, staff, number]
set_font("annotation");
if (gene.curfont.box) {
gene.curfont.box = false
bx = true
}
for (i = 0; i < l; i++) {
b = rn[i];
set_sscale(b[2]);
xy_str(b[0], b[1], b[3], "c")
}
if (bx)
gene.curfont.box = true
}
} // out_bars()
// draw_systems()
draw_vname(indent)
/* draw the staff, skipping the staff breaks */
for (st = 0; st <= nstaff; st++)
xstaff[st] = !cur_sy.st_print[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])
xstaff[st] = staves_bar ?
staves_bar : (s.x - s.wl - 2)
continue
}
if (sy.st_print[st] // if not staff stop
&& sy.staves[st].stafflines ==
cur_sy.staves[st].stafflines)
continue
if (staves_bar) {
x2 = staves_bar;
bar_force = s.time
} else {
x2 = s.x - s.wl - 2;
xstaff[st] = -1
}
draw_staff(st, x, x2)
if (sy.st_print[st])
xstaff[st] = x2
}
cur_sy = sy;
bar_set()
continue
case C.BAR:
if (s.second || s.invis || !s.bar_type)
break
st = s.st;
draw_bar(s, bar_bot[st], bar_height[st])
break
case C.STBRK:
if (cur_sy.voices[s.v].range == 0) {
if (s.xmx > 14) {
/* draw the left system if stbrk in all voices */
var nv = 0
for (var i = 0; i < voice_tb.length; i++) {
if (cur_sy.voices[i].range > 0)
nv++
}
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.type != C.STBRK)
break
nv--
}
if (nv == 0)
draw_lstaff(s.x)
}
}
s2 = s.prev
if (!s2)
break
x2 = s2.x
if (s2.type != C.BAR)
x2 += s2.wr;
st = s.st;
x = xstaff[st]
if (x >= 0) {
if (x >= x2)
continue
draw_staff(st, x, x2)
|
| ︙ | ︙ | |||
3656 3657 3658 3659 3660 3661 3662 | if (bar_force && !cur_sy.st_print[st]) continue x = xstaff[st] if (x < 0 || x >= realwidth) continue draw_staff(st, x, realwidth) } | > > > | > | | > | | | > > > | | < | | | < | | | | > < < | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 |
if (bar_force && !cur_sy.st_print[st])
continue
x = xstaff[st]
if (x < 0 || x >= realwidth)
continue
draw_staff(st, x, realwidth)
}
// and the bars
out_bars()
set_sscale(-1)
}
/* -- draw remaining symbols when the staves are defined -- */
// (possible hook)
function draw_symbols(p_voice) {
var bm = {},
s, g, x, y, st;
// bm.s2 = undefined
for (s = p_voice.sym; s; s = s.next) {
if (s.invis) {
switch (s.type) {
case C.KEY:
p_voice.key = s
default:
continue
case C.NOTE: // (beams may start on invisible notes)
break
}
}
st = s.st
x = s.x;
set_color(s.color)
switch (s.type) {
case C.NOTE:
//--fixme: recall set_scale if different staff
set_scale(s)
if (s.beam_st && !s.beam_end) {
if (self.calculate_beam(bm, s))
draw_beams(bm)
}
if (!s.invis) {
anno_start(s);
draw_note(s, !bm.s2);
anno_stop(s)
}
if (s == bm.s2)
bm.s2 = null
break
case C.REST:
if (s.invis
|| !staff_tb[st].topbar)
break
draw_rest(s);
break
case C.BAR:
break /* drawn in draw_systems */
case C.CLEF:
if (s.time >= staff_tb[st].clef.time)
staff_tb[st].clef = s
if (s.second
|| s.invis
|| !staff_tb[st].topbar)
break
set_color();
set_sscale(st);
anno_start(s);
y = staff_tb[st].y
if (s.clef_name)
xygl(x, y + s.y, s.clef_name)
else if (!s.clef_small)
xygl(x, y + s.y, s.clef_type + "clef")
else
xygl(x, y + s.y, "s" + s.clef_type + "clef")
if (s.clef_octave) {
/*fixme:break the compatibility and avoid strange numbers*/
if (s.clef_octave > 0) {
y += s.ymx - 10
if (s.clef_small)
y -= 1
} else {
y += s.ymn + 6
if (s.clef_small)
y += 1
}
xygl(x - 2, y, "oct")
}
anno_stop(s)
break
case C.METER:
p_voice.meter = s
if (s.second
// || s.invis
|| !staff_tb[s.st].topbar)
break
set_color();
set_sscale(s.st);
anno_start(s);
draw_meter(x, s);
anno_stop(s)
break
case C.KEY:
p_voice.key = s
if (s.second
|| s.invis
|| !staff_tb[s.st].topbar)
break
set_color();
set_sscale(s.st);
anno_start(s);
draw_keysig(x, s);
anno_stop(s)
break
case C.MREST:
set_scale(s);
x += 32;
anno_start(s);
xygl(x, staff_tb[s.st].y + 12, "mrest");
out_XYAB('<text style="font:bold 15px serif"\n\
x ="X" y="Y" text-anchor="middle">A</text>\n',
x, staff_tb[s.st].y + 28, s.nmes);
anno_stop(s)
break
case C.GRACE:
set_scale(s);
draw_gracenotes(s)
break
case C.SPACE:
case C.STBRK:
break /* nothing */
case C.CUSTOS:
set_scale(s);
draw_note(s, 0)
break
case C.BLOCK: // no width
case C.PART:
case C.REMARK:
case C.STAVES:
case C.TEMPO:
break
default:
error(2, s, "draw_symbols - Cannot draw symbol " + s.type)
break
}
}
set_scale(p_voice.sym);
draw_all_ties(p_voice);
// no need to reset the scale as in abcm2ps
set_color()
}
/* -- draw all symbols -- */
function draw_all_sym() {
var p_voice, v,
n = voice_tb.length
for (v = 0; v < n; v++) {
p_voice = voice_tb[v]
if (p_voice.sym
&& p_voice.sym.x != undefined)
self.draw_symbols(p_voice)
}
draw_all_deco();
set_sscale(-1) /* restore the scale */
}
/* -- set the tie directions for one voice -- */
function set_tie_dir(sym) {
var s, i, ntie, dir, sec, pit, ti
for (s = sym; s; s = s.next) {
if (!s.ti1)
continue
/* if other voice, set the ties in opposite direction */
if (s.multi != 0) {
dir = s.multi > 0 ? C.SL_ABOVE : C.SL_BELOW
for (i = 0; i <= s.nhd; i++) {
ti = s.notes[i].ti1;
if (!((ti & 0x07) == C.SL_AUTO))
continue
s.notes[i].ti1 = (ti & C.SL_DOTTED) | dir
}
continue
}
/* if one note, set the direction according to the stem */
sec = ntie = 0;
pit = 128
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].ti1) {
ntie++
if (pit < 128
&& s.notes[i].pit <= pit + 1)
sec++;
pit = s.notes[i].pit
}
}
if (ntie <= 1) {
dir = s.stem < 0 ? C.SL_ABOVE : C.SL_BELOW
for (i = 0; i <= s.nhd; i++) {
ti = s.notes[i].ti1
if (ti) {
if ((ti & 0x07) == C.SL_AUTO)
s.notes[i].ti1 =
(ti & C.SL_DOTTED) | dir
break
}
}
continue
}
if (sec == 0) {
if (ntie & 1) {
/* in chords with an odd number of notes, the outer noteheads are paired off
* center notes are tied according to their position in relation to the
* center line */
ntie = (ntie - 1) / 2;
dir = C.SL_BELOW
for (i = 0; i <= s.nhd; i++) {
ti = s.notes[i].ti1
if (ti == 0)
continue
if (ntie == 0) { /* central tie */
if (s.notes[i].pit >= 22)
dir = C.SL_ABOVE
}
if ((ti & 0x07) == C.SL_AUTO)
s.notes[i].ti1 =
(ti & C.SL_DOTTED) | dir
if (ntie-- == 0)
dir = C.SL_ABOVE
}
continue
}
/* even number of notes, ties divided in opposite directions */
ntie /= 2;
dir = C.SL_BELOW
for (i = 0; i <= s.nhd; i++) {
ti = s.notes[i].ti1
if (ti == 0)
continue
if ((ti & 0x07) == C.SL_AUTO)
s.notes[i].ti1 =
(ti & C.SL_DOTTED) | dir
if (--ntie == 0)
dir = C.SL_ABOVE
}
continue
}
/*fixme: treat more than one second */
/* if (nsec == 1) { */
/* When a chord contains the interval of a second, tie those two notes in
* opposition; then fill in the remaining notes of the chord accordingly */
pit = 128
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].ti1) {
if (pit < 128
&& s.notes[i].pit <= pit + 1) {
ntie = i
break
}
pit = s.notes[i].pit
}
}
dir = C.SL_BELOW
for (i = 0; i <= s.nhd; i++) {
ti = s.notes[i].ti1
if (ti == 0)
continue
if (ntie == i)
dir = C.SL_ABOVE
if ((ti & 0x07) == C.SL_AUTO)
s.notes[i].ti1 = (ti & C.SL_DOTTED) | dir
}
/*fixme..
continue
}
..*/
/* if a chord contains more than one pair of seconds, the pair farthest
* from the center line receives the ties drawn in opposition */
|
| ︙ | ︙ | |||
3945 3946 3947 3948 3949 3950 3951 |
if (!s)
continue
set_tie_dir(s)
for ( ; s; s = s.next) {
if (!s.ti1)
continue
if (s.notes[0].pit < 20
| | | | | 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 |
if (!s)
continue
set_tie_dir(s)
for ( ; s; s = s.next) {
if (!s.ti1)
continue
if (s.notes[0].pit < 20
&& (s.notes[0].ti1 & 0x07) == C.SL_BELOW)
;
else if (s.notes[s.nhd].pit > 24
&& (s.notes[s.nhd].ti1 & 0x07) == C.SL_ABOVE)
;
else
continue
s2 = s.next
while (s2 && s2.type != C.NOTE)
s2 = s2.next
if (s2) {
if (s2.st != s.st)
continue
dx = s2.x - s.x - 10
} else {
dx = realwidth - s.x - 10
|
| ︙ | ︙ |
Changes to core/format.js.
1 2 | // abc2svg - format.js - formatting functions // | | < | < | | | | | > > > > | > > > > > | > > > > > > > > > | | > | > | | | | > | < | > > | | | > > > > | | | < | > > > > > > > > | | | > > | | > > > | | > | > > > > > > > > | | > > > > | < < < | > > | | > > | | < < < | | < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// abc2svg - format.js - formatting functions
//
// Copyright (C) 2014-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
var font_tb = [],
font_scale_tb = {
serif: 1,
serifBold: 1,
'sans-serif': 1,
'sans-serifBold': 1,
Palatino: 1.1,
monospace: 1.35
},
fmt_lock = {}
var cfmt = {
annotationfont: { name: "sans-serif", size: 12 },
aligncomposer: 1,
// botmargin: .7 * IN, // != 1.8 * CM,
breaklimit: .7,
breakoneoln: true,
cancelkey: true,
composerfont: { name: "serifItalic", size: 14 },
composerspace: 6,
// contbarnb: false,
dblrepbar: ':][:',
decoerr: true,
dynalign: true,
footerfont: { name: "serif", size: 16 },
fullsvg: '',
gchordfont: { name: "sans-serif", size: 12 },
gracespace: new Float32Array([4, 8, 11]), // left, inside, right
graceslurs: true,
headerfont: { name: "serif", size: 16 },
historyfont: { name: "serif", size: 16 },
hyphencont: true,
indent: 0,
infofont: {name: "serifItalic", size: 14 },
infoname: 'R "Rhythm: "\n\
B "Book: "\n\
S "Source: "\n\
D "Discography: "\n\
N "Notes: "\n\
Z "Transcription: "\n\
H "History: "',
infospace: 0,
keywarn: true,
leftmargin: 1.4 * CM,
lineskipfac: 1.1,
linewarn: true,
maxshrink: .65,
maxstaffsep: 2000,
maxsysstaffsep: 2000,
measurefirst: 1,
measurefont: {name: "serifItalic", size: 10},
measurenb: -1,
musicspace: 6,
// notespacingfactor: 1.414,
partsfont: {name: "serif", size: 15},
parskipfac: .4,
partsspace: 8,
// pageheight: 29.7 * CM,
pagewidth: 21 * CM,
// pos: {
// dyn: 0,
// gch: 0,
// gst: 0,
// orn: 0,
// stm: 0,
// voc: 0,
// vol: 0
// },
printmargin: 0,
rightmargin: 1.4 * CM,
rbdbstop: true,
rbmax: 4,
rbmin: 2,
repeatfont: {name: "serif", size: 13},
scale: 1,
slurheight: 1.0,
staffsep: 46,
stemheight: 21, // one octave
stretchlast: .25,
stretchstaff: true,
subtitlefont: {name: "serif", size: 16},
subtitlespace: 3,
sysstaffsep: 34,
tempofont: {name: "serifBold", size: 15},
textfont: {name: "serif", size: 16},
// textoption: undefined,
textspace: 14,
titlefont: {name: "serif", size: 20},
// titleleft: false,
titlespace: 6,
titletrim: true,
// transp: 0, // global transpose
// topmargin: .7 * IN,
topspace: 22,
tuplets: [0, 0, 0, 0],
vocalfont: {name: "serifBold", size: 13},
vocalspace: 10,
voicefont: {name: "serifBold", size: 13},
// voicescale: 1,
writefields: "CMOPQsTWw",
wordsfont: {name: "serif", size: 16},
wordsspace: 5
}
function get_bool(param) {
return !param || !/^(0|n|f)/i.test(param) // accept void as true !
}
// %%font <font> [<encoding>] [<scale>]
function get_font_scale(param) {
var i, font,
a = info_split(param) // a[0] = font name
if (a.length <= 1)
return
var scale = parseFloat(a[a.length - 1])
if (isNaN(scale) || scale <= 0.5) {
syntax(1, "Bad scale value in %%font")
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]
if (!scale)
scale = 1.1;
font.swfac = font.size * scale
}
// %%xxxfont fontname|* [encoding] [size|*]
function param_set_font(xxxfont, param) {
var font, old_fn, n, a, new_name, new_fn, new_size, scale
// "setfont-<n>" goes to "u<n>font"
if (xxxfont[xxxfont.length - 2] == '-') {
n = xxxfont[xxxfont.length - 1]
if (n < '1' || n > '9')
return
xxxfont = "u" + n + "font"
}
// create a new font
font = cfmt[xxxfont];
if (!font) { // set-font-<n> or new element
font = {
name: "sans-serif",
size: 12
}
}
font = Object.create(font);
font.fid = font.used = undefined;
cfmt[xxxfont] = font;
// fill the values
a = param.match(/\s+(no)?box(\s|$)/)
if (a) { // if box
if (a[1])
font.box = false // nobox
else
font.box = true;
param = param.replace(a[0], a[2])
}
a = param.match(/\s+class=(.*?)(\s|$)/)
if (a) {
font.class = a[1];
param = param.replace(a[0], a[2])
}
a = param.match(/\s+wadj=(.*?)(\s|$)/)
if (a) {
if (typeof document == "undefined") // useless if in browser
switch (a[1]) {
case 'none':
font.wadj = ''
break
case 'space':
font.wadj = 'spacing'
break
case 'glyph':
font.wadj = 'spacingAndGlyphs'
break
default:
syntax(1, errs.bad_val, "%%" + xxxfont)
break
}
param = param.replace(a[0], a[2])
}
a = info_split(param)
if (!a) {
syntax(1, errs.bad_val, "%%" + xxxfont)
return
}
new_name = a[0]
if (new_name != "*") {
new_name = new_name.replace('Times-Roman', 'serif');
new_name = new_name.replace('Times', 'serif');
new_name = new_name.replace('Helvetica', 'sans-serif');
new_name = new_name.replace('Courier', 'monospace');
font.name = new_name
font.swfac = 0
}
if (a.length > 1) {
new_size = a[a.length - 1]
if (new_size != '*') {
new_size = Number(new_size)
if (isNaN(new_size)) {
syntax(1, errs.bad_val, "%%" + xxxfont)
} else {
font.size = new_size;
font.swfac = 0
}
}
}
}
// get a length with a unit - return the number of pixels
function get_unit(param) {
var v = parseFloat(param)
switch (param.slice(-2)) {
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 |
}
function get_textopt(param) {
return textopt[param]
}
/* -- position of a voice element -- */
var posval = {
| | | | | | | | | | | 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 |
}
function get_textopt(param) {
return textopt[param]
}
/* -- position of a voice element -- */
var posval = {
above: C.SL_ABOVE,
auto: 0, // !! not C.SL_AUTO !!
below: C.SL_BELOW,
down: C.SL_BELOW,
hidden: C.SL_HIDDEN,
opposite: C.SL_HIDDEN,
under: C.SL_BELOW,
up: C.SL_ABOVE
}
/* -- set the position of elements in a voice -- */
function set_pos(k, v) { // keyword, value
k = k.slice(0, 3)
if (k == "ste")
k = "stm"
self.set_v_param("pos", k + ' ' + v)
}
// set/unset the fields to write
function set_writefields(parm) {
var c, i,
a = parm.split(/\s+/)
|
| ︙ | ︙ | |||
301 302 303 304 305 306 307 308 309 |
if (cfmt.writefields.indexOf(c) >= 0)
cfmt.writefields = cfmt.writefields.replace(c, '')
}
}
}
// set a voice specific parameter
function set_v_param(k, v) {
if (curvoice) {
| > | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
if (cfmt.writefields.indexOf(c) >= 0)
cfmt.writefields = cfmt.writefields.replace(c, '')
}
}
}
// set a voice specific parameter
// (possible hook)
function set_v_param(k, v) {
if (curvoice) {
self.set_vp([k + '=', v])
return
}
k = [k + '=', v];
var vid = '*'
if (!info.V)
info.V = {}
if (info.V[vid])
|
| ︙ | ︙ | |||
337 338 339 340 341 342 343 344 |
error(0, undefined, "Bad staff width");
img.width = img.lm + img.rm + 150
}
set_posx()
} // set_page()
// set a format parameter
function set_format(cmd, param, lock) {
| > | < < < < < < < < < < < < < < < < < < | 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 |
error(0, undefined, "Bad staff width");
img.width = img.lm + img.rm + 150
}
set_posx()
} // set_page()
// set a format parameter
// (possible hook)
function set_format(cmd, param, lock) {
var f, f2, v, i
//fixme: should check the type and limits of the parameter values
if (lock) {
fmt_lock[cmd] = true
} else if (fmt_lock[cmd])
return
if (/.+font(-[\d])?$/.test(cmd)) {
param_set_font(cmd, param)
return
}
switch (cmd) {
case "aligncomposer":
case "barsperstaff":
case "infoline":
|
| ︙ | ︙ | |||
391 392 393 394 395 396 397 |
break
case "microscale":
f = parseInt(param)
if (isNaN(f) || f < 4 || f > 256 || f % 1) {
syntax(1, errs.bad_val, "%%" + cmd)
break
}
| | | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
break
case "microscale":
f = parseInt(param)
if (isNaN(f) || f < 4 || f > 256 || f % 1) {
syntax(1, errs.bad_val, "%%" + cmd)
break
}
self.set_v_param("uscale", f)
break
case "bgcolor":
case "dblrepbar":
case "titleformat":
cfmt[cmd] = param
break
case "breaklimit": // float values
|
| ︙ | ︙ | |||
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | case "pagescale": cmd = "scale"; img.chg = true break } cfmt[cmd] = f break case "bstemdown": case "breakoneoln": case "cancelkey": case "contbarnb": case "custos": case "decoerr": case "dynalign": case "flatbeams": | > > > > > > > < < < > | 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 |
case "pagescale":
cmd = "scale";
img.chg = true
break
}
cfmt[cmd] = f
break
case "annotationbox":
case "gchordbox":
case "measurebox":
case "partsbox":
cfmt[cmd.replace("box", "font")] // font
.box = get_bool(param)
break
case "bstemdown":
case "breakoneoln":
case "cancelkey":
case "contbarnb":
case "custos":
case "decoerr":
case "dynalign":
case "flatbeams":
case "graceslurs":
case "graceword":
case "hyphencont":
case "keywarn":
case "linewarn":
case "rbdbstop":
case "singleline":
case "squarebreve":
case "splittune":
case "straightflags":
case "stretchstaff":
case "timewarn":
case "titlecaps":
case "titleleft":
cfmt[cmd] = get_bool(param)
break
|
| ︙ | ︙ | |||
495 496 497 498 499 500 501 | syntax(1, errs.bad_val, '%%' + cmd) break } cfmt[cmd] = f; img.chg = true break case "concert-score": | > | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | syntax(1, errs.bad_val, '%%' + cmd) break } cfmt[cmd] = f; img.chg = true break case "concert-score": if (cfmt.sound != "play") cfmt.sound = "concert" break case "writefields": set_writefields(param) break case "dynamic": case "gchord": case "gstemdir": |
| ︙ | ︙ | |||
521 522 523 524 525 526 527 | syntax(1, "Cannot have %%fullsvg inside a tune") break } //fixme: should check only alpha, num and '_' characters cfmt[cmd] = param break case "gracespace": | | > > > > > > > | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
syntax(1, "Cannot have %%fullsvg inside a tune")
break
}
//fixme: should check only alpha, num and '_' characters
cfmt[cmd] = param
break
case "gracespace":
v = param.split(/\s+/)
for (i = 0; i < 3; i++)
if (isNaN(Number(v[i]))) {
syntax(1, errs.bad_val, "%%gracespace")
break
}
for (i = 0; i < 3; i++)
cfmt[cmd][i] = Number(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]
|
| ︙ | ︙ | |||
560 561 562 563 564 565 566 | cfmt.sound = "play" // without clef break case "pos": cmd = param.split(/\s+/); set_pos(cmd[0], cmd[1]) break case "sounding-score": | > | | 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
cfmt.sound = "play" // without clef
break
case "pos":
cmd = param.split(/\s+/);
set_pos(cmd[0], cmd[1])
break
case "sounding-score":
if (cfmt.sound != "play")
cfmt.sound = "sounding"
break
case "staffwidth":
v = get_unit(param)
if (isNaN(v)) {
syntax(1, errs.bad_val, '%%' + cmd)
break
}
|
| ︙ | ︙ | |||
594 595 596 597 598 599 600 | else cfmt[cmd] = v break case "combinevoices": syntax(1, "%%combinevoices is deprecated - use %%voicecombine instead") break case "voicemap": | | | < < < < < < < < < < < < < < < < < < < < < | < < < < < < < | | < < | | < | | < | | > | | < | | < > | | < | | < < < < < < | | > > > > > > > | < | | < < < | < < | 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 646 647 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 |
else
cfmt[cmd] = v
break
case "combinevoices":
syntax(1, "%%combinevoices is deprecated - use %%voicecombine instead")
break
case "voicemap":
self.set_v_param("map", param)
break
case "voicescale":
self.set_v_param("scale", param)
break
default: // memorize all global commands
if (parse.state == 0) // (needed for modules)
cfmt[cmd] = param
break
}
}
// font stuff
// build a font style
function style_font(font) {
var fn = font.name,
r = '',
a = fn.match(/-?[bB]old/)
if (a) {
r += "bold ";
fn = fn.replace(a[0], '')
}
a = fn.match(/-?[iI]talic/)
if (a) {
r += "italic ";
fn = fn.replace(a[0], '')
}
a = fn.match(/-?[oO]blique/)
if (a) {
r += "oblique ";
fn = fn.replace(a[0], '')
}
return 'font:' + r + font.size.toFixed(1) + 'px ' + fn
}
Abc.prototype.style_font = style_font
// build a font class
function font_class(font) {
if (font.class)
return 'f' + font.fid + cfmt.fullsvg + ' ' + font.class
return 'f' + font.fid + cfmt.fullsvg
}
// use the font
function use_font(font) {
if (!font.used) {
font.used = true;
if (font.fid == undefined) {
font.fid = font_tb.length;
font_tb.push(font)
if (!font.swfac)
set_font_fac(font)
}
font_style += "\n.f" + font.fid + cfmt.fullsvg +
" {" + style_font(font) + "}"
}
}
// get the font of the 'xxxfont' parameter
function get_font(xxx) {
var fn = xxx + "font",
font = cfmt[fn];
use_font(font)
return font
}
|
Changes to core/front.js.
1 2 | // abc2svg - front.js - ABC parsing front-end // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - front.js - ABC parsing front-end // // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
175 176 177 178 179 180 181 | continue } break } dst += '\\' + c; j = i + 1 } | > | > > > > > > > > > > > | 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 |
continue
}
break
}
dst += '\\' + c;
j = i + 1
}
// cleanup for XML treatment
return (dst + src.slice(j)).replace(/<|>| |&.*?;|&/g, function(c) {
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
case ' ': return ' Â ' // space + nbspace
case "<":
case ">":
case "&": return c
}
return "&" + c.slice(1)
})
}
// ABC include
var include = 0
function do_include(fn) {
var file, parse_sav
|
| ︙ | ︙ | |||
209 210 211 212 213 214 215 |
}
// parse ABC code
function tosvg(in_fname, // file name
file, // file content
bol, eof) { // beginning/end of file
var i, c, bol, eol, end,
| | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
}
// parse ABC code
function tosvg(in_fname, // file name
file, // file content
bol, eof) { // beginning/end of file
var i, c, bol, eol, end,
select,
line0, line1,
last_info, opt, text, a, b, s,
cfmt_sav, info_sav, char_tb_sav, glovar_sav, maps_sav,
mac_sav, maci_sav,
pscom,
txt_add = '\n' // for "+:"
|
| ︙ | ︙ | |||
241 242 243 244 245 246 247 248 |
else
eol = eof
return false
} // tune_selected()
// remove the comment at end of text
function uncomment(src, do_escape) {
if (src.indexOf('%') >= 0)
| > > > | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
else
eol = eof
return false
} // tune_selected()
// remove the comment at end of text
function uncomment(src, do_escape) {
var i
if (!src)
return src
if (src.indexOf('%') >= 0)
src = src.replace(/([^\\])%.*/, '$1')
.replace(/\\%/g, '%');
src = src.replace(/\s+$/, '')
if (do_escape && src.indexOf('\\') >= 0)
return cnv_escape(src)
return src
} // uncomment()
|
| ︙ | ︙ | |||
358 359 360 361 362 363 364 | } break } text = file.slice(bol, eol) if (!text || text[0] == '%') continue a = text.split(/\s+/, 2) | < < | < < | | | | | 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 |
}
break
}
text = file.slice(bol, eol)
if (!text || text[0] == '%')
continue
a = text.split(/\s+/, 2)
switch (a[0]) {
case "abcm2ps":
case "ss-pref":
parse.prefix = a[1] // may contain a '%'
continue
case "abc-include":
do_include(uncomment(a[1]))
continue
}
// beginxxx/endxxx
if (a[0].slice(0, 5) == 'begin') {
b = a[0].substr(5);
end = '\n' + line0 + line1 + "end" + b;
i = file.indexOf(end, eol)
if (i < 0) {
syntax(1, "No $1 after %%$2",
end.slice(1), a[0]);
parse.eol = eof
continue
}
self.do_begin_end(b, uncomment(a[1]),
file.slice(eol + 1, i).replace(
new RegExp('^' + line0 + line1, 'gm'),
''));
parse.eol = file.indexOf('\n', i + 6)
if (parse.eol < 0)
parse.eol = eof
continue
}
switch (a[0]) {
case "select":
if (parse.state != 0) {
syntax(1, "%%select ignored")
continue
}
select = uncomment(text.slice(7))
if (select[0] == '"')
select = select.slice(1, -1);
if (!select) {
delete parse.select
continue
}
select = select.replace(/\(/g, '\\(');
select = select.replace(/\)/g, '\\)');
// select = select.replace(/\|/g, '\\|');
parse.select = new RegExp(select, 'm')
continue
case "tune":
syntax(1, "%%tune not treated yet")
continue
case "voice":
if (parse.state != 0) {
syntax(1, "%%voice ignored")
continue
}
select = uncomment(text.slice(6))
/* if void %%voice, free all voice options */
if (!select) {
if (parse.cur_tune_opts)
parse.cur_tune_opts.voice_opts = null
else
parse.voice_opts = null
|
| ︙ | ︙ | |||
473 474 475 476 477 478 479 | break } break } parse.eol = bol - 1 continue } | | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
break
}
break
}
parse.eol = bol - 1
continue
}
self.do_pscom(uncomment(text, true))
continue
}
// music line (or free text)
if (line1 != ':' || !/[A-Za-z+]/.test(line0)) {
last_info = undefined;
if (parse.state < 2)
continue
parse.line.buffer = uncomment(file.slice(bol, eol), true);
parse_music_line()
continue
}
|
| ︙ | ︙ | |||
610 611 612 613 614 615 616 | case '|': // "|:" starts a music line if (parse.state < 2) continue parse.line.buffer = uncomment(file.slice(bol, eol), true); parse_music_line() continue default: | | | 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 |
case '|': // "|:" starts a music line
if (parse.state < 2)
continue
parse.line.buffer = uncomment(file.slice(bol, eol), true);
parse_music_line()
continue
default:
if ("ABCDFGHNOSZ".indexOf(line0) >= 0) {
if (parse.state >= 2) {
syntax(1, errs.ignored, line0)
continue
}
// if (cfmt.writefields.indexOf(c) < 0)
// break
if (!info[line0])
|
| ︙ | ︙ |
Changes to core/gchord.js.
1 2 | // abc2svg - gchord.js - chord symbols // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - gchord.js - chord symbols // // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
57 58 59 60 61 62 63 | c = line.next_char() } text += c } iend = parse.bol + line.index + 1 } | | > > | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
c = line.next_char()
}
text += c
}
iend = parse.bol + line.index + 1
}
if (curvoice.pos.gch == C.SL_HIDDEN)
return
if (ann_font.box)
h_ann += 3;
i = 0;
type = 'g'
while (1) {
c = text[i]
if (!c)
break
gch = {
|
| ︙ | ︙ | |||
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 |
case undefined:
case '\\':
break
}
break
}
if (c == ';') {
gch.text += c
continue
}
break
case ';':
break
}
i++
break
}
if (!a_gch)
a_gch = []
a_gch.push(gch)
}
}
// transpose a chord symbol
var note_names = "CDEFGAB",
| > < | < < < | | < | < < < < | < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < | > < < < | | | | | | | | < < | < < < < < < < | > | < | 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 247 248 249 250 251 252 253 254 255 256 257 258 |
case undefined:
case '\\':
break
}
break
}
if (c == ';') {
i++;
gch.text += c
continue
}
break
case ';':
break
}
i++
break
}
if (!a_gch)
a_gch = []
a_gch.push(gch)
}
}
// transpose a chord symbol
var note_names = "CDEFGAB",
acc_name = ["bb", "b", "", "#", "##"]
function gch_tr1(p, i2) {
var new_txt,
n, i1, i3, i4, ix, a, ip, ip2
/* main chord */
n = note_names.indexOf(p[0])
if (n < 0) {
if (p[0] != '/')
return p
}
ip = 1
if (n >= 0) { // if some chord
a = 0
while (p[ip] == '#') {
a++;
ip++
}
while (p[ip] == 'b') {
a--;
ip++
}
// if (p[ip] == '=')
// ip++
i3 = cde2fcg[n] + i2 + a * 7;
i4 = cgd2cde[(i3 + 16 * 7) % 7]; // note
i1 = ((((i3 + 22) / 7) | 0) + 159) % 5; // accidental
new_txt = note_names[i4] + acc_name[i1]
}
ip2 = p.indexOf('/', ip) // skip 'm'/'dim'..
if (ip2 < 0)
return new_txt + p.slice(ip);
/* bass */
n = note_names.indexOf(p[++ip2])
if (n < 0)
return new_txt + p.slice(ip);
new_txt += p.slice(ip, ip2);
a = 0
if (p[++ip2] == '#') {
a++
if (p[++ip2] == '#') {
a++;
ip2++
}
} else if (p[ip2] == 'b') {
a--
if (p[++ip2] == 'b') {
a--;
ip2++
}
}
i3 = cde2fcg[n] + i2 + a * 7;
i4 = cgd2cde[(i3 + 16 * 7) % 7]; // note
i1 = ((((i3 + 22) / 7) | 0) + 159) % 5; // accidental
return new_txt + note_names[i4] + acc_name[i1] + p.slice(ip2)
} // get_tr1
function gch_transp(s) {
var gch,
i = 0,
i2 = curvoice.ckey.k_sf - curvoice.okey.k_sf
for (i = 0; i < s.a_gch.length; i++) {
gch = s.a_gch[i]
if (gch.type == 'g')
gch.text = gch_tr1(gch.text, i2)
}
}
// -- build the chord indications / annotations --
// (possible hook)
function gch_build(s) {
/* split the chord indications / annotations
* and initialize their vertical offsets */
var gch, wh, xspc, ix,
pos = curvoice.pos.gch == C.SL_BELOW ? -1 : 1,
y_above = 0,
y_below = 0,
y_left = 0,
y_right = 0,
GCHPRE = .4; // portion of chord before note
s.a_gch = a_gch;
a_gch = null
if (curvoice.vtransp)
gch_transp(s)
|
| ︙ | ︙ | |||
331 332 333 334 335 336 337 338 339 340 |
case '##': return "𝄪"
case '#': return "\u266f"
case '=': return "\u266e"
case 'b': return "\u266d"
}
return "𝄫"
});
} else {
gch.text = cnv_escape(gch.text);
if (gch.type == '@'
| > > > > | > > | | > > | 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 |
case '##': return "𝄪"
case '#': return "\u266f"
case '=': return "\u266e"
case 'b': return "\u266d"
}
return "𝄫"
});
if (gch.font.box)
gch.box = true
} else {
gch.text = cnv_escape(gch.text);
if (gch.font.box)
gch.box = true
if (gch.type == '@'
&& !user.anno_start && !user.anno_stop) {
gch.wh = [0, 0]
continue /* no width */
}
}
/* set the offsets and widths */
set_font(gch.font);
wh = strwh(gch.text);
gch.wh = wh
if (gch.box)
wh[1] += 4
switch (gch.type) {
case '@':
break
case '^': /* above */
xspc = wh[0] * GCHPRE
if (xspc > 8)
xspc = 8;
|
| ︙ | ︙ | |||
372 373 374 375 376 377 378 | break case '>': /* right */ gch.x = 6; y_right -= wh[1]; gch.y = y_right + wh[1] / 2 break default: // chord symbol | < < < < < < < < < | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
break
case '>': /* right */
gch.x = 6;
y_right -= wh[1];
gch.y = y_right + wh[1] / 2
break
default: // chord symbol
xspc = wh[0] * GCHPRE
if (xspc > 8)
xspc = 8;
gch.x = -xspc;
if (pos < 0) { /* below */
y_below -= wh[1];
gch.y = y_below
} else {
y_above -= wh[1];
gch.y = y_above
}
break
}
}
/* move upwards the top and middle texts */
y_left /= 2;
|
| ︙ | ︙ | |||
422 423 424 425 426 427 428 429 |
}
}
}
// -- draw the chord symbols and annotations
// (the staves are not yet defined)
// (unscaled delayed output)
function draw_gchord(s, gchy_min, gchy_max) {
| > | < | | < | > < < < | < > < < > > | | < | | < < > | | | | > | | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 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 |
}
}
}
// -- draw the chord symbols and annotations
// (the staves are not yet defined)
// (unscaled delayed output)
// (possible hook)
function draw_gchord(s, gchy_min, gchy_max) {
var gch, text, ix, x, y, y2, hbox, h, y_above, y_below,
// adjust the vertical offset according to the chord symbols
w = 0,
yav = s.dur ?
(((s.notes[s.nhd].pit + s.notes[0].pit) >> 1) - 18) * 3 :
12 // fixed offset on measure bars
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix]
if (gch.wh[0] > w)
w = gch.wh[0]
}
y_above = y_get(s.st, 1, s.x - 2, w);
y_below = y_get(s.st, 0, s.x - 2, w)
if (y_above < gchy_max)
y_above = gchy_max
if (y_below > gchy_min)
y_below = gchy_min;
set_dscale(s.st);
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix];
use_font(gch.font);
set_font(gch.font);
h = gch.font.size;
hbox = gch.box ? 2 : 0;
w = gch.wh[0];
x = s.x + gch.x;
text = gch.text
switch (gch.type) {
case '_': /* below */
y = gch.y + y_below;
y_set(s.st, 0, x, w, y - hbox)
break
case '^': /* above */
y = gch.y + y_above + hbox;
y_set(s.st, 1, x, w, y + h + hbox)
break
case '<': /* left */
/*fixme: what symbol space?*/
if (s.notes[0].acc)
x -= s.notes[0].shac;
y = gch.y + yav - h / 2
break
case '>': /* right */
if (s.xmx)
x += s.xmx
if (s.dots)
x += 1.5 + 3.5 * s.dots;
y = gch.y + yav - h / 2
break
default: // chord symbol
if (gch.y >= 0) {
y = gch.y + y_above + hbox;
y_set(s.st, true, x, w, y + h + hbox)
} else {
y = gch.y + y_below;
y_set(s.st, false, x, w, y - hbox)
}
break
case '@': /* absolute */
y = gch.y + yav
if (y > 0) {
y2 = y + h
if (y2 > staff_tb[s.st].ann_top)
staff_tb[s.st].ann_top = y2
} else {
if (y < staff_tb[s.st].ann_bot)
staff_tb[s.st].ann_bot = y
}
break
}
if (user.anno_start)
user.anno_start("annot", gch.istart, gch.iend,
x - 2, y + h + 2, w + 4, h + 4, s)
xy_str(x, y, text, null, null, gch.wh)
if (user.anno_stop)
user.anno_stop("annot", gch.istart, gch.iend,
x - 2, y + h + 2, w + 4, h + 4, s)
}
}
|
Changes to core/license.
1 | // abc2svg - ABC to SVG translator | | | | 1 2 3 | // abc2svg - ABC to SVG translator // @source: https://chiselapp.com/user/moinejf/repository/abc2svg // Copyright (C) 2014-2019 Jean-Francois Moine - LGPL3+ |
Changes to core/lyrics.js.
1 2 | // abc2svg - lyrics.js - lyrics // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - lyrics.js - lyrics // // Copyright (C) 2014-2019 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 |
while (p[i] == ' ' || p[i] == '\t')
i++;
c = p[i]
if (!c)
break
switch (c) {
case '|':
| | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
while (p[i] == ' ' || p[i] == '\t')
i++;
c = p[i]
if (!c)
break
switch (c) {
case '|':
while (s && s.type != C.BAR)
s = s.next
if (!s) {
syntax(1, "Not enough measure bars for symbol line")
return
}
s = s.next;
i++
|
| ︙ | ︙ | |||
91 92 93 94 95 96 97 | } } syntax(1, errs.bad_char, c) break } /* store the element in the next note */ | | | | | 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 |
}
}
syntax(1, errs.bad_char, c)
break
}
/* store the element in the next note */
while (s && (s.type != C.NOTE || s.grace))
s = s.next
if (!s) {
syntax(1, "Too many elements in symbol line")
return
}
switch (c) {
default:
// case '*':
break
case '!':
deco_cnv([d.slice(1, -1)], s, s.prev)
break
case '"':
a_gch = s.a_gch;
parse_gchord(d)
if (a_gch)
self.gch_build(s)
break
}
s = s.next;
i++
}
curvoice.lyric_cont = s
}
/* -- parse a lyric (vocal) line (w:) -- */
function get_lyrics(text, cont) {
var s, word, p, i, j, ly
if (curvoice.ignore)
return
if (curvoice.pos.voc != C.SL_HIDDEN)
curvoice.have_ly = true
// get the starting symbol of the lyrics
if (cont) { // +:
s = curvoice.lyric_cont
if (!s) {
syntax(1, "+: lyric without music")
|
| ︙ | ︙ | |||
162 163 164 165 166 167 168 |
while (p[i] == ' ' || p[i] == '\t')
i++
if (!p[i])
break
j = parse.istart + i + 2 // start index
switch (p[i]) {
case '|':
| | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
while (p[i] == ' ' || p[i] == '\t')
i++
if (!p[i])
break
j = parse.istart + i + 2 // start index
switch (p[i]) {
case '|':
while (s && s.type != C.BAR)
s = s.next
if (!s) {
syntax(1, "Not enough measure bars for lyric line")
return
}
s = s.next;
i++
|
| ︙ | ︙ | |||
199 200 201 202 203 204 205 | case '*': case '|': i-- case ' ': case '\t': break case '~': | | | | | | 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 |
case '*':
case '|':
i--
case ' ':
case '\t':
break
case '~':
word += 'Â '; // ( )
i++
continue
case '-':
word += "\n"
break
case '\\':
word += p[++i];
i++
continue
default:
word += p[i++]
continue
}
break
}
break
}
/* store the word in the next note */
while (s && (s.type != C.NOTE || s.grace))
s = s.next
if (!s) {
syntax(1, "Too many words in lyric line")
return
}
if (word
&& s.pos.voc != C.SL_HIDDEN) {
if (word.match(/^\$\d/)) {
if (word[1] == '0')
set_font("vocal")
else
set_font("u" + word[1]);
word = word.slice(2)
}
ly = {
t: word,
font: gene.curfont,
wh: strwh(word),
istart: j,
iend: j + word.length
}
if (!s.a_ly)
s.a_ly = []
s.a_ly[curvoice.lyric_line] = ly
}
|
| ︙ | ︙ | |||
267 268 269 270 271 272 273 |
if (!ly)
continue
p = ly.t;
if (p == "-\n" || p == "_\n") {
ly.shift = 0
continue
}
| | | | | | 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 |
if (!ly)
continue
p = ly.t;
if (p == "-\n" || p == "_\n") {
ly.shift = 0
continue
}
w = ly.wh[0];
swfac = ly.font.swfac;
xx = w + 2 * cwid(' ') * swfac
if (s.type == C.GRACE) { // %%graceword
shift = s.wl
} else if ((p[0] >= '0' && p[0] <= '9' && p.length > 2)
|| p[1] == ':'
|| p[0] == '(' || p[0] == ')') {
if (p[0] == '(') {
sz = cwid('(') * swfac
} else {
j = p.indexOf('Â '); // ( )
set_font(ly.font)
if (j > 0)
sz = strwh(p.slice(0, j))[0]
else
sz = w * .2
}
shift = (w - sz + 2 * cwid(' ') * swfac) * .4
if (shift > 20)
shift = 20;
shift += sz
if (ly.t[0] >= '0' && ly.t[0] <= '9') {
if (shift > align)
|
| ︙ | ︙ | |||
307 308 309 310 311 312 313 |
wlw = shift;
// if (p[p.length - 1] == "\n") // if "xx-"
// xx -= cwid(' ') * swfac
xx -= shift;
shift = 2 * cwid(' ') * swfac
for (k = s.next; k; k = k.next) {
switch (k.type) {
| | | | < | | | | 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 |
wlw = shift;
// if (p[p.length - 1] == "\n") // if "xx-"
// xx -= cwid(' ') * swfac
xx -= shift;
shift = 2 * cwid(' ') * swfac
for (k = s.next; k; k = k.next) {
switch (k.type) {
case C.NOTE:
case C.REST:
if (!k.a_ly || !k.a_ly[i])
xx -= 9
else if (k.a_ly[i].t == "-\n"
|| k.a_ly[i].t == "_\n")
xx -= shift
else
break
if (xx <= 0)
break
continue
case C.CLEF:
case C.METER:
case C.KEY:
xx -= 10
continue
default:
xx -= 5
break
}
break
|
| ︙ | ︙ | |||
356 357 358 359 360 361 362 |
hyflag, lflag, x0, font, shift
if (p_voice.hy_st & (1 << j)) {
hyflag = true;
p_voice.hy_st &= ~(1 << j)
}
for (s = p_voice.sym; /*s*/; s = s.next)
| | | | | | | 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 |
hyflag, lflag, x0, font, shift
if (p_voice.hy_st & (1 << j)) {
hyflag = true;
p_voice.hy_st &= ~(1 << j)
}
for (s = p_voice.sym; /*s*/; s = s.next)
if (s.type != C.CLEF
&& s.type != C.KEY && s.type != C.METER)
break
lastx = s.prev ? s.prev.x : tsfirst.x;
x0 = 0
for ( ; s; s = s.next) {
if (s.a_ly)
ly = s.a_ly[j]
else
ly = null
if (!ly) {
switch (s.type) {
case C.REST:
case C.MREST:
if (lflag) {
out_wln(lastx + 3, y, x0 - lastx);
lflag = false;
lastx = s.x + s.wr
}
}
continue
}
if (ly.font != gene.curfont) /* font change */
gene.curfont = font = ly.font;
p = ly.t;
w = ly.wh[0];
shift = ly.shift
if (hyflag) {
if (p == "_\n") { /* '_' */
p = "-\n"
} else if (p != "-\n") { /* not '-' */
out_hyph(lastx, y, s.x - shift - lastx);
hyflag = false;
|
| ︙ | ︙ | |||
428 429 430 431 432 433 434 | ymn: y, ymx: y + gene.curfont.size, wl: 0, wr: w } anno_start(s2, 'lyrics') } | | | | 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 |
ymn: y,
ymx: y + gene.curfont.size,
wl: 0,
wr: w
}
anno_start(s2, 'lyrics')
}
xy_str(x0, y, p, null, null, ly.wh);
anno_stop(s2, 'lyrics')
lastx = x0 + w
}
if (hyflag) {
hyflag = false;
x0 = realwidth - 10
if (x0 < lastx + 10)
x0 = lastx + 10;
out_hyph(lastx, y, x0 - lastx)
if (cfmt.hyphencont)
p_voice.hy_st |= (1 << j)
}
/* see if any underscore in the next line */
for (p_voice.s_next ; s; s = s.next) {
if (s.type == C.NOTE) {
if (!s.a_ly)
break
ly = s.a_ly[j]
if (ly && ly.t == "_\n") {
lflag = true;
x0 = realwidth - 15
if (x0 < lastx + 12)
|
| ︙ | ︙ | |||
530 531 532 533 534 535 536 |
if (!a_ly)
continue
/*fixme:should get the real width*/
x = s.x;
w = 10
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
| | | | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
if (!a_ly)
continue
/*fixme:should get the real width*/
x = s.x;
w = 10
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
if (ly) {
x -= ly.shift;
w = ly.wh[0]
break
}
}
y = y_get(p_voice.st, 1, x, w)
if (top < y)
top = y;
y = y_get(p_voice.st, 0, x, w)
|
| ︙ | ︙ | |||
569 570 571 572 573 574 575 |
lyst_tb[st] = {}
lyst_tb[st].top = top;
lyst_tb[st].bot = bot;
nly_tb[v] = nly
if (nly == 0)
continue
if (p_voice.pos.voc)
| | | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 |
lyst_tb[st] = {}
lyst_tb[st].top = top;
lyst_tb[st].bot = bot;
nly_tb[v] = nly
if (nly == 0)
continue
if (p_voice.pos.voc)
above_tb[v] = p_voice.pos.voc == C.SL_ABOVE
else if (voice_tb[v + 1]
/*fixme:%%staves:KO - find an other way..*/
&& voice_tb[v + 1].st == st
&& voice_tb[v + 1].have_ly)
above_tb[v] = true
else
above_tb[v] = false
|
| ︙ | ︙ |
Changes to core/modules.js.
1 2 | // abc2svg - modules.js - module handling // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - modules.js - module handling // // Copyright (C) 2018-2019 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. |
| ︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 |
ambitus: { fn: 'ambitus-1.js' },
beginps: { fn: 'psvg-1.js' },
break: { fn: 'break-1.js' },
capo: { fn: 'capo-1.js' },
clip: { fn: 'clip-1.js' },
voicecombine: { fn: 'combine-1.js' },
diagram: { fn: 'diag-1.js' },
grid: { fn: 'grid-1.js' },
grid2: { fn: 'grid2-1.js' },
MIDI: { fn: 'MIDI-1.js' },
percmap: { fn: 'perc-1.js' },
sth: { fn: 'sth-1.js' },
| > > > > | < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
ambitus: { fn: 'ambitus-1.js' },
beginps: { fn: 'psvg-1.js' },
break: { fn: 'break-1.js' },
capo: { fn: 'capo-1.js' },
clip: { fn: 'clip-1.js' },
voicecombine: { fn: 'combine-1.js' },
diagram: { fn: 'diag-1.js' },
equalbars: { fn: 'equalbars-1.js' },
grid: { fn: 'grid-1.js' },
grid2: { fn: 'grid2-1.js' },
MIDI: { fn: 'MIDI-1.js' },
pageheight: { fn: 'page-1.js' },
percmap: { fn: 'perc-1.js' },
soloffs: { fn: 'soloffs-1.js' },
sth: { fn: 'sth-1.js' },
temperament: { fn: 'temper-1.js' },
nreq: 0,
hooks: [],
g_hooks: [],
// scan the file and find the required modules
// @file: ABC file
// @relay: (optional) callback function for continuing the treatment
|
| ︙ | ︙ | |||
58 59 60 61 62 63 64 |
return function(m) { alert(m) }
if (typeof console == 'object')
return console.log
return function(){}
}
// test if some keyword in the file
| | > | | | < | | | < < < < < | 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 |
return function(m) { alert(m) }
if (typeof console == 'object')
return console.log
return function(){}
}
// test if some keyword in the file
var m, r,
nreq_i = this.nreq,
ls = file.match(/(^|\n)(%%|I:).+?\b/g)
if (!ls)
return true
this.cbf = relay || // (only one callback function)
function(){}
this.errmsg = errmsg || get_errmsg()
for (var i = 0; i < ls.length; i++) {
m = abc2svg.modules[ls[i].replace(/\n?(%%|I:)/, '')]
if (!m || m.loaded)
continue
m.loaded = true
// load the module
this.nreq++;
abc2svg.loadjs(m.fn,
|
| ︙ | ︙ |
Changes to core/music.js.
1 2 | // abc2svg - music.js - music generation // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - music.js - music generation // // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
19 20 21 22 23 24 25 | var gene, staff_tb, nstaff, // current number of staves tsnext, // next line when cut realwidth, // real staff width while generating insert_meter, // insert time signature (1) and indent 1st line (2) | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | var gene, staff_tb, nstaff, // current number of staves tsnext, // next line when cut realwidth, // real staff width while generating insert_meter, // insert time signature (1) and indent 1st line (2) spf_last, // spacing for last short line /* width of notes indexed by log2(note_length) */ space_tb = new Float32Array([ 7, 10, 14.15, 20, 28.3, 40, /* crotchet (whole note / 4) */ 56.6, 80, 100, 120 ]), |
| ︙ | ︙ | |||
114 115 116 117 118 119 120 | if (dx_max < -dx) dx_max = -dx continue } } if (d < 0) d = -d | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
if (dx_max < -dx)
dx_max = -dx
continue
}
}
if (d < 0)
d = -d
if (d > 3 || (d >= 2 && s.head != C.SQUARE)) {
shift = false
} else {
shift = !shift
if (shift) {
s.notes[i].shhd = dx
if (dx_max < dx)
dx_max = dx
|
| ︙ | ︙ | |||
195 196 197 198 199 200 201 |
/* this routine is called only once per tune */
function set_acc_shft() {
var s, s2, st, i, acc, st, t, dx_head;
// search the notes with accidentals at the same time
s = tsfirst
while (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 |
/* this routine is called only once per tune */
function set_acc_shft() {
var s, s2, st, i, acc, st, t, dx_head;
// search the notes with accidentals at the same time
s = tsfirst
while (s) {
if (s.type != C.NOTE
|| s.invis) {
s = s.ts_next
continue
}
st = s.st;
t = s.time;
acc = false
for (s2 = s; s2; s2 = s2.ts_next) {
if (s2.time != t
|| s2.type != C.NOTE
|| s2.st != st)
break
if (acc)
continue
for (i = 0; i <= s2.nhd; i++) {
if (s2.notes[i].acc) {
acc = true
break
}
}
}
if (!acc) {
s = s2
continue
}
dx_head = dx_tb[s.head]
// if (s.dur >= C.BLEN * 2 && s.head == C.OVAL)
// if (s.dur >= C.BLEN * 2)
// dx_head = 15.8;
// build a pseudo chord and shift the accidentals
st = {
notes: []
}
for ( ; s != s2; s = s.ts_next)
|
| ︙ | ︙ | |||
269 270 271 272 273 274 275 |
if (s.next)
s.next.prev = s.prev
if (s.prev)
s.prev.next = s.next
else
s.p_v.sym = s.next
if (s.ts_next) {
| | > > > > > | > | | | 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 |
if (s.next)
s.next.prev = s.prev
if (s.prev)
s.prev.next = s.next
else
s.p_v.sym = s.next
if (s.ts_next) {
if (s.seqst) {
if (s.ts_next.seqst) {
s.ts_next.shrink += s.shrink;
s.ts_next.space += s.space
} else {
s.ts_next.seqst = true;
s.ts_next.shrink = s.shrink;
s.ts_next.space = s.space
}
}
s.ts_next.ts_prev = s.ts_prev
}
if (s.ts_prev)
s.ts_prev.ts_next = s.ts_next
if (tsfirst == s)
tsfirst = s.ts_next
if (tsnext == s)
tsnext = s.ts_next
}
/* -- insert a clef change (treble or bass) before a symbol -- */
function insert_clef(s, clef_type, clef_line) {
var p_voice = s.p_v,
new_s,
st = s.st
/* don't insert the clef between two bars */
if (s.type == C.BAR && s.prev && s.prev.type == C.BAR
&& s.prev.bar_type[0] != ':')
s = s.prev;
/* create the symbol */
p_voice.last_sym = s.prev
if (!p_voice.last_sym)
p_voice.sym = null;
p_voice.time = s.time;
new_s = sym_add(p_voice, C.CLEF);
new_s.next = s;
s.prev = new_s;
new_s.clef_type = clef_type;
new_s.clef_line = clef_line;
new_s.st = st;
new_s.clef_small = true
delete new_s.second;
new_s.notes = []
new_s.notes[0] = {
pit: s.notes[0].pit
}
new_s.nhd = 0;
/* link in time */
while (!s.seqst)
s = s.ts_prev;
lktsym(new_s, s)
if (new_s.ts_prev.type != C.CLEF)
new_s.seqst = true
return new_s
}
/* -- set the staff of the floating voices -- */
/* this function is called only once per tune */
function set_float() {
|
| ︙ | ︙ | |||
361 362 363 364 365 366 367 |
continue
}
up = 127
for (s1 = s.ts_prev; s1; s1 = s1.ts_prev) {
if (s1.st != st
|| s1.v == s.v)
break
| | | | 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 |
continue
}
up = 127
for (s1 = s.ts_prev; s1; s1 = s1.ts_prev) {
if (s1.st != st
|| s1.v == s.v)
break
if (s1.type == C.NOTE)
if (s1.notes[0].pit < up)
up = s1.notes[0].pit
}
if (up == 127) {
if (staff_chg)
s.st++
continue
}
if (s.notes[s.nhd].pit > up - 3) {
staff_chg = false
continue
}
down = -127
for (s1 = s.ts_next; s1; s1 = s1.ts_next) {
if (s1.st != st + 1
|| s1.v == s.v)
break
if (s1.type == C.NOTE)
if (s1.notes[s1.nhd].pit > down)
down = s1.notes[s1.nhd].pit
}
if (down == -127) {
if (staff_chg)
s.st++
continue
|
| ︙ | ︙ | |||
412 413 414 415 416 417 418 |
s.st++
}
}
}
/* -- set the x offset of the grace notes -- */
function set_graceoffs(s) {
| | | | | < > > > > | | | | | | < | | | | > | | > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > > > > > > > | < < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | > | > | | | | | | | | | | | > > | | | | | | | | | | | | < | < < < < < | < < < < < | | | < < | | > | | < < | 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 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 646 647 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 |
s.st++
}
}
}
/* -- set the x offset of the grace notes -- */
function set_graceoffs(s) {
var next, m, dx, x,
gspleft = cfmt.gracespace[0],
gspinside = cfmt.gracespace[1],
gspright = cfmt.gracespace[2],
g = s.extra;
if (s.prev && s.prev.type == C.BAR)
gspleft -= 3;
x = gspleft;
g.beam_st = true
for ( ; ; g = g.next) {
set_head_shift(g)
acc_shift(g.notes, 7);
dx = 0
for (m = g.nhd; m >= 0; m--) {
if (g.notes[m].shac > dx)
dx = g.notes[m].shac
}
x += dx;
g.x = x
if (g.nflags <= 0) {
g.beam_st = true;
g.beam_end = true
}
next = g.next
if (!next) {
g.beam_end = true
break
}
if (next.nflags <= 0)
g.beam_end = true
if (g.beam_end) {
next.beam_st = true;
x += gspinside / 4
}
if (g.nflags <= 0)
x += gspinside / 4
if (g.y > next.y + 8)
x -= 1.5
x += gspinside
}
next = s.next
if (next
&& next.type == C.NOTE) { /* if before a note */
if (g.y >= 3 * (next.notes[next.nhd].pit - 18))
gspright -= 1 // above, a bit closer
else if (g.beam_st
&& g.y < 3 * (next.notes[next.nhd].pit - 18) - 4)
gspright += 2 // below with flag, a bit further
}
x += gspright;
/* return the whole width */
return x
}
// Compute the smallest spacing between symbols according to chord symbols
// so that they stay at the same offset.
// Constraints:
// - assume the chord symbols are only in the first staff
// - treat only the first chord symbol of each symbol
// - the chord symbol under the staff are ignored
function set_w_chs(s) {
var i, ch, ch0, s0, dw, x,
n = 0
for ( ; s; s = s.ts_next) {
if (s.shrink) {
x += s.shrink;
n++
}
if (!s.a_gch)
continue
for (i = 0; i < s.a_gch.length; i++) {
ch = s.a_gch[i]
if (ch.type != 'g' || ch.y < 0) // upper chord symbol only
continue
if (ch0) {
if (ch0.w > x + ch.x) {
dw = (ch0.w - x - ch.x) / n
while (1) {
s0 = s0.ts_next
if (s0.shrink)
s0.shrink += dw
if (s0 == s)
break
}
}
}
s0 = s;
ch0 = ch;
n = 0;
// x = ch.box ? -2 : 0
x = 0
break
}
}
}
// compute the width needed by the left and right annotations
function gchord_width(s, wlnote, wlw) {
var gch, w, ix,
arspc = 0
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix]
switch (gch.type) {
case '<': /* left */
w = gch.w + wlnote
if (w > wlw)
wlw = w
break
case '>': /* right */
w = gch.w + s.wr
if (w > arspc)
arspc = w
break
}
}
if (s.wr < arspc)
s.wr = arspc
return wlw
}
/* -- set the width of a symbol -- */
/* This routine sets the minimal left and right widths wl,wr
* so that successive symbols are still separated when
* no extra glue is put between them */
// (possible hook)
function set_width(s) {
var s2, i, m, xx, w, wlnote, wlw, acc,
bar_type, meter, last_acc, n1, n2, esp, tmp
switch (s.type) {
case C.NOTE:
case C.REST:
/* set the note widths */
s.wr = wlnote = 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] != 0)
break
}
if (s2) {
switch (s2.type) {
case C.BAR:
case C.CLEF:
case C.KEY:
case C.METER:
wlnote += 3
break
}
}
for (m = 0; m <= s.nhd; m++) {
xx = s.notes[m].shhd
if (xx < 0) {
if (wlnote < -xx + 5)
wlnote = -xx + 5
}
if (s.notes[m].acc) {
tmp = s.notes[m].shac +
(s.notes[m].micro ? 5.5 : 3.5)
if (wlnote < tmp)
wlnote = tmp
}
}
if (s2) {
switch (s2.type) {
case C.BAR:
case C.CLEF:
case C.KEY:
case C.METER:
wlnote -= 3
break
}
} else {
wlnote += 8 // (start of tune)
}
/* room for the decorations */
if (s.a_dd)
wlnote += deco_width(s)
/* space for flag if stem goes up on standalone note */
if (s.beam_st && s.beam_end
&& s.stem > 0 && s.nflags > 0) {
if (s.wr < s.xmx + 9)
s.wr = s.xmx + 9
}
/* leave room for dots and set their offset */
if (s.dots) {
if (s.wl == undefined) // don't recompute if new music line
switch (s.head) {
case C.SQUARE:
s.xmx += 4
break
case C.OVALBARS:
case C.OVAL:
s.xmx += 2
break
case C.EMPTY:
s.xmx += 1
break
}
if (s.wr < s.xmx + 8)
s.wr = s.xmx + 8
if (s.dots >= 2)
s.wr += 3.5 * (s.dots - 1)
}
/* if a tremolo on 2 notes, have space for the small beam(s) */
if (s.trem2 && s.beam_end
&& wlnote < 20)
wlnote = 20
wlw = wlnote
if (s2) {
switch (s2.type) {
case C.NOTE: /* extra space when up stem - down stem */
if (s2.stem > 0 && s.stem < 0) {
if (wlw < 7)
wlw = 7
}
/* make sure helper lines don't overlap */
if ((s.y > 27 && s2.y > 27)
|| (s.y < -3 && s2.y < -3)) {
if (wlw < 6)
wlw = 6
}
/* have ties wide enough */
if (s2.ti1) {
if (wlw < 14)
wlw = 14
}
break
case C.CLEF: /* extra space at start of line */
if (s2.second
|| s2.clef_small)
break
wlw += 8
break
case C.KEY:
/* case C.METER: */
wlw += 4
break
}
}
/* leave room for guitar chord */
if (s.a_gch)
wlw = gchord_width(s, wlnote, wlw)
/* leave room for vocals under note */
/* related to draw_lyrics() */
if (s.a_ly)
wlw = ly_width(s, wlw)
/* if preceeded by a grace note sequence, adjust */
if (s2 && s2.type == C.GRACE)
s.wl = wlnote - 4.5
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)
xx += deco_width(s);
s.wl = xx
return
case C.BAR:
if (s.norepbra)
break
bar_type = s.bar_type
switch (bar_type) {
case "|":
w = 5 // 3 + 2
break
default:
w = 2 + 2.8 * bar_type.length
for (i = 0; i < bar_type.length; i++) {
switch (bar_type[i]) {
case "[":
case "]":
w += 3
break
case ":":
w += 2
break
}
}
break
}
s.wl = w
if (s.next
&& 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) {
if (w_tb[s2.type] != 0) {
if (s2.type == C.GRACE)
s.wl -= 8
break
}
}
if (s.a_dd)
s.wl += deco_width(s)
/* have room for the repeat numbers / chord indication */
if (s.text && s.text.length < 4
&& s.next && s.next.a_gch) {
set_font("repeat");
s.wr += strwh(s.text)[0] + 2
}
return
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 ? 9 : 12
s.wr = s.clef_small ? 7 : 12
return
case C.KEY:
s.wl = 3;
esp = 4
if (!s.k_a_acc) {
n1 = s.k_sf /* new key sig */
if (s.k_old_sf && (cfmt.cancelkey || n1 == 0))
n2 = s.k_old_sf /* old key */
else
|
| ︙ | ︙ | |||
788 789 790 791 792 793 794 |
if (n1 < 0)
n1 = -n1;
esp += 3 /* see extra space in draw_keysig() */
}
} else {
n1 = n2 = s.k_a_acc.length
if (n2)
| | | | | > > > > | > > > > | 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 |
if (n1 < 0)
n1 = -n1;
esp += 3 /* see extra space in draw_keysig() */
}
} else {
n1 = n2 = s.k_a_acc.length
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
}
}
s.wr = 5.5 * n1 + esp
return
case C.METER:
wlw = 0;
s.x_meter = []
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;
wlw += 12
break
case '.':
case '|':
s.x_meter[i] = s.x_meter[i - 1]
break
default:
w = 0
if (!meter.bot
|| meter.top.length > meter.bot.length)
meter = meter.top
else
meter = meter.bot;
for (m = 0; m < meter.length; m++) {
|
| ︙ | ︙ | |||
837 838 839 840 841 842 843 | s.x_meter[i] = wlw + w / 2 wlw += w } } s.wl = 0; s.wr = wlw + 6 return | | | | | | > > > > > > > > > > > > > > > | | | | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < | < | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > > > > > | | | > | | > > | < < > > | > > > > > | | | | | | < | | > > | > | > > > > > > > > > > > > > > > > > > > > > | < > | > > > > > | | > > > > > > | | 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 874 875 876 877 878 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 950 951 952 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 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 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 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 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 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 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 1206 1207 1208 1209 1210 1211 |
s.x_meter[i] = wlw + w / 2
wlw += w
}
}
s.wl = 0;
s.wr = wlw + 6
return
case C.MREST:
s.wl = 6;
s.wr = 66
return
case C.GRACE:
s.wl = set_graceoffs(s);
s.wr = 0
if (s.a_ly)
ly_width(s, wlw)
return
case C.STBRK:
s.wl = s.xmx
if (s.next && s.next.type == C.CLEF) {
s.wr = 2
delete s.next.clef_small /* big clef */
} else {
s.wr = 8
}
return
case C.CUSTOS:
s.wl = s.wr = 4
return
case C.TEMPO: // no width, but set here the [w,h] of the strings
set_font("tempo")
if (s.tempo_str1)
s.tempo_wh1 = strwh(s.tempo_str1)
if (s.tempo_notes ) {
s.tempo_str0 = '= '
if (s.tempo_ca)
s.tempo_str0 += s.tempo_ca
if (s.tempo)
s.tempo_str0 += s.tempo;
s.tempo_wh0 = strwh(s.tempo_str0)
}
if (s.tempo_str2)
s.tempo_wh2 = strwh(s.tempo_str2)
break
case C.BLOCK: // no width
case C.PART:
case C.REMARK:
case C.STAVES:
break
default:
error(2, s, "set_width - Cannot set width for symbol $1", s.type)
break
}
s.wl = s.wr = 0
}
// convert delta time to natural spacing
function time2space(s, len) {
var i, l, space
if (smallest_duration >= C.BLEN / 2) {
if (smallest_duration >= C.BLEN)
len /= 4
else
len /= 2
} else if (!s.next && len >= C.BLEN) {
len /= 2
}
if (len >= C.BLEN / 4) {
if (len < C.BLEN / 2)
i = 5
else if (len < C.BLEN)
i = 6
else if (len < C.BLEN * 2)
i = 7
else if (len < C.BLEN * 4)
i = 8
else
i = 9
} else {
if (len >= C.BLEN / 8)
i = 4
else if (len >= C.BLEN / 16)
i = 3
else if (len >= C.BLEN / 32)
i = 2
else if (len >= C.BLEN / 64)
i = 1
else
i = 0
}
l = len - ((C.BLEN / 16 / 8) << i)
space = space_tb[i]
if (l != 0) {
if (l < 0) {
space = space_tb[0] * len / (C.BLEN / 16 / 8)
} else {
if (i >= 9)
i = 8
space += (space_tb[i + 1] - space_tb[i]) * l / len
}
}
return space
}
/* -- set the natural space -- */
function set_space(s) {
var s2, space,
prev_time = s.ts_prev.time,
len = s.time - prev_time /* time skip */
if (len == 0) {
switch (s.type) {
case C.MREST:
return s.wl
///*fixme:do same thing at start of line*/
// case C.NOTE:
// case C.REST:
// if (s.ts_prev.type == C.BAR) {
// if (s.nflags < -2)
// return space_tb[0]
// return space_tb[2]
// }
// break
}
return 0
}
if (s.ts_prev.type == C.MREST)
// return s.ts_prev.wr + 16
// + 3 // (bar wl=5 wr=8)
return 71 // 66 (mrest.wl) + 5 (bar.wl)
space = time2space(s, len)
while (!s.dur) {
switch (s.type) {
case C.BAR:
// (hack to have quite the same note widths between measures)
return space * .9 - 7
case C.CLEF:
return space - s.wl - s.wr
case C.BLOCK: // no space
case C.PART:
case C.REMARK:
case C.STAVES:
case C.TEMPO:
s = s.ts_next
if (!s)
return space
continue
}
break
}
/* reduce spacing within a beam */
if (!s.beam_st)
space *= .9 // ex fnnp
/* decrease spacing when stem down followed by stem up */
/*fixme:to be done later, after x computed in sym_glue*/
if (s.type == C.NOTE && s.nflags >= -1
&& s.stem > 0) {
var stemdir = true
for (s2 = s.ts_prev;
s2 && s2.time == prev_time;
s2 = s2.ts_prev) {
if (s2.type == C.NOTE
&& (s2.nflags < -1 || s2.stem > 0)) {
stemdir = false
break
}
}
if (stemdir) {
for (s2 = s.ts_next;
s2 && s2.time == s.time;
s2 = s2.ts_next) {
if (s2.type == C.NOTE
&& (s2.nflags < -1 || s2.stem < 0)) {
stemdir = false
break
}
}
if (stemdir)
space *= .9
}
}
return space
}
// set a fixed spacing inside tuplets
function set_sp_tup(s, s_et) {
var s2,
tim = s.time,
endtime = s_et.time + s_et.dur,
ttim = endtime - tim,
space = time2space(s, ttim / s.tq0) * s.tq0 / ttim
// start on the second note/rest
do {
s = s.ts_next
} while (!s.seqst)
//fixme: problem when BAR inside the tuplet sequence (in case user error)
// while (!s.dur)
// s = s.ts_next
// while (!s.seqst)
// s = s.ts_prev
// stop outside the tuplet sequence
// and add a measure bar when at end of tune
do {
if (!s_et.ts_next) {
s2 = add_end_bar(s_et);
s_et = s2
} else {
s_et = s_et.ts_next
}
} while (!s_et.seqst)
// check the minimum spacing
s2 = s
while (1) {
if (s2.dur
&& s2.dur * space < s2.shrink)
space = s2.shrink / s2.dur
if (s2 == s_et)
break
s2 = s2.ts_next
}
// set the space values
while (1) {
if (s.seqst) {
s.space = (s.time - tim) * space;
tim = s.time
}
if (s == s_et)
break
s = s.ts_next
}
}
// create an invisible bar for end of music lines
function add_end_bar(s) {
var bar = {
type: C.BAR,
bar_type: "|",
fname: s.fname,
istart: s.istart,
iend: s.iend,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: 0,
seqst: true,
invis: true,
time: s.time + s.dur,
nhd: 0,
notes: [{
pit: s.notes[0].pit
}],
wl: 0,
wr: 0,
prev: s,
ts_prev: s,
shrink: s.wr + 3
}
s.next = s.ts_next = bar
return bar
}
/* -- set the width and space of all symbols -- */
/* this function is called once for the whole tune
* then, once per music line up to the first sequence */
function set_allsymwidth() {
var maxx, new_val, s_tupc, s_tupn, st, s_chs,
s = tsfirst,
s2 = s,
xa = 0,
xl = [],
wr = [],
ntup = 0
/* loop on all symbols */
while (1) {
maxx = xa
do {
if (s.a_gch && !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;
new_val = xl[st] + wr[st] + s.wl
if (new_val > maxx)
maxx = new_val;
s = s.ts_next
} while (s && !s.seqst);
// set the spaces of the time sequence
s2.shrink = maxx - xa
if (!ntup) // if not inside a tuplet sequence
s2.space = s2.ts_prev ? set_space(s2) : 0
if (s2.shrink == 0 && s2.space == 0 && s2.type == C.CLEF) {
delete s2.seqst; /* no space */
s2.time = s2.ts_prev.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
if (s2.tp0 // start of tuplet
&& ++ntup == 1
&& !s_tupc)
s_tupc = s2; // keep the first tuplet address
if (s2.te0) // end of tuplet
ntup--;
s2 = s2.ts_next
} while (!s2.seqst)
}
// let the chord symbols at the same offset
if (s_chs)
set_w_chs(s_chs)
// adjust the spacing inside the tuplets
s = s_tupc
if (!s)
return
do {
s2 = s; // start of tuplet
ntup = 1
do { // search the end of the tuplet sequence
s = s.ts_next
if (s.tp0)
ntup++
if (s.te0)
ntup--
} while (ntup != 0);
set_sp_tup(s2, s)
do { // search next tuplet
s = s.ts_next
} while (s && !s.tp0)
} while (s)
}
/* change a symbol into a rest */
function to_rest(s) {
s.type = C.REST
// just keep nl and seqst
delete s.in_tuplet
delete s.sl1
delete s.sl2
delete s.a_dd
delete s.a_gch
s.slur_start = s.slur_end = 0
|
| ︙ | ︙ | |||
1096 1097 1098 1099 1100 1101 1102 |
/* treat the sequence repeat */
if (n < 0) { /* number of notes / measures */
n = -n;
i = n /* number of notes to repeat */
for (s3 = s.prev; s3; s3 = s3.prev) {
if (!s3.dur) {
| | | | | 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 |
/* treat the sequence repeat */
if (n < 0) { /* number of notes / measures */
n = -n;
i = n /* number of notes to repeat */
for (s3 = s.prev; s3; s3 = s3.prev) {
if (!s3.dur) {
if (s3.type == C.BAR) {
error(1, s3, "Bar in repeat sequence")
return
}
continue
}
if (--i <= 0)
break
}
if (!s3) {
error(1, s, errs.not_enough_n)
return
}
dur = s.time - s3.time;
i = k * n /* whole number of notes/rests to repeat */
for (s2 = s; s2; s2 = s2.next) {
if (!s2.dur) {
if (s2.type == C.BAR) {
error(1, s2, "Bar in repeat sequence")
return
}
continue
}
if (--i <= 0)
break
}
if (!s2
|| !s2.next) { /* should have some symbol */
error(1, s, errs.not_enough_n)
return
}
for (s2 = s.prev; s2 != s3; s2 = s2.prev) {
if (s2.type == C.NOTE) {
s2.beam_end = true
break
}
}
for (j = k; --j >= 0; ) {
i = n /* number of notes/rests */
if (s.dur)
|
| ︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | } s2 = s2.ts_next } to_rest(s); s.dur = s.notes[0].dur = dur; s.rep_nb = -1; // single repeat s.beam_st = true; | | | | | | 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 |
}
s2 = s2.ts_next
}
to_rest(s);
s.dur = s.notes[0].dur = dur;
s.rep_nb = -1; // single repeat
s.beam_st = true;
self.set_width(s)
if (s.seqst)
s.space = set_space(s);
s.head = C.SQUARE;
for (s = s2; s; s = s.ts_next) {
if (s.st == st
&& s.v == v
&& s.dur)
break
}
}
return
}
/* check the measure repeat */
i = n /* number of measures to repeat */
for (s2 = s.prev.prev ; s2; s2 = s2.prev) {
if (s2.type == C.BAR
|| s2.time == tsfirst.time) {
if (--i <= 0)
break
}
}
if (!s2) {
error(1, s, errs.not_enough_m)
return
}
dur = s.time - s2.time /* repeat duration */
if (n == 1)
i = k /* repeat number */
else
i = n /* check only 2 measures */
for (s2 = s; s2; s2 = s2.next) {
if (s2.type == C.BAR) {
if (--i <= 0)
break
}
}
if (!s2) {
error(1, s, errs.not_enough_m)
return
|
| ︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 |
dur /= n
if (n == 2) { /* repeat 2 measures (once) */
s3 = s
for (s2 = s.ts_next; ; s2 = s2.ts_next) {
if (s2.st != st)
continue
if (s2.v == v
| | | | | | 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 |
dur /= n
if (n == 2) { /* repeat 2 measures (once) */
s3 = s
for (s2 = s.ts_next; ; s2 = s2.ts_next) {
if (s2.st != st)
continue
if (s2.v == v
&& s2.type == C.BAR)
break
unlksym(s2)
}
to_rest(s3);
s3.dur = s3.notes[0].dur = dur;
s3.invis = true
if (s3.seqst)
s3.space = set_space(s3);
s2.bar_mrep = 2
if (s2.seqst)
s2.space = set_space(s2);
s3 = s2.next;
for (s2 = s3.ts_next; ; s2 = s2.ts_next) {
if (s2.st != st)
continue
if (s2.v == v
&& s2.type == C.BAR)
break
unlksym(s2)
}
to_rest(s3);
s3.dur = s3.notes[0].dur = dur;
s3.invis = true;
self.set_width(s3)
if (s3.seqst)
s3.space = set_space(s3)
if (s2.seqst)
s2.space = set_space(s2)
return
}
/* repeat 1 measure */
s3 = s
for (j = k; --j >= 0; ) {
for (s2 = s3.ts_next; ; s2 = s2.ts_next) {
if (s2.st != st)
continue
if (s2.v == v
&& s2.type == C.BAR)
break
unlksym(s2)
}
to_rest(s3);
s3.dur = s3.notes[0].dur = dur;
s3.beam_st = true
if (s3.seqst)
|
| ︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 |
/* add a custos before the symbol of the next line */
function custos_add(s) {
var p_voice, new_s, i,
s2 = s
while (1) {
| | | | | | | | | 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 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 |
/* add a custos before the symbol of the next line */
function custos_add(s) {
var p_voice, new_s, i,
s2 = s
while (1) {
if (s2.type == C.NOTE)
break
s2 = s2.next
if (!s2)
return
}
p_voice = s.p_v;
p_voice.last_sym = s.prev;
// if (!p_voice.last_sym)
// p_voice.sym = null;
p_voice.time = s.time;
new_s = sym_add(p_voice, C.CUSTOS);
new_s.next = s;
s.prev = new_s;
lktsym(new_s, s);
new_s.seqst = true;
new_s.shrink = s.shrink
if (new_s.shrink < 8 + 4)
new_s.shrink = 8 + 4;
new_s.space = s2.space;
new_s.wl = 0;
new_s.wr = 4;
new_s.nhd = s2.nhd;
new_s.notes = []
for (i = 0; i < s.notes.length; i++) {
new_s.notes[i] = {
pit: s2.notes[i].pit,
shhd: 0,
dur: C.BLEN / 4
}
}
new_s.stemless = true
}
/* -- define the beginning of a new music line -- */
function set_nl(s, eoln) {
var s2, s3, p_voice, done
// set the end of line marker and ...
function set_eol(s) {
if (cfmt.custos && voice_tb.length == 1)
custos_add(s)
// ... set the nl flag if more music
for (var s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.seqst) {
s.nl = true
break
}
}
} // set_eol()
|
| ︙ | ︙ | |||
1352 1353 1354 1355 1356 1357 1358 1359 1360 |
if (s.seqst) {
set_eol(s)
break
}
}
return s
} // set_eol_next()
/* if explicit EOLN, cut on the next symbol */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | < < < < < < < < | | < < < < < < < | | | | | | | < < < < | < < < < | | | | | 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 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 1632 1633 1634 1635 1636 1637 1638 1639 1640 |
if (s.seqst) {
set_eol(s)
break
}
}
return s
} // set_eol_next()
// go to the end of the time sequence
// for adding keywarn or timewarn
while (s) {
if (!s.ts_next)
return // null
if (s.ts_next.seqst)
break
s = s.ts_next
}
// if keywarn or timewarn, move K: and M: to the end of the previous line
if (cfmt.keywarn || cfmt.timewarn) {
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
switch (s2.type) {
case C.BAR:
case C.CLEF:
continue
case C.KEY:
if (!cfmt.keywarn)
continue
case C.METER:
if (s2.type == C.METER && !cfmt.timewarn)
continue
s3 = s2.ts_prev;
if (s3 == s) { // if next symbol
s = s2 // advance the eol
continue
}
unlksym(s2); // remove
lktsym(s2, s.ts_next); // link in time at eol
s = s2
while (1) { // link in voice
s2 = s2.ts_prev
if (s2.v == s.v) {
s.next = s2.next;
s.prev = s2;
s.next.prev = s;
s2.next = s
break
}
}
// care with spacing
if (s.type != s.ts_prev.type) {
if (!s.seqst) {
s.seqst = true;
s.shrink = s.wl + s.prev.wr;
s.space = s.ts_next.space;
s.ts_next.space = 0
}
} else {
delete s.seqst
}
s2 = s3 // restart
continue
}
if (w_tb[s2.type])
break // symbol with a width
}
}
/* if explicit EOLN, cut on the next symbol */
if (eoln)
return set_eol_next(s)
/* if normal symbol, cut here */
switch (s.type) {
case C.CLEF:
case C.BAR:
case C.STAVES:
break
case C.GRACE: /* don't cut on a grace note */
s = s.next
if (!s)
return s
/* fall thru */
default:
return set_eol_next(s)
}
/* go back to handle the staff breaks at end of line */
for (; s; s = s.ts_prev) {
if (s.seqst && s.type != C.CLEF)
break
}
done = 0
for ( ; ; s = s.ts_next) {
if (!s)
return s
if (!s.seqst)
continue
if (done < 0)
break
switch (s.type) {
case C.STAVES:
if (s.ts_prev && s.ts_prev.type == C.BAR)
break
while (s.ts_next) {
if (w_tb[s.ts_next.type] != 0
&& s.ts_next.type != C.CLEF)
break
s = s.ts_next
}
if (!s.ts_next || s.ts_next.type != C.BAR)
continue
s = s.ts_next
// fall thru
case C.BAR:
if (done)
break
done = 1;
continue
case C.STBRK:
if (!s.stbrk_forced)
unlksym(s) /* remove */
else
done = -1 // keep the next symbols on the next line
continue
case C.CLEF:
if (done)
break
continue
default:
if (!done || (s.prev && s.prev.type == C.GRACE))
continue
break
}
break
}
set_eol(s)
return s
}
/* get the width of the starting clef and key signature */
// return
// r[0] = width of clef and key signature
// r[1] = width of the meter
function get_ck_width() {
var r0, r1,
p_voice = voice_tb[0]
self.set_width(p_voice.clef);
self.set_width(p_voice.key);
self.set_width(p_voice.meter)
return [p_voice.clef.wl + p_voice.clef.wr +
p_voice.key.wl + p_voice.key.wr,
p_voice.meter.wl + p_voice.meter.wr]
}
// get the width of the symbols up to the next eoln or eof
function get_width(s, last) {
|
| ︙ | ︙ | |||
1520 1521 1522 1523 1524 1525 1526 |
xmin = s.x - s.shrink - indent;
xmax = xmin + lwidth;
xmid = xmin + wwidth / nlines;
xmin += wwidth / nlines * cfmt.breaklimit;
for (s = s.ts_next; s != last ; s = s.ts_next) {
if (!s.x)
continue
| | | < < < | < | | < < | < | | 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 |
xmin = s.x - s.shrink - indent;
xmax = xmin + lwidth;
xmid = xmin + wwidth / nlines;
xmin += wwidth / nlines * cfmt.breaklimit;
for (s = s.ts_next; s != last ; s = s.ts_next) {
if (!s.x)
continue
if (s.type == C.BAR)
s2 = s
if (s.x >= xmin)
break
}
//fixme: can this occur?
if (s == last) {
if (last)
last = set_nl(last)
return last
}
/* try to cut on a measure bar */
cut_here = false;
s3 = null
for ( ; s != last; s = s.ts_next) {
x = s.x
if (!x)
continue
if (x > xmax)
break
if (s.type != C.BAR)
continue
// cut on the bar closest to the middle
if (x < xmid) {
s3 = s // closest bar before middle
continue
}
if (!s3 || x - xmid < xmid - s3.x)
s3 = s // closest bar after middle
break
}
/* if a bar, cut here */
if (s3) {
s = s3;
cut_here = true
|
| ︙ | ︙ | |||
1588 1589 1590 1591 1592 1593 1594 | if (!x) continue if (x + s.wr >= xmax) break if (beam || s.in_tuplet) continue //fixme: this depends on the meter | | | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 |
if (!x)
continue
if (x + s.wr >= xmax)
break
if (beam || s.in_tuplet)
continue
//fixme: this depends on the meter
if ((s.time - bar_time) % (C.BLEN / 4) == 0) {
s3 = s
continue
}
if (!s3 || s.x < xmid) {
s3 = s
continue
}
|
| ︙ | ︙ | |||
1653 1654 1655 1656 1657 1658 1659 |
indent = 0
}
return s
}
/* -- cut the tune into music lines -- */
function cut_tune(lwidth, indent) {
| | | 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 |
indent = 0
}
return s
}
/* -- cut the tune into music lines -- */
function cut_tune(lwidth, indent) {
var s, s2, s3, i, xmin, lwx,
//fixme: not usable yet
// pg_sav = {
// leftmargin: cfmt.leftmargin,
// rightmargin: cfmt.rightmargin,
// pagewidth: cfmt.pagewidth,
// scale: cfmt.scale
// },
|
| ︙ | ︙ | |||
1684 1685 1686 1687 1688 1689 1690 |
if (cfmt.custos && voice_tb.length == 1)
lwidth -= 12
/* if asked, count the measures and set the EOLNs */
if (cfmt.barsperstaff) {
i = cfmt.barsperstaff;
for (s2 = s; s2; s2 = s2.ts_next) {
| | > | | | | | 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 |
if (cfmt.custos && voice_tb.length == 1)
lwidth -= 12
/* if asked, count the measures and set the EOLNs */
if (cfmt.barsperstaff) {
i = cfmt.barsperstaff;
for (s2 = s; s2; s2 = s2.ts_next) {
if (s2.type != C.BAR
|| !s2.bar_num
|| --i > 0)
continue
s2.eoln = true;
i = cfmt.barsperstaff
}
}
/* cut at explicit end of line, checking the line width */
xmin = indent;
lwx = lwidth * cfmt.maxshrink;
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
// }
// continue
// }
if (!s.seqst && !s.eoln)
continue
xmin += s.shrink
if (xmin > lwx) { // overflow
s2 = set_lines(s2, s, lwidth, indent)
} else {
if (!s.eoln)
continue
delete s.eoln
// if eoln on a note or a rest,
// check for a smaller duration in an other voice
if (s.dur) {
for (s3 = s.ts_next; s3; s3 = s3.ts_next) {
if (s3.seqst
|| s3.dur < s.dur)
break
}
if (s3 && !s3.seqst)
s2 = set_lines(s2, s, lwidth, indent)
else
s2 = set_nl(s, true)
} else {
s2 = set_nl(s, true)
}
}
if (!s2)
break
// (s2 may be tsfirst - no ts_prev - when only one
// embedded info in the first line after the first K:)
|
| ︙ | ︙ | |||
1765 1766 1767 1768 1769 1770 1771 |
/* -- 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
switch (s.type) {
| | | 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 |
/* -- 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
switch (s.type) {
case C.CLEF:
if (s.second
|| s.invis) {
// s.ymx = s.ymn = (top + bot) / 2
s.ymx = s.ymn = 12
break
}
s.y = (s.clef_line - 1) * 6
|
| ︙ | ︙ | |||
1807 1808 1809 1810 1811 1812 1813 |
if (s.clef_octave) {
if (s.clef_octave > 0)
s.ymx += 12
else
s.ymn -= 12
}
break
| | | | | | | | | 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 2011 2012 2013 2014 |
if (s.clef_octave) {
if (s.clef_octave > 0)
s.ymx += 12
else
s.ymn -= 12
}
break
case C.KEY:
if (s.k_sf > 2)
s.ymx = 24 + 10
else if (s.k_sf > 0)
s.ymx = 24 + 6
else
s.ymx = 24 + 2;
s.ymn = -2
break
default:
// s.ymx = top;
s.ymx = 24;
s.ymn = 0
break
}
}
// set the clefs (treble or bass) in a 'auto clef' sequence
// return the starting clef type
function set_auto_clef(st, s_start, clef_type_start) {
var s, min, max, time, s2, s3;
/* get the max and min pitches in the sequence */
max = 12; /* "F," */
min = 20 /* "G" */
for (s = s_start; s; s = s.ts_next) {
if (s.type == C.STAVES && s != s_start)
break
if (s.st != st)
continue
if (s.type != C.NOTE) {
if (s.type == C.CLEF) {
if (s.clef_type != 'a')
break
unlksym(s)
}
continue
}
if (s.notes[0].pit < min)
|
| ︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 |
else
clef_type_start = 'b'
}
var clef_type = clef_type_start,
s_last = s,
s_last_chg = null
for (s = s_start; s != s_last; s = s.ts_next) {
| | | | | | | | | | | 2031 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 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 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 |
else
clef_type_start = 'b'
}
var clef_type = clef_type_start,
s_last = s,
s_last_chg = null
for (s = s_start; s != s_last; s = s.ts_next) {
if (s.type == C.STAVES && s != s_start)
break
if (s.st != st || s.type != C.NOTE)
continue
/* check if a clef change may occur */
time = s.time
if (clef_type == 't') {
if (s.notes[0].pit > 12 /* F, */
|| s.notes[s.nhd].pit > 20) { /* G */
if (s.notes[0].pit > 20)
s_last_chg = s
continue
}
s2 = s.ts_prev
if (s2
&& s2.time == time
&& s2.st == st
&& s2.type == C.NOTE
&& s2.notes[0].pit >= 19) /* F */
continue
s2 = s.ts_next
if (s2
&& s2.st == st
&& s2.time == time
&& s2.type == C.NOTE
&& s2.notes[0].pit >= 19) /* F */
continue
} else {
if (s.notes[0].pit < 12 /* F, */
|| s.notes[s.nhd].pit < 20) { /* G */
if (s.notes[s.nhd].pit < 12)
s_last_chg = s
continue
}
s2 = s.ts_prev
if (s2
&& s2.time == time
&& s2.st == st
&& s2.type == C.NOTE
&& s2.notes[0].pit <= 13) /* G, */
continue
s2 = s.ts_next
if (s2
&& s2.st == st
&& s2.time == time
&& s2.type == C.NOTE
&& s2.notes[0].pit <= 13) /* G, */
continue
}
/* if first change, change the starting clef */
if (!s_last_chg) {
clef_type = clef_type_start =
clef_type == 't' ? 'b' : 't';
s_last_chg = s
continue
}
/* 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
&& 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 */
if (s2.beam_st
&& !s2.p_v.second)
s3 = s2
}
|
| ︙ | ︙ | |||
1997 1998 1999 2000 2001 2002 2003 |
// set the starting clefs of the staves
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (sy.voices[v].range < 0)
continue
st = sy.voices[v].st
if (!sy.voices[v].second) { // main voices
| < < | 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 |
// set the starting clefs of the staves
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (sy.voices[v].range < 0)
continue
st = sy.voices[v].st
if (!sy.voices[v].second) { // main voices
if (p_voice.staffnonote != undefined)
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)
|
| ︙ | ︙ | |||
2035 2036 2037 2038 2039 2040 2041 |
mid[st] = (sy.staves[st].stafflines.length - 1) * 3
for (s = tsfirst; s; s = s.ts_next) {
if (s.repeat_n)
set_repeat(s)
switch (s.type) {
| | < < | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 |
mid[st] = (sy.staves[st].stafflines.length - 1) * 3
for (s = tsfirst; s; s = s.ts_next) {
if (s.repeat_n)
set_repeat(s)
switch (s.type) {
case C.STAVES:
sy = s.sy
for (st = 0; st <= nstaff; st++)
staff_clef[st].autoclef = true
for (v = 0; v < voice_tb.length; v++) {
if (sy.voices[v].range < 0)
continue
p_voice = voice_tb[v];
st = sy.voices[v].st
if (!sy.voices[v].second) {
if (p_voice.staffnonote != undefined)
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)
|
| ︙ | ︙ | |||
2098 2099 2100 2101 2102 2103 2104 | staff_clef[st].clef = p_voice.clef continue } // old staff if (new_type == staff_clef[st].clef.clef_type && new_line == staff_clef[st].clef.clef_line) continue | > > > > > > | | | | < > > | | | 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 |
staff_clef[st].clef = p_voice.clef
continue
}
// old staff
if (new_type == staff_clef[st].clef.clef_type
&& new_line == staff_clef[st].clef.clef_line)
continue
g = s.ts_prev
while (g
&& g.time == s.time
&& (g.v != v || g.st != st))
g = g.ts_prev
if (!g || g.time != s.time) {
g = s.ts_next
while (g && (g.v != v || g.st != st))
g = g.ts_next
if (!g || g.time != s.time)
g = s
}
if (g.type != C.CLEF) {
g = insert_clef(g, new_type, new_line)
if (s2.clef_auto)
g.clef_auto = true
}
staff_clef[st].clef = p_voice.clef = g
}
continue
default:
s.mid = mid[s.st]
continue
case C.CLEF:
break
}
if (s.clef_type == 'a') {
s.clef_type = set_auto_clef(s.st,
s.ts_next,
staff_clef[s.st].clef.clef_type);
|
| ︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 2213 |
[10, 10], /* crotchet */
[6, 4],
[10, 0],
[10, 4],
[10, 10]
]
function set_pitch(last_s) {
| > | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | | | | | | > | > | > | | | | 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 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 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 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 |
[10, 10], /* crotchet */
[6, 4],
[10, 0],
[10, 4],
[10, 10]
]
// (possible hook)
function set_pitch(last_s) {
var s, s2, g, st, delta, pitch, note,
dur = C.BLEN,
m = nstaff + 1,
staff_d = new Int16Array(new Array(m * 2)), // (delta - ottava)
staff_delta = new Int16Array(new Array(m * 2)), // delta clef
staff_ottava = new Int16Array(new Array(m * 2)), // ottava value
staff_noo = new Int8Array(new Array(m)), // number of ottava values
sy = cur_sy
// add an ottava decoration
function ottava_add(s, ottava, start) {
var dc_st = ["15mb(", "8vb(", null, "8va(", "15ma("],
dc_en = ["15mb)", "8vb)", null, "8va)", "15ma)"];
deco_cnv([(start ? dc_st : dc_en)[2 + ottava]], s)
}
// set the starting clefs of the staves
for (st = 0; st <= nstaff; st++) {
s = staff_tb[st].clef;
staff_delta[st] = delta_tb[s.clef_type] + s.clef_line * 2
if (s.clefpit)
staff_delta[st] += s.clefpit
if (cfmt.sound) {
if (s.clef_octave && !s.clef_oct_transp)
staff_delta[st] += s.clef_octave
} else {
if (s.clef_oct_transp)
staff_delta[st] -= s.clef_octave
}
staff_d[st] = staff_delta[st];
staff_ottava[st] = 0;
staff_noo[st] = 0
}
for (s = tsfirst; s != last_s; s = s.ts_next) {
st = s.st
// set the ottava decorations and the associated pitch shift
if (s.ottava != undefined && !cfmt.sound) {
if (s.ottava) {
if (staff_noo[st]++ == 0) { // if first ottava
ottava_add(s, s.ottava, true);
staff_ottava[st] = s.ottava;
staff_d[st] = staff_delta[st] - s.ottava * 7
}
} else {
if (--staff_noo[st] == 0) { // if last ottava
ottava_add(s, staff_ottava[st]);
staff_ottava[st] = s.ottava;
staff_d[st] = staff_delta[st]
}
}
}
switch (s.type) {
case C.CLEF:
staff_delta[st] = delta_tb[s.clef_type] +
s.clef_line * 2
if (s.clefpit)
staff_delta[st] += s.clefpit
if (cfmt.sound) {
if (s.clef_octave && !s.clef_oct_transp)
staff_delta[st] += s.clef_octave
} else {
if (s.clef_oct_transp)
staff_delta[st] -= s.clef_octave
}
staff_d[st] = staff_delta[st] - staff_ottava[st] * 7;
set_yval(s)
break
case C.GRACE:
for (g = s.extra; g; g = g.next) {
delta = staff_d[g.st]
if (delta != 0
&& !s.p_v.key.k_drum) {
for (m = 0; m <= g.nhd; m++) {
note = g.notes[m];
note.pit += delta
}
}
g.ymn = 3 * (g.notes[0].pit - 18) - 2;
g.ymx = 3 * (g.notes[g.nhd].pit - 18) + 2
}
set_yval(s)
break
case C.KEY:
s.k_y_clef = staff_delta[st] /* keep the y delta */
/* fall thru */
default:
set_yval(s)
break
case C.MREST:
if (s.invis)
break
s.y = 12;
s.ymx = 24 + 15;
s.ymn = -2
break
case C.REST:
if (voice_tb.length == 1) {
s.y = 12; /* rest single voice */
// s.ymx = 12 + 8;
// s.ymn = 12 - 8
s.ymx = 24;
s.ymn = 0
break
}
// fall thru
case C.NOTE:
delta = staff_d[st]
if (delta != 0
&& !s.p_v.key.k_drum) {
for (m = s.nhd; m >= 0; m--) {
s.notes[m].opit = s.notes[m].pit;
s.notes[m].pit += delta
}
}
if (s.type == C.NOTE) {
s.ymx = 3 * (s.notes[s.nhd].pit - 18) + 4;
s.ymn = 3 * (s.notes[0].pit - 18) - 4;
} else {
s.y = (((s.notes[0].pit - 18) / 2) | 0) * 6;
s.ymx = s.y + rest_sp[5 - s.nflags][0];
s.ymn = s.y - rest_sp[5 - s.nflags][1]
}
if (s.dur < dur)
dur = s.dur
break
}
}
if (!last_s)
smallest_duration = dur
}
/* -- set the stem direction when multi-voices -- */
/* this function is called only once per tune */
// (possible hook)
function set_stem_dir() {
var t, u, i, st, rvoice, v,
v_st, // voice -> staff 1 & 2
st_v, vobj, // staff -> (v, ymx, ymn)*
v_st_tb, // array of v_st
st_v_tb = [], // array of st_v
s = tsfirst,
sy = cur_sy,
nst = sy.nstaff
while (s) {
for (st = 0; st <= nst; st++)
st_v_tb[st] = []
v_st_tb = []
/* get the max/min offsets in the delta time */
/*fixme: the stem height is not calculated yet*/
for (u = s; u; u = u.ts_next) {
if (u.type == C.BAR)
break;
if (u.type == C.STAVES) {
if (u != s)
break
sy = s.sy
for (st = nst; st <= sy.nstaff; st++)
st_v_tb[st] = []
nst = sy.nstaff
continue
}
if ((u.type != C.NOTE && u.type != C.REST)
|| u.invis)
continue
st = u.st;
/*fixme:test*/
if (st > nst) {
var msg = "*** fatal set_stem_dir(): bad staff number " + st +
" max " + nst;
|
| ︙ | ︙ | |||
2392 2393 2394 2395 2396 2397 2398 | break } } if (i == st_v.length) st_v.push(vobj) } | | | | | > > > | | | 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 |
break
}
}
if (i == st_v.length)
st_v.push(vobj)
}
if (u.type != C.NOTE)
continue
if (u.ymx > vobj.ymx)
vobj.ymx = u.ymx
if (u.ymn < vobj.ymn)
vobj.ymn = u.ymn
if (u.xstem) {
if (u.ts_prev.st != st - 1
|| u.ts_prev.type != C.NOTE) {
error(1, s, "Bad !xstem!");
u.xstem = false
/*fixme:nflags KO*/
} else {
u.ts_prev.multi = 1;
u.multi = 1;
u.stemless = true
}
}
}
for ( ; s != u; s = s.ts_next) {
if (s.multi)
continue
switch (s.type) {
default:
continue
case C.REST:
// handle %%voicecombine 0
if ((s.combine != undefined && s.combine < 0)
|| !s.ts_next || s.ts_next.type != C.REST
|| s.ts_next.st != s.st
|| s.time != s.ts_next.time
|| s.dur != s.ts_next.dur
|| (s.a_gch && s.ts_next.a_gch)
|| s.invis)
break
if (s.ts_next.a_gch)
s.a_gch = s.ts_next.a_gch
unlksym(s.ts_next)
break
case C.NOTE:
case C.GRACE:
break
}
st = s.st;
v = s.v;
v_st = v_st_tb[v];
st_v = st_v_tb[st]
|
| ︙ | ︙ | |||
2489 2490 2491 2492 2493 2494 2495 | && (!t || t.st != s.st || t.time != s.time)) s.multi = -1 } } } | | | | | 2695 2696 2697 2698 2699 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 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 |
&& (!t
|| t.st != s.st
|| t.time != s.time))
s.multi = -1
}
}
}
while (s && s.type == C.BAR)
s = s.ts_next
}
}
/* -- adjust the offset of the rests when many voices -- */
/* this function is called only once per tune */
function set_rest_offset() {
var s, s2, v, end_time, not_alone, v_s, y, ymax, ymin,
shift, dots, dx,
v_s_tb = [],
sy = cur_sy
for (s = tsfirst; s; s = s.ts_next) {
if (s.invis)
continue
if (s.type == C.STAVES)
sy = s.sy
if (!s.dur)
continue
v_s = v_s_tb[s.v]
if (!v_s) {
v_s = {}
v_s_tb[s.v] = v_s
}
v_s.s = s;
v_s.st = s.st;
v_s.end_time = s.time + s.dur
if (s.type != C.REST)
continue
/* check if clash with previous symbols */
ymin = -127;
ymax = 127;
not_alone = dots = false
for (v = 0; v <= v_s_tb.length; v++) {
|
| ︙ | ︙ | |||
2565 2566 2567 2568 2569 2570 2571 |
/* check if clash with next symbols */
end_time = s.time + s.dur
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.time >= end_time)
break
if (s2.st != s.st
| | | 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 |
/* check if clash with next symbols */
end_time = s.time + s.dur
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.time >= end_time)
break
if (s2.st != s.st
// || (s2.type != C.NOTE && s2.type != C.REST)
|| !s2.dur
|| s2.invis)
continue
not_alone = true
if (sy.voices[s2.v].range < sy.voices[s.v].range) {
if (s2.time == s.time) {
if (s2.ymn < ymax) {
|
| ︙ | ︙ | |||
2675 2676 2677 2678 2679 2680 2681 |
last_s.shrink = 0
}
return s
}
/* -- init the symbols at start of a music line -- */
function init_music_line() {
| | | | | 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 |
last_s.shrink = 0
}
return s
}
/* -- init the symbols at start of a music line -- */
function init_music_line() {
var p_voice, s, s2, s3, last_s, v, st, shr, shrmx,
nv = voice_tb.length
/* initialize the voices */
for (v = 0; v < nv; v++) {
if (cur_sy.voices[v].range < 0)
continue
p_voice = voice_tb[v];
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++;
p_voice.st = st
}
/* add a clef at start of the main voices */
last_s = tsfirst
while (last_s && last_s.type == C.CLEF) { // move the starting clefs
v = last_s.v
if (cur_sy.voices[v].range >= 0
&& !cur_sy.voices[v].second) {
delete last_s.clef_small; /* normal clef */
p_voice = last_s.p_v;
p_voice.last_sym = p_voice.sym = last_s
}
last_s = last_s.ts_next
}
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
if (p_voice.sym && p_voice.sym.type == C.CLEF)
continue
if (cur_sy.voices[v].range < 0
|| (cur_sy.voices[v].second
&& !p_voice.bar_start)) // needed for correct linkage
continue
st = cur_sy.voices[v].st
if (!staff_tb[st]
|
| ︙ | ︙ | |||
2742 2743 2744 2745 2746 2747 2748 |
s.seqst = true
} else {
s.ts_prev.ts_next = s
delete s.seqst
}
if (last_s) {
last_s.ts_prev = s
| | | | | 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 |
s.seqst = true
} else {
s.ts_prev.ts_next = s
delete s.seqst
}
if (last_s) {
last_s.ts_prev = s
if (last_s.type == C.CLEF)
delete last_s.seqst
}
delete s.clef_small;
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
}
/* add keysig */
for (v = 0; v < nv; v++) {
if (cur_sy.voices[v].range < 0
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st])
continue
p_voice = voice_tb[v]
if (last_s && last_s.v == v && last_s.type == C.KEY) {
p_voice.last_sym = last_s;
last_s.k_old_sf = last_s.k_sf; // no key cancel
last_s = last_s.ts_next
continue
}
s2 = p_voice.key
if (s2.k_sf || s2.k_a_acc) {
s = new_sym(C.KEY, p_voice, last_s);
s.k_sf = s2.k_sf;
s.k_old_sf = s2.k_sf; // no key cancel
s.k_none = s2.k_none;
s.k_a_acc = s2.k_a_acc;
s.istart = s2.istart;
s.iend = s2.iend
if (s2.k_bagpipe) {
|
| ︙ | ︙ | |||
2792 2793 2794 2795 2796 2797 2798 | p_voice = voice_tb[v]; s2 = p_voice.meter if (cur_sy.voices[v].range < 0 || cur_sy.voices[v].second || !cur_sy.st_print[cur_sy.voices[v].st] || s2.a_meter.length == 0) continue | | | > > > < | < < | | > | > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > | | | | | | > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > | | | | | | | 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 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 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 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 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 |
p_voice = voice_tb[v];
s2 = p_voice.meter
if (cur_sy.voices[v].range < 0
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st]
|| s2.a_meter.length == 0)
continue
if (last_s && last_s.v == v && last_s.type == C.METER) {
p_voice.last_sym = last_s;
last_s = last_s.ts_next
continue
}
s = new_sym(C.METER, p_voice, last_s);
s.istart = s2.istart;
s.iend = s2.iend;
s.wmeasure = s2.wmeasure;
s.a_meter = s2.a_meter
}
insert_meter &= ~1 // no meter any more
}
/* add bar if needed (for repeat bracket) */
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v];
s2 = p_voice.bar_start;
p_voice.bar_start = null
// if bar already, keep it in sequence
if (last_s && last_s.v == v && last_s.type == C.BAR) {
p_voice.last_sym = last_s;
last_s = last_s.ts_next
continue
}
if (!s2)
continue
if (cur_sy.voices[v].range < 0
|| !cur_sy.st_print[cur_sy.voices[v].st])
continue
s2.next = p_voice.last_sym.next
if (s2.next)
s2.next.prev = s2;
p_voice.last_sym.next = s2;
s2.prev = p_voice.last_sym;
p_voice.last_sym = s2;
lktsym(s2, last_s);
s2.time = tsfirst.time
if (s2.ts_prev.type != s2.type)
s2.seqst = true;
if (last_s && last_s.type == s2.type && s2.v != last_s.v) {
delete last_s.seqst;
// last_s.shrink = 0
}
}
/* if initialization of a new music line, compute the spacing,
* including the first (old) sequence */
self.set_pitch(last_s)
for (s = last_s; s; s = s.ts_next) {
if (s.seqst) {
for (s = s.ts_next; s; s = s.ts_next)
if (s.seqst)
break
break
}
}
// set the spacing of the added symbols
while (last_s) {
if (last_s.seqst) {
do {
last_s = last_s.ts_next
} while (last_s && !last_s.seqst)
break
}
last_s = last_s.ts_next
}
s = tsfirst
while (1) {
s2 = s;
shrmx = 0
do {
self.set_width(s);
shr = s.wl
for (s3 = s.prev; s3; s3 = s3.prev) {
if (w_tb[s3.type] != 0) {
shr += s3.wr
break
}
}
if (shr > shrmx)
shrmx = shr;
s = s.ts_next
} while (s != last_s && !s.seqst);
s2.shrink = shrmx;
s2.space = 0
if (s == last_s)
break
}
}
/* -- set a pitch in all symbols and the start/stop of the beams -- */
function set_words(p_voice) {
var s, s2, nflags, lastnote, res,
start_flag = true,
pitch = 127 /* no note */
for (s = p_voice.sym; s; s = s.next) {
if (s.type == C.NOTE) {
pitch = s.notes[0].pit
break
}
}
for (s = p_voice.sym; s; s = s.next) {
switch (s.type) {
case C.MREST:
start_flag = true
break
case C.BAR:
s.bar_type = bar_cnv(s.bar_type)
if (!s.beam_on)
start_flag = true
if (!s.next && s.prev
// && s.prev.type == C.NOTE
// && s.prev.dur >= C.BLEN * 2)
&& s.prev.head == C.OVALBARS)
s.prev.head = C.SQUARE
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]
if (s.nflags <= -2)
s.stemless = true
if (s.xstem)
s.nflags = 0 // beam break
if (s.trem1) {
if (s.nflags > 0)
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
}
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_end = false;
start_flag = true
}
if (start_flag
|| nflags <= 0) {
if (lastnote) {
lastnote.beam_end = true;
lastnote = null
}
if (nflags <= 0) {
s.beam_st = true;
s.beam_end = true
} else if (s.type == C.NOTE) {
s.beam_st = true;
start_flag = false
}
}
if (s.beam_end)
start_flag = true
if (s.type == C.NOTE)
lastnote = s
break
}
if (s.type == C.NOTE) {
if (s.nhd != 0)
sort_pitch(s);
pitch = s.notes[0].pit
// if (s.prev
// && s.prev.type != C.NOTE) {
// s.prev.notes[0].pit = (s.prev.notes[0].pit
// + pitch) / 2
for (s2 = s.prev; s2; s2 = s2.prev) {
if (s2.type != C.REST)
break
s2.notes[0].pit = pitch
}
} else {
if (!s.notes) {
s.notes = []
s.notes[0] = {}
|
| ︙ | ︙ | |||
2945 2946 2947 2948 2949 2950 2951 |
/* -- set the end of the repeat sequences -- */
function set_rb(p_voice) {
var s2, mx, n,
s = p_voice.sym
while (s) {
| | | | 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 |
/* -- set the end of the repeat sequences -- */
function set_rb(p_voice) {
var s2, mx, n,
s = p_voice.sym
while (s) {
if (s.type != C.BAR || !s.rbstart || s.norepbra) {
s = s.next
continue
}
mx = cfmt.rbmax
/* if 1st repeat sequence, compute the bracket length */
if (s.text && s.text[0] == '1') {
n = 0;
s2 = null
for (s = s.next; s; s = s.next) {
if (s.type != C.BAR)
continue
n++
if (s.rbstop) {
if (n <= cfmt.rbmax) {
mx = n;
s2 = null
}
|
| ︙ | ︙ | |||
2993 2994 2995 2996 2997 2998 2999 |
if (s.rbstart != 2)
break
}
}
n = 0;
s2 = null
for (s = s.next; s; s = s.next) {
| | | 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 |
if (s.rbstart != 2)
break
}
}
n = 0;
s2 = null
for (s = s.next; s; s = s.next) {
if (s.type != C.BAR)
continue
n++
if (s.rbstop)
break
if (!s.next)
s.rbstop = 2 // right repeat with end
else if (n == mx)
|
| ︙ | ︙ | |||
3044 3045 3046 3047 3048 3049 3050 | } /* set the staff of the floating voices */ set_float(); // set the clefs and adjust the pitches of all symbol set_clefs(); | | | | | | 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 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 |
}
/* set the staff of the floating voices */
set_float();
// set the clefs and adjust the pitches of all symbol
set_clefs();
self.set_pitch(null)
}
/* -- 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,
maxw = 0
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
if (cur_sy.voices[v].range < 0)
continue
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)
continue
if (!font) {
set_font("voice");
font = gene.curfont
}
i = 0
while (1) {
j = p.indexOf("\\n", i)
if (j < 0)
w = strwh(p.slice(i))
else
w = strwh(p.slice(i, j))
w = w[0]
if (w > maxw)
maxw = w
if (j < 0)
break
i = j + 1
}
}
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
|
| ︙ | ︙ | |||
3110 3111 3112 3113 3114 3115 3116 |
/* -- 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, dy, avg, n, m, mid_p, pu, pd,
laststem = -1
for (s = sym; s; s = s.next) {
| | | | 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 |
/* -- 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, dy, avg, 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
|
| ︙ | ︙ | |||
3140 3141 3142 3143 3144 3145 3146 |
if (beam) {
s.stem = laststem
} else if (s.beam_st && !s.beam_end) { // beam start
beam = true;
pu = s.notes[s.nhd].pit;
pd = s.notes[0].pit
for (g = s.next; g; g = g.next) {
| | | 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 |
if (beam) {
s.stem = laststem
} else if (s.beam_st && !s.beam_end) { // beam start
beam = true;
pu = s.notes[s.nhd].pit;
pd = s.notes[0].pit
for (g = s.next; g; g = g.next) {
if (g.type != C.NOTE)
continue
if (g.stem || g.multi) {
s.stem = g.stem || g.multi
break
}
if (g.notes[g.nhd].pit > pu)
pu = g.notes[g.nhd].pit
|
| ︙ | ︙ | |||
3207 3208 3209 3210 3211 3212 3213 |
// check if there may be one head for unison when voice overlap
function same_head(s1, s2) {
var i1, i2, l1, l2, head, i11, i12, i21, i22, sh1, sh2
if (s1.shiftunison && s1.shiftunison >= 3)
return false
| | | | 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 |
// check if there may be one head for unison when voice overlap
function same_head(s1, s2) {
var i1, i2, l1, l2, head, i11, i12, i21, i22, sh1, sh2
if (s1.shiftunison && s1.shiftunison >= 3)
return false
if ((l1 = s1.dur) >= C.BLEN)
return false
if ((l2 = s2.dur) >= C.BLEN)
return false
if (s1.stemless && s2.stemless)
return false
if (s1.dots != s2.dots) {
if ((s1.shiftunison && (s1.shiftunison & 1))
|| s1.dots * s2.dots != 0)
return false
|
| ︙ | ︙ | |||
3288 3289 3290 3291 3292 3293 3294 |
head = 0
if (l1 != l2) {
if (l1 < l2) {
l1 = l2;
l2 = s1.dur
}
| | | | | | | 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 |
head = 0
if (l1 != l2) {
if (l1 < l2) {
l1 = l2;
l2 = s1.dur
}
if (l1 < C.BLEN / 2) {
if (s2.dots)
head = 2
else if (s1.dots)
head = 1
} else if (l2 < C.BLEN / 4) { /* (l1 >= C.BLEN / 2) */
// if ((s1.shiftunison && s1.shiftunison == 2)
// || s1.dots != s2.dots)
if (s1.shiftunison && (s1.shiftunison & 2))
return false
head = s2.dur >= C.BLEN / 2 ? 2 : 1
} else {
return false
}
}
if (head == 0)
head = s1.p_v.scale < s2.p_v.scale ? 2 : 1
if (head == 1) {
|
| ︙ | ︙ | |||
3393 3394 3395 3396 3397 3398 3399 | i = s.notes[m].pit * 2 if (i < 0) i = 0 else if (i >= MAXPIT - 1) i = MAXPIT - 2 if (w > left[i]) left[i] = w | | | 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 | i = s.notes[m].pit * 2 if (i < 0) i = 0 else if (i >= MAXPIT - 1) i = MAXPIT - 2 if (w > left[i]) left[i] = w if (s.head != C.SQUARE) w -= 1 if (w > left[i - 1]) left[i - 1] = w if (w > left[i + 1]) left[i + 1] = w } |
| ︙ | ︙ | |||
3465 3466 3467 3468 3469 3470 3471 | i = s.notes[m].pit * 2 if (i < 0) i = 0 else if (i >= MAXPIT - 1) i = MAXPIT - 2 if (w > right[i]) right[i] = w | | | 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 | i = s.notes[m].pit * 2 if (i < 0) i = 0 else if (i >= MAXPIT - 1) i = MAXPIT - 2 if (w > right[i]) right[i] = w if (s.head != C.SQUARE) w -= 1 if (w > right[i - 1]) right[i - 1] = w if (w > right[i + 1]) right[i + 1] = w } |
| ︙ | ︙ | |||
3494 3495 3496 3497 3498 3499 3500 |
d = d2;
pl = left1;
pr = right1;
dr2 = dr
}
for (s = tsfirst; s; s = s.ts_next) {
| | | 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 |
d = d2;
pl = left1;
pr = right1;
dr2 = dr
}
for (s = tsfirst; s; s = s.ts_next) {
if (s.type != C.NOTE
|| s.invis)
continue
/* treat the stem on two staves with different directions */
if (s.xstem
&& s.ts_prev.stem < 0) {
for (m = 0; m <= s.nhd; m++) {
|
| ︙ | ︙ | |||
3517 3518 3519 3520 3521 3522 3523 |
s2 = s2.ts_next
if (!s2)
break
if (s2.time != s.time) {
s2 = null
break
}
| | | 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 |
s2 = s2.ts_next
if (!s2)
break
if (s2.time != s.time) {
s2 = null
break
}
if (s2.type == C.NOTE
&& !s2.invis
&& s2.st == s.st)
break
}
if (!s2)
continue
s1 = s
|
| ︙ | ︙ | |||
3546 3547 3548 3549 3550 3551 3552 | /* compute the minimum space for 's1 s2' and 's2 s1' */ right1 = set_right(s1); left2 = set_left(s2); s3 = s1.ts_prev if (s3 && s3.time == s1.time | | | 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 |
/* compute the minimum space for 's1 s2' and 's2 s1' */
right1 = set_right(s1);
left2 = set_left(s2);
s3 = s1.ts_prev
if (s3 && s3.time == s1.time
&& s3.st == s1.st && s3.type == C.NOTE && !s3.invis) {
right3 = set_right(s3)
for (i = 0; i < MAXPIT; i++) {
if (right3[i] > right1[i])
right1[i] = right3[i]
}
} else {
s3 = null
|
| ︙ | ︙ | |||
3756 3757 3758 3759 3760 3761 3762 3763 |
if (sd)
s1.xmx = s2.xmx // align the dots
}
}
/* -- set the stem height -- */
/* this routine is called only once per tune */
function set_stems() {
| > | | | > > > > | 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 |
if (sd)
s1.xmx = s2.xmx // align the dots
}
}
/* -- set the stem height -- */
/* this routine is called only once per tune */
// (possible hook)
function set_stems() {
var s, s2, g, slen, scale,ymn, ymx, nflags, ymin, ymax, res
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;
|
| ︙ | ︙ | |||
3803 3804 3805 3806 3807 3808 3809 |
/* if start or end of beam, adjust the number of flags
* with the other end */
nflags = s.nflags
if (s.beam_st && !s.beam_end) {
if (s.feathered_beam)
nflags = ++s.nflags
for (s2 = s.next; /*s2*/; s2 = s2.next) {
| | | 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 |
/* if start or end of beam, adjust the number of flags
* with the other end */
nflags = s.nflags
if (s.beam_st && !s.beam_end) {
if (s.feathered_beam)
nflags = ++s.nflags
for (s2 = s.next; /*s2*/; s2 = s2.next) {
if (s2.type == C.NOTE) {
if (s.feathered_beam)
s2.nflags++
if (s2.beam_end)
break
}
}
/* if (s2) */
|
| ︙ | ︙ | |||
3827 3828 3829 3830 3831 3832 3833 |
if (s2.nflags > nflags)
nflags = s2.nflags
}
/* set height of stem end */
slen = cfmt.stemheight
switch (nflags) {
| | | | | | 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 |
if (s2.nflags > nflags)
nflags = s2.nflags
}
/* set height of stem end */
slen = cfmt.stemheight
switch (nflags) {
case 2: slen += 0; break
case 3: slen += 4; break
case 4: slen += 8; break
case 5: slen += 12; break
}
if ((scale = s.p_v.scale) != 1)
slen *= (scale + 1) * .5;
ymn = 3 * (s.notes[0].pit - 18)
if (s.nhd > 0) {
slen -= 2;
ymx = 3 * (s.notes[s.nhd].pit - 18)
|
| ︙ | ︙ | |||
3856 3857 3858 3859 3860 3861 3862 |
s.y = ymx
}
if (nflags == -4) /* if longa */
ymn -= 6;
s.ymx = ymx + 4;
s.ymn = ymn - 4
} else if (s.stem >= 0) {
| < < | 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 |
s.y = ymx
}
if (nflags == -4) /* if longa */
ymn -= 6;
s.ymx = ymx + 4;
s.ymn = ymn - 4
} else if (s.stem >= 0) {
if (s.notes[s.nhd].pit > 26
&& (nflags <= 0
|| !s.beam_st
|| !s.beam_end)) {
slen -= 2
if (s.notes[s.nhd].pit > 28)
slen -= 2
|
| ︙ | ︙ | |||
3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 |
ymx += 3;
s.ymx = ymx + 4
}
}
}
/* -- split up unsuitable bars at end of staff -- */
function check_bar(s) {
var bar_type, i, b1, b2,
p_voice = s.p_v
/* search the last bar */
| > | | | | | | | | | | < < < < | < < < < < | < < | | | | > | | | | 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 |
ymx += 3;
s.ymx = ymx + 4
}
}
}
/* -- split up unsuitable bars at end of staff -- */
// return true if the bar type has changed
function check_bar(s) {
var bar_type, i, b1, b2,
p_voice = s.p_v
/* search the last bar */
while (s.type == C.CLEF || s.type == C.KEY || s.type == C.METER) {
if (s.type == C.METER
&& s.time > p_voice.sym.time) /* if not empty voice */
insert_meter |= 1; /* meter in the next line */
s = s.prev
if (!s)
return
}
if (s.type != C.BAR)
return
if (s.text != undefined) { // if repeat bar
p_voice.bar_start = clone(s);
p_voice.bar_start.bar_type = ""
delete s.text
delete s.a_gch
// return
}
bar_type = s.bar_type
if (bar_type == ":")
return
if (bar_type.slice(-1) != ':') // if not left repeat bar
return
if (!p_voice.bar_start)
p_voice.bar_start = clone(s)
if (bar_type[0] != ':') { // 'xx:' (not ':xx:')
if (bar_type == "||:") {
p_voice.bar_start.bar_type = "[|:";
s.bar_type = "||"
return true
}
p_voice.bar_start.bar_type = bar_type
if (s.prev && s.prev.type == C.BAR)
unlksym(s)
else
s.bar_type = "|"
return
}
// ':xx:' -> ':x|]' and '[|x:'
i = 0
while (bar_type[i] == ':')
i++
if (i < bar_type.length) {
s.bar_type = bar_type.slice(0, i) + '|]';
i = bar_type.length - 1
while (bar_type[i] == ':')
i--;
p_voice.bar_start.bar_type = '[|' + bar_type.slice(i + 1)
} else {
i = (bar_type.length / 2) |0; // '::::' !
s.bar_type = bar_type.slice(0, i) + '|]';
p_voice.bar_start.bar_type = '[|' + bar_type.slice(i)
}
return true
}
/* -- 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
function block_gen(s) {
switch (s.subtype) {
case "leftmargin":
case "rightmargin":
case "pagescale":
case "pagewidth":
case "scale":
case "staffwidth":
svg_flush();
self.set_format(s.subtype, s.param)
break
case "ml":
svg_flush();
user.img_out(s.text)
break
case "newpage":
blk_flush();
block.newpage = true;
blk_out()
break
case "sep":
set_page();
vskip(s.sk1);
output += '<path class="stroke"\n\td="M';
out_sxsy(s.x, ' ', 0);
output += 'h' + s.l.toFixed(1) + '"/>\n';
vskip(s.sk2);
break
case "text":
write_text(s.text, s.opt)
break
case "title":
write_title(s.text, true)
|
| ︙ | ︙ | |||
4032 4033 4034 4035 4036 4037 4038 |
break
}
}
/* -- define the start and end of a piece of tune -- */
/* tsnext becomes the beginning of the next line */
function set_piece() {
| | | 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 |
break
}
}
/* -- 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, nst, nv, tmp,
non_empty = [],
non_empty_gl = [],
sy = cur_sy
function reset_staff(st) {
var p_staff = staff_tb[st],
sy_staff = sy.staves[st]
|
| ︙ | ︙ | |||
4117 4118 4119 4120 4121 4122 4123 |
* search the next end of line,
* and mark the empty staves
*/
for (s = tsfirst; s; s = s.ts_next) {
if (s.nl) {
//fixme: not useful
// // delay the next block symbols
| | | | > > | < > | | | | | < | | | | | < > | > | | < < | > > | 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 |
* search the next end of line,
* and mark the empty staves
*/
for (s = tsfirst; s; s = s.ts_next) {
if (s.nl) {
//fixme: not useful
// // delay the next block symbols
// while (s && s.type == C.BLOCK) {
// blocks.push(s);
// unlksym(s);
// s = s.ts_next
// }
break
}
if (!s.ts_next)
last = s // keep the last symbol
switch (s.type) {
case C.STAVES:
set_brace();
sy.st_print = new Uint8Array(non_empty);
sy = s.sy;
nst = sy.nstaff
if (nstaff < nst) {
for (st = nstaff + 1; st <= nst; st++)
reset_staff(st);
nstaff = nst
}
non_empty = []
continue
// the block symbols will be treated after music line generation
case C.BLOCK:
blocks.push(s);
unlksym(s)
if (last)
last = s.ts_prev
continue
}
st = s.st
if (non_empty[st])
continue
switch (s.type) {
default:
continue
case C.CLEF:
if (st > nstaff) { // if clef warning/change for new staff
staff_tb[st].clef = s;
unlksym(s)
}
continue
case C.BAR:
if (s.bar_mrep
|| sy.staves[st].staffnonote > 1)
break
continue
case C.GRACE:
break
case C.NOTE:
case C.REST:
case C.SPACE:
case C.MREST:
if (sy.staves[st].staffnonote > 1)
break
if (s.invis)
continue
if (sy.staves[st].staffnonote != 0
|| s.type == C.NOTE)
break
continue
}
non_empty_gl[st] = non_empty[st] = true
}
tsnext = s;
/* set the last empty staves */
set_brace()
// for (st = 0; st <= nstaff; st++)
// sy.st_print[st] = non_empty[st];
|
| ︙ | ︙ | |||
4225 4226 4227 4228 4229 4230 4231 |
p_voice = voice_tb[v]
if (p_voice.sym
&& p_voice.sym.time <= tsnext.time) {
for (s = tsnext.ts_prev; s; s = s.ts_prev) {
if (s.v == v) {
p_voice.s_next = s.next;
s.next = null;
| | > > > > | < < < | > < | < | < > | | > > > < > > | < > | | | < | | | < | | > > | > | < | | < < < < > | < < < < < | | < | | < < | | < < < < > | < | | | < < | < < < | | | < < < < < | < < | < | | < < < | < | < < | > | | > > > > | < < < < | < < | | < < | | < < < < < < < | > | | > > | < | | > | | | | | < < < < < < < < | < | | | < < < < < | | < < | < | | 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 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 |
p_voice = voice_tb[v]
if (p_voice.sym
&& p_voice.sym.time <= tsnext.time) {
for (s = tsnext.ts_prev; s; s = s.ts_prev) {
if (s.v == v) {
p_voice.s_next = s.next;
s.next = null;
if (check_bar(s)) {
tmp = s.wl;
self.set_width(s);
s.shrink += s.wl - tmp
}
break
}
}
if (s)
continue
}
p_voice.s_next = p_voice.sym;
p_voice.sym = null
}
}
// if the last symbol is not a bar, add an invisible bar
if (last.type != C.BAR) {
s = add_end_bar(last);
s.space = set_space(s)
if (s.space < s.shrink
&& last.type != C.KEY)
s.space = s.shrink
}
}
/* -- position the symbols along the staff -- */
// (possible hook)
function set_sym_glue(width) {
var s, g, ll,
some_grace,
spf, // spacing factor
xmin = 0, // sigma shrink = minimum spacing
xx = 0, // sigma natural spacing
x = 0, // sigma expandable elements
xs = 0, // sigma unexpandable elements with no space
xse = 0 // sigma unexpandable elements with space
/* calculate the whole space of the symbols */
for (s = tsfirst; s; s = s.ts_next) {
if (s.type == C.GRACE && !some_grace)
some_grace = s
if (s.seqst) {
xmin += s.shrink
if (s.space) {
if (s.space < s.shrink) {
xse += s.shrink;
xx += s.shrink
} else {
xx += s.space
}
} else {
xs += s.shrink
}
}
}
// can occur when bar alone in a staff system
if (xx == 0) {
realwidth = 0
return
}
// last line?
ll = !tsnext || // yes
tsnext.type == C.BLOCK // no, but followed by %%command
|| blocks.length // (abcm2ps compatibility)
// strong shrink
if (xmin >= width) {
if (xmin > width)
error(1, s, "Line too much shrunk $1 $2 $3",
xmin.toFixed(1),
xx.toFixed(1),
width.toFixed(1));
x = 0
for (s = tsfirst; s; s = s.ts_next) {
if (s.seqst)
x += s.shrink;
s.x = x
}
// realwidth = width
spf_last = 0
} else if ((ll && xx + xs > width * (1 - cfmt.stretchlast))
|| (!ll && (xx + xs > width || cfmt.stretchstaff))) {
if (xx == xse) // if no space
xx += 5
for (var cnt = 4; --cnt >= 0; ) {
spf = (width - xs - xse) / (xx - xse);
xx = 0;
xse = 0;
x = 0
for (s = tsfirst; s; s = s.ts_next) {
if (s.seqst) {
if (s.space) {
if (s.space * spf <= s.shrink) {
xse += s.shrink;
xx += s.shrink;
x += s.shrink
} else {
xx += s.space;
x += s.space * spf
}
} else {
x += s.shrink
}
}
s.x = x
}
if (Math.abs(x - width) < 0.1)
break
}
spf_last = spf
} else { // shorter line
spf = (width - xs - xse) / xx
if (spf_last < spf)
spf = spf_last
for (s = tsfirst; s; s = s.ts_next) {
if (s.seqst)
x += s.space * spf <= s.shrink ?
s.shrink : s.space * spf
s.x = x
}
}
realwidth = x
/* set the x offsets of the grace notes */
for (s = some_grace; s; s = s.ts_next) {
if (s.type != C.GRACE)
continue
if (s.gr_shift)
x = s.prev.x + s.prev.wr
else
x = s.x - s.wl
for (g = s.extra; g; g = g.next)
g.x += x
}
}
// set the starting symbols of the voices for the new music line
function set_sym_line() {
|
| ︙ | ︙ | |||
4450 4451 4452 4453 4454 4455 4456 |
for ( ; s; s = s.ts_next) {
if (s.time != tim) {
set_page()
return
}
switch (s.type) {
| | | | | | > | | < | | | | < > > > > | | 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 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 |
for ( ; s; s = s.ts_next) {
if (s.time != tim) {
set_page()
return
}
switch (s.type) {
case C.NOTE:
case C.REST:
case C.MREST:
set_page()
return
default:
continue
case C.STAVES:
cur_sy = s.sy
break
case C.BLOCK:
block_gen(s)
break
}
unlksym(s)
if (s.p_v.s_next == s)
s.p_v.s_next = s.next
}
tsfirst = null /* no more notes */
}
/* -- generate the music -- */
// (possible hook)
function output_music() {
var v, lwidth, indent, line_height
gen_init()
if (!tsfirst)
return
set_global()
if (voice_tb.length > 1) /* if many voices */
self.set_stem_dir() // set the stems direction in 'multi'
for (v = 0; v < voice_tb.length; v++)
set_beams(voice_tb[v].sym); /* decide on beams */
self.set_stems() // set the stem lengths
if (voice_tb.length > 1) { /* if many voices */
set_rest_offset(); /* set the vertical offset of rests */
set_overlap(); /* shift the notes on voice overlap */
// set_rp_bars() // set repeat bars
}
set_acc_shft(); // set the horizontal offset of accidentals
set_allsymwidth(); /* set the width of all symbols */
indent = set_indent(true)
/* if single line, adjust the page width */
if (cfmt.singleline) {
v = get_ck_width();
lwidth = indent + v[0] + v[1] + get_width(tsfirst, null);
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)
}
spf_last = 1.2 // last spacing factor
while (1) { /* loop per music line */
set_piece();
self.set_sym_glue(lwidth - indent)
if (realwidth != 0) {
if (indent != 0)
posx += indent;
draw_sym_near(); // delayed output
line_height = set_staff();
draw_systems(indent);
draw_all_sym();
delayed_update();
vskip(line_height)
if (indent != 0) {
posx -= indent;
insert_meter &= ~2 // no more indentation
}
while (blocks.length != 0)
block_gen(blocks.shift())
}
tsfirst = tsnext
if (cfmt.splittune)
blk_flush()
else
svg_flush()
if (!tsnext)
break
// next line
gen_init()
if (!tsfirst)
break
|
| ︙ | ︙ |
Changes to core/parse.js.
1 2 | // abc2svg - parse.js - ABC parse // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - parse.js - ABC parse // // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
37 38 39 40 41 42 43 |
}
// -- %% pseudo-comment
// clef definition (%%clef, K: and V:)
function new_clef(clef_def) {
var s = {
| | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
}
// -- %% pseudo-comment
// clef definition (%%clef, K: and V:)
function new_clef(clef_def) {
var s = {
type: C.CLEF,
clef_line: 2,
clef_type: "t",
v: curvoice.v,
p_v: curvoice,
time: curvoice.time,
dur: 0
},
|
| ︙ | ︙ | |||
92 93 94 95 96 97 98 | // s.clef_type = "t" // treble break case 'p': i = 4 case 'P': // perc s.clef_type = "p"; s.clef_line = 3; | | > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
// s.clef_type = "t" // treble
break
case 'p':
i = 4
case 'P': // perc
s.clef_type = "p";
s.clef_line = 3;
curvoice.key.k_sf = 0; // no accidental
curvoice.ckey.k_drum = true // no transpose
break
default:
syntax(1, "Unknown clef '$1'", clef_def)
return //undefined
}
if (clef_def[i] >= '1' && clef_def[i] <= '9') {
s.clef_line = Number(clef_def[i]);
|
| ︙ | ︙ | |||
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
s.clef_oct_transp = true
case '-':
s.clef_octave = -7
break
}
return s
}
// get a transposition value
function get_transp(param,
type) { // undefined or "instr"
var i, val, tmp, note,
pit = []
| > > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
s.clef_oct_transp = true
case '-':
s.clef_octave = -7
break
}
return s
}
var note_pit = new Int8Array([0, 2, 4, 5, 7, 9, 11])
// get a transposition value
function get_transp(param,
type) { // undefined or "instr"
var i, val, tmp, note,
pit = []
|
| ︙ | ︙ | |||
167 168 169 170 171 172 173 |
param = param.replace(/.*\//, 'c')
}
}
tmp = new scanBuf();
tmp.buffer = param
for (i = 0; i < 2; i++) {
| | < < | 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 |
param = param.replace(/.*\//, 'c')
}
}
tmp = new scanBuf();
tmp.buffer = param
for (i = 0; i < 2; i++) {
note = tmp.buffer[tmp.index] ? parse_acc_pit(tmp) : null
if (!note) {
syntax(1, "Bad transpose value")
return
}
note.pit += 124; // 126 - 2 for value > 0 and 'C' % 7 == 0
val = ((note.pit / 7) | 0) * 12 + note_pit[note.pit % 7]
if (note.acc && note.acc != 3) // if not natural
val += note.acc;
pit[i] = val
}
val = (pit[1] - pit[0]) * 3
if (note) {
switch (note.acc) {
default:
return val
case 2:
|
| ︙ | ︙ | |||
318 319 320 321 322 323 324 |
val += '|'
return val
}
// create a block symbol in the tune body
function new_block(subtype) {
var s = {
| | > | 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 |
val += '|'
return val
}
// create a block symbol in the tune body
function new_block(subtype) {
var s = {
type: C.BLOCK,
subtype: subtype,
dur: 0
}
if (parse.state == 2)
goto_tune()
var voice_s = curvoice;
curvoice = voice_tb[par_sy.top_voice]
sym_link(s);
curvoice = voice_s
return s
}
// set the voice parameters
// (possible hook)
function set_vp(a) {
var s, item, pos, val, clefpit
while (1) {
item = a.shift()
if (!item)
break
|
| ︙ | ︙ | |||
385 386 387 388 389 390 391 | case "cue=": curvoice.scale = a.shift() == 'on' ? .7 : 1 break case "instrument=": curvoice.transp = get_transp(a.shift(), 'instr') break case "map=": // %%voicemap | < | | 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | case "cue=": curvoice.scale = a.shift() == 'on' ? .7 : 1 break case "instrument=": curvoice.transp = get_transp(a.shift(), 'instr') break case "map=": // %%voicemap curvoice.map = a.shift() break case "name=": case "nm=": curvoice.nm = a.shift() if (curvoice.nm[0] == '"') curvoice.nm = curvoice.nm.slice(1, -1); curvoice.new_name = true |
| ︙ | ︙ | |||
445 446 447 448 449 450 451 452 453 454 455 456 457 458 | if (curvoice.snm[0] == '"') curvoice.snm = curvoice.snm.slice(1, -1); break case "stafflines=": val = get_st_lines(a.shift()) if (val == undefined) syntax(1, "Bad %%stafflines value") else curvoice.stafflines = val break case "staffnonote=": val = parseInt(a.shift()) if (isNaN(val)) syntax(1, "Bad %%staffnonote value") | > > | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | if (curvoice.snm[0] == '"') curvoice.snm = curvoice.snm.slice(1, -1); break case "stafflines=": val = get_st_lines(a.shift()) if (val == undefined) syntax(1, "Bad %%stafflines value") else if (curvoice.st != undefined) par_sy.staves[curvoice.st].stafflines = val else curvoice.stafflines = val break case "staffnonote=": val = parseInt(a.shift()) if (isNaN(val)) syntax(1, "Bad %%staffnonote value") |
| ︙ | ︙ | |||
510 511 512 513 514 515 516 | if (info.V['*']) a = info.V['*'].concat(a) if (info.V[curvoice.id]) a = info.V[curvoice.id].concat(a) } } if (a.length != 0) | | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 |
if (info.V['*'])
a = info.V['*'].concat(a)
if (info.V[curvoice.id])
a = info.V[curvoice.id].concat(a)
}
}
if (a.length != 0)
self.set_vp(a)
} // set_kv_parm()
// memorize the K:/V: parameters
function memo_kv_parm(vid, // voice ID (V:) / '*' (K:/V:*)
a) { // array of items
if (a.length == 0)
return
|
| ︙ | ︙ | |||
532 533 534 535 536 537 538 |
// K: key signature
// return the key and the voice/clef parameters
function new_key(param) {
var i, clef, key_end, c, tmp,
mode = 0,
s = {
| | < < < | | < > | 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 |
// K: key signature
// return the key and the voice/clef parameters
function new_key(param) {
var i, clef, key_end, c, tmp,
mode = 0,
s = {
type: C.KEY,
k_delta: 0,
dur:0
}
set_ref(s);
// tonic
i = 1
switch (param[0]) {
case 'A': s.k_sf = 3; break
case 'B': s.k_sf = 5; break
case 'C': s.k_sf = 0; break
case 'D': s.k_sf = 2; break
case 'E': s.k_sf = 4; break
case 'F': s.k_sf = -1; break
case 'G': s.k_sf = 1; break
case 'H': // bagpipe
switch (param[1]) {
case 'P':
case 'p':
s.k_bagpipe = param[1];
s.k_sf = param[1] == 'P' ? 0 : 2;
i++
break
default:
syntax(1, "Unknown bagpipe-like key")
break
}
break
case 'P':
syntax(1, "K:P is deprecated");
s.k_drum = true;
key_end = true
break
case 'n': // none
if (param.indexOf("none") == 0) {
s.k_sf = 0;
s.k_none = true;
|
| ︙ | ︙ | |||
589 590 591 592 593 594 595 596 597 598 599 600 601 602 |
if (!key_end) {
switch (param[i]) {
case '#': s.k_sf += 7; i++; break
case 'b': s.k_sf -= 7; i++; break
}
param = param.slice(i).trim()
switch (param.slice(0, 3).toLowerCase()) {
case "aeo":
case "m":
case "min": s.k_sf -= 3;
mode = 5
break
case "dor": s.k_sf -= 2;
mode = 1
| > > > > > > > > | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
if (!key_end) {
switch (param[i]) {
case '#': s.k_sf += 7; i++; break
case 'b': s.k_sf -= 7; i++; break
}
param = param.slice(i).trim()
switch (param.slice(0, 3).toLowerCase()) {
default:
if (param[0] != 'm'
|| (param[1] != ' ' && param[1] != '\t'
&& param[1] != '\n')) {
key_end = true
break
}
// fall thru ('m')
case "aeo":
case "m":
case "min": s.k_sf -= 3;
mode = 5
break
case "dor": s.k_sf -= 2;
mode = 1
|
| ︙ | ︙ | |||
611 612 613 614 615 616 617 | break case "mix": s.k_sf -= 1; mode = 4 break case "phr": s.k_sf -= 4; mode = 2 break | < < < < < < < < < < | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
break
case "mix": s.k_sf -= 1;
mode = 4
break
case "phr": s.k_sf -= 4;
mode = 2
break
}
if (!key_end)
param = param.replace(/\w+\s*/, '')
// [exp] accidentals
if (param.indexOf("exp ") == 0) {
param = param.replace(/\w+\s*/, '')
|
| ︙ | ︙ | |||
656 657 658 659 660 661 662 | param = param.replace(/\w+\s*/, '') } } s.k_delta = cgd2cde[(s.k_sf + 7) % 7]; s.k_mode = mode | | | | < | | | < | | > > > | > | > | > > | > > > > > > > > > > > > | | | 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 |
param = param.replace(/\w+\s*/, '')
}
}
s.k_delta = cgd2cde[(s.k_sf + 7) % 7];
s.k_mode = mode
return [s, info_split(param)]
}
// M: meter
function new_meter(p) {
var s = {
type: C.METER,
dur: 0,
a_meter: []
},
meter = {},
val, v,
m1 = 0, m2,
i = 0, j,
wmeasure,
in_parenth;
set_ref(s)
if (p.indexOf("none") == 0) {
i = 4; /* no meter */
wmeasure = 1; // simplify measure numbering and C.MREST conversion
} else {
wmeasure = 0
while (i < p.length) {
if (p[i] == '=')
break
switch (p[i]) {
case 'C':
meter.top = p[i++]
if (!m1) {
m1 = 4;
m2 = 4
}
break
case 'c':
case 'o':
meter.top = p[i++]
if (!m1) {
if (p[-1] == 'c') {
m1 = 2;
m2 = 4
} else {
m1 = 3;
m2 = 4
}
switch (p[i]) {
case '|':
m2 /= 2
break
case '.':
m1 *= 3;
m2 *= 2
break
}
}
break
case '.':
case '|':
meter.top = p[i++]
break
case '(':
if (p[i + 1] == '(') { /* "M:5/4 ((2+3)/4)" */
in_parenth = true;
meter.top = p[i++];
s.a_meter.push(meter);
meter = {}
}
j = i + 1
while (j < p.length) {
if (p[j] == ')' || p[j] == '/')
break
j++
}
if (p[j] == ')' && p[j + 1] == '/') { /* "M:5/4 (2+3)/4" */
i++ /* remove the parenthesis */
continue
|
| ︙ | ︙ | |||
752 753 754 755 756 757 758 | meter.bot = p[i++] while (p[i] >= '0' && p[i] <= '9') meter.bot += p[i++] break } if (p[i] != ' ' && p[i] != '+') break | | | | > > > | | | | | 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 |
meter.bot = p[i++]
while (p[i] >= '0' && p[i] <= '9')
meter.bot += p[i++]
break
}
if (p[i] != ' ' && p[i] != '+')
break
if (i >= p.length
|| p[i + 1] == '(') /* "M:5 (2/4+3/4)" */
break
meter.top += p[i++]
}
m1 = parseInt(meter.top)
break
}
if (!in_parenth) {
if (meter.bot)
m2 = parseInt(meter.bot);
wmeasure += m1 * C.BLEN / m2
}
s.a_meter.push(meter);
meter = {}
while (p[i] == ' ')
i++
if (p[i] == '+') {
meter.top = p[i++];
s.a_meter.push(meter);
meter = {}
}
}
}
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]
}
s.wmeasure = wmeasure
if (cfmt.writefields.indexOf('M') < 0)
s.a_meter = []
if (parse.state != 3) {
info.M = p;
glovar.meter = s
if (parse.state >= 1) {
/* in the tune header, change the unit note length */
if (!glovar.ulen) {
if (wmeasure <= 1
|| wmeasure >= C.BLEN * 3 / 4)
glovar.ulen = C.BLEN / 8
else
glovar.ulen = C.BLEN / 16
}
for (v = 0; v < voice_tb.length; v++) {
voice_tb[v].meter = s;
voice_tb[v].wmeasure = wmeasure
}
}
} else {
|
| ︙ | ︙ | |||
819 820 821 822 823 824 825 |
}
}
/* Q: tempo */
function new_tempo(text) {
var i = 0, j, c, nd, tmp,
s = {
| | | 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 |
}
}
/* Q: tempo */
function new_tempo(text) {
var i = 0, j, c, nd, tmp,
s = {
type: C.TEMPO,
dur: 0
}
set_ref(s)
if (cfmt.writefields.indexOf('Q') < 0)
s.del = true // don't display
|
| ︙ | ︙ | |||
853 854 855 856 857 858 859 | // c = tmp.char() c = text[tmp.index] if (c == undefined || c <= '0' || c > '9') break nd = parse_dur(tmp) if (!s.tempo_notes) s.tempo_notes = [] | | | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 |
// c = tmp.char()
c = text[tmp.index]
if (c == undefined || c <= '0' || c > '9')
break
nd = parse_dur(tmp)
if (!s.tempo_notes)
s.tempo_notes = []
s.tempo_notes.push(C.BLEN * nd[0] / nd[1])
while (1) {
// c = tmp.char()
c = text[tmp.index]
if (c != ' ')
break
tmp.index++
}
|
| ︙ | ︙ | |||
879 880 881 882 883 884 885 |
tmp.index += 4;
// c = text[tmp.index]
}
if (text[tmp.index + 1] != '/') {
s.tempo = tmp.get_int()
} else {
nd = parse_dur(tmp);
| | | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 |
tmp.index += 4;
// c = text[tmp.index]
}
if (text[tmp.index + 1] != '/') {
s.tempo = tmp.get_int()
} else {
nd = parse_dur(tmp);
s.new_beat = C.BLEN * nd[0] / nd[1]
}
c = text[tmp.index]
while (c == ' ')
c = text[++tmp.index]
}
/* string after */
|
| ︙ | ︙ | |||
920 921 922 923 924 925 926 |
function do_info(info_type, text) {
var s, d1, d2, a, vid
switch (info_type) {
// info fields in any state
case 'I':
| | | | | 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 |
function do_info(info_type, text) {
var s, d1, d2, a, vid
switch (info_type) {
// info fields in any state
case 'I':
self.do_pscom(text)
break
case 'L':
//fixme: ??
if (parse.state == 2)
goto_tune();
a = text.match(/^1\/(\d+)(=(\d+)\/(\d+))?$/)
if (a) {
d1 = Number(a[1])
if (!d1 || (d1 & (d1 - 1)) != 0)
break
d1 = C.BLEN / d1
if (a[2]) {
d2 = Number(a[4])
if (!d2 || (d2 & (d2 - 1)) != 0) {
d2 = 0
break
}
d2 = Number(a[3]) / d2 * C.BLEN
} else {
d2 = d1
}
} else if (text == "auto") {
d1 = d2 = -1
}
if (!d2) {
|
| ︙ | ︙ | |||
976 977 978 979 980 981 982 |
break
}
if (parse.state == 2)
goto_tune()
if (cfmt.writefields.indexOf(info_type) < 0)
break
s = {
| | | | 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 |
break
}
if (parse.state == 2)
goto_tune()
if (cfmt.writefields.indexOf(info_type) < 0)
break
s = {
type: C.PART,
text: text,
dur: 0
}
/*
* If not in the main voice, then,
* if the voices are synchronized and no P: yet in the main voice,
* the misplaced P: goes into the main voice.
*/
var p_voice = voice_tb[par_sy.top_voice]
if (curvoice.v != p_voice.v) {
if (curvoice.time != p_voice.time)
break
if (p_voice.last_sym && p_voice.last_sym.type == C.PART)
break // already a P:
var voice_sav = curvoice;
curvoice = p_voice;
sym_link(s);
curvoice = voice_sav
} else {
sym_link(s)
|
| ︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 |
info[info_type] += '\n' + text
break
case 'r':
if (!user.keep_remark
|| parse.state != 3)
break
s = {
| | | 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 |
info[info_type] += '\n' + text
break
case 'r':
if (!user.keep_remark
|| parse.state != 3)
break
s = {
type: C.REMARK,
text: text,
dur: 0
}
sym_link(s)
break
default:
syntax(0, "'$1:' line ignored", info_type)
|
| ︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 | /* search the start of the measure */ s2 = curvoice.last_sym if (!s2) return; /* the bar time is correct if there are multi-rests */ | | | | | | 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 |
/* search the start of the measure */
s2 = curvoice.last_sym
if (!s2)
return;
/* the bar time is correct if there are multi-rests */
if (s2.type == C.MREST
|| s2.type == C.BAR) /* in second voice */
return
while (s2.type != C.BAR && s2.prev)
s2 = s2.prev;
time = s2.time;
auto_time = curvoice.time - time
/* remove the invisible rest at start of tune */
if (time == 0) {
while (s2 && !s2.dur)
s2 = s2.next
if (s2 && s2.type == C.REST
&& s2.invis) {
time += s2.dur * curvoice.wmeasure / auto_time
if (s2.prev)
s2.prev.next = s2.next
else
curvoice.sym = s2.next
if (s2.next)
|
| ︙ | ︙ | |||
1087 1088 1089 1090 1091 1092 1093 |
for ( ; s2; s2 = s2.next) {
s2.time = time
if (!s2.dur || s2.grace)
continue
s2.dur = s2.dur * curvoice.wmeasure / auto_time;
s2.dur_orig = s2.dur_orig * curvoice.wmeasure / auto_time;
time += s2.dur
| | < < < < < < < < | | 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 |
for ( ; s2; s2 = s2.next) {
s2.time = time
if (!s2.dur || s2.grace)
continue
s2.dur = s2.dur * curvoice.wmeasure / auto_time;
s2.dur_orig = s2.dur_orig * curvoice.wmeasure / auto_time;
time += s2.dur
if (s2.type != C.NOTE && s2.type != C.REST)
continue
for (i = 0; i <= s2.nhd; i++)
s2.notes[i].dur = s2.notes[i].dur
* curvoice.wmeasure / auto_time;
}
curvoice.time = s.time = time
}
/* -- parse a bar -- */
function new_bar() {
var s2, c, bar_type,
line = parse.line,
s = {
type: C.BAR,
fname: parse.fname,
istart: parse.bol + line.index,
dur: 0,
multi: 0 // needed for decorations
}
if (vover && vover.bar) // end of voice overlay
|
| ︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 |
} else {
s.rbstop = 2 // right repeat with end
}
}
// set the guitar chord and the decorations
if (a_gch)
| | > > > > > > > > > > > > > > > > > > > | 1156 1157 1158 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 |
} else {
s.rbstop = 2 // right repeat with end
}
}
// set the guitar chord and the decorations
if (a_gch)
self.gch_build(s)
if (a_dcn) {
deco_cnv(a_dcn, s);
a_dcn = null
}
// set the start/stop of ottava
if (parse.ottava != undefined) {
s2 = s
if (curvoice.cst != curvoice.st) { // if staff change
s2 = {
type: C.SPACE, // put the decoration on a ...
fname: parse.fname,
istart: parse.bol + line.index,
dur: 0,
multi: 0,
invis: true,
width: 1 // .. small space
}
sym_link(s2)
}
s2.ottava = parse.ottava
delete parse.ottava
}
/* if the last element is '[', it may start
* a chord or an embedded header */
switch (bar_type.slice(-1)) {
case '[':
if (/[0-9" ]/.test(c)) // "
break
|
| ︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 | && !curvoice.second) s.norepbra = true if (curvoice.ulen < 0) // L:auto adjust_dur(s); s2 = curvoice.last_sym | | > | | > | > > > > > > > > > | > | | | | | | | | | | | | | | | | | | > | | | | | | | | | | > > | 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 |
&& !curvoice.second)
s.norepbra = true
if (curvoice.ulen < 0) // L:auto
adjust_dur(s);
s2 = curvoice.last_sym
if (s2 && s2.time == curvoice.time) {
if (s2.type == C.SPACE) {
s2.time-- // keep the space at the right place
} else if (bar_type == "["
|| bar_type == "|:") {
// search if a previous bar at this time
do {
if (s2.type == C.BAR)
break
if (w_tb[s2.type]) // symbol with a width
break
s2 = s2.prev
} while (s2)
if (s2 && s2.type == C.BAR) {
// && !s2.a_gch && !s2.a_dd
// && !s.a_gch && !s.a_dd) {
// remove the invisible repeat bars
// when no shift is needed
if (bar_type == "["
&& !s2.text
&& (curvoice.st == 0
|| (par_sy.staves[curvoice.st - 1].flags & STOP_BAR)
|| s.norepbra)) {
if (s.text)
s2.text = s.text
if (s.a_gch)
s2.a_gch = s.a_gch
if (s.norepbra)
s2.norepbra = s.norepbra
if (s.rbstart)
s2.rbstart = s.rbstart
if (s.rbstop)
s2.rbstop = s.rbstop
//--fixme: pb when on next line and empty staff above
return
}
// merge back-to-back repeat bars
if (s2.st == curvoice.st
&& bar_type == "|:") {
if (s2.bar_type == ":|") {
s2.bar_type = "::";
s2.rbstop = 2
return
}
if (s2.bar_type == "||") {
s2.bar_type = "||:";
s2.rbstop = 2
return
}
}
}
}
}
/* set some flags */
switch (bar_type) {
case "[":
|
| ︙ | ︙ | |||
1293 1294 1295 1296 1297 1298 1299 | } s.bar_type = bar_type if (!curvoice.lyric_restart) curvoice.lyric_restart = s if (!curvoice.sym_restart) curvoice.sym_restart = s | < < < < < < | < < < < < | | | 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 |
}
s.bar_type = bar_type
if (!curvoice.lyric_restart)
curvoice.lyric_restart = s
if (!curvoice.sym_restart)
curvoice.sym_restart = s
sym_link(s);
s.st = curvoice.st /* original staff */
/* if repeat bar and shift, add a repeat bar */
if (s.rbstart
&& !curvoice.norepbra
&& curvoice.st > 0
&& !(par_sy.staves[curvoice.st - 1].flags & STOP_BAR)) {
s2 = {
type: C.BAR,
fname: s.fname,
istart: s.istart,
iend: s.iend,
bar_type: "[",
multi: 0,
invis: true,
text: s.text,
|
| ︙ | ︙ | |||
1342 1343 1344 1345 1346 1347 1348 | a_vf = [], err = false, flags = 0, brace = 0, bracket = 0, parenth = 0, flags_st = 0, | > > | > > > | < | < | | > | 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 |
a_vf = [],
err = false,
flags = 0,
brace = 0,
bracket = 0,
parenth = 0,
flags_st = 0,
e,
a = p.match(/\w+|[^\s]/g)
if (!a) {
syntax(1, errs.bad_val, "%%staves")
return // null
}
while (1) {
e = a.shift()
if (!e)
break
switch (e) {
case '[':
if (parenth || brace + bracket >= 2) {
syntax(1, errs.misplaced, '[');
err = true
break
}
flags |= brace + bracket == 0 ? OPEN_BRACKET : OPEN_BRACKET2;
|
| ︙ | ︙ | |||
1391 1392 1393 1394 1395 1396 1397 | if (brace && !parenth && !(flags & (OPEN_BRACE | OPEN_BRACE2))) flags |= FL_VOICE break case '+': flags |= MASTER_VOICE break default: | | | | > | < < < | < < < | 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 |
if (brace && !parenth && !(flags & (OPEN_BRACE | OPEN_BRACE2)))
flags |= FL_VOICE
break
case '+':
flags |= MASTER_VOICE
break
default:
if (!/\w/.test(e)) {
syntax(1, "Bad voice ID in %%staves");
err = true
break
}
/* get / create the voice in the voice table */
vid = e
while (1) {
e = a.shift()
if (!e)
break
switch (e) {
case ']':
if (!(flags_st & OPEN_BRACKET)) {
syntax(1, errs.misplaced, ']');
err = true
break
}
bracket--;
|
| ︙ | ︙ | |||
1452 1453 1454 1455 1456 1457 1458 | flags |= STOP_BAR continue } break } a_vf.push([vid, flags]); flags = 0 | > | > > < | > < < | | > > | | | | | > > | < | | | | | | | 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 |
flags |= STOP_BAR
continue
}
break
}
a_vf.push([vid, flags]);
flags = 0
if (!e)
break
a.unshift(e)
break
}
}
if (flags_st != 0) {
syntax(1, "'}', ')' or ']' missing in %%staves");
err = true
}
if (err || a_vf.length == 0)
return //null
return a_vf
}
// split an info string
function info_split(text) {
if (!text)
return []
var a = text.match(/=?[^\s"=]+=?|".+?"/g) // "
if (!a) {
//fixme: bad error text
syntax(1, "Unterminated string")
return []
}
return a
}
/* -- get head type, dots, flags of note/rest for a duration -- */
function identify_note(s, dur_o) {
var head, dots, flags,
dots = 0,
dur = dur_o
if (dur % 12 != 0)
error(1, s, "Invalid note duration $1", dur);
dur /= 12 /* see C.BLEN for values */
if (dur == 0)
error(1, s, "Note too short")
for (flags = 5; dur != 0; dur >>= 1, flags--) {
if (dur & 1)
break
}
dur >>= 1
switch (dur) {
case 0: break
case 1: dots = 1; break
case 3: dots = 2; break
case 7: dots = 3; break
default:
error(1, s, "Invalid note duration $1", dur_o);
flags += ((11 - dur) / 4) | 0;
dots = 4
break
}
flags -= dots
if (flags >= 0) {
head = C.FULL
} else switch (flags) {
default:
error(1, s, "Note too long");
flags = -4
/* fall thru */
case -4:
head = C.SQUARE
break
case -3:
head = cfmt.squarebreve ? C.SQUARE : C.OVALBARS
break
case -2:
head = C.OVAL
break
case -1:
head = C.EMPTY
break
}
return [head, dots, flags]
}
// parse a duration and return [numerator, denominator]
// 'line' is not always 'parse.line'
|
| ︙ | ︙ | |||
1609 1610 1611 1612 1613 1614 1615 |
}
while (c == ',') {
pit -= 7;
c = line.next_char()
}
note = {
pit: pit,
| < | | | | | | < < < < | | | | > | > > > > > > | | | 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 1707 1708 |
}
while (c == ',') {
pit -= 7;
c = line.next_char()
}
note = {
pit: pit,
shhd: 0,
shac: 0,
ti1: 0
}
if (acc) {
note.acc = acc
if (micro_n) {
note.micro_n = micro_n;
note.micro_d = micro_d
}
}
return note
}
// convert a note pitch to ABC text
function note2abc(note) {
var i,
abc = 'abcdefg'[(note.pit + 77) % 7]
//fixme: treat microtone
if (note.acc)
abc = ['__', '_', '', '^', '^^', '='][note.acc + 2] + abc
for (i = note.pit; i >= 30; i -= 7) // down to 'c'
abc += "'"
for (i = note.pit; i < 23; i += 7) // up to 'C'
abc += ","
return abc
}
/* set the mapping of a note */
function set_map(note) {
var map = maps[curvoice.map], // never null
nn = note2abc(note)
if (!map[nn]) {
nn = 'octave,' + nn.replace(/[',]/g, '') // octave '
if (!map[nn]) {
nn = 'key,' + // 'key,'
'abcdefg'[(note.pit + 77 -
curvoice.ckey.k_delta) % 7]
if (!map[nn]) {
nn = 'all' // 'all'
if (!map[nn])
return
}
}
}
note.map = map[nn]
if (note.map[1]) {
note.pit = note.map[1].pit; // print/play
note.acc = note.map[1].acc
}
}
/* -- parse note or rest with pitch and length -- */
// 'line' is not always 'parse.line'
function parse_basic_note(line, ulen) {
|
| ︙ | ︙ | |||
1686 1687 1688 1689 1690 1691 1692 |
function parse_vpos() {
var c,
line = parse.line,
ti1 = 0
if (line.buffer[line.index - 1] == '.' && !a_dcn)
| | | | | | 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 |
function parse_vpos() {
var c,
line = parse.line,
ti1 = 0
if (line.buffer[line.index - 1] == '.' && !a_dcn)
ti1 = C.SL_DOTTED
switch (line.next_char()) {
case "'":
line.index++
return ti1 + C.SL_ABOVE
case ",":
line.index++
return ti1 + C.SL_BELOW
}
return ti1 + C.SL_AUTO
}
var cde2fcg = new Int8Array([0, 2, 4, -1, 1, 3, 5]),
cgd2cde = new Int8Array([0, 4, 1, 5, 2, 6, 3]),
acc2 = new Int8Array([-2, -1, 3, 1, 2])
/* transpose a note / chord */
|
| ︙ | ︙ | |||
1720 1721 1722 1723 1724 1725 1726 |
dp += ((t / 3 / 12) | 0) * 7
for (i = 0; i <= m; i++) {
note = s.notes[i];
// pitch
n = note.pit;
note.pit += dp;
| < | 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 |
dp += ((t / 3 / 12) | 0) * 7
for (i = 0; i <= m; i++) {
note = s.notes[i];
// pitch
n = note.pit;
note.pit += dp;
// accidental
i1 = cde2fcg[(n + 5 + 16 * 7) % 7]; /* fcgdaeb */
a = note.acc
if (!a) {
if (!curvoice.okey.a_acc) {
if (sf_old > 0) {
|
| ︙ | ︙ | |||
1788 1789 1790 1791 1792 1793 1794 |
} else {
a = -i1
}
break
case 2: // double sharp
if (n > d / 2) {
note.pit += 1;
| < < > | | | | > > > > > > > > > > | | | | 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 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 |
} else {
a = -i1
}
break
case 2: // double sharp
if (n > d / 2) {
note.pit += 1;
n -= d / 2
} else {
n += d / 2
}
a = i1;
note.micro_n = n
break
case -2: // double flat
if (n >= d / 2) {
note.pit -= 1;
n -= d / 2
} else {
n += d / 2
}
a = i1;
note.micro_n = n
break
}
}
note.acc = a
}
}
/* sort the notes of the chord by pitch (lowest first) */
function sort_pitch(s) {
s.notes = s.notes.sort(function(n1, n2) {
return n1.pit - n2.pit
})
}
// (possible hook)
function new_note(grace, tp_fact) {
var note, s, in_chord, c, dcn, type,
i, n, s2, nd, res, num, dur,
sl1 = 0,
line = parse.line,
a_dcn_sav = a_dcn; // save parsed decoration names
a_dcn = null;
parse.stemless = false;
s = {
type: C.NOTE,
fname: parse.fname,
stem: 0,
multi: 0,
nhd: 0,
xmx: 0
}
s.istart = parse.bol + line.index
if (curvoice.color)
s.color = curvoice.color
if (grace) {
s.grace = true
} else {
if (a_gch)
self.gch_build(s)
if (parse.repeat_n) {
s.repeat_n = parse.repeat_n;
s.repeat_k = parse.repeat_k;
parse.repeat_n = 0
}
}
c = line.char()
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;
s.dur = curvoice.wmeasure * s.nmes
// ignore if in second voice
if (curvoice.second) {
curvoice.time += s.dur
return //null
}
// convert 'Z'/'Z1' to a whole measure rest
if (s.nmes == 1) {
s.type = C.REST;
s.dur_orig = s.dur;
s.notes = [{
pit: 18,
dur: s.dur
}]
}
break
case 'y':
s.type = C.SPACE;
s.invis = true;
s.dur = 0;
c = line.next_char()
if (c >= '0' && c <= '9')
s.width = line.get_int()
else
s.width = 10
break
case 'x':
s.invis = true
case 'z':
s.type = C.REST;
line.index++;
nd = parse_dur(line);
s.dur_orig = ((curvoice.ulen < 0) ?
C.BLEN :
curvoice.ulen) * nd[0] / nd[1];
s.dur = s.dur_orig * curvoice.dur_fact;
s.notes = [{
pit: 18,
dur: s.dur_orig
}]
break
|
| ︙ | ︙ | |||
1913 1914 1915 1916 1917 1918 1919 |
if (in_chord) {
while (1) {
if (!c)
break
i = c.charCodeAt(0);
if (i >= 128) {
syntax(1, errs.not_ascii)
| | | 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 |
if (in_chord) {
while (1) {
if (!c)
break
i = c.charCodeAt(0);
if (i >= 128) {
syntax(1, errs.not_ascii)
return //null
}
type = char_tb[i]
switch (type[0]) {
case '(':
sl1 <<= 4;
sl1 += parse_vpos();
c = line.char()
|
| ︙ | ︙ | |||
1948 1949 1950 1951 1952 1953 1954 | c = line.next_char() continue } break } } note = parse_basic_note(line, | | | < < | | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 |
c = line.next_char()
continue
}
break
}
}
note = parse_basic_note(line,
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
if (sl1) {
note.sl1 = sl1
if (s.sl1)
s.sl1++
else
s.sl1 = 1;
sl1 = 0
|
| ︙ | ︙ | |||
2024 2025 2026 2027 2028 2029 2030 | } } // 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 } | | | | | | 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 |
}
}
// 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
}
if (s.grace && s.type != C.NOTE) {
syntax(1, "Not a note in grace note sequence")
return //null
}
if (s.notes) { // if note or rest
if (!s.grace) {
switch (curvoice.pos.stm) {
case C.SL_ABOVE: s.stem = 1; break
case C.SL_BELOW: s.stem = -1; break
case C.SL_HIDDEN: s.stemless = true; break
}
// adjust the symbol duration
s.dur *= tp_fact;
num = curvoice.brk_rhythm
if (num) {
curvoice.brk_rhythm = 0;
|
| ︙ | ︙ | |||
2068 2069 2070 2071 2072 2073 2074 | s2.dur = s2.dur * n / num; s2.dur_orig = s2.dur_orig * n / num for (i = 0; i <= s2.nhd; i++) s2.notes[i].dur = s2.notes[i].dur * n / num } curvoice.time = s2.time + s2.dur; | < < < < < < < < | | < | < < < | | | | < | | | | | | | | < < < < | | > > > > | | | 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 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 |
s2.dur = s2.dur * n / num;
s2.dur_orig = s2.dur_orig * n / num
for (i = 0; i <= s2.nhd; i++)
s2.notes[i].dur =
s2.notes[i].dur * n / num
}
curvoice.time = s2.time + s2.dur;
// adjust the time of the grace notes, bars...
for (s2 = s2.next; s2; s2 = s2.next)
s2.time = curvoice.time
}
} else { /* grace note - adjust its duration */
var div = curvoice.ckey.k_bagpipe ? 8 : 4
for (i = 0; i <= s.nhd; i++)
s.notes[i].dur /= div;
s.dur /= div;
s.dur_orig /= div
if (grace.stem)
s.stem = grace.stem
}
// adjust the duration
dur = s.dur_orig
if (curvoice.ulen < 0) {
dur = C.BLEN
} else if (s.type == C.REST
/* change the figure of whole measure rests */
//--fixme: does not work in abcm2ps sample.abc because broken rhythm on measure bar
&& dur == curvoice.wmeasure) {
if (dur < C.BLEN * 2)
dur = C.BLEN
else if (dur < C.BLEN * 4)
dur = C.BLEN * 2
else
dur = C.BLEN * 4
}
curvoice.last_note = s
}
sym_link(s)
if (s.type == C.NOTE) {
if (curvoice.vtransp)
note_transp(s)
if (curvoice.map
&& maps[curvoice.map]) {
for (i = 0; i <= s.nhd; i++)
set_map(s.notes[i])
}
}
if (cfmt.shiftunison)
s.shiftunison = cfmt.shiftunison
if (!grace) {
if (!curvoice.lyric_restart)
curvoice.lyric_restart = s
if (!curvoice.sym_restart)
curvoice.sym_restart = s
}
if (a_dcn_sav)
deco_cnv(a_dcn_sav, s, s.prev)
if (parse.ottava != undefined) {
s.ottava = parse.ottava
delete parse.ottava
}
if (parse.stemless)
s.stemless = true
s.iend = parse.bol + line.index
return s
}
// characters in the music line (ASCII only)
var nil = ["0"],
char_tb = [
nil, nil, nil, nil, /* 00 - .. */
nil, nil, nil, nil,
nil, " ", "\n", nil, /* . \t \n . */
nil, nil, nil, nil,
nil, nil, nil, nil,
nil, nil, nil, nil,
nil, nil, nil, nil,
|
| ︙ | ︙ | |||
2188 2189 2190 2191 2192 2193 2194 |
"d", "d", "d", "d", /* h i j k */
"d", "d", "d", "d", /* l m n o */
"d", "d", "d", "d", /* p q r s */
"d", "!upbow!",
"!downbow!", "d", /* t u v w */
"n", "n", "n", "{", /* x y z { */
"|", "}", "!gmark!", nil, /* | } ~ (del) */
| | > > | 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 |
"d", "d", "d", "d", /* h i j k */
"d", "d", "d", "d", /* l m n o */
"d", "d", "d", "d", /* p q r s */
"d", "!upbow!",
"!downbow!", "d", /* t u v w */
"n", "n", "n", "{", /* x y z { */
"|", "}", "!gmark!", nil, /* | } ~ (del) */
],
ottava = {"8va(":1, "8va)":0, "15ma(":2, "15ma)":0,
"8vb(":-1, "8vb)":0, "15mb(":-2, "15mb)":0}
function parse_music_line() {
var grace, last_note_sav, a_dcn_sav, no_eol, s,
tp_a = [], tp,
tpn = -1,
tp_fact = 1,
slur_start = 0,
|
| ︙ | ︙ | |||
2403 2404 2405 2406 2407 2408 2409 |
continue
case ')': // slur end
if (curvoice.ignore)
break
s = curvoice.last_sym
if (s) {
switch (s.type) {
| | | | | 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 |
continue
case ')': // slur end
if (curvoice.ignore)
break
s = curvoice.last_sym
if (s) {
switch (s.type) {
case C.NOTE:
case C.REST:
case C.SPACE:
break
default:
s = null
break
}
}
if (!s) {
|
| ︙ | ︙ | |||
2443 2444 2445 2446 2447 2448 2449 |
}
if (!c) {
line.index = i;
syntax(1, "No end of decoration")
break
}
}
| | | > | | | 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 |
}
if (!c) {
line.index = i;
syntax(1, "No end of decoration")
break
}
}
if (ottava[dcn] != undefined)
parse.ottava = ottava[dcn]
else
a_dcn.push(dcn)
break
case '"':
parse_gchord(type)
break
case '-':
var tie_pos = 0
if (!curvoice.last_note
|| curvoice.last_note.type != C.NOTE) {
syntax(1, "No note before '-'")
break
}
tie_pos = parse_vpos();
s = curvoice.last_note
for (i = 0; i <= s.nhd; i++) {
if (!s.notes[i].ti1)
|
| ︙ | ︙ | |||
2499 2500 2501 2502 2503 2504 2505 |
line.index = 0;
do_info(c_next, text);
line.index = i
continue
}
// fall thru ('[' is start of chord)
case 'n': // note/rest
| | | | 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 |
line.index = 0;
do_info(c_next, text);
line.index = i
continue
}
// fall thru ('[' is start of chord)
case 'n': // note/rest
s = self.new_note(grace, tp_fact)
if (!s)
continue
if (s.type == C.NOTE) {
if (slur_start) {
s.slur_start = slur_start;
slur_start = 0
}
}
if (grace) {
//fixme: tuplets in grace notes?
|
| ︙ | ︙ | |||
2542 2543 2544 2545 2546 2547 2548 |
s.tq0 = tp.q;
s.tf = tp.f; // %%tuplets
tp.p = 0
}
tp.r--
if (tp.r == 0) {
if (tpn-- == 0) {
| > > > | > > > | | 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 |
s.tq0 = tp.q;
s.tf = tp.f; // %%tuplets
tp.p = 0
}
tp.r--
if (tp.r == 0) {
if (tpn-- == 0) {
if (s.tp0) // if one note
s.tp0 = false
else
s.te0 = true;
tp_fact = 1;
curvoice.time = Math.round(curvoice.time);
s.dur = curvoice.time - s.time
} else {
if (s.tp1) // if one note
s.tp1 = false
else
s.te1 = true;
tp = tp_a[0]
if (tp.r == 0) {
tpn--;
s.te0 = true;
tp_fact = 1;
curvoice.time = Math.round(curvoice.time);
s.dur = curvoice.time - s.time
|
| ︙ | ︙ | |||
2590 2591 2592 2593 2594 2595 2596 |
break
}
last_note_sav = curvoice.last_note;
curvoice.last_note = null;
a_dcn_sav = a_dcn;
a_dcn = undefined;
grace = {
| | | | | | 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 |
break
}
last_note_sav = curvoice.last_note;
curvoice.last_note = null;
a_dcn_sav = a_dcn;
a_dcn = undefined;
grace = {
type: C.GRACE,
fname: parse.fname,
istart: parse.bol + line.index,
dur: 0,
multi: 0
}
switch (curvoice.pos.gst) {
case C.SL_ABOVE: grace.stem = 1; break
case C.SL_BELOW: grace.stem = -1; break
case C.SL_HIDDEN: grace.stem = 2; break /* opposite */
}
sym_link(grace);
c = line.next_char()
if (c == '/') {
grace.sappo = true // acciaccatura
break
}
|
| ︙ | ︙ | |||
2633 2634 2635 2636 2637 2638 2639 | s.gr_end = true; grace.extra = grace.next; grace.extra.prev = null; grace.next = null; curvoice.last_sym = grace; grace = null if (!s.prev // if one grace note | | < < < < | 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 |
s.gr_end = true;
grace.extra = grace.next;
grace.extra.prev = null;
grace.next = null;
curvoice.last_sym = grace;
grace = null
if (!s.prev // if one grace note
&& !curvoice.ckey.k_bagpipe) {
for (i = 0; i <= s.nhd; i++)
s.notes[i].dur *= 2;
s.dur *= 2;
s.dur_orig *= 2
}
curvoice.last_note = last_note_sav;
a_dcn = a_dcn_sav
break
case "\\":
c = line.buffer[line.index + 1]
if (!c) {
|
| ︙ | ︙ |
Changes to core/subs.js.
1 2 | // abc2svg - subs.js - text output // | | | | > > | | > > > > > > > > > > > > > > > > > > | > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// abc2svg - subs.js - text output
//
// Copyright (C) 2014-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
// width of characters according to the font type
// these tables were created from the font 'Liberation'
// serif
var
sw_tb = new Float32Array([
.000,.000,.000,.000,.000,.000,.000,.000, // 00
.000,.000,.000,.000,.000,.000,.000,.000,
.000,.000,.000,.000,.000,.000,.000,.000, // 10
.000,.000,.000,.000,.000,.000,.000,.000,
.250,.333,.408,.500,.500,.833,.778,.333, // 20
.333,.333,.500,.564,.250,.564,.250,.278,
.500,.500,.500,.500,.500,.500,.500,.500, // 30
.500,.500,.278,.278,.564,.564,.564,.444,
.921,.722,.667,.667,.722,.611,.556,.722, // 40
.722,.333,.389,.722,.611,.889,.722,.722,
.556,.722,.667,.556,.611,.722,.722,.944, // 50
.722,.722,.611,.333,.278,.333,.469,.500,
.333,.444,.500,.444,.500,.444,.333,.500, // 60
.500,.278,.278,.500,.278,.778,.500,.500,
.500,.500,.333,.389,.278,.500,.500,.722, // 70
.500,.500,.444,.480,.200,.480,.541,.500]),
// sans-serif
ssw_tb = new Float32Array([
.000,.000,.000,.000,.000,.000,.000,.000, // 00
.000,.000,.000,.000,.000,.000,.000,.000,
.000,.000,.000,.000,.000,.000,.000,.000, // 10
.000,.000,.000,.000,.000,.000,.000,.000,
.278,.278,.355,.556,.556,.889,.667,.191, // 20
.333,.333,.389,.584,.278,.333,.278,.278,
.556,.556,.556,.556,.556,.556,.556,.556, // 30
.556,.556,.278,.278,.584,.584,.584,.556,
1.015,.667,.667,.722,.722,.667,.611,.778, // 40
.722,.278,.500,.667,.556,.833,.722,.778,
.667,.778,.722,.667,.611,.722,.667,.944, // 50
.667,.667,.611,.278,.278,.278,.469,.556,
.333,.556,.556,.500,.556,.556,.278,.556, // 60
.556,.222,.222,.500,.222,.833,.556,.556,
.556,.556,.333,.500,.278,.556,.500,.722, // 70
.500,.500,.500,.334,.260,.334,.584,.512]),
cw_tb = sw_tb // current width table
/* -- return the character width -- */
function cwid(c) {
var i = c.charCodeAt(0) // utf-16
if (i >= 0x80) { // if not ASCII
if (i >= 0x300 && i < 0x370)
return 0; // combining diacritical mark
i = 0x61 // 'a'
}
return cw_tb[i]
}
// 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 = typeof document != "undefined" ?
// .. by the browser
(function(el) {
el.style.position = 'absolute';
el.style.top = '-1000px';
el.style.padding = '0';
document.body.appendChild(el)
return function(str) {
var c,
font = gene.curfont,
h = font.size,
w = 0,
n = str.length,
i0 = 0,
i = 0
el.style.font = style_font(font).slice(5);
while (1) {
i = str.indexOf('$', i)
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);
w += el.clientWidth
if (font.size > h)
h = font.size;
el.style.font = style_font(font).slice(5);
i += 2;
i0 = i
}
el.innerHTML = str.slice(i0);
w += el.clientWidth;
gene.curfont = font
return [w, h]
}
})(document.createElement('div')) :
// .. by internal tables
function(str) {
var font = gene.curfont,
swfac = font.swfac,
h = font.size,
w = 0,
i, j, c,
n = str.length
|
| ︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
return [w, h]
}
// set the default and current font
function set_font(xxx) {
if (typeof xxx == "string")
xxx = get_font(xxx);
gene.curfont = gene.deffont = xxx
}
// output a string handling the font changes
function out_str(str) {
var n_font,
o_font = gene.curfont,
c_font = o_font;
| > | < < < < < < < < < < < < | | > | > | | | > > > > > | > | > | | < < | | | | < < | | | | | < > | 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 |
return [w, h]
}
// set the default and current font
function set_font(xxx) {
if (typeof xxx == "string")
xxx = get_font(xxx);
cw_tb = xxx.name.slice(0, 4) == 'sans' ? ssw_tb : sw_tb;
gene.curfont = gene.deffont = xxx
}
// output a string handling the font changes
function out_str(str) {
var n_font,
o_font = gene.curfont,
c_font = o_font;
output += str.replace(/\$./g, function(c) {
if (c[1] == '0') {
n_font = gene.deffont;
use_font(n_font)
} else if (c[1] >= '1' && c[1] <= '9')
n_font = get_font("u" + c[1])
else
return c
c = ''
if (n_font == c_font)
return c
if (c_font != o_font)
c = "</tspan>";
c_font = n_font
if (c_font == o_font)
return c
return c + '<tspan\n\tclass="' +
font_class(n_font) + '">'
})
if (c_font != o_font) {
output += "</tspan>";
gene.curfont = c_font // keep current font for next paragraph
}
}
// output a string, handling the font changes
// the action is:
// 'c' align center
// 'r' align right
// 'j' justify - w is the line width
// otherwise align left
function xy_str(x, y, str,
action, // default: align left
w, // needed for justify
wh) { // optional [width, height]
if (!wh)
wh = strwh(str);
output += '<text class="' + font_class(gene.curfont)
if (action != 'j' && str.length > 5
&& gene.curfont.wadj)
output += '" lengthAdjust="' + gene.curfont.wadj +
'" textLength="' + wh[0].toFixed(1);
output += '" x="';
out_sxsy(x, '" y="', y + wh[1] * .2) // a bit upper for the descent
switch (action) {
case 'c':
x -= wh[0] / 2;
output += '" text-anchor="middle">'
break
case 'j':
output += '" textLength="' + w.toFixed(1) + '">'
break
case 'r':
x -= wh[0];
output += '" text-anchor="end">'
break
default:
output += '">'
break
}
out_str(str);
output += "</text>\n"
if (!w && gene.curfont.box) {
// not in the SVG documentation,
// but this works for almost all browsers but firefox
// output += '<g style="outline: solid black;\
// outline-width: 1px">\n';
// // xy_str(x, y, str, action, w);
// output += '</g>\n'
output += '<rect class="stroke" x="';
out_sxsy(x - 2, '" y="', y + wh[1]);
output += '" width="' + (wh[0] + 4).toFixed(1) +
'" height="' + (wh[1] + 2).toFixed(1) +
'"/>\n'
}
}
/* -- move trailing "The" to front, set to uppercase letters or add xref -- */
function trim_title(title, is_subtitle) {
var i
if (cfmt.titletrim) {
|
| ︙ | ︙ | |||
223 224 225 226 227 228 229 |
return (img.width - img.lm - img.rm
- 2) // for bar thickness at eol
/ cfmt.scale
}
// header generation functions
function write_title(title, is_subtitle) {
| | | > | | < < < < < > | > | > > | > | > > | > > > | > > | > > | > > | | 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 427 428 429 430 431 432 433 434 435 436 437 |
return (img.width - img.lm - img.rm
- 2) // for bar thickness at eol
/ cfmt.scale
}
// header generation functions
function write_title(title, is_subtitle) {
var h, wh
if (!title)
return
set_page();
title = trim_title(title, is_subtitle)
if (is_subtitle) {
set_font("subtitle");
h = cfmt.subtitlespace
} else {
set_font("title");
h = cfmt.titlespace
}
wh = strwh(title);
vskip(wh[1] + h)
if (cfmt.titleleft)
xy_str(0, 0, title, null, null, wh)
else
xy_str(get_lwidth() / 2, 0, title, "c", null, wh)
}
/* -- output a header format '111 (222)' -- */
function put_inf2r(x, y, str1, str2, action) {
if (!str1) {
if (!str2)
return
str1 = str2;
str2 = null
}
if (!str2)
xy_str(x, y, str1, action)
else
xy_str(x, y, str1 + ' (' + str2 + ')', action)
}
/* -- write a text block (%%begintext / %%text / %%center) -- */
function write_text(text, action) {
if (action == 's')
return // skip
set_font("text");
set_page();
var wh, font,
strlw = get_lwidth(),
sz = gene.curfont.size,
lineskip = sz * cfmt.lineskipfac,
parskip = sz * cfmt.parskipfac,
p_start = block.started ? function(){} : blk_out,
p_flush = block.started ? svg_flush : blk_flush,
i, j, x, words, w, k, ww, str;
p_start()
switch (action) {
default:
// case 'c':
// case 'r':
switch (action) {
case 'c': x = strlw / 2; break
case 'r': x = strlw; break
default: x = 0; break
}
j = 0
font = gene.curfont
while (1) {
i = text.indexOf('\n', j)
if (i < 0) {
str = text.slice(j);
wh = strwh(str);
gene.curfont = font;
vskip(wh[1] * cfmt.lineskipfac);
xy_str(x, 0, str, action, null, wh);
font = gene.curfont
break
}
if (i == j) { // new paragraph
vskip(parskip);
p_flush();
use_font(gene.curfont)
while (text[i + 1] == '\n') {
vskip(lineskip);
i++
}
if (i == text.length)
break
p_start()
} else {
str = text.slice(j, i);
wh = strwh(str);
gene.curfont = font;
vskip(wh[1] * cfmt.lineskipfac);
xy_str(x, 0, str, action, null, wh);
font = gene.curfont
}
j = i + 1
}
vskip(parskip);
p_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 = 0
font = gene.curfont
for (j = 0; j < words.length; j++) {
ww = strwh(words[j] + ' ')[0];
w += ww
if (w >= strlw) {
str = words.slice(k, j).join(' ');
gene.curfont = font;
wh = strwh(str);
gene.curfont = font;
vskip(wh[1] * cfmt.lineskipfac);
xy_str(0, 0, str, action, strlw, wh);
font = gene.curfont;
k = j;
w = ww
}
}
if (w != 0) {
str = words.slice(k).join(' ');
gene.curfont = font;
wh = strwh(str);
gene.curfont = font;
vskip(wh[1] * cfmt.lineskipfac);
xy_str(0, 0, str, null, null, wh)
}
vskip(parskip);
p_flush()
if (i < 0)
break
while (text[i + 2] == '\n') {
vskip(lineskip);
|
| ︙ | ︙ | |||
393 394 395 396 397 398 399 | if (k != 0) xy_str(x, 0, p.slice(j, k), 'r') if (i < p.length) xy_str(x + 5, 0, p.slice(i), 'l') return i >= p.length && k == 0 } // put_wline() | < | | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
if (k != 0)
xy_str(x, 0, p.slice(j, k), 'r')
if (i < p.length)
xy_str(x + 5, 0, p.slice(i), 'l')
return i >= p.length && k == 0
} // put_wline()
set_font("words")
/* see if we may have 2 columns */
var middle = get_lwidth() / 2,
max2col = (middle - 45.) / cwidf('a');
n = 0;
words = words.split('\n');
nw = words.length
for (i = 0; i < nw; i++) {
p = words[i]
/*fixme:utf8*/
if (p.length > max2col) {
|
| ︙ | ︙ | |||
471 472 473 474 475 476 477 |
i2++
}
}
}
/* -- output history -- */
function put_history() {
| | > | | | 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 |
i2++
}
}
}
/* -- output history -- */
function put_history() {
var i, j, c, str, font, h, w, wh, head,
names = cfmt.infoname.split("\n"),
n = names.length
for (i = 0; i < n; i++) {
c = names[i][0]
if (cfmt.writefields.indexOf(c) < 0)
continue
str = info[c]
if (!str)
continue
if (!font) {
font = true;
set_font("history");
vskip(cfmt.textspace);
h = gene.curfont.size * cfmt.lineskipfac
}
head = names[i].slice(2)
if (head[0] == '"')
head = head.slice(1, -1);
vskip(h);
wh = strwh(head);
xy_str(0, 0, head, null, null, wh);
w = wh[0];
str = str.split('\n');
xy_str(w, 0, str[0])
for (j = 1; j < str.length; j++) {
vskip(h);
xy_str(w, 0, str[j])
}
vskip(h * .3);
|
| ︙ | ︙ | |||
662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
if (info_sz[c])
sz += info_sz[c];
set_font(font);
x = xa[align];
y = ya[align] + sz
if (c == 'Q') { /* special case for tempo */
if (!glovar.tempo.del) {
if (align != 'l') {
var w = tempo_width(glovar.tempo)
if (align == 'c')
w *= .5;
x -= w
| > | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
if (info_sz[c])
sz += info_sz[c];
set_font(font);
x = xa[align];
y = ya[align] + sz
if (c == 'Q') { /* special case for tempo */
set_width(glovar.tempo)
if (!glovar.tempo.del) {
if (align != 'l') {
var w = tempo_width(glovar.tempo)
if (align == 'c')
w *= .5;
x -= w
|
| ︙ | ︙ | |||
738 739 740 741 742 743 744 | } write_title(info.T.slice(i, j), i != 0); i = j + 1 } } /* rhythm, composer, origin */ | < > > | 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 |
}
write_title(info.T.slice(i, j), i != 0);
i = j + 1
}
}
/* rhythm, composer, origin */
// down1 = cfmt.composerspace + gene.curfont.size
down1 = down2 = 0
if (parse.ckey.k_bagpipe
&& !cfmt.infoline
&& cfmt.writefields.indexOf('R') >= 0)
rhythm = info.R
if (rhythm) {
set_font("composer");
xy_str(0, -cfmt.composerspace, rhythm);
down1 = cfmt.composerspace
}
area = info.A
if (cfmt.writefields.indexOf('C') >= 0)
composer = info.C
if (cfmt.writefields.indexOf('O') >= 0)
origin = info.O
if (composer || origin || cfmt.infoline) {
var xcomp, align;
set_font("composer");
vskip(cfmt.composerspace)
if (cfmt.aligncomposer < 0) {
xcomp = 0;
align = ' '
} else if (cfmt.aligncomposer == 0) {
xcomp = lwidth * .5;
align = 'c'
|
| ︙ | ︙ |
Changes to core/svg.js.
1 2 | // abc2svg - svg.js - svg functions // | | | | | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
// abc2svg - svg.js - svg functions
//
// Copyright (C) 2014-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
var output = "", // output buffer
style = '\n.fill{fill:currentColor}\
\n.stroke{stroke:currentColor;fill:none}\
\n.bW{stroke-width:1}\
\n.bthW{stroke-width:3}\
\n.slW{stroke-width:.7}\
\n.slthW{stroke-width:1.5}\
\n.sW{stroke-width:.7}',
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
|
| ︙ | ︙ | |||
41 42 43 44 45 46 47 48 |
g: 0
// color: undefined
},
block = {} /* started & newpage */
// glyphs in music font
var tgls = {
brace: {x:0, y:0, c:"\ue000"},
| > > > > > > > > > > > | | > > | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > | | | | | > | > > > > > | | > > > > > > > > > > > > | | | | > > > > > > > > > > > > > > > > > | > > > | < | | | | | | < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < | < < < < < < < < < < < < < < | < < < > | 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 |
g: 0
// color: undefined
},
block = {} /* started & newpage */
// glyphs in music font
var tgls = {
"mtr ": {x:0, y:0, c:"\u0020"}, // space
brace: {x:0, y:0, c:"\ue000"},
hl: {x:-4, y:0, c:"\ue022"},
hl1: {x:-6, y:0, c:"\ue023"},
// hl2: {x:-6, y:0, c:"\ue023"}, // (unused)
ghl: {x:-4, y:0, c:"\ue024"},
lphr: {x:0, y:24, c:"\ue030"},
mphr: {x:0, y:24, c:"\ue038"},
sphr: {x:0, y:27, c:"\ue039"},
rdots: {x:-1, y:0, c:"\ue043"}, // repeat dots
dsgn: {x:-4, y:-4, c:"\ue045"}, // D.S.
dcap: {x:-4, y:-4, c:"\ue046"}, // D.C.
sgno: {x:-6, y:0, c:"\ue047"}, // segno
coda: {x:-12, y:-6, c:"\ue048"},
tclef: {x:-8, y:0, c:"\ue050"},
cclef: {x:-8, y:0, c:"\ue05c"},
bclef: {x:-8, y:0, c:"\ue062"},
pclef: {x:-6, y:0, c:"\ue069"},
spclef: {x:-6, y:0, c:"\ue069"},
stclef: {x:-8, y:0, c:"\ue07a"},
scclef: {x:-8, y:0, c:"\ue07b"},
sbclef: {x:-7, y:0, c:"\ue07c"},
oct: {x:0, y:2, c:"\ue07d"}, // 8 for clefs
mtr0: {x:0, y:0, c:"\ue080"}, // meters
mtr1: {x:0, y:0, c:"\ue081"},
mtr2: {x:0, y:0, c:"\ue082"},
mtr3: {x:0, y:0, c:"\ue083"},
mtr4: {x:0, y:0, c:"\ue084"},
mtr5: {x:0, y:0, c:"\ue085"},
mtr6: {x:0, y:0, c:"\ue086"},
mtr7: {x:0, y:0, c:"\ue087"},
mtr8: {x:0, y:0, c:"\ue088"},
mtr9: {x:0, y:0, c:"\ue089"},
mtrC: {x:0, y:0, c:"\ue08a"}, // common time (4/4)
// "mtrC|": {x:0, y:0, c:"\ue08b"}, // cut time (2/2) (unused)
"mtr+": {x:0, y:0, c:"\ue08c"},
"mtr(": {x:0, y:0, c:"\ue094"},
"mtr)": {x:0, y:0, c:"\ue095"},
HDD: {x:-7, y:0, c:"\ue0a0"},
breve: {x:-7, y:0, c:"\ue0a1"},
HD: {x:-5.2, y:0, c:"\ue0a2"},
Hd: {x:-3.8, y:0, c:"\ue0a3"},
hd: {x:-3.7, y:0, c:"\ue0a4"},
ghd: {x:2, y:0, c:"\ue0a4", sc:.66}, // grace note head
pshhd: {x:-3.7, y:0, c:"\ue0a9"},
pfthd: {x:-3.7, y:0, c:"\ue0b3"},
x: {x:-3.7, y:0, c:"\ue0a9"}, // 'x' note head
"circle-x": {x:-3.7, y:0, c:"\ue0b3"}, // 'circle-x' note head
srep: {x:-5, y:0, c:"\ue101"},
diamond: {x:-4, y:0, c:"\ue1b9"},
triangle: {x:-4, y:0, c:"\ue1bb"},
dot: {x:-2, y:0, c:"\ue1e7"},
flu1: {x:-.3, y:0, c:"\ue240"}, // flags
fld1: {x:-.3, y:0, c:"\ue241"},
flu2: {x:-.3, y:0, c:"\ue242"},
fld2: {x:-.3, y:0, c:"\ue243"},
flu3: {x:-.3, y:3.5, c:"\ue244"},
fld3: {x:-.3, y:-4, c:"\ue245"},
flu4: {x:-.3, y:8, c:"\ue246"},
fld4: {x:-.3, y:-9, c:"\ue247"},
flu5: {x:-.3, y:12.5, c:"\ue248"},
fld5: {x:-.3, y:-14, c:"\ue249"},
"acc-1": {x:-1, y:0, c:"\ue260"}, // flat
acc3: {x:-1, y:0, c:"\ue261"}, // natural
acc1: {x:-2, y:0, c:"\ue262"}, // sharp
acc2: {x:-3, y:0, c:"\ue263"}, // double sharp
"acc-2": {x:-3, y:0, c:"\ue264"}, // double flat
"acc-1_1_4": {x:-2, y:0, c:"\ue280"}, // quarter-tone flat
"acc-1_3_4": {x:-3, y:0, c:"\ue281"}, // three-quarter-tones flat
acc1_1_4: {x:-1, y:0, c:"\ue282"}, // quarter-tone sharp
acc1_3_4: {x:-3, y:0, c:"\ue283"}, // three-quarter-tones sharp
accent: {x:-3, y:0, c:"\ue4a0"},
stc: {x:-1, y:-2, c:"\ue4a2"}, // staccato
emb: {x:-4, y:-2, c:"\ue4a4"},
wedge: {x:-1, y:0, c:"\ue4a8"},
marcato: {x:-3, y:0, c:"\ue4ac"},
hld: {x:-7, y:0, c:"\ue4c0"}, // fermata
brth: {x:0, y:0, c:"\ue4ce"},
r00: {x:-1.5, y:0, c:"\ue4e1"},
r0: {x:-1.5, y:0, c:"\ue4e2"},
r1: {x:-3.5, y:-6, c:"\ue4e3"},
r2: {x:-3.2, y:0, c:"\ue4e4"},
r4: {x:-3, y:0, c:"\ue4e5"},
r8: {x:-3, y:0, c:"\ue4e6"},
r16: {x:-4, y:0, c:"\ue4e7"},
r32: {x:-4, y:0, c:"\ue4e8"},
r64: {x:-4, y:0, c:"\ue4e9"},
r128: {x:-4, y:0, c:"\ue4ea"},
mrest: {x:-10, y:0, c:"\ue4ee"},
mrep: {x:-6, y:0, c:"\ue500"},
mrep2: {x:-9, y:0, c:"\ue501"},
p: {x:-4, y:-6, c:"\ue520"},
f: {x:-4, y:-6, c:"\ue522"},
pppp: {x:-4, y:-6, c:"\ue529"},
ppp: {x:-4, y:-6, c:"\ue52a"},
pp: {x:-4, y:-6, c:"\ue52b"},
mp: {x:-4, y:-6, c:"\ue52c"},
mf: {x:-4, y:-6, c:"\ue52d"},
ff: {x:-4, y:-6, c:"\ue52f"},
fff: {x:-4, y:-6, c:"\ue530"},
ffff: {x:-4, y:-6, c:"\ue531"},
sfz: {x:-4, y:-6, c:"\ue539"},
trl: {x:-4, y:-4, c:"\ue566"}, // trill
turn: {x:-5, y:-4, c:"\ue567"},
turnx: {x:-5, y:-4, c:"\ue569"},
umrd: {x:-7, y:-2, c:"\ue56c"},
lmrd: {x:-7, y:-2, c:"\ue56d"},
dplus: {x:-4, y:10, c:"\ue582"}, // plus
sld: {x:-8, y:12, c:"\ue5d4"}, // slide
grm: {x:-2, y:0, c:"\ue5e2"}, // grace mark
dnb: {x:-4, y:0, c:"\ue610"}, // down bow
upb: {x:-3, y:0, c:"\ue612"}, // up bow
opend: {x:-2, y:0, c:"\ue614"}, // harmonic
roll: {x:0, y:0, c:"\ue618"},
thumb: {x:0, y:0, c:"\ue624"},
snap: {x:-2, y:0, c:"\ue630"},
ped: {x:-10, y:0, c:"\ue650"},
pedoff: {x:-5, y:0, c:"\ue655"},
// "mtro.": {x:0, y:0, c:"\ue910"}, // (unused)
mtro: {x:0, y:0, c:"\ue911"}, // tempus perfectum
// "mtro|": {x:0, y:0, c:"\ue912"}, // (unused)
// "mtrc.": {x:0, y:0, c:"\ue914"}, // (unused)
mtrc: {x:0, y:0, c:"\ue915"}, // tempus imperfectum
// "mtrc|": {x:0, y:0, c:"\ue918"}, // (unused)
"mtr.": {x:0, y:0, c:"\ue920"}, // prolatione perfecta
"mtr|": {x:0, y:0, c:"\ue925"}, // (twice as fast)
longa: {x:-3.7, y:0, c:"\ue95d"},
custos: {x:-4, y:3, c:"\uea02"},
ltr: {x:2, y:6, c:"\ueaa4"} // long trill element
}
// glyphs to put in <defs>
var glyphs = {
}
// convert a meter string to a SmuFL encoded string
function m_gl(s) {
return s.replace(/[Cco]\||[co]\.|./g,
function(e) {
var m = tgls["mtr" + e]
if (!m.x && !m.y)
return m.c
return '<tspan dx="'+ m.x.toFixed(1) +
'" dy="' + m.y.toFixed(1) + '">' +
m.c + '</tspan>'
})
}
// mark a glyph as used and add it in <defs>
function def_use(gl) {
var i, j, g
if (defined_glyph[gl])
|
| ︙ | ︙ | |||
299 300 301 302 303 304 305 |
output += ">\n";
stv_g.started = true
}
/* set the color */
function set_color(color) {
if (color == stv_g.color)
| | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
output += ">\n";
stv_g.started = true
}
/* set the color */
function set_color(color) {
if (color == stv_g.color)
return undefined // same color
var old_color = stv_g.color;
stv_g.color = color;
set_g()
return old_color
}
/* -- set the staff scale (only) -- */
|
| ︙ | ︙ | |||
370 371 372 373 374 375 376 |
// update the y offsets of delayed output
function delayed_update() {
var st, new_out, text
for (st = 0; st <= nstaff; st++) {
if (staff_tb[st].sc_out) {
output += '<g transform="translate(0,' +
| | | | 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 |
// update the y offsets of delayed output
function delayed_update() {
var st, new_out, text
for (st = 0; st <= nstaff; st++) {
if (staff_tb[st].sc_out) {
output += '<g transform="translate(0,' +
(posy - staff_tb[st].y).toFixed(1) +
') scale(' +
staff_tb[st].staffscale.toFixed(2) +
')">\n' +
staff_tb[st].sc_out +
'</g>\n';
staff_tb[st].sc_out = ""
}
if (!staff_tb[st].output)
continue
output += '<g transform="translate(0,' +
(-staff_tb[st].y).toFixed(1) +
')">\n' +
staff_tb[st].output +
'</g>\n';
staff_tb[st].output = ""
}
}
|
| ︙ | ︙ | |||
405 406 407 408 409 410 411 | return var type = s.type, h = s.ymx - s.ymn + 4, wl = s.wl || 2, wr = s.wr || 2 if (s.grace) | | | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
return
var type = s.type,
h = s.ymx - s.ymn + 4,
wl = s.wl || 2,
wr = s.wr || 2
if (s.grace)
type = C.GRACE
f(t || anno_type[type], s.istart, s.iend,
s.x - wl - 2, staff_tb[s.st].y + s.ymn + h - 2,
wl + wr + 4, h, s);
}
function a_start(s, t) {
|
| ︙ | ︙ | |||
433 434 435 436 437 438 439 |
// A and B are replaced by a and b as string
// F and G are replaced by a and b as float
function out_XYAB(str, x, y, a, b) {
x = sx(x);
y = sy(y);
output += str.replace(/X|Y|A|B|F|G/g, function(c) {
switch (c) {
| | | | | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
// A and B are replaced by a and b as string
// F and G are replaced by a and b as float
function out_XYAB(str, x, y, a, b) {
x = sx(x);
y = sy(y);
output += str.replace(/X|Y|A|B|F|G/g, function(c) {
switch (c) {
case 'X': return x.toFixed(1)
case 'Y': return y.toFixed(1)
case 'A': return a
case 'B': return b
case 'F': return a.toFixed(1)
// case 'G':
default: return b.toFixed(1)
}
})
}
// open / close containers
function g_open(x, y, rot, sx, sy) {
out_XYAB('<g transform="translate(X,Y', x, y);
|
| ︙ | ︙ | |||
476 477 478 479 480 481 482 |
if (stv_g.g)
return x
return (x + posx) / stv_g.scale
}
Abc.prototype.sx = sx
function sy(y) {
if (stv_g.g)
| | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
if (stv_g.g)
return x
return (x + posx) / stv_g.scale
}
Abc.prototype.sx = sx
function sy(y) {
if (stv_g.g)
return -y
if (stv_g.scale == 1)
return posy - y
if (stv_g.st < 0)
return (posy - y) / stv_g.scale // voice scale
return stv_g.dy - y // staff scale
}
Abc.prototype.sy = sy;
|
| ︙ | ︙ | |||
505 506 507 508 509 510 511 |
return h
return h * stv_g.scale
}
// output scaled (x + <sep> + y)
function out_sxsy(x, sep, y) {
x = sx(x);
y = sy(y);
| | | | | 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 |
return h
return h * stv_g.scale
}
// output scaled (x + <sep> + y)
function out_sxsy(x, sep, y) {
x = sx(x);
y = sy(y);
output += x.toFixed(1) + sep + y.toFixed(1)
}
Abc.prototype.out_sxsy = out_sxsy
// define the start of a path
function xypath(x, y, fill) {
out_XYAB('<path class="A" d="mX Y\n', x, y, fill ? "fill" : "stroke")
}
Abc.prototype.xypath = xypath
// output a glyph
function xygl(x, y, gl) {
// (avoid ps<->js loop)
// if (psxygl(x, y, gl))
// return
var tgl = tgls[gl]
if (tgl && !glyphs[gl]) {
x += tgl.x * stv_g.scale;
y -= tgl.y
if (tgl.sc)
out_XYAB('<text transform="translate(X,Y) scale(A)">B</text>\n',
x, y, tgl.sc, tgl.c);
else
out_XYAB('<text x="X" y="Y">A</text>\n', x, y, tgl.c)
return
}
if (!glyphs[gl]) {
error(1, null, 'no definition of $1', gl)
|
| ︙ | ︙ | |||
551 552 553 554 555 556 557 |
} else {
x -= 5;
y -= 4
}
out_XYAB('<path class="stroke" d="mX YlF G"/>\n',
x, y, dx, -dy)
}
| < < < < < < < < | | | | | 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 |
} else {
x -= 5;
y -= 4
}
out_XYAB('<path class="stroke" d="mX YlF G"/>\n',
x, y, dx, -dy)
}
// tuplet value - the staves are not defined
function out_bnum(x, y, str) {
out_XYAB('<text style="font:italic 12px serif"\n\
x="X" y="Y" text-anchor="middle">A</text>\n',
x, y, str.toString())
}
// staff system brace
function out_brace(x, y, h) {
//fixme: '-6' depends on the scale
x += posx - 6;
y = posy - y;
h /= 24;
output += '<text transform="translate(' +
x.toFixed(1) + ',' + y.toFixed(1) +
') scale(2.5,' + h.toFixed(2) +
')">' + tgls.brace.c + '</text>\n'
}
// staff system bracket
function out_bracket(x, y, h) {
x += posx - 5;
y = posy - y - 3;
h += 2;
output += '<path class="fill"\n\
d="m' + x.toFixed(1) + ' ' + y.toFixed(1) + '\n\
c10.5 1 12 -4.5 12 -3.5c0 1 -3.5 5.5 -8.5 5.5\n\
v' + h.toFixed(1) + '\n\
c5 0 8.5 4.5 8.5 5.5c0 1 -1.5 -4.5 -12 -3.5"/>\n'
}
// hyphen
function out_hyph(x, y, w) {
var n, a_y,
d = 25 + ((w / 20) | 0) * 3
|
| ︙ | ︙ | |||
617 618 619 620 621 622 623 | slen = -h if (h < 0) dx = -dx; // down x += dx * stv_g.scale if (stv_g.st < 0) slen /= stv_g.scale; | | < < | < < | < < < < < < > > > | < < | < < < < < < > > < < < < < < < < | | | | | | | | | | | | | | 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 646 647 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 |
slen = -h
if (h < 0)
dx = -dx; // down
x += dx * stv_g.scale
if (stv_g.st < 0)
slen /= stv_g.scale;
out_XYAB('<path class="stroke sW" d="mX YvF"/>\n', // stem
x, y, slen)
if (!nflags)
return
y += h
if (h > 0) { // up
if (!straight) {
if (!grace) {
xygl(x, y, "flu" + nflags)
return
} else { // grace
output += '<path class="fill" d="'
if (nflags == 1) {
out_XYAB('MX Yc0.6 3.4 5.6 3.8 3 10\n\
1.2 -4.4 -1.4 -7 -3 -7\n', x, y)
} else {
while (--nflags >= 0) {
out_XYAB('MX Yc1 3.2 5.6 2.8 3.2 8\n\
1.4 -4.8 -2.4 -5.4 -3.2 -5.2\n', x, y);
y -= 3.5
}
}
}
} else { // straight
output += '<path class="fill" d="'
//fixme: to do
if (!grace) {
//fixme: check endpoints
y += 1
while (--nflags >= 0) {
out_XYAB('MX Yl7 3.2 0 3.2 -7 -3.2z\n',
x, y);
y -= 5.4
}
} else { // grace
while (--nflags >= 0) {
out_XYAB('MX Yl3 1.5 0 2 -3 -1.5z\n',
x, y);
y -= 3
}
}
}
} else { // down
if (!straight) {
if (!grace) {
xygl(x, y, "fld" + nflags)
return
} else { // grace
output += '<path class="fill" d="'
if (nflags == 1) {
out_XYAB('MX Yc0.6 -3.4 5.6 -3.8 3 -10\n\
1.2 4.4 -1.4 7 -3 7\n', x, y)
} else {
while (--nflags >= 0) {
out_XYAB('MX Yc1 -3.2 5.6 -2.8 3.2 -8\n\
1.4 4.8 -2.4 5.4 -3.2 5.2\n', x, y);
y += 3.5
}
}
}
} else { // straight
output += '<path class="fill" d="'
if (!grace) {
//fixme: check endpoints
y += 1
while (--nflags >= 0) {
out_XYAB('MX Yl7 -3.2 0 -3.2 -7 3.2z\n',
x, y);
y += 5.4
}
// } else { // grace
//--fixme: error?
}
}
}
output += '"/>\n'
}
// tremolo
function out_trem(x, y, ntrem) {
out_XYAB('<path class="fill" d="mX Y\n\t', x - 4.5, y)
while (1) {
output += 'l9 -3v3l-9 3z'
if (--ntrem <= 0)
break
output += 'm0 5.4'
}
output += '"/>\n'
}
// tuplet bracket - the staves are not defined
function out_tubr(x, y, dx, dy, up) {
var h = up ? -3 : 3;
y += h;
dx /= stv_g.scale;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
output += 'v' + h.toFixed(1) +
'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) +
'v' + (-h).toFixed() + '"/>\n'
}
// tuplet bracket with number - the staves are not defined
function out_tubrn(x, y, dx, dy, up, str) {
var sw = str.length * 10,
h = up ? -3 : 3;
out_XYAB('<text style="font:italic 12px serif"\n\
x="X" y="Y" text-anchor="middle">A</text>\n',
x + dx / 2, y + dy / 2, str);
dx /= stv_g.scale
if (!up)
y += 6;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
output += 'v' + h.toFixed(1) +
'm' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) +
'v' + (-h).toFixed(1) + '"/>\n' +
'<path class="stroke" stroke-dasharray="' +
((dx - sw) / 2).toFixed(1) + ' ' + sw.toFixed(1) +
'" d="m';
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)
}
// decorations with string
var deco_str_style = {
crdc: {
dx: 0,
dy: 5,
style: 'font:italic 14px serif'
},
dacs: {
dx: 0,
dy: 3,
style: 'font:16px serif',
anchor: ' text-anchor="middle"'
},
fng: {
dx: 0,
dy: 1,
style: 'font-family:Bookman; font-size:8px',
anchor: ' text-anchor="middle"'
},
pf: {
dx: 0,
dy: 5,
style: 'font:italic bold 16px serif'
},
'@': {
dx: 0,
dy: 5,
style: 'font: 12px sans-serif'
}
}
function out_deco_str(x, y, name, str) {
var a, f,
a_deco = deco_str_style[name]
|
| ︙ | ︙ | |||
823 824 825 826 827 828 829 |
out_str(str);
output += '</text>\n'
}
function out_arp(x, y, val) {
g_open(x, y, 270);
x = 0;
| < | | | | | > > > > > > > | | | | | | | | > | | 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 874 875 876 877 878 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 |
out_str(str);
output += '</text>\n'
}
function out_arp(x, y, val) {
g_open(x, y, 270);
x = 0;
val = Math.ceil(val / 6)
while (--val >= 0) {
xygl(x, 6, "ltr");
x += 6
}
g_close()
}
function out_cresc(x, y, val, defl) {
x += val;
val = -val;
out_XYAB('<path class="stroke"\n\
d="mX YlA ', x, y + 5, val)
if (defl.nost)
output += '-2.2m0 -3.6l' + (-val).toFixed(1) + ' -2.2"/>\n'
else
output += '-4l' + (-val).toFixed(1) + ' -4"/>\n'
}
function out_dim(x, y, val, defl) {
out_XYAB('<path class="stroke"\n\
d="mX YlA ', x, y + 5, val)
if (defl.noen)
output += '-2.2m0 -3.6l' + (-val).toFixed(1) + ' -2.2"/>\n'
else
output += '-4l' + (-val).toFixed(1) + ' -4"/>\n'
}
function out_ltr(x, y, val) {
y += 4;
val = Math.ceil(val / 6)
while (--val >= 0) {
xygl(x, y, "ltr");
x += 6
}
}
function out_lped(x, y, val, defl) {
y += 4;
if (!defl.nost)
xygl(x, y, "ped");
if (!defl.noen)
xygl(x + val, y, "pedoff")
}
function out_8va(x, y, val, defl) {
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px serif">8\
<tspan dy="-4" style="font-size:10px">va</tspan></text>\n',
x - 8, y);
x += 12;
val -= 12
} else {
val -= 5
}
y += 6;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv6"/>\n', x + val, y)
}
function out_8vb(x, y, val, defl) {
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px serif">8\
<tspan dy="-4" style="font-size:10px">vb</tspan></text>\n',
x - 8, y);
x += 4;
val -= 4
} else {
val -= 5
}
// y -= 2;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv-6"/>\n', x + val, y)
}
function out_15ma(x, y, val, defl) {
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px serif">15\
<tspan dy="-4" style="font-size:10px">ma</tspan></text>\n',
x - 10, y);
x += 20;
val -= 20
} else {
val -= 5
}
y += 6;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv6"/>\n', x + val, y)
}
function out_15mb(x, y, val, defl) {
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px serif">15\
<tspan dy="-4" style="font-size:10px">mb</tspan></text>\n',
x - 10, y);
x += 7;
val -= 7
} else {
val -= 5
}
// y -= 2;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv-6"/>\n', x + val, y)
}
var deco_val_tb = {
arp: out_arp,
cresc: out_cresc,
dim: out_dim,
ltr: out_ltr,
lped: out_lped,
"8va": out_8va,
"8vb": out_8vb,
"15ma": out_15ma,
"15mb": out_15mb
}
function out_deco_val(x, y, name, val, defl) {
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 de1 = de.start,
x1 = de1.x,
y1 = de1.y + staff_tb[de1.st].y,
ar = Math.atan2(y1 - y2, x2 - x1),
a = ar / Math.PI * 180,
len = (x2 - x1) / Math.cos(ar);
g_open(x1, y1, a);
x1 = de1.s.dots ? 13 + de1.s.xmx : 8;
len = (len - x1 - 6) / 6 | 0
if (len < 1)
|
| ︙ | ︙ | |||
976 977 978 979 980 981 982 | a = ar / Math.PI * 180, len = (x2 - x1) / Math.cos(ar); g_open(x1, y1, a); x1 = de1.s.dots ? 13 + de1.s.xmx : 8; len -= x1 + 8; xypath(x1, 0); | | | 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
a = ar / Math.PI * 180,
len = (x2 - x1) / Math.cos(ar);
g_open(x1, y1, a);
x1 = de1.s.dots ? 13 + de1.s.xmx : 8;
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
}
|
| ︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 |
}
if (style || font_style || musicfont) {
head += '<style type="text/css">' + style + font_style
if (musicfont) {
if (musicfont.indexOf('(') > 0) {
head += '\n\
| | | | | | 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 |
}
if (style || font_style || musicfont) {
head += '<style type="text/css">' + style + font_style
if (musicfont) {
if (musicfont.indexOf('(') > 0) {
head += '\n\
.music {font:24px music;fill:currentColor}\n\
@font-face {\n\
font-family:"music";\n\
src:' + musicfont + '}';
} else {
head += '\n\
.music {font:24px '+ musicfont +';fill:currentColor}'
}
}
head += '\n</style>\n'
}
defs += fulldefs
if (defs)
head += '<defs>' + defs + '\n</defs>\n'
|
| ︙ | ︙ | |||
1063 1064 1065 1066 1067 1068 1069 |
user.img_out(head + output + g + "</svg>");
output = ""
font_style = ''
if (cfmt.fullsvg) {
defined_glyph = {}
| > | | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
user.img_out(head + output + g + "</svg>");
output = ""
font_style = ''
if (cfmt.fullsvg) {
defined_glyph = {}
for (var i = 0; i < font_tb.length; i++)
font_tb[i].used = false
} else {
musicfont = '';
style = '';
fulldefs = ''
}
defs = '';
posy = 0
|
| ︙ | ︙ |
Changes to core/tail.js.
1 2 | // abc2svg - tail.js // | | > < > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// abc2svg - tail.js
//
// Copyright (C) 2014-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
// PostScript hooks
function psdeco() { return false }
function psxygl() { return false }
// initialize
init_tune()
// Abc functions used by the modules
Abc.prototype.add_style = function(s) { style += s };
Abc.prototype.calculate_beam = calculate_beam;
Abc.prototype.cfmt = function() { return cfmt };
Abc.prototype.clone = clone;
Abc.prototype.deco_cnv = deco_cnv;
Abc.prototype.do_pscom = do_pscom;
Abc.prototype.do_begin_end = do_begin_end;
Abc.prototype.draw_gchord = draw_gchord;
Abc.prototype.draw_note = draw_note;
Abc.prototype.draw_symbols = draw_symbols;
Abc.prototype.errs = errs;
Abc.prototype.font_class = font_class;
Abc.prototype.gch_build = gch_build;
Abc.prototype.gch_tr1 = gch_tr1;
Abc.prototype.get_a_gch = function() { return a_gch };
Abc.prototype.get_bool = get_bool;
Abc.prototype.get_cur_sy = function() { return cur_sy };
Abc.prototype.get_curvoice = function() { return curvoice };
Abc.prototype.get_delta_tb = function() { return delta_tb };
Abc.prototype.get_decos = function() { return decos };
Abc.prototype.get_fname = function() { return parse.fname };
Abc.prototype.get_font = get_font;
Abc.prototype.get_font_style = function() { return font_style };
|
| ︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 |
return true
}
};
Abc.prototype.get_posy = function() { var t = posy; posy = 0; return t };
Abc.prototype.get_staff_tb = function() { return staff_tb };
Abc.prototype.get_top_v = function() { return par_sy.top_voice };
Abc.prototype.get_tsfirst = function() { return tsfirst };
Abc.prototype.get_voice_tb = function() { return voice_tb };
Abc.prototype.info = function() { return info };
Abc.prototype.set_tsfirst = function(s) { tsfirst = s };
| > > > > > > > > > > > > > > > > > > > > > > > | | | < < > > > > > > < | | < < < < < < < < | < | | 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 |
return true
}
};
Abc.prototype.get_posy = function() { var t = posy; posy = 0; return t };
Abc.prototype.get_staff_tb = function() { return staff_tb };
Abc.prototype.get_top_v = function() { return par_sy.top_voice };
Abc.prototype.get_tsfirst = function() { return tsfirst };
Abc.prototype.get_unit = get_unit;
Abc.prototype.get_voice_tb = function() { return voice_tb };
Abc.prototype.goto_tune = goto_tune;
Abc.prototype.info = function() { return info };
Abc.prototype.new_block = new_block;
Abc.prototype.new_note = new_note;
Abc.prototype.out_arp = out_arp;
Abc.prototype.out_deco_str = out_deco_str;
Abc.prototype.out_deco_val = out_deco_val;
Abc.prototype.out_ltr = out_ltr;
Abc.prototype.output_music = output_music;
Abc.prototype.param_set_font = param_set_font;
Abc.prototype.parse = parse;
Abc.prototype.psdeco = psdeco;
Abc.prototype.psxygl = psxygl;
Abc.prototype.set_bar_num = set_bar_num;
Abc.prototype.set_cur_sy = function(sy) { cur_sy = sy };
Abc.prototype.set_dscale = set_dscale;
Abc.prototype.set_font = set_font;
Abc.prototype.set_format = set_format;
Abc.prototype.set_pitch = set_pitch;
Abc.prototype.set_scale = set_scale;
Abc.prototype.set_stem_dir = set_stem_dir;
Abc.prototype.set_stems = set_stems;
Abc.prototype.set_sym_glue = set_sym_glue;
Abc.prototype.set_tsfirst = function(s) { tsfirst = s };
Abc.prototype.set_vp = set_vp;
Abc.prototype.set_v_param = set_v_param;
Abc.prototype.set_width = set_width;
Abc.prototype.sort_pitch = sort_pitch;
Abc.prototype.strwh = strwh;
Abc.prototype.stv_g = function() { return stv_g };
Abc.prototype.svg_flush = svg_flush;
Abc.prototype.syntax = syntax;
Abc.prototype.unlksym = unlksym;
Abc.prototype.use_font = use_font;
Abc.prototype.xy_str = xy_str;
Abc.prototype.xygl = xygl;
var hook_init // set after setting the first module hooks
// export functions and/or set module hooks
function set_hooks() {
var h = abc2svg.modules.hooks,
gh = abc2svg.modules.g_hooks
function set_hs(hs) {
for (var k = 0; k < hs.length; k++)
hs[k](self)
} // set_hs()
if (hook_init) { // if new modules
if (h.length) {
set_hs(h);
gh.push.apply(gh, h);
abc2svg.modules.hooks = []
}
} else { // all modules
if (h.length) {
gh.push.apply(gh, h);
abc2svg.modules.hooks = []
}
set_hs(gh);
hook_init = true
}
} // set_hooks()
} // end of Abc()
} // end of abc2svg
// compatibility
var Abc = abc2svg.Abc
// nodejs
if (typeof module == 'object' && typeof exports == 'object') {
exports.abc2svg = abc2svg;
exports.Abc = Abc
}
|
Changes to core/tune.js.
1 2 | // abc2svg - tune.js - tune generation // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - tune.js - tune generation // // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
33 34 35 36 37 38 39 |
if (!parse.voice_opts.hasOwnProperty(opt))
continue
sel = new RegExp(opt)
if (sel.test(curvoice.id)
|| sel.test(curvoice.nm)) {
for (i in parse.voice_opts[opt])
if (parse.voice_opts[opt].hasOwnProperty(i))
| | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
if (!parse.voice_opts.hasOwnProperty(opt))
continue
sel = new RegExp(opt)
if (sel.test(curvoice.id)
|| sel.test(curvoice.nm)) {
for (i in parse.voice_opts[opt])
if (parse.voice_opts[opt].hasOwnProperty(i))
self.do_pscom(parse.voice_opts[opt][i])
}
}
}
/* -- link a ABC symbol into the current voice -- */
function sym_link(s) {
if (!s.fname)
|
| ︙ | ︙ | |||
95 96 97 98 99 100 101 |
function mrest_expand(s) {
var p_voice, s2, next,
nb = s.nmes,
dur = s.dur / nb
/* change the multi-rest (type bar) to a single rest */
var a_dd = s.a_dd;
| | | < < | | | < < | 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 |
function mrest_expand(s) {
var p_voice, s2, next,
nb = s.nmes,
dur = s.dur / nb
/* change the multi-rest (type bar) to a single rest */
var a_dd = s.a_dd;
s.type = C.REST;
s.dur = s.dur_orig = dur;
/* add the bar(s) and rest(s) */
next = s.next;
p_voice = s.p_v;
p_voice.last_sym = s;
p_voice.time = s.time + dur;
p_voice.cst = s.st;
s2 = s
while (--nb > 0) {
s2 = sym_add(p_voice, C.BAR);
s2.bar_type = "|";
s2 = sym_add(p_voice, C.REST);
if (s.invis)
s2.invis = true;
s2.dur = s2.dur_orig = dur;
p_voice.time += dur
}
s2.next = next
if (next)
next.prev = s2;
/* copy the mrest decorations to the last rest */
|
| ︙ | ︙ | |||
201 202 203 204 205 206 207 |
w = w_tb[s.type]
if (s.time < time) {
time = s.time;
wmin = w
} else if (w < wmin) {
wmin = w
}
| | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
w = w_tb[s.type]
if (s.time < time) {
time = s.time;
wmin = w
} else if (w < wmin) {
wmin = w
}
if (s.type == C.MREST) {
if (s.nmes == 1)
mrest_expand(s)
else if (multi > 0)
mrest_time = time
}
}
|
| ︙ | ︙ | |||
223 224 225 226 227 228 229 | v = vn[ir] if (v == undefined) break s = vtb[v] if (!s || s.time != time || w_tb[s.type] != wmin) continue | | | | | 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 |
v = vn[ir]
if (v == undefined)
break
s = vtb[v]
if (!s || s.time != time
|| w_tb[s.type] != wmin)
continue
if (s.type != C.MREST) {
mrest_time = -1 /* some note or rest */
break
}
if (nb == 0) {
nb = s.nmes
} else if (nb != s.nmes) {
mrest_time = -1 /* different duration */
break
}
}
if (mrest_time < 0) {
for (ir = 0; ir < nv; ir++) {
v = vn[ir]
if (v == undefined)
break
s = vtb[v]
if (s && s.type == C.MREST)
mrest_expand(s)
}
}
}
/* link the vertical sequence */
for (ir = 0; ir < nv; ir++) {
v = vn[ir]
if (v == undefined)
break
s = vtb[v]
if (!s || s.time != time
|| w_tb[s.type] != wmin)
continue
if (s.type == C.STAVES) {
new_sy = s.sy;
// set all voices of previous and next staff systems
// as reachable
for (ir2 = 0; ir2 < nv; ir2++) {
if (vn[ir2] == undefined)
break
|
| ︙ | ︙ | |||
343 344 345 346 347 348 349 |
} // end set_feathered_beam()
/* if Q: from tune header, put it at start of the music */
s = glovar.tempo
if (s && staves_found <= 0) { // && !s.del) { - play problem
v = par_sy.top_voice;
p_voice = voice_tb[v];
| | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
} // end set_feathered_beam()
/* if Q: from tune header, put it at start of the music */
s = glovar.tempo
if (s && staves_found <= 0) { // && !s.del) { - play problem
v = par_sy.top_voice;
p_voice = voice_tb[v];
if (p_voice.sym && p_voice.sym.type != C.TEMPO) {
s = clone(s);
s.v = v;
s.p_v = p_voice;
s.st = p_voice.st;
s.time = 0;
s.next = p_voice.sym
if (s.next)
|
| ︙ | ︙ | |||
366 367 368 369 370 371 372 |
p_voice.ignore = false
for (s = p_voice.sym; s; s = s.next) {
if (s.time >= staves_found)
break
}
for ( ; s; s = s.next) {
switch (s.type) {
| | | | | | | 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 |
p_voice.ignore = false
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] = 2,
// 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 (!cfmt.graceword)
continue
for (s2 = s.next; s2; s2 = s2.next) {
switch (s2.type) {
case C.SPACE:
continue
case C.NOTE:
if (!s2.a_ly)
break
s.a_ly = s2.a_ly;
s2.a_ly = null
break
}
break
|
| ︙ | ︙ | |||
416 417 418 419 420 421 422 |
//fixme: there may be other symbols before the %%staves at this same time
if (s.time >= staves_found)
break
}
p_voice2.clef = clone(p_voice.clef);
curvoice = p_voice2
for ( ; s; s = s.next) {
| | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
//fixme: there may be other symbols before the %%staves at this same time
if (s.time >= staves_found)
break
}
p_voice2.clef = clone(p_voice.clef);
curvoice = p_voice2
for ( ; s; s = s.next) {
if (s.type == C.STAVES)
continue
s2 = clone(s)
if (s.notes) {
s2.notes = []
for (i = 0; i <= s.nhd; i++)
s2.notes.push(clone(s.notes[i]))
}
|
| ︙ | ︙ | |||
478 479 480 481 482 483 484 485 486 487 |
if (init) { /* first staff system */
cur_sy = par_sy = sy_new
return
}
// update the previous system
for (v = 0; v < voice_tb.length; v++) {
st = par_sy.voices[v].st
var sy_staff = par_sy.staves[st],
p_voice = voice_tb[v]
| > | < > > | | | | | | 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 |
if (init) { /* first staff system */
cur_sy = par_sy = sy_new
return
}
// update the previous system
for (v = 0; v < voice_tb.length; v++) {
if (par_sy.voices[v].range >= 0) {
st = par_sy.voices[v].st
var sy_staff = par_sy.staves[st],
p_voice = voice_tb[v]
if (p_voice.staffnonote != undefined)
sy_staff.staffnonote = p_voice.staffnonote
if (p_voice.staffscale)
sy_staff.staffscale = p_voice.staffscale;
}
sy_new.voices[v] = clone(par_sy.voices[v]);
sy_new.voices[v].range = -1;
delete sy_new.voices[v].second
}
for (st = 0; st < par_sy.staves.length; st++) {
sy_new.staves[st] = clone(par_sy.staves[st]);
sy_new.staves[st].flags = 0
}
par_sy.next = sy_new;
par_sy = sy_new
}
/* -- set the bar numbers -- */
// (possible hook)
function set_bar_num() {
var s, s2, tim, bar_time, bar_num, rep_dtime,
v = cur_sy.top_voice,
wmeasure = voice_tb[v].meter.wmeasure,
bar_rep = gene.nbar
/* don't count a bar at start of line */
for (s = tsfirst; ; s = s.ts_next) {
if (!s)
return
switch (s.type) {
case C.METER:
wmeasure = s.wmeasure
case C.CLEF:
case C.KEY:
case C.STBRK:
continue
case C.BAR:
if (s.bar_num) {
gene.nbar = s.bar_num /* (%%setbarnb) */
break
}
if (s.text // if repeat bar
&& !cfmt.contbarnb) {
if (s.text[0] == '1') {
|
| ︙ | ︙ | |||
540 541 542 543 544 545 546 |
break
}
// at start of tune, check for an anacrusis
bar_time = s.time + wmeasure
if (s.time == 0) {
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
| | | | | | | | < < < | | > > > > > | | 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 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 |
break
}
// at start of tune, check for an anacrusis
bar_time = s.time + wmeasure
if (s.time == 0) {
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.type == C.BAR && s2.time) {
if (s2.time < bar_time) { // if anacrusis
s = s2;
bar_time = s.time + wmeasure
}
break
}
}
}
// set the measure number on the top bars
bar_num = gene.nbar
for ( ; s; s = s.ts_next) {
switch (s.type) {
case C.METER:
wmeasure = s.wmeasure
if (s.time < bar_time)
bar_time = s.time + wmeasure
break
case C.MREST:
bar_num += s.nmes - 1
while (s.ts_next
&& s.ts_next.type != C.BAR)
s = s.ts_next
break
case C.BAR:
if (s.bar_num)
bar_num = s.bar_num // (%%setbarnb)
if (s.time < bar_time) { // incomplete measure
if (s.text && s.text[0] == '1') {
bar_rep = bar_num;
rep_dtime = bar_time - s.time
}
break
}
/* check if any repeat bar at this time */
tim = s.time;
s2 = s
do {
if (s2.dur)
break
if (s2.type == C.BAR && s2.text) // if repeat bar
break
s2 = s2.next
} while (s2 && s2.time == tim);
bar_num++
if (s2 && s2.type == C.BAR && s2.text) {
if (s2.text[0] == '1') {
rep_dtime = 0;
bar_rep = bar_num
} else { // restart bar numbering
if (!cfmt.contbarnb)
bar_num = bar_rep
if (rep_dtime) { // [1 inside measure
if (cfmt.contbarnb)
bar_num--;
bar_time = tim + rep_dtime
break
}
}
}
s.bar_num = bar_num;
bar_time = tim + wmeasure
// skip the bars of the other voices
while (s.ts_next
&& !s.ts_next.seqst)
s = s.ts_next
break
}
}
if (cfmt.measurenb < 0) /* if no display of measure bar */
gene.nbar = bar_num /* update in case of more music to come */
}
// note mapping
// %%map map_name note [print [note_head]] [param]*
function get_map(text) {
if (!text)
return
var i, note, notes, map, tmp, ns,
a = info_split(text)
if (a.length < 3) {
syntax(1, "Not enough parameters in %%map")
return
}
ns = a[1]
if (ns.indexOf("octave,") == 0
|
| ︙ | ︙ | |||
644 645 646 647 648 649 650 |
tmp = new scanBuf();
tmp.buffer = a[1];
note = parse_acc_pit(tmp)
if (!note) {
syntax(1, "Bad note in %%map")
return
}
| < | < < < < < | 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
tmp = new scanBuf();
tmp.buffer = a[1];
note = parse_acc_pit(tmp)
if (!note) {
syntax(1, "Bad note in %%map")
return
}
ns = note2abc(note)
}
notes = maps[a[0]]
if (!notes)
maps[a[0]] = notes = {}
map = notes[ns]
if (!map)
|
| ︙ | ︙ | |||
685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
for (; i < a.length; i++) {
switch (a[i]) {
case "heads=":
map[0] = a[++i].split(',')
break
case "print=":
tmp = new scanBuf();
tmp.buffer = a[++i];
map[1] = parse_acc_pit(tmp)
break
// case "transpose=":
// switch (a[++i][0]) {
// case "n":
| > > | 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 |
for (; i < a.length; i++) {
switch (a[i]) {
case "heads=":
map[0] = a[++i].split(',')
break
case "print=":
if (cfmt.sound == "play")
break
tmp = new scanBuf();
tmp.buffer = a[++i];
map[1] = parse_acc_pit(tmp)
break
// case "transpose=":
// switch (a[++i][0]) {
// case "n":
|
| ︙ | ︙ | |||
737 738 739 740 741 742 743 |
if (curvoice.key.k_none)
curvoice.key.k_sf = 0
return
}
// set the transposition in the previous K:
while (1) {
| | < < < < < < < < < < < < < < < < < < < < < < < < < > | 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 |
if (curvoice.key.k_none)
curvoice.key.k_sf = 0
return
}
// set the transposition in the previous K:
while (1) {
if (s.type == C.KEY)
break
if (!s.prev) {
s = curvoice.key
break
}
s = s.prev
}
key_transp(s);
curvoice.ckey = clone(s)
if (curvoice.key.k_none)
s.k_sf = 0
}
/* -- process a pseudo-comment (%% or I:) -- */
// (possible hook)
function do_pscom(text) {
var h1, val, s, cmd, param, n, k, b,
lock = false
if (text.slice(-5) == ' lock') {
lock = true;
text = text.slice(0, -5).trim()
|
| ︙ | ︙ | |||
883 884 885 886 887 888 889 |
goto_tune()
}
n = parseInt(param)
if (isNaN(n) || n < -2 || n > 2) {
syntax(1, errs.bad_val, "%%ottava")
return
}
| < < < < < < < < < < | < < < < < < < < < < < < < | | | 855 856 857 858 859 860 861 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 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 |
goto_tune()
}
n = parseInt(param)
if (isNaN(n) || n < -2 || n > 2) {
syntax(1, errs.bad_val, "%%ottava")
return
}
parse.ottava = n
return
case "repbra":
if (parse.state >= 2) {
if (parse.state == 2)
goto_tune();
curvoice.norepbra = !get_bool(param)
}
return
case "repeat":
if (parse.state != 3)
return
if (!curvoice.last_sym) {
syntax(1, "%%repeat cannot start a tune")
return
}
if (!param.length) {
n = 1;
k = 1
} else {
b = param.split(/\s+/);
n = parseInt(b[0]);
k = parseInt(b[1])
if (isNaN(n) || n < 1
|| (curvoice.last_sym.type == C.BAR
&& n > 2)) {
syntax(1, "Incorrect 1st value in %%repeat")
return
}
if (isNaN(k)) {
k = 1
} else {
if (k < 1) {
syntax(1, "Incorrect 2nd value in %%repeat")
return
}
}
}
parse.repeat_n = curvoice.last_sym.type == C.BAR ? n : -n;
parse.repeat_k = k
return
case "sep":
var h2, len, values, lwidth;
set_page();
lwidth = img.width - img.lm - img.rm;
|
| ︙ | ︙ | |||
980 981 982 983 984 985 986 | s.sk2 = h2 return } blk_out(); vskip(h1); output += '<path class="stroke"\n\td="M'; out_sxsy((lwidth - len) / 2 / cfmt.scale, ' ', 0); | | | | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | s.sk2 = h2 return } blk_out(); vskip(h1); output += '<path class="stroke"\n\td="M'; out_sxsy((lwidth - len) / 2 / cfmt.scale, ' ', 0); output += 'h' + (len / cfmt.scale).toFixed(1) + '"/>\n'; vskip(h2); blk_flush() return case "setbarnb": val = parseInt(param) if (isNaN(val) || val < 1) syntax(1, "Bad %%setbarnb value") else if (parse.state >= 2) glovar.new_nbar = val else cfmt.measurefirst = val return case "staff": |
| ︙ | ︙ | |||
1024 1025 1026 1027 1028 1029 1030 |
case "staffbreak":
if (parse.state != 3) {
if (parse.state != 2)
return
goto_tune()
}
s = {
| | | | 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 999 1000 1001 1002 1003 1004 |
case "staffbreak":
if (parse.state != 3) {
if (parse.state != 2)
return
goto_tune()
}
s = {
type: C.STBRK,
dur:0
}
if (param[0] >= '0' && param[0] <= '9') {
s.xmx = get_unit(param)
if (param.slice(-1) == 'f')
s.stbrk_forced = true
} else {
s.xmx = 14
if (param[0] == 'f')
s.stbrk_forced = true
}
sym_link(s)
return
case "stafflines":
case "staffscale":
case "staffnonote":
self.set_v_param(cmd, param)
return
case "staves":
case "score":
if (parse.state == 0)
return
get_staves(cmd, param)
return
|
| ︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 |
return
// case 2:
// goto_tune()
// break
}
for (s = curvoice.last_sym; s; s = s.prev) {
switch (s.type) {
| | | | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
return
// case 2:
// goto_tune()
// break
}
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
}
do_info('V', curvoice.id + ' shift=' + param)
|
| ︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 |
if (cmd == "newpage") {
blk_flush();
block.newpage = true;
return
}
break
}
| | > > | | 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 |
if (cmd == "newpage") {
blk_flush();
block.newpage = true;
return
}
break
}
self.set_format(cmd, param, lock)
}
// treat the %%beginxxx / %%endxxx sequences
// (posible hook)
function do_begin_end(type,
opt,
text) {
var i, j, action, s
switch (type) {
case "js":
js_inject(text)
break
case "ml":
if (parse.state >= 2) {
s = new_block(type);
s.text = text
} else {
svg_flush();
if (user.img_out)
user.img_out(text)
}
break
case "svg":
j = 0
while (1) {
i = text.indexOf('<style type="text/css">\n', j)
if (i < 0)
|
| ︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | if (voice_tb.length == 0) return voice_adj(); dupl_voice(); sort_all() /* define the time / vertical sequences */ if (!tsfirst) return | | | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 |
if (voice_tb.length == 0)
return
voice_adj();
dupl_voice();
sort_all() /* define the time / vertical sequences */
if (!tsfirst)
return
self.set_bar_num()
if (!tsfirst)
return /* no more symbol */
// give the parser result to the application
if (user.get_abcmodel)
user.get_abcmodel(tsfirst, voice_tb, anno_type, info)
if (user.img_out) // if SVG generation
self.output_music()
/* reset the parser */
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;
|
| ︙ | ︙ | |||
1345 1346 1347 1348 1349 1350 1351 |
if (!s)
return //undefined;
time = s.time
for (; s; s = s.prev) {
switch (s.type) {
| | | | | 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 |
if (!s)
return //undefined;
time = s.time
for (; 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.type == C.NOTE) {
if (s.time + s.dur == time)
break
return //undefined
}
if (s.time < time)
return //undefined
}
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].pit == pitch
&& s.notes[i].ti1)
return s.notes[i].acc
}
return //undefined
case C.NOTE:
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].pit == pitch)
return s.notes[i].acc
}
break
}
}
|
| ︙ | ︙ | |||
1421 1422 1423 1424 1425 1426 1427 |
if (par_sy.voices[v].range >= 0) {
curvoice = voice_tb[v]
break
}
}
curvoice.time = maxtime;
s = {
| | | 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 |
if (par_sy.voices[v].range >= 0) {
curvoice = voice_tb[v]
break
}
}
curvoice.time = maxtime;
s = {
type: C.STAVES,
dur: 0
}
sym_link(s); // link the staves in this voice
par_sy.nstaff = nstaff;
new_syst();
s.sy = par_sy
|
| ︙ | ︙ | |||
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 | delete p_voice.snm delete p_voice.new_name delete p_voice.lyric_restart delete p_voice.lyric_cont delete p_voice.ly_a_h; delete p_voice.sym_restart delete p_voice.sym_cont voice_tb.push(p_voice) return p_voice } // clone_voice() /* treat the end of overlay */ if (curvoice.ignore) | > | 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | delete p_voice.snm delete p_voice.new_name delete p_voice.lyric_restart delete p_voice.lyric_cont delete p_voice.ly_a_h; delete p_voice.sym_restart delete p_voice.sym_cont delete p_voice.have_ly voice_tb.push(p_voice) return p_voice } // clone_voice() /* treat the end of overlay */ if (curvoice.ignore) |
| ︙ | ︙ | |||
1691 1692 1693 1694 1695 1696 1697 |
if (!vover) { /* first '&' in a measure */
vover = {
bar: true,
p_voice: curvoice
}
time = p_voice2.time
for (s = curvoice.last_sym; /*s*/; s = s.prev) {
| | | 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 |
if (!vover) { /* first '&' in a measure */
vover = {
bar: true,
p_voice: curvoice
}
time = p_voice2.time
for (s = curvoice.last_sym; /*s*/; s = s.prev) {
if (s.type == C.BAR
|| s.time <= time) /* (if start of tune) */
break
}
vover.time = s.time
} else {
if (curvoice != vover.p_voice
&& curvoice.time != vover.p_voice.time) {
|
| ︙ | ︙ | |||
1732 1733 1734 1735 1736 1737 1738 |
if (is_voice_sig()) {
curvoice.clef = s
return
}
// clef change
| < < < < < < < < < < < < < < < < < < < < | < < < < < < | 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 |
if (is_voice_sig()) {
curvoice.clef = s
return
}
// clef change
sym_link(s);
s.clef_small = true
}
// treat K: (kp = key signature + parameters)
function get_key(parm) {
var v, p_voice, s, transp,
// [s_key, a] = new_key(parm) // KO with nodejs
|
| ︙ | ︙ | |||
1787 1788 1789 1790 1791 1792 1793 |
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
p_voice.key = clone(s_key);
p_voice.okey = clone(s_key);
p_voice.ckey = clone(s_key)
}
| < | > | | 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 |
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
p_voice.key = clone(s_key);
p_voice.okey = clone(s_key);
p_voice.ckey = clone(s_key)
}
parse.ckey = s_key
if (a.length != 0)
memo_kv_parm('*', a)
if (!glovar.ulen)
glovar.ulen = C.BLEN / 8;
parse.state = 2; // in tune header after K:
set_page();
write_heading();
reset_gen();
gene.nbar = cfmt.measurefirst // measure numbering
return
case 2: // K: at start of tune body
goto_tune(true)
break
}
if (a.length != 0)
set_kv_parm(a);
if (!curvoice.ckey.k_bagpipe && !curvoice.ckey.k_drum)
transp = (cfmt.transp || 0) +
(curvoice.transp || 0) +
(curvoice.shift || 0)
if (s_key.k_sf == undefined) {
if (!s_key.k_a_acc
&& !transp)
return
|
| ︙ | ︙ | |||
1837 1838 1839 1840 1841 1842 1843 | if (s_key.k_none) curvoice.key.k_sf = 0 return } /* the key signature must appear before a time signature */ s = curvoice.last_sym | | | 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 |
if (s_key.k_none)
curvoice.key.k_sf = 0
return
}
/* the key signature must appear before a time signature */
s = curvoice.last_sym
if (s && s.type == C.METER) {
curvoice.last_sym = s.prev
if (!curvoice.last_sym)
curvoice.sym = null;
sym_link(s_key);
s_key.next = s;
s.prev = s_key;
curvoice.last_sym = s
|
| ︙ | ︙ | |||
1897 1898 1899 1900 1901 1902 1903 | vol: 0 }, scale: 1, // st: 0, // cst: 0, ulen: glovar.ulen, dur_fact: 1, | | | | | | 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 |
vol: 0
},
scale: 1,
// st: 0,
// cst: 0,
ulen: glovar.ulen,
dur_fact: 1,
key: clone(parse.ckey), // key at start of tune (parse) / line (gene)
ckey: clone(parse.ckey), // current key (parse)
okey: clone(parse.ckey), // key without transposition (parse)
meter: clone(glovar.meter),
wmeasure: glovar.meter.wmeasure,
clef: {
type: C.CLEF,
clef_auto: true,
clef_type: "a", // auto
time: 0
},
hy_st: 0
}
|
| ︙ | ︙ | |||
1929 1930 1931 1932 1933 1934 1935 |
nstaff = -1;
voice_tb = [];
curvoice = null;
new_syst(true);
staves_found = -1;
gene = {}
a_de = [] // remove old decorations
| < | 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 |
nstaff = -1;
voice_tb = [];
curvoice = null;
new_syst(true);
staves_found = -1;
gene = {}
a_de = [] // remove old decorations
}
// treat V: with many voices
function do_cloning(vs) {
var i, eol,
file = parse.file,
start = parse.eol + 1, // next line after V:
|
| ︙ | ︙ | |||
1966 1967 1968 1969 1970 1971 1972 |
}
include--
}
// treat a 'V:' info
function get_voice(parm) {
var v, transp, vtransp, vs,
| | | 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 |
}
include--
}
// treat a 'V:' info
function get_voice(parm) {
var v, transp, vtransp, vs,
a = info_split(parm),
vid = a.shift();
if (!vid)
return // empty V:
if (vid.indexOf(',') > 0) { // if many voices
vs = vid.split(',');
|
| ︙ | ︙ | |||
2004 2005 2006 2007 2008 2009 2010 |
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;
par_sy.voices[v].range = v;
par_sy.staves[nstaff] = {
| | | 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 |
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;
par_sy.voices[v].range = v;
par_sy.staves[nstaff] = {
stafflines: curvoice.stafflines || "|||||",
staffscale: 1
}
}
if (par_sy.voices[v].range < 0) {
// if (cfmt.alignbars)
// syntax(1, "V: does not work with %%alignbars")
|
| ︙ | ︙ | |||
2033 2034 2035 2036 2037 2038 2039 |
}
// change state from 'tune header after K:' to 'in tune body'
// curvoice is defined when called from get_voice()
function goto_tune(is_K) {
var v, p_voice,
s = {
| | | | | | < < | 1958 1959 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 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 |
}
// change state from 'tune header after K:' to 'in tune body'
// curvoice is defined when called from get_voice()
function goto_tune(is_K) {
var v, p_voice,
s = {
type: C.STAVES,
dur: 0,
sy: par_sy
}
parse.state = 3; // in tune body
// if no voice yet, create the default voice
if (voice_tb.length == 0) {
get_voice("1");
curvoice.clef.istart = curvoice.key.istart;
curvoice.clef.iend = curvoice.key.iend;
// nstaff = 0;
curvoice.default = true
} else if (!curvoice) {
curvoice = voice_tb[staves_found < 0 ? 0 : par_sy.top_voice]
}
if (!curvoice.init && !is_K) {
set_kv_parm([]);
set_transp()
}
// update some voice parameters
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
p_voice.ulen = glovar.ulen
if (p_voice.ckey.k_bagpipe
&& !p_voice.pos.stm) {
p_voice.pos = clone(p_voice.pos);
p_voice.pos.stm = C.SL_BELOW
}
}
// initialize the voices when no %%staves/score
if (staves_found < 0) {
nstaff = voice_tb.length - 1
for (v = 0; v <= nstaff; v++) {
p_voice = voice_tb[v];
delete p_voice.new; // old voice
p_voice.st = p_voice.cst =
par_sy.voices[v].st =
par_sy.voices[v].range = v;
par_sy.staves[v] = {
stafflines: p_voice.stafflines || "|||||",
staffscale: 1
}
}
par_sy.nstaff = nstaff
}
// link the first %%score in the top voice
p_voice = curvoice;
curvoice = voice_tb[par_sy.top_voice];
sym_link(s)
curvoice = p_voice
}
|
Changes to edit-de.js.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//JS - abc2svg edit - Text in Deutsch
function loadtxt() {
texts = {
bad_nb: 'fehlerhafte Zeilennummer',
fn: 'Filename: ',
load: 'Bitte öffne die eingebundene Datei ',
play: 'Wiedergabe',
stop: 'Stop',
}
var text_kv = {
a: 'Über ...',
b: 'ABC-Files:',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Fehler',
f: 'File',
fl: 'Lade File',
| > > > > > < < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
//JS - abc2svg edit - Text in Deutsch
function loadtxt() {
texts = {
bad_nb: 'fehlerhafte Zeilennummer',
fn: 'Filename: ',
load: 'Bitte öffne die eingebundene Datei ',
play: 'Wiedergabe',
stop: 'Stop',
}
var text_kv = {
a: 'Über ...',
b: 'ABC-Files:',
cmpa: 'Alles',
cmpt: 'Stück',
cmps: 'Auswahl',
cmpl: 'Schleife',
cmpc: 'Weiter',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Fehler',
f: 'File',
fl: 'Lade File',
fs: 'Schriftgröße',
gv: 'Lautstärke',
h: 'Hilfe',
ha: 'Hilfe',
lg: 'Sprache',
pr: 'Einstellungen',
saveas: 'Speichere File',
sful: 'Sound font URL',
sp: 'Speed'
}
for (var k in text_kv)
document.getElementById(k).innerHTML = text_kv[k];
document.getElementById('ctxMenu').title = 'Wiedergabe';
document.getElementById("hlp").outerHTML = '<ul id="hlp">\n\
<li>Du kannst entweder:\n\
<ul>\n\
<li>im Textfeld direkt ABC-Code direkt eintragen, oder</li>\n\
<li>ABC-Code im Textfeld aus der Zwischenablage einfügen, oder</li>\n\
<li>ein lokales ABC-File laden (\'ABC | Lade File\' Taste), oder</li>\n\
|
| ︙ | ︙ |
Changes to edit-en.js.
1 2 3 4 5 6 |
//JS - abc2svg edit - text in English
function loadtxt() {
texts = {
bad_nb: 'Bad line number',
fn: 'File name: ',
load: 'Please, load the included file ',
| < < > > > > > < < > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
//JS - abc2svg edit - text in English
function loadtxt() {
texts = {
bad_nb: 'Bad line number',
fn: 'File name: ',
load: 'Please, load the included file ',
}
var text_kv = {
a: 'About',
b: 'ABC files:',
cmpa: 'All',
cmpt: 'Tune',
cmps: 'Selection',
cmpl: 'Loop',
cmpc: 'Continue',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Errors',
f: 'File',
fl: 'Load file',
fs: 'Font size',
gv: 'Volume',
h: 'Help',
ha: 'Help',
lg: 'Language',
pr: 'Preferences',
saveas: 'Save file',
sful: 'Soundfont URL',
sp: 'Speed'
}
for (var k in text_kv)
document.getElementById(k).innerHTML = text_kv[k];
document.getElementById('ctxMenu').title = 'Play';
document.getElementById("hlp").outerHTML = '<ul id="hlp">\n\
<li>You may either:\n\
<ul>\n\
<li>directly write ABC code in the text area, or</li>\n\
<li>paste ABC code in the text area, or</li>\n\
<li>load a local ABC file (\'ABC | Load file\' button), or</li>\n\
<li>drag & drop a local file from your file manager\n\
or a selected text to the text area.</li>\n\
</ul></li>\n\
<li>You may change at will the ABC code in the text area.<br/>\n\
Rendering is done 2 seconds later.</li>\n\
<li>The \'Print\' button of the browser outputs the rendering area.</li>\n\
<li>You may select a part of the tunes either from the source text area\
(click and move), or from the rendered area.<br/>\n\
In the latter case, a left click on a music element defines the\
start of the selection. A right click defines its end.<br/>\
Also, if your browser can play the music, a right click\
outside the music displays the play menu.</li>\
</ul>'
}
|
Changes to edit-fr.js.
1 2 3 4 5 6 |
//JS - abc2svg edit - textes en français
function loadtxt() {
texts = {
bad_nb: 'Mauvais numéro de ligne',
fn: 'Nom de fichier: ',
load: 'SVP, ouvrez le fichier à inclure ',
| < < > > > > > < < > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
//JS - abc2svg edit - textes en français
function loadtxt() {
texts = {
bad_nb: 'Mauvais numéro de ligne',
fn: 'Nom de fichier: ',
load: 'SVP, ouvrez le fichier à inclure ',
}
var text_kv = {
a: 'A propos',
b: 'Fichiers ABC:',
cmpa: 'Tout',
cmpt: 'Morceau',
cmps: 'Selection',
cmpl: 'Boucle',
cmpc: 'Continuer',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Erreurs',
f: 'Fichier',
fl: 'Ouvrir un fichier',
fs: 'Taille police',
gv: 'Volume son',
h: 'Aide',
ha: 'Aide',
lg: 'Langue',
pr: 'Préférences',
saveas: 'Sauver le fichier',
sful: 'URL police de sons',
sp: 'Vitesse'
}
for (var k in text_kv)
document.getElementById(k).innerHTML = text_kv[k];
document.getElementById('ctxMenu').title = 'Jouer';
document.getElementById("hlp").outerHTML = '<ul id="hlp">\n\
<li>Vous pouvez, soit:\n\
<ul>\n\
<li>écrire directement du code ABC dans la zone d\'édition, ou</li>\n\
<li>coller du code ABC dans la zone d\'édition, ou</li>\n\
<li>charger un fichier ABC local (bouton \'Ouvrir un fichier\'), ou</li>\n\
<li>glisser-déposer un fichier ABC local\n\
ou une sélection de texte dans la zone d\'édition.</li>\n\
</ul></li>\n\
<li>Vous pouvez modifier le code ABC comme vous voulez.<br/>\n\
Le rendu se fait 2 secondes après.</li>\n\
<li>Le bouton \'Imprimer\' de votre browser n\'imprime que la zone de rendu.</li>\n\
<li>Vous pouvez sélectionner une partie des morceaux, ou bien depuis la zone\
d\'édition (click et déplacement), ou bien depuis la zone de rendu.<br/>\
Dans le dernier cas, un click gauche sur un élément de musique définit\
le début de la sélection. Un click droit définit la fin.<br/>\
Si votre navigateur peut jouer la musique, un click droit\
en dehors de la musique affiche le menu associé.</li>\
</ul>';
}
|
Changes to edit-it.js.
1 2 3 4 5 6 |
//JS - abc2svg edit - text in Italian
function loadtxt() {
texts = {
bad_nb: 'Numero di linea errato',
fn: 'Nome file: ',
load: 'Carica il file da includere ',
| < < > > > > > < < > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
//JS - abc2svg edit - text in Italian
function loadtxt() {
texts = {
bad_nb: 'Numero di linea errato',
fn: 'Nome file: ',
load: 'Carica il file da includere ',
}
var text_kv = {
a: 'A proposito',
b: 'File ABC:',
cmpa: 'Tutto',
cmpt: 'Brano',
cmps: 'Selezione',
cmpl: 'Loop',
cmpc: 'Continua',
// df: 'Caratteristiche di abc2svg',
// dp: 'Parametri di abc2svg',
er: 'Errori',
f: 'File',
fl: 'Carica file',
fs: 'Dimensione del font',
gv: 'Volume',
h: 'Aiuto',
ha: 'Aiuto',
lg: 'Lingua',
pr: 'Preferenze',
saveas: 'Salva il file',
sful: 'URL del Soundfont',
sp: 'Velocità '
}
for (var k in text_kv)
document.getElementById(k).innerHTML = text_kv[k];
document.getElementById('ctxMenu').title = 'Suonare';
document.getElementById("hlp").outerHTML = '<ul id="hlp">\n\
<li>Opzioni:\n\
<ul>\n\
<li>scrivere direttamente codice ABC nell\'area di testo, oppure</li>\n\
<li>incollare codice ABC nell\'area di testo, oppure</li>\n\
<li>caricare un file ABC locale (menu \'ABC | Carica file\'), oppure</li>\n\
<li>trascinare un file locale da file manager\n\
o del testo selezionato nell\'area di testo.</li>\n\
</ul></li>\n\
<li>Puoi modificare il codice ABC nell\'area di testo;<br/>\n\
dopo 2 secondi la musica viene visualizzata o aggiornata.</li>\n\
<li>L\'opzione \'Stampa\' del browser stampa la musica.</li>\n\
<li>Puoi selezionare parte di un brano sia nell\'area di testo\
(fai click e seleziona), o nell\'area dello spartito.<br/>\n\
In questo caso, un click su un elemento musicale inizia la selezione,\
mentre un click col tasto destro la termina.<br/>\
Inoltre, se il browser può suonare la musica, un click col tasto destro\
al di fuori della musica mostra il menu Suonare.</li>\
</ul>'
}
|
Changes to edit-pt_BR.js.
1 2 3 4 5 6 |
//JS - abc2svg edit - texto em português do Brasil
function loadtxt() {
texts = {
bad_nb: 'Número de linha incorreto',
fn: 'Nome do arquivo: ',
load: 'Por favor, inclua o arquivo ',
| < < > > > > > < | | | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
//JS - abc2svg edit - texto em português do Brasil
function loadtxt() {
texts = {
bad_nb: 'Número de linha incorreto',
fn: 'Nome do arquivo: ',
load: 'Por favor, inclua o arquivo ',
}
var text_kv = {
a: 'Sobre',
b: 'Arquivos ABC:',
cmpa: 'Todo',
cmpt: 'Peça',
cmps: 'Selecção',
cmpl: 'Loop',
cmpc: 'Continua',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Erros',
f: 'Arquivo',
fl: 'Abrir arquivo ABC',
fs: 'Tamanho da fonte',
gv: 'Volume',
h: 'Ajuda',
ha: 'Ajuda',
lg: 'LÃngua',
// playbutton: 'Tocar',
pr: 'Opções',
saveas: 'Salvar arquivo',
sful: 'Sound font',
sp: 'Velocidade'
}
for (var k in text_kv)
document.getElementById(k).innerHTML = text_kv[k];
document.getElementById('ctxMenu').title = 'Tocar';
document.getElementById("hlp").outerHTML = '<ul id="hlp">\n\
<li>Você pode:\n\
<ul>\n\
<li>escrever música em notação ABC diretamente na área de edição, ou</li>\n\
<li>colar notação ABC na área de edição, ou</li>\n\
<li>abrir um arquivo ABC local\n\
(usando o botão \'Arquivo | Abrir arquivo\'), ou</li>\n\
<li>arrastar e soltar na área de edição um arquivo ABC do seu gerenciador de arquivos\n\
ou algum texto selecionado.</li>\n\
</ul></li>\n\
<li>Você pode modificar o código ABC à vontade na área de edição.\n\
Após 2 segundos, a partitura será gerada.</li>\n\
<li>A função \'Imprimir\' do seu navegador imprimirá apenas a partitura.</li>\n\
<li>Você pode selecionar uma parte da música ou da área de edição<br/>\
(clicar e mover) ou da área da partitura.<br/>\
Nesse último caso, um clique esquerdo num elemento musical\
definirá o inÃcio da seleção. Um clique direito determinará o seu fim.<br/>\
Um clique direito fora da música mostrará o menu de execução,\
se o seu navegador for capaz de tocar a música.</li>\
</ul>';
}
|
Changes to editor/edit.css.
| ︙ | ︙ | |||
65 66 67 68 69 70 71 |
color: red;
}
#abckbd td {
border: 1px solid black;
padding: 0.5rem;
text-align: center;
}
| > > > > > > > > > > > > > > | > > > > > > > | | 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 |
color: red;
}
#abckbd td {
border: 1px solid black;
padding: 0.5rem;
text-align: center;
}
#ctxMenu {
position:absolute;
display:none;
left:0px;
top:0px;
height:20px;
width:40px;
padding:0;
margin:0;
border:1px solid;
background-color:white;
font-weight:normal;
white-space:nowrap;
z-index:100;
}
#ctxMenu:hover > .droplinks {
display:block;
}
#ctxMenu:before {
content:attr(title);
}
}
@media print {
#dleft, #ctxMenu, .popup { display: none }
body {
margin:0; padding:0; border:0;
background-color: white;
}
#dright { margin:0; padding:0; border:0 }
.newpage { page-break-before: always }
.nobrk { page-break-inside: avoid }
|
| ︙ | ︙ |
Changes to editor/edit.js.
1 2 | // edit.js - file used in the abc2svg editor // | | | 1 2 3 4 5 6 7 8 9 10 | // edit.js - file used in the abc2svg editor // // Copyright (C) 2014-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
28 29 30 31 32 33 34 |
alert("window error: " + msg)
return false
}
var abc_images, // image buffer
abc_fname = ["noname.abc", ""], // file names
abc, // Abc object
| | | | | | < < < | < < < < < < | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
alert("window error: " + msg)
return false
}
var abc_images, // image buffer
abc_fname = ["noname.abc", ""], // file names
abc, // Abc object
srcend, // source symbol end index
elt_ref = {}, // pointers to page HTML elements
selx = [0, 0], // selected source indexes
selx_sav = [], // (saved while playing/printing)
play = {}, // play data
pop, // current popup message
texts = {}, // language specific texts
jsdir = document.currentScript ?
document.currentScript.src.match(/.*\//) :
(function() {
var scrs = document.getElementsByTagName('script');
return scrs[scrs.length - 1].src.match(/.*\//) || ''
})()
|
| ︙ | ︙ | |||
79 80 81 82 83 84 85 |
abc_images += str
},
// -- optional methods
// annotations
anno_stop: function(type, start, stop, x, y, w, h) {
if (["beam", "slur", "tuplet"].indexOf(type) >= 0)
return
| | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
abc_images += str
},
// -- optional methods
// annotations
anno_stop: function(type, start, stop, x, y, w, h) {
if (["beam", "slur", "tuplet"].indexOf(type) >= 0)
return
srcend[start] = stop; // source index of the end of the element
// create a rectangle
abc.out_svg('<rect class="abcr _' + start +
'_" x="');
abc.out_sxsy(x, '" y="', y);
abc.out_svg('" width="' + w.toFixed(2) +
'" height="' + abc.sh(h).toFixed(2) + '"/>\n')
|
| ︙ | ︙ | |||
141 142 143 144 145 146 147 |
if (!no_memo)
storage(true, "lang", lang == "en" ? 0 : lang)
}
// show/hide a popup message
function popshow(area, visible) {
var e = document.getElementById(area)
| | > > > | > | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
if (!no_memo)
storage(true, "lang", lang == "en" ? 0 : lang)
}
// show/hide a popup message
function popshow(area, visible) {
var e = document.getElementById(area)
if (pop) {
if (pop == e)
visible = false
else
pop.style.visibility = 'hidden'
}
e.style.visibility = visible ? 'visible' : 'hidden';
pop = visible ? e : null
}
// load the (ABC source or include) file in the textarea
function loadtune() {
var files = document.getElementById("abcfile").files
|
| ︙ | ︙ | |||
190 191 192 193 194 195 196 |
}
// render the textarea content to the right side
function render() {
var i, j,
content = elt_ref.source.value;
| | > < < | | > > | | < < < < < < < < < < | < < < | | < < < < < < < < < < < | < | | | | < < < < < | < < < < < | | < < < < < < < < < | | | | | | | > | > > | > | | | > | < > > | > | < | < < < > > | < | | > > | | < < > | < < < < | > | < < < | > | < | < < | | | < < < < < < < < < | < < < < < | > < | | < | < | < < | < < < < < < < < | < < | | < < < < > | | > > > > > > | | | < < | | > > > | | | > > > > > | | > | < > > > > | > > | < < | > | | | < < | | | < < < < < | | | < > > > > > > > > | > > > < | < > | | | < | < | | < < | < | < < < < | | | > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | > > > | > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > | > > > > > > > > > | | > > | > > > > > | > | 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 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 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 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 646 647 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 |
}
// render the textarea content to the right side
function render() {
var i, j,
content = elt_ref.source.value;
play.a_pe = null
if (!content)
return // empty source
// if include file not loaded yet, ask it
i = content.indexOf('%%abc-include ')
if (i >= 0) {
var sl = elt_ref.s1
if (!sl.value) {
sl.style.display = "inline";
j = content.indexOf('\n', i);
sl.value = content.slice(i + 14, j);
selsrc(1);
alert(texts.load + sl.value)
return
}
}
elt_ref.diverr.innerHTML = '';
selx[0] = selx[1] = 0;
render2()
}
function render2() {
var content = elt_ref.source.value
// load the required modules
if (!abc2svg.modules.load(content + elt_ref.src1.value, render2))
return
user.img_out = user.my_img_out;
user.get_abcmodel = null;
abc = new abc2svg.Abc(user);
abc_images = '';
abc.tosvg('edit', '%%bgcolor white');
// document.body.style.cursor = "wait";
srcend = []
try {
abc.tosvg(abc_fname[0], content)
} catch(e) {
alert(e.message + '\nabc2svg tosvg bug - stack:\n' + e.stack)
return
}
abc2svg.abc_end() // close the page if %%pageheight
// document.body.style.cursor = "auto";
try {
elt_ref.target.innerHTML = abc_images
} catch(e) {
alert(e.message + '\nabc2svg image bug - abort')
return
}
// show the 'Error' button if some error
document.getElementById("er").style.display =
elt_ref.diverr.innerHTML ? 'inline' : 'none';
}
// select a source ABC element on error
function gotoabc(l, c) {
var s = elt_ref.source,
idx = 0;
selsrc(0)
while (--l >= 0) {
idx = s.value.indexOf('\n', idx) + 1
if (idx <= 0) {
alert(texts.bad_nb);
idx = s.value.length - 1;
c = 0
break
}
}
c = Number(c) + idx;
s.focus();
s.setSelectionRange(c, srcend[c] || c + 1)
}
// click in the target
function selsvg(evt) {
var v,
elt = evt.target,
cl = elt.getAttribute('class'),
ctxMenu = document.getElementById("ctxMenu");
play.loop = false;
evt.stopImmediatePropagation();
evt.preventDefault()
// remove the context menu if active
if (ctxMenu && ctxMenu.style.display == "block") {
ctxMenu.style.display = "none"
return false
}
// stop playing
if (play.playing && !play.stop) {
play.stop = -1;
play.abcplay.stop()
return false
}
// highlight the clicked element or clear the selection start
s = elt_ref.source;
if (cl && cl.substr(0, 4) == 'abcr') {
v = Number(cl.slice(6, -1));
s.setSelectionRange(v, srcend[v])
} else {
s.setSelectionRange(0, 0)
}
s.blur();
s.focus()
}
// set/clear a selection
function setsel(idx, v) {
var i, elts, s,
old_v = selx[idx];
if (v == old_v)
return
if (old_v) {
elts = document.getElementsByClassName('_' + old_v + '_');
i = elts.length
while (--i >= 0)
elts[i].style.fillOpacity = 0
}
if (v) {
elts = document.getElementsByClassName('_' + v + '_');
i = elts.length
while (--i >= 0)
elts[i].style.fillOpacity = 0.4
}
selx[idx] = v
}
function do_scroll(elt) {
var r,
dr = elt_ref.target.parentElement, // <div> 'dright'
drh = dr.getBoundingClientRect().height, // height of the view
ty = elt_ref.target.getBoundingClientRect().y // y offset of <div> 'target'
elt = elt.parentNode;
r = elt.getBoundingClientRect()
// upper -> top, lower -> bottom
if (r.y < 0) // y offset of the svg container
dr.scrollTo(0, r.y - ty)
else if (r.y + r.height > drh)
dr.scrollTo(0, r.y - ty - drh + r.height)
// in the middle
// if (r.y < 0 // y offset of the svg container
// || r.y + r.height > drh)
// dr.scrollTo(0, r.y - ty - drh / 2 + r.height)
}
// source text selection callback
function seltxt(evt) {
var s, elts,
e = 0,
elt = elt_ref.source,
start = elt.selectionStart,
end = elt.selectionEnd
play.loop = false
if (!start) {
if (end == elt.value.length)
return // select all
setsel(0, 0); // clear selection
setsel(1, 0)
return
}
if (srcend) {
srcend.forEach(function(ie, is) {
if (!s) {
if (is >= start)
s = is
} else if (ie <= end) {
e = is
}
})
}
if (!s)
return
if (selx[0] != s)
setsel(0, s)
if (selx[1] != e)
setsel(1, e);
elts = document.getElementsByClassName('_' + s + '_')
if (elts[0])
do_scroll(elts[0]) // move the element in the screen
}
// open a new window for file save
function saveas() {
var s = srcidx == 0 ? "source" : "src1",
source = elt_ref[s].value,
uriContent = "data:text/plain;charset=utf-8," +
encodeURIComponent(source),
// create a link for our script to 'click'
link = document.createElement("a");
elt_ref["s" + srcidx].value =
link.download =
abc_fname[srcidx] =
prompt(texts.fn, abc_fname[srcidx]);
link.innerHTML = "Hidden Link";
link.href = uriContent;
// open in a new tab
link.target = '_blank';
// when link is clicked call a function to remove it from
// the DOM in case user wants to save a second file.
link.onclick = destroyClickedElement;
// make sure the link is hidden.
link.style.display = "none";
// add the link to the DOM
document.body.appendChild(link);
// click the new link
link.click()
}
// destroy the clicked element
function destroyClickedElement(evt) {
document.body.removeChild(evt.target)
}
// set the size of the font of the textarea
function setfont() {
var fs = document.getElementById("fontsize").value.toString();
elt_ref.source.style.fontSize =
elt_ref.src1.style.fontSize = fs + "px";
storage(true, "fontsz", fs == "14" ? 0 : fs)
}
// playing
// set soundfont URL
function set_sfu(v) {
play.abcplay.set_sfu(v)
storage(true, "sfu", v == "Scc1t2" ? 0 : v)
}
// set_speed value = 1..20, 10 = no change
function set_speed(iv) {
var spvl = document.getElementById("spvl"),
v = Math.pow(3, // max 3 times lower/faster
(iv - 10) * .1);
play.abcplay.set_speed(v);
spvl.innerHTML = v
}
// set volume
function set_vol(v) {
var gvl = document.getElementById("gvl");
gvl.innerHTML = v.toFixed(2);
play.abcplay.set_vol(v)
storage(true, "volume", v == 0.7 ? 0 : v.toFixed(2))
}
function notehlight(i, on) {
if (play.stop) {
if (on) // (should not occur anymore)
return
if (play.stop < 0) // if first stop
play.stop = i // keep the last note reference
if (i == selx[1]) // if end selection
return // don't remove highlight
}
var elts = document.getElementsByClassName('_' + i + '_');
if (elts && elts[0]) {
if (on)
do_scroll(elts[0]);
elts[0].style.fillOpacity = on ? 0.4 : 0
}
}
function endplay() {
if (play.loop) {
play.abcplay.play(play.si, play.ei, play.a_pe)
return
}
play.playing = false;
// redisplay the selection
selx[0] = selx[1] = 0;
setsel(0, selx_sav[0]);
setsel(1, selx_sav[1])
}
// start playing
// -1: All
// 0: Tune
// 1: Selection
// 2: Loop
// 3: Continue
function play_tune(what) {
if (play.playing) {
if (!play.stop) {
play.stop = -1;
play.abcplay.stop()
}
return
}
// search a playing event from a source index
function get_se(si) { // get highest starting event
var i, s, tim,
sih = 1000000,
pa = play.a_pe,
ci = 0
if (si <= pa[0][0])
return 0
if (si >= pa[pa.length - 1][0])
return pa.length
si = go_note(si);
i = pa.length
while (--i > 0) {
s = pa[i][0]
if (s < si)
continue
if (s == si) {
ci = i
break
}
if (s < sih) {
ci = i;
sih = s
}
}
// go to the first voice at this time
if (ci < pa.length) {
tim = pa[ci][1]
while (--ci >= 0) {
if (pa[ci][1] != tim)
break
}
}
return ci + 1
} // get_se()
function get_ee(si, i) { // get lowest ending event
var s, tim,
sil = 0,
pa = play.a_pe,
ci = 0
if (si <= pa[0][0])
return 0
if (si >= pa[pa.length - 1][0])
return pa.length
si = go_note(si)
for ( ; i < pa.length; i++) {
s = pa[i][0]
if (s > si)
continue
if (s == si) {
ci = i
break
}
if (s > sil) {
ci = i;
sil = s
}
}
// go to after the last voice at this time
if (ci > 0) {
tim = pa[ci++][1]
for ( ; ci < pa.length; ci++) {
if (pa[ci][1] != tim)
break
}
}
return ci
} // get_ee()
// start playing
function play_start(si, ei) {
selx_sav[0] = selx[0]; // remove the colors
selx_sav[1] = selx[1];
setsel(0, 0);
setsel(1, 0);
play.stop = 0;
play.abcplay.play(si, ei, play.a_pe) // start playing
}
// play tune()
var abc, i, si, ei, elt, tim,
s = elt_ref.source.value,
ctxMenu = document.getElementById("ctxMenu");
// search a note/rest in the source from a selection
function go_note(si) {
for (var i = si; ; i++) {
if (!s[i])
return si
if ('ABCDEFGabcdefg[^_='.indexOf(s[i]) >= 0)
break
}
return i
}
ctxMenu.style.display = "none"; // remove the play menu
play.playing = true;
if (!play.a_pe) { // if no playing event
user.img_out = null // get the schema and stop SVG generation
user.get_abcmodel = play.abcplay.add // inject the model in the play engine
abc = new abc2svg.Abc(user);
play.abcplay.clear();
abc.tosvg("play", "%%play")
try {
abc.tosvg(abc_fname[0], s)
} catch(e) {
alert(e.message + '\nabc2svg tosvg bug - stack:\n' + e.stack);
play.playing = false;
play.a_pe = null
return
}
play.a_pe = play.abcplay.clear(); // keep the playing events
play.si = play.ei = play.stop = 0;
play.loop = false
}
// play all
if (what < 0) {
play.loop = false;
play.si = 0;
play.ei = play.a_pe.length;
play_start(play.si, play.ei)
return
}
// if loop again
if (what == 2 && play.loop) {
play_start(play.si, play.ei)
return
}
// get the starting and ending play indexes, and start playing
if (what == 3 && play.stop > 0) { // if stopped and continue
play_start(get_se(play.stop), play.ei)
return
}
if (what != 0 && selx[0] && selx[1]) { // if full selection
si = get_se(selx[0]);
ei = get_ee(selx[1], si)
} else if (what != 0 && selx[0]) { // if selection without end
si = get_se(selx[0]);
i = s.indexOf('\nX:', selx[0]);
ei = i < 0 ? play.a_pe.length : get_ee(i, si)
} else if (what != 0 && selx[1]) { // if selection without start
i = s.lastIndexOf('\nX:', selx[1]);
si = i < 0 ? 0 : get_se(i);
ei = get_ee(selx[1], si)
} else { // no selection => tune
si = play.click.svg.getElementsByClassName('abcr');
elt = play.click.svg // (dummy)
for (i = 0; ; i++) {
if (!si[i]) {
elt = null
break
}
if (si[i].parentNode == elt.parentNode)
continue // same container
elt = si[i];
ei = elt.parentNode.getBoundingClientRect()
if (ei.y < play.click.Y
&& ei.y + ei.height > play.click.Y)
break
}
i = elt ? Number(elt.getAttribute('class').slice(6, -1)) : 0;
si = ei = 0
if (s[0] == 'X' && s[1] == ':')
si = 1
while (1) { // search the start and end of the tune
ei = s.indexOf('\nX:', ei)
if (ei < 0 || ei > i)
break
si = s.indexOf('\nK:', ++ei)
if (si < 0)
break
ei = s.indexOf('\n', si + 1) + 1
}
if (si <= 0) {
play.playing = false
return // no tune!
}
si = get_se(si);
ei = ei < 0 ? play.a_pe.length : get_ee(ei, si)
}
if (what != 3) { // if not continue
play.si = si;
play.ei = ei;
play.loop = what == 2
}
play_start(si, ei)
}
// set the version and initialize the playing engine
function edit_init() {
// loop until abc2svg is fully loaded
if (typeof abc2svg != "object"
|
| ︙ | ︙ | |||
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
s.onload = relay;
s.onerror = onerror || function() {
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
function set_pref() {
var v = storage(true, "fontsz")
if (v) {
elt_ref.source.style.fontSize =
elt_ref.src1.style.fontSize =
v + "px";
document.getElementById("fontsize").value =
Number(v)
}
| > > > | < | | | < | | > | < | > | > | | | | | < > | < < < < < | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
s.onload = relay;
s.onerror = onerror || function() {
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
// accept page formatting
abc2svg.abc_end = function() {}
function set_pref() {
var v = storage(true, "fontsz")
if (v) {
elt_ref.source.style.fontSize =
elt_ref.src1.style.fontSize =
v + "px";
document.getElementById("fontsize").value =
Number(v)
}
v = storage(true, "lang");
loadlang(v || 'en', true)
}
document.getElementById("abc2svg").innerHTML =
'abc2svg-' + abc2svg.version + ' (' + abc2svg.vdate + ')'
// keep references on the page elements
var a = ["diverr", "source", "src1", "s0", "s1", "target"]
for (var i = 0; i < a.length; i++) {
var e = a[i];
elt_ref[e] = document.getElementById(e)
}
// set the callback functions
document.getElementById("saveas").onclick = saveas;
elt_ref.s0.onclick = function(){selsrc(0)};
elt_ref.s1.onclick = function(){selsrc(1)};
elt_ref.target.onclick = selsvg;
elt_ref.source.onselect = seltxt;
// remove the selection on print
window.onbeforeprint = function() {
selx_sav[0] = selx[0]; // remove the colors
selx_sav[1] = selx[1];
setsel(0, 0);
setsel(1, 0)
};
window.onafterprint = function() {
setsel(0, selx_sav[0]);
setsel(1, selx_sav[1])
}
// if playing is possible, load the playing script
if (window.AudioContext || window.webkitAudioContext
|| navigator.requestMIDIAccess) {
abc2svg.loadjs("play-@MAJOR@.js", function() {
play.abcplay = AbcPlay({
onend: endplay,
onnote:notehlight,
});
document.getElementById("playdiv1").style.display =
document.getElementById("playdiv3").style.display =
document.getElementById("playdiv4").style.display =
"list-item";
document.getElementById("sfu").value = play.abcplay.set_sfu();
// document.getElementById("spv").innerHTML =
// Math.log(play.abcplay.set_speed()) / Math.log(3);
document.getElementById("gvol").setAttribute("value",
play.abcplay.set_vol() * 10)
document.getElementById("gvl").setAttribute("value",
(play.abcplay.set_vol() * 10).toFixed(2))
});
var e = elt_ref.target;
e.oncontextmenu = function(evt) {
var x, y,
elt = evt.target,
cl = elt.getAttribute('class');
evt.stopImmediatePropagation();
evt.preventDefault()
// if right click on an element, select it
if (cl && cl.substr(0, 4) == 'abcr') {
setsel(1, Number(cl.slice(6, -1)))
return false
}
// otherwise, display the play menu
play.click = { // keep the click references for 'play tune'
svg: elt,
Y: evt.pageY
}
var ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "block";
x = evt.pageX - elt_ref.target.parentNode.offsetLeft
+ elt_ref.target.parentNode.scrollLeft;
y = evt.pageY + elt_ref.target.parentNode.scrollTop;
ctxMenu.style.left = (x - 30) + "px";
ctxMenu.style.top = (y - 10) + "px"
return false
} // oncontextmenu
}
set_pref() // set the preferences from local storage
}
// drag and drop
function drag_over(evt) {
evt.stopImmediatePropagation();
|
| ︙ | ︙ | |||
716 717 718 719 720 721 722 |
}
}
// render the music after 2 seconds on textarea change
var timer
function src_change() {
clearTimeout(timer);
| | | 860 861 862 863 864 865 866 867 868 869 870 871 872 |
}
}
// render the music after 2 seconds on textarea change
var timer
function src_change() {
clearTimeout(timer);
if (!play.playing)
timer = setTimeout(render, 2000)
}
// wait for scripts to be loaded
setTimeout(edit_init, 500)
|
Changes to editor/edit.xhtml.
| ︙ | ︙ | |||
33 34 35 36 37 38 39 | </li> <li id="playdiv1" style="display: none"> <label id="sful">Sound font URL</label> <input id="sfu" type="text" maxlength="120" size="50" onblur="set_sfu(this.value)"/> </li> | < < < < < | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | </li> <li id="playdiv1" style="display: none"> <label id="sful">Sound font URL</label> <input id="sfu" type="text" maxlength="120" size="50" onblur="set_sfu(this.value)"/> </li> <li id="playdiv3" style="display: none"> <label id="gv">Volume</label> <input id="gvol" type="range" min="1" max="10" value="7" onchange="set_vol(this.value / 10)"/> <label id="gvl">0.70</label> </li> <li id="playdiv4" style="display: none"> |
| ︙ | ︙ | |||
62 63 64 65 66 67 68 |
<li onclick="loadlang('de')">Deutsch</li>
<li onclick="loadlang('en')">English</li>
<li onclick="loadlang('fr')">Français</li>
<li onclick="loadlang('it')">Italiano</li>
<li onclick="loadlang('pt_BR')">Português do Brasil</li>
</ul>
</li>
| < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<li onclick="loadlang('de')">Deutsch</li>
<li onclick="loadlang('en')">English</li>
<li onclick="loadlang('fr')">Français</li>
<li onclick="loadlang('it')">Italiano</li>
<li onclick="loadlang('pt_BR')">Português do Brasil</li>
</ul>
</li>
<li class="dropbutton"><label id="h">Help</label>
<ul class="droplinks">
<li id="ha" onclick="popshow('help', true)">Help</li>
<li><a id="df" target="_blank"
href="http://moinejf.free.fr/abcm2ps-doc/features.xhtml">abc2svg features</a>
</li>
<li><a id="dp" target="_blank"
|
| ︙ | ︙ | |||
92 93 94 95 96 97 98 |
<label id="er" onclick="popshow('errlist', true)"
style="display: none; background: #ff8080">Errors</label>
<!-- ABC source in textarea (main and include) -->
</p>
<textarea id="source" rows="40" cols="73" wrap="off"
style="font: 14px monospace"
| < > > > > > > > > > > > < < < < < < < < | < < < > > > > > > > > | 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 |
<label id="er" onclick="popshow('errlist', true)"
style="display: none; background: #ff8080">Errors</label>
<!-- ABC source in textarea (main and include) -->
</p>
<textarea id="source" rows="40" cols="73" wrap="off"
style="font: 14px monospace"
ondrop="dropped(event)" ondragenter="drag_over(event)"
ondragover="drag_over(event)"
oninput="src_change()"></textarea>
<textarea id="src1" rows="40" cols="73" wrap="off"
style="font: 14px monospace; display: none"
oninput="src_change()"></textarea>
</div>
<!-- right - needed for the scrollbars -->
<div id="dright">
<!-- context menu -->
<div id="ctxMenu" title="Play">
<ul class="droplinks">
<li id="cmpa" onclick="play_tune(-1)">All</li>
<li id="cmpt" onclick="play_tune(0)">Tune</li>
<li id="cmps" onclick="play_tune(1)">Selection</li>
<li id="cmpl" onclick="play_tune(2)">Loop</li>
<li id="cmpc" onclick="play_tune(3)">Continue</li>
</ul>
</div>
<!-- rendering area -->
<div id="target">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
width="8.3in" height="2in" viewBox="0 0 595 144">
<text x="250" y="100" font-family="serif" font-size="12">(void)</text>
</svg>
</div>
</div>
<!-- error popup window -->
<div id="errlist" class="popup" style="width: 500px">
<div class="close" onclick="popshow('errlist')">x</div>
<div id="diverr">
</div>
</div>
<!-- help popup window -->
<div id="help" class="popup" style="width: 550px">
<div class="close" onclick="popshow('help')">x</div>
<ul id="hlp">
<li>(dynamically loaded)</li>
</ul>
</div>
<!-- about popup window -->
<div id="about" class="popup" style="width: 350px">
<div class="close" onclick="popshow('about')">x</div>
<p id="abc2svg">abc2svg</p>
<p>Copyright © 2016-2018 Jean-François Moine</p>
</div>
<!-- javascript must be enabled -->
<div id="okjs" class="popup" style="width:50%;background:#ff8080;visibility:visible">
Please enable Javascript.
</div>
<script>
document.getElementById('okjs').style.visibility = 'hidden'
</script>
</body>
</html>
|
Changes to font.js.
1 | // abc2svg music font | | | | | | | | | | > | | > | | > | < > > > > | < < > > > > | | > | | | > > | | < < | | | | | | | > > > > > > > > > > > > | < < > > > > | | > > > > > > > > > > > > > > | < < > > > | | < < < > | < < < < | | | | | > | | < | > > > > > > > > > > > > > > > > > > > > > | | | | > | < | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | < < | < > > | | > | > > > > > > > > > > > > > > > > > > | > > > > > > | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > | | < < > > > > > | < < > > > > > > | | > > > > > > > | < < < < < < < < > > > > > > > > > > > > > > | | | | < > > > > > > > > > > > | < < < < < < > > > > > | | | | | | | < > > > > > > > > > > | | | | > > > > > > > > > > > > | < < > > | | | > > | > | | | | > > > | | | > > > | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 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 |
// abc2svg music font
var musicfont = 'url("data:application/x-font-ttf;base64,\
AAEAAAAOAIAAAwBgRkZUTYGiLYcAAFMIAAAAHEdERUYAFQAUAABS7AAAABxPUy8yWLxbCQAAAWgA\
AABWY21hcM7xzSEAAAPMAAADKmN2dCAAIgKIAAAG+AAAAARnYXNw//8AAwAAUuQAAAAIZ2x5ZvUw\
oLYAAAgEAABCqGhlYWQNXJHdAAAA7AAAADZoaGVhCWn/CwAAASQAAAAkaG10eM2n+wQAAAHAAAAC\
CmxvY2HVL+UYAAAG/AAAAQhtYXhwAMoBPQAAAUgAAAAgbmFtZcjHNnAAAEqsAAADGHBvc3TQFqwa\
AABNxAAABR8AAQAAAAEAAGk1jGtfDzz1AAsEAAAAAADRlyIXAAAAANgjLVL/OPzvBUsEiAAAAAgA\
AgAAAAAAAAABAAAEiPzvAFwEJf84/XQFSwABAAAAAAAAAAAAAAAAAAAAggABAAAAgwEMAAUAAAAA\
AAIAAAABAAEAAABAAC4AAAAAAAEBlwGQAAUACAKZAswAAACPApkCzAAAAesAMwEJAAACAAUDAAAA\
AAAAAAAAARAAAAAAAAAAAAAAAFBmRWQAQAAA6qQDM/8zAFwEiAMRAAAAAQAAAAAAAAF2ACIAAAAA\
AVUAAAGQAAACWAAAAFcAAAFK/7ACE/+wANL/sAAjAAAAIwAAACMAAABkAAAEIwAABCUAAAHg/9wD\
XgB6AwsAAALSAAACv/+6AdYAAAMLAAADDgAAAyf/yADIAAABrgAAASIAAAGQAAABfAAAAZAAAAGQ\
AAABgQAAAZAAAAGQAAABgQAAAZkACQGYAAkB9AAAAQQAFAEEAAoCawAkAhIAAAHCAAABSQAAAUAA\
AAFK//4BLAAAAjAAAAFKAAABSgAAAGQAAAE7AAABOwAAATsAAAE7AAABOwAAATsAAAE7AAABOwAA\
ATsAAAE7AAABDQAAAMgAAAD/AAABCwAUAW4AAAENADIBbv/1AKkAAAE6AAABQP/9AFAAAAFAAAAB\
QAAAARgAAAJYAAAAtgAAAIIAAACCAAABLAAAASwAAADuAAAA/wAAAUkAAAGPAAAB2AAAAdgAAANT\
AAACM//wAyD/4QIz/7QBuP/bAV//fgIzAAACM//kAr//tAIz/7QCv/+0Ayv/2wFf/9sCaf9+AV//\
fgJp/34BXwAAAf0ABQG1AAABtQAAAkQADQJEAA0BGAAAATYAAAEs//8BLAAAAPoAAADIAAABGP84\
APoAAADIAAAEDQAAAhwADAH0AAAB9AAAAfQAAAH0AAAB9AAAAfQAAAB4AAAALQAAAhwAAAD6AAD/\
6gAAAAAAAwAAAAMAAAAcAAEAAAAAAiQAAwABAAAAHAAEAggAAAB+AEAABQA+AAAAIOAA4CTgMOA5\
4EPgSOBQ4FzgYuBp4H3gjOCV4KTgqeCz4QHhueG74efiSeJk4oPkoOSi5KTkqOSs5MDkzuTq5O7l\
AeUi5SXlLeUx5TnlZ+Vp5W3lguXQ5eLmEOYS5hTmGOYk5jDmUOZV6RLpFekY6SDpJeld6gLqpP//\
AAAAAAAg4ADgIuAw4DjgQ+BF4FDgXOBi4GngeuCA4JTgoOCp4LPhAeG54bvh5+JA4mDigOSg5KLk\
pOSo5KzkwOTO5OHk7uUA5SDlJOUp5S/lOeVm5WnlbOWC5dDl4uYQ5hLmFOYY5iTmMOZQ5lXpEOkU\
6RjpIOkl6V3qAuqk//8AA//kIAUf5B/ZH9IfyR/IH8Efth+xH6sfmx+ZH5IfiB+EH3sfLh53HnYe\
Sx3zHd0dwhumG6UbpBuhG54bixt+G2wbaRtYGzobORs2GzUbLhsCGwEa/xrrGp4ajRpgGl8aXhpb\
GlAaRRomGiIXaBdnF2UXXhdaFyMWfxXeAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGAAADAAAAAAAAAAECAAAA\
AgAAAAAAAAAAAAAAAAAAAAEAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAIgKIAAAAKgAqACoANgA+AG4AfACKAJgApACwAL4A3AFQAawCHAJe\
AvADggPkA/gElAUmBX4FvAXeBfIGRAaUBrQG+gc6B3QHwAgACEYIoAi0CNoJAAkyCU4JcAmcCbIJ\
zAoCChAKHAooCjoKVApuCqIK1gsqC3QL1AwyDKgNHA1CDVwNjA22Dg4ONA6ODq4O7A8UDygPNA9C\
D1IPeg+gD6wPuA/ED9AP8hAYEE4QnBD8EXARhhGsEdoSPhK2ExQTXBO4FRIWHhbYF5gYaBkEGeIa\
/hwAHEIchhzQHOodDh0iHTYdZh12HYgdpB26Hd4eDh7wH6wf1B/yICQgYiCUINYg6CD2IRIhLCFU\
AAIAIgAAATICqgADAAcALrEBAC88sgcEAO0ysQYF3DyyAwIA7TIAsQMALzyyBQQA7TKyBwYB/Dyy\
AQIA7TIzESERJzMRIyIBEO7MzAKq/VYiAmYAAAEAAAAAAZEBkAADAAAxESERAZEBkP5wAAEAAAAA\
AAAAAAAAAAAxAAABAAAAAABXBAMAIAAAETU2NTQnJjU0NwYVFBcWFRQHFhUUBwYVFBcmNTQ3NjU0\
NSMSVz8VJU1NJRU/VxIjAgMCGEM2YDk0ZjoySyI5YU1hGBhmTGA5JUoyOmY0OWA2SAAB/7D/7AGa\
ABQAAwAAJyEVIVAB6v4WFCgAAAAAAf+w/+wCYgAUAAMAACchFSFQArL9ThQoAAAAAAH/sP/sASIA\
FAADAAAnIRUhUAFy/o4UKAAAAAABAAAAAAAjA+gAAwAAETMRIyMjA+j8GAABAAAB9AAjA+gAAwAA\
ETMRIyMjA+j+DAABAAAC+AAjBFYAAwAAETcRIyMjBEwK/qIAAAAAAgAAAUAAZAKeAAcADwAAEiIm\
NDYyFhQCIiY0NjIWFEcqHR0qHR0qHR0qHQI6HSodHSr+6R0qHR0qAAAABQAAAAAEJAGuAC8ANwA/\
AEcAUwAAITUzHgEzMjY1NCcuBDU0NjMyFhc3MxcjLgEjIgYVFB4DFx4BFRQGIyInByAiJjQ2MhYU\
BCImNDYyFhQBETMyNjQmIwM1MxEjNTMyFhUUIwJOHhVPMik7lBkaKhYRWT0kJxkeHgceD0owHzkQ\
IhkyCE5NW09FLiMBmyodHSod/eoqHR0qHf6JKDxGRjzcRkbccYn6oDxLICEtKAcIFBQjFUNNCw4Z\
mzpIKBsPFw8JCwIVNzM6TiAgHSodHSodHSodHSoBaf6YYaZh/noeAWgeZ2vSAAUAAAAABCQBrgAa\
ACIAKgAyAD4AACEiJjU0NjMyFhc3MxcHJiMiBhQWMzI2NxcOATIiJjQ2MhYUBCImNDYyFhQBETMy\
NjQmIwM1MxEjNTMyFhUUIwMCZ3WCWiUpGx4eCCEkXjg2Njg2TREjFFmxKh0dKh396iodHSod/oko\
PEZGPNxGRtxxifprZ2V3DBIepgSMbZhtST4KSlEdKh0dKh0dKh0dKgFp/phhpmH+eh4BaB5na9IA\
AAAD/9wAAgHeArMABwAPAE0AAAAiJjQ2MhYUBCImNDYyFhQXNDYzMhYVFAcWMzI2NTQvAQMnEy4B\
NTQ+ATc2MzIWFRQGIyImNTQ3JiMiBhUUHwETFwMeARUUDgEHBiMiJgGeIBgYIBj+fiAYGCAYWxsU\
Ex4sFykmNiZ7zyvRWkgcExQmMzA4GxQTHiwXKSY2JnrUK9VaSBwTFCYzMDgBUhggGBggVBggGBgg\
0xIcGhEdDhctJi0mZf7eIAElR3E4Fi0RERM4IRIcGhEdDhctJi0mZQEmH/7XR3I4Fi0RERM4AAUA\
ev80A14CVAAXABsAHwAjACcAAAEzFR4BFzMVIw4BBxUjNS4BJyM1Mz4BNxEjFhc3FTY3JzMmJwc1\
BgcB2ChVeAeKigd4VShVeAeKigd4VXAFayhrBXBwBWsoawUCVIkIi2AoYIsIiYkIi2AoYokI/uW6\
DsjIDrooug7IyQ67AAAAAAQAAP1vAqcEiAALAEgAUgBnAAABBhUUFz4BNTQnDgETFxQVFAYjIiY1\
NDYzMhYUBgcWMzI2NTQ1JwYjIi4CNTQ3PgY/ASY1NDY3FhUUBgcXNjMyFhUUJzQmIyIGIxM+AScO\
ARUUFhcuATU0NycOAQceATMyNwFsBwVIdTY5QksXT01SX0AyL0E/Ly0YLkEXFBVJhmc9Og0kIC4d\
MRIXFg1sSWJceRQQD3GITmJQAgcCIVtB4jZGJx09P6YRj2wBAqB6EBADUzYuF2YxlUhyDQde+2zs\
AQJMXFNBLUg7WDcBGT1FAgHpAjNbh0+FZhcwJS0aJw4REJZmjKEHOuWIqV/PAp1yzro9ZwH+nRJd\
8gtGMSBCEg5FR6kuvXKXZ42jAgAAAAACAAD9/ALSAgAAZABoAAABMjY1NCcmIyIHDgIHJicmJxEj\
ETMRNjc2Nx4DFxYzMjY1NCcmIyIHFhcUFhUUBisBJjU0NzY3NjMyFxYXFRQGBwYjIicHFzYzMhYX\
Fh0BBgcGIyImNTQ3MzIWFRQGFQYHFgEzESMB3j5KDRpJRjwCBgoEIhoeLhwcLh4aIgYUDBkPJyUx\
PRIkUi8xMg0CMyEFRAUaVScjXlU3CFpIHy00PyIiPzRCZh4oCDdWXUxyRAUhMwIPMDX+TXt7/iB4\
Si0tbEkFDhsKYicrH/4EBAD+ER8rJ2ILKhcdCRt7QjE2YhoQKAMNBB4rGTIUC0QZDU80UxJObxwN\
F0tKFz4sOUMSUzRQTjwyGSseBA4EJhAcA978AAAAA/+6/aUCwwD/ACsANwBDAAA3NDYzMhYXFhUU\
BgcOAQc+ATc+ATc2NTQmJy4BIyIGBz4BMzIWFRQHBiMiJgUiJjU0NjMyFhUUBiciJjU0NjMyFhUU\
BhOLZ1VrKy9CVWjVkXevSDEsEw4RHR80MD9iERcjHC49JyExM0UCghYdGhQVHhoaFxscFRQcGx1i\
gDQ5PnJ/sE9iVQggVUgxVFA7akdQIyQdTE0dFEEvMiAeUYocFxYcHRUWHfIeGRUaGxQZHgAAAAIA\
AP8GAXIA+gADAAcAADczEyMDMxMj3JQCltyUApb6/gwB9P4MAAAEAAD+CgIfA6oACQAgAGIAbQAA\
JRYXPgE1NCYjIgMCJw4BFRQXLgE1NDY3JicOAQceATMyFx4BHwEdARQjIiY1NDYzMhYVFAYHFjMy\
NjU0LwEGIyImNTQ3PgE3PgI3JjU0NjceARUUBgceARc2MzIXFhUUBwYDBhUUFz4BNTQnBgFJEwZN\
R1ZCDg0YASw5HyAqTDsFCXFVAQVtggMiAwYCAno2UzMoJTUxJxUiIywBDQkVjZkuDkweBSMnEg5Z\
QC8ZSWECCAQSCFw5MmM2ZAMGN14pX3XEWxJPMzZW/uABCxAJNCcpJhJBKThOED5aWnlTcX4aIEAX\
FxsHf0gxJDM3JCIoAQwzNQ8JjQGSimpRHFAYBCAhDcIHbn8TM2JbbYdMEW4kAkM2YncwGwNWHiI5\
JCV7M0YmJgACAAD+YwJCAZoAYwBnAAABMjY1NCcmIyIHDgEHJicmJxEjETMRNjc2Nx4DFxYzMjY1\
NCcmIyIHFhcUFhUUBisBJjU0NzY3NjMyFxYXFRQGBwYjIicHFzYzMhYXFh0BBgcGIyImNTQ3MzIW\
FRQGFQYHFgEzESMBfjI7ChU6ODACDAQdExglFhYlGBMdBBEKEwwgHScxDhxDJScoCgIqGgQ2BBVE\
IxhJRi0GSDoYJSsxGxs0KDVSGCAGLUZJPVs2BBoqAgwmK/6jYmL+gGA7JCRXOwUdC1IcIhn+agMz\
/nQZIhxSCCISFwgWYjUrKE4VDSACCwMYIhQoEAk1FQtAK0EOPloWChI8OxMyIy41D0ErQD8wKBQj\
GAMLAx8NFgMY/M0AAAAAA//I/h4CNgDMACYALwA7AAA3NDYzMhcWFRQHDgEHNjc2NzY1NCcuASMi\
Bgc+ATMyFhUUBwYjIiYFIiY0NjIWFAYnIiY1NDYzMhYVFAYPcFKCPCN4Q8ZpwF5HHgktGC0gMFIK\
EhYWJTkgGSUsOQICEhcUIhgVFRIWFRIRFhUhTV5XM1rGbDtXBjNkSowvKWYzGhRCNhcNPCYoGhhT\
dRckFhciGMIYFBEUFRATGQAAAAADAAAAAADIAPAACQATACkAADcGFRQWMzI2NTQnIgYVFBc2NTQm\
ByImNTQ2Ny4BNTQ2MzIWFRQHFhUUBlAjGxARFAIOEyAjEzAlNSMiEQwoHiQ2PCg0dxQdFB4bERaG\
EQ4XGQshDxTcKB4XGgsPExAaIiAcIxAgGyAmAAAAAgAA/wYBrgD6AAsAFAAAMxQWMzI2NTQmIyIG\
BzQ2MhYUBiImiiojIisnJiUoin20fX20fWJ4eWFldXZhZ5CR0pGSAAABAAD/BgEiAPoACQAAMTcz\
ERcVIzU3EWR9QfBB+v4+HhQUHgEsAAAAAQAA/wYBjwD6ADwAADcyFRQHDgMHNjMyFjMyNz4CMw4C\
BwYHBiMiJiMiBiMiNTQnPgU1NCciBzIWFRQGIyI1ND4Bx8gFDTZAbzYTIBtkHBgeBRAMAQEFBQEH\
EBopGnQVH1YCBwECLD5HPChTThocKTceTDxY+n4aDiEuHUQtDCMOAw0LBRYWAykOGCcmEAECIUU4\
PDI4GGIBNSUeHylnKDkZAAABAAD/BgF1APoAOQAANzIWFRQGIyImNTQ3NjMyFxYVFAYHHgEVFAcG\
IyImJyY0NjMyFhUUBiMWMzI2NTQmJyY0Nz4BNCYjImYbIichGzIfM1lGJkRGPT5RSyRNJ1cYIzIg\
IiolGww/JCtILhYWL0spJDyqHBcbIysjLxoqEyJILkQLC0UtQycTFhQdTC4hGxkeKTEnJjoIBCIE\
CTdQMAAAAQAA/wYBkAD6ABEAAAUXIzc1IzU2NTMBMz8BETMVIwFFMsgy4ZOj/vuwAWNLS9EpKTEo\
8oD+jpaR/tkoAAAAAAEAAP8HAX4A+gAvAAAXNjMyFhUUBiMWMzI3PgE1NCcmIyIHEyEOASsBBzYz\
MhceARUUBw4CIyInLgE1NBIcIRsqIBwaJDEcEwkeHChOSAoBYgs1JdUGOUJTMSErQxZAKyU8KxAe\
XyAgFxwgIR4UHyA5HBo1ASIkOnkeHxVBJU8vEBACFAkyEiMAAAAAAgAA/wYBgQD6AAkALAAAFzI2\
NTQmIyIHFhMWFRQGIyImNTQ2MyYjIgYVPgIzMhYVFAYjIiYnPgEzMhbIKS0qKCwwB90bIxgeIhsQ\
Fjc1LxUYLR5MT3FIYWYBAWxbMD/SRSwiMCWeAZ8aJhkoHhsMHiN4XwsKCUA2RFmCeGmREgABAAD/\
BgGQAPsAKAAANyIOAwc3PggzMhYzMjY3DgQVIzY3Njc2NwYjIiZhFBoUCREFCgEMAgsFCwkNEAkv\
dSMaOxEbRRoeCIIBCBFoHi0RHiVgoQUOCRsGdAELAgkBBgEDASYXDkOnQVxCK0UbNocnOQooAAMA\
AP8GAYQA+gAOABwANAAAFw4BFRQWMzI2NTQuAzc+ATU0JiIGFRQeAwcuATU0NjcyFhUUBgceARUU\
BiMiJjU0Npo2LFgsKj8PIB0xPjMjRFIzChwSMXAxKWZKS2UqMDoydU1MdjkqGSQbHTApHw4XEg0T\
WhoiHB0wKCAPFxMKFT8YPDUzTQFGMic0Fxo6NTdKSDAkNQAAAgAA/wYBgQD6AAkALAAANyIGFRQW\
MzI3JgMmNTQ2MzIWFRQGIxYzMjY1DgIjIiY1NDYzMhYXDgEjIia5KS0qKCwwB90bIxgeIhsQFjc1\
LxUYLR5MT3FIYWYBAWxbMD/SRSwiMCWe/mEaJhkoHhsMHiN4XwsKCUA2RFmCeGmREgABAAn/CgGZ\
APkAMAAAJTAXNjU0JiMOARUUFxYzMjc2NxQeARUOAQciJyYnNCY1NDcyFhcWFRQGIyImNT4BMwEv\
EgQ8HzJBJyEwKygcKgkIG1VWTzs7BAHbJEARIiQcICkCIBqkAwUIFCICZWuOMyoiGFgBBAMBVVAB\
OTlmAisC5gIeFCckJTkuHBYmAAIACf6iAZkBXgA4AD8AACUwFzY1NCYjIgcRFjMyNzY3FB4BFQ4B\
ByMVIzUmJyYnNCY1NDc1MxUyNjMyFhcWFRQGIyImNT4BMwMRBhUUFxYBLxIEPB8DEAwMKygcKgkI\
G1FVASM9LjsEAasjAwcDJEARIiQcICkCIBp6PScKpAMFCBQiBP5LBCIYWAEEAwFUUQFoawktOWYC\
KwLLGWlmAR4UJyQlOS4cFib+lwGWLpGOMw0AAAEAAP8GAfQA+gALAAA1MzUzFTMVIxUjNSPXRtfX\
Rtcj19dG19cAAAABABT+BgDjAgAAEwAAExYHBicmAjU0Ejc2FxYHBgIVFBLcBw0JBUlra0kJCwYG\
PEZH/hYIBQMGVwEgfXwBIlYLBwYISf7niIb+5QAAAQAK/gIA3AH9ABMAABM2EjU0AicmNzYXFhIV\
FAIHBicmFDtHRjwJDAoHSWtrSQgLBv4WSQEbhogBGUkLBAQJVv7efH3+4FcJCQQAAAQAJP9WAkwA\
qgALAA8AEwAeAAAFNCYjIgYVFBYzMjY3MxEjATMRIyQUBiMiJjU0NjMyAahUPCA0Vz0hL3IyMv4K\
MjIB9XtmZXx5aGYgNU4nHzVLI+r+rAFU/qzmeEZJOT9DAAACAAD/JAISANwAAwAPAAA3FSE1JTMV\
ITUzESM1IRUjHgHW/gweAdYeHv4qHkGCgps3N/5INzcAAAIAAP9/AcIAgQALABMAAAU0JiMiBhUU\
FjMyPgEUBiImNDYyAVFaNiA0XTchL3F9yH19yB40TycfNEwjdGxLS2xLAAAAAgAA/2wBSACUAA0A\
GwAAJSYjIgYVFBcWMzI2NTQ3FhUUBiMiJyY1NDYzMgEkDSU8lwYLJjyXEA9+SE8kD35IT0QXYSsK\
CRdhKwkXHh1DZ0MeHUNnAAAAAAEAAP95AUAAhwALAAAlFAYjIiY1NDYzMhYBQHlZMjx6WDI8KEZp\
OCdFajgAAf/+/28BTACRAAsAACc3FzcXBxcHJwcnNwIbjIwbhoYci4schnEgdnUgcHAhdXUhcAAA\
AAUAAP9qASwAlgAFAAsAEQAXAB8AABcHFjMyNy8BBhUUFz8BJiMiBx8BNjU0JwY0NjIWFAYilkcd\
KikfXUcdHVxIHykqHVxHHR3yWHxYWHwSSB0dWkkfKSodWEgdHVpIHykqHYV8WFh8WAAAAAEAAP8G\
AjAA+gADAAAVATMBAbh4/kf6AfT+DAABAAD/dAFKAIwAAwAAMTcXB6WlpYyMjAABAAD/dAFKAIwA\
AgAAFRsBpaWMARj+6AABAAD/zgBkADIABwAAFiImNDYyFhRHKh0dKh0yHSodHSoAAAABAAD87wE7\
AAAADwAAFTUzHgQVFAc2NTQmJx4GP1FQNy4SkXDv7zVwZWyJSWBpQUmP3yoAAQAAAAABOwMRAA8A\
ADE1Mz4BNTQnFhUUDgMHHnCSEy43UFE/Bu8f4ZNHSGdeSIptZ3E1AAIAAP1EATwAAAAWACMAABkB\
Mx4EFRQHFhUUBzY1NC4DIzUeAxc2NTQuAx4JQlBONBITHgUoPklAFglETVYVASk+SUD+qQFXJFBK\
T2IzKi0qKjU6HR03ZEUzGaskVENdKQsJOGRFNBgAAgAA//8BPAK8ABYAIwAAFREzMj4DNTQnFhUU\
BxYVFA4DBzUyPgM1NCcOAx4WQEk+KAUeExI0TlBCCRZAST4pARVWTUQBAVcZM0VkNx0dOjUqKi0q\
M2JPSlAkqxg0RWQ4CQopXUNTAAADAAD9KgE8AJEAGwArADsAABkBMx4GFRQHFhUUBxYVFAc2NTQu\
AiM1HgMXNDY1NCcmJyYjIiceAxc0NjU0JyYnJiMiHgYnMzs4LhwSEhITHgU9V1UcCURNVhUBckZA\
BwUBAQlETVYVAXJGQAcFAf6QAgEbOTM3Oj1IJSwrJy0sKykrNjkZIUR3SCmpJFRBXSkEDQOIXzsI\
AaskU0JdKQQNA4hfOwgBAAADAAD/VgE8Ar0AGQAmADMAABEzMj4DNTQnFhUUBxYUBxYVFA4DByM3\
Mj4DNTQnDgMnMj4DNTQnDgMeFkBJPigFHhMSEhI0TlBCCR4eFkBJPikBFVZNRAkWQEk+KQEVVk1E\
AVcZM0VkNx0dOjUqKixVKi0qM2JPSlAkqhk0RWQ4CgopXUNUhhk0RWQ4CgopXUNUAAAABAAA/UIB\
PAFUABwAKQA2AEMAABkBMx4EFRQHFhQHFhQHFhUUBzY1NC4DIzUeAxc2NTQuAyceAxc2NTQuAyce\
Axc2NTQuAx4JQlBONBISEhISEx4FKD5JQBYJRE1WFQEpPklAFglETVYVASk+SUAWCURNVhUBKT5J\
QP6oAqwkUEpPYjMqLSpVLCpVLCoqNTodHTdkRTMZqyRUQ10pCwk4ZEU0GKskVENdKQsJOGRFNBir\
JFRDXSkLCThkRTQYAAAABAAA/o4BPAKgABwAKQA2AEMAABkBMzI+AzU0JxYVFAcWFAcWFAcWFRQO\
Awc1Mj4DNTQnDgMnMj4DNTQnDgMnMj4DNTQnDgMeFkBJPigFHhMSEhISEjROUEIJFkBJPikBFVZN\
RAkWQEk+KQEVVk1ECRZAST4pARVWTUT+jgKsGTNFZDcdHTo1KiosVSosVSotKjNiT0pQJKoZNEVk\
OAoKKV1DVIYZNEVkOAoKKV1DVIYZNEVkOAoKKV1DVAAFAAD9VQE8AhIAIAAtADoARwBUAAAZATMe\
BRUUBxYUBxYUBxYUBxYVFAc2NTQuAyM1HgMXNjU0LgMnHgMXNjU0LgMnHgMXNjU0LgMnHgMXNjU0\
LgMeBzI/RjolEhISEhISEhMeBSg+SUAWCURNVhUBKT5JQBYJRE1WFQEpPklAFglETVYVASk+SUAW\
CURNVhUBKT5JQP67A1cfQzpGQVQrKi0qVSwqVSwqVSwqKjU6HR03ZEUzGaskVENdKQsJOGRFNBir\
JFRDXSkLCThkRTQYqyRUQ10pCwk4ZEU0GKskVENdKQoKOGRFNBgAAAUAAP28ATwCeQAfACwAOQBG\
AFMAABkBMzI+AzU0JxYVFAcWFAcWFAcWFAcWFRQOAwc1Mj4DNTQnDgMnMj4DNTQnDgMnMj4DNTQn\
DgMnMj4DNTQnDgMeFkBJPigFHhMSEhISEhISNE5QQgkWQEk+KQEVVk1ECRZAST4pARVWTUQJFkBJ\
PikBFVZNRAkWQEk+KQEVVk1E/bwDVxkzRWQ3HR06NSoqLFUqLFUqLFUqLSozYk9KUCSqGTRFZDgK\
CildQ1SGGTRFZDgKCildQ1SGGTRFZDgKCildQ1SGGTRFZDgKCildQ1QAAAACAAD/ZADhAbAACgAW\
AAA3IgYdATY3NjU0JjcyFhUUBwYjETMRNmcUKyImKx0HIzlLUkQoI3omE7kPODsvGyYmMiNJTFIC\
TP68NAAAAgAA/oYAxQF6AAMADAAAFzc1BxEVNxEjNQcRNxyQkKkZrAFlLZYtAUnoNP3A4jMCQwEA\
AAIAAP6YAP8BaAADAB8AADcVNzUDIzUHNTc1BzU3NTMVNzUzFTcVBxU3FQcVIzUHU1paHjU1NTUe\
Wh01NTU1HVpGpxun/jejD1wPpw9aD6ifHKujD1wPpw9aD6ifHAAAAAEAFP+EAQsAegAeAAAXNSYn\
BzAVIzUzNycwIzUzFRYXNzA1MxUjBgcXMDMVwygMM0g5MzM5SCESNEg5IRM0OXw7Jg0zO0oyMkg5\
IhEzOUciETRIAAQAAP9qAWwBsAAOABwAKwA6AAA3DgEdATI3Njc2NTQnJiM3MhYVFAcGBwYjETMR\
NhcOAR0BMjc2NzY1NCcmIzcyFhUUBwYHDgEjETMRNk4RHg4eHwwEChARGR0rCRgrNS8fGdERHRAe\
HQsGCxAPFh8qCxkoFjcWHht9AR4QxikrNA0ZHhQVJjkhEiA5NEACRv7BMiYBHRHGKS8wExMcFhUm\
NiQWHD4vGyUCRv7BMgAAAgAy/2QBDQGwAAoAFgAANyIGFRQXFhc1NCYnMhcRMxEiJyY1NDarFyAu\
LhoqMzojIzpSTzl6JhswRUIDyxIeJjQBRP20UlBFIzIAAAT/9f9qAWwBsAAOAB0ALAA7AAA3IyIH\
BhUUFxYXFjM1NCYnMhcRMxEiJicmJyY1NDYXDgEdATI3Njc2NTQnJiM3MhYVFAcGBw4BIxEzETZX\
AREQCgQMHx4OHiswGR8WNxcrGAkr6REdEB4dCwYLEA8WHyoLGSgWNxYeG30VFB4ZDTQrKcYQHicy\
AT/9uiUbNDkgEiE5JgEdEcYpLzATExwWFSY2JBYcPi8bJQJG/sEyAAAAAAEAAP7AAKkBQAATAAAT\
MxU3FQcVNxUHFSM1BzU3NQc1N0QeR0dHRx5EREREAUCiDlwOfw5aD6iiDlwOfw5aDwADAAD+mAE6\
AWgAIwAnACsAADc1MxU3FQcVNxUHFSM1BxUjNQ8BIzUHNTc1BzU3NTMVNzUzFQM1BxU3FTc16R4z\
MzMzHj0ePAEeMzMzMx49Hh49Wz3AqJ4PXA+fD1oPtaoSrKQQqJ4PXA+fD1oPtaoSrKT+/Z4Rn7ie\
EZ8AAf/9AAABPwD0ABgAADcGIyImNTQ/ATYvASY1NDYzMjEXBRYVFAcSAgMHCQbPDg7NCAsHAQIB\
Hw4OAQEQCAoDSQcGTwMLChIBawYODQUAAAABAAAAAABQAFAACQAANTQ2MhYUBiMiJhciFxcREBgo\
ERcXIhcYAAAAAQAAAAABQAAoAAMAADE1IRUBQCgoAAAAAQAAAAAAZAEYAAMAADMDMwMoKGQoARj+\
6AAAAAEAAAAAARgBNQAFAAAxGwEjJweMjEFYWgE1/svGxgAAAgAAAAACWAFKAA4AGQAAMTQ2MzIe\
AhUjLgEiBgchIiY0NjMyFhUUBrN5OWtVMw8LouCiCwEcFyUlFxkjI5iyLFGATW6Ghm4kMCQkGBkj\
AAABAAAAAAC2AS0AFwAAEzIWFxYVFAcOASMnJjU0NjU0Iy4BNTQ2VhsbEBoyGUQQBgFHFBsoLQEt\
DBEdMD08HS0DAQIIaxMPASYcHjEAAQAA/wYAggD6AAMAADUzESOCgvr+DAAAAQAAAAAAggD6AAMA\
ADUzFSOCgvr6AAAAAQAA/4MBLAAAAAMAADEhFSEBLP7UfQAAAQAAAAABLAB9AAMAADUhFSEBLP7U\
fX0AAQAA/n4A6wGHABMAABMXBxcmIyIGFRQXJjU0NjMyFyc3Kb1nbDI0HyY4eDQlIiKHZAGH5dnP\
LiQdNTRLTSMtFby0AAABAAD/DQEAAMAAFgAANw4CIyImNTQ2MhYVFAcyNjc2MhcDJ6sDGRoTKzcm\
OCkXIjMhAhUDljA8AQcEKSgfIB4ZHRshLAIC/m8QAAAAAQAA/gwBSADAACQAABcGIyImNTQ2MzIW\
FRQHMj8BBiMiJjU0NjMyFhUUBzI3NjIXAyerKCErNycbHCkXQQs8NhgrNycbHCkXSC4CFQPFLcQM\
KCggIB8ZHRsiygwpKB8gHhkdG00CAv1uDAAAAQAA/gwBjwHAADYAADcGIyImNTQ2MzIWFRQHMj8B\
Ig4BIyImNTQ2MzIWFRQHMjc2MhcBJxMGIyImNTQ2MzIWFRQHMjf2KB8rNycbHCkXPws6ASAcEys3\
JxscKRdILgEWA/70LVUoISs3JxscKRdBCzwMKCggIB8ZHRsiywkEKSgfIB4ZHRtNAgL8bgwBJAwo\
KCAgHxkdGyIAAAAAAQAA/QwB2gHAAEUAABMGIyImNTQ2MzIWFRQHMj8BBiMiJjU0NjMyFhUUBzI/\
AQYjIiY1NDYzMhYVFAcyPwEiDgEjIiY1NDYyFhUUBzI3NjIXASerKCErNycbHCkXQQs6KCErNycb\
HCkXQQs6KB8rNycbHCkXPws6ASAcEys3JjgpF0guAhUD/qkt/jwMKCggIB8ZHRsiygwoKCAgHxkd\
GyLKDCgoICAfGR0bIssJBCkoHyAeGR0bTQIC+24MAAAAAQAA/QwCGQKuAFYAACUGIyImNTQ2MzIW\
FRQHMj8BBiMiJjU0NjMyFhUUBzI/ASIOASMiJjU0NjMyFhUUBzI3NjIXAScTBiMiJjU0NjMyFhUU\
BzI/AQYjIiY1NDYzMhYVFAcyNwE/KCErNycbHCkXQQs2KB8rNycbHCkXPws0ASAcEys3JxscKRdI\
LgEWA/5qLVUoISs3JxscKRdBCzooISs3JxscKRdBCzQMKCggIB8ZHRsixAwoKCAgHxkdGyLHCQQp\
KB8gHhkdG00CAvqADAEkDCgoICAfGR0bIsgMKCggIB8ZHRsiAAEAAP8aA1IA5gALAAA1MxUhNTMR\
IzUhFSMZAyAZGfzgGeZ9ff40fX0AAAAAA//w/wYCJgD6AAcADwATAAA2IiY0NjIWFAAiJjQ2MhYU\
BQEzAVAyIyMyIwGIMiMjMiP90gG4fv5HSyMyIyMy/s8jMiMjMloB9P4MAAT/4f8GAwcA+gAHAA8A\
EwAXAAA2IiY0NjIWFAAiJjQ2MhYUBQEzATMBMwFBMiMjMiMCdzIjIzIj/OMBuHv+R3kBuHv+R0sj\
MiMjMv7PIzIjIzJaAfT+DAH0/gwAAv+0/4gBfAEYABkASAAANxYzMjY3PgU1NCYnJiMiBgcGFRQe\
ARciJwczMhQrASI0OwETPgI1NC4CIyIOAwcGJjc2NzYzMhYXPgEzMhYVFAbFAwQSMg4CAwMDAQEH\
CAMDEzQLDwQHCBYZLTQLC+ELC0toAQMCAQIFAwgMDwsZCgUbBTEPGCQjJAcdJiMeLWsoATUkBQsM\
DAwMBhAXAwEzHCYlDBQNKiB6Hh4BHQIIDgYDBQUCBxQSLBAIDwlYEBkTGh4PNDBHbQAB/9v/9gG+\
ARgAVwAANwYHBisBIj8BNiYjIgYHBiY3PgMzMhc2MzIXPgEzMh4DFRQPAQYVFDMyNz4FNzYWBw4C\
IyImNTQ2PwI0IyIPAQYHJwYmPwE2NTQmIyIHUAcIBAQ1DQ1CBAYIDRYkBRUEFBAiHxI3CyQkLQkL\
KRMKEg8LBwUvBAgCAwULBwwDDQEGFQYSFy0fFRkCAzQBFRsIQQgPJg0IBEMBDAkbCBURAwEapw0P\
GjkIDAklGjASKCgoEBgGCw8TCg0NfQsJDgIDCQYPBRIBCQ0LHx8aFRQGDQeIBg4UqxYBAQEPCKsD\
AwYIFAAB/37/YAFeAbgASAAAByImNTQ2MzIWFRQHBhUUMzI+BzcjIiY1ND4DOwE+ATMyFhUUBiMi\
JjU0NzY0IyIOBwczMhYUBisBDgEyIDAXExIXEgoZCxAPCw0KDg0UCjUJCgEDBAYDQRRpNCAwFxMS\
FxIKGQcMCgcIBQYDBgE2CQoKCT8hdqAmIBoiFA8OCwcNDgYREyUkPDdVJwwJAwUFBAJLXyYgGiIU\
Dw4LBhwFCwoUDRoNHgYMEAzFwQAAAAEAAAAAANoBGAA0AAAzIiY1NDYzMhYVFAcWMzI2NTQuAicm\
NTQ2MzIWFRQGIyIuATU0NyYjIgYVFB4CFx4BFRRQHjISDA4XDAYYFiEJCxgGPDctIjYWEAgQCwUQ\
Dg8ZERIeBRsXKxsQFg0LGAwSFhILDwcNBCYqIy0kGBAYCQ8KCAgUEQ0JEwwRAxIfFVoAAAH/5P//\
AOcBEAA/AAAnBi4BPwEuASMqASMiDgEHBicmNz4BNxYzMj4BMzIXFhQPAQ4BFRQeARcWNicuATU0\
NjMyFRQHBgciJiMuASMiCgYLAQWwCBcRBQwHBREUBQ8EAwgMCwEwIhkgEQcFCAsHngEBECwXCAwD\
AyQUDCYkERIDBQIXNAkSAwQIDQbBBAMbIQQNCwkSHjACAwMEAQERB6cDAwIFAQkLBA8JCAgUCxM3\
KhUJAQEDDQAF/7T/iAVLARgAGwA1ANkA8AELAAAlFjMyPgE3PgY1NCYnJiMiBgcOAhUUBRYzMjY3\
PgU1NCYnJiMiBgcGFRQeARciJwczMhQrASI0OwETPgI1NC4CIyIOAwcGJjc2NzYzMhYXPgEzMhc+\
ATMyFhc+ATMyFz4BMzIWFz4BMzIXPgEzMhYXPgEzMhYVFAYjIicHMzIUKwEiNDsBEz4CNTQmIyIG\
BxUUBiMiJwczMhQrASI0OwETPgI1NCYjIgYHFRQGIyInBzMyFCsBIjQ7ARM0PgM0NTQmIyIGBxUU\
BiUWMzI2Nz4ENTQmJyYjIgYHBhUUBRYzMjY3PgY1NCYnJiMiDgEHBhUUFgIKAwQMHx4JAgMCAgIB\
AQcIAwMTNAsFBwP+ywMEEjIOAgMDAwEBBwgDAxM0Cw8EBwgWGS00CwvhCwtLaAEDAgECBQMIDA8L\
GQoFGwUxDxgkIyQHHSYjLxMSIhsjJAcdJiMvExIiGyMkBx0mIy8TEiIbIyQHHSYjHi1rSRYZLTQL\
C+ELC0toAQMCBQYOFBRrSRYZLTQLC+ELC0toAQMCBQYOFBRrSRYZLTQLC+ELC0toAQIBAgUGDhQU\
awODAwQSMg4CBAMDAQcIAwMTNAsP/ssDBBIyDgIDAgICAQEHCAMDDCEeBw8JKAEYKhcECgkLCgoL\
BRAXAwEzHA0bGAsoBwE1JAULDAwMDAYQFwMBMxwmJQwUDSogeh4eAR0CCA4GAwUFAgcUEiwQCA8J\
WBAZExoeDzIcFhMaHg8yHBYTGh4PMhwWExoeDzQwR20geh4eAR0CCA4GBwgYIwFHbSB6Hh4BHQII\
DgYHCBgjAUdtIHoeHgEdAQMFBQYHAwcIGCMBR20oATUkBg0PDg8HEBcDATMcJiUoBwE1JAQKCQsK\
CgsFEBcDARglEiYlEhoAAAT/tP+IBAYBGAB9AJgAtADOAAAhIicHMzIUKwEiNDsBEz4CNTQmIyIG\
BxUUBiMiJwczMhQrASI0OwETND4DNDU0JiMiBgcVFAYjIicHMzIUKwEiNDsBEz4CNTQuAiMiDgMH\
BiY3Njc2MzIWFz4BMzIXPgEzMhYXPgEzMhc+ATMyFhc+ATMyFhUUBicWMzI2Nz4GNTQmJyYjIg4B\
BwYVFBYFFjMyPgE3PgY1NCYnJiMiBgcOAhUUBRYzMjY3PgU1NCYnJiMiBgcGFRQeAQNSFhktNAsL\
4QsLS2gBAwIFBg4UFGtJFhktNAsL4QsLS2gBAgECBQYOFBRrSRYZLTQLC+ELC0toAQMCAQIFAwgM\
DwsZCgUbBTEPGCQjJAcdJiMvExIiGyMkBx0mIy8TEiIbIyQHHSYjHi1rTAMEEjIOAgMCAgIBAQcI\
AwMMIR4HDwn+wgMEDB8eCQIDAgICAQEHCAMDEzQLBQcD/ssDBBIyDgIDAwMBAQcIAwMTNAsPBAcg\
eh4eAR0CCA4GBwgYIwFHbSB6Hh4BHQEDBQUGBwMHCBgjAUdtIHoeHgEdAggOBgMFBQIHFBIsEAgP\
CVgQGRMaHg8yHBYTGh4PMhwWExoeDzQwR20oATUkBAoJCwoKCwUQFwMBGCUSJiUSGgMBGCoXBAoJ\
CwoKCwUQFwMBMxwNGxgLKAcBNSQFCwwMDAwGEBcDATMcJiUMFA0AA/+0/4gCwQEYAFcAcQCNAAAz\
IicHMzIUKwEiNDsBEz4CNTQuAiMiDgMHBiY3Njc2MzIWFz4BMzIXPgEzMhYXPgEzMhYVFAYjIicH\
MzIUKwEiNDsBEzQ+AzQ1NCYjIgYHFRQGJxYzMjY3PgU1NCYnJiMiBgcGFRQeAQUWMzI+ATc+BjU0\
JicmIyIGBw4CFRTIFhktNAsL4QsLS2gBAwIBAgUDCAwPCxkKBRsFMQ8YJCMkBx0mIy8TEiIbIyQH\
HSYjHi1rSRYZLTQLC+ELC0toAQIBAgUGDhQUa0wDBBIyDgIDAwMBAQcIAwMTNAsPBAcBSgMEDB8e\
CQIDAgICAQEHCAMDEzQLBQcDIHoeHgEdAggOBgMFBQIHFBIsEAgPCVgQGRMaHg8yHBYTGh4PNDBH\
bSB6Hh4BHQEDBQUGBwMHCBgjAUdtKAE1JAULDAwMDAYQFwMBMxwmJQwUDQIBGCoXBAoJCwoKCwUQ\
FwMBMxwNGxgLKAAAAv/b/4gDKwEYAHoAjwAAJTY3NjMyFhc+ATMyFhUUBiMiJwczMhQrASI0OwET\
PgM1NCYjIg4DBw4BIyImNTQ2PwI0IyIPAQYHJwYmPwE2NTQmIyIPAQYHBisBIj8BNiYjIgYHBiY3\
PgMzMhc2MzIXPgEzMh4DFRQPAQYVFDMyNz4BFxYzMjY3PgE1NCYnJiMiBgcGFRQWAa0xFBgiIyQH\
HSYjHi1rSRYZLTQLC+ELC0toAQEDAQUGBw8SDhgIGjwtFRkCAzQBFRsIQQgPJg0IBEMBDAkbCEQH\
CAQENQ0NQgQGCA0WJAUVBBQQIh8SNwskJC0JCykTChIPCwcFLwQIAgMPJdEDBBIyDgYHBwgDAxM0\
Cw8Jd2wYHRMaHg80MEdtIHoeHgEdAgUJCQUHCA0fGzUQNjgVFAYNB4gGDhSrFgEBAQ8IqwMDBggU\
rBEDARqnDQ8aOQgMCSUaMBIoKCgQGAYLDxMKDQ19CwkOAgg1OQE1JA8mERAXAwEzHCYlEhoAAv/b\
/2ADGQG4AFcAnwAANwYHBisBIj8BNiYjIgYHBiY3PgMzMhc2MzIXPgEzMh4DFRQPAQYVFDMyNz4F\
NzYWBw4CIyImNTQ2PwI0IyIPAQYHJwYmPwE2NTQmIyIHEyImNTQ2MzIWFRQHBhUUMzI+BzcjIiY1\
NDY7AT4BMzIWFRQGIyImNTQ3NjQjIg4HBzMyFhUUDgErAQ4BUAcIBAQ1DQ1CBAYIDRYkBRUEFBAi\
HxI3CyQkLQkLKRMKEg8LBwUvBAgCAwULBwwDDQEGFQYSFy0fFRkCAzQBFRsIQQgPJg0IBEMBDAkb\
CPUgMBcTEhcSChkLEA8LDQoODRQKNQkKCQhBFGk0IDAXExIXEgoZBwwKBwgFBgMGATYJCwUJBj8h\
dhURAwEapw0PGjkIDAklGjASKCgoEBgGCw8TCg0NfQsJDgIDCQYPBRIBCQ0LHx8aFRQGDQeIBg4U\
qxYBAQEPCKsDAwYIFP6fJiAaIhQPDgsHDQ4GERMlJDw3VScMCQgLS18mIBoiFA8OCwYcBQsKFA0a\
DR4GDAgFCQbFwQAAAAAB/37/YAJpAbgAewAAJSMOASMiJjU0NjMyFhUUBwYVFDMyPgc3IyImNTQ+\
AzsBPgEzMhYVFAYjIiY1NDc2NCMiBwYHFz4BMzIWFRQGIyImNTQ3NjQjIg4HBzMyFhQGKwEOASMi\
JjU0NjMyFhUUBwYVFDMyPgcBX5shdl8gMBcTEhcSChkLEA8LDQoODRQKNQkKAQMEBgNBFGk0IDAX\
ExIXEgoZJhcDAZsUaTQgMBcTEhcSChkHDAoHCAUGAwYBNgkLCwk/IXZfIDAXExIXEgoZCxAPCw0K\
Dw0U5sXBJiAaIhQPDgsHDQ4GERMlJDw3VScMCQMFBQQCS18mIBoiFA8OCwYccwwGAUtfJiAaIhQP\
DgsGHAULChQNGg0eBgwQDMXBJiAaIhQPDgsHDQ4GERMlJDw3VQAAAAAB/37/YAN0AbgAswAAEzM+\
ATMyFhUUBiMiJjU0NzY0IyIHBgcXPgEzMhYVFAYjIiY1NDc2NCMiDgcHMzIWFRQOASsBDgEjIiY1\
NDYzMhYVFAcGFRQzMj4HNyMOASMiJjU0NjMyFhUUBwYVFDMyPgc3Iw4BIyImNTQ2MzIWFRQHBhUU\
MzI+BzcjIiY1ND4DOwE+ATMyFhUUBiMiJjU0NzY0IyIOAgcGzJwUaTQgMBcTEhcSChkmFwMBmxRp\
NCAwFxMSFxIKGQcMCgcIBQYDBgE2CQoECQY/IXZfIDAXExIXEgoZCxAPCw0KDw0UCpshdl8gMBcT\
EhcSChkLEA8LDQoODRUKmyF2XyAwFxMSFxIKGQsQDwsNCg4NFAo1CQoBAwQGA0EUaTQgMBcTEhcS\
ChkOFQ4IBgIBDktfJiAaIhQPDgsGHHMMBgFLXyYgGiIUDw4LBhwFCwoUDRoNHgYMCAUJBsXBJiAa\
IhQPDgsHDQ4GERMlJDw3VSfFwSYgGiIUDw4LBw0OBhETJSQ7OFUnxcEmIBoiFA8OCwcNDgYREyUk\
PDdVJwwJAwUFBAJLXyYgGiIUDw4LBhwTJyIbCgAB/37/YASAAbgA5wAAARc+ATMyFhUUBiMiJjU0\
NzY0IyIHBgcXPgEzMhYVFAYjIiY1NDc2NCMiDgcHMzIWFAYrAQ4BIyImNTQ2MzIWFRQHBhUUMzI+\
BzcjDgEjIiY1NDYzMhYVFAcGFRQzMj4HNyMOASMiJjU0NjMyFhUUBwYVFDMyPgc3Iw4BIyImNTQ2\
MzIWFRQHBhUUMzI+BzcjIiY1ND4DOwE+ATMyFhUUBiMiJjU0NzY0IyIHBgcXPgEzMhYVFAYjIiY1\
NDc2NCMiDgcB2JwUaTQgMBcTEhcSChkmFwMBmxRpNCAwFxMSFxIKGQcMCgcIBQYDBgE2CQoKCT8h\
dl8gMBcTEhcSChkLEA8LDQoPDRQKmyF2XyAwFxMSFxIKGQsQDwsNCg4NFAqbIXZfIDAXExIXEgoZ\
CxAPCw0KDw0UCpshdl8gMBcTEhcSChkLEA8LDQoODRQKNQkKAQMEBgNBFGk0IDAXExIXEgoZJhcD\
AZsUaTQgMBcTEhcSChkHDAoHCAUGAwYBDwFLXyYgGiIUDw4LBhxzDAYBS18mIBoiFA8OCwYcBQsK\
FA0aDR4GDBAMxcEmIBoiFA8OCwcNDgYREyUkPDdVJ8XBJiAaIhQPDgsHDQ4GERMlIzw3VifFwSYg\
GiIUDw4LBw0OBhETJSQ8N1UnxcEmIBoiFA8OCwcNDgYREyUkPDdVJwwJAwUFBAJLXyYgGiIUDw4L\
BhxzDAYBS18mIBoiFA8OCwYcBQoLEw4ZDh0AAwAA/2AC3wG4ADcAewDFAAAzIiY1NDYzMhYVFAcW\
MzI2NTQuAycuAjU0NjMyFhUUBiMiLgE1NDcmIyIGFRQeAhceARUUJQYuAT8BLgIjIgYjIg4BBwYn\
Jjc+ATceATMyNjMyFhcWFA8BDgEVFB4BFxY+AScuATU0NjMyFRQHBiMiIy4CIyIGBSImNTQ2MzIW\
FRQHDgEeARUUFjI+BzcjIi4BNTQ2OwE+ATMyFhUUBiMiJjU0NzY0IyIOBwczMhYUBisBDgFQHjIS\
DA4XDAYYFiEDDAUXAxQYFDctIjYWEAgQCwUQDg8ZERIeBRsXASYGCwEFrgQJCgcGHAYFEBIFEAUD\
BwsMARglDiAoBwQLBwsHmgICGioNBQkFAgMkFAwmJhITAwMSIxgIChL+vSAwFxMSFxIEAQECBhYQ\
DwsNCg4NFAo1BgkECQhBFGk0IDAXExIXEgoZBwwKBwgFBgMGATYJCgoJPyF2KxsQFg0LGAwSFhIJ\
DA0EDgINEh4PIy0kGBAYCQ8KCAgUEQ0JEwwRAxIfFVoDBAgNBr8CAgEBGB8EDQsIEx4uBAIBCAEB\
AREHowMFAgcDBwsDBA0GCAgUCxM3KxQJAQgGB6smIBoiFA8OCwIFBAYDCAYGERMlJDw3VScGCQYI\
C0tfJiAaIhQPDgsGHAULChQNGg0eBgwQDMXBAAAAAgAF//sB/AGaAAkALAAAAQ8BBhUUMzI2NwcO\
ASMiJjU0PwEjNTM/AQc3MhU2MzIWFRQGIiY1NDcGDwEjATZ/OQIUGEQSDCkyHyIiAzdpcxZZJpgZ\
IDUYHRggFgk3EEJIAQkHuAgDFRcPKBkUJBoLC7MgSi54Ci0pHBUSGxEOEhMPJ9gAAQAA//0BtQDU\
AC8AACUyNTQnBiImNT4BMzIWFRQHBiMiLwEmIyIVFBc2MzIWFRQGByInJjU0NzYzFh8BFgFwLRoQ\
HBQBFwkkLSkXHiYeohoRLhkQDw0VFA0dGBwoFiIqF6IcMTkgExAWDQ4WMzUzJBUVehI6IBIQFw4P\
EgIaIi0zJBMCEHoTAAEAAP/NAbUBAwA2AAAXIiY1NDc2MxYfATUzFRcWMzI2NTQnBiMiNT4BMzIW\
FRQHBiMiLwEVIzUnJiMiBhUUFzYzMhUUTSAtKBYgKBcuHlwiDxUcFhQSHAEPCSAtKRccJB4uHlwg\
DxYcFRQTHANDJjMkEwIQJGmARxcpHCcQDBsPFUImMyQVFSRsg0cWKB4nDwwdIAABAA0AAAJFAOAA\
CwAANyc3FzcXNxcHJwcnIhWOZXhqTRaSaXRpLhmZfHx8VBehfHx8AAAAAQAN/8sCRQERABMAACUH\
JwcnNxc3NTMXNxc3FwcnBxUjARZAaUsVjmUWGwFGak8UkmkZG0ZGfE4ZmXwXlntKfFUYoXwblgAA\
AQAAAAABGAEYAAsAADM1IzUzNTMVMxUjFXt7eyJ7e3sie3siewAAAAEAAAAAATYBcgAKAAAxNT4E\
NzMUBiQxTDQ0Dx7APAcPKz1vSY7aAAAB//8AAAEtAKAAHQAANz4CMzIeARcWMzI3NhYHDgIjIi4B\
JyYjIgcGJgEJECkcGCYmDwkKHhgEDgIIESkcGCQlEgcIHR0FDUYZISAhMQoGJAYHBxkiHyExCgQj\
BggAAAABAAAAAAEsASwABwAAMREhESM1IxUBLCPmASz+1LS0AAEAAAAAAPoBwgAGAAAzAzMbATMD\
aWkoVVUoaQHC/pgBaP4+AAIAAAAAAMgAyAAHAA8AADYyNjQmIgYUFiImNDYyFhRFPiwsPix0Ujs7\
UjsZLD4sLD5FO1I7O1IAAf84AAAAyADIAAsAACM0NjIWFSM0JiIGFch2pHYeYJRgUnZ2UkpgYEoA\
AAACAAAAAAC0ASwABwAVAAA2MjY0JiIGFBc1LgE1NDYyFhUUBgcVSx4bGx4bGB0rN0Y3Kx14NTY1\
NTatZAg1Jyg8PCgnNQhkAAACAAAAAADIASwADwAfAAA3LgE1NDYyFhUUBgcdASM1Nz4BNTQmIgYV\
FBYXPQEzFVQkMDtSOzAkICAZIiw+LCIZIGYFOCUpOzspJTgFAWVlGQYqGh8sLB8aKgYBSUkAAAAE\
AAD//AP0An8AhwCRAJ0ApwAANz4BNTQuAScuATU0PgI/Ag4BFRQzMjcXDgEjIiY1ND4CMzIWFRQG\
IyImJzceATMyNTQuAicHBhUUHgIVFAYPAR4CMzoBMzI3JjU0NzYzMhYVFAcGBx4BMzI2NTQ2Ny4C\
PQEeARUUBiMiJwYjIi4BJw4BIiYnJiMiDgEHBiMiNTQ2BSImNDYzMhYUBiU+ATU0JyYjIgYVFAU2\
NTQmJw4BFRSYNkUBAgIDUgMEBQECPWJqIB4dGhUpJR4tHz5wSH1yMi4cNhIYERQUMwwcQC0bCR0i\
HR8QEA4pHwwDCAIQIyEcIkwbIwodPBMgGxYxQ10ggV66tFFCQSMkPCEzFg4sKCAbHBoSChQZBloh\
CjADXAsTEwsMEhH+DzMkBAUVHC4BPFoXEj8wWhg/IAQHBwQIdCIFDg4MBASlBGMsIzwNQi8mGiFH\
RCxRNzA1MCsOHhEyChoiGgJCJBseNiEsFSZPFBQKKRoeNSg1JS4rICETOTAXEioZUl8ZLFk0BgE8\
sWtGXzk6FRQSJhkWIC0LFQQ6Bw04TxIYEhIYEoAvLxsHDhI5Kx50BYEiSRUdWEQ/AAAAAAIADAAK\
AdMBzwAKAI8AACU0JiMiBhQWMzI2Jw4BIyImNDYzMhYXNjU0JyYjIiY0NjMyFx4BFxYzMjU0Jy4B\
NTQ2MzIWFRQGBxQzMjc+ATc2MzIWFRQGIyIGBwYVFDMyNjMyFhQGIyImIyIGFRQXHgEXFhUUBiMi\
Jy4BJyYjIhUUFhUUBiMiJjQ2NTQjIgcOAQcGIyImNTQ3NjMyNzY1NAEWGA8QFRYPEBeJGSYOGRsa\
GQ0qGCUMFBgdHBkXEhALAxQLEhQBAiceFBIbIwEWEA0RAQ0MGhMeGxIbFQ0QIRsrDhwbHRkPJxQX\
EgsUOA0OGRcTFAwBExEKEiogExIdJhcNDhIDERIMFBoNDBYjEg3uEBQTIhYVCgElGSobJQIDFg4K\
ExwoHQwLPhYNGA0IFycPFxobFhEjGSoQEzgPDhsUESMGCw4PFicdKBomCAoWChIDCw0ZExsOCzkV\
Dx8eMBMUGBokMRckDhI9DAcWFBgODRINDBoAAAADAAD/BgH0APoABwAPABcAADYUFjI2NCYiAjQ2\
MhYUBiI2IiY0NjIWFC14qnh4qqWS0JKS0IEyIyMyI1WqeHiqeP7L0JKS0JK+IzIjIzIAAAIAAP8G\
AfQA+gAHAA8AADYUFjI2NCYiAjQ2MhYUBiIteKp4eKqlktCSktBVqnh4qnj+y9CSktCSAAAAAAMA\
AP6iAfQBXgARABcAHQAAEzMVHgEVFAYHFSM1LgE1NDY3GQEOARQWFz4BNCYn5C1gg4NgLWCEg2FN\
amp6TWlpTQFeZAqOYmGPCmRlCI9iY44I/jsBmAh1nnUICXSedAkAAAACAAD/BgHSAPoAIQApAAAl\
FhUUBwYjIicmIyIGFBYzMjc2MzIXFhUUBwYjIiY0NjMyAiImNDYyFhQBzwILBQYNCjN3VXh4VXgy\
BhIHAwwDQJVokpJolHsyIyMyI4IGBA8GAw5feKp4Xw0CBwwGBniS0JL+yiMyIyMyAAAAAQAA/wYB\
0gD6ACEAACUWFRQHBiMiJyYjIgYUFjMyNzYzMhcWFRQHBiMiJjQ2MzIBzwILBQYNCjN3VXh4VXgy\
BhIHAwwDQJVokpJolIIGBA8GAw5feKp4Xw0CBwwGBniS0JIAAAIAAP6iAdIBXgAkACoAACUWFxYV\
FAcGIyInJicRNjc2MzIXFhUUBwYHFSM1LgE1NDY3NTMDEQ4BFBYBEYQ6AgsFBg0KLWZlLgYSBwMM\
AzyCLWCEg2EtLU5pafkKbQYEDwYDDlQK/mgHVw0CBwwGBnAHZWUIj2Jjjghl/dYBmAh1nnUAAAEA\
AP/EAHgAPAAHAAAWIiY0NjIWFFUyIyMyIzwjMiMjMgAAAAEAAP6iAC0BXgADAAATESMRLS0BXv1E\
ArwAAAACAAD9EgFKAL4AAwAPAAA3FSE1JTMVITUzESMRIRUjHgEO/tQeAQ4eHv7yHkaMjHgyMvxU\
AmIyAAEAAAAAAlYBcgALAAA1Nxc3FzcXAScHJweJVFZSryL+/FRWUzVBuXNzcekW/qR0dHBHAAAB\
/+oAvQEQATcAGQAAET4BMzIWMjc2MzIVFAcOASMiJiIHBiMiNTQYIRwUVSgUAwcMFhghHBRVKBQE\
BwsBDhgRPRQDCQwWGBE9FAQKDAAAAAAADgCuAAEAAAAAAAAAfgD+AAEAAAAAAAEABwGNAAEAAAAA\
AAIABwGlAAEAAAAAAAMAJAH3AAEAAAAAAAQABwIsAAEAAAAAAAUACQJIAAEAAAAAAAYABwJiAAMA\
AQQJAAAA/AAAAAMAAQQJAAEADgF9AAMAAQQJAAIADgGVAAMAAQQJAAMASAGtAAMAAQQJAAQADgIc\
AAMAAQQJAAUAEgI0AAMAAQQJAAYADgJSAEMAbwBwAHkAcgBpAGcAaAB0ACAAXAAyADUAMQAgADIA\
MAAxADgAIABKAGUAYQBuAC0ARgByAGEAbgBjAG8AaQBzACAATQBvAGkAbgBlAC4AIABUAGgAaQBz\
ACAAZgBvAG4AdAAgAGkAcwAgAGwAaQBjAGUAbgBzAGUAZAAgAHUAbgBkAGUAcgAgAHQAaABlACAA\
UwBJAEwAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUAIABcACgAaAB0AHQAcAA6\
AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAFwAKQAuAABDb3B5cmln\
aHQgXDI1MSAyMDE4IEplYW4tRnJhbmNvaXMgTW9pbmUuIFRoaXMgZm9udCBpcyBsaWNlbnNlZCB1\
bmRlciB0aGUgU0lMIE9wZW4gRm9udCBMaWNlbnNlIFwoaHR0cDovL3NjcmlwdHMuc2lsLm9yZy9P\
RkxcKS4AAGEAYgBjADIAcwB2AGcAAGFiYzJzdmcAAFIAZQBnAHUAbABhAHIAAFJlZ3VsYXIAAEYA\
bwBuAHQARgBvAHIAZwBlACAAMgAuADAAIAA6ACAAYQBiAGMAMgBzAHYAZwAgADoAIAAyADcALQAx\
ADEALQAyADAAMQA4AABGb250Rm9yZ2UgMi4wIDogYWJjMnN2ZyA6IDI3LTExLTIwMTgAAGEAYgBj\
ADIAcwB2AGcAAGFiYzJzdmcAAFYAZQByAHMAaQBvAG4AIAAgAABWZXJzaW9uICAAAGEAYgBjADIA\
cwB2AGcAAGFiYzJzdmcAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwAAAAEAAgEC\
AAMBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0B\
HgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6\
ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYB\
VwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFz\
AXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYAGLm5vZGVmB3VuaUUwMDAHdW5pRTAyMgd1bmlFMDIz\
B3VuaUUwMjQHdW5pRTAzMAd1bmlFMDM4B3VuaUUwMzkHdW5pRTA0Mwd1bmlFMDQ1B3VuaUUwNDYH\
dW5pRTA0Nwd1bmlFMDQ4B3VuaUUwNTAHdW5pRTA1Qwd1bmlFMDYyB3VuaUUwNjkHdW5pRTA3QQd1\
bmlFMDdCB3VuaUUwN0MHdW5pRTA3RAd1bmlFMDgwB3VuaUUwODEHdW5pRTA4Mgd1bmlFMDgzB3Vu\
aUUwODQHdW5pRTA4NQd1bmlFMDg2B3VuaUUwODcHdW5pRTA4OAd1bmlFMDg5B3VuaUUwOEEHdW5p\
RTA4Qgd1bmlFMDhDB3VuaUUwOTQHdW5pRTA5NQd1bmlFMEEwB3VuaUUwQTEHdW5pRTBBMgd1bmlF\
MEEzB3VuaUUwQTQHdW5pRTBBOQd1bmlFMEIzB3VuaUUxMDEHdW5pRTFCOQd1bmlFMUJCB3VuaUUx\
RTcHdW5pRTI0MAd1bmlFMjQxB3VuaUUyNDIHdW5pRTI0Mwd1bmlFMjQ0B3VuaUUyNDUHdW5pRTI0\
Ngd1bmlFMjQ3B3VuaUUyNDgHdW5pRTI0OQd1bmlFMjYwB3VuaUUyNjEHdW5pRTI2Mgd1bmlFMjYz\
B3VuaUUyNjQHdW5pRTI4MAd1bmlFMjgxB3VuaUUyODIHdW5pRTI4Mwd1bmlFNEEwB3VuaUU0QTIH\
dW5pRTRBNAd1bmlFNEE4B3VuaUU0QUMHdW5pRTRDMAd1bmlFNENFB3VuaUU0RTEHdW5pRTRFMgd1\
bmlFNEUzB3VuaUU0RTQHdW5pRTRFNQd1bmlFNEU2B3VuaUU0RTcHdW5pRTRFOAd1bmlFNEU5B3Vu\
aUU0RUEHdW5pRTRFRQd1bmlFNTAwB3VuaUU1MDEHdW5pRTUyMAd1bmlFNTIxB3VuaUU1MjIHdW5p\
RTUyNAd1bmlFNTI1B3VuaUU1MjkHdW5pRTUyQQd1bmlFNTJCB3VuaUU1MkMHdW5pRTUyRAd1bmlF\
NTJGB3VuaUU1MzAHdW5pRTUzMQd1bmlFNTM5B3VuaUU1NjYHdW5pRTU2Nwd1bmlFNTY5B3VuaUU1\
NkMHdW5pRTU2RAd1bmlFNTgyB3VuaUU1RDAHdW5pRTVFMgd1bmlFNjEwB3VuaUU2MTIHdW5pRTYx\
NAd1bmlFNjE4B3VuaUU2MjQHdW5pRTYzMAd1bmlFNjUwB3VuaUU2NTUHdW5pRTkxMAd1bmlFOTEx\
B3VuaUU5MTIHdW5pRTkxNAd1bmlFOTE1B3VuaUU5MTgHdW5pRTkyMAd1bmlFOTI1B3VuaUU5NUQH\
dW5pRUEwMgd1bmlFQUE0AAAAAAH//wACAAEAAAAAAAAADAAUAAQAAAACAAAAAQAAAAEAAAAAAAEA\
AAAA1+feHQAAAADRlyIXAAAAANgjLVI=\
")'
|
Changes to font/abc2svg.sfd.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | SplineFontDB: 3.0 FontName: abc2svg FullName: abc2svg FamilyName: abc2svg Weight: Regular ItalicAngle: 0 UnderlinePosition: 0 UnderlineWidth: 0 Ascent: 819 Descent: 205 InvalidEm: 0 LayerCount: 2 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 | > > | > > > | | > > > | | < | | | | > > > | > > > | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 | SplineFontDB: 3.0 FontName: abc2svg FullName: abc2svg FamilyName: abc2svg Weight: Regular Copyright: Copyright \\251 2018 Jean-Francois Moine. This font is licensed under the SIL Open Font License \\(http://scripts.sil.org/OFL\\). Version: ItalicAngle: 0 UnderlinePosition: 0 UnderlineWidth: 0 Ascent: 819 Descent: 205 InvalidEm: 0 LayerCount: 2 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: 1543339218 PfmFamily: 17 TTFWeight: 400 TTFWidth: 5 LineGap: 92 VLineGap: 92 Panose: 2 0 5 3 0 0 0 0 0 0 OS2TypoAscent: 0 OS2TypoAOffset: 1 OS2TypoDescent: 0 OS2TypoDOffset: 1 OS2TypoLinegap: 92 OS2WinAscent: 0 OS2WinAOffset: 1 OS2WinDescent: 0 OS2WinDOffset: 1 HheadAscent: 0 HheadAOffset: 1 HheadDescent: 0 HheadDOffset: 1 OS2Vendor: 'PfEd' MarkAttachClasses: 1 DEI: 91125 LangName: 1033 Encoding: Custom Compacted: 1 UnicodeInterp: none NameList: Adobe Glyph List DisplaySize: -96 AntiAlias: 1 FitToEm: 1 WinInfo: 48 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: 128 128 StartChar: .nodef Encoding: 0 0 0 Width: 400 Flags: M LayerCount: 2 Fore SplineSet 0 0 m 1 0 400 l 1 401 400 l 1 401 0 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: space Encoding: 1 32 1 Width: 600 Flags: HM LayerCount: 2 Fore SplineSet 0 0 m 1053 EndSplineSet Validated: 1 EndChar StartChar: uniE000 Encoding: 2 57344 2 Width: 87 Flags: MW LayerCount: 2 Fore SplineSet 0 515 m 9 0 517 l 1 35 533 53 565 53 608 c 0 53 642 42 692 18 758 c 0 |
| ︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 | 29 39 0 91 0 160 c 0 0 193 5 228 18 269 c 0 42 335 53 385 53 419 c 0 53 463 35 499 0 515 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE047 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 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 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | 29 39 0 91 0 160 c 0 0 193 5 228 18 269 c 0 42 335 53 385 53 419 c 0 53 463 35 499 0 515 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE022 Encoding: 3 57378 3 Width: 330 Flags: MW LayerCount: 2 Fore SplineSet -80 20 m 5 410 20 l 5 410 -20 l 5 -80 -20 l 5 -80 20 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE023 Encoding: 4 57379 4 Width: 531 Flags: MW LayerCount: 2 Fore SplineSet -80 20 m 1 610 20 l 5 610 -20 l 1 -80 -20 l 1 -80 20 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE024 Encoding: 5 57380 5 Width: 210 Flags: HMW LayerCount: 2 Fore SplineSet -80 20 m 1 290 20 l 1 290 -20 l 1 -80 -20 l 1 -80 20 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE030 Encoding: 6 57392 6 Width: 35 Flags: HMW LayerCount: 2 Fore SplineSet 0 1000 m 5 35 1000 l 5 35 0 l 5 0 0 l 5 0 1000 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE038 Encoding: 7 57400 7 Width: 35 Flags: HMW LayerCount: 2 Fore SplineSet 0 1000 m 1 35 1000 l 1 35 500 l 1 0 500 l 1 0 1000 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE039 Encoding: 8 57401 8 Width: 35 Flags: HMW LayerCount: 2 Fore SplineSet 0 1100 m 1 35 1110 l 5 35 760 l 1 0 760 l 1 0 1100 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE043 Encoding: 9 57411 9 Width: 100 Flags: W HStem: 320 100<8.4375 91.5625> 570 100<8.4375 91.5625> VStem: 0 100<328.438 411.562 578.438 661.562> LayerCount: 2 Fore SplineSet 50 570 m 3 22 570 0 592 0 620 c 3 0 648 22 670 50 670 c 3 78 670 100 648 100 620 c 3 100 592 78 570 50 570 c 3 50 320 m 7 22 320 0 342 0 370 c 7 0 398 22 420 50 420 c 7 78 420 100 398 100 370 c 7 100 342 78 320 50 320 c 7 EndSplineSet Validated: 1 EndChar StartChar: uniE045 Encoding: 10 57413 10 Width: 1059 Flags: HMW LayerCount: 2 Fore SplineSet 590 0 m 24 590 160 l 24 620 160 l 0 647 83 701 25 770 25 c 0 818 25 870 42 870 90 c 0 870 135 766 163 722 175 c 0 661 192 590 212 590 286 c 0 590 380 665 430 740 430 c 0 791 430 809 423 840 405 c 0 870 430 l 24 900 430 l 24 907 275 l 24 877 275 l 0 857 351 806 405 740 405 c 0 702 405 652 376 652 338 c 0 652 285 733 277 785 263 c 0 878 238 940 209 940 136 c 0 940 62 879 0 770 0 c 0 718 0 688 9 655 32 c 0 620 0 l 24 590 0 l 24 1010 0 m 3 982 0 960 22 960 50 c 3 960 78 982 100 1010 100 c 3 1038 100 1060 78 1060 50 c 3 1060 22 1038 0 1010 0 c 3 505 0 m 3 477 0 455 22 455 50 c 3 455 78 477 100 505 100 c 3 533 100 555 78 555 50 c 3 555 22 533 0 505 0 c 3 180 390 m 24 180 30 l 24 220 30 l 0 300 30 350 100 350 210 c 0 350 320 300 390 220 390 c 0 180 390 l 24 0 0 m 0 0 30 l 24 70 30 l 24 70 390 l 24 0 390 l 24 0 420 l 24 220 420 l 0 360 420 470 361 470 210 c 0 470 60 370 0 220 0 c 0 147 0 73 0 0 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE046 Encoding: 11 57414 11 Width: 1061 Flags: HMW LayerCount: 2 Fore SplineSet 770 0 m 0 636 0 550 70 550 210 c 0 550 350 656 430 770 430 c 0 818 430 838 425 875 400 c 0 905 430 l 24 935 430 l 24 943 264 l 24 910 260 l 0 886 354 841 400 780 400 c 0 700 400 670 305 670 215 c 0 670 125 700 30 780 30 c 0 855 30 906 86 928 165 c 0 963 155 l 0 939 65 890 0 770 0 c 0 1010 0 m 3 982 0 960 22 960 50 c 3 960 78 982 100 1010 100 c 3 1038 100 1060 78 1060 50 c 3 1060 22 1038 0 1010 0 c 3 505 0 m 3 477 0 455 22 455 50 c 3 455 78 477 100 505 100 c 3 533 100 555 78 555 50 c 3 555 22 533 0 505 0 c 3 180 390 m 24 180 30 l 24 220 30 l 0 300 30 350 100 350 210 c 0 350 320 300 390 220 390 c 0 180 390 l 24 0 0 m 0 0 30 l 24 70 30 l 24 70 390 l 24 0 390 l 24 0 420 l 24 220 420 l 0 360 420 470 361 470 210 c 0 470 60 370 0 220 0 c 0 147 0 73 0 0 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE047 Encoding: 12 57415 12 Width: 480 Flags: HMW LayerCount: 2 Fore SplineSet 398 338 m 3 376 338 358 356 358 378 c 3 358 400 376 418 398 418 c 3 420 418 438 400 438 378 c 3 438 356 420 338 398 338 c 3 36 278 m 3 14 278 -4 296 -4 318 c 3 -4 340 14 358 36 358 c 3 58 358 76 340 76 318 c 3 76 296 58 278 36 278 c 3 167 91 m 0 167 114 186 137 214 137 c 0 240 137 263 116 263 94 c 0 263 78 251 61 219 51 c 1 235 35 259 28 283 28 c 0 331 28 375 59 375 111 c 0 375 135 369 162 337 194 c 1 214 295 l 1 7 5 l 1 -36 37 l 1 173 330 l 1 47 429 11 500 11 570 c 0 11 618 54 651 78 671 c 1 110 687 139 690 167 690 c 0 235 690 271 641 271 601 c 0 271 578 252 555 224 555 c 0 198 555 175 576 175 598 c 0 175 614 187 631 219 641 c 1 203 657 179 664 155 664 c 0 107 664 63 633 63 581 c 0 63 557 69 530 101 498 c 1 223 397 l 1 435 691 l 1 478 660 l 1 265 363 l 1 391 263 427 192 427 122 c 0 427 74 384 41 360 21 c 1 328 5 299 2 271 2 c 0 203 2 167 51 167 91 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE048 Encoding: 13 57416 13 Width: 862 Flags: W HStem: -67 43<422.573 472 512 561.427> 176 40<122 261.794 360 472 512 624 722.206 862> 417 42<420.937 472 512 558.146> VStem: 260 100<86.3906 176 216 307.453> 472 40<-204 -64.8472 -24 176 216 416 456.872 596> 624 100<86.3906 176 216 306.031> CounterMasks: 1 1c LayerCount: 2 Fore |
| ︙ | ︙ | |||
192 193 194 195 196 197 198 | 412 409 364 361 360 216 c 1 472 216 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE050 | | | < < | | > > | | | < | < | > | | | | | < | > | < | > | | < | | | | | > | > | < | | | > | | > | < | | | < < < < < | | | 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 | 412 409 364 361 360 216 c 1 472 216 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE050 Encoding: 14 57424 14 Width: 779 Flags: HMW LayerCount: 2 Fore SplineSet 364 851 m 0 358.834831965 811.556898639 356.976973124 782.035724861 356.976973124 751.255004513 c 0 356.976973124 716.483564406 359.347803652 680.10480549 362 626 c 1 443 681 551 791 551 896 c 4 551 942 546 1011 497 1023 c 5 417 1013 376 939 364 851 c 0 449 -250 m 9 472 -486 l 0 472.010742188 -487.030273438 472.015625 -488.056640625 472.015625 -489.081054688 c 0 472.015625 -586.490234375 422.876582453 -657 316 -657 c 0 204 -657 139 -593 139 -509 c 0 139 -452 184 -392 253 -392 c 0 315 -392 365 -436 365 -495 c 0 365 -554 317 -594 255 -595 c 1 275 -606 298 -620 324 -620 c 0 376.540978621 -620 435.012695312 -591.5 435.012695312 -489.685546875 c 0 435.012695312 -488.795898438 435.008789062 -487.900390625 435 -487 c 0 412 -254 l 17 398.364449186 -255.357092735 384.770660292 -256.025113783 371.270180398 -256.025113783 c 0 175.860782244 -256.025113783 5.68434188608e-14 -116.071979914 0 100 c 0 0 188 25 277 58 335 c 8 131 463 275 562 326 600 c 1 317 704 313 787 313 852 c 0 313 1052 406 1152 494 1160 c 1 570 1115 592 1005 592 873 c 0 592 688 538 598 379 473 c 1 399 266 l 0 409.453125 267.208007812 419.672851562 267.79296875 429.6484375 267.79296875 c 0 584.774414062 267.79296875 679 144.540865361 679 -3 c 0 679 -124 618 -220 449 -250 c 9 601 -23 m 0 601 51.748046875 536.096679688 141.236328125 423.16015625 141.236328125 c 0 419.477539062 141.236328125 415.756835938 140.158203125 412 140 c 1 445 -215 l 1 575 -189 601 -121 601 -23 c 0 375 138 m 1 306 124 251 75 251 8 c 0 251 -35 281 -84 319 -108 c 1 246 -91 195 -56 195 46 c 0 195 176 270 236 361 261 c 1 344 450 l 1 164 306 93 226 92 82 c 1 94.8109172159 -111.016315493 218.774420218 -221.508405886 375.873991765 -221.508405886 c 0 386.441654234 -221.508405886 397.159253713 -221.008441515 408 -220 c 0 375 138 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE05C Encoding: 15 57436 15 Width: 722 Flags: W HStem: -516 36<404.33 535.95> -88 35<438.435 550.878> 50 35<444.881 548.647> 475 37<397.951 540.179> VStem: 0 123<-514 510> 186 28<-514 -6 15 510> 290 157<-427.748 -329.281 326.281 424.154> 614 108<-378.538 -189.443 184.402 376.99> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
321 322 323 324 325 326 327 | 0 -514 l 1 0 510 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE062 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 0 -514 l 1 0 510 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE062 Encoding: 16 57442 16 Width: 703 Flags: W HStem: -170 101<618.042 698.676> -113 224<91.5691 210.802> 72 102<613.779 693.281> 215 40<163.491 326.905> VStem: 19 241<-54.3228 59.215> 422 121<-211.326 98.8623> 610 97<-162.037 -77.8382 83.7117 162.856> LayerCount: 2 Fore SplineSet 19 29 m 0x5e 19 161 125 255 261 255 c 0 378 255 440 220 496 146 c 0 528.135801023 103.534834363 543 31 543 -30 c 0 543 -193 509 -303 392 -412 c 24 250 -545 118 -593 -70 -603 c 1 72 -565 193 -517 296 -414 c 0 362.272166103 -347.727833897 383 -307 408 -201 c 0 417.095703125 -162.434570312 422 -69 422 -36 c 0 422 48 418 100 376 150 c 0 339.06264499 193.973041679 314 215 245 215 c 0 168 215 91 170 67 62 c 1 97 100 116 111 153 111 c 4 214 111 260 62 260 -1 c 0 260 -33 248 -61 221 -83 c 1 198 -104 166 -113 139 -113 c 0 71 -113 19 -52 19 29 c 0x5e 661 -170 m 0x9e 632 -170 610 -150 610 -119 c 0 610 -90 629 -69 656 -69 c 4 683 -69 707 -90 707 -119 c 0 707 -148 687 -170 661 -170 c 0x9e 655 72 m 0x3e 625 72 605 94 605 127 c 0 605 156 626 174 654 174 c 4 681 174 702 153 702 127 c 0 702 94 682 72 655 72 c 0x3e EndSplineSet Validated: 1 EndChar StartChar: uniE069 Encoding: 17 57449 17 Width: 470 Flags: W VStem: 0 150<-250 250> 220 150<-250 250> LayerCount: 2 Fore SplineSet 220 250 m 1 |
| ︙ | ︙ | |||
383 384 385 386 387 388 389 | 0 -250 l 1 0 250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE07A | | | 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | 0 -250 l 1 0 250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE07A Encoding: 18 57466 18 Width: 779 Flags: W HStem: -502 30<205.501 304.477> -204 31<214.246 323 357 391.941> 113 95<243.207 289> 118 99<329.167 431.634> VStem: 0 76<-48.8921 170.465> 111 181<-436.162 -326.772> 154 43<-16.0423 68.9973> 249 38<502.74 719.447> 338 32<-437.341 -205.711> 442 32<651.371 785.751> 502 41<-92.0505 45.5518> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
445 446 447 448 449 450 451 | 442 749 433 790 401 820 c 1 331 792 299 728 290 658 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE07B | | | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | 442 749 433 790 401 820 c 1 331 792 299 728 290 658 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE07B Encoding: 19 57467 19 Width: 782 Flags: W HStem: -413 29<322.95 428.387> -70 28<351.623 440.673> 40 28<355.737 438.873> 380 30<318.164 432.756> VStem: 0 98<-411 408> 149 22<-411 -5 12 408> 232 126<-344.637 -259.418 257.61 342.509> 491 87<-311.532 -144.136 138.096 308.532> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
513 514 515 516 517 518 519 | 0 -411 l 1 0 408 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE07C | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | 0 -411 l 1 0 408 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE07C Encoding: 20 57468 20 Width: 807 Flags: W HStem: -136 81<491.982 561.648> -102 188<67.2812 172.801> 58 81<488.633 557.386> 170 34<129.66 260.591> VStem: 15 195<-48.9031 47.6335> 340 94<-168.512 89.0947> 488 78<-131.953 -59.6448 63.9747 133.311> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 | 500 58 484 76 484 102 c 0 484 125 499 139 523 139 c 0 545 139 562 123 562 102 c 0 562 76 546 58 524 58 c 0x3e EndSplineSet Validated: 1 EndChar StartChar: uniE080 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | 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 | 500 58 484 76 484 102 c 0 484 125 499 139 523 139 c 0 545 139 562 123 562 102 c 0 562 76 546 58 524 58 c 0x3e EndSplineSet Validated: 1 EndChar StartChar: uniE07D Encoding: 21 57469 21 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet 80 119 m 1 55 105 45 90 45 70 c 0 45 42 68 20 88 20 c 0 113 20 125 44 125 64 c 0 125 84 103 102 80 119 c 1 123 220 m 28 105 220 90 209 90 189 c 0 90 169 99 159 122 141 c 1 145 148 157 161 157 185 c 0 157 205 144 220 123 220 c 28 90 0 m 0 41 0 0 30 0 70 c 0 0 104 32 118 69 130 c 1 49 148 40 157 40 180 c 0 40 215 70 240 110 240 c 0 154 240 200 220 200 180 c 0 200 156 178 139 140 129 c 1 164 110 180 90 180 70 c 0 180 27 140 0 90 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE080 Encoding: 22 57472 22 Width: 430 Flags: HMW LayerCount: 2 Fore SplineSet 138 0 m 1 138 -130 168 -218 215 -218 c 1 260 -218 292 -130 292 0 c 1 292 130 268 218 215 218 c 1 165 218 138 130 138 0 c 1 0 3 m 1 0 140 95 250 215 250 c 1 335 250 430 140 430 0 c 1 430 -140 335 -250 215 -250 c 1 95 -250 0 -140 0 3 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE081 Encoding: 23 57473 23 Width: 290 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 25 100 250 l 25 |
| ︙ | ︙ | |||
596 597 598 599 600 601 602 | 115 100 l 29 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE082 | | | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 | 115 100 l 29 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE082 Encoding: 24 57474 24 Width: 400 Flags: HMW HStem: -250 500 VStem: 0 400 LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
631 632 633 634 635 636 637 | 28 25 0 60 0 128 c 0 0 213 102 250 199 250 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE083 | | | 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 | 28 25 0 60 0 128 c 0 0 213 102 250 199 250 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE083 Encoding: 25 57475 25 Width: 380 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 102 170 m 1 |
| ︙ | ︙ | |||
668 669 670 671 672 673 674 | 252 177 223 213 175 213 c 0 131 213 109 193 102 170 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE084 | | | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 | 252 177 223 213 175 213 c 0 131 213 109 193 102 170 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE084 Encoding: 26 57476 26 Width: 400 Flags: HMW HStem: -250 500 VStem: 0 400 LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
699 700 701 702 703 704 705 | 325 -160 l 5 325 -209 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE085 | | | 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 | 325 -160 l 5 325 -209 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE085 Encoding: 27 57477 27 Width: 400 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 18 -95 m 0 |
| ︙ | ︙ | |||
734 735 736 737 738 739 740 | 25 -217 0 -176 0 -152 c 0 0 -135 3 -113 18 -95 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE086 | | | 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 | 25 -217 0 -176 0 -152 c 0 0 -135 3 -113 18 -95 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE086 Encoding: 28 57478 28 Width: 385 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 200 -210 m 0 |
| ︙ | ︙ | |||
764 765 766 767 768 769 770 | 1 133 74 250 200 250 c 0 257 250 298 244 340 205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE087 | | | 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 | 1 133 74 250 200 250 c 0 257 250 298 244 340 205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE087 Encoding: 29 57479 29 Width: 400 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 97 161 m 0 |
| ︙ | ︙ | |||
787 788 789 790 791 792 793 | 305 125 280 121 268 121 c 0 194 121 173 161 97 161 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE088 | | | 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 | 305 125 280 121 268 121 c 0 194 121 173 161 97 161 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE088 Encoding: 30 57480 30 Width: 400 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 154 -42 m 1 |
| ︙ | ︙ | |||
814 815 816 817 818 819 820 821 822 823 | 294 250 370 197 370 130 c 0 370 77 342 46 280 16 c 1 351 -16 388 -46 388 -121 c 4 388 -197 293 -250 194 -250 c 1 93 -250 0 -194 0 -130 c 0 0 -77 50 -44 108 -16 c 1 EndSplineSet EndChar StartChar: uniE089 | > | | 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | 294 250 370 197 370 130 c 0 370 77 342 46 280 16 c 1 351 -16 388 -46 388 -121 c 4 388 -197 293 -250 194 -250 c 1 93 -250 0 -194 0 -130 c 0 0 -77 50 -44 108 -16 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE089 Encoding: 31 57481 31 Width: 385 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 185 210 m 0 |
| ︙ | ︙ | |||
847 848 849 850 851 852 853 | 384 -133 311 -250 185 -250 c 0 128 -250 87 -244 45 -205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE08A | | | 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 | 384 -133 311 -250 185 -250 c 0 128 -250 87 -244 45 -205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE08A Encoding: 32 57482 32 Width: 409 Flags: W HStem: -246 29<187.663 292.861> 30 134<264.058 320.72> 228 21<196.786 281.147> VStem: 9 110<-126.934 138.101> 325 54<100.5 183.933> 392 17<-84.7973 -75.9219> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
881 882 883 884 885 886 887 | 244 130 265 164 302 164 c 2 303 164 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08B | | | 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 | 244 130 265 164 302 164 c 2 303 164 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08B Encoding: 33 57483 33 Width: 408 Flags: W HStem: -246 29<215.419 292.933> 30 134<264.058 320.72> 228 21<215.371 280.515> VStem: 9 110<-126.934 136.6> 180 35<-350 -246 -197 209 248 350> 325 54<100.5 183.933> 392 17<-84.661 -75.9219> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
928 929 930 931 932 933 934 | 119 -58 126 -133 158 -175 c 0 165 -184 172 -191 180 -197 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08C | | | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 | 119 -58 126 -133 158 -175 c 0 165 -184 172 -191 180 -197 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08C Encoding: 34 57484 34 Width: 500 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 0 35 m 25 |
| ︙ | ︙ | |||
953 954 955 956 957 958 959 | 0 -35 l 25 0 35 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE094 | | | | | | < < > > > > > | | | | | | | | | | < < < < < < < < < < < | < | | | > | | | < < | | | | | | | | | | | | | | | | | | | < < | < > | < | < < | < < < | | | | | | | 1222 1223 1224 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 1350 1351 1352 1353 1354 | 0 -35 l 25 0 35 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE094 Encoding: 35 57492 35 Width: 260 Flags: MW HStem: -250 500 LayerCount: 2 Fore SplineSet 220 -490 m 0 228 -500 208 -509 200 -500 c 4 105 -388 20 -171 20 0 c 0 20 170 105 388 200 500 c 0 211 513 231 503 220 490 c 0 136 388 90 170 90 0 c 0 90 -169 138 -388 220 -490 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE095 Encoding: 36 57493 36 Width: 260 Flags: HMW LayerCount: 2 Fore SplineSet 20 -490 m 0 102 -388 150 -169 150 0 c 0 150 170 104 388 20 490 c 0 9 503 29 513 40 500 c 0 135 388 220 170 220 0 c 0 220 -171 135 -388 40 -500 c 0 32 -509 12 -500 20 -490 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A0 Encoding: 37 57504 37 Width: 619 Flags: HMW LayerCount: 2 Fore SplineSet 424 -32 m 0 424 38 361 99 280 99 c 0 241 99 196 73 196 29 c 0 196 -42 263 -99 344 -99 c 0 385 -99 424 -77 424 -32 c 0 538 170 m 1 588 170 l 1 588 -170 l 1 538 -170 l 1 538 170 l 1 36 170 m 1 86 170 l 1 86 -170 l 1 36 -170 l 1 36 170 l 1 537 0 m 0 537 -80 448 -130 312 -130 c 0 176 -130 87 -75 87 0 c 0 87 85 176 130 312 130 c 0 448 130 537 80 537 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A1 Encoding: 38 57505 38 Width: 530 Flags: HMW LayerCount: 2 Fore SplineSet 30 65 m 25 30 -65 l 25 500 -65 l 25 500 65 l 25 30 65 l 25 0 220 m 29 30 220 l 25 30 165 l 25 500 165 l 25 500 220 l 25 530 220 l 25 530 -220 l 25 500 -220 l 25 500 -165 l 25 30 -165 l 25 30 -220 l 25 0 -220 l 25 0 220 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE0A2 Encoding: 39 57506 39 Width: 450 Flags: HMW LayerCount: 2 Fore SplineSet 337 -30 m 4 337 40 264 101 193 101 c 4 154 101 109 75 109 31 c 4 109 -40 186 -97 257 -97 c 4 298 -97 337 -75 337 -30 c 4 450 0 m 0 450 -70 361 -129 225 -129 c 0 89 -129 0 -70 0 0 c 0 0 70 89 129 225 129 c 0 361 129 450 70 450 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A3 Encoding: 40 57507 40 Width: 329 Flags: W HStem: -148 57<54.5533 171.763> 91 57<156.237 273.528> VStem: 0 31<-79.2669 -12.3025> 297 31<12.3025 73.4219> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1116 1117 1118 1119 1120 1121 1122 | 0 70 105 148 198 148 c 0 245 148 288 128 313 81 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A4 | | | | < < | | | | < | < | | 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 | 0 70 105 148 198 148 c 0 245 148 288 128 313 81 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A4 Encoding: 41 57508 41 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 320 40 m 0 320 -51 231 -135 110 -135 c 0 40 -135 0 -90 0 -40 c 0 0 50 90 135 210 135 c 0 280 135 320 90 320 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A9 Encoding: 42 57513 42 Width: 330 Flags: HMW LayerCount: 2 Fore SplineSet -2 113 m 1 25 145 l 1 |
| ︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | 132 -0 l 1 -2 113 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE0B3 | | | 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 | 132 -0 l 1 -2 113 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE0B3 Encoding: 43 57523 43 Width: 300 Flags: HMW LayerCount: 2 Fore SplineSet 150 -18 m 1 79 -90 l 1 |
| ︙ | ︙ | |||
1196 1197 1198 1199 1200 1201 1202 | 300 -83 233 -150 150 -150 c 24 67 -150 0 -83 0 0 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE101 | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < | | | | | | | | | | | | | | | | 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 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 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 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 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 | 300 -83 233 -150 150 -150 c 24 67 -150 0 -83 0 0 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE101 Encoding: 44 57601 44 Width: 560 Flags: W LayerCount: 2 Fore SplineSet 0 -250 m 5 440 250 l 5 560 250 l 5 119 -250 l 5 0 -250 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE1B9 Encoding: 45 57785 45 Width: 330 Flags: W HStem: -140 280 VStem: 0 330 LayerCount: 2 Fore SplineSet 0 0 m 1 165 140 l 1 330 0 l 1 165 -140 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE1BB Encoding: 46 57787 46 Width: 330 Flags: W HStem: -140 280 VStem: 0 330 LayerCount: 2 Fore SplineSet 0 -140 m 29 165 140 l 25 330 -140 l 29 0 -140 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE1E7 Encoding: 47 57831 47 Width: 100 Flags: MW LayerCount: 2 Fore SplineSet 50 -50 m 3 22 -50 0 -28 0 0 c 3 0 28 22 50 50 50 c 3 78 50 100 28 100 0 c 3 100 -28 78 -50 50 -50 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE240 Encoding: 48 57920 48 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -239 m 9 0 0 l 1 30 0 l 1 51 -195 315 -321 315 -584 c 0 315 -643 302 -710 269 -785 c 1 282 -738 287 -691 287 -647 c 0 287 -452 175 -294 30 -239 c 1 0 -239 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE241 Encoding: 49 57921 49 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 1 0 239 l 1 30 239 l 1 178 280 288 445 288 642 c 0 288 688 282 736 269 785 c 1 302 711 315 647 315 588 c 0 315 328 51 195 30 0 c 0 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE242 Encoding: 50 57922 50 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -343 m 9 0 0 l 1 30 0 l 1 62.1962890625 -133.135742188 315.4921875 -235.983398438 315.4921875 -417.918945312 c 0 315.4921875 -445.063476562 309.853515625 -473.969726562 297 -505 c 1 308.7109375 -531.232421875 315.594726562 -559.000976562 315.594726562 -588.922851562 c 0 315.594726562 -622.875976562 306.73046875 -659.6015625 286 -700 c 1 289.740234375 -679.993164062 291.475585938 -660.758789062 291.475585938 -642.3125 c 0 291.475585938 -448.700195312 100.301757812 -342 30 -342 c 1 0 -343 l 9 30 -171 m 1 56 -278 226 -366 291 -492 c 1 291.465820312 -485.108398438 291.692382812 -478.3203125 291.692382812 -471.635742188 c 0 291.692382812 -277.536132812 100.569335938 -171 30 -171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE243 Encoding: 51 57923 51 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -1 m 9 0 342 l 1 30 342 l 1 100.301757812 342 291.475585938 448.700195312 291.475585938 642.3125 c 0 291.475585938 660.758789062 289.740234375 679.993164062 286 700 c 1 306.73046875 659.6015625 315.594726562 622.875976562 315.594726562 588.922851562 c 0 315.594726562 559.000976562 308.7109375 531.232421875 297 505 c 1 309.853515625 473.969726562 315.4921875 445.063476562 315.4921875 417.918945312 c 0 315.4921875 235.983398438 62.1962890625 133.135742188 30 0 c 1 0 -1 l 9 30 171 m 1 100.569335938 171 291.692382812 277.536132812 291.692382812 471.635742188 c 0 291.692382812 478.3203125 291.465820312 484.108398438 291 491 c 1 226 365 56 278 30 171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE244 Encoding: 52 57924 52 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -368 m 9 0 145 l 1 30 145 l 1 62 12 315 -91 315 -273 c 0 315 -300 310 -329 297 -360 c 1 309 -386 315 -414 315 -444 c 0 315 -471 310 -500 297 -531 c 1 309 -557 316 -585 316 -615 c 0 316 -649 307 -686 286 -726 c 1 290 -706 291 -687 291 -668 c 0 291 -475 100 -368 30 -368 c 1 0 -368 l 9 30 -199 m 1 56 -307 226 -392 291 -518 c 1 291 -511 292 -504 292 -498 c 0 292 -305.781467412 104.491731968 -198.972460053 31.9860569235 -198.972460053 c 0 31.3140795885 -198.972460053 30.6519803414 -198.981634357 30 -199 c 1 30 -28 m 1 56 -135 226 -221 291 -347 c 1 291 -340 292 -333 292 -327 c 0 292 -134.781467412 104.491731968 -27.9724600525 31.9860569235 -27.9724600525 c 0 31.3140795885 -27.9724600525 30.6519803414 -27.9816343566 30 -28 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE245 Encoding: 53 57925 53 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 343 m 17 30 343 l 1 100.301757812 343 291.475585938 449.700195312 291.475585938 643.3125 c 0 291.475585938 661.758789062 289.740234375 680.993164062 286 701 c 1 306.73046875 660.6015625 315.594726562 623.875976562 315.594726562 589.922851562 c 0 315.594726562 560.000976562 308.7109375 532.232421875 297 506 c 1 309.81640625 475.145507812 315.422851562 446.318359375 315.422851562 419.19921875 c 0 315.422851562 389.1875 308.556640625 361.265625 297 335 c 1 309.853515625 303.969726562 315.4921875 275.063476562 315.4921875 247.918945312 c 0 315.4921875 65.9833984375 62.1962890625 -36.8642578125 30 -170 c 1 0 -170 l 1 0 343 l 17 30 0 m 1 100.569335938 0 291.692382812 107.536132812 291.692382812 301.635742188 c 0 291.692382812 308.3203125 291.465820312 315.108398438 291 322 c 1 226 196 56 109 30 0 c 1 30 171 m 1 100.569335938 171 291.692382812 278.536132812 291.692382812 472.635742188 c 0 291.692382812 479.3203125 291.465820312 486.108398438 291 493 c 1 226 367 56 280 30 171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE246 Encoding: 54 57926 54 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -344 m 9 0 340 l 1 30 340 l 1 62.1962890625 206.864257812 315.4921875 104.016601562 315.4921875 -77.9189453125 c 0 315.4921875 -105.063476562 309.853515625 -133.969726562 297 -165 c 1 308.556640625 -191.265625 315.422851562 -219.1875 315.422851562 -249.19921875 c 0 315.422851562 -276.318359375 309.81640625 -305.145507812 297 -336 c 1 308.556640625 -362.265625 315.422851562 -390.1875 315.422851562 -420.19921875 c 0 315.422851562 -447.318359375 309.81640625 -476.145507812 297 -507 c 1 308.7109375 -533.232421875 315.594726562 -561.000976562 315.594726562 -590.922851562 c 0 315.594726562 -624.875976562 306.73046875 -661.6015625 286 -702 c 1 289.740234375 -681.993164062 291.475585938 -662.758789062 291.475585938 -644.3125 c 0 291.475585938 -450.700195312 100.301757812 -344 30 -344 c 1 0 -344 l 9 30 -173 m 1 56 -281 226 -368 291 -494 c 1 291.465820312 -487.108398438 291.692382812 -480.3203125 291.692382812 -473.635742188 c 0 291.692382812 -279.536132812 100.569335938 -173 30 -173 c 1 30 -2 m 1 56 -110 226 -197 291 -323 c 1 291.465820312 -316.108398438 291.692382812 -309.3203125 291.692382812 -302.635742188 c 0 291.692382812 -108.536132812 100.569335938 -2 30 -2 c 1 30 169 m 1 56 62 226 -26 291 -152 c 1 291.465820312 -145.108398438 291.692382812 -138.3203125 291.692382812 -131.635742188 c 0 291.692382812 62.4638671875 100.569335938 169 30 169 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE247 Encoding: 55 57927 55 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -370 m 9 0 314 l 1 30 314 l 1 100.301757812 314 291.475585938 420.700195312 291.475585938 614.3125 c 0 291.475585938 632.758789062 289.740234375 651.993164062 286 672 c 1 306.73046875 631.6015625 315.594726562 594.875976562 315.594726562 560.922851562 c 0 315.594726562 531.000976562 308.7109375 503.232421875 297 477 c 1 309.81640625 446.145507812 315.422851562 417.318359375 315.422851562 390.19921875 c 0 315.422851562 360.1875 308.556640625 332.265625 297 306 c 1 309.81640625 275.145507812 315.422851562 246.318359375 315.422851562 219.19921875 c 0 315.422851562 189.1875 308.556640625 161.265625 297 135 c 1 309.853515625 103.969726562 315.4921875 75.0634765625 315.4921875 47.9189453125 c 0 315.4921875 -134.016601562 62.1962890625 -236.864257812 30 -370 c 1 0 -370 l 9 30 -200 m 5 100.569335938 -200 291.692382812 -92.4638671875 291.692382812 101.635742188 c 0 291.692382812 108.3203125 291.465820312 115.108398438 291 122 c 5 226 -4 56 -91 30 -200 c 5 30 -29 m 1 100.569335938 -29 291.692382812 78.5361328125 291.692382812 272.635742188 c 0 291.692382812 279.3203125 291.465820312 286.108398438 291 293 c 1 226 167 56 81 30 -29 c 1 30 142 m 1 100.569335938 142 291.692382812 249.536132812 291.692382812 443.635742188 c 0 291.692382812 450.3203125 291.465820312 457.108398438 291 464 c 1 226 338 56 251 30 142 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE248 Encoding: 56 57928 56 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -325 m 9 0 530 l 1 30 530 l 1 62.1962890625 396.864257812 315.4921875 294.016601562 315.4921875 112.081054688 c 0 315.4921875 84.9365234375 309.853515625 56.0302734375 297 25 c 1 308.556640625 -1.265625 315.422851562 -29.1875 315.422851562 -59.19921875 c 0 315.422851562 -86.318359375 309.81640625 -115.145507812 297 -146 c 1 308.556640625 -172.265625 315.422851562 -200.1875 315.422851562 -230.19921875 c 0 315.422851562 -257.318359375 309.81640625 -286.145507812 297 -317 c 1 308.556640625 -343.265625 315.422851562 -371.1875 315.422851562 -401.19921875 c 0 315.422851562 -428.318359375 309.81640625 -457.145507812 297 -488 c 1 308.7109375 -514.232421875 315.594726562 -542.000976562 315.594726562 -571.922851562 c 0 315.594726562 -605.875976562 306.73046875 -642.6015625 286 -683 c 1 289.740234375 -662.993164062 291.475585938 -643.758789062 291.475585938 -625.3125 c 0 291.475585938 -431.700195312 100.301757812 -325 30 -325 c 1 0 -325 l 9 30 -154 m 1 56 -262 226 -349 291 -475 c 1 291.465820312 -468.108398438 291.692382812 -461.3203125 291.692382812 -454.635742188 c 0 291.692382812 -260.536132812 100.569335938 -154 30 -154 c 1 30 17 m 1 56 -91 226 -178 291 -304 c 1 291.465820312 -297.108398438 291.692382812 -290.3203125 291.692382812 -283.635742188 c 0 291.692382812 -89.5361328125 100.569335938 17 30 17 c 1 30 188 m 1 56 80 226 -7 291 -133 c 1 291.465820312 -126.108398438 291.692382812 -119.3203125 291.692382812 -112.635742188 c 0 291.692382812 81.4638671875 100.569335938 188 30 188 c 1 30 359 m 1 56 252 226 164 291 38 c 1 291.465820312 44.8916015625 291.692382812 51.6796875 291.692382812 58.3642578125 c 0 291.692382812 252.463867188 100.569335938 359 30 359 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE249 Encoding: 57 57929 57 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -580 m 9 0 275 l 1 30 275 l 1 100.301757812 275 291.475585938 381.700195312 291.475585938 575.3125 c 0 291.475585938 593.758789062 289.740234375 612.993164062 286 633 c 1 306.73046875 592.6015625 315.594726562 555.875976562 315.594726562 521.922851562 c 0 315.594726562 492.000976562 308.7109375 464.232421875 297 438 c 1 309.81640625 407.145507812 315.422851562 378.318359375 315.422851562 351.19921875 c 0 315.422851562 321.1875 308.556640625 293.265625 297 267 c 1 309.81640625 236.145507812 315.422851562 207.318359375 315.422851562 180.19921875 c 0 315.422851562 150.1875 308.556640625 122.265625 297 96 c 1 309.81640625 65.1455078125 315.422851562 36.318359375 315.422851562 9.19921875 c 0 315.422851562 -20.8125 308.556640625 -48.734375 297 -75 c 1 309.853515625 -106.030273438 315.4921875 -134.936523438 315.4921875 -162.081054688 c 0 315.4921875 -344.016601562 62.1962890625 -446.864257812 30 -580 c 1 0 -580 l 9 30 -410 m 5 100.569335938 -410 291.692382812 -302.463867188 291.692382812 -108.364257812 c 0 291.692382812 -101.6796875 291.465820312 -94.8916015625 291 -88 c 5 226 -214 56 -301 30 -410 c 5 30 -239 m 1 100.569335938 -239 291.692382812 -131.463867188 291.692382812 62.6357421875 c 0 291.692382812 69.3203125 291.465820312 76.1083984375 291 83 c 1 226 -43 56 -129 30 -239 c 1 30 -68 m 1 100.569335938 -68 291.692382812 39.5361328125 291.692382812 233.635742188 c 0 291.692382812 240.3203125 291.465820312 247.108398438 291 254 c 1 226 128 56 41 30 -68 c 1 30 103 m 1 100.569335938 103 291.692382812 210.536132812 291.692382812 404.635742188 c 0 291.692382812 411.3203125 291.465820312 418.108398438 291 425 c 1 226 299 56 213 30 103 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE260 Encoding: 58 57952 58 Width: 269 Flags: HMW LayerCount: 2 Fore SplineSet 103 122 m 0 77 122 40 90 40 65 c 2 40 -120 l 1 58 -112 83 -92 112 -49 c 1 142 -8 155 22 155 57 c 0 155 92 134 122 103 122 c 0 133 160 m 0 177 160 225 124 225 75 c 0 225 28 203 -20 150 -74 c 0 96 -128 40 -156 0 -156 c 1 0 432 l 1 40 432 l 1 40 108 l 1 63 142 93 160 133 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE261 Encoding: 59 57953 59 Width: 200 Flags: W VStem: 0 28<-101 49 146 376> 172 25<-378 -152 -56 94> LayerCount: 2 Fore SplineSet 28 -101 m 1 |
| ︙ | ︙ | |||
1284 1285 1286 1287 1288 1289 1290 | 1 377 l 1 28 378 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE262 | | | | < | | | | | | | | | | > | | | | | > | | | | | | < < | | | | | | | | | | | | | 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 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 | 1 377 l 1 28 378 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE262 Encoding: 60 57954 60 Width: 255 Flags: HMW LayerCount: 2 Fore SplineSet 83 70 m 21 83 -97 l 5 173 -70 l 5 173 97 l 5 83 70 l 21 83 -360 m 5 53 -360 l 5 53 -197 l 5 0 -212 l 5 0 -120 l 5 53 -105 l 5 53 62 l 5 0 47 l 5 0 137 l 5 53 152 l 5 53 320 l 5 83 320 l 5 83 161 l 5 173 189 l 5 173 360 l 5 202 360 l 5 202 197 l 5 255 212 l 5 255 120 l 5 202 105 l 5 202 -62 l 5 255 -47 l 5 255 -137 l 5 202 -152 l 5 202 -320 l 5 173 -320 l 5 173 -161 l 5 83 -189 l 5 83 -360 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE263 Encoding: 61 57955 61 Width: 267 Flags: W HStem: -124 74<20 77 210 267> 50 72<20 77 210 267> VStem: 20 72<-124 -65 65 122> 195 72<-124 -65 65 122> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1368 1369 1370 1371 1372 1373 1374 | 267 -124 l 1 195 -124 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE264 | | | < < | | | | | | 1957 1958 1959 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 2011 2012 2013 2014 2015 2016 2017 2018 | 267 -124 l 1 195 -124 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE264 Encoding: 62 57956 62 Width: 366 Flags: HMW LayerCount: 2 Fore SplineSet 78 125 m 1 55 124 31 100 31 78 c 2 31 -120 l 1 43 -120 54 -108 75 -79 c 0 96 -50 110 -19 118 16 c 0 122 29 122 42 122 54 c 0 122 72 119 90 112 104 c 1 102 117 90 125 79 125 c 2 78 125 l 1 104 163 m 0 144 163 176 116 176 73 c 0 176 57 172 41 167 23 c 1 150 -17 128 -52 100 -86 c 0 71 -121 33 -150 0 -150 c 1 0 432 l 1 31 432 l 1 31 113 l 1 47 145 68 163 104 163 c 0 265 125 m 1 242 124 219 100 219 78 c 2 219 -120 l 5 230 -120 244 -108 265 -79 c 0 283 -50 297 -19 305 16 c 0 309 29 311 42 311 54 c 0 311 72 307 90 300 104 c 1 290 117 280 125 269 125 c 2 265 125 l 1 291 163 m 0 333 163 364 119 364 73 c 0 364 57 360 41 353 23 c 0 337 -17 317 -52 288 -86 c 1 260 -121 219 -150 189 -150 c 1 189 432 l 1 219 432 l 1 219 113 l 1 235 143 256 163 291 163 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE280 Encoding: 63 57984 63 Width: 269 Flags: HMW LayerCount: 2 Fore SplineSet 171 122 m 0 140 122 116 92 116 57 c 0 |
| ︙ | ︙ | |||
1440 1441 1442 1443 1444 1445 1446 1447 1448 | 269 236 269 40 269 -156 c 1 235 -156 183 -128 129 -74 c 0 76 -20 50 28 50 75 c 0 50 124 97 160 141 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4A0 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 2027 2028 2029 2030 2031 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 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 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 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 | 269 236 269 40 269 -156 c 1 235 -156 183 -128 129 -74 c 0 76 -20 50 28 50 75 c 0 50 124 97 160 141 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE281 Encoding: 64 57985 64 Width: 366 Flags: HMW LayerCount: 2 Fore SplineSet 87 125 m 1 86 125 l 2 75 125 63 117 53 104 c 1 46 90 43 72 43 54 c 0 43 42 43 29 47 16 c 0 55 -19 69 -50 90 -79 c 0 111 -108 122 -120 134 -120 c 1 134 78 l 2 134 100 110 124 87 125 c 1 61 163 m 0 97 163 118 145 134 113 c 1 134 432 l 1 165 432 l 1 165 -150 l 1 135 -150 94 -121 65 -86 c 0 37 -52 15 -17 -2 23 c 1 -7 41 -11 57 -11 73 c 0 -11 116 21 163 61 163 c 0 265 125 m 1 242 124 219 100 219 78 c 2 219 -120 l 1 230 -120 244 -108 265 -79 c 0 283 -50 297 -19 305 16 c 0 309 29 311 42 311 54 c 0 311 72 307 90 300 104 c 1 290 117 280 125 269 125 c 2 265 125 l 1 291 163 m 0 333 163 364 119 364 73 c 0 364 57 360 41 353 23 c 0 337 -17 317 -52 288 -86 c 1 260 -121 219 -150 189 -150 c 1 189 432 l 1 219 432 l 1 219 113 l 1 235 143 256 163 291 163 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE282 Encoding: 65 57986 65 Width: 169 Flags: HMW LayerCount: 2 Fore SplineSet 68 320 m 8 98 320 l 1 98 158 l 1 169 172 l 1 169 80 l 1 98 66 l 1 98 -61 l 1 169 -47 l 1 169 -137 l 1 98 -152 l 1 98 -320 l 8 68 -320 l 1 68 -158 l 1 0 -172 l 1 0 -80 l 1 68 -66 l 1 68 61 l 1 0 47 l 1 0 137 l 1 68 152 l 1 68 320 l 8 EndSplineSet Validated: 1 EndChar StartChar: uniE283 Encoding: 66 57987 66 Width: 314 Flags: HMW LayerCount: 2 Fore SplineSet 233 192 m 17 233 360 l 1 263 360 l 1 263 202 l 1 314 217 l 1 314 125 l 1 263 110 l 1 263 -49 l 1 314 -34 l 1 314 -124 l 1 263 -139 l 1 263 -320 l 1 233 -320 l 1 233 -150 l 1 172 -168 l 1 172 -340 l 25 142 -340 l 25 142 -176 l 25 82 -192 l 17 81 -360 l 1 51 -360 l 1 51 -202 l 1 0 -217 l 1 0 -125 l 1 51 -110 l 1 51 49 l 1 0 34 l 1 0 124 l 1 51 139 l 1 51 320 l 1 81 320 l 1 81 150 l 1 142 168 l 1 142 340 l 25 172 340 l 25 172 176 l 25 233 192 l 17 142 -83 m 9 142 75 l 1 81 58 l 1 81 -101 l 1 142 -83 l 9 172 83 m 9 172 -75 l 1 233 -58 l 1 233 101 l 1 172 83 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE4A0 Encoding: 67 58528 67 Width: 320 Flags: W HStem: 0 244<5 15> VStem: -3 322 LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1467 1468 1469 1470 1471 1472 1473 1474 1475 | 305 136 l 1 314 132 319 124 319 116 c 0 319 109 314 101 305 98 c 1 18 1 l 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4AC | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < | | | | | | | | | > | | < | | | | < < | | < < | | < < | | < < | 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 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 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 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 | 305 136 l 1 314 132 319 124 319 116 c 0 319 109 314 101 305 98 c 1 18 1 l 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4A2 Encoding: 68 58530 68 Width: 80 Flags: HMW LayerCount: 2 Fore SplineSet 0 40 m 24 0 63 17 80 40 80 c 24 62 80 80 63 80 40 c 24 80 18 63 0 40 0 c 24 18 0 0 18 0 40 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE4A4 Encoding: 69 58532 69 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 25 0 40 l 25 320 40 l 25 320 0 l 25 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE4A8 Encoding: 70 58536 70 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 40 0 m 29 0 280 l 25 100 280 l 25 60 0 l 25 40 0 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE4AC Encoding: 71 58540 71 Width: 280 Flags: W HStem: 0 309 VStem: 0 280 LayerCount: 2 Fore SplineSet 0 0 m 1 140 309 l 25 280 0 l 1 215 0 l 1 127 198 l 25 37 0 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4C0 Encoding: 72 58560 72 Width: 600 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 1 0 214 150 330 300 330 c 3 450 330 600 213 600 0 c 1 585 0 l 5 570 150 446 244 300 244 c 3 154 244 30 150 15 0 c 1 0 0 l 1 299 0 m 3 268 0 239 28 239 60 c 3 239 92 268 120 299 120 c 3 332 120 359 92 359 60 c 3 359 27 333 0 299 0 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE4CE Encoding: 73 58574 73 Width: 182 Flags: HMW LayerCount: 2 Fore SplineSet 86 301 m 0 123 301 136 294 156 272 c 0 175 251 182 226 182 195 c 0 182 152 162 110 132 74 c 0 97 34 43 0 23 0 c 0 21 0 19 2 17 3 c 0 16 4 16 5 16 6 c 0 16 26 87 105 87 140 c 0 87 149 81 155 67 155 c 0 32 156 -0 184 -0 222 c 0 -0 258 27 301 86 301 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4E1 Encoding: 74 58593 74 Width: 130 Flags: HMW LayerCount: 2 Fore SplineSet 0 250 m 1 130 250 l 1 130 -250 l 5 0 -250 l 1 0 250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E2 Encoding: 75 58594 75 Width: 130 Flags: MW LayerCount: 2 Fore SplineSet 0 250 m 1 130 250 l 1 130 0 l 1 0 0 l 1 0 250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E3 Encoding: 76 58595 76 Width: 300 Flags: MW LayerCount: 2 Fore SplineSet 0 0 m 1 300 0 l 1 300 -125 l 1 0 -125 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E4 Encoding: 77 58596 77 Width: 300 Flags: MW LayerCount: 2 Fore SplineSet 0 125 m 1 300 125 l 1 300 0 l 1 0 0 l 1 0 125 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E5 Encoding: 78 58597 78 Width: 238 Flags: MW LayerCount: 2 Fore SplineSet 41 391 m 1 230 162 l 1 127 -55 l 1 235 -262 l 1 |
| ︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 | 122 193 l 1 41 391 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E6 | | | 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 | 122 193 l 1 41 391 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E6 Encoding: 79 58598 79 Width: 255 Flags: W HStem: 48 33<112 170.038> VStem: 0 135<81.9955 177.625> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 | 58 -227 l 1 171 60 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E7 | | | 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 | 58 -227 l 1 171 60 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E7 Encoding: 80 58599 80 Width: 329 Flags: W HStem: -208 32<112 170.069> 48 33<184 242.918> VStem: 0 135<-174.731 -78.875> 72 135<81.9955 177.625> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1687 1688 1689 1690 1691 1692 1693 | 86 -488 l 1 171 -196 l 1xd0 EndSplineSet Validated: 1 EndChar StartChar: uniE4E8 | | | 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 | 86 -488 l 1 171 -196 l 1xd0 EndSplineSet Validated: 1 EndChar StartChar: uniE4E8 Encoding: 81 58600 81 Width: 399 Flags: W HStem: -208 32<112 170.069> 48 32<189 245.07> 304 33<255 314.117> VStem: 0 135<-174.731 -78.875> 77 135<81.2688 177.125> 143 135<337.996 433.625> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1725 1726 1727 1728 1729 1730 1731 | 158 -176 182 -160 188 -142 c 1 246 60 l 1xf4 EndSplineSet Validated: 1 EndChar StartChar: uniE4E9 | | | 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 | 158 -176 182 -160 188 -142 c 1 246 60 l 1xf4 EndSplineSet Validated: 1 EndChar StartChar: uniE4E9 Encoding: 82 58601 82 Width: 472 Flags: W HStem: -464 32<112 170.069> -208 32<187 245.069> 48 32<264 320.07> 304 33<330 389.117> VStem: 0 135<-430.731 -334.875> 75 135<-174.731 -78.875> 152 135<81.2688 177.125> 218 135<337.996 433.625> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1770 1771 1772 1773 1774 1775 1776 | 86 -744 l 1 171 -452 l 1xf1 EndSplineSet Validated: 1 EndChar StartChar: uniE4EA | | | 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 | 86 -744 l 1 171 -452 l 1xf1 EndSplineSet Validated: 1 EndChar StartChar: uniE4EA Encoding: 83 58602 83 Width: 472 Flags: W HStem: -464 32<112 170.069> -210 32<187 245.069> 40 32<260 318.069> 290 32<333 389.07> 542 33<393 452.117> VStem: 0 135<-430.731 -334.875> 75 135<-176.731 -80.875> 148 135<73.2688 169.125> 221 135<323.269 419.125> 281 135<575.996 671.625> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1822 1823 1824 1825 1826 1827 1828 | 233 -178 257 -162 263 -144 c 1 319 52 l 1xfa EndSplineSet Validated: 1 EndChar StartChar: uniE4EE | | | 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 | 233 -178 257 -162 263 -144 c 1 319 52 l 1xfa EndSplineSet Validated: 1 EndChar StartChar: uniE4EE Encoding: 84 58606 84 Width: 851 Flags: W HStem: -105 210<25 825> VStem: 0 25<-230 -105 105 230> 825 25<-230 -105 105 230> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1848 1849 1850 1851 1852 1853 1854 | 0 -230 l 25 0 230 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE500 | | | 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 | 0 -230 l 25 0 230 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE500 Encoding: 85 58624 85 Width: 563 Flags: W HStem: -195 120<435.745 528.255> 75 120<8.74536 101.255> VStem: -5 120<88.7454 181.255> 422 120<-181.255 -88.7454> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1876 1877 1878 1879 1880 1881 1882 | 109 -250 l 1 -16 -250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE501 | | | 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 | 109 -250 l 1 -16 -250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE501 Encoding: 86 58625 86 Width: 800 Flags: W HStem: -195 120<659.745 752.255> 75 120<-6.25464 86.2546> VStem: -20 120<88.7454 181.255> 646 120<-181.255 -88.7454> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
1907 1908 1909 1910 1911 1912 1913 1914 1915 | 652 250 l 5 775 250 l 5 334 -250 l 5 212 -250 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE567 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 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 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 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 2796 2797 2798 2799 2800 2801 2802 2803 2804 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 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 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 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 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 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 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 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 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 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 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 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 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 3498 3499 3500 3501 3502 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 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 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 | 652 250 l 5 775 250 l 5 334 -250 l 5 212 -250 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE520 Encoding: 87 58656 87 Width: 563 Flags: HMW LayerCount: 2 Fore SplineSet 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 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 0 -65 -120 l 0 -79 -120 -80 -90 -65 -90 c 2 10 -90 l 1 114 195 l 0 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 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 341 280 380 248 380 180 c 0 380 87 299 0 200 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE521 Encoding: 88 58657 88 Width: 440 Flags: W HStem: -10 44.404<309.482 391.648> 0 21G<-1 65.5 153 199> 212.877 67.1232<170.507 229.008 295.16 358.649> 221 59<37.7036 99.8884> VStem: 276.686 77.1955<12.819 101.414> 335.007 74.6509<146.188 236.074> LayerCount: 2 Fore SplineSet 80 21 m 0x64 76 11 74 1 57 0 c 0 4 0 l 0 -6 0 0 18 4 26 c 1 70 193 l 0 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 0x54 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 0x24 409.658220776 210.41331474 408.193901764 201.830198995 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 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 0xa8 276.685848474 38.4136929968 278.359032859 47.2149008096 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 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 80 21 l 0x64 EndSplineSet Validated: 1 EndChar StartChar: uniE522 Encoding: 89 58658 89 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet -50 -160 m 0 -90 -160 -130 -135 -130 -90 c 0 -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 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 332 205 270 c 1 232 270 229 270 259 270 c 0 272 270 278.5 260 278.5 250 c 0 278.5 240 272 230 259 230 c 0 233 230 229 230 196 230 c 1 153 -26 80 -160 -50 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE524 Encoding: 90 58660 90 Width: 563 Flags: W HStem: 0 30<56.2969 128.192> 250 30<86.1231 145.206> VStem: 0 67<48.3332 106.102> 30 50<188.851 246.418> 140 60<38.2418 104.228> 145.315 72.6848<183.703 229.735> LayerCount: 2 Fore SplineSet 80 0 m 0xd8 41 0 0 33 0 70 c 0xe0 0 92 14 108 30 108 c 0xd0 47 108 67 100 67 84 c 0 67 69 62 55 55 48 c 1 60 34 69 30 85 30 c 0 113 30 140 45 140 70 c 0xe8 140 100 116 103 90 120 c 0 57 141 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 0xd4 145.315176651 218.765893239 146.732008255 224.335480975 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 EndSplineSet Validated: 1 EndChar StartChar: uniE525 Encoding: 91 58661 91 Width: 563 Flags: HMW LayerCount: 2 Fore SplineSet -10 3 m 0 -22 -6 -34 16 -23 26 c 0 153 219 l 0 141.918058124 224.910369 126.469558534 226.454180286 105.444752759 226.454180286 c 0 98.0113613903 226.454180286 89.8809317488 226.261203875 81 226 c 0 70 226 47 173 34 162 c 0 20 150 6 154 20 187 c 0 41 238 38 251 44 267 c 1 79.2709584661 264.544426942 105.57190844 263.63368868 125.594979066 263.63368868 c 0 183.112330324 263.63368868 188.827343421 271.148705903 206.551743542 271.148705903 c 0 210.297411805 271.148705903 214.579415356 270.813087697 220 270 c 0 235 268 233 254 224 245 c 0 66 78 l 0 64.6486486486 74.6216216216 63.972972973 72.1015339664 63.972972973 70.1929599431 c 0 63.972972973 57.9780861943 91.6486486486 70.8108108108 147 44 c 0 158 39 168 52 164 64 c 0 157 84 125 65 125 100 c 0 125 115 141 130 157 130 c 0 177 130 195 117 195 75 c 0 195 36.9571906054 164.866783384 2.35817739562 123.772791397 2.35817739562 c 0 120.578422501 2.35817739562 117.317823606 2.5672403992 114 3 c 0 69.8119048549 8.52351189314 48.9765181701 18.5669028431 29.7645164434 18.5669028431 c 0 17.6725183082 18.5669028431 6.22361116537 14.5882936895 -10 3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE529 Encoding: 92 58665 92 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 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 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 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 981 280 1008 264 1021 230 c 1 1045 267 1063 280 1100 280 c 0 1145 280 1168 271 1178 235 c 1 1219 278 1238 280 1280 280 c 0 1316 280 1355 248 1355 180 c 0 1355 87 1274 0 1175 0 c 0 1158 0 1148 6 1128 32 c 1 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 1064 240 1053 221 1030 181 c 0 1030 181 1030 180 1030 180 c 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 739 240 728 221 705 181 c 0 705 181 705 180 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 414 240 403 221 380 181 c 0 380 181 380 180 380 180 c 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 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 EndSplineSet Validated: 1 EndChar StartChar: uniE52A Encoding: 93 58666 93 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> 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 739 240 728 221 705 181 c 0 705 181 705 180 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 414 240 403 221 380 181 c 0 380 181 380 180 380 180 c 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 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 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 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 EndSplineSet Validated: 1 EndChar StartChar: uniE52B Encoding: 94 58667 94 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 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 414 240 403 221 380 181 c 0 380 181 380 180 380 180 c 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 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 EndSplineSet Validated: 1 EndChar StartChar: uniE52C Encoding: 95 58668 95 Width: 811 Flags: HMW LayerCount: 2 Fore SplineSet 429 119 m 0 480 232 500 280 556 280 c 0 601 280 624 271 634 235 c 1 675 278 694 280 736 280 c 0 772 280 811 248 811 180 c 0 811 87 730 0 631 0 c 0 614 0 604 6 584 32 c 1 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 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 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 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 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 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 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 EndSplineSet Validated: 1 EndChar StartChar: uniE52D Encoding: 96 58669 96 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet 80 21 m 0 76 11 74 1 57 0 c 0 4 0 l 0 -6 0 0 18 4 26 c 1 70 193 l 0 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 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 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 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 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 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 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 676 230 672 230 639 230 c 1 596 -26 523 -160 393 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52F Encoding: 97 58671 97 Width: 617 Flags: HMW LayerCount: 2 Fore SplineSet 351 230 m 9 196 230 l 1 153 -26 80 -160 -50 -160 c 0 -90 -160 -130 -135 -130 -90 c 0 -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 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 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 192 -120 202 -124 217 -124 c 0 280 -124 284 -35 351 230 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE530 Encoding: 98 58672 98 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet 204 270 m 9 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 333 472 271 c 1 627 270 l 1 655 374 738 440 804 440 c 0 844 440 884 415 884 370 c 0 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 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 459 -120 469 -124 484 -124 c 0 547 -124 551 -35 618 230 c 9 463 230 l 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 192 -120 202 -124 217 -124 c 0 280 -124 283 -35 351 230 c 9 196 230 l 1 153 -26 80 -160 -50 -160 c 0 -90 -160 -130 -135 -130 -90 c 0 -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 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 217 332 204 270 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE531 Encoding: 99 58673 99 Width: 617 Flags: HMW LayerCount: 2 Fore SplineSet 472 271 m 9 628 270 l 1 656 374 739 440 805 440 c 0 845 440 885 415 885 370 c 0 885 335 868 310 843 310 c 0 818 310 802 325 802 345 c 0 802 355 809 363 820 370 c 0 831 377 830 380 830 390 c 0 830 400 820 404 805 404 c 0 763 404 753 333 740 271 c 1 895 270 l 1 923 374 1006 440 1072 440 c 0 1112 440 1152 415 1152 370 c 0 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 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 727 -120 737 -124 752 -124 c 0 815 -124 819 -35 886 230 c 9 731 230 l 1 688 -26 615 -160 485 -160 c 0 445 -160 405 -135 405 -90 c 0 405 -55 422 -30 447 -30 c 0 472 -30 488 -45 488 -65 c 0 488 -75 481 -83 470 -90 c 0 460 -97 460 -100 460 -110 c 0 460 -120 470 -124 485 -124 c 0 548 -124 551 -36 618 230 c 9 463 230 l 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 192 -120 202 -124 217 -124 c 0 280 -124 284 -35 351 230 c 9 196 230 l 1 153 -26 80 -160 -50 -160 c 0 -90 -160 -130 -135 -130 -90 c 0 -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 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 271 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE539 Encoding: 100 58681 100 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet 80 0 m 0xd8 41 0 0 33 0 70 c 0xe8 0 92 14 108 30 108 c 0xd8 47 108 67 100 67 84 c 0xe8 67 69 62 55 55 48 c 1 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 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 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 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 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 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 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 465 230 461 230 428 230 c 1 385 -26 312 -160 182 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE566 Encoding: 101 58726 101 Width: 509 Flags: HMW LayerCount: 2 Fore SplineSet 310 265 m 1 183 258 l 1 126 74 l 0 125 70 124 67 124 63 c 0 124 51 132 42 144 42 c 0 176 42 230 60 254 80 c 9 310 265 l 1 242 40 m 1 192 9 164 -5 120 -5 c 0 72 -5 52 26 52 57 c 0 52 64 53 72 55 79 c 0 110 258 l 1 5 258 l 1 5 290 l 1 120 290 l 1 142 364 l 1 231 410 l 1 193 290 l 1 345 300 l 1 367 300 370 281 370 255 c 1 390 281 423 296 455 296 c 0 488 296 508 275 508 247 c 0 508 223 490 202 468 202 c 0 447 202 430 214 430 233 c 0 430 249 431 253 439 270 c 1 402 260 378 241 368 216 c 0 302 0 l 1 230 0 l 1 242 40 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE567 Encoding: 102 58727 102 Width: 437 Flags: W HStem: -3 72<49.5596 110.739> 0 49<319.775 397.094> 141 71<327.059 386.441> 161 47<36.904 118.027> VStem: 0 24<64.6579 145.71> 413 24<63.9568 143.617> LayerCount: 2 Fore SplineSet 368 49 m 0x5c 396 49 413 69 413 106 c 0 413 136 402 146 387 157 c 1 375 145 368 141 357 141 c 0 338 141 323 159 323 176 c 0 324 196 345 212 356 212 c 0 401 212 437 183 437 108 c 0 437 69 419 41 396 21 c 0 382 8 362 0 343 0 c 0x6c 323 0 295 7 275 21 c 1 113 143 l 1 94 156 85 161 70 161 c 0 41 161 24 142 24 103 c 0 24 74 34 64 49 53 c 1 61 65 69 69 80 69 c 0 98 69 114 51 114 32 c 0 114 11 97 -1 81 -3 c 1x9c 67 -3 44 6 28 23 c 1 10 45 0 69 0 102 c 0 0 141 18 169 40 189 c 0 55 202 77 208 96 208 c 0 116 207 141 204 161 190 c 1 323 68 l 1 342 55 353 49 368 49 c 0x5c EndSplineSet Validated: 1 EndChar StartChar: uniE569 Encoding: 103 58729 103 Width: 437 Flags: HMW LayerCount: 2 Fore SplineSet 77 -3 m 0 33 -3 0 54 0 102 c 0 |
| ︙ | ︙ | |||
1988 1989 1990 1991 1992 1993 1994 | 92 61 102 51 102 32 c 0 102 11 93 -1 77 -3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE56C | | | 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 | 92 61 102 51 102 32 c 0 102 11 93 -1 77 -3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE56C Encoding: 104 58732 104 Width: 580 Flags: W HStem: 0 224 LayerCount: 2 Fore SplineSet 34 46 m 13 |
| ︙ | ︙ | |||
2013 2014 2015 2016 2017 2018 2019 | 109 124 l 5 34 46 l 13 EndSplineSet Validated: 1 EndChar StartChar: uniE56D | | | 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 | 109 124 l 5 34 46 l 13 EndSplineSet Validated: 1 EndChar StartChar: uniE56D Encoding: 105 58733 105 Width: 580 Flags: W HStem: -53 326<278 305> 0 21G<197.065 232.286 418.065 453.137> VStem: 278 27<-53 70 150 273> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
2045 2046 2047 2048 2049 2050 2051 2052 2053 | 305 97 l 9 305 -53 l 25 278 -53 l 25 278 70 l 1xa0 EndSplineSet Validated: 1 EndChar StartChar: uniE650 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > > | > > > > > > > > > > > > | > > | | > > > > > | | | | | | | | | | | | | | | < < < < < < < < | < | < < < < < < | < | < < < | < < | | | | | | | | | | 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 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 | 305 97 l 9 305 -53 l 25 278 -53 l 25 278 70 l 1xa0 EndSplineSet Validated: 1 EndChar StartChar: uniE582 Encoding: 106 58754 106 Width: 280 Flags: HMW LayerCount: 2 Fore SplineSet 123 0 m 25 123 123 l 25 0 123 l 25 0 157 l 25 123 157 l 25 123 280 l 25 157 280 l 25 157 157 l 25 280 157 l 25 280 123 l 25 157 123 l 25 157 0 l 25 123 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE5D0 Encoding: 107 58832 107 Width: 310 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 1 0 60 l 1 93 79 229 114 280 370 c 1 310 370 l 1 310 175 152 13 0 0 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE5E2 Encoding: 108 58850 108 Width: 300 Flags: W HStem: 0 62<198.921 262.211> 96 64<38.8054 112.592> VStem: 283 16<88.1179 101.401> LayerCount: 2 Fore SplineSet 1 70 m 0 14 108 35 160 95 160 c 0 150 160 169 95 210 68 c 0 216 64 222 62 229 62 c 0 250 62 271 80 283 98 c 0 288 106 302 100 299 90 c 0 286 50 265 0 205 0 c 0 150 0 137 65 90 92 c 0 85 95 80 96 75 96 c 0 55 96 32 79 17 61 c 0 10 53 -2 61 1 70 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE610 Encoding: 109 58896 109 Width: 300 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 25 0 300 l 25 300 300 l 25 300 0 l 25 265 0 l 25 265 180 l 25 35 180 l 29 35 0 l 29 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE612 Encoding: 110 58898 110 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 105 0 m 25 0 450 l 29 40 450 l 29 125 90 l 25 210 450 l 29 250 450 l 29 145 0 l 25 105 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE614 Encoding: 111 58900 111 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet 100 25 m 28 141 25 175 59 175 100 c 28 175 141 141 175 100 175 c 28 59 175 25 141 25 100 c 28 25 59 59 25 100 25 c 28 100 0 m 28 45 0 0 45 0 100 c 28 0 155 45 200 100 200 c 28 155 200 200 155 200 100 c 28 200 45 155 0 100 0 c 28 EndSplineSet Validated: 1 EndChar StartChar: uniE618 Encoding: 112 58904 112 Width: 280 Flags: HMW LayerCount: 2 Fore SplineSet -200 0 m 1 -200 110 -110 200 0 200 c 24 110 200 200 110 200 0 c 1 170 0 l 1 170 99 99 170 0 170 c 24 -99 170 -170 99 -170 0 c 1 -200 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE624 Encoding: 113 58916 113 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 90 120 m 0 110 120 132 165 132 200 c 28 132 235 110 280 90 280 c 0 70 280 48 235 48 200 c 24 48 165 70 120 90 120 c 0 72 0 m 25 72 100 l 17 37 110 0 144.818359375 0 200 c 0 0 255 45 300 90 300 c 0 135 300 180 255 180 200 c 0 180 144.818359375 143 110 108 100 c 0 108 0 l 25 72 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE630 Encoding: 114 58928 114 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet 84 102 m 1 36.534641833 109.00393025 -7.1054273576e-15 150.442560477 0 200 c 24 0 255 45 300 100 300 c 24 155 300 200 255 200 200 c 24 200 150.442560477 163.465358167 109.00393025 116 102 c 1 116 101.288034818 l 1 116 0 l 25 84 0 l 25 84 101.288034818 l 1 84 102 l 1 116 126 m 5 149.481193966 134.213607404 175 164.479867787 175 200 c 24 175 241 141 275 100 275 c 24 59 275 25 241 25 200 c 24 25 164.479867787 50.5188060342 134.213607404 84 126 c 1 84 126.757636954 l 1 84 200 l 25 116 200 l 25 116 126.757636954 l 1 116 126 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE650 Encoding: 115 58960 115 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> 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 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 146 384 124 359 75 359 c 0x37ef 35 359 0 389 0 423 c 0 0 505 74 639 277 639 c 3 460 639 516 565 516 503 c 0 516 439 482 402 420 402 c 0 384 402 344 435 320 493 c 1 344 507 l 1 366 469 373 460 401 460 c 0 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 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 630 49 675 80 675 116 c 0 675 217 703 283 835 318 c 1 761 420 580 491 580 509 c 2 580 510 l 1 835 427 946 304 946 166 c 0 946 75 889 1 799 1 c 0 767 1 730 7 699 58 c 1xa7ef 672 15 633 0 603 0 c 3 532 0 504 33 483 59 c 1 425 9 405 -4 383 -4 c 0 361 -4 347 9 312 50 c 1 294 81 282 95 268 95 c 0 246 95 227 72 207 59 c 0 134 12 102 1 84 1 c 0 77 1 74 4 74 8 c 0 74 23 108 71 152 90 c 0x67ef 982 -2 m 3xa7cf 967 -2 952 12 952 28 c 3 952 44 967 58 982 58 c 3 998 58 1012 44 1012 28 c 3 1012 12 1000 -2 982 -2 c 3xa7cf 498 126 m 1 563 185 585 210 585 247 c 0 585 253 583 261 581 268 c 0 577 284 568 286 555 286 c 0 520 286 481 246 481 186 c 0x27ef 481 159 484 151 498 126 c 1 797 40 m 1 864 44 887 102 887 174 c 0 887 218 870 274 846 302 c 1 758 262 735 202 735 117 c 0 735 73 753 50 797 40 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE655 Encoding: 116 58965 116 Width: 540 Flags: W HStem: 68 93<79.5149 155.133> 182 17<220 222.173 252.655 264.303> 192 94<18.5323 100.176 375.888 460.387> 230 56<60.9363 133.273> 230 18<300.618 361.695> 274 18<213.64 227.572 256.894 258> 315 97<73.5817 155.121 322.704 406.413> VStem: 179 23<209.875 223.47 254.181 264.625> 192 98<17.9339 97.9009 381.276 451.65> 230 18<113.95 174.519 300.936 363.797> 278 17<212.458 224.186 254.5 261> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
2198 2199 2200 2201 2202 2203 2204 | 135 161 150 163 166 179 c 0 173 186 179 196 179 204 c 0 179 219 166 230 141 230 c 0xcb40 EndSplineSet Validated: 1 EndChar | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | > > > > | | | | | | | < < | | | | < < | < | | 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 | 135 161 150 163 166 179 c 0 173 186 179 196 179 204 c 0 179 219 166 230 141 230 c 0xcb40 EndSplineSet Validated: 1 EndChar StartChar: uniE910 Encoding: 117 59664 117 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 45 0 m 28 45 -113 137 -205 250 -205 c 28 363 -205 455 -113 455 0 c 28 455 113 363 205 250 205 c 28 137 205 45 113 45 0 c 28 0 0 m 28 0 139 111 250 250 250 c 28 388 250 500 139 500 0 c 28 500 -138 389 -250 250 -250 c 28 112 -250 0 -138 0 0 c 28 250 -60 m 7 217 -60 190 -33 190 0 c 7 190 33 217 60 250 60 c 7 283 60 310 33 310 0 c 7 310 -33 283 -60 250 -60 c 7 EndSplineSet Validated: 1 EndChar StartChar: uniE911 Encoding: 118 59665 118 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 45 0 m 24 45 -113 137 -205 250 -205 c 24 363 -205 455 -113 455 0 c 24 455 113 363 205 250 205 c 24 137 205 45 113 45 0 c 24 0 0 m 24 0 139 111 250 250 250 c 24 388 250 500 139 500 0 c 24 500 -138 389 -250 250 -250 c 24 112 -250 0 -138 0 0 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE912 Encoding: 119 59666 119 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 228 350 m 1 273 350 l 1 273 250 l 1 400 237 500 131 500 0 c 0 500 -130 401 -237 273 -250 c 1 273 -350 l 5 228 -350 l 5 228 -249 l 1 100 -238 0 -131 0 0 c 0 0 132 99 238 228 249 c 1 228 350 l 1 228 -203.826663616 m 1 228 203.826663616 l 1 125.298009966 192.809355922 45 105.569124751 45 0 c 0 45 -105.569124751 125.298009966 -192.809355922 228 -203.826663616 c 1 273 -203.716902537 m 1 375.222749877 -192.242459755 455 -105.22624212 455 0 c 0 455 105.22624212 375.222749877 192.242459755 273 203.716902537 c 1 273 -203.716902537 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE914 Encoding: 120 59668 120 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 463 130 m 0 464 127 465 123 465 120 c 0 465 112 461 103 454 99 c 0 451 97 447 96 443 96 c 0 435 96 427 100 420 110 c 1 386 173 323 205 250 205 c 8 137 205 45 113 45 0 c 24 45 -113 137 -205 250 -205 c 16 330 -205 386 -174 420 -110 c 0 424 -102 434 -97 444 -97 c 0 448 -97 451 -97 454 -99 c 0 462 -104 466 -111 466 -118 c 0 466 -122 465 -126 463 -130 c 0 420 -211 350 -250 250 -250 c 8 112 -250 0 -138 0 0 c 24 0 139 111 250 250 250 c 0 344 250 420 210 463 130 c 0 250 -60 m 3 217 -60 190 -33 190 0 c 3 190 33 217 60 250 60 c 3 283 60 310 33 310 0 c 3 310 -33 283 -60 250 -60 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE915 Encoding: 121 59669 121 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 463 130 m 0 464 127 465 123 465 120 c 0 465 112 461 103 454 99 c 0 451 97 447 96 443 96 c 0 435 96 427 100 420 110 c 1 386 173 323 205 250 205 c 8 137 205 45 113 45 0 c 24 45 -113 137 -205 250 -205 c 16 330 -205 386 -174 420 -110 c 0 424 -102 434 -97 444 -97 c 0 448 -97 451 -97 454 -99 c 0 462 -104 466 -111 466 -118 c 0 466 -122 465 -126 463 -130 c 0 420 -211 350 -250 250 -250 c 8 112 -250 0 -138 0 0 c 24 0 139 111 250 250 250 c 0 344 250 420 210 463 130 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE918 Encoding: 122 59672 122 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 273 249 m 1 356 243 424 203 463 130 c 0 464 127 465 123 465 120 c 0 465 112 461 103 454 99 c 0 451 97 447 96 443 96 c 0 435 96 427 100 420 110 c 0 390 166 336 198 273 204 c 1 273 -204 l 1 341 -199 389 -168 420 -110 c 0 424 -102 434 -97 444 -97 c 0 448 -97 451 -97 454 -99 c 0 462 -104 466 -111 466 -118 c 0 466 -122 465 -126 463 -130 c 0 423 -205 361 -244 273 -249 c 1 273 -350 l 1 228 -350 l 1 228 -249 l 1 100 -238 0 -131 0 0 c 0 0 132 99 238 228 249 c 1 228 350 l 1 273 350 l 1 273 249 l 1 228 -204 m 1 228 204 l 1 125 193 45 106 45 0 c 0 45 -106 125 -193 228 -204 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE920 Encoding: 123 59680 123 Width: 120 Flags: HMW LayerCount: 2 Fore SplineSet 60 -60 m 3 27 -60 0 -33 0 0 c 3 0 33 27 60 60 60 c 3 93 60 120 33 120 0 c 3 120 -33 93 -60 60 -60 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE925 Encoding: 124 59685 124 Width: 45 Flags: HMW LayerCount: 2 Fore SplineSet 45 350 m 9 45 -350 l 1 0 -350 l 9 0 350 l 1 45 350 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE95D Encoding: 125 59741 125 Width: 540 Flags: HMW LayerCount: 2 Fore SplineSet 30 70 m 25 30 -70 l 25 300 -70 l 25 300 70 l 25 30 70 l 25 0 190 m 25 30 190 l 25 30 140 l 25 300 140 l 25 300 190 l 25 330 190 l 1 330 -750 l 29 300 -750 l 5 300 -140 l 1 30 -140 l 25 30 -190 l 25 0 -190 l 25 0 190 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniEA02 Encoding: 126 59906 126 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 0 65 m 25 137 250 l 25 221 135 l 25 307 250 l 25 389 137 l 1 564 370 l 1 598 348 l 1 338 0 l 1 254 116 l 25 168 0 l 25 85 112 l 25 32 41 l 25 0 65 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniEAA4 Encoding: 127 60068 127 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 0 270 m 0 30 300 45 311 85 311 c 0 125 311 170 250 210 250 c 0 222 250 230 250 250 270 c 0 252 272 256 273 260 273 c 0 266 273 272 271 272 264 c 0 272 257 266 246 250 230 c 0 220 200 205 189 165 189 c 0 125 189 80 250 40 250 c 0 28 250 20 250 0 230 c 0 -2 228 -7 226 -11 226 c 0 -17 226 -22 229 -22 236 c 0 -22 243 -17 253 0 270 c 0 EndSplineSet Validated: 1 EndChar EndChars EndSplineFont |
Changes to modules/MIDI.js.
1 2 | // MIDI.js - module to handle the %%MIDI parameters // | | | 1 2 3 4 5 6 7 8 9 10 | // MIDI.js - module to handle the %%MIDI parameters // // Copyright (C) 2019 Jean-Francois Moine - GPL3+ // // This module is loaded when "%%MIDI" appears in a ABC source. // // Parameters (see abcMIDI for details) // %%MIDI channel n // %%MIDI program n // %%MIDI control k v |
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
var pit = Number(p)
if (isNaN(pit))
return
p = ((pit / 12) | 0) * 7 - 19; // octave
pit = pit % 12; // in octave
p += pits[pit]
note = {
| | < | | | | 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 |
var pit = Number(p)
if (isNaN(pit))
return
p = ((pit / 12) | 0) * 7 - 19; // octave
pit = pit % 12; // in octave
p += pits[pit]
note = {
pit: p
}
if (accs[pit])
note.acc = accs[pit]
return note
} // tonote()
// normalize a note for mapping
function norm(p) {
var a = p.match(/^([_^=]*)([A-Ga-g])([,']*)$/) // '
if (!a)
return
if (p.match(/[A-Z]/)) {
p = p.toLowerCase();
if (p.indexOf("'") > 0)
p = p.replace("'", '')
else
p += ','
}
return p
} // norm()
var n, v, s,
maps = this.get_maps(),
a = parm.split(/\s+/)
switch (a[1]) {
case "channel":
if (a[2] != "10")
break
this.set_v_param("midictl", "0 1") // channel 10 is bank 128 program 0
break
case "drummap":
if (this.cfmt().sound != "play")
break
//fixme: should have a 'MIDIdrum' per voice?
n = norm(a[2]);
v = tonote(a[3]);
if (!n || !v) {
this.syntax(1, this.errs.bad_val, "%%MIDI drummap")
break
}
if (!maps.MIDIdrum)
maps.MIDIdrum = {}
maps.MIDIdrum[n] = [null, v];
this.set_v_param("mididrum", "MIDIdrum")
break
|
| ︙ | ︙ | |||
93 94 95 96 97 98 99 |
return
}
v = parseInt(a[3])
if (isNaN(v) || v < 0 || v > 127) {
this.syntax(1, "Bad controller value in %%MIDI")
return
}
| > > > | > > > | | 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 |
return
}
v = parseInt(a[3])
if (isNaN(v) || v < 0 || v > 127) {
this.syntax(1, "Bad controller value in %%MIDI")
return
}
if (this.cfmt().sound != "play")
break
if (this.parse.state >= 2) {
s = this.new_block("midictl");
s.ctrl = n;
s.val = v
}
break
}
}, // do_midi()
// set the MIDI parameters in the current voice
set_midi: function(a) {
var i, item,
curvoice = this.get_curvoice()
for (i = 0; i < a.length; i++) {
switch (a[i]) {
case "instr=": // %%MIDI program
curvoice.instr = a[i + 1]
break
case "midictl=": // %%MIDI control
if (!curvoice.midictl)
curvoice.midictl = []
item = a[i + 1].split(' ');
curvoice.midictl[item[0]] = Number(item[1])
break
case "mididrum=": // %%MIDI drummap note midipitch
if (!curvoice.map)
curvoice.map = {}
curvoice.map = a[i + 1]
|
| ︙ | ︙ | |||
133 134 135 136 137 138 139 140 141 142 |
else
of(text)
},
set_vp: function(of, a) {
abc2svg.MIDI.set_midi.call(this, a);
of(a)
}
} // MIDI
| > > > > > | < < < < < < < < | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
else
of(text)
},
set_vp: function(of, a) {
abc2svg.MIDI.set_midi.call(this, a);
of(a)
},
set_hooks: function(abc) {
abc.do_pscom = abc2svg.MIDI.do_pscom.bind(abc, abc.do_pscom);
abc.set_vp = abc2svg.MIDI.set_vp.bind(abc, abc.set_vp)
}
} // MIDI
abc2svg.modules.hooks.push(abc2svg.MIDI.set_hooks);
// the module is loaded
abc2svg.modules.MIDI.loaded = true
|
Changes to modules/ambitus.js.
1 2 | // ambitus.js - module to insert an ambitus at start of a voice // | | | < < < < | > > | | | | < < < | < < < > | | > | < > > > > > > > | < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// ambitus.js - module to insert an ambitus at start of a voice
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%ambitus" appears in a ABC source.
//
// Parameters
// %%ambitus 1
abc2svg.ambitus = {
do_ambitus: function() {
var C = abc2svg.C,
s, v, p_v, min, max,
voice_tb = this.get_voice_tb()
for (v = 0; v < voice_tb.length; v++) {
p_v = voice_tb[v];
if (p_v.second)
continue
min = 100;
max = -100
// search the top and bottom pitches
for (s = p_v.sym; s; s = s.next) {
if (s.type != C.NOTE)
continue
if (s.notes[s.nhd].pit > max)
max = s.notes[s.nhd].pit
if (s.notes[0].pit < min)
min = s.notes[0].pit
}
if (min == 100)
continue // no note
s = p_v.clef;
s.stem = 1;
s.head = C.FULL;
s.stemless = true;
s.nhd = 1;
s.notes = [{
dur: C.BLEN / 4,
pit: min,
shhd: 0
},{
dur: C.BLEN / 4,
pit: max,
shhd: 0
}]
}
}, // do_ambitus()
draw_symbols: function(of, p_voice) {
var staff_tb = this.get_staff_tb(),
s = p_voice.sym
if (s.clef_type != undefined && s.nhd > 0) {
s.x -= 26;
this.set_scale(s);
this.draw_note(s)
if (s.notes[1].pit - s.notes[0].pit > 4) {
this.xypath(s.x, 3 * (s.notes[1].pit - 18) + staff_tb[s.st].y);
this.out_svg('v' +
((s.notes[1].pit - s.notes[0].pit) * 3).toFixed(1) +
'" stroke-width=".6"/>\n');
}
s.x += 26;
p_voice.clef.nhd = 0
}
of(p_voice)
}, // draw_symbols()
set_pitch: function(of, last_s) {
of(last_s)
if (!last_s && this.cfmt().ambitus)
abc2svg.ambitus.do_ambitus.call(this)
},
set_fmt: function(of, cmd, param, lock) {
if (cmd == "ambitus") {
this.cfmt().ambitus = param
return
}
of(cmd, param, lock)
},
set_width: function(of, s) {
if (s.clef_type != undefined && s.nhd > 0) {
s.wl = 40;
s.wr = 12
} else {
of(s)
}
},
set_hooks: function(abc) {
abc.draw_symbols = abc2svg.ambitus.draw_symbols.bind(abc, abc.draw_symbols);
abc.set_pitch = abc2svg.ambitus.set_pitch.bind(abc, abc.set_pitch);
abc.set_format = abc2svg.ambitus.set_fmt.bind(abc, abc.set_format);
abc.set_width = abc2svg.ambitus.set_width.bind(abc, abc.set_width)
}
} // ambitus
abc2svg.modules.hooks.push(abc2svg.ambitus.set_hooks);
// the module is loaded
abc2svg.modules.ambitus.loaded = true
|
Changes to modules/break.js.
1 2 | // break.js - module to handle the %%break command // | | | | | | | | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// break.js - module to handle the %%break command
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%break" appears in a ABC source.
//
// Parameters
// %%break measure_nb [":" num "/" den] [" " measure ...]*
abc2svg.break = {
// get the %%break parameters
get_break: function(parm) {
var C = abc2svg.C,
b, c, d, sq,
a = parm.split(/[ ,]/),
cfmt = this.cfmt()
if (!cfmt.break)
cfmt.break = []
for (n = 1; n < a.length; n++) {
b = a[n];
c = b.match(/(\d+)([a-z]?)(:\d+\/\d+)?/)
if (!c) {
this.syntax(1, this.errs.bad_val, "%%break")
continue
}
if (c[2])
sq = c[2].charCodeAt(0) - 0x61
if (!c[3]) {
cfmt.break.push({ // on measure bar
m: c[1],
t: 0,
sq: sq})
continue
}
d = c[3].match(/:(\d+)\/(\d+)/)
if (!d || d[2] < 1) {
this.syntax(1, "Bad denominator in %%break")
continue
}
cfmt.break.push({
m: c[1],
t: d[1] * C.BLEN / d[2],
sq: sq})
}
}, // get_break()
// insert the EOLs of %%break
do_break: function() {
var i, m, t, brk, seq,
voice_tb = this.get_voice_tb()
v = this.get_cur_sy().top_voice,
s1 = voice_tb[v].sym,
cfmt = this.cfmt()
for (i = 0; i < cfmt.break.length; i++) {
brk = cfmt.break[i];
m = brk.m
for (s = s1; s; s = s.next) {
if (s.bar_num == m)
break
}
if (!s)
continue
if (brk.sq) {
seq = brk.sq
for (s = s.ts_next; s; s = s.ts_next) {
if (s.bar_num == m) {
if (--seq == 0)
break
}
}
if (!s)
continue
}
|
| ︙ | ︙ | |||
99 100 101 102 103 104 105 106 107 108 |
of(text)
},
set_bar_num: function(of) {
of()
if (this.cfmt().break)
abc2svg.break.do_break.call(this)
}
} // break
| > > > > > | < < < < < < < | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
of(text)
},
set_bar_num: function(of) {
of()
if (this.cfmt().break)
abc2svg.break.do_break.call(this)
},
set_hooks: function(abc) {
abc.do_pscom = abc2svg.break.do_pscom.bind(abc, abc.do_pscom);
abc.set_bar_num = abc2svg.break.set_bar_num.bind(abc, abc.set_bar_num)
}
} // break
abc2svg.modules.hooks.push(abc2svg.break.set_hooks);
// the module is loaded
abc2svg.modules.break.loaded = true
|
Changes to modules/capo.js.
1 2 | // capo.js - module to add a capo chord line // | | | 1 2 3 4 5 6 7 8 9 10 |
// capo.js - module to add a capo chord line
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%capo" appears in a ABC source.
//
// Parameters
// %%capo n 'n' is the capo fret number
abc2svg.capo = {
|
| ︙ | ︙ | |||
53 54 55 56 57 58 59 |
set_fmt: function(of, cmd, param, lock) {
if (cmd == "capo") {
this.cfmt().capo = param
return
}
of(cmd, param, lock)
| | > | > > | > | < < < < < < < < | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
set_fmt: function(of, cmd, param, lock) {
if (cmd == "capo") {
this.cfmt().capo = param
return
}
of(cmd, param, lock)
},
set_hooks: function(abc) {
abc.gch_build = abc2svg.capo.gch_build.bind(abc, abc.gch_build);
abc.output_music = abc2svg.capo.output_music.bind(abc, abc.output_music);
abc.set_format = abc2svg.capo.set_fmt.bind(abc, abc.set_format)
}
} // capo
abc2svg.modules.hooks.push(abc2svg.capo.set_hooks);
// the module is loaded
abc2svg.modules.capo.loaded = true
|
Changes to modules/clip.js.
1 2 | // clip.js - module to handle the %%clip command // | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// clip.js - module to handle the %%clip command
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%clip" appears in a ABC source.
//
// Parameters
// %%clip start_measure_nb [":" num "/" den] "-" end_measure_nb [":" num "/" den]
abc2svg.clip = {
get_clip: function(parm) {
var C = abc2svg.C
// get the start/stop points
function get_symsel(a) {
var j, d, sq,
b = a.match(/(\d+)([a-z]?)(:\d+\/\d+)?/)
if (!b)
return
if (b[2])
sq = b[2].charCodeAt(0) - 0x61
if (!b[3])
return {m: b[1], t: 0, sq: sq} // on measure bar
a = b[3].match(/:(\d+)\/(\d+)/)
if (!a || a[2] < 1)
return
return {m: b[1], t: a[1] * C.BLEN / a[2], sq: sq}
} // get_symsel()
var b, c,
a = parm.split(/[ -]/)
if (a.length != 3) {
this.syntax(1, this.errs.bad_val, "%%clip")
|
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
return
}
this.cfmt().clip = [b, c]
}, // get_clip()
// cut the tune
do_clip: function() {
| < < | < < | | | | | 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 |
return
}
this.cfmt().clip = [b, c]
}, // get_clip()
// cut the tune
do_clip: function() {
var C = abc2svg.C
voice_tb = this.get_voice_tb(),
cfmt = this.cfmt()
// go to a global (measure + time)
function go_global_time(s, sel) {
var s2, bar_time, seq
if (sel.m <= 1) { // special case: there is no measure 0/1
if (sel.m == 1) {
for (s2 = s; s2; s2 = s2.ts_next) {
if (s2.type == C.BAR
&& s2.time != 0)
break
}
if (s2.time < voice_tb[this.get_cur_sy().top_voice].
meter.wmeasure)
s = s2
}
} else {
for ( ; s; s = s.ts_next) {
if (s.type == C.BAR
&& s.bar_num >= sel.m)
break
}
if (!s)
return // null
if (sel.sq) {
seq = sel.sq
for (s = s.ts_next; s; s = s.ts_next) {
if (s.type == C.BAR
&& s.bar_num == sel.m) {
if (--seq == 0)
break
}
}
if (!s)
return // null
|
| ︙ | ︙ | |||
122 123 124 125 126 127 128 |
return
}
// update the start of voices
sy = this.get_cur_sy()
for (s2 = this.get_tsfirst(); s2 != s; s2 = s2.ts_next) {
switch (s2.type) {
| | | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
return
}
// update the start of voices
sy = this.get_cur_sy()
for (s2 = this.get_tsfirst(); s2 != s; s2 = s2.ts_next) {
switch (s2.type) {
case C.CLEF:
s2.p_v.clef = s2
break
case C.KEY:
s2.p_v.key = this.clone(s2.as.u.key)
break
case C.METER:
s2.p_v.meter = this.clone(s2.as.u.meter)
break
case C.STAVES:
sy = s2.sy;
this.set_cur_sy(sy)
break
}
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
|
| ︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 |
of(text)
},
set_bar_num: function(of) {
of()
if (this.cfmt().clip)
abc2svg.clip.do_clip.call(this)
}
} // clip
| > > > > > | < < < < < < < < | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
of(text)
},
set_bar_num: function(of) {
of()
if (this.cfmt().clip)
abc2svg.clip.do_clip.call(this)
},
set_hooks: function(abc) {
abc.do_pscom = abc2svg.clip.do_pscom.bind(abc, abc.do_pscom);
abc.set_bar_num = abc2svg.clip.set_bar_num.bind(abc, abc.set_bar_num)
}
} // clip
abc2svg.modules.hooks.push(abc2svg.clip.set_hooks);
// the module is loaded
abc2svg.modules.clip.loaded = true
|
Changes to modules/combine.js.
1 2 | // combine.js - module to add a combine chord line // | | < | < < < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// combine.js - module to add a combine chord line
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%voicecombine" appears in a ABC source.
//
// Parameters
// %%voicecombine n 'n' is the combine level
abc2svg.combine = {
// function called at start of the generation when multi-voices
comb_v: function() {
var C = abc2svg.C
// check if voice combine may occur
function may_combine(s) {
var nhd2,
s2 = s.ts_next
if (!s2 || (s2.type != C.NOTE && s2.type != C.REST))
return false
if (s2.v == s.v
|| s2.st != s.st
|| s2.time != s.time
|| s2.dur != s.dur)
return false
if (s.combine <= 0
&& s2.type != s.type)
return false
// if (s2.a_dd) { //fixme: should check the double decorations
// return false
// }
if (s.a_gch && s2.a_gch)
return false
if (s.type == C.REST) {
if (s.type == s2.type && s.invis && !s2.invis)
return false
return true
}
if (s2.a_ly
|| s2.sl1 || s2.sl2
|| s2.slur_start || s2.slur_end)
|
| ︙ | ︙ | |||
75 76 77 78 79 80 81 | } s.ymx = 3 * (s.notes[nhd].pit - 18) + 4; s.ymn = 3 * (s.notes[0].pit - 18) - 4; // force the tie directions type = s.notes[0].ti1 | | | | | | | | 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 |
}
s.ymx = 3 * (s.notes[nhd].pit - 18) + 4;
s.ymn = 3 * (s.notes[0].pit - 18) - 4;
// force the tie directions
type = s.notes[0].ti1
if ((type & 0x0f) == C.SL_AUTO)
s.notes[0].ti1 = C.SL_BELOW | (type & ~C.SL_DOTTED);
type = s.notes[nhd].ti1
if ((type & 0x0f) == C.SL_AUTO)
s.notes[nhd].ti1 = C.SL_ABOVE | (type & ~C.SL_DOTTED)
} // combine_notes()
// combine 2 voices
function do_combine(s) {
var s2, nhd, nhd2, type
while (1) {
nhd = s.nhd;
s2 = s.ts_next;
nhd2 = s2.nhd
if (s.type != s2.type) { // if note and rest
if (s2.type != C.REST) {
s2 = s;
s = s2.ts_next
}
} else if (s.type == C.REST) {
if (s.invis
&& !s2.invis)
delete s.invis
} else {
combine_notes.call(this, s, s2)
}
|
| ︙ | ︙ | |||
123 124 125 126 127 128 129 |
}
} // do_combine()
var s, s2, g, i, r
for (s = this.get_tsfirst(); s; s = s.ts_next) {
switch (s.type) {
| | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
}
} // do_combine()
var s, s2, g, i, r
for (s = this.get_tsfirst(); s; s = s.ts_next) {
switch (s.type) {
case C.REST:
if (s.combine == undefined || s.combine < 0)
continue
if (may_combine.call(this, s))
do_combine.call(this, s)
continue
default:
continue
case C.NOTE:
if (s.combine == undefined || s.combine <= 0)
continue
break
}
if (!s.beam_st)
continue
|
| ︙ | ︙ | |||
156 157 158 159 160 161 162 |
break
}
//fixme: may have rests in beam
if (s2.beam_end)
break
do {
s2 = s2.next
| | | | 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 |
break
}
//fixme: may have rests in beam
if (s2.beam_end)
break
do {
s2 = s2.next
} while (s2.type != C.NOTE && s2.type != C.REST)
}
if (!s2)
continue
s2 = s
while (1) {
do_combine.call(this, s2)
//fixme: may have rests in beam
if (s2.beam_end)
break
do {
s2 = s2.next
} while (s2.type != C.NOTE && s2.type != C.REST)
}
}
}, // comb_v()
do_pscom: function(of, text) {
if (text.slice(0, 13) == "voicecombine ")
this.set_v_param("combine", text.split(/[ \t]/)[1])
|
| ︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 |
for (i = 0; i < a.length; i++) {
if (a[i] == "combine=") { // %%voicecombine
curvoice.combine = a[i + 1]
break
}
}
of(a)
}
} // combine
| > > > > > > > | < < < < < < < < < < | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
for (i = 0; i < a.length; i++) {
if (a[i] == "combine=") { // %%voicecombine
curvoice.combine = a[i + 1]
break
}
}
of(a)
},
set_hooks: function(abc) {
abc.do_pscom = abc2svg.combine.do_pscom.bind(abc, abc.do_pscom);
abc.new_note = abc2svg.combine.new_note.bind(abc, abc.new_note);
abc.set_stem_dir = abc2svg.combine.set_stem_dir.bind(abc, abc.set_stem_dir);
abc.set_vp = abc2svg.combine.set_vp.bind(abc, abc.set_vp)
}
} // combine
abc2svg.modules.hooks.push(abc2svg.combine.set_hooks);
// the module is loaded
abc2svg.modules.voicecombine.loaded = true
|
Changes to modules/diag.js.
1 2 | // diag.js - module to insert guitar chord diagrams // | | | 1 2 3 4 5 6 7 8 9 10 |
// diag.js - module to insert guitar chord diagrams
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%diagram" appears in a ABC source.
//
// Parameters
// %%diagram 1
abc2svg.diag = {
|
| ︙ | ︙ | |||
484 485 486 487 488 489 490 491 492 493 |
set_fmt: function(of, cmd, param, lock) {
if (cmd == "diagram") {
this.cfmt().diag = param
return
}
of(cmd, param, lock)
}
} // diag
| > > > > > | < < < < < < | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
set_fmt: function(of, cmd, param, lock) {
if (cmd == "diagram") {
this.cfmt().diag = param
return
}
of(cmd, param, lock)
},
set_hooks: function(abc) {
abc.output_music = abc2svg.diag.output_music.bind(abc, abc.output_music);
abc.set_format = abc2svg.diag.set_fmt.bind(abc, abc.set_format)
}
} // diag
abc2svg.modules.hooks.push(abc2svg.diag.set_hooks);
// the module is loaded
abc2svg.modules.diagram.loaded = true
|
Added modules/equalbars.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// equalbars.js - module to set equal spaced measure bars
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%equalbars" appears in a ABC source.
//
// Parameters
// %%equalbars bool
abc2svg.equalbars = {
// new tune - clear the width of the start of the staff
output_music: function(of) {
this.equalbars_d = 0;
of()
},
// get the equalbars parameter
set_fmt: function(of, cmd, param, lock) {
if (cmd == "equalbars")
this.cfmt().equalbars = this.get_bool(param)
else
of(cmd, param, lock)
},
// adjust the symbol offsets of a music line
set_sym_glue: function(of, width) {
var C = abc2svg.C,
s, s2, w, i, n, x, g, t, t0,
bars = [],
tsfirst = this.get_tsfirst();
of(width) // compute the x offset of the symbols
if (!this.cfmt().equalbars)
return
// search the first note/rest/bar
for (s2 = tsfirst; s2; s2 = s2.ts_next) {
if (!s2.seqst)
continue
switch (s2.type) {
default:
continue
case C.GRACE:
case C.MREST:
case C.NOTE:
case C.REST:
case C.SPACE:
break
}
break
}
if (!s2)
return
// build an array of the bars
t0 = t = s2.time
for (s = s2; s.ts_next; s = s.ts_next) {
if (s.type == C.BAR && s.seqst) {
bars.push([s, s.time - t]);
t = s.time
}
}
bars.push([s, s.time - t]);
t = s.time
if (s.dur)
t += s.dur;
n = bars.length
if (n <= 1)
return // one or no bar
// set the measure parameters
x = s2.type == C.GRACE ? s2.extra.x : s2.x;
d = this.equalbars_d
if (!d)
d = this.equalbars_d = x; // offset first note/rest
w = (width - d) / (t - t0) // width per time unit
// loop on the bars
for (i = 0; i < n; i++) {
s = bars[i][0]; // next bar
f = w * bars[i][1] / (s.x - x)
// and update the x offsets
for ( ; s2 != s; s2 = s2.ts_next) {
if (s2.type == C.GRACE) {
for (g = s2.extra; g; g = g.next)
g.x = d + (g.x - x) * f
} else if (s2.x) {
s2.x = d + (s2.x - x) * f
}
}
d += w * bars[i][1];
x = s2.x
while (1) {
s2.x = d;
s2 = s2.ts_next
if (!s2 || s2.seqst)
break
}
if (!s2)
break
}
}, // set_sym_glue()
set_hooks: function(abc) {
abc.output_music = abc2svg.equalbars.output_music.bind(abc, abc.output_music);
abc.set_format = abc2svg.equalbars.set_fmt.bind(abc, abc.set_format);
abc.set_sym_glue = abc2svg.equalbars.set_sym_glue.bind(abc, abc.set_sym_glue)
}
} // equalbars
abc2svg.modules.hooks.push(abc2svg.equalbars.set_hooks);
// the module is loaded
abc2svg.modules.equalbars.loaded = true
|
Changes to modules/grid.js.
1 2 | // grid.js - module to insert a chord grid before or after a tune // | | > > | > > > > | | < < < < < < < < < | | > | | | | | | > > | > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > < < | < | < < | < < < < < < < < < < < | > | | > | > > > | | | > | > > | > | | | | < | | > | > | | > < | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | | | | | | | | | > > > > > > > > > | | > | | | > > > | > | > > > > | < < < < | > | | | | > > > > | > < < < < < < < < > | | > > > > > | < | > > > > > > > > > > > > > > > > > > > > | | > > > > > | < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 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 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 |
// grid.js - module to insert a chord grid before or after a tune
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%grid" appears in a ABC source.
//
// Parameters
// %%grid <n> [include=<list>] [nomusic] [norepeat]
// <n> = number of columns (1: auto)
// > 0: above the tune, < 0: under the tune
// <list> = comma separated list of (continuous) measure numbers
// 'nomusic' displays only the grid
// 'norepeat' omits the ':' indications
// %%gridfont font_name size (default: 'serif 16')
abc2svg.grid = {
// function called before tune generation
do_grid: function() {
var C = abc2svg.C,
tsfirst = this.get_tsfirst(),
voice_tb = this.get_voice_tb(),
img, font_cl, cls,
cfmt = this.cfmt(),
grid = cfmt.grid
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;
beat = C.BLEN / s.a_meter[0].bot[0] |0
if (s.a_meter[0].bot[0] == 8
&& s.a_meter[0].top[0] % 3 == 0)
beat = C.BLEN / 8 * 3
return beat
} // get_beat()
// generate the grid
function build_grid(chords, bars, font, wmx) {
var i, j, k, l, nr, line, bar, w, hr, x0, x, y, yl,
cell = '',
pcell = '',
cells = [],
nc = grid.n
// set some chord(s) in each cell
function set_chords() {
var i, ch,
pch = '-'
for (i = 0; i < chords.length; i++) {
ch = chords[i]
if (!ch[0])
ch[0] = pch
if (ch.length == 0)
continue
if (ch.length == 1) {
pch = ch[0]
continue
}
if (ch.length == 2) {
ch[2] = ch[1];
ch[1] = null;
pch = ch[2]
continue
}
if (ch.length == 3) {
pch = ch[2]
continue
}
if (!ch[2])
ch[2] = ch[1] || ch[0];
pch = ch[3]
}
} // set_chords()
// set some chords in each cell
set_chords()
// build the content of the cells
if (!grid.ls) {
cells = chords
} else { // with list of mesure numbers
bar = bars;
bars = []
for (i = 0; i < grid.ls.length; i++) {
l = grid.ls[i]
if (l.indexOf('-') < 0)
l = [l, l]
else
l = l.split('-')
for (k = l[0] - 1; k < l[1]; k++) {
if (!chords[k]) // error
break
cells.push(chords[k]);
bars.push(bar[k])
}
}
}
// get the number of columns and rows
if (nc < 0)
nc = -nc
if (nc < 3) // auto
nc = cells.length % 6 == 0 ? 6 : 8
if (nc > cells.length)
nc = cells.length;
nr = ((cells.length + nc - 1) / nc) |0;
hr = font.size * 2
if (wmx < hr * 1.4)
wmx = hr * 1.4; // cell width
w = wmx * nc
if (w > img.width) {
nc /= 2;
nr *= 2;
w /= 2
}
// build the SVG image
line = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"\n\
xmlns:xlink="http://www.w3.org/1999/xlink"\n\
color="black" width="' + img.width.toFixed(0) +
'px" height="' + (hr * nr + 6).toFixed(0) + 'px"';
i = cfmt.bgcolor
if (i)
line += ' style="background-color: ' + i + '"';
line += '>\n<style type="text/css">\n\
.mid {text-anchor:middle}\n'
if (cfmt.fullsvg || grid.nomusic)
line += '\
.stroke {stroke: currentColor; fill: none}\n\
.' + font_cl + ' {' + this.style_font(font) + '}\n';
line += '</style>\n'
// draw the lines
line += '<path class="stroke" d="\n';
x0 = (img.width - w) / 2;
y = 1
for (j = 0; j <= nr; j++) {
line += 'M' + x0.toFixed(1) + ' ' + y.toFixed(1) +
'h' + w.toFixed(1)+ '\n';
y += hr
}
x = x0
for (i = 0; i <= nc; i++) {
line += 'M' + x.toFixed(1) + ' 1v' + (hr * nr).toFixed(1) + '\n';
x += wmx
}
line += '"/>\n';
// insert the chords
y = 1 - hr / 2 + font.size * .3;
yl = 1
for (i = 0; i < cells.length; i++) {
cell = cells[i]
if (i % nc == 0) {
y += hr; // new row
yl += hr;
x = x0 + wmx / 2
}
if (cell.length > 1) {
line += '<path class="stroke" stroke-width="1" d="M' +
(x - wmx / 2).toFixed(1) + ' ' +
yl.toFixed(1) + 'l' +
wmx.toFixed(1) + ' -' + hr.toFixed(1) +
'"/>\n';
if (cell[1]) {
line += '<path class="stroke" stroke-width="1" d="M' +
(x - wmx / 2).toFixed(1) + ' ' +
(yl - hr).toFixed(1) + 'l' +
(wmx / 2).toFixed(1) + ' ' + (hr / 2).toFixed(1) +
'"/>\n';
line += '<text class="' + cls + '" style="font-size:' +
(font.size * .72).toFixed(1) + '" x="' +
(x - wmx / 3).toFixed(1) + '" y="' +
y.toFixed(1) + '">' +
cell[0] + '</text>\n';
line += '<text class="' + cls + '" style="font-size:' +
(font.size * .72).toFixed(1) + '" x="' +
x.toFixed(1) + '" y="' +
(y - hr / 3).toFixed(1) + '">' +
cell[1] + '</text>\n'
} else {
line += '<text class="' + cls + '" style="font-size:' +
(font.size * .72).toFixed(1) + '" x="' +
(x - wmx * .2).toFixed(1) + '" y="' +
(y - hr / 4).toFixed(1) + '">' +
cell[0] + '</text>\n'
}
if (cell.length >= 3) {
if (cell[3]) {
line += '<path class="stroke" stroke-width="1" d="M' +
x.toFixed(1) + ' ' +
(yl - hr / 2).toFixed(1) + 'l' +
(wmx / 2).toFixed(1) + ' ' + (hr / 2).toFixed(1) +
'"/>\n';
line += '<text class="' + cls + '" style="font-size:' +
(font.size * .72).toFixed(1) + '" x="' +
x.toFixed(1) + '" y="' +
(y + hr / 3).toFixed(1) + '">' +
cell[2] + '</text>\n';
line += '<text class="' + cls + '" style="font-size:' +
(font.size * .72).toFixed(1) + '" x="' +
(x + wmx / 3).toFixed(1) + '" y="' +
y.toFixed(1) + '">' +
cell[3] + '</text>\n'
} else {
line += '<text class="' + cls + '" style="font-size:' +
(font.size * .72).toFixed(1) + '" x="' +
(x + wmx * .2).toFixed(1) + '" y="' +
(y + hr / 4).toFixed(1) + '">' +
cell[2] + '</text>\n'
}
}
} else {
line += '<text class="' + cls + '" x="' +
x.toFixed(1) + '" y="' + y.toFixed(1) + '">' +
cell[0] + '</text>\n'
}
x += wmx
}
// show the repeat signs
y = 1 - hr / 2 + font.size * .3;
x = x0
for (i = 0; i < bars.length; i++) {
bar = bars[i]
if (bar[0] == ':')
line += '<text class="' + cls + '" x="' +
(x - 5).toFixed(1) +
'" y="' + y.toFixed(1) +
'" style="font-weight:bold;font-size:' +
(font.size + 2).toFixed(1) + '">:</text>\n'
if (i % nc == 0) {
y += hr; // new row
x = x0
}
if (bar[bar.length - 1] == ':')
line += '<text class="' + cls + '" x="' +
(x + 5).toFixed(1) +
'" y="' + y.toFixed(1) +
'" style="font-weight:bold;font-size:' +
(font.size + 2).toFixed(1) + '">:</text>\n'
x += wmx
}
return line + '</svg>'
} // build_grid()
var s, beat, cur_beat, i, beat_i, p_voice, n, font, wm, bt, w, wmx, rep,
bars = [],
chords = [],
chord = [];
img = this.get_img();
// get the beat
beat = get_beat(voice_tb[0].meter);
wm = voice_tb[0].meter.wmeasure;
// set the text style
if (!cfmt.gridfont)
this.param_set_font("gridfont", "serif 16");
font = this.get_font('grid');
font_cl = this.font_class(font)
cls = font_cl + " mid";
this.set_font('grid'); // (for strwh())
// scan the first voice of the tune
cur_beat = beat_i = n = wmx = 0;
bars.push('|')
for (s = voice_tb[0].sym; s; s = s.next) {
while (s.time > cur_beat) {
if (beat_i < 3) // only 2, 3 or 4 beats / measure...
beat_i++;
cur_beat += beat
}
switch (s.type) {
case C.NOTE:
case C.REST:
if (s.a_gch) { // search a chord symbol
for (i = 0; i < s.a_gch.length; i++) {
if (s.a_gch[i].type == 'g') {
if (!chord[beat_i]) {
chord[beat_i] = s.a_gch[i].text;
w = this.strwh(chord[beat_i])[0]
if (w > wmx)
wmx = w;
n++
}
break
}
}
}
break
case C.BAR:
bt = grid.norep ? '|' : s.bar_type
if (s.time < wm) { // if anacrusis
if (chord.length) {
chords.push(chord);
bars.push(bt)
} else {
bars[0] = bt
}
} else {
if (!s.bar_num) // if not normal measure bar
break
chords.push(chord);
bars.push(bt)
}
chord = [];
cur_beat = s.time; // synchronize in case of error
beat_i = 0
if (bt.indexOf(':'))
rep = true // some repeat
break
case C.METER:
beat = get_beat(s)
wm = s.wmeasure
break
}
}
if (n == 0) // no chord in this tune
return
if (chord.length != 0) {
bars.push('')
chords.push(chord)
}
// create the grid
wmx += this.strwh(rep ? ' ' : ' ')[0];
p_voice = voice_tb[this.get_top_v()]
s = {
type: C.BLOCK,
subtype: 'ml',
dur: 0,
time: 0,
p_v: p_voice,
v: p_voice.v,
text: build_grid.call(this, chords, bars, font, wmx)
}
if (grid.nomusic) { // if no music
this.set_tsfirst(s)
return
}
// and insert it in the tune
if (cfmt.grid.n < 0) { // below
for (var s2 = tsfirst; s2.ts_next; s2 = s2.ts_next)
;
s.time = s2.time;
s.prev = p_voice.last_sym;
s.ts_prev = s2;
p_voice.last_sym.next = s;
s2.ts_next = s
} else { // above
s.time = 0;
s.next = p_voice.sym;
s.ts_next = tsfirst;
tsfirst.ts_prev = s;
this.set_tsfirst(s);
p_voice.sym.prev = s;
p_voice.sym = s
}
}, // do_grid()
output_music: function(of) {
if (this.cfmt().grid)
abc2svg.grid.do_grid.call(this);
of()
},
set_fmt: function(of, cmd, parm, lock) {
if (cmd == "grid") {
if (!parm)
parm = "1";
parm = parm.split(/\s+/)
var grid = {n: Number(parm.shift())}
if (isNaN(grid.n)) {
if (parm.length) {
this.syntax(1, this.errs.bad_val, "%%grid")
return
}
grid.n = 1
}
while (parm.length) {
var item = parm.shift()
if (item == "norepeat")
grid.norep = true
else if (item == "nomusic")
grid.nomusic = true
else if (item.slice(0, 8) == "include=")
grid.ls = item.slice(8).split(',')
}
this.cfmt().grid = grid
return
}
of(cmd, parm, lock)
},
set_hooks: function(abc) {
abc.output_music = abc2svg.grid.output_music.bind(abc, abc.output_music);
abc.set_format = abc2svg.grid.set_fmt.bind(abc, abc.set_format)
}
} // grid
abc2svg.modules.hooks.push(abc2svg.grid.set_hooks);
// the module is loaded
abc2svg.modules.grid.loaded = true
|
Changes to modules/grid2.js.
1 2 | // grid2.js - module to replace a voice in the music by a chord grid // | | < > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// grid2.js - module to replace a voice in the music by a chord grid
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%grid2" appears in a ABC source.
//
// Parameters
// %%grid2 y
// This command must appear in a voice.
abc2svg.grid2 = {
// function called before tune generation
do_grid: function() {
var s, v, p_v,
voice_tb = this.get_voice_tb()
for (v = 0; v < voice_tb.length; v++) {
p_v = voice_tb[v]
if (!p_v.grid2)
continue
p_v.clef.invis = true; // no clef
p_v.key.k_sf = p_v.key.k_a_acc = 0; // no key signature
p_v.staffnonote = 2 // draw the staff
for (s = p_v.sym; s; s = s.next) {
if (s.dur) { // set all notes
s.invis = true; // as invisible
delete s.sl1; // with no slur
s.ti1 = 0 // and no tie
if (s.tf) // don't show the tuplets
s.tf[0] = 1
}
}
}
}, // do_grid()
// draw the chord symbol in the middle of the staff
draw_chosym: function(s) {
|
| ︙ | ︙ | |||
56 57 58 59 60 61 62 |
},
output_music: function(of) {
abc2svg.grid2.do_grid.call(this);
of()
},
| | | > > > > > > > > | < < < < < < < < < < | 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 |
},
output_music: function(of) {
abc2svg.grid2.do_grid.call(this);
of()
},
set_fmt: function(of, cmd, param, lock) {
if (cmd == "grid2") {
var curvoice = this.get_curvoice()
if (curvoice) {
this.set_v_param("stafflines", "..."); // no staff lines
curvoice.grid2 = param
}
return
}
of(cmd, param, lock)
},
set_hooks: function(abc) {
abc.draw_gchord = abc2svg.grid2.draw_gchord.bind(abc, abc.draw_gchord);
abc.output_music = abc2svg.grid2.output_music.bind(abc, abc.output_music);
abc.set_format = abc2svg.grid2.set_fmt.bind(abc, abc.set_format)
}
} // grid2
abc2svg.modules.hooks.push(abc2svg.grid2.set_hooks);
// the module is loaded
abc2svg.modules.grid2.loaded = true
|
Added modules/page.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 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 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 |
// page.js - module to generate one SVG image per page
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%pageheight" appears in a ABC source.
//
// Parameters
// %%pageheight <unit>
abc2svg.page = {
// output a new block
img_out: function(page, p) {
var cur_img_out = user.img_out;
page.user_out(p)
// user.img_out may have been changed ..
if (user.img_out != cur_img_out) {
page.user_out = user.img_out;
if (cur_img_out == page.img_out_sav) { // .. by the backend
user.img_out = abc2svg.page.img_in.bind(page.abc);
page.img_out_sav = user.img_out // keep our reference
} else {
user.img_out = cur_img_out // .. by an other extension
}
}
},
//function called at end of generation
abc_end: function(of) {
var page = this.page
if (page.h) {
abc2svg.page.img_out(page,
page.head + page.style + page.hf + page.out + '</svg>');
abc2svg.page.img_out(page, '</div>');
page.h = 0;
page.out = ''
}
of()
}, // abc_end()
// define the SVG header of the page
svg_head: function(cfmt) {
return '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"\n\
xmlns:xlink="http://www.w3.org/1999/xlink"\n\
color="black" class="music" stroke-width=".7"\n\
width="' + cfmt.pagewidth.toFixed(0) +
'px" height="' + cfmt.pageheight.toFixed(0) + 'px"' +
(cfmt.bgcolor ? (' style="background-color: ' + cfmt.bgcolor + '"') : '') +
'>\n'
}, // svg_head()
// start a new page
svg_out: function(abc, page) {
var h,
cfmt = abc.cfmt()
function header_footer(str) {
var c, i, t,
nl = 1,
j = 0,
r = ["", "", ""]
if (str[0] == '"')
str = str.slice(1, -1)
if (str.indexOf('\t') < 0) // if no TAB
str = '\t' + str // center
for (i = 0; i < str.length; i++) {
c = str[i]
switch (c) {
case '\t':
if (j < 2)
j++ // next column
continue
case '\\': // hope '\n'
for (j = 0; j < 3; j++)
r[j] += '\n';
nl++;
j = 0;
i++
continue
default:
r[j] += c
continue
case '$':
break
}
c = str[++i]
switch (c) {
case 'd': // cannot know the modification date of the file
break
case 'D':
r[j] += new Date().toUTCString()
break
case 'F':
r[j] += abc.get_fname()
break
case 'I':
c = str[++i]
case 'T':
t = abc.info()[c]
if (t)
r[j] += t.split('\n', 1)[0]
break
case 'P':
case 'Q':
t = c == 'P' ? page.pn : page.pna
switch (str[i + 1]) {
case '0':
i++
if (!(t & 1))
r[j] += t
break
case '1':
i++
if (t & 1)
r[j] += t
break
default:
r[j] += t
break
}
break
case 'V':
r[j] += "abc2svg-" + abc2svg.version
break
//fixme: handle the font changes ($<number>) ?
}
}
r[4] = nl // number of lines
return r
} // header_footer()
function font_class(font) {
if (font.class)
return 'f' + font.fid + cfmt.fullsvg + ' ' + font.class
return 'f' + font.fid + cfmt.fullsvg
}
// generate a header or footer
function gen_hf(up, font, str) {
var a, i, j, k, x, y, y0, s,
fh = font.size * 1.1,
pos = [ '">',
'" text-anchor="middle">',
'" text-anchor="end">' ]
if (str[0] == '-') { // not on 1st page
if (page.pn == 1)
return 0
str = str.slice(1)
}
a = header_footer(str)
if (up)
y0 = page.hbase + fh
else
y0 = cfmt.pageheight - page.topmargin - fh * a[4]
for (i = 0; i < 3; i++) {
str = a[i]
if (!str)
continue
if (i == 0)
x = cfmt.leftmargin
else if (i == 1)
x = cfmt.pagewidth / 2
else
x = cfmt.pagewidth - cfmt.rightmargin;
x += page.gutter;
y = y0;
k = 0
while (1) {
j = str.indexOf('\n', k)
if (j >= 0)
s = str.slice(k, j)
else
s = str.slice(k)
if (s)
page.hf += '<text class="' +
font_class(font) +
'" x="' + x.toFixed(1) +
'" y="' + y.toFixed(1) +
pos[i] +
s + '</text>\n'
if (j < 0)
break
k = j + 1;
y += fh
}
}
return fh * a[4]
} // gen_hf()
// svg_out()
// start a new SVG container for the page
abc2svg.page.img_out(abc.page, '<div>');
page.hbase = page.topmargin;
page.hmax = cfmt.pageheight - page.topmargin - page.botmargin;
page.pn++;
page.pna++;
page.gutter = -page.gutter;
// define the header/footer
page.hf = ''
if (page.header) {
h = gen_hf(true, abc.get_font("header"), page.header);
page.hmax -= h;
page.hbase += h
}
if (page.footer)
page.hmax -= gen_hf(false, abc.get_font("footer"), page.footer);
page.h = page.hb = 0;
page.out = ''
}, // svg_out()
// handle the output flow of the abc2svg generator
img_in: function(p) {
var h, i,
page = this.page
// copy a block
function blkcpy(page) {
var b, h, i
if (!page.blk || !page.blk.length) {
page.blk = null
return
}
h = page.hb
for (i = 0; i < page.blk.length; i++) {
b = page.blk[i]
page.out += b.p
.replace(/<svg(.|\n)*?>/,
'<g transform="translate(' +
page.gutter.toFixed(1) + ', ' +
(h + page.hbase).toFixed(1) +
')">')
.replace('</svg>', '</g>\n');
h += b.h
}
page.blk = null
page.h = h
} // blkcpy()
// get the style from the image and remove it from the block
function get_style(p, page) {
var i,
sty = p.match(/<style.*?>((.|\n)*?)<\/style>/)
if (!sty)
return p
sty = sty[1].split('\n')
if (!page.style)
page.style = '<style type="text/css">\n</style>\n'
for (i = 0; i < sty.length; i++) {
if (page.style.indexOf(sty[i]) < 0)
page.style = page.style.replace('</style>\n',
sty[i] + '\n</style>\n')
}
return p.replace(/<style(.|\n)*?\/style>\n/, '')
} // get_style()
// img_in()
switch (p.slice(0, 4)) {
case "<div": // new block (tune / paragraph)
if (p.indexOf('newpage') > 0
|| (page.oneperpage && this.info().X)
|| page.h == 0) {
if (page.h) {
abc2svg.page.img_out(page,
page.head + page.style + page.hf +
page.out + '</svg>');
abc2svg.page.img_out(page, '</div>')
}
abc2svg.page.svg_out(this, page)
if (!this.cfmt().fullsvg)
page.style = ''
}
page.blk = [];
page.hb = page.h
break
case "<svg": // SVG image
h = Number(p.match(/height="(\d+)px"/)[1])
if (h + page.h >= page.hmax) { // if page overflow
if (!page.out) // if at start of page
blkcpy(page); // output the start of tune
abc2svg.page.img_out(page,
page.head + page.style + page.hf +
page.out + '</svg>');
abc2svg.page.img_out(page, '</div>');
abc2svg.page.svg_out(this, page);
page.h = page.hb = this.cfmt().topspace;
if (page.blk)
blkcpy(page) // output the start of tune
if (!this.cfmt().fullsvg)
page.style = ''
}
p = get_style(p, page)
// if no overflow yet, keep the block
if (page.blk) {
page.blk.push({p: p, h: h})
} else {
page.out += p
.replace(/<svg(.|\n)*?>/,
'<g transform="translate(' +
page.gutter.toFixed(1) + ', ' +
(page.h + page.hbase).toFixed(1) + ')">')
.replace('</svg>', '</g>\n')
}
page.h += h
break
case "</di": // end of block
blkcpy(page);
page.out += '\n'
break
// default:
////fixme: %%beginml cannot be treated (no information about its height)
//// page.out += p
// break
}
}, // img_in()
// handle the page related parameters
set_fmt: function(of, cmd, parm, lock) {
var v,
cfmt = this.cfmt(),
page = this.page
if (cmd == "pageheight") {
v = this.get_unit(parm)
if (isNaN(v)) {
this.syntax(1, errs.bad_val, '%%' + cmd)
return
}
cfmt.pageheight = v
// if first definition, install the hook
if (!page && user.img_out && abc2svg.abc_end) {
this.page = page = {
abc: this,
topmargin: 38, // 1cm
botmargin: 38, // 1cm
gutter: 0,
h: 0, // current page height
pn: 0, // page number
pna: 0, // absolute page number
out: '', // page content
head: abc2svg.page.svg_head(cfmt),
user_out: user.img_out
}
// don't let the backend handle the header/footer
if (cfmt.header) {
page.header = cfmt.header;
cfmt.header = null
}
if (cfmt.footer) {
page.footer = cfmt.footer;
cfmt.footer = null
}
// get the previously defined page parameters
if (cfmt.botmargin) {
v = this.get_unit(cfmt.botmargin)
if (!isNaN(v))
page.botmargin = v
}
if (cfmt.topmargin) {
v = this.get_unit(cfmt.topmargin)
if (!isNaN(v))
page.topmargin = v
}
if (cfmt.gutter) {
v = this.get_unit(cfmt.gutter)
if (!isNaN(v))
page.gutter = (page.pn & 1) ? v : -v
}
if (cfmt.oneperpage)
page.oneperpage = this.get_bool(cfmt.oneperpage)
// set the hooks
user.img_out = abc2svg.page.img_in.bind(this);
page.img_out_sav = user.img_out;
abc2svg.abc_end = abc2svg.page.abc_end.bind(this,
abc2svg.abc_end)
}
return
}
if (page) {
switch (cmd) {
case "header":
case "footer":
page[cmd] = parm
return
case "newpage":
if (!parm)
break
v = Number(parm)
if (isNaN(v)) {
this.syntax(1, errs.bad_val, '%%' + cmd)
return
}
page.pn = v - 1
return
case "gutter":
case "botmargin":
case "topmargin":
v = this.get_unit(parm)
if (isNaN(v)) {
this.syntax(1, errs.bad_val, '%%' + cmd)
return
}
page[cmd] = v
if (cmd == "gutter" && !(page.pn & 1))
page.gutter = -page.gutter
return
case "oneperpage":
page[cmd] = this.get_bool(parm)
return
}
}
of(cmd, parm, lock)
if (page) {
switch (cmd) {
case "pagewidth":
case "bgcolor":
page.head = abc2svg.page.svg_head(cfmt)
break
}
}
}, // set_fmt()
set_hooks: function(abc) {
abc.set_format = abc2svg.page.set_fmt.bind(abc, abc.set_format)
}
} // page
abc2svg.modules.hooks.push(abc2svg.page.set_hooks);
// the module is loaded
abc2svg.modules.pageheight.loaded = true
|
Changes to modules/perc.js.
1 2 | // perc.js - module to handle %%percmap // | | | 1 2 3 4 5 6 7 8 9 10 | // perc.js - module to handle %%percmap // // Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+ // // This module is loaded when "%%percmap" appears in a ABC source. // // Parameters (from W. Vree) // %%percmap ABC_note percussion [note_head] // The percussion may be a number (MIDI percussion number range 35..81), // a ABC note or a possibly abbreviated percussion name. |
| ︙ | ︙ | |||
119 120 121 122 123 124 125 |
// convert a drum instrument to a note
function tonote(p) {
var i, j, s,
pit = Number(p)
if (isNaN(pit)) {
| | | < | 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 |
// convert a drum instrument to a note
function tonote(p) {
var i, j, s,
pit = Number(p)
if (isNaN(pit)) {
s = p.match(/^([_^=]*)([A-Ga-g])([,']*)$/) // '
if (s) { // note name
i = "CDEFGABcdefgab".indexOf(s[2]) + 16
switch(s[3]) {
case "'":
i += 7 * s[3].length
break
case ',':
i -= 7 * s[3].length
break
}
note = {
pit: i
}
switch (s[1]) {
case '^': note.acc = 1; break
case '_': note.acc = -1; break
}
return note
}
|
| ︙ | ︙ | |||
186 187 188 189 190 191 192 |
if (!pit)
return
p = ((pit / 12) | 0) * 7 - 19; // octave
pit = pit % 12; // in octave
p += pits[pit];
note = {
| | < | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
if (!pit)
return
p = ((pit / 12) | 0) * 7 - 19; // octave
pit = pit % 12; // in octave
p += pits[pit];
note = {
pit: p
}
if (accs[pit])
note.acc = accs[pit]
return note
} // tonote()
// normalize a note for mapping
|
| ︙ | ︙ | |||
215 216 217 218 219 220 221 |
var n, v,
maps = this.get_maps(),
a = parm.split(/\s+/);
n = norm(a[1])
if (!n) {
| | | | | 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 |
var n, v,
maps = this.get_maps(),
a = parm.split(/\s+/);
n = norm(a[1])
if (!n) {
this.syntax(1, this.errs.bad_val, "%%percmap")
return
}
if (this.cfmt().sound != "play") { // !play
if (!a[3])
return
if (!maps.MIDIdrum)
maps.MIDIdrum = {}
v = tonote(n)
if (!v) {
this.syntax(1, this.errs.bad_val, "%%percmap")
return
}
delete v.acc
maps.MIDIdrum[n] = [[a[3]], v]
} else { // play
v = tonote(a[2])
if (!v) {
this.syntax(1, this.errs.bad_val, "%%percmap")
return
}
if (!maps.MIDIdrum)
maps.MIDIdrum = {}
maps.MIDIdrum[n] = [null, v]
}
this.set_v_param("perc", "MIDIdrum")
|
| ︙ | ︙ | |||
272 273 274 275 276 277 278 279 280 281 |
else
of(text)
},
set_vp: function(of, a) {
abc2svg.perc.set_perc.call(this, a);
of(a)
}
} // perc
| > > > > > | < < < < < < < | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
else
of(text)
},
set_vp: function(of, a) {
abc2svg.perc.set_perc.call(this, a);
of(a)
},
set_hooks: function(abc) {
abc.do_pscom = abc2svg.perc.do_pscom.bind(abc, abc.do_pscom);
abc.set_vp = abc2svg.perc.set_vp.bind(abc, abc.set_vp)
}
} // perc
abc2svg.modules.hooks.push(abc2svg.perc.set_hooks);
// the module is loaded
abc2svg.modules.percmap.loaded = true
|
Changes to modules/psvg.js.
1 2 | // psvg.js - small PS to SVG convertor for abc2svg | | | 1 2 3 4 5 6 7 8 9 10 | // psvg.js - small PS to SVG convertor for abc2svg // Copyright (C) 2014-2019 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. |
| ︙ | ︙ | |||
69 70 71 72 73 74 75 |
if (gcur.xoffs || gcur.yoffs) {
var x, xtmp = gcur.xoffs,
y = gcur.yoffs,
_sin = gcur.sin,
_cos = gcur.cos;
x = xtmp * _cos - y * _sin;
y = xtmp * _sin + y * _cos;
| | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
if (gcur.xoffs || gcur.yoffs) {
var x, xtmp = gcur.xoffs,
y = gcur.yoffs,
_sin = gcur.sin,
_cos = gcur.cos;
x = xtmp * _cos - y * _sin;
y = xtmp * _sin + y * _cos;
svgbuf += " translate(" + x.toFixed(1) + "," +
y.toFixed(1) + ")";
x_rot = gcur.xoffs;
y_rot = gcur.yoffs;
gcur.xoffs = 0;
gcur.yoffs = 0
}
svgbuf += " rotate(" + gcur.rotate.toFixed(2) + ")"
}
|
| ︙ | ︙ | |||
149 150 151 152 153 154 155 |
function path_def() {
if (path)
return
setg(1);
gcur.px = gcur.cx;
gcur.py = gcur.cy;
| | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
function path_def() {
if (path)
return
setg(1);
gcur.px = gcur.cx;
gcur.py = gcur.cy;
path = '<path d="m' + (gcur.xoffs + gcur.cx).toFixed(1) +
' ' + (gcur.yoffs - gcur.cy).toFixed(1) + '\n'
}
function path_end() {
svgbuf += path;
path = ''
}
|
| ︙ | ︙ | |||
200 201 202 203 204 205 206 |
if (gcur.cx != undefined) {
if (path) {
if (x1 != gcur.cx || y1 != gcur.cy)
path += 'l'
else
path += 'm';
| | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
if (gcur.cx != undefined) {
if (path) {
if (x1 != gcur.cx || y1 != gcur.cy)
path += 'l'
else
path += 'm';
path += (x1 - gcur.cx).toFixed(1) + " " +
(-(y1 - gcur.cy)).toFixed(1)
} else {
gcur.cx = x1;
gcur.cy = y1;
path_def()
}
} else {
if (path) // should not occur
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 |
Psvg.prototype.cy = function() {
return gcur.cy
}
Psvg.prototype.curveto = function(x1, y1, x2, y2, x, y) {
path_def();
path += "\tC" +
| | | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
Psvg.prototype.cy = function() {
return gcur.cy
}
Psvg.prototype.curveto = function(x1, y1, x2, y2, x, y) {
path_def();
path += "\tC" +
(gcur.xoffs + x1).toFixed(1) + " " + (gcur.yoffs - y1).toFixed(1) + " " +
(gcur.xoffs + x2).toFixed(1) + " " + (gcur.yoffs - y2).toFixed(1) + " " +
(gcur.xoffs + x).toFixed(1) + " " + (gcur.yoffs - y).toFixed(1) + "\n";
gcur.cx = x;
gcur.cy = y
}
Psvg.prototype.eofill = function() {
path_end();
svgbuf += '" fill-rule="evenodd" fill="currentColor"/>\n'
|
| ︙ | ︙ | |||
291 292 293 294 295 296 297 |
gcur = gc_stack.pop();
gchg = true
}
Psvg.prototype.lineto = function(x, y) {
path_def()
if (x == gcur.cx)
| | | | | | | | | | | | | | | | | 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 |
gcur = gc_stack.pop();
gchg = true
}
Psvg.prototype.lineto = function(x, y) {
path_def()
if (x == gcur.cx)
path += "\tv" + (gcur.cy - y).toFixed(1) + "\n"
else if (y == gcur.cy)
path += "\th" + (x - gcur.cx).toFixed(1) + "\n"
else
path += "\tl" + (x - gcur.cx).toFixed(1) + " " +
(gcur.cy - y).toFixed(1) + "\n";
gcur.cx = x;
gcur.cy = y
}
Psvg.prototype.moveto = function(x, y) {
gcur.cx = x;
gcur.cy = y
if (path) {
path += "\tM" + (gcur.xoffs + gcur.cx).toFixed(1) + " " +
(gcur.yoffs - gcur.cy).toFixed(1) + "\n"
} else if (g == 2) {
svgbuf += "</text>\n";
g = 1
}
}
Psvg.prototype.newpath = function() {
gcur.cx = gcur.cy = undefined
}
Psvg.prototype.rcurveto = function(x1, y1, x2, y2, x, y) {
path_def();
path += "\tc" +
x1.toFixed(1) + " " + (-y1).toFixed(1) + " " +
x2.toFixed(1) + " " + (-y2).toFixed(1) + " " +
x.toFixed(1) + " " + (-y).toFixed(1) + "\n";
gcur.cx += x;
gcur.cy += y
}
function rlineto(x, y) {
path_def()
if (x == 0)
path += "\tv" + (-y).toFixed(1) + "\n"
else if (y == 0)
path += "\th" + x.toFixed(1) + "\n"
else
path += "\tl" + x.toFixed(1) + " " +
(-y).toFixed(1) + "\n";
gcur.cx += x;
gcur.cy += y
}
Psvg.prototype.rlineto = rlineto;
Psvg.prototype.rmoveto = function(x, y) {
if (path) {
path += "\tm" + x.toFixed(1) + " " +
(-y).toFixed(1) + "\n"
} else if (g == 2) {
svgbuf += "</text>\n";
g = 1
}
gcur.cx += x;
gcur.cy += y
}
|
| ︙ | ︙ | |||
463 464 465 466 467 468 469 |
x = gcur.cx;
y = gcur.cy
if (span) {
svgbuf += "<tspan\n\t";
output_font(true);
svgbuf += ">"
} else if (g != 2) {
| | | | | 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 |
x = gcur.cx;
y = gcur.cy
if (span) {
svgbuf += "<tspan\n\t";
output_font(true);
svgbuf += ">"
} else if (g != 2) {
svgbuf += '<text x="' + (x + gcur.xoffs).toFixed(1) + '" y="' +
(gcur.yoffs - y).toFixed(1) + '">';
g = 2
}
svgbuf += s.replace(/<|>|&| /g, function(c){
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
case ' ': return ' Â ' // space + nbspace
}
})
if (span)
svgbuf += "</tspan>";
gcur.cx = x + strw(s)
}
Psvg.prototype.stroke = function() {
path_end()
if (gcur.linewidth != 0.7)
svgbuf += '" stroke-width="' + gcur.linewidth.toFixed(1);
svgbuf += '" stroke="currentColor" fill="none"' + gcur.dash + '/>\n'
}
Psvg.prototype.translate = function(x, y) {
gcur.xoffs += x;
gcur.yoffs -= y;
gcur.cx -= x;
|
| ︙ | ︙ | |||
554 555 556 557 558 559 560 |
// common part
function pscall(f, x, y, script) {
gcur.xorig = gcur.xoffs = abcobj.sx(0);
gcur.yorig = gcur.yoffs = abcobj.sy(0);
gcur.cx = 0;
gcur.cy = 0;
wps.parse(script +
| | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
// common part
function pscall(f, x, y, script) {
gcur.xorig = gcur.xoffs = abcobj.sx(0);
gcur.yorig = gcur.yoffs = abcobj.sy(0);
gcur.cx = 0;
gcur.cy = 0;
wps.parse(script +
(x / abcobj.stv_g().scale).toFixed(1) + ' ' + y.toFixed(1) + ' ' + f);
ps_flush(true) // + setg(0)
return true
}
// try to generate a decoration by PS
Psvg.prototype.psdeco = function(f, x, y, de) {
var dd, de2, script, defl,
|
| ︙ | ︙ | |||
579 580 581 582 583 584 585 |
defl |= 2
if (de.s.stem >= 0)
defl |= 4;
Os.pop();
script = '/defl ' + defl + ' def '
if (de.lden) {
| | | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 |
defl |= 2
if (de.s.stem >= 0)
defl |= 4;
Os.pop();
script = '/defl ' + defl + ' def '
if (de.lden) {
script += x.toFixed(1) + ' ' + y.toFixed(1) + ' ';
de2 = de.start;
x = de2.x;
y = de2.y + staff_tb[de2.st].y
if (x > de.x - 20)
x = de.x - 20
}
dd = de.dd
|
| ︙ | ︙ | |||
737 738 739 740 741 742 743 |
/turn{(turn).svg(xygl)3 .call0}.bdef\n\
/umrd{(umrd).svg(xygl)3 .call0}.bdef\n\
/y0{.svg(y0)1 .call}.bdef\n\
/y1{.svg(y1)1 .call}.bdef\n")
} // Psvg()
| | | | > > > > | < < < < < < < | | | < < | 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 |
/turn{(turn).svg(xygl)3 .call0}.bdef\n\
/umrd{(umrd).svg(xygl)3 .call0}.bdef\n\
/y0{.svg(y0)1 .call}.bdef\n\
/y1{.svg(y1)1 .call}.bdef\n")
} // Psvg()
abc2svg.psvg = {
do_begin_end: function(of, type, opt, text) {
if (type != "ps") {
of(type, opt, text)
return
}
if (opt == 'nosvg')
return
if (!this.psvg)
this.psvg = new Psvg(this);
this.psvg.ps_eval.call(this.psvg, text)
},
psdeco: function(of, f, x, y, de) {
if (!this.psvg) // no %%beginps yet
return false
return this.psvg.psdeco.call(this.psvg, f, x, y, de)
},
psxygl: function(of, x, y, gl) {
if (!this.psvg)
return false
return this.psvg.psxygl.call(this.psvg, x, y, gl)
},
set_hooks: function(abc) {
abc.do_begin_end = abc2svg.psvg.do_begin_end.bind(abc, abc.do_begin_end);
abc.psdeco = abc2svg.psvg.psdeco.bind(abc, abc.psdeco);
abc.psxygl = abc2svg.psvg.psxygl.bind(abc, abc.psxygl)
}
} // psvg
abc2svg.modules.hooks.push(abc2svg.psvg.set_hooks);
// the module is loaded
abc2svg.modules.beginps.loaded = true
|
Added modules/soloffs.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// soloffs.js - module to set the X offset of some elements at start of music line
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// Parameters
// %%soloffs <type>=<offset> [<type>=<offset>]*
// <type> is one of 'part', 'tempo' or 'space'
// <offset> is the X offset from the start of staff
abc2svg.soloffs = {
set_fmt: function(of, cmd, parm, lock) {
if (cmd == "soloffs") {
var i, v,
C = abc2svg.C,
soloffs = this.cfmt().soloffs = {}
parm = parm.split(/\s+/)
while (parm.length) {
i = parm.shift().split('=')
v = Number(i[1])
if (isNaN(v))
continue // error
switch (i[0]) {
// case 'bar':
// soloffs[C.BAR] = v
// break
case 'part':
soloffs[C.PART] = v + 10 // see deco.js
break
case 'tempo':
soloffs[C.TEMPO] = v + 16 // see deco.js
break
case 'space':
soloffs[C.SPACE] = v
break
// default:
// // error
// break
}
}
return
}
of(cmd, parm, lock)
},
set_sym_glue: function(of, width) {
var s,
C = abc2svg.C,
tsfirst = this.get_tsfirst(),
soloffs = this.cfmt().soloffs;
of(width) // compute the x offset of the symbols
if (!soloffs)
return
for (s = tsfirst; s; s = s.ts_next) {
if (s.dur)
break
if (soloffs[s.type] != undefined)
s.x = soloffs[s.type]
}
}, // set_sym_glue()
set_hooks: function(abc) {
abc.set_sym_glue = abc2svg.soloffs.set_sym_glue.bind(abc, abc.set_sym_glue);
abc.set_format = abc2svg.soloffs.set_fmt.bind(abc, abc.set_format)
}
} // soloffs
abc2svg.modules.hooks.push(abc2svg.soloffs.set_hooks);
// the module is loaded
abc2svg.modules.soloffs.loaded = true
|
Changes to modules/sth.js.
1 2 | // sth.js - module to set the stem heights // | | | | > > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// sth.js - module to set the stem heights
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%sth" appears in a ABC source.
//
// Parameters
// %%sth h1 h2 h3 ...
// The values h1, h2, .. are applied to the following notes which
// have a stem and which are not inside a beam.
// The value may be '*' for keeping the original stem length.
abc2svg.sth = {
// function called after beam calculation
recal_beam: function(bm, s) {
var staff_tb = this.get_staff_tb(),
y = staff_tb[s.st].y,
s2 = bm.s2,
y2 = staff_tb[s2.st].y
if (s.sth)
s.ys = s.sth
if (s2.sth)
s2.ys = s2.sth;
bm.a = (s.ys + y - s2.ys - y2) / (s.xs - s2.xs);
bm.b = s.ys - s.xs * bm.a + y
while (1) {
s.ys = bm.a * s.xs + bm.b - y
if (s.stem > 0)
s.ymx = s.ys + 2.5
else
s.ymn = s.ys - 2.5;
s = s.next
if (s == s2)
break
|
| ︙ | ︙ | |||
77 78 79 80 81 82 83 |
s.sth = s.ys
}
}
}, // set_sth()
calculate_beam: function(of, bm, s1) {
var done = of(bm, s1)
| | | | > | | > | > > > > > | | < < < < < < < < < | 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 |
s.sth = s.ys
}
}
}, // set_sth()
calculate_beam: function(of, bm, s1) {
var done = of(bm, s1)
if (done && bm.s2 && (s1.sth || bm.s2.sth))
abc2svg.sth.recal_beam.call(this, bm, s1)
return done
},
new_note: function(of, grace, tp_fact) {
var C = abc2svg.C,
s = of(grace, tp_fact),
curvoice = this.get_curvoice()
if (curvoice.sth && s && s.type == C.NOTE) {
s.sth = curvoice.sth;
curvoice.sth = null // some stem widths in this voice
}
return s
},
set_format: function(of, cmd, param, lock) {
if (cmd == "sth") {
var curvoice = this.get_curvoice()
if (this.parse.state == 2)
this.goto_tune()
if (curvoice)
curvoice.sth = param.split(/[ \t;-]+/)
return
}
of(cmd, param, lock)
},
set_stems: function(of) {
of();
abc2svg.sth.set_sth.call(this)
},
set_hooks: function(abc) {
abc.calculate_beam = abc2svg.sth.calculate_beam.bind(abc, abc.calculate_beam);
abc.new_note = abc2svg.sth.new_note.bind(abc, abc.new_note);
abc.set_format = abc2svg.sth.set_format.bind(abc, abc.set_format);
abc.set_stems = abc2svg.sth.set_stems.bind(abc, abc.set_stems)
}
} // sth
abc2svg.modules.hooks.push(abc2svg.sth.set_hooks);
// the module is loaded
abc2svg.modules.sth.loaded = true
|
Added modules/temper.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// temper.js - module to define the temperament
//
// Copyright (C) 2018-2019 Jean-Francois Moine - GPL3+
//
// This module is loaded when "%%temperament" appears in a ABC source.
//
// Parameters
// %%temperament <list>
// The <list> must contain 12 integer values that are the detune values in cents
// of the 12 notes of the equal scale.
// Examples:
//
// % pythagore (~500 B.C)
// %%temperament +00 +14 +04 -06 +08 -02 +12 +02 +16 +06 -04 +10
//
// % just intonation
// %%temperament +00 -08 -18 -06 -14 -02 -10 +02 -08 -16 -04 -12
//
// % meantone (Pietro Aaron 1523)
// %%temperament +00 -24 -07 +10 -14 +03 -21 -03 -27 +10 +07 -17
//
// % Andreas Werckmeister III (1681)
// %%temperament +00 -04 +04 +00 -04 +04 +00 +02 -08 +00 +02 -02
//
// % well temperament (F.A. Vallotti 1754)
// %%temperament +00 -06 -04 -02 -08 +02 -08 -02 -04 -06 +00 -10
abc2svg.temper = {
// move the temperament to the 1st voice
set_bar_num: function(of) {
of()
if (this.cfmt().temper) {
var v0 = this.get_voice_tb()[0];
v0.temper = new Float32Array(12)
for (var i = 0; i < 12; i++)
v0.temper[i] = this.cfmt().temper[i] / 100
}
},
// get the temperament
set_fmt: function(of, cmd, param, lock) {
if (cmd == "temperament") {
var ls = new Float32Array(param.split(/ +/)),
i = ls.length
if (i == 12) {
while (--i >= 0) {
if (isNaN(parseInt(ls[i])))
break
}
if (i < 0) {
this.cfmt().temper = ls
return
}
}
this.syntax(1, this.errs.bad_val, "%%temperament")
return
}
of(cmd, param, lock)
},
set_hooks: function(abc) {
abc.set_bar_num = abc2svg.temper.set_bar_num.bind(abc, abc.set_bar_num);
abc.set_format = abc2svg.temper.set_fmt.bind(abc, abc.set_format)
}
} // temper
abc2svg.modules.hooks.push(abc2svg.temper.set_hooks);
// the module is loaded
abc2svg.modules.temperament.loaded = true
|
Changes to package.json.
1 2 |
{
"name": "abc2svg",
| | > > > > > < > | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
{
"name": "abc2svg",
"version": "1.19.1",
"description": "ABC music notation translator",
"devDependencies": {
"uglify-js": "^2.5.0"
},
"files": [
"COPYING",
"COPYING.LESSER",
"MIDI-1.js",
"Scc1t2/",
"abc2odt",
"abc2svg",
"abc2svg-1.js",
"abc2svg.ttf",
"abcdoc-1.js",
"abcemb-1.js",
"abcemb2-1.js",
"ambitus-1.js",
"break-1.js",
"capo-1.js",
"clip-1.js",
"cmdline.js",
"combine-1.js",
"diag-1.js",
"edit-1.css",
"edit-1.js",
"edit-1.xhtml",
"edit-de.js",
"edit-en.js",
"edit-fr.js",
"edit-it.js",
"edit-pt_BR.js",
"equalbars-1.js",
"err-de.js",
"err-en.js",
"err-fr.js",
"err-it.js",
"err-pt_BR.js",
"follow-1.js",
"grid-1.js",
"grid2-1.js",
"json-1.js",
"page-1.js",
"perc-1.js",
"play-1.js",
"psvg-1.js",
"setmidi-1.js",
"sth-1.js",
"soloffs-1.js",
"temper-1.js",
"toabc.js",
"toaudio-1.js",
"toabw.js",
"toodt.js",
"toxhtml.js"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"bin": {
"abc2odt": "./abc2odt",
"abc2svg": "./abc2svg"
},
"repository": {
"type": "fossil",
"url": "https://chiselapp.com/user/moinejf/repository/abc2svg"
},
"keywords": [
"ABC",
"music",
"SVG"
],
"author": "Jean-François Moine",
"license": "LGPL-3.0",
"bugs": {
"url": "https://chiselapp.com/user/moinejf/repository/abc2svg/reportlist"
},
"homepage": "https://chiselapp.com/user/moinejf/repository/abc2svg"
}
|
Changes to toabc.js.
1 2 | // abc2svg - toabc.js - convert ABC to ABC // | | < < < < < < < < < < < < < < < < < < | < < < < < | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
// abc2svg - toabc.js - convert ABC to ABC
//
// Copyright (C) 2016-2019 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 General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
// constants from core/abc2svg.js
var C = abc2svg.C,
OPEN_BRACE = 0x01,
CLOSE_BRACE = 0x02,
OPEN_BRACKET = 0x04,
CLOSE_BRACKET = 0x08,
OPEN_PARENTH = 0x10,
CLOSE_PARENTH = 0x20,
STOP_BAR = 0x40,
FL_VOICE = 0x80,
OPEN_BRACE2 = 0x0100,
CLOSE_BRACE2 = 0x0200,
OPEN_BRACKET2 = 0x0400,
CLOSE_BRACKET2 = 0x0800,
MASTER_VOICE = 0x1000
var deco_l = { // decorations
dot: '.',
fermata: 'H',
emphasis: 'L',
lowermordent: 'M',
coda: 'O',
|
| ︙ | ︙ | |||
153 154 155 156 157 158 159 | case "pagescale": case "pagewidth": case "scale": case "staffwidth": ln += s.param break case "sep": | | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
case "pagescale":
case "pagewidth":
case "scale":
case "staffwidth":
ln += s.param
break
case "sep":
ln += s.sk1.toFixed(1) + ' ' +
s.l.toFixed(1) + ' ' +
s.sk2.toFixed(1)
break
case "skip":
ln += s.sk
break
case "text":
if (s.text.indexOf('\n') <= 0
&& (!s.opt || s.opt == 'c')) {
|
| ︙ | ︙ | |||
221 222 223 224 225 226 227 |
else
line += '!' + n + '!'
}
} // deco_dump
function dur_dump(dur, grace) {
var d = 0,
| | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
else
line += '!' + n + '!'
}
} // deco_dump
function dur_dump(dur, grace) {
var d = 0,
l = grace ? C.BLEN / 4 : ulen
if (dur == l)
return
while (1) {
if (dur % l == 0) {
dur /= l
if (dur != 1)
line += dur.toString()
|
| ︙ | ︙ | |||
340 341 342 343 344 345 346 |
while (nly < ly.length)
w[nly++] = ""
}
if (nly == 0)
continue
for (s = voice_tb[v].sym; s; s = s.next) {
switch (s.type) {
| | | | 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 |
while (nly < ly.length)
w[nly++] = ""
}
if (nly == 0)
continue
for (s = voice_tb[v].sym; s; s = s.next) {
switch (s.type) {
case C.BAR:
if (w.length == 0)
continue
if (++nb < 4)
continue
nb = 0
if (!s.next)
continue
for (i = 0; i < nly; i++)
w[i] += '\n'
// t = "|"
// if (++nb >= 4) {
// nb = 0;
// t = "|\n"
// }
// for (i = 0; i < nly; i++)
// w[i] += t
default:
continue
case C.NOTE:
break
}
ly = s.a_ly
if (!ly) {
for (i = 0; i < nly; i++)
w[i] += "*"
continue
|
| ︙ | ︙ | |||
437 438 439 440 441 442 443 |
case 2: line += '^^'; break
case 3: line += '='; break
}
if (note.micro_n) {
if (s.p_v.uscale)
line += note.micro_n
else
| | | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
case 2: line += '^^'; break
case 3: line += '='; break
}
if (note.micro_n) {
if (s.p_v.uscale)
line += note.micro_n
else
line += dur_dump(C.BLEN / 4 *
note.micro_n / note.micro_d,
true)
}
p = note.pit
if (p >= 23) {
line += "abcdefg"[p % 7]
if (p >= 30) {
line += "'"
if (p >= 37)
line += "'"
}
|
| ︙ | ︙ | |||
468 469 470 471 472 473 474 |
if (!tie_ch && note.ti1)
slti_dump(note.ti1, '-')
if (note.sl2)
line += ')'
} // note_dump()
function slti_dump(fl, ty) {
| | | | | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
if (!tie_ch && note.ti1)
slti_dump(note.ti1, '-')
if (note.sl2)
line += ')'
} // note_dump()
function slti_dump(fl, ty) {
if (fl & C.SL_DOTTED)
line += ".";
line += ty
switch (fl & 0x07) {
case C.SL_ABOVE:
line += "'"
break
case C.SL_BELOW:
line += ','
break
}
} // slti_dump()
//fixme: missing: '+' (master voice) and '*' (floating voice)
function staves_dump(s) {
|
| ︙ | ︙ | |||
549 550 551 552 553 554 555 |
if (staff.flags & CLOSE_BRACKET2)
ln += ']'
if (staff.flags & CLOSE_BRACKET)
ln += ']';
// output the following bars
for (s = s.ts_next; s; s = s.ts_next) {
| | | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
if (staff.flags & CLOSE_BRACKET2)
ln += ']'
if (staff.flags & CLOSE_BRACKET)
ln += ']';
// output the following bars
for (s = s.ts_next; s; s = s.ts_next) {
if (s.type != C.BAR)
break
if (s.time != vti[s.v])
continue
sym_dump(s);
s.del = true
if (line) {
vo[s.v].push(line);
|
| ︙ | ︙ | |||
572 573 574 575 576 577 578 |
function tempo_dump(s) {
var i,
ln = 'Q:'
function qdur_dump(dur) {
var d = 0,
| | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
function tempo_dump(s) {
var i,
ln = 'Q:'
function qdur_dump(dur) {
var d = 0,
l = C.BLEN
if (dur == l)
ln += "1/1"
while (1) {
if (dur % l == 0) {
dur /= l;
ln += dur.toString()
break
|
| ︙ | ︙ | |||
673 674 675 676 677 678 679 |
slti_dump(tmp, '(');
tmp >>= 4
}
if (s.a_gch)
gch_dump(s.a_gch)
if (s.a_dd)
deco_dump(s.a_dd)
| | | | | | | | | | | | 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 |
slti_dump(tmp, '(');
tmp >>= 4
}
if (s.a_gch)
gch_dump(s.a_gch)
if (s.a_dd)
deco_dump(s.a_dd)
if (s.invis && s.type != C.REST && s.type != C.SPACE)
line += "!invisible!"
if (s.color)
line += "!" + s.color + "!"
if (s.feathered_beam)
line += s.feathered_beam > 0 ? "!beam-accel!" : "!beam-rall!"
switch (s.type) {
case C.BAR:
if (s.beam_on)
line += "!beamon!"
if (s.bar_dotted)
line += '.';
line += s.bar_type
if (s.text) {
if (s.text[0] >= '0' && s.text[0] <= '9')
line += s.text + ' '
else
line += '"' + s.text + '"'
}
break
case C.CLEF:
info_out("K: " + clef_dump(s))
break
case C.CUSTOS:
break
case C.GRACE:
line += '{'
if (s.sappo)
line += '/'
for (g = s.extra; g; g = g.next)
sym_dump(g)
if (s.gr_shift)
line += ' ';
line += '}'
break
case C.KEY:
info_out(key_dump(s))
break
case C.METER:
info_out(meter_dump(s))
break
case C.MREST:
line += s.invis ? 'X' : 'Z'
if (s.nmes != 1)
line += s.nmes
break
case C.NOTE:
if (s.beam_br1)
line += "!beambr1!"
if (s.beam_br2)
line += "!beambr2!"
if (s.trem1)
line += '!' + "///".slice(0, s.ntrem) + '!'
if (s.xstem)
line += "!xstem!"
if (s.stemless
&& s.notes[0].dur < C.BLEN) // head duration
line += "!stemless!"
if (s.trem22)
line += "!trem" + s.ntrem + "!"
else if (s.trem2 && s.next && s.next.trem2)
s.next.trem22 = true
tie_ch = true
if (s.notes.length == 1) {
|
| ︙ | ︙ | |||
773 774 775 776 777 778 779 |
slti_dump(s.notes[0].ti1, '-');
tmp = s.slur_end
while (tmp) {
line += ')';
tmp--
}
break
| | | | | | | | | | | | | | 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 |
slti_dump(s.notes[0].ti1, '-');
tmp = s.slur_end
while (tmp) {
line += ')';
tmp--
}
break
case C.PART:
info_out('P:' + s.text)
break
case C.REST:
line += s.invis ? 'x' : 'z';
dur_dump(s.dur)
break
case C.SPACE:
line += 'y'
if (s.width != 10)
line += s.width
break
case C.STAVES:
if (nv == 1)
break
staves_dump(s)
break
case C.STBRK:
voice_out();
abc2svg.print('%%staffbreak ' + s.xmx.toString() +
(s.stbrk_forced ? 'f' : ''))
break
case C.TEMPO:
tempo_dump(s)
break
case C.BLOCK:
voice_out();
block_dump(s)
break
case C.REMARK:
info_out('r:' + s.text)
break
default:
voice_out();
abc2svg.print('% ??sym: ' + music_types[s.type])
break
}
} // sym_dump()
abc2svg.print('\nX:' + info['X'])
header_dump("TC")
abc2svg.print(meter_dump(voice_tb[0].meter));
ulen = voice_tb[0].ulen < 0 ? C.BLEN / 4 : voice_tb[0].ulen;
abc2svg.print('L:1/' + (C.BLEN / ulen).toString());
header_dump("OABDFGRNPSZH")
for (v = 0; v < nv; v++) {
vo[v] = [];
vti[v] = 0
}
if (info.Q) {
for (s = tsfirst; s; s = s.ts_next) {
if (s.type == C.TEMPO) {
tempo_dump(s);
s.del = true
break
}
}
}
abc2svg.print(key_dump(voice_tb[0].key, voice_tb[0].clef))
// loop by time
for (s = tsfirst; s; s = s.ts_next) {
if (eoln && s.seqst)
voice_out();
if (s.del)
continue
line = "";
// (all voices are synchronized on %%score)
if (s.type != C.STAVES && s.time > vti[s.v]) {
//fixme: put 'X' if more than one measure
line += 'x';
dur_dump(s.time - vti[s.v]);
vti[s.v] = s.time
}
sym_dump(s)
if (s.dur)
|
| ︙ | ︙ |
Changes to toabw.js.
1 2 | // abc2svg - toabw.js - SVG generation for Abiword // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - toabw.js - SVG generation for Abiword // // Copyright (C) 2018-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
44 45 46 47 48 49 50 |
seq = 1
// set a value in page unit
function set_unit(p) {
if (typeof p == "string")
return p
if (page_type[0] == 'L')
| | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
seq = 1
// set a value in page unit
function set_unit(p) {
if (typeof p == "string")
return p
if (page_type[0] == 'L')
return (p / 96).toFixed(1) + 'in'
return (p / 37.8).toFixed(1) + 'cm'
}
function header_footer(str) {
var c, i, t,
j = 0,
r = ["", "", ""]
|
| ︙ | ︙ | |||
238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
if (typeof abc2svg.printErr == 'function')
abc2svg.printErr(e.message + "\n*** Abort ***\n" + e.stack)
else
section += "<p>" + e.message + "\n*** Abort ***\n" + e.stack + "</p>\n";
abc2svg.abc_end();
abc2svg.quit()
}
function svg_out(str) {
var r, w, h,
cfmt = abc.cfmt()
switch (str.slice(0, 4)) {
case '<svg':
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > > > | 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 |
if (typeof abc2svg.printErr == 'function')
abc2svg.printErr(e.message + "\n*** Abort ***\n" + e.stack)
else
section += "<p>" + e.message + "\n*** Abort ***\n" + e.stack + "</p>\n";
abc2svg.abc_end();
abc2svg.quit()
}
function font_bug(str) {
var i, k, l, r, w,
j = 0
while (1) {
i = str.indexOf('font:', j)
if (i < 0)
return str
if (str[i - 1] == '"') {
j = str.indexOf('"', i)
} else {
j = str.indexOf('}', i);
k = str.indexOf(';', i)
if (j < 0 || (k >= 0 && k < j))
j = k
}
w = str.slice(i + 5, j).match(/[^ \t"]+|".+?"/g) // "
l = w.length;
r = 'font-family:' + w[--l] +
';font-size:' + w[--l]
while (--l >= 0) {
switch (w[l]) {
case 'italic':
r += ';font-style:italic'
break
case 'oblique':
r += ';font-style:oblique'
break
case 'bold':
r += ';font-weight:bold'
break
}
}
str = str.replace(str.slice(i, j), r)
}
}
function svg_out(str) {
var r, w, h,
cfmt = abc.cfmt()
switch (str.slice(0, 4)) {
case '<svg':
//fixme: the shorthand 'font:' does not work in the library 'librsvg'
// used by libreoffice and abiword
// (https://gitlab.gnome.org/GNOME/librsvg/issues/34)
str = font_bug(str)
data += '<d name="g'+ (++seq).toString() +
'" mime-type="image/svg+xml" base64="no">\n\
<![CDATA[' + str + ']]>\n\
</d>\n';
r = str.slice(0, 200).match(/.*width="(.*?)px" height="(.*?)px"/);
w = r[1] / 96;
h = r[2] / 96;
section += '<p style="Normal" xid="'+
(seq + 1).toString() + '"><image dataid="g' +
seq.toString() + '" xid="' +seq.toString() +
'" props="height:' + h.toFixed(2) + 'in; width:' +
w.toFixed(2) + 'in"/></p>\n';
seq++
|
| ︙ | ︙ | |||
294 295 296 297 298 299 300 | return '<c' case '</span>': return '</c>' case '<br/>': // hope followed by '\n'! return '' default: // size:..px var r = c.match(/size:(.+)px/) | | > > > | | > | 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 |
return '<c'
case '</span>':
return '</c>'
case '<br/>': // hope followed by '\n'!
return ''
default: // size:..px
var r = c.match(/size:(.+)px/)
return 'size:' + (r[1] * 72 / 96).toFixed(1) + 'pt'
}
})
section += '\n'
break
}
}
// entry point from cmdline
abc2svg.abc_init = function() {
// get the page parameters
user.img_out = function(str) {
var cfmt = abc.cfmt(),
pw = cfmt.pagewidth;
page_type = pw > 800 ? 'Letter' : 'A4';
page_size = pw > 800 ?
'width="8.50" height="11.00" units="in"' :
'width="210.00" height="297.00" units="mm"';
if (abc.page) {
topmargin = botmargin = 0
} else {
topmargin = set_unit(cfmt.topmargin || 37.8);
botmargin = set_unit(cfmt.botmargin || 37.8)
}
// output the first generated string
svg_out(str);
// change the output function
user.img_out = svg_out
}
|
| ︙ | ︙ |
Changes to tolead.js.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 | // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. | < < > | | | | | | | | | | | 13 14 15 16 17 18 19 20 21 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 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
function lead(tsfirst, voice_tb, music_types, info) {
var C = abc2svg.C
s, beat, cur_beat, i,
line = '';
function get_beat(s) {
if (s.a_meter[0].top[0] == 'C' || !s.a_meter[0].bot) {
beat = C.BLEN / 4
} else {
beat = C.BLEN / s.a_meter[0].bot[0] |0
if (isNaN(beat)) {
abc2svg.print('** Cannot get the beat')
return
}
if (s.a_meter[0].bot[0] == 8
&& s.a_meter[0].top[0] % 3 == 0)
beat = C.BLEN / 8 * 3
}
} // get_beat()
abc2svg.print('-- ' + info.T + ' --');
// get the beat
get_beat(voice_tb[0].meter)
if (beat == undefined)
return
// treat only the first voice
cur_beat = 0
for (s = voice_tb[0].sym; s; s = s.next) {
while (s.time > cur_beat) {
line += '/ ';
cur_beat += beat
}
switch (s.type) {
case C.NOTE:
case C.REST:
if (s.a_gch) { // search a chord symbol
for (i = 0; i < s.a_gch.length; i++) {
if (s.a_gch[i].type == 'g') {
line += s.a_gch[i].text + ' ';
cur_beat = s.time + beat
break
}
}
}
break
case C.BAR:
if (s.eoln) {
if (s.bar_type == '::')
line += ':|\n|: '
else
line += s.bar_type +'\n'
} else {
if (s.bar_type == '::')
line += ':|: '
else
line += s.bar_type + ' '
}
cur_beat = s.time // re-synchronize
break
case C.METER:
get_beat(s)
break
}
}
abc2svg.print(line)
}
|
| ︙ | ︙ |
Changes to toodt.js.
1 2 | // abc2svg - toodt.js - ABC translation to ODT+SVG // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - toodt.js - ABC translation to ODT+SVG // // Copyright (C) 2017-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
27 28 29 30 31 32 33 | // // (this script must appear immediately after the command) // // Constraints: // This module runs only with the nodeJS script 'abc2svg' and asks for // the npm module 'jszip' to be installed. | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
//
// (this script must appear immediately after the command)
//
// Constraints:
// This module runs only with the nodeJS script 'abc2svg' and asks for
// the npm module 'jszip' to be installed.
var margins, page_size, page_type, page_left, page_mid, page_right,
header, footer, headerfont, footerfont, in_p, t_info, title,
style = '',
content = '',
imgs = '',
seq = 0,
outfn = 'abc.odt',
fs = require('fs'), // file system
|
| ︙ | ︙ | |||
60 61 62 63 64 65 66 |
}
// convert a pixel value into page unit
function set_unit(p) {
if (typeof p == "string")
return p
if (page_type[0] == 'L')
| | | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
}
// convert a pixel value into page unit
function set_unit(p) {
if (typeof p == "string")
return p
if (page_type[0] == 'L')
return (p / 96).toFixed(1) + 'in'
return (p / 37.8).toFixed(1) + 'cm'
}
// output a header or a footer
function gen_hf(type, stype, str) {
var c, i, res_left,
j = 0,
res = '<style:' + type + '>\n\
<text:p text:style-name="' + stype + '\"><text:tab/>'
if (str[0] == '"')
str = str.slice(1, -1)
if (str.indexOf('\t') < 0) // if no TAB
str = '\t' + str // center
for (i = 0; i < str.length; i++) {
|
| ︙ | ︙ | |||
272 273 274 275 276 277 278 | xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"\ xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"\ xmlns:ooo="http://openoffice.org/2004/office"\ xmlns:ooow="http://openoffice.org/2004/writer"\ office:version="1.1">\n\ <office:styles>\n\ <style:default-style style:family="paragraph">\n\ | | > > | | 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 | xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"\ xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"\ xmlns:ooo="http://openoffice.org/2004/office"\ xmlns:ooow="http://openoffice.org/2004/writer"\ office:version="1.1">\n\ <office:styles>\n\ <style:default-style style:family="paragraph">\n\ <style:paragraph-properties fo:orphans="5" fo:widows="5"/>\n\ <style:text-properties style:use-window-font-color="true"\ style:font-name="Liberation Serif" fo:font-size="12pt"/>\n\ </style:default-style>\n\ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>\n\ <style:style style:name="P" style:family="paragraph"\ style:parent-style-name="Standard"/>\n\ <style:style style:name="Pbr" style:family="paragraph"\ style:parent-style-name="Standard">\n\ <style:paragraph-properties fo:break-before="page"/>\n\ </style:style>\n\ <style:style style:name="Header" style:family="paragraph"\ style:parent-style-name="Standard" style:class="extra">\n\ <style:paragraph-properties>\n\ <style:tab-stops>\n\ <style:tab-stop style:position="' + page_left + '" style:type="left"/>\n\ <style:tab-stop style:position="' + page_mid + '" style:type="center"/>\n\ <style:tab-stop style:position="' + page_right + '" style:type="right"/>\n\ </style:tab-stops>\n\ </style:paragraph-properties>\n\ <style:text-properties ' + headerfont + '/>\n\ </style:style>\n\ <style:style style:name="Footer" style:family="paragraph"\ style:parent-style-name="Standard" style:class="extra">\n\ <style:paragraph-properties>\n\ <style:tab-stops>\n\ <style:tab-stop style:position="' + page_left + '" style:type="left"/>\n\ <style:tab-stop style:position="' + page_mid + '" style:type="center"/>\n\ <style:tab-stop style:position="' + page_right + '" style:type="right"/>\n\ </style:tab-stops>\n\ </style:paragraph-properties>\n\ <style:text-properties ' + footerfont + '/>\n\ </style:style>\n\ </office:styles>\n\ <office:automatic-styles>\n\ <style:style style:family="graphic" style:name="graphic1" style:display-name="graphic1" style:parent-style-name="Graphics">\n\ <style:graphic-properties style:wrap="run-through" style:run-through="foreground" style:vertical-pos="top" style:vertical-rel="baseline"/>\n\ </style:style>\n\ <style:page-layout style:name="Standard">\n\ <style:page-layout-properties ' + margins + '\ fo:margin-left="0" fo:margin-right="0"/>\n\ </style:page-layout>\n\ </office:automatic-styles>\n\ <office:master-styles>\n\ <style:master-page style:name="Standard" style:page-layout-name="Standard">\n' + (header || '') + (footer || '') + '\ </style:master-page>\n\ |
| ︙ | ︙ | |||
343 344 345 346 347 348 349 |
"\n*** Abort ***\n" + e.stack + "</text:p>\n";
odt_out();
abc2svg.quit()
}
// convert a CSS font definition (in pixels) to ODT (in points)
function def_font(font) {
| < | > > > > > | > > > > > > > > > > > > | > > > | > > > | > > | > > > > > > > | > > | > | | > > > > > > > > > > > > > > > > > > > > | 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 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
"\n*** Abort ***\n" + e.stack + "</text:p>\n";
odt_out();
abc2svg.quit()
}
// convert a CSS font definition (in pixels) to ODT (in points)
function def_font(font) {
var css_font = abc.style_font(abc.cfmt()[font])
.slice(5) // remove 'font:'
.split(' '),
l = css_font.length,
fo = 'fo:font-family="' + css_font[--l] + '"',
i = css_font[--l].slice(0, -2)
fo += ' fo:font-size="' +
(i * 72 / 96).toFixed(1) + 'pt"'
while (--l >= 0) {
i = css_font[l]
switch (i) {
case 'italic':
case 'oblique':
fo += ' fo:font-style="' + i + '"'
break
case 'bold':
fo += ' fo:font-weight="' + i + '"'
break
}
}
return fo
}
function font_bug(str) {
var i, k, l, r, w,
j = 0
while (1) {
i = str.indexOf('font:', j)
if (i < 0)
return str
if (str[i - 1] == '"') {
j = str.indexOf('"', i)
} else {
j = str.indexOf('}', i);
k = str.indexOf(';', i)
if (j < 0 || (k >= 0 && k < j))
j = k
}
w = str.slice(i + 5, j).match(/[^ \t"]+|".+?"/g) // "
l = w.length;
r = 'font-family:' + w[--l] +
';font-size:' + w[--l]
while (--l >= 0) {
switch (w[l]) {
case 'italic':
r += ';font-style:italic'
break
case 'oblique':
r += ';font-style:oblique'
break
case 'bold':
r += ';font-weight:bold'
break
}
}
str = str.replace(str.slice(i, j), r)
}
}
function svg_out(str) {
var img, r, w, h,
cfmt = abc.cfmt()
switch (str.slice(0, 4)) {
case '<svg':
// get the first header/footer
if (header == undefined) {
r = cfmt.header;
header = r ? gen_hf("header", "Header", r) : '';
headerfont = def_font("headerfont")
}
if (footer == undefined) {
r = cfmt.footer;
footer = r ? gen_hf("footer", "Footer", r) : '';
footerfont = def_font("footerfont")
}
//fixme: the shorthand 'font:' does not work in the library 'librsvg'
// used by libreoffice and abiword
// (https://gitlab.gnome.org/GNOME/librsvg/issues/34)
str = font_bug(str)
// save the image
img = 'Pictures/abc' + (++seq).toString() + '.svg';
zip.file(img, str, { compression: "DEFLATE" });
// it is part of the document
imgs +='\
|
| ︙ | ︙ | |||
463 464 465 466 467 468 469 |
zip.file('mimetype',
'application/vnd.oasis.opendocument.text',
{ compression: "STORE" });
// define some functions in the Abc object
abc.tosvg("toodt", "\
%%fullsvg 1\n\
| < > | | > | | > > | > | | 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 |
zip.file('mimetype',
'application/vnd.oasis.opendocument.text',
{ compression: "STORE" });
// define some functions in the Abc object
abc.tosvg("toodt", "\
%%fullsvg 1\n\
%%musicfont abc2svg")
// get the page parameters
user.img_out = function(str) {
var cfmt = abc.cfmt(),
pw = cfmt.pagewidth;
// page size
if (pw > 800) {
page_type = 'Letter';
page_size = 'fo:page-width="8.5in" fo:page-height="11in"';
page_left = set_unit(cfmt.leftmargin);
page_mid = '4.25in';
page_right = set_unit(816 - cfmt.rightmargin)
} else {
page_type = 'A4';
page_size = 'fo:page-width="21cm" fo:page-height="29.7cm"';
page_left = set_unit(cfmt.leftmargin);
page_mid = '10.5cm';
page_right = set_unit(793.8 - cfmt.rightmargin)
}
// if abc2svg page formatting
if (abc.page)
margins = 'fo:margin-top="0" fo:margin-bottom="0"'
else
margins = 'fo:margin-top="' +
set_unit(cfmt.topmargin || 37.8) +
'" fo:margin-bottom="' +
set_unit(cfmt.botmargin || 37.8) + '"';
// output the first generated string
svg_out(str);
|
| ︙ | ︙ |
Changes to toxhtml.js.
1 2 | // abc2svg - toxhtml.js - SVG generation // | | < | > < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// abc2svg - toxhtml.js - SVG generation
//
// Copyright (C) 2014-2019 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 General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
var init_done, pw, ml, mr, pkf, lkf
// replace <>& by XML character references
function clean_txt(txt) {
return txt.replace(/<|>|&.*?;|&/g, function(c) {
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
}
return c
})
}
abc2svg.abort = function(e) {
if (!init_done) // if empty document
user.img_out('')
|
| ︙ | ︙ | |||
112 113 114 115 116 117 118 |
cfmt = abc.cfmt(),
psty = '';
nml = cfmt.leftmargin;
if (nml != ml) {
if (ml == undefined)
ml = nml;
| | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 |
cfmt = abc.cfmt(),
psty = '';
nml = cfmt.leftmargin;
if (nml != ml) {
if (ml == undefined)
ml = nml;
psty += 'margin-left:' + nml.toFixed(1) + 'px;'
}
nmr = cfmt.rightmargin;
if (nmr != mr) {
if (mr == undefined)
mr = nmr;
psty += 'margin-right:' + nmr.toFixed(1) + 'px;'
}
nlkf = cfmt.lineskipfac;
if (nlkf != lkf) {
if (lkf == undefined)
lkf = nlkf;
psty += 'line-height:' + ((nlkf * 100) | 0).toString() + '%;'
}
npkf = cfmt.parskipfac;
if (npkf != pkf) {
if (pkf == undefined)
pkf = npkf;
psty += 'margin-bottom:' + npkf.toFixed(2) + 'em;'
}
npw = cfmt.pagewidth
if (npw != pw || nml != ml || nmr != mr) {
if (pw == undefined)
pw = npw;
psty += 'width:' + (npw - nml - nmr).toFixed(1) + 'px;'
}
return psty
}
// entry point from cmdline
abc2svg.abc_init = function() {
var cfmt = abc.cfmt()
// output a header or footer
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
counter-increment: page;\n\
content: counter(page);\n\
}\n\
div.left {text-align: left}\n\
div.center {text-align: center}\n\
div.right {text-align: right}\n\
}';
abc2svg.print('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n\
"http://www.w3.org/TR/xhtml1/DTD/xhtml1.dtd">\n\
<html xmlns="http://www.w3.org/1999/xhtml">\n\
<head>\n\
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>\n\
<meta name="generator" content="abc2svg-' + abc2svg.version + '"/>\n\
| > > > > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
counter-increment: page;\n\
content: counter(page);\n\
}\n\
div.left {text-align: left}\n\
div.center {text-align: center}\n\
div.right {text-align: right}\n\
}';
// no margin / header / footer when SVG page formatting
if (abc.page)
topmargin = botmargin = header = footer = 0;
abc2svg.print('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n\
"http://www.w3.org/TR/xhtml1/DTD/xhtml1.dtd">\n\
<html xmlns="http://www.w3.org/1999/xhtml">\n\
<head>\n\
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>\n\
<meta name="generator" content="abc2svg-' + abc2svg.version + '"/>\n\
|
| ︙ | ︙ | |||
367 368 369 370 371 372 373 |
gen_hf("footer", footer);
// output the first generated string
abc2svg.print(str);
init_done = true;
// change the output function
| | < < | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
gen_hf("footer", footer);
// output the first generated string
abc2svg.print(str);
init_done = true;
// change the output function
user.img_out = abc2svg.print
}
}
abc2svg.abc_end = function() {
var font_style = abc.get_font_style()
if (!init_done) // if empty document
user.img_out('')
if (user.errtxt)
abc2svg.print("<pre>" + clean_txt(user.errtxt) + "</pre>")
if (font_style) // if some %%text at the end
abc2svg.print('<style type="text/css">' + font_style + '\n</style>');
abc2svg.print("</body>\n</html>")
}
|
Changes to util/abcdoc.js.
1 2 3 | //#javascript // abcdoc-1.js file to include in html pages with abc2svg-1.js // | | | 1 2 3 4 5 6 7 8 9 10 11 | //#javascript // abcdoc-1.js file to include in html pages with abc2svg-1.js // // Copyright (C) 2014-2019 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 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 |
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
var page = document.body.innerHTML
// load the required modules
if (!abc2svg.modules.load(page, dom_loaded))
return
// search the ABC tunes and add their rendering as SVG images
var i = 0, j, k, res,
re = /\n%abc|\nX:/g, // start on "%abc" or "X:"
| > > > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
var page = document.body.innerHTML
// accept page formatting
abc2svg.abc_end = function() {}
// load the required modules
if (!abc2svg.modules.load(page, dom_loaded))
return
// search the ABC tunes and add their rendering as SVG images
var i = 0, j, k, res,
re = /\n%abc|\nX:/g, // start on "%abc" or "X:"
|
| ︙ | ︙ | |||
112 113 114 115 116 117 118 | if (!res) break j = re.lastIndex - res[0].length; new_page += page.slice(i, j); // get the end of the ABC sequence // including the %%beginxxx/%%endxxx sequences | | | | | > | | 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 |
if (!res)
break
j = re.lastIndex - res[0].length;
new_page += page.slice(i, j);
// get the end of the ABC sequence
// including the %%beginxxx/%%endxxx sequences
re_stop.lastIndex = ++j
while (1) {
res = re_stop.exec(page)
if (!res || res[0] == "\n<")
break
k = page.indexOf(res[0].replace("begin", "end"),
re_stop.lastIndex)
if (k < 0)
break
re_stop.lastIndex = k
}
if (!res || k < 0)
k = page.length
else
k = re_stop.lastIndex - 2;
tune = page.slice(j, k);
new_page += '<pre style="display:inline-block; vertical-align: top">' +
clean_txt(tune) +
'</pre>\n\
<div style="display:inline-block; vertical-align: top">\n'
// not "float:right"
try {
abc.tosvg('abcdoc', tune)
} catch (e) {
alert("abc2svg javascript error: " + e.message +
"\nStack:\n" + e.stack)
}
if (errtxt) {
i = page.indexOf("\n", j);
i = page.indexOf("\n", i + 1);
alert("Errors in\n" +
page.slice(j, i) +
"\n...\n\n" + errtxt);
errtxt = ""
}
abc2svg.abc_end(); // close the page if %%pageheight
new_page += '</div><br/>\n';
i = k
if (k >= page.length)
break
re.lastIndex = i
}
try {
document.body.innerHTML = new_page + page.slice(i)
} catch (e) {
alert("abc2svg bad generated SVG: " + e.message +
"\nStack:\n" + e.stack)
}
}
// wait for the page to be loaded
document.addEventListener("DOMContentLoaded", dom_loaded, false)
|
Changes to util/abcemb.js.
1 2 3 | //#javascript // abcemb-1.js file to include in html pages with abc2svg-1.js // | | | 1 2 3 4 5 6 7 8 9 10 11 | //#javascript // abcemb-1.js file to include in html pages with abc2svg-1.js // // Copyright (C) 2014-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
84 85 86 87 88 89 90 |
if (!abcplay) {
if (typeof AbcPlay == "undefined") { // as play-1.js not loaded,
playseq = function(){} // don't come here anymore
return
}
abcplay = AbcPlay(playconf);
| < < < < < | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
if (!abcplay) {
if (typeof AbcPlay == "undefined") { // as play-1.js not loaded,
playseq = function(){} // don't come here anymore
return
}
abcplay = AbcPlay(playconf);
}
if (playing) {
abcplay.stop();
return
}
playing = true
if (!a_pe[seq]) { // if no playing event
|
| ︙ | ︙ | |||
143 144 145 146 147 148 149 150 |
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
page = document.body.innerHTML;
// load the required modules
| > > > | > > | > > | | | 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 |
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
page = document.body.innerHTML;
// accept page formatting
abc2svg.abc_end = function() {}
// load the required modules
if (abc2svg.modules.load(page, render))
render()
}
function render() {
page = document.body.innerHTML;
// search the ABC tunes,
// replace them by SVG images with play on click
var i = 0, j, k, res, src,
seq = 0,
re = /\n%abc|\nX:/g,
re_stop = /\nX:|\n<|\n%.begin/g,
select = window.location.hash.slice(1);
abc = new abc2svg.Abc(user)
// check if a selection
if (select) {
select = decodeURIComponent(select);
select = page.search(select)
if (select < 0)
select = 0
}
for (;;) {
// get the start of a ABC sequence
|
| ︙ | ︙ | |||
210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
try {
abc.tosvg('abcemb', page, j, k)
} catch (e) {
alert("abc2svg javascript error: " + e.message +
"\nStack:\n" + e.stack)
}
if (errtxt) {
i = page.indexOf("\n", j);
i = page.indexOf("\n", i + 1);
alert("Errors in\n" +
page.slice(j, i) +
"\n...\n\n" + errtxt);
errtxt = ""
| > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
try {
abc.tosvg('abcemb', page, j, k)
} catch (e) {
alert("abc2svg javascript error: " + e.message +
"\nStack:\n" + e.stack)
}
abc2svg.abc_end() // close the page if %%pageheight
if (errtxt) {
i = page.indexOf("\n", j);
i = page.indexOf("\n", i + 1);
alert("Errors in\n" +
page.slice(j, i) +
"\n...\n\n" + errtxt);
errtxt = ""
|
| ︙ | ︙ |
Added util/abcemb2.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
//#javascript
// abcemb2-1.js file to include in html pages with abc2svg-1.js
//
// Copyright (C) 2018-2019 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 General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
window.onerror = function(msg, url, line) {
if (typeof msg == 'string')
alert("window error: " + msg +
"\nURL: " + url +
"\nLine: " + line)
else if (typeof msg == 'object')
alert("window error: " + msg.type + ' ' + msg.target.src)
else
alert("window error: " + msg)
return false
}
var errtxt = '',
abc, // (must be global for follow.js)
elts, // ABC HTML elements
tunes = '', // source of the ABC sequences
indx = [], // indexes of the tunes in tunes
select,
playing,
abcplay,
playconf = {
onend: endplay
},
a_pe = [], // index: #sequence, value: playing events
glop, // global sequence index for play
old_gm,
jsdir = document.currentScript ?
document.currentScript.src.match(/.*\//) :
(function() {
var scrs = document.getElementsByTagName('script');
return scrs[scrs.length - 1].src.match(/.*\//) || ''
})()
// -- abc2svg init argument
var user = {
errmsg: function(msg, l, c) { // get the errors
errtxt += clean_txt(msg) + '\n'
},
img_out: function(str) { // image output
new_page += str
},
page_format: true // define the non-page-breakable blocks
}
// replace <>& by XML character references
function clean_txt(txt) {
return txt.replace(/<|>|&.*?;|&/g, function(c) {
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
}
return c
})
}
function endplay() {
playing = false
}
// function called on click on the music
function playseq(i) {
var outputs
if (!abcplay) {
if (typeof AbcPlay == "undefined") { // as play-1.js not loaded,
playseq = function(){} // don't come here anymore
return
}
abcplay = AbcPlay(playconf);
}
if (playing) {
abcplay.stop()
return
}
playing = true
if (!a_pe[i]) { // if no playing event
abc = new abc2svg.Abc(user);
abcplay.clear();
abc.tosvg("play", "%%play")
if (select)
abc.tosvg('abcemb2', select)
try {
if (glop != undefined)
abc.tosvg("abcemb2", tunes, indx[glop], indx[glop + 1]);
abc.tosvg("abcemb2-" + i, tunes, indx[i], indx[i + 1])
} catch(e) {
alert(e.message + '\nabc2svg tosvg bug - stack:\n' + e.stack);
playing = false;
a_pe[seq] = null
return
}
a_pe[i] = abcplay.clear() // keep the playing events
}
abcplay.play(0, 100000, a_pe[i])
}
// function called when the page is loaded
function dom_loaded() {
// loop until abc2svg is fully loaded
if (typeof abc2svg != "object"
|| !abc2svg.modules) {
setTimeout(dom_loaded, 500)
return
}
// convert HTML to ABC
function toabc(s) {
return s.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/&/g, '&')
.replace(/[ \t]+(%%)/g, '$1')
.replace(/[ \t]+(.:)/g, '$1')
}
// function to load javascript files
abc2svg.loadjs = function(fn, relay, onerror) {
var s = document.createElement('script');
if (/:\/\//.test(fn))
s.src = fn // absolute URL
else
s.src = jsdir + fn;
s.type = 'text/javascript'
if (relay)
s.onload = relay;
s.onerror = onerror || function() {
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
// extract the ABC code
elts = document.getElementsByClassName('abc')
for (var i = 0; i < elts.length; i++) {
var elt = elts[i];
indx[i] = tunes.length;
tunes += toabc(elt.innerHTML) + '\n'
}
indx[i] = tunes.length;
ready()
}
function ready() {
var i, j
// load the required modules
if (!abc2svg.modules.load(tunes, ready))
return
// accept page formatting
abc2svg.abc_end = function() {}
var sel = window.location.hash.slice(1)
if (sel)
select = '%%select ' + decodeURIComponent(sel);
abc = new abc2svg.Abc(user)
// generate and replace
for (var i = 0; i < elts.length; i++) {
new_page = ""
// set the playing callback
j = tunes.indexOf('X:', indx[i])
if (j >= 0 && j < indx[i + 1])
new_page += '<div onclick="playseq(' + i + ')">\n'
else if (glop == undefined)
glop = i
if (sel) {
abc.tosvg('abcemb2', select);
sel = ''
}
try {
abc.tosvg('abcemb2', tunes, indx[i], indx[i + 1])
} catch (e) {
alert("abc2svg javascript error: " + e.message +
"\nStack:\n" + e.stack)
}
if (errtxt) {
new_page += '<p style="background:#ff8080">' +
errtxt + "</p>\n";
errtxt = ""
}
try {
elts[i].innerHTML = new_page
} catch (e) {
alert("abc2svg bad generated SVG: " + e.message +
"\nStack:\n" + e.stack)
}
if (j >= 0 && j < indx[i + 1])
new_page += '</div>\n'
abc2svg.abc_end() // close the page if %%pageheight
}
// prepare for playing
delete user.img_out; // stop SVG generation
old_gm = user.get_abcmodel;
user.get_abcmodel = function(tsfirst, voice_tb, music_types, info) {
if (old_gm)
old_gm(tsfirst, voice_tb, music_types, info);
abcplay.add(tsfirst, voice_tb)
}
} // dom_loaded()
// wait for the page to be loaded
document.addEventListener("DOMContentLoaded", dom_loaded, false)
|
Changes to util/follow.js.
1 | // follow-1.js - file to include in html pages after | | | | 1 2 3 4 5 6 7 8 9 10 11 12 | // follow-1.js - file to include in html pages after // abc2svg-1.js, abcemb[2]-1.js and play-1.js. // This script permits to follow the notes while playing. // // Copyright (C) 2015-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ |
Changes to util/midi.js.
| ︙ | ︙ | |||
34 35 36 37 38 39 40 |
//
// // The MIDI pitches are stored in the notes
// // s.notes[i].midi
// }
// AbcMIDI creation
function AbcMIDI() {
| | < < < < < < > | 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 |
//
// // The MIDI pitches are stored in the notes
// // s.notes[i].midi
// }
// AbcMIDI creation
function AbcMIDI() {
var C = abc2svg.C
// add MIDI pitches
AbcMIDI.prototype.add = function(s, // starting symbol
voice_tb) { // voice table
var scale = new Int8Array( // note to pitch
[0, 2, 4, 5, 7, 9, 11]),
bmap = new Int8Array(7), // measure base map
map = new Int8Array(70), // current map - 10 octaves
tie_map, // index = MIDI pitch
tie_time,
v,
transp // clef transpose
// re-initialize the map on bar
function bar_map() {
for (var j = 0; j < 10; j++)
for (var i = 0; i < 7; i++)
|
| ︙ | ︙ | |||
89 90 91 92 93 94 95 |
} // key_map()
// convert ABC pitch to MIDI
function pit2midi(p, a) {
if (a)
map[p] = a == 3 ? 0 : a; // (3 = natural)
return ((p / 7) | 0) * 12 + scale[p % 7] +
| | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
} // key_map()
// convert ABC pitch to MIDI
function pit2midi(p, a) {
if (a)
map[p] = a == 3 ? 0 : a; // (3 = natural)
return ((p / 7) | 0) * 12 + scale[p % 7] +
(tie_time[p] ? tie_map[p] : map[p])
} // pit2midi()
// initialize the clefs and keys
for (v = 0; v < voice_tb.length; v++) {
if (!voice_tb[v].sym)
continue
s = voice_tb[v].clef
|
| ︙ | ︙ | |||
112 113 114 115 116 117 118 |
// and loop on the symbols of the voice
vloop(v)
}
function vloop(v) {
var i, g, p, note,
s = voice_tb[v].sym,
vtime = s.time, // next time
| < > | | | | | | | | | | | | 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 |
// and loop on the symbols of the voice
vloop(v)
}
function vloop(v) {
var i, g, p, note,
s = voice_tb[v].sym,
vtime = s.time, // next time
rep_tie_map = []
tie_map = []
tie_time = []
while (s) {
if (s.time > vtime) { // if time skip
bar_map() // force a measure bar
vtime = s.time
}
if (s.dur)
vtime = s.time + s.dur
switch (s.type) {
case C.BAR:
//fixme: pb when lack of measure bar (voice overlay, new voice)
// x times repeat
if (s.text) {
if (s.text[0] == '1') { // 1st time
rep_tie_map = [];
rep_tie_time = []
for (i = 0; i < tie_map.length; i++)
rep_tie_map[i] = tie_map[i]
} else if (rep_tie_map.length != 0) {
tie_map = []
tie_time = []
for (i = 0; i < rep_tie_map.length; i++) {
tie_map[i] = rep_tie_map[i];
tie_time[i] = s.time
}
}
}
if (!s.invis)
bar_map()
break
case C.CLEF:
if (!s.clef_octave
|| s.clef_oct_transp)
transp = 0
else
transp = s.clef_octave
break
case C.GRACE:
for (g = s.extra; g; g = g.next) {
if (!g.type != C.NOTE)
continue
for (i = 0; i <= g.nhd; i++) {
note = g.notes[i];
p = note.pit + 19 + transp;
note.midi = pit2midi(p, note.acc)
}
}
break
case C.KEY:
key_map(s)
break
case C.NOTE:
for (i = 0; i <= s.nhd; i++) {
note = s.notes[i];
p = note.pit + 19 + // pitch from C-1
transp
if (tie_time[p]) {
if (s.time > tie_time[p]) {
delete tie_map[p]
delete tie_time[p]
}
}
note.midi = pit2midi(p, note.acc)
if (note.ti1) {
|
| ︙ | ︙ |
Changes to util/play.js.
1 2 | // play-1.js - file to include in html pages with abc2svg-1.js for playing // | | | 1 2 3 4 5 6 7 8 9 10 | // play-1.js - file to include in html pages with abc2svg-1.js for playing // // Copyright (C) 2015-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
20 21 22 23 24 25 26 | // This file is a wrapper around // - ToAudio (toaudio.js - convert ABC to audio sequences) // - Audio5 (toaudio5.js - play the audio sequences with webaudio and SF2) // - Midi5 (tomidi5.js - play the audio sequences with webmidi) // AbcPlay methods: // | < < < < < < < > < < < < < < < < < < < < < < < < < < < | < < < < < < | 20 21 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 |
// This file is a wrapper around
// - ToAudio (toaudio.js - convert ABC to audio sequences)
// - Audio5 (toaudio5.js - play the audio sequences with webaudio and SF2)
// - Midi5 (tomidi5.js - play the audio sequences with webmidi)
// AbcPlay methods:
//
// set_sfu() - get/set the soundfont URL
// @url: URL - undefined = return current value
//
// set_speed() - get/set the play speed
// @speed: < 1 slower, > 1 faster - undefined = return current value
//
// set_vol() - get/set the current sound volume
// @volume: range [0..1] - undefined = return current value
function AbcPlay(i_conf) {
var conf = i_conf,
init = {},
audio = ToAudio(),
audio5, midi5, current,
abcplay = { // returned object (only instance)
clear: audio.clear,
add: audio.add,
set_sft: vf,
set_sfu: function(v) {
if (v == undefined)
return conf.sfu
conf.sfu = v
},
set_speed: function(v) {
if (v == undefined)
|
| ︙ | ︙ | |||
94 95 96 97 98 99 100 |
stop: vf
}
function vf() {} // void function
// start playing when no defined output
function play(istart, i_iend, a_e) {
| > > > > > > > > > > > | > > > | > > > > > > | | | > > > | < | < < | < | < | < < | > > | < | < < < | 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 |
stop: vf
}
function vf() {} // void function
// start playing when no defined output
function play(istart, i_iend, a_e) {
init.istart = istart;
init.i_iend = i_iend;
init.a_e = a_e
if (midi5)
midi5.get_outputs(play2) // get the MIDI ports
else
play2()
} // play()
// if set, out contains an array of the MIDI output ports
function play2(out) {
var o
if (!out)
out = []
o = audio5.get_outputs() // get the HTML5 audio port
if (o)
out = out.concat(o)
if (out.length == 0) {
if (conf.onend) // no output port
conf.onend()
}
if (out.length == 1) {
o = 0 // only one port
} else {
o = -1 // ask which port?
var pr = "Use"
for (var i = 0; i < out.length; i++)
pr += "\n " + i + ": " + out[i]
var res = window.prompt(pr, '0')
if (res) {
o = Number(res)
if (isNaN(o) || o < 0 || o >= out.length)
o = -1
}
if (!res || o < 0) {
if (conf.onend)
conf.onend()
return
}
}
// set the current output changing the play functions
current = out[o] == 'sf2' ? audio5 : midi5;
abcplay.play = current.play;
abcplay.stop = current.stop
if (current.set_output)
current.set_output(out[o]);
abcplay.play(init.istart, init.i_iend, init.a_e);
init = {}
} // play2()
// set default configuration values
conf.gain = 0.7;
conf.speed = 1;
// get the play parameters from localStorage
(function get_param() {
try {
if (!localStorage)
return
} catch (e) {
return
}
var v = localStorage.getItem("sfu")
if (v)
conf.sfu = v;
v = localStorage.getItem("volume")
if (v)
conf.gain = Number(v)
})()
|
| ︙ | ︙ |
Changes to util/sf2-parser.js.
1 2 3 4 5 6 7 8 9 10 11 12 | /*! JavaScript SoundFont 2 Parser. Copyright 2013-2015 imaya/GREE Inc and Colin Clark. Licensed under the MIT License. */ /* * JavaScript SoundFont 2 Parser * * Copyright 2013 imaya/GREE Inc * Copyright 2015 Colin Clark * * Based on code from the "SoundFont Synthesizer for WebMidiLink" * https://github.com/gree/sf2synth.js * * Adapted to abc2svg | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/*! JavaScript SoundFont 2 Parser. Copyright 2013-2015 imaya/GREE Inc and Colin Clark. Licensed under the MIT License. */
/*
* JavaScript SoundFont 2 Parser
*
* Copyright 2013 imaya/GREE Inc
* Copyright 2015 Colin Clark
*
* Based on code from the "SoundFont Synthesizer for WebMidiLink"
* https://github.com/gree/sf2synth.js
*
* Adapted to abc2svg
* Copyright (C) 2018-2019 Jean-Francois Moine
*
* Licensed under the MIT License.
*/
/*global require*/
(function (root, factory) {
|
| ︙ | ︙ |
Changes to util/toaudio.js.
1 2 | // toaudio.js - audio generation // | | < | < < < < < < < < > | > > > > > > > > > > > | | | | > > > > > > > > > > > > > > > | | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 |
// toaudio.js - audio generation
//
// Copyright (C) 2015-2019 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.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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/>.
// ToAudio creation
function ToAudio() {
var C = abc2svg.C,
scale = new Uint8Array([0, 2, 4, 5, 7, 9, 11]), // note to pitch conversion
a_e, // event array
p_time, // last playing time
abc_time, // last ABC time
play_factor; // play time factor
// ToAudio
return {
// clear the playing events and
// return the old ones as an array of Float32Array:
// [0]: index of the note in the ABC source
// [1]: time in seconds
// [2]: if >= 0: MIDI instrument (MIDI GM number - 1)
// else: MIDI control message
// [3]: MIDI note pitch (with cents) / controller
// [4]: duration / controller value
// [5]: volume (0..1)
// [6]: voice number
clear: function() {
var a_pe = a_e;
a_e = null
return a_pe
}, // clear()
// add playing events from the ABC model
add: function(start, // starting symbol
voice_tb) { // voice table
var kmaps = [], // accidentals per voice from key signature
cmaps = [], // current accidental table
map, // map of the current voice - 10 octaves
temper, // temperament
i, n, dt, d, v,
top_v, // top voice
rep_st_s, // start of sequence to be repeated
rep_en_s, // end ("|1")
rep_nx_s, // restart at end of repeat
rep_st_transp, // transposition at start of repeat sequence
rep_st_map, // and map
rep_st_fac, // and play factor
transp, // clef transposition per voice
instr = [], // instrument per voice
s = start
// set the accidentals, transpositions and instruments of the voices
function set_voices() {
var v, p_v, s, mi
temper = voice_tb[0].temper; // (set by the module temper.js)
transp = new Int8Array(voice_tb.length)
for (v = 0; v < voice_tb.length; v++) {
p_v = voice_tb[v];
mi = p_v.instr || 0
if (p_v.midictl) {
p_v.midictl.forEach(function(val, i) {
switch(i) {
case 0: // bank MSB
mi += val * 128 * 128
break
case 32: // bank LSB
mi += val * 128
break
default: // generate a MIDI control
a_e.push(new Float32Array([
p_v.sym.istart,
1, // (time)
-1, // MIDI control
i,
val,
1,
v]))
}
})
}
instr[v] = mi; // MIDI instrument
s = p_v.clef;
transp[v] = (!s.clef_octave || s.clef_oct_transp) ?
0 : s.clef_octave
kmaps[v] = new Float32Array(70);
cmaps[v] = new Float32Array(70);
p_v.key.v = v;
key_map(p_v.key)
}
} // set_voices()
// define the accidentals of a voice
function key_map(s) {
var i, bmap
if (s.k_bagpipe) {
// detune for just intonation in A (C is C#, F is F# and G is Gnat)
// bmap = new Float32Array([100-13.7, -2, 2, 100-15.6, -31.2, 0, 3.9])
// for (i = 0; i < 7; i++)
// bmap[i] = (bmap[i] + 150.6) / 100 // 'A' bagpipe = 480Hz
// // 150.6 = (Math.log2(480/440) - 1)*1200
bmap = new Float32Array([2.37, 1.49, 1.53, 2.35, 1.19, 1.51, 1.55])
} else {
bmap = new Float32Array(7)
switch (s.k_sf) {
case 7: bmap[6] = 1
case 6: bmap[2] = 1
case 5: bmap[5] = 1
case 4: bmap[1] = 1
|
| ︙ | ︙ | |||
126 127 128 129 130 131 132 |
for (i = 0; i < 10; i++)
kmaps[s.v].set(bmap, i * 7);
cmaps[s.v].set(kmaps[s.v])
} // key_map()
// convert ABC pitch to MIDI index
function pit2mid(s, i) {
| < | | > > | > > > | | 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 |
for (i = 0; i < 10; i++)
kmaps[s.v].set(bmap, i * 7);
cmaps[s.v].set(kmaps[s.v])
} // key_map()
// convert ABC pitch to MIDI index
function pit2mid(s, i) {
var note = s.notes[i],
p = note.pit + 19, // pitch from C-1
a = note.acc
if (transp[s.v])
p += transp[s.v]
if (a) {
if (a == 3) // (3 = natural)
a = 0
else if (note.micro_n)
a = (a < 0 ? -note.micro_n : note.micro_n) /
note.micro_d * 2;
map[p] = a
} else {
a = map[p]
}
p = ((p / 7) | 0) * 12 + scale[p % 7] + a
if (!temper || a | 0 != a) // if equal temperament or micro-tone
return p
return p + temper[p % 12]
} // pit2mid()
// handle the ties
function do_tie(s, note, d) {
var n,
end_time = s.time + s.dur,
pit = note.pit,
p = pit + 19,
a = note.acc
if (transp[s.v])
p += transp[s.v]
// search the end of the tie
|
| ︙ | ︙ | |||
172 173 174 175 176 177 178 | s = s.ts_next if (!s) return d end_time = s.time } if (s.time != end_time) return d | | | | | | | | | > > > | > > | | | | | > > | | | > | | 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 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
s = s.ts_next
if (!s)
return d
end_time = s.time
}
if (s.time != end_time)
return d
if (s.type == C.NOTE)
break
}
n = s.notes.length
for (i = 0; i < n; i++) {
note = s.notes[i]
if (note.pit == pit) {
d += s.dur / play_factor;
note.ti2 = true
return note.ti1 ? do_tie(s, note, d) : d
}
}
return d
} // do_tie()
// generate the grace notes
function gen_grace(s) {
var g, i, n, t, d, s2,
next = s.next
// before beat
if (s.sappo) {
d = C.BLEN / 16
} else if ((!next || next.type != C.NOTE)
&& s.prev && s.prev.type == C.NOTE) {
d = s.prev.dur / 2
// on beat
} else {
// keep the sound elements in time order
next.ts_prev.ts_next = next.ts_next;
next.ts_next.ts_prev = next.ts_prev;
for (s2 = next.ts_next; s2; s2 = s2.ts_next) {
if (s2.time != next.time) {
next.ts_next = s2
next.ts_prev = s2.ts_prev;
next.ts_prev.ts_next = next;
s2.ts_prev = next
break
}
}
// if (!next.dots)
// d = next.dur / 2
// else if (next.dots == 1)
// d = next.dur / 3
// else
// d = next.dur * 2 / 7;
d = next.dur / 12
if (d & (d - 1) == 0)
d = next.dur / 2 // no dot
else
d = next.dur / 3;
next.time += d;
next.dur -= d
}
n = 0
for (g = s.extra; g; g = g.next)
if (g.type == C.NOTE)
n++;
d /= n * play_factor;
t = p_time
for (g = s.extra; g; g = g.next) {
if (g.type != C.NOTE)
continue
gen_notes(g, t, d);
t += d
}
} // gen_grace()
// generate the notes
function gen_notes(s, t, d) {
for (var i = 0; i <= s.nhd; i++) {
var note = s.notes[i]
if (note.ti2)
continue
a_e.push(new Float32Array([
s.istart,
t,
instr[s.v],
pit2mid(s, i),
note.ti1 ? do_tie(s, note, d) : d,
1,
s.v]))
}
} // gen_note()
// add() main
set_voices(); // initialize the voice parameters
if (!a_e) { // if first call
a_e = []
abc_time = rep_st_t = p_time = 0;
play_factor = C.BLEN / 4 * 120 / 60 // default: Q:1/4=120
} else if (s.time < abc_time) {
abc_time = rep_st_t = s.time
}
// loop on the symbols
while (s) {
// if (s.type == C.TEMPO
// && s.tempo) {
if (s.tempo) { // tempo change
d = 0;
n = s.tempo_notes.length
for (i = 0; i < n; i++)
d += s.tempo_notes[i];
play_factor = d * s.tempo / 60
}
dt = s.time - abc_time
if (dt > 0) {
p_time += dt / play_factor;
abc_time = s.time
}
if (s == rep_en_s) { // repeat end
s = rep_nx_s;
abc_time = s.time
}
map = cmaps[s.v]
switch (s.type) {
case C.BAR:
//fixme: does not work if different measures per voice
if (s.v != top_v)
break
// right repeat
if (s.bar_type[0] == ':') {
s.bar_type = '|' +
|
| ︙ | ︙ | |||
344 345 346 347 348 349 350 |
break
// 1st time repeat
} else if (s.text && s.text[0] == '1') {
rep_en_s = s
}
break
| | | | | | | | | | | > | | > > > > > > > > > | > > > > > > > > > > > > | 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 |
break
// 1st time repeat
} else if (s.text && s.text[0] == '1') {
rep_en_s = s
}
break
case C.CLEF:
transp[s.v] = (!s.clef_octave || s.clef_oct_transp) ?
0 : s.clef_octave
break
case C.GRACE:
if (s.time == 0 // if before beat at start time
&& abc_time == 0) {
dt = 0
if (s.sappo)
dt = C.BLEN / 16
else if (!s.next || s.next.type != C.NOTE)
dt = d / 2;
abc_time -= dt
}
gen_grace(s)
break
case C.KEY:
key_map(s)
break
case C.REST:
case C.NOTE:
d = s.dur
if (s.next && s.next.type == C.GRACE) {
dt = 0
if (s.next.sappo)
dt = C.BLEN / 16
else if (!s.next.next || s.next.next.type != C.NOTE)
dt = d / 2;
s.next.time -= dt;
d -= dt
}
d /= play_factor
if (s.type == C.NOTE)
gen_notes(s, p_time, d)
else
a_e.push(new Float32Array([
s.istart,
p_time,
0,
0,
d,
0,
s.v]))
break
case C.STAVES:
top_v = s.sy.top_voice
break
case C.BLOCK:
if (s.subtype != "midictl")
break
a_e.push(new Float32Array([ // generate a MIDI control
s.istart,
p_time,
-1, // MIDI control
s.ctrl,
s.val,
1,
s.v]))
break
}
s = s.ts_next
}
} // add()
} // return
} // ToAudio
// nodejs
if (typeof module == 'object' && typeof exports == 'object')
exports.ToAudio = ToAudio
|
Changes to util/toaudio5.js.
1 2 | // toaudio5.js - audio output using HTML5 audio // | | | | | > > > > > > > > > > > > > | < < | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 | // toaudio5.js - audio output using HTML5 audio // // Copyright (C) 2015-2019 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 General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // Audio5 creation // @conf: configuration object - all items are optional: // ac: audio context - (default: created on play start) // sfu: soundfont URL (sf2 base64 encoded - default: "Scc1t2") // onend: callback function called at end of playing // (no arguments) // onnote: callback function called on note start/stop playing // Arguments: // i: start index of the note in the ABC source // on: true on note start, false on note stop // instr_load: function to load the sound font of an instrument // (default: js_instr_load) // Arguments: // instr: MIDI instrument number // done: callback function in case of success // Arguments: soundfont in binary format // fail: callback function in case of error // no argument // errmsg: function called on error (default: alert) // // When playing, the following items must/may be set: // gain: (mandatory) volume, must be set to [0..1] // speed: (mandatory) must be set to 1 // new_speed: (optional) new speed value // Audio5 methods // get_outputs() - get the output devices // return ['sf2'] or null // // play() - start playing // @start_index - // @stop_index: indexes of the play_event array // @play_event: array of array // [0]: index of the note in the ABC source // [1]: time in seconds // [2]: if >= 0: MIDI instrument (MIDI GM number - 1) // else: MIDI control message (not treated here) // [3]: MIDI note pitch (with cents) // [4]: duration // [5]: volume (0..1 - optional) // // stop() - stop playing // // set_vol() - set the current sound volume |
| ︙ | ︙ | |||
66 67 68 69 70 71 72 | // instruments/notes params = [], // [instr][key] note parameters per instrument rates = [], // [instr][key] playback rates w_instr = 0, // number of instruments being loaded // -- play the memorized events -- evt_idx, // event index while playing | | | > > > > > > > > > > > > > | 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 |
// instruments/notes
params = [], // [instr][key] note parameters per instrument
rates = [], // [instr][key] playback rates
w_instr = 0, // number of instruments being loaded
// -- play the memorized events --
evt_idx, // event index while playing
iend, // play array stop index
stime, // start playing time
timouts = [] // note start events
// default sound font load function
function js_instr_load(instr, done, fail) {
abc2svg.loadjs(conf.sfu + '/' + instr + '.js',
function() {
done(b64dcod(abcsf2[instr]))
},
fail
)
}
if (!conf.instr_load)
conf.instr_load = js_instr_load
// base64 stuff
var b64d = []
function init_b64d() {
var b64l = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
l = b64l.length
for (var i = 0; i < l; i++)
|
| ︙ | ︙ | |||
188 189 190 191 192 193 194 | (j + tune) * scale); params[instr][j] = parm } } } // sf2_create() // load an instrument (.js file) | | | | | | > | > | | | | 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 |
(j + tune) * scale);
params[instr][j] = parm
}
}
} // sf2_create()
// load an instrument (.js file)
function load_instr(instr, a_e) {
w_instr++;
conf.instr_load(instr,
function(sf2_bin) {
var parser = new sf2.Parser(sf2_bin);
parser.parse();
sf2_create(parser, instr);
if (--w_instr == 0)
play_start(a_e)
},
function() {
errmsg('could not find the instrument ' +
((instr / 128) | 0).toString() + '-' +
(instr % 128).toString());
if (--w_instr == 0)
play_start(a_e)
})
} // load_instr()
// start loading the instruments
function load_res(a_e) {
var i, e, instr
for (i = evt_idx; ; i++) {
e = a_e[i]
if (!e || evt_idx >= iend)
break
instr = e[2]
if (instr >= 0 && !params[instr]) {
params[instr] = [];
load_instr(instr, a_e)
}
}
}
// create a note
// @e[2] = instrument index
// @e[3] = MIDI key + detune
|
| ︙ | ︙ | |||
278 279 280 281 282 283 284 |
} // note_run()
// play the next time sequence
function play_next(a_e) {
var t, e, e2, maxt, st, d;
// play the next events
| > | | < > > | | < | | | | | > | > | < < | 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 |
} // note_run()
// play the next time sequence
function play_next(a_e) {
var t, e, e2, maxt, st, d;
// play the next events
if (a_e) // if not stop
e = a_e[evt_idx]
if (!e || evt_idx >= iend) {
onend()
return
}
// if speed change, shift the start time
if (conf.new_speed) {
stime = ac.currentTime -
(ac.currentTime - stime) *
conf.speed / conf.new_speed;
conf.speed = conf.new_speed;
conf.new_speed = 0
}
timouts = [];
//fixme: better, count the number of events?
t = e[1] / conf.speed; // start time
maxt = t + 3 // max time = evt time + 3 seconds
while (1) {
d = e[4] / conf.speed
if (e[2] >= 0) { // if not a MIDI control message
if (e[5] != 0) // if not a rest
note_run(e, t + stime, d)
// follow the notes while playing
var i = e[0];
st = (t + stime - ac.currentTime) * 1000;
timouts.push(setTimeout(onnote, st, i, true));
setTimeout(onnote, st + d * 1000, i, false)
}
e = a_e[++evt_idx]
if (!e || evt_idx >= iend) {
setTimeout(onend,
(t + stime - ac.currentTime + d) * 1000)
return
}
t = e[1] / conf.speed
if (t > maxt)
break
}
// delay before next sound generation
timouts.push(setTimeout(play_next, (t + stime - ac.currentTime)
* 1000 - 300, // wake before end of playing
a_e))
} // play_next()
// wait for all resources, then start playing
function play_start(a_e) {
if (iend == 0) { // play stop
onend()
return
}
// wait for instruments
if (w_instr != 0)
return
// all resources are there
gain.connect(ac.destination);
stime = ac.currentTime + .2 // start time + 0.2s
- a_e[evt_idx][1] * conf.speed;
play_next(a_e)
} // play_start()
|
| ︙ | ︙ | |||
363 364 365 366 367 368 369 |
get_outputs: function() {
return (window.AudioContext || window.webkitAudioContext) ?
['sf2'] : null
}, // get_outputs()
// play the events
play: function(istart, i_iend, a_e) {
| | | < < < < < < > > > > | 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 |
get_outputs: function() {
return (window.AudioContext || window.webkitAudioContext) ?
['sf2'] : null
}, // get_outputs()
// play the events
play: function(istart, i_iend, a_e) {
if (!a_e || istart >= a_e.length) {
onend() // nothing to play
return
}
// initialize the audio subsystem if not done yet
// (needed for iPhone/iPad/...)
if (!gain) {
ac = conf.ac
if (!ac)
conf.ac = ac = new (window.AudioContext ||
window.webkitAudioContext);
gain = ac.createGain();
gain.gain.value = conf.gain
}
iend = i_iend;
evt_idx = istart;
load_res(a_e);
play_start(a_e)
}, // play()
// stop playing
stop: function() {
iend = 0
timouts.forEach(function(id) {
clearTimeout(id)
})
play_next()
if (gain) {
gain.disconnect();
gain = null
}
}, // stop()
// set volume
set_vol: function(v) {
if (gain)
gain.gain.value = v
} // set_vol()
}
} // end Audio5
|
Changes to util/tomidi5.js.
1 2 | // tomidi5.js - audio output using HTML5 MIDI // | | | > > > > | < < | | > | | > > | < | | > > > > | > > > > > | > | | > > > > > > > > > > > > > > > > | > > | < < < < < < < > > | | | > > > | | | > > > > > > > > > > > > > > > > > > > > | > | > > > | > > | > | | > > > > > > > > < > | | > > > > > > > > > > | | < < | > > > > > > > > > | > > > | | > < < > > > > < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 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 |
// tomidi5.js - audio output using HTML5 MIDI
//
// Copyright (C) 2018-2019 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 General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
// Midi5 creation
// @conf: configuration object - all items are optional:
// onend: callback function called at end of playing
// (no arguments)
// onnote: callback function called on note start/stop playing
// Arguments:
// i: start index of the note in the ABC source
// on: true on note start, false on note stop
// When playing, the following items must/may be set:
// speed: (mandatory) must be set to 1
// new_speed: (optional) new speed value
// Midi5 methods
// get_outputs() - get the output ports
//
// set_output() - set the output port
//
// play() - start playing
// @start_index -
// @stop_index: indexes of the play_event array
// @play_event: array of array
// [0]: index of the note in the ABC source
// [1]: time in seconds
// [2]: if >= 0: MIDI instrument (MIDI GM number - 1)
// else: MIDI control message
// [3]: MIDI note pitch (with cents) / controller
// [4]: duration / controller value
// [5]: volume (0..1 - optional)
// [6]: voice number
//
// stop() - stop playing
function Midi5(i_conf) {
var conf = i_conf, // configuration
onend = conf.onend || function() {},
onnote = conf.onnote || function() {},
rf, // get_outputs result function
// MIDI variables
op, // output port
v_i = [], // voice (channel) to instrument
// -- play the memorized events --
evt_idx, // event index while playing
iend, // play array stop index
stime, // start playing time in ms
timouts = [] // note start events
// create a note
// @e[2] = instrument index
// @e[3] = MIDI key + detune
// @e[6] = voice (channel) number
// @t = audio start time (ms)
// @d = duration adjusted for speed (ms)
function note_run(e, t, d) {
var k = e[3] | 0,
i = e[2],
c = e[6] & 0x0f, //fixme
a = (e[3] * 100) % 100 // detune in cents
if (i == 16384) { // if bank 128
c = 9 // channel 10 (percussion)
} else if (i != v_i[c]) { // if program change
// at channel start, reset all controllers
//fixme: does not work with fluidsynth
if (v_i[c] == undefined)
op.send(new Uint8Array([0xb0 + c, 121, 0]));
v_i[c] = i
op.send(new Uint8Array([
0xb0 + c, 0, (i >> 14) & 0x7f, // MSB bank
0xb0 + c, 32, (i >> 7) & 0x7f, // LSB bank
0xc0 + c, i & 0x7f // program
]))
}
if (a && Midi5.ma.sysexEnabled) { // if microtone
// fixme: should cache the current microtone values
op.send(new Uint8Array([
0xf0, 0x7f, // realtime SysEx
0x7f, // all devices
0x08, // MIDI tuning standard
0x02, // note change
i & 0x7f, // tuning prog number
0x01, // number of notes
k, // key
k, // note
a / .78125, // MSB fract
0, // LSB fract
0xf7 // SysEx end
]), t);
}
op.send(new Uint8Array([0x90 + c, k, 127]), t); // note on
op.send(new Uint8Array([0x80 + c, k, 0]), t + d - 20) // note off
} // note_run()
// play the next time sequence
function play_next(a_e) {
var t, e, e2, maxt, st, d
// play the next events
if (a_e) // if not stop
e = a_e[evt_idx]
if (!op || evt_idx >= iend || !e) {
onend()
return
}
// if speed change, shift the start time
if (conf.new_speed) {
stime = window-performance.now() -
(window.performance.now() - stime) *
conf.speed / conf.new_speed;
conf.speed = conf.new_speed;
conf.new_speed = 0
}
timouts = [];
t = e[1] / conf.speed * 1000; // start time
maxt = t + 3000 // max time = evt time + 3 seconds
while (1) {
d = e[4] / conf.speed * 1000
if (e[2] >= 0) { // if not a MIDI control message
if (e[5] != 0) // if not a rest
note_run(e, t + stime, d)
// follow the notes while playing
st = t + stime - window.performance.now();
timouts.push(setTimeout(onnote, st, e[0], true));
setTimeout(onnote, st + d, e[0], false)
} else { // MIDI control
op.send(new Uint8Array([0xb0 + (e[6] & 0x0f),
e[3], e[4]]), t + stime)
}
e = a_e[++evt_idx]
if (!e || evt_idx >= iend) {
setTimeout(onend,
t + stime - window.performance.now() + d)
return
}
t = e[1] / conf.speed * 1000
if (t > maxt)
break
}
// delay before next sound generation
timouts.push(setTimeout(play_next, (t + stime - window.performance.now())
- 300, // wake before end of playing
a_e))
} // play_next()
// MIDI output is possible,
// return the possible ports in return to get_outputs()
function send_outputs(access) {
var o, os,
out = [];
Midi5.ma = access; // store the MIDI access in the Midi5 function
if (access && access.outputs.size > 0) {
os = access.outputs.values()
while (1) {
o = os.next()
if (!o || o.done)
break
out.push(o.value.name)
}
}
rf(out)
} // send_outputs()
// Midi5 object creation (only one instance)
// public methods
return {
// get outputs
get_outputs: function(f) {
if (!navigator.requestMIDIAccess) {
f() // no MIDI
return
}
rf = f;
// open MIDI with SysEx
navigator.requestMIDIAccess({sysex: true}).then(
send_outputs,
function(msg) {
// open MIDI without SysEx
navigator.requestMIDIAccess().then(
send_outputs,
function(msg) {
rf()
}
)
}
)
}, // get_outputs()
// set the output port
set_output: function(name) {
var o, os
if (!Midi5.ma)
return
os = Midi5.ma.outputs.values()
while (1) {
o = os.next()
if (!o || o.done)
break
if (o.value.name == name) {
op = o.value
break
}
}
},
// play the events
play: function(istart, i_iend, a_e) {
if (!a_e || istart >= a_e.length) {
onend() // nothing to play
return
}
iend = i_iend;
evt_idx = istart;
if (0) {
// temperament
op.send(new Uint8Array([
0xf0, 0x7f, // realtime SysEx
0x7f, // all devices
0x08, // MIDI tuning standard
0x02, // note change
0x00, // tuning prog number
0x01, // number of notes
0x69, // key
0x69, // note
0x00, // MSB fract
0, // LSB fract
0xf7 // SysEx end
]), t);
}
v_i = []; // must do a reset of all channels
stime = window.performance.now() + 200 // start time + 0.2s
- a_e[evt_idx][1] * conf.speed * 1000;
play_next(a_e)
}, // play()
// stop playing
stop: function() {
iend = 0
timouts.forEach(function(id) {
clearTimeout(id)
})
play_next()
//fixme: op.clear() should exist...
if (op && op.clear)
op.clear()
} // stop()
}
} // end Midi5
|