abcjs 6.0.0-beta.7 → 6.0.0
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 +92 -3
- package/RELEASE.md +957 -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 +28231 -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/dist/report-basic.html +37 -0
- package/dist/report-before-glyph-compress.html +37 -0
- package/dist/report-brown-ts-target-es5.html +37 -0
- package/dist/report-dev-orig-no-babel.html +37 -0
- package/dist/report-synth.html +37 -0
- package/docker-build.sh +1 -0
- package/glyphs.json +1 -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 +234 -116
- package/src/api/abc_tunebook.js +18 -67
- package/src/api/abc_tunebook_svg.js +38 -46
- 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 +9 -19
- 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/temp.txt +17 -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/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/docs/README.md +0 -33
- package/fix-versions.sh +0 -23
- package/mei.js +0 -43
- 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
package/src/write/abc_spacing.js
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
// Copyright (C) 2014-2020 Gregory Dyke (gregdyke at gmail dot com)
|
|
2
|
-
//
|
|
3
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
4
|
-
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
5
|
-
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
6
|
-
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
|
-
//
|
|
8
|
-
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
|
-
//
|
|
10
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
11
|
-
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
12
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
13
|
-
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
14
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
15
|
-
|
|
16
1
|
var spacing = {};
|
|
17
2
|
|
|
18
3
|
spacing.FONTEM = 360;
|
|
@@ -1,22 +1,4 @@
|
|
|
1
1
|
// abc_staff_group_element.js: Definition of the StaffGroupElement 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
|
-
/*globals console */
|
|
18
|
-
|
|
19
|
-
var spacing = require('./abc_spacing');
|
|
20
2
|
|
|
21
3
|
// StaffGroupElement contains all the elements that go together to make one line of music.
|
|
22
4
|
// That might be multiple staves that are tied together, and it might be multiple voices on one staff.
|
|
@@ -44,8 +26,10 @@ var spacing = require('./abc_spacing');
|
|
|
44
26
|
// TODO-PER: Where is that used? It looks like it might not be needed.
|
|
45
27
|
// height: Set in the draw() method to the height actually used. Used by the calling function to know where to start the next staff group.
|
|
46
28
|
// TODO-PER: This should actually be set in the layout method and passed back as a return value.
|
|
29
|
+
var calcHeight = require('./calcHeight');
|
|
47
30
|
|
|
48
|
-
var StaffGroupElement = function() {
|
|
31
|
+
var StaffGroupElement = function(getTextSize) {
|
|
32
|
+
this.getTextSize = getTextSize;
|
|
49
33
|
this.voices = [];
|
|
50
34
|
this.staffs = [];
|
|
51
35
|
this.brace = undefined; //tony
|
|
@@ -91,6 +75,17 @@ StaffGroupElement.prototype.addVoice = function (voice, staffnumber, stafflines)
|
|
|
91
75
|
voice.staff = this.staffs[staffnumber];
|
|
92
76
|
};
|
|
93
77
|
|
|
78
|
+
StaffGroupElement.prototype.setHeight = function () {
|
|
79
|
+
this.height = calcHeight(this);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
StaffGroupElement.prototype.setWidth = function (width) {
|
|
83
|
+
this.w = width;
|
|
84
|
+
for (var i=0;i<this.voices.length;i++) {
|
|
85
|
+
this.voices[i].setWidth(width);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
94
89
|
StaffGroupElement.prototype.setStaffLimits = function (voice) {
|
|
95
90
|
voice.staff.top = Math.max(voice.staff.top, voice.top);
|
|
96
91
|
voice.staff.bottom = Math.min(voice.staff.bottom, voice.bottom);
|
|
@@ -107,334 +102,4 @@ StaffGroupElement.prototype.setStaffLimits = function (voice) {
|
|
|
107
102
|
this.setLimit('dynamicHeightBelow', voice);
|
|
108
103
|
};
|
|
109
104
|
|
|
110
|
-
StaffGroupElement.prototype.setUpperAndLowerElements = function(renderer) {
|
|
111
|
-
// Each staff already has the top and bottom set, now we see if there are elements that are always on top and bottom, and resolve their pitch.
|
|
112
|
-
// Also, get the overall height of all the staves in this group.
|
|
113
|
-
var lastStaffBottom;
|
|
114
|
-
for (var i = 0; i < this.staffs.length; i++) {
|
|
115
|
-
var staff = this.staffs[i];
|
|
116
|
-
// the vertical order of elements that are above is: tempo, part, volume/dynamic, ending/chord, lyric
|
|
117
|
-
// the vertical order of elements that are below is: lyric, chord, volume/dynamic
|
|
118
|
-
var positionY = {
|
|
119
|
-
tempoHeightAbove: 0,
|
|
120
|
-
partHeightAbove: 0,
|
|
121
|
-
volumeHeightAbove: 0,
|
|
122
|
-
dynamicHeightAbove: 0,
|
|
123
|
-
endingHeightAbove: 0,
|
|
124
|
-
chordHeightAbove: 0,
|
|
125
|
-
lyricHeightAbove: 0,
|
|
126
|
-
|
|
127
|
-
lyricHeightBelow: 0,
|
|
128
|
-
chordHeightBelow: 0,
|
|
129
|
-
volumeHeightBelow: 0,
|
|
130
|
-
dynamicHeightBelow: 0
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
if (/*ABCJS.write.debugPlacement*/false) {
|
|
134
|
-
staff.originalTop = staff.top; // This is just being stored for debugging purposes.
|
|
135
|
-
staff.originalBottom = staff.bottom; // This is just being stored for debugging purposes.
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (staff.specialY.lyricHeightAbove) { staff.top += staff.specialY.lyricHeightAbove; positionY.lyricHeightAbove = staff.top; }
|
|
139
|
-
if (staff.specialY.chordHeightAbove) { staff.top += staff.specialY.chordHeightAbove; positionY.chordHeightAbove = staff.top; }
|
|
140
|
-
if (staff.specialY.endingHeightAbove) {
|
|
141
|
-
if (staff.specialY.chordHeightAbove)
|
|
142
|
-
staff.top += 2;
|
|
143
|
-
else
|
|
144
|
-
staff.top += staff.specialY.endingHeightAbove;
|
|
145
|
-
positionY.endingHeightAbove = staff.top;
|
|
146
|
-
}
|
|
147
|
-
if (staff.specialY.dynamicHeightAbove && staff.specialY.volumeHeightAbove) {
|
|
148
|
-
staff.top += Math.max(staff.specialY.dynamicHeightAbove, staff.specialY.volumeHeightAbove);
|
|
149
|
-
positionY.dynamicHeightAbove = staff.top;
|
|
150
|
-
positionY.volumeHeightAbove = staff.top;
|
|
151
|
-
} else if (staff.specialY.dynamicHeightAbove) {
|
|
152
|
-
staff.top += staff.specialY.dynamicHeightAbove; positionY.dynamicHeightAbove = staff.top;
|
|
153
|
-
} else if (staff.specialY.volumeHeightAbove) { staff.top += staff.specialY.volumeHeightAbove; positionY.volumeHeightAbove = staff.top; }
|
|
154
|
-
if (staff.specialY.partHeightAbove) { staff.top += staff.specialY.partHeightAbove; positionY.partHeightAbove = staff.top; }
|
|
155
|
-
if (staff.specialY.tempoHeightAbove) { staff.top += staff.specialY.tempoHeightAbove; positionY.tempoHeightAbove = staff.top; }
|
|
156
|
-
|
|
157
|
-
if (staff.specialY.lyricHeightBelow) { positionY.lyricHeightBelow = staff.bottom; staff.bottom -= staff.specialY.lyricHeightBelow; }
|
|
158
|
-
if (staff.specialY.chordHeightBelow) { positionY.chordHeightBelow = staff.bottom; staff.bottom -= staff.specialY.chordHeightBelow; }
|
|
159
|
-
if (staff.specialY.volumeHeightBelow && staff.specialY.dynamicHeightBelow) {
|
|
160
|
-
positionY.volumeHeightBelow = staff.bottom;
|
|
161
|
-
positionY.dynamicHeightBelow = staff.bottom;
|
|
162
|
-
staff.bottom -= Math.max(staff.specialY.volumeHeightBelow, staff.specialY.dynamicHeightBelow);
|
|
163
|
-
} else if (staff.specialY.volumeHeightBelow) {
|
|
164
|
-
positionY.volumeHeightBelow = staff.bottom; staff.bottom -= staff.specialY.volumeHeightBelow;
|
|
165
|
-
} else if (staff.specialY.dynamicHeightBelow) {
|
|
166
|
-
positionY.dynamicHeightBelow = staff.bottom; staff.bottom -= staff.specialY.dynamicHeightBelow;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (/*ABCJS.write.debugPlacement*/false)
|
|
170
|
-
staff.positionY = positionY; // This is just being stored for debugging purposes.
|
|
171
|
-
|
|
172
|
-
for (var j = 0; j < staff.voices.length; j++) {
|
|
173
|
-
var voice = this.voices[staff.voices[j]];
|
|
174
|
-
voice.setUpperAndLowerElements(positionY);
|
|
175
|
-
}
|
|
176
|
-
// We might need a little space in between staves if the staves haven't been pushed far enough apart by notes or extra vertical stuff.
|
|
177
|
-
// Only try to put in extra space if this isn't the top staff.
|
|
178
|
-
if (lastStaffBottom !== undefined) {
|
|
179
|
-
var thisStaffTop = staff.top - 10;
|
|
180
|
-
var forcedSpacingBetween = lastStaffBottom + thisStaffTop;
|
|
181
|
-
var minSpacingInPitches = renderer.spacing.systemStaffSeparation/spacing.STEP;
|
|
182
|
-
var addedSpace = minSpacingInPitches - forcedSpacingBetween;
|
|
183
|
-
if (addedSpace > 0)
|
|
184
|
-
staff.top += addedSpace;
|
|
185
|
-
}
|
|
186
|
-
lastStaffBottom = 2 - staff.bottom; // the staff starts at position 2 and the bottom variable is negative. Therefore to find out how large the bottom is, we reverse the sign of the bottom, and add the 2 in.
|
|
187
|
-
|
|
188
|
-
// Now we need a little margin on the top, so we'll just throw that in.
|
|
189
|
-
//staff.top += 4;
|
|
190
|
-
//console.log("Staff Y: ",i,heightInPitches,staff.top,staff.bottom);
|
|
191
|
-
}
|
|
192
|
-
//console.log("Staff Height: ",heightInPitches,this.height);
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
StaffGroupElement.prototype.finished = function() {
|
|
196
|
-
for (var i=0;i<this.voices.length;i++) {
|
|
197
|
-
if (!this.voices[i].layoutEnded()) return false;
|
|
198
|
-
}
|
|
199
|
-
return true;
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
function getLeftEdgeOfStaff(renderer, voices, brace, bracket) {
|
|
203
|
-
var x = renderer.padding.left;
|
|
204
|
-
|
|
205
|
-
// find out how much space will be taken up by voice headers
|
|
206
|
-
var voiceheaderw = 0;
|
|
207
|
-
for (var i=0;i<voices.length;i++) {
|
|
208
|
-
if(voices[i].header) {
|
|
209
|
-
var size = renderer.getTextSize(voices[i].header, 'voicefont', '');
|
|
210
|
-
voiceheaderw = Math.max(voiceheaderw,size.width);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
if (voiceheaderw) {
|
|
214
|
-
// Give enough spacing to the right - we use the width of an A for the amount of spacing.
|
|
215
|
-
var sizeW = renderer.getTextSize("A", 'voicefont', '');
|
|
216
|
-
voiceheaderw += sizeW.width;
|
|
217
|
-
}
|
|
218
|
-
x += voiceheaderw;
|
|
219
|
-
|
|
220
|
-
var ofs = 0;
|
|
221
|
-
if (brace) {
|
|
222
|
-
brace.setLocation(x);
|
|
223
|
-
ofs = brace.getWidth();
|
|
224
|
-
}
|
|
225
|
-
if (bracket) {
|
|
226
|
-
bracket.setLocation(x);
|
|
227
|
-
ofs = Math.max(ofs, bracket.getWidth());
|
|
228
|
-
}
|
|
229
|
-
return x + ofs;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
StaffGroupElement.prototype.layout = function(spacing, renderer, debug) {
|
|
233
|
-
var epsilon = 0.0000001; // Fudging for inexactness of floating point math.
|
|
234
|
-
var spacingunits = 0; // number of times we will have ended up using the spacing distance (as opposed to fixed width distances)
|
|
235
|
-
var minspace = 1000; // a big number to start off with - used to find out what the smallest space between two notes is -- GD 2014.1.7
|
|
236
|
-
|
|
237
|
-
var x = getLeftEdgeOfStaff(renderer, this.voices, this.brace, this.bracket);
|
|
238
|
-
this.startx=x;
|
|
239
|
-
var i;
|
|
240
|
-
|
|
241
|
-
var currentduration = 0;
|
|
242
|
-
if (debug) console.log("init layout", spacing);
|
|
243
|
-
for (i=0;i<this.voices.length;i++) {
|
|
244
|
-
this.voices[i].beginLayout(x);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
var spacingunit = 0; // number of spacingunits coming from the previously laid out element to this one
|
|
248
|
-
while (!this.finished()) {
|
|
249
|
-
// find first duration level to be laid out among candidates across voices
|
|
250
|
-
currentduration= null; // candidate smallest duration level
|
|
251
|
-
for (i=0;i<this.voices.length;i++) {
|
|
252
|
-
if (!this.voices[i].layoutEnded() && (!currentduration || this.voices[i].getDurationIndex()<currentduration))
|
|
253
|
-
currentduration=this.voices[i].getDurationIndex();
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// isolate voices at current duration level
|
|
258
|
-
var currentvoices = [];
|
|
259
|
-
var othervoices = [];
|
|
260
|
-
for (i=0;i<this.voices.length;i++) {
|
|
261
|
-
var durationIndex = this.voices[i].getDurationIndex();
|
|
262
|
-
// PER: Because of the inexactness of JS floating point math, we just get close.
|
|
263
|
-
if (durationIndex - currentduration > epsilon) {
|
|
264
|
-
othervoices.push(this.voices[i]);
|
|
265
|
-
//console.log("out: voice ",i);
|
|
266
|
-
} else {
|
|
267
|
-
currentvoices.push(this.voices[i]);
|
|
268
|
-
//if (debug) console.log("in: voice ",i);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// among the current duration level find the one which needs starting furthest right
|
|
273
|
-
spacingunit = 0; // number of spacingunits coming from the previously laid out element to this one
|
|
274
|
-
var spacingduration = 0;
|
|
275
|
-
for (i=0;i<currentvoices.length;i++) {
|
|
276
|
-
//console.log("greatest spacing unit", x, currentvoices[i].getNextX(), currentvoices[i].getSpacingUnits(), currentvoices[i].spacingduration);
|
|
277
|
-
if (currentvoices[i].getNextX()>x) {
|
|
278
|
-
x=currentvoices[i].getNextX();
|
|
279
|
-
spacingunit=currentvoices[i].getSpacingUnits();
|
|
280
|
-
spacingduration = currentvoices[i].spacingduration;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
spacingunits+=spacingunit;
|
|
284
|
-
minspace = Math.min(minspace,spacingunit);
|
|
285
|
-
if (debug) console.log("currentduration: ",currentduration, spacingunits, minspace);
|
|
286
|
-
|
|
287
|
-
for (i=0;i<currentvoices.length;i++) {
|
|
288
|
-
var voicechildx = currentvoices[i].layoutOneItem(x,spacing);
|
|
289
|
-
var dx = voicechildx-x;
|
|
290
|
-
if (dx>0) {
|
|
291
|
-
x = voicechildx; //update x
|
|
292
|
-
for (var j=0;j<i;j++) { // shift over all previously laid out elements
|
|
293
|
-
currentvoices[j].shiftRight(dx);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// remove the value of already counted spacing units in other voices (e.g. if a voice had planned to use up 5 spacing units but is not in line to be laid out at this duration level - where we've used 2 spacing units - then we must use up 3 spacing units, not 5)
|
|
299
|
-
for (i=0;i<othervoices.length;i++) {
|
|
300
|
-
othervoices[i].spacingduration-=spacingduration;
|
|
301
|
-
othervoices[i].updateNextX(x,spacing); // adjust other voices expectations
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// update indexes of currently laid out elems
|
|
305
|
-
for (i=0;i<currentvoices.length;i++) {
|
|
306
|
-
var voice = currentvoices[i];
|
|
307
|
-
voice.updateIndices();
|
|
308
|
-
}
|
|
309
|
-
} // finished laying out
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// find the greatest remaining x as a base for the width
|
|
313
|
-
for (i=0;i<this.voices.length;i++) {
|
|
314
|
-
if (this.voices[i].getNextX()>x) {
|
|
315
|
-
x=this.voices[i].getNextX();
|
|
316
|
-
spacingunit=this.voices[i].getSpacingUnits();
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
//console.log("greatest remaining",spacingunit,x);
|
|
320
|
-
spacingunits+=spacingunit;
|
|
321
|
-
this.w = x;
|
|
322
|
-
|
|
323
|
-
for (i=0;i<this.voices.length;i++) {
|
|
324
|
-
this.voices[i].w=this.w;
|
|
325
|
-
}
|
|
326
|
-
return { spacingUnits: spacingunits, minSpace: minspace };
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
StaffGroupElement.prototype.calcHeight = function () {
|
|
330
|
-
// the height is calculated here in a parallel way to the drawing below in hopes that both of these functions will be modified together.
|
|
331
|
-
// TODO-PER: also add the space between staves. (That's systemStaffSeparation, which is the minimum distance between the staff LINES.)
|
|
332
|
-
var height = 0;
|
|
333
|
-
for (var i=0;i<this.voices.length;i++) {
|
|
334
|
-
var staff = this.voices[i].staff;
|
|
335
|
-
if (!this.voices[i].duplicate) {
|
|
336
|
-
height += staff.top;
|
|
337
|
-
if (staff.bottom < 0)
|
|
338
|
-
height += -staff.bottom;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
return height;
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
StaffGroupElement.prototype.draw = function (renderer) {
|
|
345
|
-
// We enter this method with renderer.y pointing to the topmost coordinate that we're allowed to draw.
|
|
346
|
-
// All of the children that will be drawn have a relative "pitch" set, where zero is the first ledger line below the staff.
|
|
347
|
-
// renderer.y will be offset at the beginning of each staff by the amount required to make the relative pitch work.
|
|
348
|
-
// If there are multiple staves, then renderer.y will be incremented for each new staff.
|
|
349
|
-
|
|
350
|
-
var debugPrint;
|
|
351
|
-
var colorIndex;
|
|
352
|
-
if (/*ABCJS.write.debugPlacement*/false) {
|
|
353
|
-
var colors = [ "rgb(207,27,36)", "rgb(168,214,80)", "rgb(110,161,224)", "rgb(191,119,218)", "rgb(195,30,151)",
|
|
354
|
-
"rgb(31,170,177)", "rgb(220,166,142)" ];
|
|
355
|
-
debugPrint = function(staff, key) {
|
|
356
|
-
if (staff.positionY[key]) {
|
|
357
|
-
//renderer.printHorizontalLine(50, renderer.calcY(staff.positionY[key]), key.substr(0, 4) + " " + Math.round(staff.positionY[key]));
|
|
358
|
-
var height = staff.specialY[key] * spacing.STEP;
|
|
359
|
-
renderer.printShadedBox(renderer.padding.left, renderer.calcY(staff.positionY[key]), renderer.controller.width, height,colors[colorIndex], 0.4, key.substr(0, 4));
|
|
360
|
-
colorIndex += 1; if (colorIndex > 6) colorIndex = 0;
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// An invisible marker is useful to be able to find where each system starts.
|
|
366
|
-
renderer.addInvisibleMarker("abcjs-top-of-system");
|
|
367
|
-
|
|
368
|
-
var startY = renderer.y; // So that it can be restored after we're done.
|
|
369
|
-
// Set the absolute Y position for each staff here, so the voice drawing below can just use if.
|
|
370
|
-
for (var j = 0; j < this.staffs.length; j++) {
|
|
371
|
-
var staff1 = this.staffs[j];
|
|
372
|
-
//renderer.printHorizontalLine(50, renderer.y, "start");
|
|
373
|
-
renderer.moveY(spacing.STEP, staff1.top);
|
|
374
|
-
staff1.absoluteY = renderer.y;
|
|
375
|
-
if (/*ABCJS.write.debugPlacement*/false) {
|
|
376
|
-
colorIndex = 0;
|
|
377
|
-
renderer.printShadedBox(renderer.padding.left, renderer.calcY(staff1.originalTop), renderer.controller.width, renderer.calcY(staff1.originalBottom)-renderer.calcY(staff1.originalTop), "#000000", 0.1);
|
|
378
|
-
debugPrint(staff1, 'chordHeightAbove');
|
|
379
|
-
debugPrint(staff1, 'chordHeightBelow');
|
|
380
|
-
debugPrint(staff1, 'dynamicHeightAbove');
|
|
381
|
-
debugPrint(staff1, 'dynamicHeightBelow');
|
|
382
|
-
debugPrint(staff1, 'endingHeightAbove');
|
|
383
|
-
debugPrint(staff1, 'lyricHeightAbove');
|
|
384
|
-
debugPrint(staff1, 'lyricHeightBelow');
|
|
385
|
-
debugPrint(staff1, 'partHeightAbove');
|
|
386
|
-
debugPrint(staff1, 'tempoHeightAbove');
|
|
387
|
-
debugPrint(staff1, 'volumeHeightAbove');
|
|
388
|
-
debugPrint(staff1, 'volumeHeightBelow');
|
|
389
|
-
}
|
|
390
|
-
if (staff1.bottom < 0)
|
|
391
|
-
renderer.moveY(spacing.STEP, -staff1.bottom);
|
|
392
|
-
}
|
|
393
|
-
var topLine; // these are to connect multiple staves. We need to remember where they are.
|
|
394
|
-
var bottomLine;
|
|
395
|
-
|
|
396
|
-
var bartop = 0;
|
|
397
|
-
renderer.measureNumber = null;
|
|
398
|
-
renderer.noteNumber = null;
|
|
399
|
-
for (var i=0;i<this.voices.length;i++) {
|
|
400
|
-
var staff = this.voices[i].staff;
|
|
401
|
-
renderer.y = staff.absoluteY;
|
|
402
|
-
renderer.voiceNumber = i;
|
|
403
|
-
//renderer.y = staff.y;
|
|
404
|
-
// offset for starting the counting at middle C
|
|
405
|
-
if (!this.voices[i].duplicate) {
|
|
406
|
-
// renderer.moveY(spacing.STEP, staff.top);
|
|
407
|
-
if (!topLine) topLine = renderer.calcY(10);
|
|
408
|
-
bottomLine = renderer.calcY(2);
|
|
409
|
-
if (staff.lines !== 0) {
|
|
410
|
-
renderer.measureNumber = null;
|
|
411
|
-
renderer.noteNumber = null;
|
|
412
|
-
renderer.printStave(this.startx, this.w, staff.lines);
|
|
413
|
-
}
|
|
414
|
-
if (this.brace && this.brace.isStartVoice(i)) {//Tony
|
|
415
|
-
this.brace.draw(renderer, topLine, bottomLine); //tony
|
|
416
|
-
}
|
|
417
|
-
if (this.bracket && this.bracket.isStartVoice(i)) {
|
|
418
|
-
this.bracket.draw(renderer, topLine, bottomLine);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
this.voices[i].draw(renderer, bartop);
|
|
422
|
-
renderer.measureNumber = null;
|
|
423
|
-
renderer.noteNumber = null;
|
|
424
|
-
if (!this.voices[i].duplicate) {
|
|
425
|
-
bartop = renderer.calcY(2); // This connects the bar lines between two different staves.
|
|
426
|
-
// if (staff.bottom < 0)
|
|
427
|
-
// renderer.moveY(spacing.STEP, -staff.bottom);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
renderer.measureNumber = null;
|
|
431
|
-
renderer.noteNumber = null;
|
|
432
|
-
|
|
433
|
-
// connect all the staves together with a vertical line
|
|
434
|
-
if (this.staffs.length>1) {
|
|
435
|
-
renderer.printStem(this.startx, 0.6, topLine, bottomLine);
|
|
436
|
-
}
|
|
437
|
-
renderer.y = startY;
|
|
438
|
-
};
|
|
439
|
-
|
|
440
105
|
module.exports = StaffGroupElement;
|
|
@@ -1,57 +1,22 @@
|
|
|
1
1
|
// abc_tempo_element.js: Definition of the TempoElement class.
|
|
2
|
-
// Copyright (C) 2014-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 RelativeElement = require('./abc_relative_element');
|
|
19
5
|
|
|
20
|
-
var TempoElement
|
|
21
|
-
|
|
22
|
-
"use strict";
|
|
23
|
-
var totalHeightInPitches = 5;
|
|
24
|
-
|
|
25
|
-
TempoElement = function TempoElement(tempo, tuneNumber, createNoteHead) {
|
|
6
|
+
var TempoElement = function TempoElement(tempo, tuneNumber, createNoteHead) {
|
|
7
|
+
this.type = "TempoElement";
|
|
26
8
|
this.tempo = tempo;
|
|
27
9
|
this.tempo.type = "tempo"; /// TODO-PER: this should be set earlier, in the parser, probably.
|
|
28
10
|
this.tuneNumber = tuneNumber;
|
|
29
|
-
|
|
11
|
+
// TODO: can these two properties be merged?
|
|
12
|
+
this.totalHeightInPitches = 6;
|
|
13
|
+
this.tempoHeightAbove = this.totalHeightInPitches;
|
|
30
14
|
this.pitch = undefined; // This will be set later
|
|
31
15
|
if (this.tempo.duration && !this.tempo.suppressBpm) {
|
|
32
16
|
this.note = this.createNote(createNoteHead, tempo, tuneNumber);
|
|
33
17
|
}
|
|
34
18
|
};
|
|
35
19
|
|
|
36
|
-
TempoElement.prototype.setUpperAndLowerElements = function(positionY) { // TODO-PER: This might not be called.
|
|
37
|
-
this.pitch = positionY.tempoHeightAbove;
|
|
38
|
-
this.top = positionY.tempoHeightAbove;
|
|
39
|
-
this.bottom = positionY.tempoHeightAbove;
|
|
40
|
-
if (this.note) {
|
|
41
|
-
var tempoPitch = this.pitch - totalHeightInPitches + 1; // The pitch we receive is the top of the allotted area: change that to practically the bottom.
|
|
42
|
-
this.note.top = tempoPitch;
|
|
43
|
-
this.note.bottom = tempoPitch;
|
|
44
|
-
for (var i = 0; i < this.note.children.length; i++) {
|
|
45
|
-
var child = this.note.children[i];
|
|
46
|
-
child.top += tempoPitch;
|
|
47
|
-
child.bottom += tempoPitch;
|
|
48
|
-
child.pitch += tempoPitch;
|
|
49
|
-
if (child.pitch2 !== undefined)
|
|
50
|
-
child.pitch2 += tempoPitch;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
20
|
TempoElement.prototype.setX = function (x) {
|
|
56
21
|
this.x = x;
|
|
57
22
|
};
|
|
@@ -79,93 +44,20 @@ var TempoElement;
|
|
|
79
44
|
else if (duration <= 2) { note = "noteheads.dbl"; dot = 0; }
|
|
80
45
|
else { note = "noteheads.dbl"; dot = 1; }
|
|
81
46
|
|
|
82
|
-
var ret = createNoteHead(absElem,
|
|
83
|
-
|
|
84
|
-
{ verticalPos: 0}, // This is just temporary: we'll offset the vertical positioning when we get the actual vertical spot.
|
|
85
|
-
"up",
|
|
86
|
-
0,
|
|
87
|
-
0,
|
|
88
|
-
flag,
|
|
89
|
-
dot,
|
|
90
|
-
0,
|
|
91
|
-
temposcale,
|
|
92
|
-
[],
|
|
93
|
-
false
|
|
94
|
-
);
|
|
47
|
+
var ret = createNoteHead(absElem, note, { verticalPos: 0}, // This is just temporary: we'll offset the vertical positioning when we get the actual vertical spot.
|
|
48
|
+
{ dir: "up", flag: flag, dot: dot, scale: temposcale});
|
|
95
49
|
var tempoNote = ret.notehead;
|
|
96
50
|
absElem.addHead(tempoNote);
|
|
97
51
|
var stem;
|
|
98
52
|
if (note !== "noteheads.whole" && note !== "noteheads.dbl") {
|
|
99
53
|
var p1 = 1 / 3 * temposcale;
|
|
100
|
-
var p2 =
|
|
54
|
+
var p2 = 5 * temposcale;
|
|
101
55
|
var dx = tempoNote.dx + tempoNote.w;
|
|
102
56
|
var width = -0.6;
|
|
103
57
|
stem = new RelativeElement(null, dx, 0, p1, {"type": "stem", "pitch2": p2, linewidth: width});
|
|
104
|
-
absElem.
|
|
58
|
+
absElem.addRight(stem);
|
|
105
59
|
}
|
|
106
60
|
return absElem;
|
|
107
61
|
};
|
|
108
62
|
|
|
109
|
-
TempoElement.prototype.draw = function(renderer) {
|
|
110
|
-
var x = this.x;
|
|
111
|
-
if (this.pitch === undefined)
|
|
112
|
-
window.console.error("Tempo Element y-coordinate not set.");
|
|
113
|
-
|
|
114
|
-
var self = this;
|
|
115
|
-
var tempoGroup;
|
|
116
|
-
renderer.wrapInAbsElem(this.tempo, "abcjs-tempo", function () {
|
|
117
|
-
renderer.createElemSet({klass: renderer.addClasses("tempo")});
|
|
118
|
-
var y = renderer.calcY(self.pitch);
|
|
119
|
-
var text;
|
|
120
|
-
if (self.tempo.preString) {
|
|
121
|
-
text = renderer.renderText({x:x, y: y, text: self.tempo.preString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true});
|
|
122
|
-
var size = renderer.getTextSize(self.tempo.preString, 'tempofont', 'tempo', text);
|
|
123
|
-
var preWidth = size.width;
|
|
124
|
-
var charWidth = preWidth / self.tempo.preString.length; // Just get some average number to increase the spacing.
|
|
125
|
-
x += preWidth + charWidth;
|
|
126
|
-
}
|
|
127
|
-
if (self.note) {
|
|
128
|
-
self.note.setX(x);
|
|
129
|
-
for (var i = 0; i < self.note.children.length; i++)
|
|
130
|
-
self.note.children[i].draw(renderer, x);
|
|
131
|
-
x += (self.note.w + 5);
|
|
132
|
-
var str = "= " + self.tempo.bpm;
|
|
133
|
-
text = renderer.renderText({x:x, y: y, text: str, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true});
|
|
134
|
-
size = renderer.getTextSize(str, 'tempofont', 'tempo', text);
|
|
135
|
-
var postWidth = size.width;
|
|
136
|
-
var charWidth2 = postWidth / str.length; // Just get some average number to increase the spacing.
|
|
137
|
-
x += postWidth + charWidth2;
|
|
138
|
-
}
|
|
139
|
-
if (self.tempo.postString) {
|
|
140
|
-
renderer.renderText({x:x, y: y, text: self.tempo.postString, type: 'tempofont', klass: 'abcjs-tempo', anchor: "start", noClass: true});
|
|
141
|
-
}
|
|
142
|
-
tempoGroup = renderer.closeElemSet();
|
|
143
|
-
});
|
|
144
|
-
return tempoGroup;
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
TempoElement.prototype.adjustElements = function(renderer) {
|
|
148
|
-
// TODO-PER: This straightens out the tempo elements because they are written in the wrong order.
|
|
149
|
-
for (var i = renderer.controller.history.length - 1; i >= 0; i--) {
|
|
150
|
-
if (renderer.controller.history[i].absEl.abcelem.type !== "tempo")
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
var group;
|
|
154
|
-
for (var ii = i+1; ii < renderer.controller.history.length; ii++) {
|
|
155
|
-
var hist = renderer.controller.history[ii];
|
|
156
|
-
var inGroup = hist.svgEl.parentNode.tagName.toLowerCase() === 'g';
|
|
157
|
-
if (inGroup)
|
|
158
|
-
group = hist.svgEl.parentNode;
|
|
159
|
-
else if (group) {
|
|
160
|
-
group.appendChild(hist.svgEl);
|
|
161
|
-
}
|
|
162
|
-
hist.svgEl.setAttribute("class", '');
|
|
163
|
-
}
|
|
164
|
-
var len = renderer.controller.history.length-i-1;
|
|
165
|
-
if (group && len > 1) {
|
|
166
|
-
renderer.controller.combineHistory(len, group);
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
})();
|
|
170
|
-
|
|
171
63
|
module.exports = TempoElement;
|
|
@@ -1,20 +1,7 @@
|
|
|
1
1
|
// abc_tie_element.js: Definition of the TieElement 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
3
|
var TieElem = function TieElem(options) {
|
|
4
|
+
this.type = "TieElem";
|
|
18
5
|
// console.log("constructor", options.anchor1 ? options.anchor1.pitch : "N/A", options.anchor2 ? options.anchor2.pitch : "N/A", options.isTie, options.isGrace);
|
|
19
6
|
this.anchor1 = options.anchor1; // must have a .x and a .pitch, and a .parent property or be null (means starts at the "beginning" of the line - after keysig)
|
|
20
7
|
this.anchor2 = options.anchor2; // must have a .x and a .pitch property or be null (means ends at the end of the line)
|
|
@@ -26,6 +13,8 @@ var TieElem = function TieElem(options) {
|
|
|
26
13
|
this.stemDir = options.stemDir;
|
|
27
14
|
if (options.voiceNumber !== undefined)
|
|
28
15
|
this.voiceNumber = options.voiceNumber;
|
|
16
|
+
if (options.style !== undefined)
|
|
17
|
+
this.dotted = true;
|
|
29
18
|
this.internalNotes = [];
|
|
30
19
|
};
|
|
31
20
|
|
|
@@ -51,10 +40,6 @@ TieElem.prototype.setHint = function () {
|
|
|
51
40
|
this.hint = true;
|
|
52
41
|
};
|
|
53
42
|
|
|
54
|
-
TieElem.prototype.setUpperAndLowerElements = function(positionY) {
|
|
55
|
-
// Doesn't depend on the highest and lowest, so there's nothing to do here.
|
|
56
|
-
};
|
|
57
|
-
|
|
58
43
|
TieElem.prototype.calcTieDirection = function () {
|
|
59
44
|
// The rules:
|
|
60
45
|
// 1) If it is in a grace note group, then the direction is always BELOW.
|
|
@@ -128,6 +113,8 @@ TieElem.prototype.calcX = function (lineStartX, lineEndX) {
|
|
|
128
113
|
this.startX = this.startLimitX.x+this.startLimitX.w; // if there is no start element, but there is a repeat mark before the start of the line.
|
|
129
114
|
else
|
|
130
115
|
this.startX = lineStartX; // There is no element and no repeat mark: extend to the beginning of the line.
|
|
116
|
+
if (!this.anchor1 && this.dotted)
|
|
117
|
+
this.startX -= 3; // The arc needs to be long enough to tell that it is dotted.
|
|
131
118
|
|
|
132
119
|
if (this.anchor2)
|
|
133
120
|
this.endX = this.anchor2.x; // The normal case where there is a starting element to attach to.
|
|
@@ -200,54 +187,4 @@ TieElem.prototype.avoidCollisionAbove = function () {
|
|
|
200
187
|
}
|
|
201
188
|
};
|
|
202
189
|
|
|
203
|
-
TieElem.prototype.layout = function (lineStartX, lineEndX) {
|
|
204
|
-
// We now have all of the input variables set, so we can figure out the start and ending x,y coordinates, and finalize the direction of the arc.
|
|
205
|
-
|
|
206
|
-
// Ties and slurs are handled a little differently, so do calculations for them separately.
|
|
207
|
-
if (!this.anchor1 || !this.anchor2)
|
|
208
|
-
this.isTie = true; // if the slur goes off the end of the line, then draw it like a tie
|
|
209
|
-
else if (this.anchor1.pitch === this.anchor2.pitch && this.internalNotes.length === 0)
|
|
210
|
-
this.isTie = true;
|
|
211
|
-
else
|
|
212
|
-
this.isTie = false;
|
|
213
|
-
|
|
214
|
-
// TODO-PER: Not sure why this would be needed, but it would be better to figure out a way to have the anchors be immutable here anyway.
|
|
215
|
-
// if (this.isTie) {
|
|
216
|
-
// if (this.anchor1) // this can happen if the tie comes from the previous line.
|
|
217
|
-
// this.anchor1.isTie = true;
|
|
218
|
-
// if (this.anchor2) // this can happen if the tie does not go to the next line.
|
|
219
|
-
// this.anchor2.isTie = true;
|
|
220
|
-
// }
|
|
221
|
-
|
|
222
|
-
if (this.isTie) {
|
|
223
|
-
this.calcTieDirection();
|
|
224
|
-
// TODO-PER: Not sure why this would be needed, but it would be better to figure out a way to have the anchors be immutable here anyway.
|
|
225
|
-
// if (this.anchor1) // this can happen if the tie comes from the previous line.
|
|
226
|
-
// this.anchor1.tieAbove = this.above;
|
|
227
|
-
// if (this.anchor2) // this can happen if the tie goes to the next line.
|
|
228
|
-
// this.anchor2.tieAbove = this.above;
|
|
229
|
-
this.calcX(lineStartX, lineEndX);
|
|
230
|
-
this.calcTieY();
|
|
231
|
-
|
|
232
|
-
} else {
|
|
233
|
-
this.calcSlurDirection();
|
|
234
|
-
this.calcX(lineStartX, lineEndX);
|
|
235
|
-
this.calcSlurY();
|
|
236
|
-
}
|
|
237
|
-
this.avoidCollisionAbove();
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
TieElem.prototype.draw = function (renderer, linestartx, lineendx) {
|
|
241
|
-
this.layout(linestartx, lineendx);
|
|
242
|
-
|
|
243
|
-
var klass;
|
|
244
|
-
if (this.hint)
|
|
245
|
-
klass = "abcjs-hint";
|
|
246
|
-
var fudgeY = this.fixedY ? 1.5 : 0; // TODO-PER: This just compensates for drawArc, which contains too much knowledge of ties and slurs.
|
|
247
|
-
renderer.controller.currentAbsEl = { tuneNumber: renderer.controller.engraver.tuneNumber, elemset: [], abcelem: { el_type: "slur", startChar: -1, endChar: -1 }};
|
|
248
|
-
var el = renderer.drawArc(this.startX, this.endX, this.startY+fudgeY, this.endY+fudgeY, this.above, klass, this.isTie);
|
|
249
|
-
renderer.controller.currentAbsEl.elemset.push(el);
|
|
250
|
-
|
|
251
|
-
};
|
|
252
|
-
|
|
253
190
|
module.exports = TieElem;
|