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.
Files changed (197) hide show
  1. package/.github/workflows/tests.yml +29 -0
  2. package/CODE_OF_CONDUCT.md +76 -0
  3. package/CONTRIBUTING.md +1 -0
  4. package/LICENSE.md +1 -1
  5. package/README.md +88 -7
  6. package/RELEASE.md +961 -1
  7. package/abcjs-audio.css +14 -5
  8. package/dist/.gitignore +1 -2
  9. package/dist/abcjs-basic-min.js +3 -0
  10. package/dist/abcjs-basic-min.js.LICENSE +23 -0
  11. package/dist/abcjs-basic.js +28232 -0
  12. package/dist/abcjs-basic.js.map +1 -0
  13. package/dist/abcjs-plugin-min.js +3 -0
  14. package/dist/abcjs-plugin-min.js.LICENSE +23 -0
  15. package/index.js +27 -2
  16. package/{static-wrappers/license.js → license.js} +1 -1
  17. package/package.json +26 -29
  18. package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
  19. package/src/api/abc_animation.js +1 -17
  20. package/src/api/abc_tablatures.js +144 -0
  21. package/src/api/abc_timing_callbacks.js +216 -117
  22. package/src/api/abc_tunebook.js +18 -67
  23. package/src/api/abc_tunebook_svg.js +40 -48
  24. package/src/data/abc_tune.js +232 -972
  25. package/src/data/deline-tune.js +199 -0
  26. package/src/edit/abc_editarea.js +112 -0
  27. package/src/edit/abc_editor.js +95 -221
  28. package/src/midi/abc_midi_create.js +48 -50
  29. package/src/parse/abc_common.js +0 -14
  30. package/src/parse/abc_parse.js +167 -1321
  31. package/src/parse/abc_parse_book.js +62 -0
  32. package/src/parse/abc_parse_directive.js +164 -41
  33. package/src/parse/abc_parse_header.js +116 -145
  34. package/src/parse/abc_parse_key_voice.js +26 -20
  35. package/src/parse/abc_parse_music.js +1337 -0
  36. package/src/parse/abc_tokenizer.js +21 -15
  37. package/src/parse/abc_transpose.js +3 -15
  38. package/src/parse/tune-builder.js +896 -0
  39. package/src/parse/wrap_lines.js +205 -453
  40. package/src/synth/abc_midi_flattener.js +1292 -0
  41. package/src/{midi → synth}/abc_midi_renderer.js +44 -17
  42. package/src/synth/abc_midi_sequencer.js +648 -0
  43. package/src/synth/active-audio-context.js +3 -14
  44. package/src/synth/cents-to-factor.js +10 -0
  45. package/src/synth/create-note-map.js +21 -32
  46. package/src/synth/create-synth-control.js +20 -103
  47. package/src/synth/create-synth.js +185 -77
  48. package/src/synth/download-buffer.js +7 -21
  49. package/src/synth/get-midi-file.js +13 -20
  50. package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
  51. package/src/synth/images/loop.svg.js +65 -0
  52. package/src/synth/images/pause.svg.js +10 -0
  53. package/src/synth/images/play.svg.js +9 -0
  54. package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
  55. package/src/synth/instrument-index-to-name.js +1 -16
  56. package/src/synth/load-note.js +37 -76
  57. package/src/synth/pitch-to-note-name.js +0 -15
  58. package/src/synth/pitches-to-perc.js +64 -0
  59. package/src/synth/place-note.js +78 -68
  60. package/src/synth/play-event.js +17 -18
  61. package/src/synth/register-audio-context.js +11 -23
  62. package/src/synth/sounds-cache.js +0 -15
  63. package/src/synth/supports-audio.js +9 -23
  64. package/src/synth/synth-controller.js +80 -49
  65. package/src/synth/synth-sequence.js +20 -34
  66. package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
  67. package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
  68. package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
  69. package/src/tablatures/instruments/string-patterns.js +277 -0
  70. package/src/tablatures/instruments/string-tablature.js +56 -0
  71. package/src/tablatures/instruments/tab-note.js +282 -0
  72. package/src/tablatures/instruments/tab-notes.js +41 -0
  73. package/src/tablatures/instruments/violin/tab-violin.js +47 -0
  74. package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
  75. package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
  76. package/src/tablatures/tab-absolute-elements.js +310 -0
  77. package/src/tablatures/tab-common.js +29 -0
  78. package/src/tablatures/tab-renderer.js +243 -0
  79. package/src/tablatures/transposer.js +110 -0
  80. package/src/test/abc_midi_lint.js +5 -22
  81. package/src/test/abc_midi_sequencer_lint.js +11 -14
  82. package/src/test/abc_parser_lint.js +136 -32
  83. package/src/test/abc_vertical_lint.js +94 -32
  84. package/src/test/rendering-lint.js +38 -5
  85. package/src/write/abc_absolute_element.js +112 -120
  86. package/src/write/abc_abstract_engraver.js +102 -253
  87. package/src/write/abc_beam_element.js +30 -290
  88. package/src/write/abc_brace_element.js +12 -121
  89. package/src/write/abc_create_clef.js +21 -32
  90. package/src/write/abc_create_key_signature.js +8 -26
  91. package/src/write/abc_create_note_head.js +107 -0
  92. package/src/write/abc_create_time_signature.js +2 -21
  93. package/src/write/abc_crescendo_element.js +3 -50
  94. package/src/write/abc_decoration.js +7 -30
  95. package/src/write/abc_dynamic_decoration.js +3 -37
  96. package/src/write/abc_ending_element.js +1 -57
  97. package/src/write/abc_engraver_controller.js +111 -234
  98. package/src/write/abc_glyphs.js +8 -18
  99. package/src/write/abc_relative_element.js +57 -97
  100. package/src/write/abc_renderer.js +10 -832
  101. package/src/write/abc_spacing.js +0 -15
  102. package/src/write/abc_staff_group_element.js +14 -349
  103. package/src/write/abc_tempo_element.js +9 -117
  104. package/src/write/abc_tie_element.js +5 -68
  105. package/src/write/abc_triplet_element.js +6 -124
  106. package/src/write/abc_voice_element.js +7 -222
  107. package/src/write/add-chord.js +103 -0
  108. package/src/write/add-text-if.js +33 -0
  109. package/src/write/bottom-text.js +79 -0
  110. package/src/write/calcHeight.js +17 -0
  111. package/src/write/classes.js +100 -0
  112. package/src/write/draw/absolute.js +68 -0
  113. package/src/write/draw/beam.js +56 -0
  114. package/src/write/draw/brace.js +106 -0
  115. package/src/write/draw/crescendo.js +38 -0
  116. package/src/write/draw/debug-box.js +8 -0
  117. package/src/write/draw/draw.js +56 -0
  118. package/src/write/draw/dynamics.js +20 -0
  119. package/src/write/draw/ending.js +46 -0
  120. package/src/write/draw/group-elements.js +66 -0
  121. package/src/write/draw/horizontal-line.js +25 -0
  122. package/src/write/draw/non-music.js +50 -0
  123. package/src/write/draw/print-line.js +24 -0
  124. package/src/write/draw/print-path.js +7 -0
  125. package/src/write/draw/print-stem.js +30 -0
  126. package/src/write/draw/print-symbol.js +59 -0
  127. package/src/write/draw/print-vertical-line.js +18 -0
  128. package/src/write/draw/relative.js +77 -0
  129. package/src/write/draw/round-number.js +5 -0
  130. package/src/write/draw/selectables.js +59 -0
  131. package/src/write/draw/separator.js +16 -0
  132. package/src/write/draw/set-paper-size.js +45 -0
  133. package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
  134. package/src/write/draw/staff-group.js +226 -0
  135. package/src/write/draw/staff-line.js +9 -0
  136. package/src/write/draw/staff.js +33 -0
  137. package/src/write/draw/tab-line.js +40 -0
  138. package/src/write/draw/tempo.js +45 -0
  139. package/src/write/draw/text.js +71 -0
  140. package/src/write/draw/tie.js +97 -0
  141. package/src/write/draw/triplet.js +46 -0
  142. package/src/write/draw/voice.js +102 -0
  143. package/src/write/format-jazz-chord.js +15 -0
  144. package/src/write/free-text.js +41 -0
  145. package/src/write/get-font-and-attr.js +37 -0
  146. package/src/write/get-text-size.js +56 -0
  147. package/src/write/highlight.js +11 -0
  148. package/src/write/layout/VoiceElements.js +121 -0
  149. package/src/write/layout/beam.js +213 -0
  150. package/src/write/layout/get-left-edge-of-staff.js +56 -0
  151. package/src/write/layout/getBarYAt.js +6 -0
  152. package/src/write/layout/layout.js +94 -0
  153. package/src/write/layout/setUpperAndLowerElements.js +232 -0
  154. package/src/write/layout/staffGroup.js +146 -0
  155. package/src/write/layout/triplet.js +75 -0
  156. package/src/write/layout/voice.js +137 -0
  157. package/src/write/selection.js +188 -70
  158. package/src/write/separator.js +10 -0
  159. package/src/write/set-class.js +21 -0
  160. package/src/write/subtitle.js +12 -0
  161. package/src/write/svg.js +95 -43
  162. package/src/write/top-text.js +54 -0
  163. package/src/write/unhighlight.js +11 -0
  164. package/test.js +27 -64
  165. package/types/index.d.ts +1095 -0
  166. package/version.js +1 -1
  167. package/.babelrc +0 -5
  168. package/.eslintrc +0 -3
  169. package/.gitmodules +0 -3
  170. package/Dockerfile +0 -8
  171. package/abcjs-midi.css +0 -166
  172. package/build-utils/loadPresets.js +0 -14
  173. package/build-utils/presets/webpack.analyze.js +0 -6
  174. package/build-utils/presets/webpack.optimize.js +0 -30
  175. package/build-utils/webpack.development.js +0 -14
  176. package/build-utils/webpack.production.js +0 -35
  177. package/deploy-docs.sh +0 -25
  178. package/docker-compose.yml +0 -13
  179. package/docs/README.md +0 -33
  180. package/fix-versions.sh +0 -23
  181. package/midi.js +0 -62
  182. package/src/api/abc_tunebook_midi.js +0 -116
  183. package/src/midi/abc_midi_controls.js +0 -701
  184. package/src/midi/abc_midi_flattener.js +0 -1119
  185. package/src/midi/abc_midi_js_preparer.js +0 -243
  186. package/src/midi/abc_midi_sequencer.js +0 -401
  187. package/src/midi/abc_midi_ui_generator.js +0 -86
  188. package/src/plugin/abc_plugin_midi.js +0 -220
  189. package/src/synth/images/loop.svg +0 -61
  190. package/src/synth/images/pause.svg +0 -6
  191. package/src/synth/images/play.svg +0 -5
  192. package/src/transform/abc2abc_write.js +0 -395
  193. package/static-wrappers/basic.js +0 -2
  194. package/static-wrappers/midi.js +0 -2
  195. package/static-wrappers/plugin-midi.js +0 -6
  196. package/static-wrappers/plugin.js +0 -6
  197. 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
- var BeamElem;
45
-
46
- (function() {
47
- "use strict";
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
- var middleLine = 6; // hardcoded 6 is B
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
- // private functions
183
- //
184
- function minStem(element, stemsUp, referencePitch, minStemHeight) {
185
- if (!element.children)
186
- return minStemHeight;
187
- for (var i = 0; i < element.children.length; i++) {
188
- var elem = element.children[i];
189
- if (stemsUp && elem.top !== undefined && elem.c === "flags.ugrace")
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
- return [ startY, endY];
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
- function createAdditionalBeams(elems, asc, beam, isGrace, dy) {
304
- var beams = [];
305
- var auxBeams = []; // auxbeam will be {x, y, durlog, single} auxbeam[0] should match with durlog=-4 (16th) (j=-4-durlog)
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 sprintf = require('./sprintf');
18
- var spacing = require('./abc_spacing');
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(staff) {
26
- this.endStaff = staff;
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(staff) {
17
+ BraceElem.prototype.continuing = function(voice) {
30
18
  // If the final staff isn't present, then use the last one we saw.
31
- this.lastContinuedStaff = staff;
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.startStaff && this.startStaff.voices.length > 0 && this.startStaff.voices[0] === voice)
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.addChild(new RelativeElement("clef="+elem.type, 0, 0, undefined, {type:"debug"}));
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
- abselem.addRight(new RelativeElement(clef, dx, glyphs.getSymbolWidth(clef), elem.clefPos));
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;