abcjs-rails 1.11 → 2.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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/abcjs/api/abc_animation.js +41 -1
- data/app/assets/javascripts/abcjs/api/abc_tunebook.js +5 -0
- data/app/assets/javascripts/abcjs/data/abc_tune.js +4 -3
- data/app/assets/javascripts/abcjs/edit/abc_editor.js +10 -0
- data/app/assets/javascripts/abcjs/parse/abc_parse.js +120 -19
- data/app/assets/javascripts/abcjs/parse/abc_parse_directive.js +456 -115
- data/app/assets/javascripts/abcjs/raphael.js +2 -2
- data/app/assets/javascripts/abcjs/write/abc_absolute_element.js +111 -4
- data/app/assets/javascripts/abcjs/write/abc_abstract_engraver.js +899 -0
- data/app/assets/javascripts/abcjs/write/abc_beam_element.js +263 -37
- data/app/assets/javascripts/abcjs/write/abc_create_clef.js +76 -0
- data/app/assets/javascripts/abcjs/write/abc_create_key_signature.js +41 -0
- data/app/assets/javascripts/abcjs/write/abc_create_time_signature.js +51 -0
- data/app/assets/javascripts/abcjs/write/{abc_cresendo_element.js → abc_crescendo_element.js} +32 -1
- data/app/assets/javascripts/abcjs/write/abc_decoration.js +321 -0
- data/app/assets/javascripts/abcjs/write/abc_dynamic_decoration.js +22 -1
- data/app/assets/javascripts/abcjs/write/abc_ending_element.js +31 -1
- data/app/assets/javascripts/abcjs/write/abc_engraver_controller.js +359 -0
- data/app/assets/javascripts/abcjs/write/abc_glyphs.js +119 -9
- data/app/assets/javascripts/abcjs/write/abc_layout.js +2 -2
- data/app/assets/javascripts/abcjs/write/abc_relative_element.js +106 -8
- data/app/assets/javascripts/abcjs/write/abc_renderer.js +754 -0
- data/app/assets/javascripts/abcjs/write/abc_staff_group_element.js +249 -9
- data/app/assets/javascripts/abcjs/write/abc_tempo_element.js +104 -0
- data/app/assets/javascripts/abcjs/write/abc_tie_element.js +69 -22
- data/app/assets/javascripts/abcjs/write/abc_triplet_element.js +77 -10
- data/app/assets/javascripts/abcjs/write/abc_voice_element.js +100 -8
- data/app/assets/javascripts/abcjs/write/abc_write.js +64 -68
- data/lib/abcjs-rails/version.rb +1 -1
- metadata +12 -4
@@ -35,8 +35,6 @@ if (!window.ABCJS.write)
|
|
35
35
|
// Members:
|
36
36
|
// staffs: an array of all the staves in this group. Each staff contains the following elements:
|
37
37
|
// { top, bottom, highest, lowest, y }
|
38
|
-
// stafflines: an array of the same length as staffs. It contains an integer with the number of lines.
|
39
|
-
// TODO-PER: stafflines should actually be an element of staffs, I think.
|
40
38
|
// voices: array of VoiceElement objects. This is mostly passed in, but the VoiceElement objects are modified here.
|
41
39
|
//
|
42
40
|
// spacingunits: number of relative x-units in the line. Used by the calling function to pass back in as the "spacing" input parameter.
|
@@ -54,18 +52,148 @@ if (!window.ABCJS.write)
|
|
54
52
|
ABCJS.write.StaffGroupElement = function() {
|
55
53
|
this.voices = [];
|
56
54
|
this.staffs = [];
|
57
|
-
|
55
|
+
};
|
56
|
+
|
57
|
+
ABCJS.write.StaffGroupElement.prototype.setLimit = function(member, voice) {
|
58
|
+
if (!voice.specialY[member]) return;
|
59
|
+
if (!voice.staff.specialY[member])
|
60
|
+
voice.staff.specialY[member] = voice.specialY[member];
|
61
|
+
else
|
62
|
+
voice.staff.specialY[member] = Math.max(voice.staff.specialY[member], voice.specialY[member]);
|
58
63
|
};
|
59
64
|
|
60
65
|
ABCJS.write.StaffGroupElement.prototype.addVoice = function (voice, staffnumber, stafflines) {
|
61
|
-
this.voices
|
62
|
-
|
63
|
-
|
64
|
-
this.
|
66
|
+
var voiceNum = this.voices.length;
|
67
|
+
this.voices[voiceNum] = voice;
|
68
|
+
if (this.staffs[staffnumber])
|
69
|
+
this.staffs[staffnumber].voices.push(voiceNum);
|
70
|
+
else {
|
71
|
+
// TODO-PER: how does the min/max change when stafflines is not 5?
|
72
|
+
this.staffs[this.staffs.length] = {
|
73
|
+
top: 10,
|
74
|
+
bottom: 2,
|
75
|
+
lines: stafflines,
|
76
|
+
voices: [voiceNum],
|
77
|
+
specialY: {
|
78
|
+
tempoHeightAbove: 0,
|
79
|
+
partHeightAbove: 0,
|
80
|
+
volumeHeightAbove: 0,
|
81
|
+
dynamicHeightAbove: 0,
|
82
|
+
endingHeightAbove: 0,
|
83
|
+
chordHeightAbove: 0,
|
84
|
+
lyricHeightAbove: 0,
|
85
|
+
|
86
|
+
lyricHeightBelow: 0,
|
87
|
+
chordHeightBelow: 0,
|
88
|
+
volumeHeightBelow: 0,
|
89
|
+
dynamicHeightBelow: 0
|
90
|
+
}
|
91
|
+
};
|
65
92
|
}
|
66
93
|
voice.staff = this.staffs[staffnumber];
|
67
94
|
};
|
68
95
|
|
96
|
+
ABCJS.write.StaffGroupElement.prototype.setStaffLimits = function (voice) {
|
97
|
+
voice.staff.top = Math.max(voice.staff.top, voice.top);
|
98
|
+
voice.staff.bottom = Math.min(voice.staff.bottom, voice.bottom);
|
99
|
+
this.setLimit('tempoHeightAbove', voice);
|
100
|
+
this.setLimit('partHeightAbove', voice);
|
101
|
+
this.setLimit('volumeHeightAbove', voice);
|
102
|
+
this.setLimit('dynamicHeightAbove', voice);
|
103
|
+
this.setLimit('endingHeightAbove', voice);
|
104
|
+
this.setLimit('chordHeightAbove', voice);
|
105
|
+
this.setLimit('lyricHeightAbove', voice);
|
106
|
+
this.setLimit('lyricHeightBelow', voice);
|
107
|
+
this.setLimit('chordHeightBelow', voice);
|
108
|
+
this.setLimit('volumeHeightBelow', voice);
|
109
|
+
this.setLimit('dynamicHeightBelow', voice);
|
110
|
+
};
|
111
|
+
|
112
|
+
ABCJS.write.StaffGroupElement.prototype.setUpperAndLowerElements = function(renderer) {
|
113
|
+
// 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.
|
114
|
+
// Also, get the overall height of all the staves in this group.
|
115
|
+
var lastStaffBottom;
|
116
|
+
for (var i = 0; i < this.staffs.length; i++) {
|
117
|
+
var staff = this.staffs[i];
|
118
|
+
// the vertical order of elements that are above is: tempo, part, volume/dynamic, ending/chord, lyric
|
119
|
+
// the vertical order of elements that are below is: lyric, chord, volume/dynamic
|
120
|
+
var positionY = {
|
121
|
+
tempoHeightAbove: 0,
|
122
|
+
partHeightAbove: 0,
|
123
|
+
volumeHeightAbove: 0,
|
124
|
+
dynamicHeightAbove: 0,
|
125
|
+
endingHeightAbove: 0,
|
126
|
+
chordHeightAbove: 0,
|
127
|
+
lyricHeightAbove: 0,
|
128
|
+
|
129
|
+
lyricHeightBelow: 0,
|
130
|
+
chordHeightBelow: 0,
|
131
|
+
volumeHeightBelow: 0,
|
132
|
+
dynamicHeightBelow: 0
|
133
|
+
};
|
134
|
+
|
135
|
+
if (ABCJS.write.debugPlacement) {
|
136
|
+
staff.originalTop = staff.top; // This is just being stored for debugging purposes.
|
137
|
+
staff.originalBottom = staff.bottom; // This is just being stored for debugging purposes.
|
138
|
+
}
|
139
|
+
|
140
|
+
if (staff.specialY.lyricHeightAbove) { staff.top += staff.specialY.lyricHeightAbove; positionY.lyricHeightAbove = staff.top; }
|
141
|
+
if (staff.specialY.chordHeightAbove) { staff.top += staff.specialY.chordHeightAbove; positionY.chordHeightAbove = staff.top; }
|
142
|
+
if (staff.specialY.endingHeightAbove) {
|
143
|
+
if (staff.specialY.chordHeightAbove)
|
144
|
+
staff.top += 2;
|
145
|
+
else
|
146
|
+
staff.top += staff.specialY.endingHeightAbove;
|
147
|
+
positionY.endingHeightAbove = staff.top;
|
148
|
+
}
|
149
|
+
if (staff.specialY.dynamicHeightAbove && staff.specialY.volumeHeightAbove) {
|
150
|
+
staff.top += Math.max(staff.specialY.dynamicHeightAbove, staff.specialY.volumeHeightAbove);
|
151
|
+
positionY.dynamicHeightAbove = staff.top;
|
152
|
+
positionY.volumeHeightAbove = staff.top;
|
153
|
+
} else if (staff.specialY.dynamicHeightAbove) {
|
154
|
+
staff.top += staff.specialY.dynamicHeightAbove; positionY.dynamicHeightAbove = staff.top;
|
155
|
+
} else if (staff.specialY.volumeHeightAbove) { staff.top += staff.specialY.volumeHeightAbove; positionY.volumeHeightAbove = staff.top; }
|
156
|
+
if (staff.specialY.partHeightAbove) { staff.top += staff.specialY.partHeightAbove; positionY.partHeightAbove = staff.top; }
|
157
|
+
if (staff.specialY.tempoHeightAbove) { staff.top += staff.specialY.tempoHeightAbove; positionY.tempoHeightAbove = staff.top; }
|
158
|
+
|
159
|
+
if (staff.specialY.lyricHeightBelow) { positionY.lyricHeightBelow = staff.bottom; staff.bottom -= staff.specialY.lyricHeightBelow; }
|
160
|
+
if (staff.specialY.chordHeightBelow) { positionY.chordHeightBelow = staff.bottom; staff.bottom -= staff.specialY.chordHeightBelow; }
|
161
|
+
if (staff.specialY.volumeHeightBelow && staff.specialY.dynamicHeightBelow) {
|
162
|
+
positionY.volumeHeightBelow = staff.bottom;
|
163
|
+
positionY.dynamicHeightBelow = staff.bottom;
|
164
|
+
staff.bottom -= Math.max(staff.specialY.volumeHeightBelow, staff.specialY.dynamicHeightBelow);
|
165
|
+
} else if (staff.specialY.volumeHeightBelow) {
|
166
|
+
positionY.volumeHeightBelow = staff.bottom; staff.bottom -= staff.specialY.volumeHeightBelow;
|
167
|
+
} else if (staff.specialY.dynamicHeightBelow) {
|
168
|
+
positionY.dynamicHeightBelow = staff.bottom; staff.bottom -= staff.specialY.dynamicHeightBelow;
|
169
|
+
}
|
170
|
+
|
171
|
+
if (ABCJS.write.debugPlacement)
|
172
|
+
staff.positionY = positionY; // This is just being stored for debugging purposes.
|
173
|
+
|
174
|
+
for (var j = 0; j < staff.voices.length; j++) {
|
175
|
+
var voice = this.voices[staff.voices[j]];
|
176
|
+
voice.setUpperAndLowerElements(positionY);
|
177
|
+
}
|
178
|
+
// 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.
|
179
|
+
// Only try to put in extra space if this isn't the top staff.
|
180
|
+
if (lastStaffBottom !== undefined) {
|
181
|
+
var thisStaffTop = staff.top - 10;
|
182
|
+
var forcedSpacingBetween = lastStaffBottom + thisStaffTop;
|
183
|
+
var minSpacingInPitches = renderer.spacing.systemStaffSeparation/ABCJS.write.spacing.STEP;
|
184
|
+
var addedSpace = minSpacingInPitches - forcedSpacingBetween;
|
185
|
+
if (addedSpace > 0)
|
186
|
+
staff.top += addedSpace;
|
187
|
+
}
|
188
|
+
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.
|
189
|
+
|
190
|
+
// Now we need a little margin on the top, so we'll just throw that in.
|
191
|
+
//staff.top += 4;
|
192
|
+
//console.log("Staff Y: ",i,heightInPitches,staff.top,staff.bottom);
|
193
|
+
}
|
194
|
+
//console.log("Staff Height: ",heightInPitches,this.height);
|
195
|
+
};
|
196
|
+
|
69
197
|
ABCJS.write.StaffGroupElement.prototype.finished = function() {
|
70
198
|
for (var i=0;i<this.voices.length;i++) {
|
71
199
|
if (!this.voices[i].layoutEnded()) return false;
|
@@ -73,21 +201,36 @@ ABCJS.write.StaffGroupElement.prototype.finished = function() {
|
|
73
201
|
return true;
|
74
202
|
};
|
75
203
|
|
204
|
+
<<<<<<< HEAD
|
205
|
+
ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, renderer, debug) {
|
206
|
+
this.spacingunits = 0; // number of times we will have ended up using the spacing distance (as opposed to fixed width distances)
|
207
|
+
this.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
|
208
|
+
var x = renderer.padding.left;
|
209
|
+
=======
|
76
210
|
ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, controller, debug) {
|
77
211
|
this.spacingunits = 0; // number of times we will have ended up using the spacing distance (as opposed to fixed width distances)
|
78
212
|
this.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
|
79
213
|
var x = controller.paddingleft*controller.scale;
|
214
|
+
>>>>>>> origin/master
|
80
215
|
|
81
216
|
// find out how much space will be taken up by voice headers
|
82
217
|
var voiceheaderw = 0;
|
83
218
|
for (var i=0;i<this.voices.length;i++) {
|
84
219
|
if(this.voices[i].header) {
|
85
|
-
|
220
|
+
<<<<<<< HEAD
|
221
|
+
var size = renderer.getTextSize(this.voices[i].header, 'voicefont', '');
|
222
|
+
voiceheaderw = Math.max(voiceheaderw,size.width);
|
223
|
+
}
|
224
|
+
}
|
225
|
+
x=x+voiceheaderw*1.1; // When there is no voice header, 110% of 0 is 0
|
226
|
+
=======
|
227
|
+
var t = controller.renderText(100, this.y-10, this.voices[i].header, 'voicefont', ''); // code duplicated below // don't scale this as we ask for the bbox
|
86
228
|
voiceheaderw = Math.max(voiceheaderw,t.getBBox().width);
|
87
229
|
t.remove();
|
88
230
|
}
|
89
231
|
}
|
90
232
|
x=x+voiceheaderw*(1/controller.scale)*1.1; // 10% of 0 is 0
|
233
|
+
>>>>>>> origin/master
|
91
234
|
this.startx=x;
|
92
235
|
|
93
236
|
var currentduration = 0;
|
@@ -124,12 +267,14 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, controller, d
|
|
124
267
|
spacingunit = 0; // number of spacingunits coming from the previously laid out element to this one
|
125
268
|
var spacingduration = 0;
|
126
269
|
for (i=0;i<currentvoices.length;i++) {
|
270
|
+
//console.log("greatest spacing unit", x, currentvoices[i].getNextX(), currentvoices[i].getSpacingUnits(), currentvoices[i].spacingduration);
|
127
271
|
if (currentvoices[i].getNextX()>x) {
|
128
272
|
x=currentvoices[i].getNextX();
|
129
273
|
spacingunit=currentvoices[i].getSpacingUnits();
|
130
274
|
spacingduration = currentvoices[i].spacingduration;
|
131
275
|
}
|
132
276
|
}
|
277
|
+
//console.log("new spacingunit", spacingunit, this.spacingunits, "="+(spacingunit+ this.spacingunits));
|
133
278
|
this.spacingunits+=spacingunit;
|
134
279
|
this.minspace = Math.min(this.minspace,spacingunit);
|
135
280
|
|
@@ -165,6 +310,7 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, controller, d
|
|
165
310
|
spacingunit=this.voices[i].getSpacingUnits();
|
166
311
|
}
|
167
312
|
}
|
313
|
+
//console.log("greatest remaining",spacingunit,x);
|
168
314
|
this.spacingunits+=spacingunit;
|
169
315
|
this.w = x;
|
170
316
|
|
@@ -173,6 +319,18 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, controller, d
|
|
173
319
|
}
|
174
320
|
};
|
175
321
|
|
322
|
+
<<<<<<< HEAD
|
323
|
+
ABCJS.write.StaffGroupElement.prototype.calcHeight = function () {
|
324
|
+
// the height is calculated here in a parallel way to the drawing below in hopes that both of these functions will be modified together.
|
325
|
+
// TODO-PER: also add the space between staves. (That's systemStaffSeparation, which is the minimum distance between the staff LINES.)
|
326
|
+
var height = 0;
|
327
|
+
for (var i=0;i<this.voices.length;i++) {
|
328
|
+
var staff = this.voices[i].staff;
|
329
|
+
if (!this.voices[i].duplicate) {
|
330
|
+
height += staff.top;
|
331
|
+
if (staff.bottom < 0)
|
332
|
+
height += -staff.bottom;
|
333
|
+
=======
|
176
334
|
ABCJS.write.StaffGroupElement.prototype.draw = function (renderer, y) {
|
177
335
|
|
178
336
|
this.y = y;
|
@@ -192,10 +350,59 @@ ABCJS.write.StaffGroupElement.prototype.draw = function (renderer, y) {
|
|
192
350
|
if (this.stafflines[i] === undefined)
|
193
351
|
this.stafflines[i] = 5;
|
194
352
|
renderer.printStave(this.startx, this.w, this.stafflines[i]);
|
353
|
+
>>>>>>> origin/master
|
195
354
|
}
|
196
355
|
}
|
197
|
-
|
356
|
+
return height;
|
357
|
+
};
|
198
358
|
|
359
|
+
<<<<<<< HEAD
|
360
|
+
ABCJS.write.StaffGroupElement.prototype.draw = function (renderer) {
|
361
|
+
// We enter this method with renderer.y pointing to the topmost coordinate that we're allowed to draw.
|
362
|
+
// All of the children that will be drawn have a relative "pitch" set, where zero is the first ledger line below the staff.
|
363
|
+
// renderer.y will be offset at the beginning of each staff by the amount required to make the relative pitch work.
|
364
|
+
// If there are multiple staves, then renderer.y will be incremented for each new staff.
|
365
|
+
|
366
|
+
var debugPrint;
|
367
|
+
var colorIndex;
|
368
|
+
if (ABCJS.write.debugPlacement) {
|
369
|
+
var colors = [ "rgba(207,27,36,0.4)", "rgba(168,214,80,0.4)", "rgba(110,161,224,0.4)", "rgba(191,119,218,0.4)", "rgba(195,30,151,0.4)",
|
370
|
+
"rgba(31,170,177,0.4)", "rgba(220,166,142,0.4)" ];
|
371
|
+
debugPrint = function(staff, key) {
|
372
|
+
if (staff.positionY[key]) {
|
373
|
+
//renderer.printHorizontalLine(50, renderer.calcY(staff.positionY[key]), key.substr(0, 4) + " " + Math.round(staff.positionY[key]));
|
374
|
+
var height = staff.specialY[key] * ABCJS.write.spacing.STEP;
|
375
|
+
renderer.printShadedBox(renderer.padding.left, renderer.calcY(staff.positionY[key]), renderer.controller.width, height,colors[colorIndex], key.substr(0, 4));
|
376
|
+
colorIndex += 1; if (colorIndex > 6) colorIndex = 0;
|
377
|
+
}
|
378
|
+
};
|
379
|
+
}
|
380
|
+
|
381
|
+
var startY = renderer.y; // So that it can be restored after we're done.
|
382
|
+
// Set the absolute Y position for each staff here, so the voice drawing below can just use if.
|
383
|
+
for (var j = 0; j < this.staffs.length; j++) {
|
384
|
+
var staff1 = this.staffs[j];
|
385
|
+
//renderer.printHorizontalLine(50, renderer.y, "start");
|
386
|
+
renderer.moveY(ABCJS.write.spacing.STEP, staff1.top);
|
387
|
+
staff1.absoluteY = renderer.y;
|
388
|
+
if (ABCJS.write.debugPlacement) {
|
389
|
+
colorIndex = 0;
|
390
|
+
renderer.printShadedBox(renderer.padding.left, renderer.calcY(staff1.originalTop), renderer.controller.width, renderer.calcY(staff1.originalBottom)-renderer.calcY(staff1.originalTop),"rgba(0,0,0,0.1)");
|
391
|
+
debugPrint(staff1, 'chordHeightAbove');
|
392
|
+
debugPrint(staff1, 'chordHeightBelow');
|
393
|
+
debugPrint(staff1, 'dynamicHeightAbove');
|
394
|
+
debugPrint(staff1, 'dynamicHeightBelow');
|
395
|
+
debugPrint(staff1, 'endingHeightAbove');
|
396
|
+
debugPrint(staff1, 'lyricHeightAbove');
|
397
|
+
debugPrint(staff1, 'lyricHeightBelow');
|
398
|
+
debugPrint(staff1, 'partHeightAbove');
|
399
|
+
debugPrint(staff1, 'tempoHeightAbove');
|
400
|
+
debugPrint(staff1, 'volumeHeightAbove');
|
401
|
+
debugPrint(staff1, 'volumeHeightBelow');
|
402
|
+
}
|
403
|
+
if (staff1.bottom < 0)
|
404
|
+
renderer.moveY(ABCJS.write.spacing.STEP, -staff1.bottom);
|
405
|
+
=======
|
199
406
|
var bartop = 0;
|
200
407
|
renderer.measureNumber = null;
|
201
408
|
for (i=0;i<this.voices.length;i++) {
|
@@ -210,8 +417,35 @@ ABCJS.write.StaffGroupElement.prototype.draw = function (renderer, y) {
|
|
210
417
|
renderer.y = this.staffs[this.staffs.length-1].y;
|
211
418
|
var bottom = renderer.calcY(2);
|
212
419
|
renderer.printStem(this.startx, 0.6, top, bottom);
|
420
|
+
>>>>>>> origin/master
|
213
421
|
}
|
422
|
+
var topLine; // these are to connect multiple staves. We need to remember where they are.
|
423
|
+
var bottomLine;
|
214
424
|
|
425
|
+
<<<<<<< HEAD
|
426
|
+
var bartop = 0;
|
427
|
+
renderer.measureNumber = null;
|
428
|
+
for (var i=0;i<this.voices.length;i++) {
|
429
|
+
var staff = this.voices[i].staff;
|
430
|
+
renderer.y = staff.absoluteY;
|
431
|
+
//renderer.y = staff.y;
|
432
|
+
// offset for starting the counting at middle C
|
433
|
+
if (!this.voices[i].duplicate) {
|
434
|
+
// renderer.moveY(ABCJS.write.spacing.STEP, staff.top);
|
435
|
+
if (!topLine) topLine = renderer.calcY(10);
|
436
|
+
bottomLine = renderer.calcY(2);
|
437
|
+
if (staff.lines !== 0)
|
438
|
+
renderer.printStave(this.startx, this.w, staff.lines);
|
439
|
+
}
|
440
|
+
this.voices[i].draw(renderer, bartop);
|
441
|
+
if (!this.voices[i].duplicate) {
|
442
|
+
bartop = renderer.calcY(2); // This connects the bar lines between two different staves.
|
443
|
+
// if (staff.bottom < 0)
|
444
|
+
// renderer.moveY(ABCJS.write.spacing.STEP, -staff.bottom);
|
445
|
+
}
|
446
|
+
}
|
447
|
+
renderer.measureNumber = null;
|
448
|
+
=======
|
215
449
|
// for (i=0;i<this.staffs.length;i++) {
|
216
450
|
// if (this.stafflines[i] === 0) continue;
|
217
451
|
// renderer.y = this.staffs[i].y;
|
@@ -220,6 +454,12 @@ ABCJS.write.StaffGroupElement.prototype.draw = function (renderer, y) {
|
|
220
454
|
// this.stafflines[i] = 5;
|
221
455
|
// renderer.printStave(this.startx,this.w, this.stafflines[i]);
|
222
456
|
// }
|
457
|
+
>>>>>>> origin/master
|
223
458
|
|
459
|
+
// connect all the staves together with a vertical line
|
460
|
+
if (this.staffs.length>1) {
|
461
|
+
renderer.printStem(this.startx, 0.6, topLine, bottomLine);
|
462
|
+
}
|
463
|
+
renderer.y = startY;
|
224
464
|
};
|
225
465
|
|
@@ -0,0 +1,104 @@
|
|
1
|
+
// abc_tempo_element.js: Definition of the TempoElement class.
|
2
|
+
// Copyright (C) 2014 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
3
|
+
//
|
4
|
+
// This program is free software: you can redistribute it and/or modify
|
5
|
+
// it under the terms of the GNU General Public License as published by
|
6
|
+
// the Free Software Foundation, either version 3 of the License, or
|
7
|
+
// (at your option) any later version.
|
8
|
+
//
|
9
|
+
// This program is distributed in the hope that it will be useful,
|
10
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
// GNU General Public License for more details.
|
13
|
+
//
|
14
|
+
// You should have received a copy of the GNU General Public License
|
15
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
/*globals ABCJS */
|
18
|
+
|
19
|
+
if (!window.ABCJS)
|
20
|
+
window.ABCJS = {};
|
21
|
+
|
22
|
+
if (!window.ABCJS.write)
|
23
|
+
window.ABCJS.write = {};
|
24
|
+
|
25
|
+
(function() {
|
26
|
+
"use strict";
|
27
|
+
var totalHeightInPitches = 5;
|
28
|
+
|
29
|
+
ABCJS.write.TempoElement = function(tempo) {
|
30
|
+
this.tempo = tempo;
|
31
|
+
this.tempoHeightAbove = totalHeightInPitches;
|
32
|
+
this.pitch = undefined; // This will be set later
|
33
|
+
};
|
34
|
+
|
35
|
+
ABCJS.write.TempoElement.prototype.setUpperAndLowerElements = function(positionY) { // TODO-PER: This might not be called.
|
36
|
+
this.pitch = positionY.tempoHeightAbove;
|
37
|
+
};
|
38
|
+
|
39
|
+
ABCJS.write.TempoElement.prototype.setX = function (x) {
|
40
|
+
this.x = x;
|
41
|
+
};
|
42
|
+
|
43
|
+
ABCJS.write.TempoElement.prototype.draw = function(renderer) {
|
44
|
+
var x = this.x;
|
45
|
+
if (this.pitch === undefined)
|
46
|
+
window.console.error("Tempo Element y-coordinate not set.");
|
47
|
+
|
48
|
+
var y = renderer.calcY(this.pitch);
|
49
|
+
var text;
|
50
|
+
if (this.tempo.preString) {
|
51
|
+
text = renderer.renderText(x, y, this.tempo.preString, 'tempofont', 'tempo', "start");
|
52
|
+
var preWidth = text.getBBox().width;
|
53
|
+
var charWidth = preWidth / this.tempo.preString.length; // Just get some average number to increase the spacing.
|
54
|
+
x += preWidth + charWidth;
|
55
|
+
}
|
56
|
+
if (this.tempo.duration) {
|
57
|
+
var temposcale = 0.75;
|
58
|
+
var tempopitch = this.pitch - totalHeightInPitches + 1; // The pitch we receive is the top of the allotted area: change that to practically the bottom.
|
59
|
+
var duration = this.tempo.duration[0]; // TODO when multiple durations
|
60
|
+
var abselem = new ABCJS.write.AbsoluteElement(this.tempo, duration, 1, 'tempo');
|
61
|
+
var durlog = Math.floor(Math.log(duration) / Math.log(2));
|
62
|
+
var dot = 0;
|
63
|
+
for (var tot = Math.pow(2, durlog), inc = tot / 2; tot < duration; dot++, tot += inc, inc /= 2);
|
64
|
+
var c = renderer.engraver.chartable.note[-durlog];
|
65
|
+
var flag = renderer.engraver.chartable.uflags[-durlog];
|
66
|
+
var temponote = renderer.engraver.createNoteHead(abselem, // TODO-PER: This seems late to be creating this element. Shouldn't it happen before draw?
|
67
|
+
c,
|
68
|
+
{verticalPos: tempopitch},
|
69
|
+
"up",
|
70
|
+
0,
|
71
|
+
0,
|
72
|
+
flag,
|
73
|
+
dot,
|
74
|
+
0,
|
75
|
+
temposcale
|
76
|
+
);
|
77
|
+
abselem.addHead(temponote);
|
78
|
+
var stem;
|
79
|
+
if (duration < 1) {
|
80
|
+
var p1 = tempopitch + 1 / 3 * temposcale;
|
81
|
+
var p2 = tempopitch + 7 * temposcale;
|
82
|
+
var dx = temponote.dx + temponote.w;
|
83
|
+
var width = -0.6;
|
84
|
+
stem = new ABCJS.write.RelativeElement(null, dx, 0, p1, {"type": "stem", "pitch2": p2, linewidth: width});
|
85
|
+
stem.setX(x);
|
86
|
+
abselem.addExtra(stem);
|
87
|
+
}
|
88
|
+
abselem.x = x;
|
89
|
+
temponote.setX(x);
|
90
|
+
temponote.draw(renderer, x);
|
91
|
+
if (stem)
|
92
|
+
stem.draw(renderer, x);
|
93
|
+
x += (abselem.w + 5);
|
94
|
+
var str = "= " + this.tempo.bpm;
|
95
|
+
text = renderer.renderText(x, y, str, 'tempofont', 'tempo', "start");
|
96
|
+
var postWidth = text.getBBox().width;
|
97
|
+
var charWidth2 = postWidth / str.length; // Just get some average number to increase the spacing.
|
98
|
+
x += postWidth + charWidth2;
|
99
|
+
}
|
100
|
+
if (this.tempo.postString) {
|
101
|
+
renderer.renderText(x, y, this.tempo.postString, 'tempofont', 'tempo', "start");
|
102
|
+
}
|
103
|
+
};
|
104
|
+
})();
|