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.
Files changed (204) 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 +92 -3
  6. package/RELEASE.md +957 -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 +28231 -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/dist/report-basic.html +37 -0
  16. package/dist/report-before-glyph-compress.html +37 -0
  17. package/dist/report-brown-ts-target-es5.html +37 -0
  18. package/dist/report-dev-orig-no-babel.html +37 -0
  19. package/dist/report-synth.html +37 -0
  20. package/docker-build.sh +1 -0
  21. package/glyphs.json +1 -0
  22. package/index.js +27 -2
  23. package/{static-wrappers/license.js → license.js} +1 -1
  24. package/package.json +26 -29
  25. package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
  26. package/src/api/abc_animation.js +1 -17
  27. package/src/api/abc_tablatures.js +144 -0
  28. package/src/api/abc_timing_callbacks.js +234 -116
  29. package/src/api/abc_tunebook.js +18 -67
  30. package/src/api/abc_tunebook_svg.js +38 -46
  31. package/src/data/abc_tune.js +232 -972
  32. package/src/data/deline-tune.js +199 -0
  33. package/src/edit/abc_editarea.js +112 -0
  34. package/src/edit/abc_editor.js +95 -221
  35. package/src/midi/abc_midi_create.js +48 -50
  36. package/src/parse/abc_common.js +0 -14
  37. package/src/parse/abc_parse.js +167 -1321
  38. package/src/parse/abc_parse_book.js +62 -0
  39. package/src/parse/abc_parse_directive.js +164 -41
  40. package/src/parse/abc_parse_header.js +116 -145
  41. package/src/parse/abc_parse_key_voice.js +26 -20
  42. package/src/parse/abc_parse_music.js +1337 -0
  43. package/src/parse/abc_tokenizer.js +21 -15
  44. package/src/parse/abc_transpose.js +3 -15
  45. package/src/parse/tune-builder.js +896 -0
  46. package/src/parse/wrap_lines.js +205 -453
  47. package/src/synth/abc_midi_flattener.js +1292 -0
  48. package/src/{midi → synth}/abc_midi_renderer.js +44 -17
  49. package/src/synth/abc_midi_sequencer.js +648 -0
  50. package/src/synth/active-audio-context.js +3 -14
  51. package/src/synth/cents-to-factor.js +10 -0
  52. package/src/synth/create-note-map.js +21 -32
  53. package/src/synth/create-synth-control.js +20 -103
  54. package/src/synth/create-synth.js +185 -77
  55. package/src/synth/download-buffer.js +7 -21
  56. package/src/synth/get-midi-file.js +13 -20
  57. package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
  58. package/src/synth/images/loop.svg.js +65 -0
  59. package/src/synth/images/pause.svg.js +10 -0
  60. package/src/synth/images/play.svg.js +9 -0
  61. package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
  62. package/src/synth/instrument-index-to-name.js +1 -16
  63. package/src/synth/load-note.js +37 -76
  64. package/src/synth/pitch-to-note-name.js +0 -15
  65. package/src/synth/pitches-to-perc.js +64 -0
  66. package/src/synth/place-note.js +78 -68
  67. package/src/synth/play-event.js +17 -18
  68. package/src/synth/register-audio-context.js +11 -23
  69. package/src/synth/sounds-cache.js +0 -15
  70. package/src/synth/supports-audio.js +9 -23
  71. package/src/synth/synth-controller.js +80 -49
  72. package/src/synth/synth-sequence.js +20 -34
  73. package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
  74. package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
  75. package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
  76. package/src/tablatures/instruments/string-patterns.js +277 -0
  77. package/src/tablatures/instruments/string-tablature.js +56 -0
  78. package/src/tablatures/instruments/tab-note.js +282 -0
  79. package/src/tablatures/instruments/tab-notes.js +41 -0
  80. package/src/tablatures/instruments/violin/tab-violin.js +47 -0
  81. package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
  82. package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
  83. package/src/tablatures/tab-absolute-elements.js +310 -0
  84. package/src/tablatures/tab-common.js +29 -0
  85. package/src/tablatures/tab-renderer.js +243 -0
  86. package/src/tablatures/transposer.js +110 -0
  87. package/src/test/abc_midi_lint.js +5 -22
  88. package/src/test/abc_midi_sequencer_lint.js +11 -14
  89. package/src/test/abc_parser_lint.js +136 -32
  90. package/src/test/abc_vertical_lint.js +94 -32
  91. package/src/test/rendering-lint.js +38 -5
  92. package/src/write/abc_absolute_element.js +112 -120
  93. package/src/write/abc_abstract_engraver.js +102 -253
  94. package/src/write/abc_beam_element.js +30 -290
  95. package/src/write/abc_brace_element.js +12 -121
  96. package/src/write/abc_create_clef.js +21 -32
  97. package/src/write/abc_create_key_signature.js +8 -26
  98. package/src/write/abc_create_note_head.js +107 -0
  99. package/src/write/abc_create_time_signature.js +2 -21
  100. package/src/write/abc_crescendo_element.js +3 -50
  101. package/src/write/abc_decoration.js +7 -30
  102. package/src/write/abc_dynamic_decoration.js +3 -37
  103. package/src/write/abc_ending_element.js +1 -57
  104. package/src/write/abc_engraver_controller.js +111 -234
  105. package/src/write/abc_glyphs.js +9 -19
  106. package/src/write/abc_relative_element.js +57 -97
  107. package/src/write/abc_renderer.js +10 -832
  108. package/src/write/abc_spacing.js +0 -15
  109. package/src/write/abc_staff_group_element.js +14 -349
  110. package/src/write/abc_tempo_element.js +9 -117
  111. package/src/write/abc_tie_element.js +5 -68
  112. package/src/write/abc_triplet_element.js +6 -124
  113. package/src/write/abc_voice_element.js +7 -222
  114. package/src/write/add-chord.js +103 -0
  115. package/src/write/add-text-if.js +33 -0
  116. package/src/write/bottom-text.js +79 -0
  117. package/src/write/calcHeight.js +17 -0
  118. package/src/write/classes.js +100 -0
  119. package/src/write/draw/absolute.js +68 -0
  120. package/src/write/draw/beam.js +56 -0
  121. package/src/write/draw/brace.js +106 -0
  122. package/src/write/draw/crescendo.js +38 -0
  123. package/src/write/draw/debug-box.js +8 -0
  124. package/src/write/draw/draw.js +56 -0
  125. package/src/write/draw/dynamics.js +20 -0
  126. package/src/write/draw/ending.js +46 -0
  127. package/src/write/draw/group-elements.js +66 -0
  128. package/src/write/draw/horizontal-line.js +25 -0
  129. package/src/write/draw/non-music.js +50 -0
  130. package/src/write/draw/print-line.js +24 -0
  131. package/src/write/draw/print-path.js +7 -0
  132. package/src/write/draw/print-stem.js +30 -0
  133. package/src/write/draw/print-symbol.js +59 -0
  134. package/src/write/draw/print-vertical-line.js +18 -0
  135. package/src/write/draw/relative.js +77 -0
  136. package/src/write/draw/round-number.js +5 -0
  137. package/src/write/draw/selectables.js +59 -0
  138. package/src/write/draw/separator.js +16 -0
  139. package/src/write/draw/set-paper-size.js +45 -0
  140. package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
  141. package/src/write/draw/staff-group.js +226 -0
  142. package/src/write/draw/staff-line.js +9 -0
  143. package/src/write/draw/staff.js +33 -0
  144. package/src/write/draw/tab-line.js +40 -0
  145. package/src/write/draw/tempo.js +45 -0
  146. package/src/write/draw/text.js +71 -0
  147. package/src/write/draw/tie.js +97 -0
  148. package/src/write/draw/triplet.js +46 -0
  149. package/src/write/draw/voice.js +102 -0
  150. package/src/write/format-jazz-chord.js +15 -0
  151. package/src/write/free-text.js +41 -0
  152. package/src/write/get-font-and-attr.js +37 -0
  153. package/src/write/get-text-size.js +56 -0
  154. package/src/write/highlight.js +11 -0
  155. package/src/write/layout/VoiceElements.js +121 -0
  156. package/src/write/layout/beam.js +213 -0
  157. package/src/write/layout/get-left-edge-of-staff.js +56 -0
  158. package/src/write/layout/getBarYAt.js +6 -0
  159. package/src/write/layout/layout.js +94 -0
  160. package/src/write/layout/setUpperAndLowerElements.js +232 -0
  161. package/src/write/layout/staffGroup.js +146 -0
  162. package/src/write/layout/triplet.js +75 -0
  163. package/src/write/layout/voice.js +137 -0
  164. package/src/write/selection.js +188 -70
  165. package/src/write/separator.js +10 -0
  166. package/src/write/set-class.js +21 -0
  167. package/src/write/subtitle.js +12 -0
  168. package/src/write/svg.js +95 -43
  169. package/src/write/top-text.js +54 -0
  170. package/src/write/unhighlight.js +11 -0
  171. package/temp.txt +17 -0
  172. package/test.js +27 -64
  173. package/types/index.d.ts +1095 -0
  174. package/version.js +1 -1
  175. package/.babelrc +0 -5
  176. package/.eslintrc +0 -3
  177. package/.gitmodules +0 -3
  178. package/abcjs-midi.css +0 -166
  179. package/build-utils/loadPresets.js +0 -14
  180. package/build-utils/presets/webpack.analyze.js +0 -6
  181. package/build-utils/presets/webpack.optimize.js +0 -30
  182. package/build-utils/webpack.development.js +0 -14
  183. package/build-utils/webpack.production.js +0 -35
  184. package/deploy-docs.sh +0 -25
  185. package/docs/README.md +0 -33
  186. package/fix-versions.sh +0 -23
  187. package/mei.js +0 -43
  188. package/midi.js +0 -62
  189. package/src/api/abc_tunebook_midi.js +0 -116
  190. package/src/midi/abc_midi_controls.js +0 -701
  191. package/src/midi/abc_midi_flattener.js +0 -1119
  192. package/src/midi/abc_midi_js_preparer.js +0 -243
  193. package/src/midi/abc_midi_sequencer.js +0 -401
  194. package/src/midi/abc_midi_ui_generator.js +0 -86
  195. package/src/plugin/abc_plugin_midi.js +0 -220
  196. package/src/synth/images/loop.svg +0 -61
  197. package/src/synth/images/pause.svg +0 -6
  198. package/src/synth/images/play.svg +0 -5
  199. package/src/transform/abc2abc_write.js +0 -395
  200. package/static-wrappers/basic.js +0 -2
  201. package/static-wrappers/midi.js +0 -2
  202. package/static-wrappers/plugin-midi.js +0 -6
  203. package/static-wrappers/plugin.js +0 -6
  204. package/webpack.config.js +0 -29
@@ -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
- (function() {
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
- this.tempoHeightAbove = totalHeightInPitches;
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
- note,
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 = 7 * temposcale;
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.addExtra(stem);
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;