abcjs 6.0.0-beta.9 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/tests.yml +29 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/CONTRIBUTING.md +1 -0
- package/LICENSE.md +1 -1
- package/README.md +88 -7
- package/RELEASE.md +961 -1
- package/abcjs-audio.css +14 -5
- package/dist/.gitignore +1 -2
- package/dist/abcjs-basic-min.js +3 -0
- package/dist/abcjs-basic-min.js.LICENSE +23 -0
- package/dist/abcjs-basic.js +28232 -0
- package/dist/abcjs-basic.js.map +1 -0
- package/dist/abcjs-plugin-min.js +3 -0
- package/dist/abcjs-plugin-min.js.LICENSE +23 -0
- package/index.js +27 -2
- package/{static-wrappers/license.js → license.js} +1 -1
- package/package.json +26 -29
- package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
- package/src/api/abc_animation.js +1 -17
- package/src/api/abc_tablatures.js +144 -0
- package/src/api/abc_timing_callbacks.js +216 -117
- package/src/api/abc_tunebook.js +18 -67
- package/src/api/abc_tunebook_svg.js +40 -48
- package/src/data/abc_tune.js +232 -972
- package/src/data/deline-tune.js +199 -0
- package/src/edit/abc_editarea.js +112 -0
- package/src/edit/abc_editor.js +95 -221
- package/src/midi/abc_midi_create.js +48 -50
- package/src/parse/abc_common.js +0 -14
- package/src/parse/abc_parse.js +167 -1321
- package/src/parse/abc_parse_book.js +62 -0
- package/src/parse/abc_parse_directive.js +164 -41
- package/src/parse/abc_parse_header.js +116 -145
- package/src/parse/abc_parse_key_voice.js +26 -20
- package/src/parse/abc_parse_music.js +1337 -0
- package/src/parse/abc_tokenizer.js +21 -15
- package/src/parse/abc_transpose.js +3 -15
- package/src/parse/tune-builder.js +896 -0
- package/src/parse/wrap_lines.js +205 -453
- package/src/synth/abc_midi_flattener.js +1292 -0
- package/src/{midi → synth}/abc_midi_renderer.js +44 -17
- package/src/synth/abc_midi_sequencer.js +648 -0
- package/src/synth/active-audio-context.js +3 -14
- package/src/synth/cents-to-factor.js +10 -0
- package/src/synth/create-note-map.js +21 -32
- package/src/synth/create-synth-control.js +20 -103
- package/src/synth/create-synth.js +185 -77
- package/src/synth/download-buffer.js +7 -21
- package/src/synth/get-midi-file.js +13 -20
- package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
- package/src/synth/images/loop.svg.js +65 -0
- package/src/synth/images/pause.svg.js +10 -0
- package/src/synth/images/play.svg.js +9 -0
- package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
- package/src/synth/instrument-index-to-name.js +1 -16
- package/src/synth/load-note.js +37 -76
- package/src/synth/pitch-to-note-name.js +0 -15
- package/src/synth/pitches-to-perc.js +64 -0
- package/src/synth/place-note.js +78 -68
- package/src/synth/play-event.js +17 -18
- package/src/synth/register-audio-context.js +11 -23
- package/src/synth/sounds-cache.js +0 -15
- package/src/synth/supports-audio.js +9 -23
- package/src/synth/synth-controller.js +80 -49
- package/src/synth/synth-sequence.js +20 -34
- package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
- package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
- package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
- package/src/tablatures/instruments/string-patterns.js +277 -0
- package/src/tablatures/instruments/string-tablature.js +56 -0
- package/src/tablatures/instruments/tab-note.js +282 -0
- package/src/tablatures/instruments/tab-notes.js +41 -0
- package/src/tablatures/instruments/violin/tab-violin.js +47 -0
- package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
- package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
- package/src/tablatures/tab-absolute-elements.js +310 -0
- package/src/tablatures/tab-common.js +29 -0
- package/src/tablatures/tab-renderer.js +243 -0
- package/src/tablatures/transposer.js +110 -0
- package/src/test/abc_midi_lint.js +5 -22
- package/src/test/abc_midi_sequencer_lint.js +11 -14
- package/src/test/abc_parser_lint.js +136 -32
- package/src/test/abc_vertical_lint.js +94 -32
- package/src/test/rendering-lint.js +38 -5
- package/src/write/abc_absolute_element.js +112 -120
- package/src/write/abc_abstract_engraver.js +102 -253
- package/src/write/abc_beam_element.js +30 -290
- package/src/write/abc_brace_element.js +12 -121
- package/src/write/abc_create_clef.js +21 -32
- package/src/write/abc_create_key_signature.js +8 -26
- package/src/write/abc_create_note_head.js +107 -0
- package/src/write/abc_create_time_signature.js +2 -21
- package/src/write/abc_crescendo_element.js +3 -50
- package/src/write/abc_decoration.js +7 -30
- package/src/write/abc_dynamic_decoration.js +3 -37
- package/src/write/abc_ending_element.js +1 -57
- package/src/write/abc_engraver_controller.js +111 -234
- package/src/write/abc_glyphs.js +8 -18
- package/src/write/abc_relative_element.js +57 -97
- package/src/write/abc_renderer.js +10 -832
- package/src/write/abc_spacing.js +0 -15
- package/src/write/abc_staff_group_element.js +14 -349
- package/src/write/abc_tempo_element.js +9 -117
- package/src/write/abc_tie_element.js +5 -68
- package/src/write/abc_triplet_element.js +6 -124
- package/src/write/abc_voice_element.js +7 -222
- package/src/write/add-chord.js +103 -0
- package/src/write/add-text-if.js +33 -0
- package/src/write/bottom-text.js +79 -0
- package/src/write/calcHeight.js +17 -0
- package/src/write/classes.js +100 -0
- package/src/write/draw/absolute.js +68 -0
- package/src/write/draw/beam.js +56 -0
- package/src/write/draw/brace.js +106 -0
- package/src/write/draw/crescendo.js +38 -0
- package/src/write/draw/debug-box.js +8 -0
- package/src/write/draw/draw.js +56 -0
- package/src/write/draw/dynamics.js +20 -0
- package/src/write/draw/ending.js +46 -0
- package/src/write/draw/group-elements.js +66 -0
- package/src/write/draw/horizontal-line.js +25 -0
- package/src/write/draw/non-music.js +50 -0
- package/src/write/draw/print-line.js +24 -0
- package/src/write/draw/print-path.js +7 -0
- package/src/write/draw/print-stem.js +30 -0
- package/src/write/draw/print-symbol.js +59 -0
- package/src/write/draw/print-vertical-line.js +18 -0
- package/src/write/draw/relative.js +77 -0
- package/src/write/draw/round-number.js +5 -0
- package/src/write/draw/selectables.js +59 -0
- package/src/write/draw/separator.js +16 -0
- package/src/write/draw/set-paper-size.js +45 -0
- package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
- package/src/write/draw/staff-group.js +226 -0
- package/src/write/draw/staff-line.js +9 -0
- package/src/write/draw/staff.js +33 -0
- package/src/write/draw/tab-line.js +40 -0
- package/src/write/draw/tempo.js +45 -0
- package/src/write/draw/text.js +71 -0
- package/src/write/draw/tie.js +97 -0
- package/src/write/draw/triplet.js +46 -0
- package/src/write/draw/voice.js +102 -0
- package/src/write/format-jazz-chord.js +15 -0
- package/src/write/free-text.js +41 -0
- package/src/write/get-font-and-attr.js +37 -0
- package/src/write/get-text-size.js +56 -0
- package/src/write/highlight.js +11 -0
- package/src/write/layout/VoiceElements.js +121 -0
- package/src/write/layout/beam.js +213 -0
- package/src/write/layout/get-left-edge-of-staff.js +56 -0
- package/src/write/layout/getBarYAt.js +6 -0
- package/src/write/layout/layout.js +94 -0
- package/src/write/layout/setUpperAndLowerElements.js +232 -0
- package/src/write/layout/staffGroup.js +146 -0
- package/src/write/layout/triplet.js +75 -0
- package/src/write/layout/voice.js +137 -0
- package/src/write/selection.js +188 -70
- package/src/write/separator.js +10 -0
- package/src/write/set-class.js +21 -0
- package/src/write/subtitle.js +12 -0
- package/src/write/svg.js +95 -43
- package/src/write/top-text.js +54 -0
- package/src/write/unhighlight.js +11 -0
- package/test.js +27 -64
- package/types/index.d.ts +1095 -0
- package/version.js +1 -1
- package/.babelrc +0 -5
- package/.eslintrc +0 -3
- package/.gitmodules +0 -3
- package/Dockerfile +0 -8
- package/abcjs-midi.css +0 -166
- package/build-utils/loadPresets.js +0 -14
- package/build-utils/presets/webpack.analyze.js +0 -6
- package/build-utils/presets/webpack.optimize.js +0 -30
- package/build-utils/webpack.development.js +0 -14
- package/build-utils/webpack.production.js +0 -35
- package/deploy-docs.sh +0 -25
- package/docker-compose.yml +0 -13
- package/docs/README.md +0 -33
- package/fix-versions.sh +0 -23
- package/midi.js +0 -62
- package/src/api/abc_tunebook_midi.js +0 -116
- package/src/midi/abc_midi_controls.js +0 -701
- package/src/midi/abc_midi_flattener.js +0 -1119
- package/src/midi/abc_midi_js_preparer.js +0 -243
- package/src/midi/abc_midi_sequencer.js +0 -401
- package/src/midi/abc_midi_ui_generator.js +0 -86
- package/src/plugin/abc_plugin_midi.js +0 -220
- package/src/synth/images/loop.svg +0 -61
- package/src/synth/images/pause.svg +0 -6
- package/src/synth/images/play.svg +0 -5
- package/src/transform/abc2abc_write.js +0 -395
- package/static-wrappers/basic.js +0 -2
- package/static-wrappers/midi.js +0 -2
- package/static-wrappers/plugin-midi.js +0 -6
- package/static-wrappers/plugin.js +0 -6
- package/webpack.config.js +0 -29
|
@@ -1,33 +1,4 @@
|
|
|
1
1
|
// abc_beam_element.js: Definition of the BeamElem class.
|
|
2
|
-
// Copyright (C) 2010-2020 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
|
3
|
-
//
|
|
4
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
5
|
-
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
6
|
-
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
7
|
-
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
-
//
|
|
9
|
-
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
-
//
|
|
11
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
12
|
-
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
13
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
14
|
-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
15
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
|
-
|
|
17
|
-
var AbsoluteElement = require('./abc_absolute_element');
|
|
18
|
-
var RelativeElement = require('./abc_relative_element');
|
|
19
|
-
var spacing = require('./abc_spacing');
|
|
20
|
-
|
|
21
|
-
var getDurlog = function(duration) {
|
|
22
|
-
// TODO-PER: This is a hack to prevent a Chrome lockup. Duration should have been defined already,
|
|
23
|
-
// but there's definitely a case where it isn't. [Probably something to do with triplets.]
|
|
24
|
-
if (duration === undefined) {
|
|
25
|
-
return 0;
|
|
26
|
-
}
|
|
27
|
-
// console.log("getDurlog: " + duration);
|
|
28
|
-
return Math.floor(Math.log(duration)/Math.log(2));
|
|
29
|
-
};
|
|
30
|
-
|
|
31
2
|
|
|
32
3
|
// Most elements on the page are related to a particular absolute element -- notes, rests, bars, etc. Beams, however, span multiple elements.
|
|
33
4
|
// This means that beams can't be laid out until the absolute elements are placed. There is the further complication that the stems for beamed
|
|
@@ -41,22 +12,19 @@ var getDurlog = function(duration) {
|
|
|
41
12
|
// There are three phases: the setup phase, when new elements are being discovered, the layout phase, when everything is calculated, and the drawing phase,
|
|
42
13
|
// when the object is not changed, but is used to put the elements on the page.
|
|
43
14
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
// Setup phase
|
|
51
|
-
//
|
|
52
|
-
BeamElem = function BeamElem(stemHeight, type, flat, firstElement) {
|
|
15
|
+
//
|
|
16
|
+
// Setup phase
|
|
17
|
+
//
|
|
18
|
+
var BeamElem = function BeamElem(stemHeight, type, flat, firstElement) {
|
|
53
19
|
// type is "grace", "up", "down", or undefined. flat is used to force flat beams, as it commonly found in the grace notes of bagpipe music.
|
|
20
|
+
this.type = "BeamElem";
|
|
54
21
|
this.isflat = !!flat;
|
|
55
|
-
this.isgrace = (type && type === "grace");
|
|
56
|
-
this.forceup = this.isgrace || (type && type === "up");
|
|
57
|
-
this.forcedown = (type && type === "down");
|
|
22
|
+
this.isgrace = !!(type && type === "grace");
|
|
23
|
+
this.forceup = !!(this.isgrace || (type && type === "up"));
|
|
24
|
+
this.forcedown = !!(type && type === "down");
|
|
58
25
|
this.elems = []; // all the AbsoluteElements that this beam touches. It may include embedded rests.
|
|
59
26
|
this.total = 0;
|
|
27
|
+
this.average = 6; // use middle line as start for average.
|
|
60
28
|
this.allrests = true;
|
|
61
29
|
this.stemHeight = stemHeight;
|
|
62
30
|
this.beams = []; // During the layout phase, this will become a list of the beams that need to be drawn.
|
|
@@ -90,260 +58,32 @@ var BeamElem;
|
|
|
90
58
|
}
|
|
91
59
|
};
|
|
92
60
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
BeamElem.prototype.calcDir = function() {
|
|
96
|
-
if (this.forceup) return true;
|
|
97
|
-
if (this.forcedown) return false;
|
|
98
|
-
var average = calcAverage(this.total, this.elems.length);
|
|
99
|
-
return average < middleLine;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
// layout phase
|
|
104
|
-
//
|
|
105
|
-
BeamElem.prototype.layout = function() {
|
|
106
|
-
if (this.elems.length === 0 || this.allrests) return;
|
|
107
|
-
|
|
108
|
-
this.stemsUp = this.calcDir(); // True means the stems are facing up.
|
|
109
|
-
var dy = calcDy(this.stemsUp, this.isgrace); // This is the width of the beam line.
|
|
110
|
-
|
|
111
|
-
// create the main beam
|
|
112
|
-
var firstElement = this.elems[0];
|
|
113
|
-
var lastElement = this.elems[this.elems.length - 1];
|
|
114
|
-
var minStemHeight = 0; // The following is to leave space for "!///!" marks.
|
|
115
|
-
var referencePitch = this.stemsUp ? firstElement.abcelem.maxpitch : firstElement.abcelem.minpitch;
|
|
116
|
-
minStemHeight = minStem(firstElement, this.stemsUp, referencePitch, minStemHeight);
|
|
117
|
-
minStemHeight = minStem(lastElement, this.stemsUp, referencePitch, minStemHeight);
|
|
118
|
-
minStemHeight = Math.max(this.stemHeight, minStemHeight + 3); // TODO-PER: The 3 is the width of a 16th beam. The actual height of the beam should be used instead.
|
|
119
|
-
var yPos = calcYPos(this.total, this.elems.length, minStemHeight, this.stemsUp, firstElement.abcelem.averagepitch, lastElement.abcelem.averagepitch, this.isflat, this.min, this.max, this.isgrace);
|
|
120
|
-
var xPos = calcXPos(this.stemsUp, firstElement, lastElement);
|
|
121
|
-
this.beams.push({ startX: xPos[0], endX: xPos[1], startY: yPos[0], endY: yPos[1], dy: dy });
|
|
122
|
-
|
|
123
|
-
// create the rest of the beams (in the case of 1/16th notes, etc.
|
|
124
|
-
var beams = createAdditionalBeams(this.elems, this.stemsUp, this.beams[0], this.isgrace, dy);
|
|
125
|
-
for (var i = 0; i < beams.length; i++)
|
|
126
|
-
this.beams.push(beams[i]);
|
|
127
|
-
|
|
128
|
-
// Now that the main beam is defined, we know how tall the stems should be, so create them and attach them to the original notes.
|
|
129
|
-
createStems(this.elems, this.stemsUp, this.beams[0], dy, this.mainNote);
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
BeamElem.prototype.isAbove = function() {
|
|
133
|
-
return this.stemsUp;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
// We can't just use the entire beam for the calculation. The range has to be passed in, because the beam might extend into some unrelated notes. for instance, (3_a'f'e'f'2 when L:16
|
|
137
|
-
BeamElem.prototype.heightAtMidpoint = function(startX, endX) {
|
|
138
|
-
if (this.beams.length === 0)
|
|
139
|
-
return 0;
|
|
140
|
-
var beam = this.beams[0];
|
|
141
|
-
var midPoint = startX + (endX - startX) / 2;
|
|
142
|
-
return getBarYAt(beam.startX, beam.startY, beam.endX, beam.endY, midPoint);
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
BeamElem.prototype.yAtNote = function(element) {
|
|
146
|
-
var beam = this.beams[0];
|
|
147
|
-
return getBarYAt(beam.startX, beam.startY, beam.endX, beam.endY, element.x);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
BeamElem.prototype.xAtMidpoint = function(startX, endX) {
|
|
151
|
-
return startX + (endX - startX)/2;
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
//
|
|
155
|
-
// Drawing phase
|
|
156
|
-
//
|
|
157
|
-
BeamElem.prototype.draw = function(renderer) {
|
|
158
|
-
if (this.beams.length === 0) return;
|
|
159
|
-
|
|
160
|
-
var klass = 'beam-elem';
|
|
161
|
-
if (this.hint)
|
|
162
|
-
klass += " abcjs-hint";
|
|
163
|
-
|
|
164
|
-
var pathString = "";
|
|
165
|
-
for (var i = 0; i < this.beams.length; i++) {
|
|
166
|
-
var beam = this.beams[i];
|
|
167
|
-
pathString += drawBeam(renderer, beam.startX, beam.startY, beam.endX, beam.endY, beam.dy);
|
|
168
|
-
}
|
|
169
|
-
var durationClass = ("abcjs-d"+this.duration).replace(/\./g,"-");
|
|
170
|
-
var klasses = renderer.addClasses('beam-elem '+durationClass);
|
|
171
|
-
renderer.controller.currentAbsEl = { tuneNumber: renderer.controller.engraver.tuneNumber, elemset: [], abcelem: { el_type: "beam", startChar: -1, endChar: -1 }};
|
|
172
|
-
var el = renderer.printPath({
|
|
173
|
-
path: pathString,
|
|
174
|
-
stroke: "none",
|
|
175
|
-
fill: "#000000",
|
|
176
|
-
'class': klasses
|
|
177
|
-
}, {history: 'not-selectable'});
|
|
178
|
-
renderer.controller.currentAbsEl.elemset.push(el);
|
|
61
|
+
BeamElem.prototype.addBeam = function(beam) {
|
|
62
|
+
this.beams.push(beam);
|
|
179
63
|
};
|
|
180
64
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
var
|
|
189
|
-
|
|
190
|
-
minStemHeight = Math.max(minStemHeight, elem.top - referencePitch);
|
|
191
|
-
else if (!stemsUp && elem.bottom !== undefined && elem.c === "flags.ugrace")
|
|
192
|
-
minStemHeight = Math.max(minStemHeight, referencePitch - elem.bottom + 7); // The extra 7 is because we are measuring the slash from the top.
|
|
193
|
-
}
|
|
194
|
-
return minStemHeight;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function calcSlant(leftAveragePitch, rightAveragePitch, numStems, isFlat) {
|
|
198
|
-
if (isFlat)
|
|
199
|
-
return 0;
|
|
200
|
-
var slant = leftAveragePitch - rightAveragePitch;
|
|
201
|
-
var maxSlant = numStems / 2;
|
|
202
|
-
|
|
203
|
-
if (slant > maxSlant) slant = maxSlant;
|
|
204
|
-
if (slant < -maxSlant) slant = -maxSlant;
|
|
205
|
-
return slant;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function calcAverage(total, numElements) {
|
|
209
|
-
if (!numElements)
|
|
210
|
-
return 0;
|
|
211
|
-
return total / numElements;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function getBarYAt(startx, starty, endx, endy, x) {
|
|
215
|
-
return starty + (endy - starty) / (endx - startx) * (x - startx);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function calcDy(asc, isGrace) {
|
|
219
|
-
var dy = (asc) ? spacing.STEP : -spacing.STEP;
|
|
220
|
-
if (isGrace) dy = dy * 0.4;
|
|
221
|
-
return dy;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function drawBeam(renderer, startX, startY, endX, endY, dy) {
|
|
225
|
-
// the X coordinates are actual coordinates, but the Y coordinates are in pitches.
|
|
226
|
-
startY = renderer.calcY(startY);
|
|
227
|
-
endY = renderer.calcY(endY);
|
|
228
|
-
return "M" + startX + " " + startY + " L" + endX + " " + endY +
|
|
229
|
-
"L" + endX + " " + (endY + dy) + " L" + startX + " " + (startY + dy) + "z";
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function calcXPos(asc, firstElement, lastElement) {
|
|
233
|
-
var starthead = firstElement.heads[asc ? 0 : firstElement.heads.length - 1];
|
|
234
|
-
var endhead = lastElement.heads[asc ? 0 : lastElement.heads.length - 1];
|
|
235
|
-
var startX = starthead.x;
|
|
236
|
-
if (asc) startX += starthead.w - 0.6;
|
|
237
|
-
var endX = endhead.x;
|
|
238
|
-
if (asc) endX += endhead.w;
|
|
239
|
-
return [ startX, endX ];
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function calcYPos(total, numElements, stemHeight, asc, firstAveragePitch, lastAveragePitch, isFlat, minPitch, maxPitch, isGrace) {
|
|
243
|
-
var average = calcAverage(total, numElements); // This is the average pitch for the all the notes that will be beamed.
|
|
244
|
-
var barpos = stemHeight - 2; // (isGrace)? 5:7;
|
|
245
|
-
var barminpos = stemHeight - 2;
|
|
246
|
-
var pos = Math.round(asc ? Math.max(average + barpos, maxPitch + barminpos) : Math.min(average - barpos, minPitch - barminpos));
|
|
247
|
-
|
|
248
|
-
var slant = calcSlant(firstAveragePitch, lastAveragePitch, numElements, isFlat);
|
|
249
|
-
var startY = pos + Math.floor(slant / 2);
|
|
250
|
-
var endY = pos + Math.floor(-slant / 2);
|
|
251
|
-
|
|
252
|
-
// If the notes are too high or too low, make the beam go down to the middle
|
|
253
|
-
if (!isGrace) {
|
|
254
|
-
if (asc && pos < 6) {
|
|
255
|
-
startY = 6;
|
|
256
|
-
endY = 6;
|
|
257
|
-
} else if (!asc && pos > 6) {
|
|
258
|
-
startY = 6;
|
|
259
|
-
endY = 6;
|
|
260
|
-
}
|
|
65
|
+
BeamElem.prototype.calcDir = function() {
|
|
66
|
+
this.average = calcAverage(this.total, this.elems.length);
|
|
67
|
+
if (this.forceup) {
|
|
68
|
+
this.stemsUp = true;
|
|
69
|
+
} else if (this.forcedown) {
|
|
70
|
+
this.stemsUp = false;
|
|
71
|
+
} else {
|
|
72
|
+
var middleLine = 6; // hardcoded 6 is B
|
|
73
|
+
this.stemsUp = this.average < middleLine; // true is up, false is down;
|
|
261
74
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
function createStems(elems, asc, beam, dy, mainNote) {
|
|
267
|
-
for (var i = 0; i < elems.length; i++) {
|
|
268
|
-
var elem = elems[i];
|
|
269
|
-
if (elem.abcelem.rest)
|
|
270
|
-
continue;
|
|
271
|
-
// TODO-PER: This is odd. If it is a regular beam then elems is an array of AbsoluteElements, if it is a grace beam then it is an array of objects , so we directly attach the element to the parent. We tell it if is a grace note because they are passed in as a generic object instead of an AbsoluteElement.
|
|
272
|
-
var isGrace = elem.addExtra ? false : true;
|
|
273
|
-
var parent = isGrace ? mainNote : elem;
|
|
274
|
-
var furthestHead = elem.heads[(asc) ? 0 : elem.heads.length - 1];
|
|
275
|
-
var ovalDelta = 1 / 5;//(isGrace)?1/3:1/5;
|
|
276
|
-
var pitch = furthestHead.pitch + ((asc) ? ovalDelta : -ovalDelta);
|
|
277
|
-
var dx = asc ? furthestHead.w : 0; // down-pointing stems start on the left side of the note, up-pointing stems start on the right side, so we offset by the note width.
|
|
278
|
-
var x = furthestHead.x + dx; // this is now the actual x location in pixels.
|
|
279
|
-
var bary = getBarYAt(beam.startX, beam.startY, beam.endX, beam.endY, x);
|
|
280
|
-
var lineWidth = (asc) ? -0.6 : 0.6;
|
|
281
|
-
if (!asc)
|
|
282
|
-
bary -= (dy / 2) / spacing.STEP; // TODO-PER: This is just a fudge factor so the down-pointing stems don't overlap.
|
|
283
|
-
if (isGrace)
|
|
284
|
-
dx += elem.heads[0].dx;
|
|
285
|
-
// TODO-PER-HACK: One type of note head has a different placement of the stem. This should be more generically calculated:
|
|
286
|
-
if (furthestHead.c === 'noteheads.slash.quarter') {
|
|
287
|
-
if (asc)
|
|
288
|
-
pitch += 1;
|
|
289
|
-
else
|
|
290
|
-
pitch -= 1;
|
|
75
|
+
var dir = this.stemsUp ? 'up' : 'down';
|
|
76
|
+
for (var i = 0; i < this.elems.length; i++) {
|
|
77
|
+
for (var j = 0; j < this.elems[i].heads.length; j++) {
|
|
78
|
+
this.elems[i].heads[j].stemDir = dir;
|
|
291
79
|
}
|
|
292
|
-
var stem = new RelativeElement(null, dx, 0, pitch, {
|
|
293
|
-
"type": "stem",
|
|
294
|
-
"pitch2": bary,
|
|
295
|
-
linewidth: lineWidth
|
|
296
|
-
});
|
|
297
|
-
stem.setX(parent.x); // This is after the x coordinates were set, so we have to set it directly.
|
|
298
|
-
parent.addExtra(stem);
|
|
299
80
|
}
|
|
81
|
+
};
|
|
300
82
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
for (var i = 0; i < elems.length; i++) {
|
|
307
|
-
var elem = elems[i];
|
|
308
|
-
if (elem.abcelem.rest)
|
|
309
|
-
continue;
|
|
310
|
-
var furthestHead = elem.heads[(asc) ? 0 : elem.heads.length - 1];
|
|
311
|
-
var x = furthestHead.x + ((asc) ? furthestHead.w : 0);
|
|
312
|
-
var bary = getBarYAt(beam.startX, beam.startY, beam.endX, beam.endY, x);
|
|
313
|
-
|
|
314
|
-
var sy = (asc) ? -1.5 : 1.5;
|
|
315
|
-
if (isGrace) sy = sy * 2 / 3; // This makes the second beam on grace notes closer to the first one.
|
|
316
|
-
var duration = elem.abcelem.duration; // get the duration via abcelem because of triplets
|
|
317
|
-
if (duration === 0) duration = 0.25; // if this is stemless, then we use quarter note as the duration.
|
|
318
|
-
for (var durlog = getDurlog(duration); durlog < -3; durlog++) {
|
|
319
|
-
if (auxBeams[-4 - durlog]) {
|
|
320
|
-
auxBeams[-4 - durlog].single = false;
|
|
321
|
-
} else {
|
|
322
|
-
auxBeams[-4 - durlog] = {
|
|
323
|
-
x: x + ((asc) ? -0.6 : 0), y: bary + sy * (-4 - durlog + 1),
|
|
324
|
-
durlog: durlog, single: true
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
for (var j = auxBeams.length - 1; j >= 0; j--) {
|
|
330
|
-
if (i === elems.length - 1 || getDurlog(elems[i + 1].abcelem.duration) > (-j - 4)) {
|
|
331
|
-
|
|
332
|
-
var auxBeamEndX = x;
|
|
333
|
-
var auxBeamEndY = bary + sy * (j + 1);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
if (auxBeams[j].single) {
|
|
337
|
-
auxBeamEndX = (i === 0) ? x + 5 : x - 5;
|
|
338
|
-
auxBeamEndY = getBarYAt(beam.startX, beam.startY, beam.endX, beam.endY, auxBeamEndX) + sy * (j + 1);
|
|
339
|
-
}
|
|
340
|
-
beams.push({ startX: auxBeams[j].x, endX: auxBeamEndX, startY: auxBeams[j].y, endY: auxBeamEndY, dy: dy });
|
|
341
|
-
auxBeams = auxBeams.slice(0, j);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
return beams;
|
|
346
|
-
}
|
|
347
|
-
})();
|
|
83
|
+
function calcAverage(total, numElements) {
|
|
84
|
+
if (!numElements)
|
|
85
|
+
return 0;
|
|
86
|
+
return total / numElements;
|
|
87
|
+
}
|
|
348
88
|
|
|
349
89
|
module.exports = BeamElem;
|
|
@@ -1,38 +1,22 @@
|
|
|
1
1
|
// abc_brace_element.js: Definition of the BraceElement class.
|
|
2
|
-
// Copyright (C) 2010-2020 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
|
3
|
-
//
|
|
4
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
5
|
-
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
6
|
-
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
7
|
-
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
-
//
|
|
9
|
-
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
-
//
|
|
11
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
12
|
-
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
13
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
14
|
-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
15
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
2
|
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
var BraceElem = function BraceElem(staff, type) {
|
|
21
|
-
this.startStaff = staff;
|
|
3
|
+
var BraceElem = function BraceElem(voice, type) {
|
|
4
|
+
this.startVoice = voice;
|
|
22
5
|
this.type = type;
|
|
23
6
|
};
|
|
24
7
|
|
|
25
|
-
BraceElem.prototype.setBottomStaff = function(
|
|
26
|
-
this.
|
|
8
|
+
BraceElem.prototype.setBottomStaff = function(voice) {
|
|
9
|
+
this.endVoice = voice;
|
|
10
|
+
// If only the start brace has a name then the name belongs to the brace instead of the staff.
|
|
11
|
+
if (this.startVoice.header && !this.endVoice.header) {
|
|
12
|
+
this.header = this.startVoice.header;
|
|
13
|
+
delete this.startVoice.header;
|
|
14
|
+
}
|
|
27
15
|
};
|
|
28
16
|
|
|
29
|
-
BraceElem.prototype.continuing = function(
|
|
17
|
+
BraceElem.prototype.continuing = function(voice) {
|
|
30
18
|
// If the final staff isn't present, then use the last one we saw.
|
|
31
|
-
this.
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
BraceElem.prototype.setLocation = function(x) {
|
|
35
|
-
this.x = x;
|
|
19
|
+
this.lastContinuedVoice = voice;
|
|
36
20
|
};
|
|
37
21
|
|
|
38
22
|
BraceElem.prototype.getWidth = function() {
|
|
@@ -40,102 +24,9 @@ BraceElem.prototype.getWidth = function() {
|
|
|
40
24
|
};
|
|
41
25
|
|
|
42
26
|
BraceElem.prototype.isStartVoice = function (voice) {
|
|
43
|
-
if (this.
|
|
27
|
+
if (this.startVoice && this.startVoice.staff && this.startVoice.staff.voices.length > 0 && this.startVoice.staff.voices[0] === voice)
|
|
44
28
|
return true;
|
|
45
29
|
return false;
|
|
46
30
|
};
|
|
47
31
|
|
|
48
|
-
BraceElem.prototype.draw = function (renderer, top, bottom) {
|
|
49
|
-
// The absoluteY number is the spot where the note on the first ledger line is drawn (i.e. middle C if treble clef)
|
|
50
|
-
// The STEP offset here moves it to the top and bottom lines
|
|
51
|
-
this.startY = this.startStaff.absoluteY - spacing.STEP*10;
|
|
52
|
-
if (this.endStaff)
|
|
53
|
-
this.endY = this.endStaff.absoluteY - spacing.STEP*2;
|
|
54
|
-
else if (this.lastContinuedStaff)
|
|
55
|
-
this.endY = this.lastContinuedStaff.absoluteY - spacing.STEP*2;
|
|
56
|
-
else
|
|
57
|
-
this.endY = this.startStaff.absoluteY - spacing.STEP*2;
|
|
58
|
-
this.drawBrace(renderer, this.x,this.startY, this.endY);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
function straightPath(renderer, xLeft, yTop, yBottom, type) {
|
|
62
|
-
xLeft += spacing.STEP;
|
|
63
|
-
var xLineWidth = spacing.STEP*0.75;
|
|
64
|
-
var yOverlap = spacing.STEP*0.75;
|
|
65
|
-
var height = yBottom - yTop;
|
|
66
|
-
// Straight line
|
|
67
|
-
var pathString = sprintf("M %f %f l %f %f l %f %f l %f %f z",
|
|
68
|
-
xLeft, yTop-yOverlap, // top left line
|
|
69
|
-
0, height+yOverlap*2, // bottom left line
|
|
70
|
-
xLineWidth, 0, // bottom right line
|
|
71
|
-
0, - (height+yOverlap*2) // top right line
|
|
72
|
-
);
|
|
73
|
-
// Top arm
|
|
74
|
-
var wCurve = spacing.STEP*2;
|
|
75
|
-
var hCurve = spacing.STEP;
|
|
76
|
-
pathString += sprintf("M %f %f q %f %f %f %f q %f %f %f %f z",
|
|
77
|
-
xLeft+xLineWidth, yTop-yOverlap, // top left arm
|
|
78
|
-
wCurve*0.6, hCurve*0.2,
|
|
79
|
-
wCurve, -hCurve, // right point
|
|
80
|
-
-wCurve*0.1, hCurve*0.3,
|
|
81
|
-
-wCurve, hCurve+spacing.STEP // left bottom
|
|
82
|
-
);
|
|
83
|
-
// Bottom arm
|
|
84
|
-
pathString += sprintf("M %f %f q %f %f %f %f q %f %f %f %f z",
|
|
85
|
-
xLeft+xLineWidth, yTop+yOverlap+height, // bottom left arm
|
|
86
|
-
wCurve*0.6, -hCurve*0.2,
|
|
87
|
-
wCurve, hCurve, // right point
|
|
88
|
-
-wCurve*0.1, -hCurve*0.3,
|
|
89
|
-
-wCurve, -hCurve-spacing.STEP // left bottom
|
|
90
|
-
);
|
|
91
|
-
return renderer.paper.path({path:pathString, stroke:"#000000", fill:"#000000", 'class': renderer.addClasses(type)});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function curvyPath(renderer, xLeft, yTop, yBottom, type) {
|
|
95
|
-
var yHeight = yBottom - yTop;
|
|
96
|
-
|
|
97
|
-
var xCurve = [7.5, -8, 21, 0, 18.5, -10.5, 7.5];
|
|
98
|
-
var yCurve = [0, yHeight/5.5, yHeight/3.14, yHeight/2, yHeight/2.93, yHeight/4.88, 0];
|
|
99
|
-
|
|
100
|
-
var pathString = sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z",
|
|
101
|
-
xLeft+xCurve[0], yTop+yCurve[0],
|
|
102
|
-
xLeft+xCurve[1], yTop+yCurve[1],
|
|
103
|
-
xLeft+xCurve[2], yTop+yCurve[2],
|
|
104
|
-
xLeft+xCurve[3], yTop+yCurve[3],
|
|
105
|
-
xLeft+xCurve[4], yTop+yCurve[4],
|
|
106
|
-
xLeft+xCurve[5], yTop+yCurve[5],
|
|
107
|
-
xLeft+xCurve[6], yTop+yCurve[6]);
|
|
108
|
-
|
|
109
|
-
xCurve = [0, 17.5, -7.5, 6.6, -5, 20, 0];
|
|
110
|
-
yCurve = [yHeight/2, yHeight/1.46, yHeight/1.22, yHeight, yHeight/1.19, yHeight/1.42, yHeight/2];
|
|
111
|
-
|
|
112
|
-
pathString += sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z",
|
|
113
|
-
xLeft+xCurve[0], yTop+yCurve[0],
|
|
114
|
-
xLeft+xCurve[1], yTop+yCurve[1],
|
|
115
|
-
xLeft+xCurve[2], yTop+yCurve[2],
|
|
116
|
-
xLeft+xCurve[3], yTop+yCurve[3],
|
|
117
|
-
xLeft+xCurve[4], yTop+yCurve[4],
|
|
118
|
-
xLeft+xCurve[5], yTop+yCurve[5],
|
|
119
|
-
xLeft+xCurve[6], yTop+yCurve[6]);
|
|
120
|
-
return renderer.paper.path({path:pathString, stroke:"#000000", fill:"#000000", 'class': renderer.addClasses(type)});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
BraceElem.prototype.drawBrace = function(renderer, xLeft, yTop, yBottom) {//Tony
|
|
124
|
-
var type = this.type;
|
|
125
|
-
var ret = renderer.wrapInAbsElem({ el_type: type, startChar: -1, endChar: -1 }, 'abcjs-'+type, function() {
|
|
126
|
-
var ret;
|
|
127
|
-
if (type === "brace")
|
|
128
|
-
ret = curvyPath(renderer, xLeft, yTop, yBottom, type);
|
|
129
|
-
else if (type === "bracket")
|
|
130
|
-
ret = straightPath(renderer, xLeft, yTop, yBottom, type);
|
|
131
|
-
renderer.controller.recordHistory(ret, true);
|
|
132
|
-
return ret;
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
if (renderer.doRegression){
|
|
136
|
-
renderer.addToRegression(ret);
|
|
137
|
-
}
|
|
138
|
-
return ret;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
32
|
module.exports = BraceElem;
|
|
@@ -1,31 +1,13 @@
|
|
|
1
1
|
// abc_create_clef.js
|
|
2
|
-
// Copyright (C) 2010-2020 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
|
3
|
-
//
|
|
4
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
5
|
-
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
6
|
-
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
7
|
-
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
-
//
|
|
9
|
-
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
-
//
|
|
11
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
12
|
-
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
13
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
14
|
-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
15
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
2
|
|
|
17
3
|
var AbsoluteElement = require('./abc_absolute_element');
|
|
18
4
|
var glyphs = require('./abc_glyphs');
|
|
19
5
|
var RelativeElement = require('./abc_relative_element');
|
|
20
6
|
|
|
21
|
-
var createClef
|
|
22
|
-
|
|
23
|
-
(function() {
|
|
24
|
-
"use strict";
|
|
25
|
-
|
|
26
|
-
createClef = function(elem, tuneNumber) {
|
|
7
|
+
var createClef = function(elem, tuneNumber) {
|
|
27
8
|
var clef;
|
|
28
9
|
var octave = 0;
|
|
10
|
+
elem.el_type = "clef";
|
|
29
11
|
var abselem = new AbsoluteElement(elem,0,10, 'staff-extra clef', tuneNumber);
|
|
30
12
|
abselem.isClef = true;
|
|
31
13
|
switch (elem.type) {
|
|
@@ -43,26 +25,23 @@ var createClef;
|
|
|
43
25
|
case 'alto-8': clef="clefs.C"; octave = -1; break;
|
|
44
26
|
case 'none': return null;
|
|
45
27
|
case 'perc': clef="clefs.perc"; break;
|
|
46
|
-
default: abselem.
|
|
28
|
+
default: abselem.addFixed(new RelativeElement("clef="+elem.type, 0, 0, undefined, {type:"debug"}));
|
|
47
29
|
}
|
|
48
30
|
// if (elem.verticalPos) {
|
|
49
31
|
// pitch = elem.verticalPos;
|
|
50
32
|
// }
|
|
51
33
|
var dx =5;
|
|
52
34
|
if (clef) {
|
|
53
|
-
|
|
35
|
+
var height = glyphs.symbolHeightInPitches(clef);
|
|
36
|
+
var ofs = clefOffsets(clef);
|
|
37
|
+
abselem.addRight(new RelativeElement(clef, dx, glyphs.getSymbolWidth(clef), elem.clefPos, { top: height+elem.clefPos+ofs, bottom: elem.clefPos+ofs}));
|
|
54
38
|
|
|
55
|
-
if (clef === 'clefs.G') {
|
|
56
|
-
abselem.top = 13;
|
|
57
|
-
abselem.bottom = -1;
|
|
58
|
-
} else {
|
|
59
|
-
abselem.top = 10;
|
|
60
|
-
abselem.bottom = 2;
|
|
61
|
-
}
|
|
62
39
|
if (octave !== 0) {
|
|
63
40
|
var scale = 2 / 3;
|
|
64
41
|
var adjustspacing = (glyphs.getSymbolWidth(clef) - glyphs.getSymbolWidth("8") * scale) / 2;
|
|
65
42
|
var pitch = (octave > 0) ? abselem.top + 3 : abselem.bottom - 1;
|
|
43
|
+
var top = (octave > 0) ? abselem.top + 3 : abselem.bottom - 3;
|
|
44
|
+
var bottom = top-2;
|
|
66
45
|
if (elem.type === "bass-8") {
|
|
67
46
|
// The placement for bass octave is a little different. It should hug the clef.
|
|
68
47
|
pitch = 3;
|
|
@@ -70,14 +49,24 @@ var createClef;
|
|
|
70
49
|
}
|
|
71
50
|
abselem.addRight(new RelativeElement("8", dx + adjustspacing, glyphs.getSymbolWidth("8") * scale, pitch, {
|
|
72
51
|
scalex: scale,
|
|
73
|
-
scaley: scale
|
|
52
|
+
scaley: scale,
|
|
53
|
+
top: top,
|
|
54
|
+
bottom: bottom
|
|
74
55
|
}));
|
|
75
|
-
abselem.top += 2;
|
|
56
|
+
//abselem.top += 2;
|
|
76
57
|
}
|
|
77
58
|
}
|
|
78
59
|
return abselem;
|
|
79
60
|
};
|
|
80
61
|
|
|
81
|
-
|
|
62
|
+
function clefOffsets(clef) {
|
|
63
|
+
switch (clef) {
|
|
64
|
+
case "clefs.G": return -5;
|
|
65
|
+
case "clefs.C": return -4;
|
|
66
|
+
case "clefs.F": return -4;
|
|
67
|
+
case "clefs.perc": return -2;
|
|
68
|
+
default: return 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
82
71
|
|
|
83
72
|
module.exports = createClef;
|
|
@@ -1,18 +1,4 @@
|
|
|
1
1
|
// abc_create_key_signature.js
|
|
2
|
-
// Copyright (C) 2010-2020 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
|
3
|
-
//
|
|
4
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
5
|
-
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
6
|
-
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
7
|
-
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
-
//
|
|
9
|
-
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
-
//
|
|
11
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
12
|
-
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
13
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
14
|
-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
15
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
2
|
|
|
17
3
|
var AbsoluteElement = require('./abc_absolute_element');
|
|
18
4
|
var glyphs = require('./abc_glyphs');
|
|
@@ -20,12 +6,8 @@ var RelativeElement = require('./abc_relative_element');
|
|
|
20
6
|
|
|
21
7
|
var parseCommon = require('../parse/abc_common');
|
|
22
8
|
|
|
23
|
-
var createKeySignature
|
|
24
|
-
|
|
25
|
-
(function() {
|
|
26
|
-
"use strict";
|
|
27
|
-
|
|
28
|
-
createKeySignature = function(elem, tuneNumber) {
|
|
9
|
+
var createKeySignature = function(elem, tuneNumber) {
|
|
10
|
+
elem.el_type = "keySignature";
|
|
29
11
|
if (!elem.accidentals || elem.accidentals.length === 0)
|
|
30
12
|
return null;
|
|
31
13
|
var abselem = new AbsoluteElement(elem, 0, 10, 'staff-extra key-signature', tuneNumber);
|
|
@@ -33,19 +15,19 @@ var createKeySignature;
|
|
|
33
15
|
var dx = 0;
|
|
34
16
|
parseCommon.each(elem.accidentals, function(acc) {
|
|
35
17
|
var symbol;
|
|
18
|
+
var fudge = 0;
|
|
36
19
|
switch(acc.acc) {
|
|
37
|
-
case "sharp": symbol = "accidentals.sharp"; break;
|
|
20
|
+
case "sharp": symbol = "accidentals.sharp"; fudge = -3; break;
|
|
38
21
|
case "natural": symbol = "accidentals.nat"; break;
|
|
39
|
-
case "flat": symbol = "accidentals.flat"; break;
|
|
40
|
-
case "quartersharp": symbol = "accidentals.halfsharp"; break;
|
|
41
|
-
case "quarterflat": symbol = "accidentals.halfflat"; break;
|
|
22
|
+
case "flat": symbol = "accidentals.flat"; fudge = -1.2; break;
|
|
23
|
+
case "quartersharp": symbol = "accidentals.halfsharp"; fudge = -2.5; break;
|
|
24
|
+
case "quarterflat": symbol = "accidentals.halfflat"; fudge = -1.2; break;
|
|
42
25
|
default: symbol = "accidentals.flat";
|
|
43
26
|
}
|
|
44
|
-
abselem.addRight(new RelativeElement(symbol, dx, glyphs.getSymbolWidth(symbol), acc.verticalPos, {thickness: glyphs.symbolHeightInPitches(symbol)}));
|
|
27
|
+
abselem.addRight(new RelativeElement(symbol, dx, glyphs.getSymbolWidth(symbol), acc.verticalPos, {thickness: glyphs.symbolHeightInPitches(symbol), top: acc.verticalPos+glyphs.symbolHeightInPitches(symbol)+fudge, bottom: acc.verticalPos+fudge }));
|
|
45
28
|
dx += glyphs.getSymbolWidth(symbol) + 2;
|
|
46
29
|
}, this);
|
|
47
30
|
return abselem;
|
|
48
31
|
};
|
|
49
|
-
})();
|
|
50
32
|
|
|
51
33
|
module.exports = createKeySignature;
|