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,24 +1,11 @@
1
1
  // abc_abstract_engraver.js: Creates a data structure suitable for printing a line of abc
2
- // Copyright (C) 2010-2020 Gregory Dyke (gregdyke at gmail dot com)
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 BeamElem = require('./abc_beam_element');
19
5
  var BraceElem = require('./abc_brace_element');
20
6
  var createClef = require('./abc_create_clef');
21
7
  var createKeySignature = require('./abc_create_key_signature');
8
+ var createNoteHead = require('./abc_create_note_head');
22
9
  var createTimeSignature = require('./abc_create_time_signature');
23
10
  var Decoration = require('./abc_decoration');
24
11
  var EndingElem = require('./abc_ending_element');
@@ -30,14 +17,11 @@ var TempoElement = require('./abc_tempo_element');
30
17
  var TieElem = require('./abc_tie_element');
31
18
  var TripletElem = require('./abc_triplet_element');
32
19
  var VoiceElement = require('./abc_voice_element');
20
+ var addChord = require('./add-chord');
21
+ var pitchesToPerc = require('../synth/pitches-to-perc')
33
22
 
34
23
  var parseCommon = require('../parse/abc_common');
35
24
 
36
- var AbstractEngraver;
37
-
38
- (function() {
39
- "use strict";
40
-
41
25
  var getDuration = function(elem) {
42
26
  var d = 0;
43
27
  if (elem.duration) {
@@ -54,16 +38,21 @@ var hint = false;
54
38
  rhythm:{"-1": "noteheads.slash.whole", 0:"noteheads.slash.whole", 1:"noteheads.slash.whole", 2:"noteheads.slash.quarter", 3:"noteheads.slash.quarter", 4:"noteheads.slash.quarter", 5:"noteheads.slash.quarter", 6:"noteheads.slash.quarter", 7:"noteheads.slash.quarter", nostem: "noteheads.slash.nostem"},
55
39
  x:{"-1": "noteheads.indeterminate", 0:"noteheads.indeterminate", 1:"noteheads.indeterminate", 2:"noteheads.indeterminate", 3:"noteheads.indeterminate", 4:"noteheads.indeterminate", 5:"noteheads.indeterminate", 6:"noteheads.indeterminate", 7:"noteheads.indeterminate", nostem: "noteheads.indeterminate"},
56
40
  harmonic:{"-1": "noteheads.harmonic.quarter", 0:"noteheads.harmonic.quarter", 1:"noteheads.harmonic.quarter", 2:"noteheads.harmonic.quarter", 3:"noteheads.harmonic.quarter", 4:"noteheads.harmonic.quarter", 5:"noteheads.harmonic.quarter", 6:"noteheads.harmonic.quarter", 7:"noteheads.harmonic.quarter", nostem: "noteheads.harmonic.quarter"},
41
+ triangle:{"-1": "noteheads.triangle.quarter", 0:"noteheads.triangle.quarter", 1:"noteheads.triangle.quarter", 2:"noteheads.triangle.quarter", 3:"noteheads.triangle.quarter", 4:"noteheads.triangle.quarter", 5:"noteheads.triangle.quarter", 6:"noteheads.triangle.quarter", 7:"noteheads.triangle.quarter", nostem: "noteheads.triangle.quarter"},
57
42
  uflags:{3:"flags.u8th", 4:"flags.u16th", 5:"flags.u32nd", 6:"flags.u64th"},
58
43
  dflags:{3:"flags.d8th", 4:"flags.d16th", 5:"flags.d32nd", 6:"flags.d64th"}
59
44
  };
60
45
 
61
- AbstractEngraver = function(renderer, tuneNumber, options) {
46
+ var AbstractEngraver = function(getTextSize, tuneNumber, options) {
62
47
  this.decoration = new Decoration();
63
- this.renderer = renderer;
48
+ this.getTextSize = getTextSize;
64
49
  this.tuneNumber = tuneNumber;
65
50
  this.isBagpipes = options.bagpipes;
66
51
  this.flatBeams = options.flatbeams;
52
+ this.graceSlurs = options.graceSlurs;
53
+ this.percmap = options.percmap;
54
+ this.initialClef = options.initialClef
55
+ this.jazzchords = !!options.jazzchords
67
56
  this.reset();
68
57
  };
69
58
 
@@ -127,23 +116,24 @@ AbstractEngraver.prototype.popCrossLineElems = function(s,v) {
127
116
  }
128
117
  };
129
118
 
130
- AbstractEngraver.prototype.createABCLine = function(staffs, tempo) {
119
+ AbstractEngraver.prototype.createABCLine = function(staffs, tempo, l) {
131
120
  this.minY = 2; // PER: This will be the lowest that any note reaches. It will be used to set the dynamics row.
132
121
  // See if there are any lyrics on this line.
133
122
  this.containsLyrics(staffs);
134
- var staffgroup = new StaffGroupElement();
123
+ var staffgroup = new StaffGroupElement(this.getTextSize);
135
124
  this.tempoSet = false;
136
125
  for (var s = 0; s < staffs.length; s++) {
137
126
  if (hint)
138
127
  this.restoreState();
139
128
  hint = false;
140
- this.createABCStaff(staffgroup, staffs[s], tempo, s);
129
+ this.createABCStaff(staffgroup, staffs[s], tempo, s, l);
141
130
  }
142
131
  return staffgroup;
143
132
  };
144
133
 
145
- AbstractEngraver.prototype.createABCStaff = function(staffgroup, abcstaff, tempo, s) {
134
+ AbstractEngraver.prototype.createABCStaff = function(staffgroup, abcstaff, tempo, s, l) {
146
135
  // If the tempo is passed in, then the first element should get the tempo attached to it.
136
+ staffgroup.getTextSize.updateFonts(abcstaff);
147
137
  for (var v = 0; v < abcstaff.voices.length; v++) {
148
138
  var voice = new VoiceElement(v,abcstaff.voices.length);
149
139
  if (v===0) {
@@ -152,13 +142,19 @@ AbstractEngraver.prototype.createABCStaff = function(staffgroup, abcstaff, tempo
152
142
  } else {
153
143
  voice.duplicate = true; // bar lines and other duplicate info need not be created
154
144
  }
155
- if (abcstaff.title && abcstaff.title[v]) voice.header=abcstaff.title[v];
156
- var clef = createClef(abcstaff.clef, this.tuneNumber);
145
+ if (abcstaff.title && abcstaff.title[v]) {
146
+ voice.header=abcstaff.title[v].replace(/\\n/g, "\n");
147
+ voice.headerPosition = 6 + staffgroup.getTextSize.baselineToCenter(voice.header, "voicefont", 'staff-extra voice-name', v, abcstaff.voices.length)/spacing.STEP;
148
+ }
149
+ if (abcstaff.clef && abcstaff.clef.type === "perc")
150
+ voice.isPercussion = true;
151
+ var clef = (!this.initialClef || l === 0) && createClef(abcstaff.clef, this.tuneNumber);
157
152
  if (clef) {
158
153
  if (v ===0 && abcstaff.barNumber) {
159
154
  this.addMeasureNumber(abcstaff.barNumber, clef);
160
155
  }
161
156
  voice.addChild(clef);
157
+ this.startlimitelem = clef; // limit ties here
162
158
  }
163
159
  var keySig = createKeySignature(abcstaff.key, this.tuneNumber);
164
160
  if (keySig) {
@@ -181,22 +177,27 @@ AbstractEngraver.prototype.createABCStaff = function(staffgroup, abcstaff, tempo
181
177
  var isSingleLineStaff = staffLines === 1;
182
178
  this.createABCVoice(abcstaff.voices[v],tempo, s, v, isSingleLineStaff, voice);
183
179
  staffgroup.setStaffLimits(voice);
184
- if(abcstaff.brace === "start" || (!staffgroup.brace && abcstaff.brace)){
185
- staffgroup.brace = new BraceElem(voice.staff, "brace");
186
- }
187
- else if(abcstaff.brace === "end" && staffgroup.brace) {
188
- staffgroup.brace.setBottomStaff(voice.staff);
189
- } else if(abcstaff.brace === "continue" && staffgroup.brace) {
190
- staffgroup.brace.continuing(voice.staff);
191
- }
192
- if(abcstaff.bracket === "start" || (!staffgroup.bracket && abcstaff.bracket)){
193
- staffgroup.bracket = new BraceElem(voice.staff, "bracket");
194
- }
195
- else if(abcstaff.bracket === "end" && staffgroup.bracket) {
196
- staffgroup.bracket.setBottomStaff(voice.staff);
197
- } else if(abcstaff.bracket === "continue" && staffgroup.bracket) {
198
- staffgroup.bracket.continuing(voice.staff);
199
- }
180
+ if (v === 0) {
181
+ // only do brace and bracket processing on the first voice, otherwise it would be done twice.
182
+ if (abcstaff.brace === "start" || (!staffgroup.brace && abcstaff.brace)) {
183
+ if (!staffgroup.brace)
184
+ staffgroup.brace = [];
185
+ staffgroup.brace.push(new BraceElem(voice, "brace"));
186
+ } else if (abcstaff.brace === "end" && staffgroup.brace) {
187
+ staffgroup.brace[staffgroup.brace.length - 1].setBottomStaff(voice);
188
+ } else if (abcstaff.brace === "continue" && staffgroup.brace) {
189
+ staffgroup.brace[staffgroup.brace.length - 1].continuing(voice);
190
+ }
191
+ if (abcstaff.bracket === "start" || (!staffgroup.bracket && abcstaff.bracket)) {
192
+ if (!staffgroup.bracket)
193
+ staffgroup.bracket = [];
194
+ staffgroup.bracket.push(new BraceElem(voice, "bracket"));
195
+ } else if (abcstaff.bracket === "end" && staffgroup.bracket) {
196
+ staffgroup.bracket[staffgroup.bracket.length - 1].setBottomStaff(voice);
197
+ } else if (abcstaff.bracket === "continue" && staffgroup.bracket) {
198
+ staffgroup.bracket[staffgroup.bracket.length - 1].continuing(voice);
199
+ }
200
+ }
200
201
  }
201
202
  };
202
203
 
@@ -228,14 +229,14 @@ AbstractEngraver.prototype.createABCVoice = function(abcline, tempo, s, v, isSin
228
229
  for (var slur in this.slurs) {
229
230
  if (this.slurs.hasOwnProperty(slur)) {
230
231
  // this is already a slur element, but it was created for the last line, so recreate it.
231
- this.slurs[slur]= new TieElem({force: this.slurs[slur].force, voiceNumber: voiceNumber, stemDir: this.slurs[slur].stemDir});
232
+ this.slurs[slur]= new TieElem({force: this.slurs[slur].force, voiceNumber: voiceNumber, stemDir: this.slurs[slur].stemDir, style: this.slurs[slur].dotted});
232
233
  if (hint) this.slurs[slur].setHint();
233
234
  voice.addOther(this.slurs[slur]);
234
235
  }
235
236
  }
236
237
  for (var i=0; i<this.ties.length; i++) {
237
238
  // this is already a tie element, but it was created for the last line, so recreate it.
238
- this.ties[i]=new TieElem({ force: this.ties[i].force, stemDir: this.ties[i].stemDir, voiceNumber: voiceNumber });
239
+ this.ties[i]=new TieElem({ force: this.ties[i].force, stemDir: this.ties[i].stemDir, voiceNumber: voiceNumber, style: this.ties[i].dotted });
239
240
  if (hint) this.ties[i].setHint();
240
241
  voice.addOther(this.ties[i]);
241
242
  }
@@ -254,8 +255,8 @@ AbstractEngraver.prototype.createABCVoice = function(abcline, tempo, s, v, isSin
254
255
  for (i = 0; i < abselems.length; i++) {
255
256
  if (!this.tempoSet && tempo && !tempo.suppress) {
256
257
  this.tempoSet = true;
257
- var tempoElement = new AbsoluteElement(ret.elem, 0, 0, "tempo", this.tuneNumber, {});
258
- tempoElement.addChild(new TempoElement(tempo, this.tuneNumber, createNoteHead));
258
+ var tempoElement = new AbsoluteElement(tempo, 0, 0, "tempo", this.tuneNumber, {});
259
+ tempoElement.addFixedX(new TempoElement(tempo, this.tuneNumber, createNoteHead));
259
260
  voice.addChild(tempoElement);
260
261
  }
261
262
  voice.addChild(abselems[i]);
@@ -331,17 +332,17 @@ AbstractEngraver.prototype.createABCElement = function(isFirstStaff, isSingleLin
331
332
  if (voice.duplicate && elemset.length > 0) elemset[0].invisible = true;
332
333
  break;
333
334
  case "stem":
334
- this.stemdir=elem.direction;
335
+ this.stemdir=elem.direction === "auto" ? undefined : elem.direction;
335
336
  break;
336
337
  case "part":
337
338
  var abselem = new AbsoluteElement(elem,0,0, 'part', this.tuneNumber);
338
- var dim = this.renderer.getTextSize(elem.title, 'partsfont', "part");
339
- abselem.addChild(new RelativeElement(elem.title, 0, 0, undefined, {type:"part", height: dim.height/spacing.STEP}));
339
+ var dim = this.getTextSize.calc(elem.title, 'partsfont', "part");
340
+ abselem.addFixedX(new RelativeElement(elem.title, 0, 0, undefined, {type:"part", height: dim.height/spacing.STEP}));
340
341
  elemset[0] = abselem;
341
342
  break;
342
343
  case "tempo":
343
344
  var abselem3 = new AbsoluteElement(elem,0,0, 'tempo', this.tuneNumber);
344
- abselem3.addChild(new TempoElement(elem, this.tuneNumber, createNoteHead));
345
+ abselem3.addFixedX(new TempoElement(elem, this.tuneNumber, createNoteHead));
345
346
  elemset[0] = abselem3;
346
347
  break;
347
348
  case "style":
@@ -363,7 +364,7 @@ AbstractEngraver.prototype.createABCElement = function(isFirstStaff, isSingleLin
363
364
 
364
365
  default:
365
366
  var abselem2 = new AbsoluteElement(elem,0,0, 'unsupported', this.tuneNumber);
366
- abselem2.addChild(new RelativeElement("element type "+elem.el_type, 0, 0, undefined, {type:"debug"}));
367
+ abselem2.addFixed(new RelativeElement("element type "+elem.el_type, 0, 0, undefined, {type:"debug"}));
367
368
  elemset[0] = abselem2;
368
369
  }
369
370
 
@@ -383,26 +384,11 @@ AbstractEngraver.prototype.createABCElement = function(isFirstStaff, isSingleLin
383
384
  }
384
385
  }
385
386
 
386
- AbstractEngraver.prototype.calcBeamDir = function (isSingleLineStaff, voice, elems) {
387
- if (this.stemdir) // If the user or voice is forcing the stem direction, we already know the answer.
388
- return this.stemdir;
389
- var beamelem = new BeamElem(this.stemHeight * this.voiceScale, this.stemdir, this.flatBeams);
390
- for (var i = 0; i < elems.length; i++) {
391
- beamelem.add({abcelem: elems[i]}); // This is a hack to call beam elem with just a minimum of processing: for our purposes, we don't need to construct the whole note.
392
- }
393
-
394
- var dir = beamelem.calcDir();
395
- return dir ? "up" : "down";
396
- };
397
-
398
387
  AbstractEngraver.prototype.createBeam = function (isSingleLineStaff, voice, elems) {
399
388
  var abselemset = [];
400
389
 
401
- var dir = this.calcBeamDir(isSingleLineStaff, voice, elems);
402
- var beamelem = new BeamElem(this.stemHeight * this.voiceScale, dir, this.flatBeams, elems[0]);
390
+ var beamelem = new BeamElem(this.stemHeight * this.voiceScale, this.stemdir, this.flatBeams, elems[0]);
403
391
  if (hint) beamelem.setHint();
404
- var oldDir = this.stemdir;
405
- this.stemdir = dir;
406
392
  for (var i = 0; i < elems.length; i++) {
407
393
  var elem = elems[i];
408
394
  var abselem = this.createNote(elem, true, isSingleLineStaff, voice);
@@ -414,7 +400,7 @@ AbstractEngraver.prototype.createABCElement = function(isFirstStaff, isSingleLin
414
400
  this.tripletmultiplier = 1;
415
401
  }
416
402
  }
417
- this.stemdir = oldDir;
403
+ beamelem.calcDir();
418
404
  voice.addBeam(beamelem);
419
405
  return abselemset;
420
406
  };
@@ -437,20 +423,20 @@ var sortPitch = function(elem) {
437
423
  var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, additionalLedgers, dir, dx, scale) {
438
424
  for (var i=maxPitch; i>11; i--) {
439
425
  if (i%2===0 && !isRest) {
440
- abselem.addChild(new RelativeElement(null, dx, (symbolWidth+4)*scale, i, {type:"ledger"}));
426
+ abselem.addFixed(new RelativeElement(null, dx, (symbolWidth+4)*scale, i, {type:"ledger"}));
441
427
  }
442
428
  }
443
429
 
444
430
  for (i=minPitch; i<1; i++) {
445
431
  if (i%2===0 && !isRest) {
446
- abselem.addChild(new RelativeElement(null, dx, (symbolWidth+4)*scale, i, {type:"ledger"}));
432
+ abselem.addFixed(new RelativeElement(null, dx, (symbolWidth+4)*scale, i, {type:"ledger"}));
447
433
  }
448
434
  }
449
435
 
450
436
  for (i = 0; i < additionalLedgers.length; i++) { // PER: draw additional ledgers
451
437
  var ofs = symbolWidth;
452
438
  if (dir === 'down') ofs = -ofs;
453
- abselem.addChild(new RelativeElement(null, ofs+dx, (symbolWidth+4)*scale, additionalLedgers[i], {type:"ledger"}));
439
+ abselem.addFixed(new RelativeElement(null, ofs+dx, (symbolWidth+4)*scale, additionalLedgers[i], {type:"ledger"}));
454
440
  }
455
441
  };
456
442
 
@@ -467,6 +453,7 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
467
453
  gracebeam.mainNote = abselem; // this gives us a reference back to the note this is attached to so that the stems can be attached somewhere.
468
454
  }
469
455
 
456
+ var i;
470
457
  var graceoffsets = [];
471
458
  for (i = elem.gracenotes.length - 1; i >= 0; i--) { // figure out where to place each gracenote
472
459
  roomtaken += 10;
@@ -476,13 +463,13 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
476
463
  }
477
464
  }
478
465
 
479
- var i;
480
466
  for (i = 0; i < elem.gracenotes.length; i++) {
481
467
  var gracepitch = elem.gracenotes[i].verticalPos;
482
468
 
483
469
  flag = (gracebeam) ? null : chartable.uflags[(isBagpipes) ? 5 : 3];
484
470
  var accidentalSlot = [];
485
- var ret = createNoteHead(abselem, "noteheads.quarter", elem.gracenotes[i], "up", -graceoffsets[i], -graceoffsets[i], flag, 0, 0, gracescale*this.voiceScale, accidentalSlot, false);
471
+ var ret = createNoteHead(abselem, "noteheads.quarter", elem.gracenotes[i],
472
+ {dir: "up", headx: -graceoffsets[i], extrax: -graceoffsets[i], flag: flag, scale: gracescale*this.voiceScale, accidentalSlot: accidentalSlot});
486
473
  ret.notehead.highestVert = ret.notehead.pitch + stemHeight;
487
474
  var grace = ret.notehead;
488
475
  this.addSlursAndTies(abselem, elem.gracenotes[i], grace, voice, "up", true);
@@ -511,14 +498,19 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
511
498
  }
512
499
  ledgerLines(abselem, gracepitch, gracepitch, false, glyphs.getSymbolWidth("noteheads.quarter"), [], true, grace.dx - 1, 0.6);
513
500
 
514
- if (i === 0 && !isBagpipes && !(elem.rest && (elem.rest.type === "spacer" || elem.rest.type === "invisible"))) {
501
+ // if this is the first grace note, we might want to start a slur.
502
+ // there is a slur if graceSlurs is specifically set.
503
+ // there is no slur if it is bagpipes.
504
+ // there is not a slur if the element is a spacer or invisible rest.
505
+ var isInvisibleRest = elem.rest && (elem.rest.type === "spacer" || elem.rest.type === "invisible");
506
+ if (i === 0 && !isBagpipes && this.graceSlurs && !isInvisibleRest) {
515
507
  // This is the overall slur that is under the grace notes.
516
- var isTie = (elem.gracenotes.length === 1 && grace.pitch === notehead.pitch);
517
508
  voice.addOther(new TieElem({ anchor1: grace, anchor2: notehead, isGrace: true}));
518
509
  }
519
510
  }
520
511
 
521
512
  if (gracebeam) {
513
+ gracebeam.calcDir();
522
514
  voice.addBeam(gracebeam);
523
515
  }
524
516
  return roomtaken;
@@ -563,6 +555,7 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
563
555
  elem.maxpitch = restpitch;
564
556
  break;
565
557
  case "invisible":
558
+ case "invisible-multimeasure":
566
559
  case "spacer":
567
560
  c = "";
568
561
  elem.averagepitch = restpitch;
@@ -576,12 +569,13 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
576
569
  elem.maxpitch = restpitch;
577
570
  dot = 0;
578
571
  var mmWidth = glyphs.getSymbolWidth(c);
579
- abselem.addHead(new RelativeElement(c, -mmWidth, mmWidth * 2, 7));
580
- var numMeasures = new RelativeElement("" + elem.duration, 0, mmWidth, 16, {type: "multimeasure-text"});
572
+ abselem.addHead(new RelativeElement(c, mmWidth, mmWidth * 2, 7));
573
+ var numMeasures = new RelativeElement("" + elem.rest.text, mmWidth, mmWidth, 16, {type: "multimeasure-text"});
581
574
  abselem.addExtra(numMeasures);
582
575
  }
583
- if (elem.rest.type !== "multimeasure") {
584
- var ret = createNoteHead(abselem, c, {verticalPos: restpitch}, null, 0, 0, null, dot, 0, voiceScale, [], false);
576
+ if (elem.rest.type.indexOf("multimeasure") < 0 && elem.rest.type !== "invisible") {
577
+ var ret = createNoteHead(abselem, c, {verticalPos: restpitch},
578
+ { dot: dot, scale: voiceScale});
585
579
  noteHead = ret.notehead;
586
580
  if (noteHead) {
587
581
  abselem.addHead(noteHead);
@@ -661,6 +655,13 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
661
655
  var c;
662
656
  if (elem.pitches[p].style) { // There is a style for the whole group of pitches, but there could also be an override for a particular pitch.
663
657
  c = chartable[elem.pitches[p].style][-durlog];
658
+ } else if (voice.isPercussion && this.percmap) {
659
+ c = noteSymbol;
660
+ var percHead = this.percmap[pitchesToPerc(elem.pitches[p])];
661
+ if (percHead && percHead.noteHead) {
662
+ if (chartable[percHead.noteHead])
663
+ c = chartable[percHead.noteHead][-durlog];
664
+ }
664
665
  } else
665
666
  c = noteSymbol;
666
667
  // The highest position for the sake of placing slurs is itself if the slur is internal. It is the highest position possible if the slur is for the whole chord.
@@ -694,7 +695,8 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
694
695
  }
695
696
 
696
697
  var hasStem = !nostem && durlog<=-1;
697
- var ret = createNoteHead(abselem, c, elem.pitches[p], dir, 0, -roomTaken, flag, dot, dotshiftx, this.voiceScale, accidentalSlot, !stemdir);
698
+ var ret = createNoteHead(abselem, c, elem.pitches[p],
699
+ {dir: dir, extrax: -roomTaken, flag: flag, dot: dot, dotshiftx: dotshiftx, scale: this.voiceScale, accidentalSlot: accidentalSlot, shouldExtendStem: !stemdir, printAccidentals: !voice.isPercussion});
698
700
  symbolWidth = Math.max(glyphs.getSymbolWidth(c), symbolWidth);
699
701
  abselem.extraw -= ret.extraLeft;
700
702
  noteHead = ret.notehead;
@@ -721,13 +723,13 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
721
723
  var dx = (dir==="down" || abselem.heads.length === 0)?0:abselem.heads[0].w;
722
724
  var width = (dir==="down")?1:-1;
723
725
  // TODO-PER-HACK: One type of note head has a different placement of the stem. This should be more generically calculated:
724
- if (noteHead.c === 'noteheads.slash.quarter') {
726
+ if (noteHead && noteHead.c === 'noteheads.slash.quarter') {
725
727
  if (dir === 'down')
726
728
  p2 -= 1;
727
729
  else
728
730
  p1 += 1;
729
731
  }
730
- abselem.addExtra(new RelativeElement(null, dx, 0, p1, {"type": "stem", "pitch2":p2, linewidth: width}));
732
+ abselem.addRight(new RelativeElement(null, dx, 0, p1, {"type": "stem", "pitch2":p2, linewidth: width, bottom: p1-1}));
731
733
  //var RelativeElement = function RelativeElement(c, dx, w, pitch, opt) {
732
734
  min = Math.min(p1, p2);
733
735
  }
@@ -740,65 +742,9 @@ var ledgerLines = function(abselem, minPitch, maxPitch, isRest, symbolWidth, add
740
742
  var div = ly.divider === ' ' ? "" : ly.divider;
741
743
  lyricStr += ly.syllable + div + "\n";
742
744
  });
743
- var lyricDim = this.renderer.getTextSize(lyricStr, 'vocalfont', "lyric");
745
+ var lyricDim = this.getTextSize.calc(lyricStr, 'vocalfont', "lyric");
744
746
  var position = elem.positioning ? elem.positioning.vocalPosition : 'below';
745
- abselem.addCentered(new RelativeElement(lyricStr, 0, lyricDim.width, undefined, {type:"lyric", position: position, height: lyricDim.height / spacing.STEP }));
746
- };
747
-
748
- AbstractEngraver.prototype.addChord = function(abselem, elem, roomTaken, roomTakenRight) {
749
- var chordMargin = 8; // If there are chords next to each other, this is how close they can get.
750
- for (var i = 0; i < elem.chord.length; i++) {
751
- var chord = elem.chord[i];
752
- var x = 0;
753
- var y;
754
- var font;
755
- var klass;
756
- if (chord.position === "left" || chord.position === "right" || chord.position === "below" || chord.position === "above") {
757
- font = 'annotationfont';
758
- klass = "annotation";
759
- } else {
760
- font = 'gchordfont';
761
- klass = "chord";
762
- }
763
- var dim = this.renderer.getTextSize(chord.name, 'annotationfont', "annotation");
764
- var chordWidth = dim.width;
765
- var chordHeight = dim.height / spacing.STEP;
766
- switch (chord.position) {
767
- case "left":
768
- roomTaken+=chordWidth+7;
769
- x = -roomTaken; // TODO-PER: This is just a guess from trial and error
770
- y = elem.averagepitch;
771
- abselem.addExtra(new RelativeElement(chord.name, x, chordWidth+4, y, {type:"text", height: chordHeight}));
772
- break;
773
- case "right":
774
- roomTakenRight+=4;
775
- x = roomTakenRight;// TODO-PER: This is just a guess from trial and error
776
- y = elem.averagepitch;
777
- abselem.addRight(new RelativeElement(chord.name, x, chordWidth+4, y, {type:"text", height: chordHeight}));
778
- break;
779
- case "below":
780
- // setting the y-coordinate to undefined for now: it will be overwritten later on, after we figure out what the highest element on the line is.
781
- abselem.addRight(new RelativeElement(chord.name, 0, chordWidth+chordMargin, undefined, {type: "text", position: "below", height: chordHeight}));
782
- break;
783
- case "above":
784
- // setting the y-coordinate to undefined for now: it will be overwritten later on, after we figure out what the highest element on the line is.
785
- abselem.addRight(new RelativeElement(chord.name, 0, chordWidth+chordMargin, undefined, {type: "text", height: chordHeight}));
786
- break;
787
- default:
788
- if (chord.rel_position) {
789
- var relPositionY = chord.rel_position.y + 3*spacing.STEP; // TODO-PER: this is a fudge factor to make it line up with abcm2ps
790
- abselem.addChild(new RelativeElement(chord.name, x + chord.rel_position.x, 0, elem.minpitch + relPositionY / spacing.STEP, {type: "text", height: chordHeight}));
791
- } else {
792
- // setting the y-coordinate to undefined for now: it will be overwritten later on, after we figure out what the highest element on the line is.
793
- var pos2 = 'above';
794
- if (elem.positioning && elem.positioning.chordPosition)
795
- pos2 = elem.positioning.chordPosition;
796
-
797
- abselem.addCentered(new RelativeElement(chord.name, x, chordWidth, undefined, {type: "chord", position: pos2, height: chordHeight }));
798
- }
799
- }
800
- }
801
- return { roomTaken: roomTaken, roomTakenRight: roomTakenRight };
747
+ abselem.addCentered(new RelativeElement(lyricStr, 0, lyricDim.width, undefined, {type:"lyric", position: position, height: lyricDim.height / spacing.STEP, dim: this.getTextSize.attr('vocalfont', "lyric") }));
802
748
  };
803
749
 
804
750
  AbstractEngraver.prototype.createNote = function(elem, nostem, isSingleLineStaff, voice) { //stem presence: true for drawing stemless notehead
@@ -808,7 +754,6 @@ AbstractEngraver.prototype.createNote = function(elem, nostem, isSingleLineStaff
808
754
  var symbolWidth = 0;
809
755
  var additionalLedgers = []; // PER: handle the case of [bc'], where the b doesn't have a ledger line
810
756
 
811
- var i;
812
757
  var dir;
813
758
 
814
759
  var duration = getDuration(elem);
@@ -827,12 +772,14 @@ AbstractEngraver.prototype.createNote = function(elem, nostem, isSingleLineStaff
827
772
  var durationForSpacing = duration * this.tripletmultiplier;
828
773
  if (elem.rest && elem.rest.type === 'multimeasure')
829
774
  durationForSpacing = 1;
775
+ if (elem.rest && elem.rest.type === 'invisible-multimeasure')
776
+ durationForSpacing = this.measureLength*elem.rest.text;
830
777
  var absType = elem.rest ? "rest" : "note";
831
778
  var abselem = new AbsoluteElement(elem, durationForSpacing, 1, absType, this.tuneNumber, { durationClassOveride: elem.duration * this.tripletmultiplier});
832
779
  if (hint) abselem.setHint();
833
780
 
834
781
  if (elem.rest) {
835
- if (this.measureLength === duration && elem.rest.type !== 'invisible' && elem.rest.type !== 'spacer')
782
+ if (this.measureLength === duration && elem.rest.type !== 'invisible' && elem.rest.type !== 'spacer' && elem.rest.type.indexOf('multimeasure') < 0)
836
783
  elem.rest.type = 'whole'; // If the rest is exactly a measure, always use a whole rest
837
784
  var ret1 = addRestToAbsElement(abselem, elem, duration, dot, voice.voicetotal > 1, this.stemdir, isSingleLineStaff, durlog, this.voiceScale);
838
785
  notehead = ret1.noteHead;
@@ -863,19 +810,18 @@ AbstractEngraver.prototype.createNote = function(elem, nostem, isSingleLineStaff
863
810
  }
864
811
 
865
812
  if (elem.barNumber) {
866
- abselem.addChild(new RelativeElement(elem.barNumber, -10, 0, 0, {type:"barNumber"}));
813
+ abselem.addFixed(new RelativeElement(elem.barNumber, -10, 0, 0, {type:"barNumber"}));
867
814
  }
868
815
 
869
816
  // ledger lines
870
817
  ledgerLines(abselem, elem.minpitch, elem.maxpitch, elem.rest, symbolWidth, additionalLedgers, dir, -2, 1);
871
818
 
872
819
  if (elem.chord !== undefined) {
873
- var ret3 = this.addChord(abselem, elem, roomtaken, roomtakenright);
820
+ var ret3 = addChord(this.getTextSize, abselem, elem, roomtaken, roomtakenright, symbolWidth, this.jazzchords);
874
821
  roomtaken = ret3.roomTaken;
875
822
  roomtakenright = ret3.roomTakenRight;
876
823
  }
877
824
 
878
-
879
825
  if (elem.startTriplet) {
880
826
  this.triplet = new TripletElem(elem.startTriplet, notehead, { flatBeams: this.flatBeams }); // above is opposite from case of slurs
881
827
  }
@@ -884,108 +830,13 @@ AbstractEngraver.prototype.createNote = function(elem, nostem, isSingleLineStaff
884
830
  this.triplet.setCloseAnchor(notehead);
885
831
  }
886
832
 
887
- if (this.triplet && !elem.startTriplet && !elem.endTriplet) {
833
+ if (this.triplet && !elem.startTriplet && !elem.endTriplet && !(elem.rest && elem.rest.type === "spacer")) {
888
834
  this.triplet.middleNote(notehead);
889
835
  }
890
836
 
891
-
892
837
  return abselem;
893
838
  };
894
839
 
895
-
896
-
897
-
898
- var createNoteHead = function(abselem, c, pitchelem, dir, headx, extrax, flag, dot, dotshiftx, scale, accidentalSlot, shouldExtendStem) {
899
- // TODO scale the dot as well
900
- var pitch = pitchelem.verticalPos;
901
- var notehead;
902
- var i;
903
- var accidentalshiftx = 0;
904
- var newDotShiftX = 0;
905
- var extraLeft = 0;
906
- if (c === undefined)
907
- abselem.addChild(new RelativeElement("pitch is undefined", 0, 0, 0, {type:"debug"}));
908
- else if (c==="") {
909
- notehead = new RelativeElement(null, 0, 0, pitch);
910
- } else {
911
- var shiftheadx = headx;
912
- if (pitchelem.printer_shift) {
913
- var adjust = (pitchelem.printer_shift==="same")?1:0;
914
- shiftheadx = (dir==="down")?-glyphs.getSymbolWidth(c)*scale+adjust:glyphs.getSymbolWidth(c)*scale-adjust;
915
- }
916
- var opts = {scalex:scale, scaley: scale, thickness: glyphs.symbolHeightInPitches(c)*scale };
917
- notehead = new RelativeElement(c, shiftheadx, glyphs.getSymbolWidth(c)*scale, pitch, opts);
918
- notehead.stemDir = dir;
919
- if (flag) {
920
- var pos = pitch+((dir==="down")?-7:7)*scale;
921
- // if this is a regular note, (not grace or tempo indicator) then the stem will have been stretched to the middle line if it is far from the center.
922
- if (shouldExtendStem) {
923
- if (dir==="down" && pos > 6)
924
- pos = 6;
925
- if (dir==="up" && pos < 6)
926
- pos = 6;
927
- }
928
- //if (scale===1 && (dir==="down")?(pos>6):(pos<6)) pos=6;
929
- var xdelta = (dir==="down")?headx:headx+notehead.w-0.6;
930
- abselem.addRight(new RelativeElement(flag, xdelta, glyphs.getSymbolWidth(flag)*scale, pos, {scalex:scale, scaley: scale}));
931
- }
932
- newDotShiftX = notehead.w+dotshiftx-2+5*dot;
933
- for (;dot>0;dot--) {
934
- var dotadjusty = (1-Math.abs(pitch)%2); //PER: take abs value of the pitch. And the shift still happens on ledger lines.
935
- abselem.addRight(new RelativeElement("dots.dot", notehead.w+dotshiftx-2+5*dot, glyphs.getSymbolWidth("dots.dot"), pitch+dotadjusty));
936
- }
937
- }
938
- if (notehead)
939
- notehead.highestVert = pitchelem.highestVert;
940
-
941
- if (pitchelem.accidental) {
942
- var symb;
943
- switch (pitchelem.accidental) {
944
- case "quartersharp":
945
- symb = "accidentals.halfsharp";
946
- break;
947
- case "dblsharp":
948
- symb = "accidentals.dblsharp";
949
- break;
950
- case "sharp":
951
- symb = "accidentals.sharp";
952
- break;
953
- case "quarterflat":
954
- symb = "accidentals.halfflat";
955
- break;
956
- case "flat":
957
- symb = "accidentals.flat";
958
- break;
959
- case "dblflat":
960
- symb = "accidentals.dblflat";
961
- break;
962
- case "natural":
963
- symb = "accidentals.nat";
964
- }
965
- // if a note is at least a sixth away, it can share a slot with another accidental
966
- var accSlotFound = false;
967
- var accPlace = extrax;
968
- for (var j = 0; j < accidentalSlot.length; j++) {
969
- if (pitch - accidentalSlot[j][0] >= 6) {
970
- accidentalSlot[j][0] = pitch;
971
- accPlace = accidentalSlot[j][1];
972
- accSlotFound = true;
973
- break;
974
- }
975
- }
976
- if (accSlotFound === false) {
977
- accPlace -= (glyphs.getSymbolWidth(symb)*scale+2);
978
- accidentalSlot.push([pitch,accPlace]);
979
- accidentalshiftx = (glyphs.getSymbolWidth(symb)*scale+2);
980
- }
981
- abselem.addExtra(new RelativeElement(symb, accPlace, glyphs.getSymbolWidth(symb), pitch, {scalex:scale, scaley: scale}));
982
- extraLeft = glyphs.getSymbolWidth(symb) / 2; // TODO-PER: We need a little extra width if there is an accidental, but I'm not sure why it isn't the full width of the accidental.
983
- }
984
-
985
- return { notehead: notehead, accidentalshiftx: accidentalshiftx, dotshiftx: newDotShiftX, extraLeft: extraLeft };
986
-
987
- };
988
-
989
840
  AbstractEngraver.prototype.addSlursAndTies = function(abselem, pitchelem, notehead, voice, dir, isGrace) {
990
841
  if (pitchelem.endTie) {
991
842
  if (this.ties.length > 0) {
@@ -1008,7 +859,7 @@ var createNoteHead = function(abselem, c, pitchelem, dir, headx, extrax, flag, d
1008
859
 
1009
860
  var voiceNumber = voice.voicetotal < 2 ? -1 : voice.voicenumber;
1010
861
  if (pitchelem.startTie) {
1011
- var tie = new TieElem({ anchor1: notehead, force: (this.stemdir==="down" || this.stemdir==="up"), stemDir: this.stemdir, isGrace: isGrace, voiceNumber: voiceNumber});
862
+ var tie = new TieElem({ anchor1: notehead, force: (this.stemdir==="down" || this.stemdir==="up"), stemDir: this.stemdir, isGrace: isGrace, voiceNumber: voiceNumber, style: pitchelem.startTie.style });
1012
863
  if (hint) tie.setHint();
1013
864
 
1014
865
  this.ties[this.ties.length]=tie;
@@ -1019,10 +870,11 @@ var createNoteHead = function(abselem, c, pitchelem, dir, headx, extrax, flag, d
1019
870
  abselem.startTie = true;
1020
871
  }
1021
872
 
873
+ var slur;
874
+ var slurid;
1022
875
  if (pitchelem.endSlur) {
1023
876
  for (var i=0; i<pitchelem.endSlur.length; i++) {
1024
- var slurid = pitchelem.endSlur[i];
1025
- var slur;
877
+ slurid = pitchelem.endSlur[i];
1026
878
  if (this.slurs[slurid]) {
1027
879
  slur = this.slurs[slurid];
1028
880
  slur.setEndAnchor(notehead);
@@ -1046,8 +898,8 @@ var createNoteHead = function(abselem, c, pitchelem, dir, headx, extrax, flag, d
1046
898
 
1047
899
  if (pitchelem.startSlur) {
1048
900
  for (i=0; i<pitchelem.startSlur.length; i++) {
1049
- var slurid = pitchelem.startSlur[i].label;
1050
- var slur = new TieElem({ anchor1: notehead, stemDir: this.stemdir, voiceNumber: voiceNumber});
901
+ slurid = pitchelem.startSlur[i].label;
902
+ slur = new TieElem({ anchor1: notehead, stemDir: this.stemdir, voiceNumber: voiceNumber, style: pitchelem.startSlur[i].style});
1051
903
  if (hint) slur.setHint();
1052
904
  this.slurs[slurid]=slur;
1053
905
  voice.addOther(slur);
@@ -1056,9 +908,9 @@ var createNoteHead = function(abselem, c, pitchelem, dir, headx, extrax, flag, d
1056
908
  };
1057
909
 
1058
910
  AbstractEngraver.prototype.addMeasureNumber = function (number, abselem) {
1059
- var measureNumDim = this.renderer.getTextSize(number, "measurefont", 'bar-number');
911
+ var measureNumDim = this.getTextSize.calc(number, "measurefont", 'bar-number');
1060
912
  var dx = measureNumDim.width > 18 && abselem.abcelem.type === "treble" ? -7 : 0;
1061
- abselem.addChild(new RelativeElement(number, dx, measureNumDim.width, 11+measureNumDim.height / spacing.STEP, {type:"barNumber"}));
913
+ abselem.addFixed(new RelativeElement(number, dx, measureNumDim.width, 11+measureNumDim.height / spacing.STEP, {type:"barNumber", dim: this.getTextSize.attr("measurefont", 'bar-number')}));
1062
914
  };
1063
915
 
1064
916
  AbstractEngraver.prototype.createBarLine = function (voice, elem, isFirstStaff) {
@@ -1140,7 +992,7 @@ AbstractEngraver.prototype.createBarLine = function (voice, elem, isFirstStaff)
1140
992
  } // 2 is hardcoded
1141
993
 
1142
994
  if (elem.startEnding && isFirstStaff) { // only put the first & second ending marks on the first staff
1143
- var textWidth = this.renderer.getTextSize(elem.startEnding, "repeatfont", '').width;
995
+ var textWidth = this.getTextSize.calc(elem.startEnding, "repeatfont", '').width;
1144
996
  abselem.minspacing += textWidth + 10; // Give plenty of room for the ending number.
1145
997
  this.partstartelem = new EndingElem(elem.startEnding, anchor, null);
1146
998
  voice.addOther(this.partstartelem);
@@ -1153,7 +1005,4 @@ AbstractEngraver.prototype.createBarLine = function (voice, elem, isFirstStaff)
1153
1005
 
1154
1006
  };
1155
1007
 
1156
-
1157
- })();
1158
-
1159
1008
  module.exports = AbstractEngraver;