abcjs-rails 2.3 → 3.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 +166 -4
- data/app/assets/javascripts/abcjs/api/abc_tunebook.js +170 -15
- data/app/assets/javascripts/abcjs/data/abc_tune.js +69 -47
- data/app/assets/javascripts/abcjs/edit/abc_editor.js +78 -37
- data/app/assets/javascripts/abcjs/midi/abc_midi_controls.js +513 -0
- data/app/assets/javascripts/abcjs/midi/abc_midi_create.js +29 -7
- data/app/assets/javascripts/abcjs/midi/abc_midi_flattener.js +21 -18
- data/app/assets/javascripts/abcjs/midi/abc_midi_js_preparer.js +233 -0
- data/app/assets/javascripts/abcjs/midi/abc_midi_renderer.js +3 -229
- data/app/assets/javascripts/abcjs/midi/abc_midi_sequencer.js +11 -3
- data/app/assets/javascripts/abcjs/parse/abc_common.js +24 -0
- data/app/assets/javascripts/abcjs/parse/abc_parse.js +58 -16
- data/app/assets/javascripts/abcjs/parse/abc_parse_header.js +4 -1
- data/app/assets/javascripts/abcjs/parse/abc_parse_key_voice.js +5 -0
- data/app/assets/javascripts/abcjs/write/abc_absolute_element.js +9 -2
- data/app/assets/javascripts/abcjs/write/abc_abstract_engraver.js +71 -19
- data/app/assets/javascripts/abcjs/write/abc_beam_element.js +11 -3
- data/app/assets/javascripts/abcjs/write/abc_brace_element.js +51 -0
- data/app/assets/javascripts/abcjs/write/abc_create_clef.js +3 -3
- data/app/assets/javascripts/abcjs/write/abc_create_key_signature.js +3 -3
- data/app/assets/javascripts/abcjs/write/abc_create_time_signature.js +3 -3
- data/app/assets/javascripts/abcjs/write/abc_crescendo_element.js +4 -1
- data/app/assets/javascripts/abcjs/write/abc_decoration.js +1 -1
- data/app/assets/javascripts/abcjs/write/abc_engraver_controller.js +10 -9
- data/app/assets/javascripts/abcjs/write/abc_glyphs.js +1 -1
- data/app/assets/javascripts/abcjs/write/abc_relative_element.js +1 -1
- data/app/assets/javascripts/abcjs/write/abc_renderer.js +85 -13
- data/app/assets/javascripts/abcjs/write/abc_staff_group_element.js +16 -0
- data/app/assets/javascripts/abcjs/write/abc_tempo_element.js +31 -11
- data/app/assets/javascripts/abcjs/write/abc_tie_element.js +8 -1
- data/lib/abcjs-rails/version.rb +1 -1
- metadata +6 -3
@@ -53,6 +53,10 @@ if (!window.ABCJS.write)
|
|
53
53
|
this.beams = []; // During the layout phase, this will become a list of the beams that need to be drawn.
|
54
54
|
};
|
55
55
|
|
56
|
+
ABCJS.write.BeamElem.prototype.setHint = function () {
|
57
|
+
this.hint = true;
|
58
|
+
};
|
59
|
+
|
56
60
|
ABCJS.write.BeamElem.prototype.add = function(abselem) {
|
57
61
|
var pitch = abselem.abcelem.averagepitch;
|
58
62
|
if (pitch === undefined) return; // don't include elements like spacers in beams
|
@@ -134,7 +138,7 @@ if (!window.ABCJS.write)
|
|
134
138
|
renderer.beginGroup();
|
135
139
|
for (var i = 0; i < this.beams.length; i++) {
|
136
140
|
var beam = this.beams[i];
|
137
|
-
drawBeam(renderer, beam.startX, beam.startY, beam.endX, beam.endY, beam.dy);
|
141
|
+
drawBeam(renderer, beam.startX, beam.startY, beam.endX, beam.endY, beam.dy, this.hint);
|
138
142
|
}
|
139
143
|
renderer.endGroup('beam-elem');
|
140
144
|
};
|
@@ -169,7 +173,11 @@ if (!window.ABCJS.write)
|
|
169
173
|
return dy;
|
170
174
|
}
|
171
175
|
|
172
|
-
function drawBeam(renderer, startX, startY, endX, endY, dy) {
|
176
|
+
function drawBeam(renderer, startX, startY, endX, endY, dy, isHint) {
|
177
|
+
var klass = 'beam-elem';
|
178
|
+
if (isHint)
|
179
|
+
klass += " abcjs-hint";
|
180
|
+
|
173
181
|
// the X coordinates are actual coordinates, but the Y coordinates are in pitches.
|
174
182
|
startY = renderer.calcY(startY);
|
175
183
|
endY = renderer.calcY(endY);
|
@@ -179,7 +187,7 @@ if (!window.ABCJS.write)
|
|
179
187
|
path: pathString,
|
180
188
|
stroke: "none",
|
181
189
|
fill: "#000000",
|
182
|
-
'class': renderer.addClasses(
|
190
|
+
'class': renderer.addClasses(klass)
|
183
191
|
});
|
184
192
|
}
|
185
193
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
// abc_brace_element.js: Definition of the BraceElement class.
|
2
|
+
// Copyright (C) 2010,2016 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
|
+
|
23
|
+
if (!window.ABCJS.write)
|
24
|
+
window.ABCJS.write = {};
|
25
|
+
|
26
|
+
ABCJS.write.BraceElem = function() {
|
27
|
+
this.length = 1;
|
28
|
+
};
|
29
|
+
|
30
|
+
ABCJS.write.BraceElem.prototype.increaseStavesIncluded = function() {
|
31
|
+
this.length++;
|
32
|
+
};
|
33
|
+
|
34
|
+
ABCJS.write.BraceElem.prototype.setLocation = function(x) {
|
35
|
+
this.x = x;
|
36
|
+
};
|
37
|
+
|
38
|
+
ABCJS.write.BraceElem.prototype.getWidth = function() {
|
39
|
+
return 10; // TODO-PER: right now the drawing function doesn't vary the width at all. If it does in the future then this will change.
|
40
|
+
};
|
41
|
+
|
42
|
+
ABCJS.write.BraceElem.prototype.layout = function (renderer, top, bottom) {
|
43
|
+
this.startY = top;
|
44
|
+
this.endY = bottom;
|
45
|
+
};
|
46
|
+
|
47
|
+
ABCJS.write.BraceElem.prototype.draw = function (renderer, top, bottom) {
|
48
|
+
this.layout(renderer, top, bottom);
|
49
|
+
renderer.drawBrace(this.x,this.startY, this.endY);
|
50
|
+
|
51
|
+
};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// abc_create_clef.js
|
2
|
-
// Copyright (C) 2010,
|
2
|
+
// Copyright (C) 2010,2016 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
3
3
|
//
|
4
4
|
// This program is free software: you can redistribute it and/or modify
|
5
5
|
// it under the terms of the GNU General Public License as published by
|
@@ -25,10 +25,10 @@ if (!window.ABCJS.write)
|
|
25
25
|
(function() {
|
26
26
|
"use strict";
|
27
27
|
|
28
|
-
ABCJS.write.createClef = function(elem) {
|
28
|
+
ABCJS.write.createClef = function(elem, tuneNumber) {
|
29
29
|
var clef;
|
30
30
|
var octave = 0;
|
31
|
-
var abselem = new ABCJS.write.AbsoluteElement(elem,0,10, 'staff-extra');
|
31
|
+
var abselem = new ABCJS.write.AbsoluteElement(elem,0,10, 'staff-extra', tuneNumber);
|
32
32
|
switch (elem.type) {
|
33
33
|
case "treble": clef = "clefs.G"; break;
|
34
34
|
case "tenor": clef="clefs.C"; break;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// abc_create_key_signature.js
|
2
|
-
// Copyright (C) 2010,
|
2
|
+
// Copyright (C) 2010,2016 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
3
3
|
//
|
4
4
|
// This program is free software: you can redistribute it and/or modify
|
5
5
|
// it under the terms of the GNU General Public License as published by
|
@@ -25,10 +25,10 @@ if (!window.ABCJS.write)
|
|
25
25
|
(function() {
|
26
26
|
"use strict";
|
27
27
|
|
28
|
-
ABCJS.write.createKeySignature = function(elem) {
|
28
|
+
ABCJS.write.createKeySignature = function(elem, tuneNumber) {
|
29
29
|
if (!elem.accidentals || elem.accidentals.length === 0)
|
30
30
|
return null;
|
31
|
-
var abselem = new ABCJS.write.AbsoluteElement(elem, 0, 10, 'staff-extra');
|
31
|
+
var abselem = new ABCJS.write.AbsoluteElement(elem, 0, 10, 'staff-extra', tuneNumber);
|
32
32
|
var dx = 0;
|
33
33
|
window.ABCJS.parse.each(elem.accidentals, function(acc) {
|
34
34
|
var symbol = (acc.acc === "sharp") ? "accidentals.sharp" : (acc.acc === "natural") ? "accidentals.nat" : "accidentals.flat";
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// abc_create_time_signature.js
|
2
|
-
// Copyright (C) 2010,
|
2
|
+
// Copyright (C) 2010,2016 Gregory Dyke (gregdyke at gmail dot com) and Paul Rosen
|
3
3
|
//
|
4
4
|
// This program is free software: you can redistribute it and/or modify
|
5
5
|
// it under the terms of the GNU General Public License as published by
|
@@ -25,8 +25,8 @@ if (!window.ABCJS.write)
|
|
25
25
|
(function() {
|
26
26
|
"use strict";
|
27
27
|
|
28
|
-
ABCJS.write.createTimeSignature = function(elem) {
|
29
|
-
var abselem = new ABCJS.write.AbsoluteElement(elem,0,10, 'staff-extra');
|
28
|
+
ABCJS.write.createTimeSignature = function(elem, tuneNumber) {
|
29
|
+
var abselem = new ABCJS.write.AbsoluteElement(elem,0,10, 'staff-extra', tuneNumber);
|
30
30
|
if (elem.type === "specified") {
|
31
31
|
//TODO make the alignment for time signatures centered
|
32
32
|
for (var i = 0; i < elem.value.length; i++) {
|
@@ -55,7 +55,10 @@ ABCJS.write.CrescendoElem.prototype.draw = function (renderer) {
|
|
55
55
|
};
|
56
56
|
|
57
57
|
ABCJS.write.CrescendoElem.prototype.drawLine = function (renderer, y1, y2) {
|
58
|
+
// TODO-PER: This is just a quick hack to make the dynamic marks not crash if they are mismatched. See the slur treatment for the way to get the beginning and end.
|
59
|
+
var left = this.anchor1 ? this.anchor1.x : 0;
|
60
|
+
var right = this.anchor2 ? this.anchor2.x : 800;
|
58
61
|
var pathString = ABCJS.write.sprintf("M %f %f L %f %f",
|
59
|
-
|
62
|
+
left, y1, right, y2);
|
60
63
|
renderer.printPath({path:pathString, stroke:"#000000", 'class': renderer.addClasses('decoration')});
|
61
64
|
};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// abc_decoration.js: Creates a data structure suitable for printing a line of abc
|
2
|
-
// Copyright (C) 2010-
|
2
|
+
// Copyright (C) 2010-2016 Gregory Dyke (gregdyke at gmail dot com) & Paul Rosen
|
3
3
|
//
|
4
4
|
// This program is free software: you can redistribute it and/or modify
|
5
5
|
// it under the terms of the GNU General Public License as published by
|
@@ -71,6 +71,7 @@ ABCJS.write.EngraverController = function(paper, params) {
|
|
71
71
|
if (this.usingSvg && params.add_classes)
|
72
72
|
Raphael._availableAttrs['class'] = "";
|
73
73
|
Raphael._availableAttrs['text-decoration'] = "";
|
74
|
+
Raphael._availableAttrs['data-vertical'] = "";
|
74
75
|
|
75
76
|
//TODO-GD factor out all calls directly made to renderer.paper and fix all the coupling issues below
|
76
77
|
this.renderer=new ABCJS.write.Renderer(paper, params.regression);
|
@@ -102,7 +103,7 @@ ABCJS.write.EngraverController.prototype.engraveABC = function(abctunes) {
|
|
102
103
|
this.reset();
|
103
104
|
|
104
105
|
for (var i = 0; i < abctunes.length; i++) {
|
105
|
-
this.engraveTune(abctunes[i]);
|
106
|
+
this.engraveTune(abctunes[i], i);
|
106
107
|
}
|
107
108
|
if (this.renderer.doRegression)
|
108
109
|
return this.renderer.regressionLines.join("\n");
|
@@ -121,24 +122,24 @@ ABCJS.write.EngraverController.prototype.adjustNonScaledItems = function (scale)
|
|
121
122
|
* Run the engraving process on a single tune
|
122
123
|
* @param {ABCJS.Tune} abctune
|
123
124
|
*/
|
124
|
-
ABCJS.write.EngraverController.prototype.engraveTune = function (abctune) {
|
125
|
+
ABCJS.write.EngraverController.prototype.engraveTune = function (abctune, tuneNumber) {
|
125
126
|
this.renderer.lineNumber = null;
|
126
127
|
abctune.formatting.tripletfont = {face: "Times", size: 11, weight: "normal", style: "italic", decoration: "none"}; // TODO-PER: This font isn't defined in the standard, so it's hardcoded here for now.
|
127
128
|
|
128
129
|
this.renderer.abctune = abctune; // TODO-PER: this is just to get the font info.
|
129
130
|
this.renderer.setVerticalSpace(abctune.formatting);
|
130
131
|
this.renderer.measureNumber = null;
|
131
|
-
var scale = abctune.formatting.scale ? abctune.formatting.scale : this.scale;
|
132
|
-
if (scale === undefined) scale = abctune.media === 'print' ? 0.75 : 1;
|
133
132
|
this.renderer.setPrintMode(abctune.media === 'print');
|
133
|
+
var scale = abctune.formatting.scale ? abctune.formatting.scale : this.scale;
|
134
|
+
if (scale === undefined) scale = this.renderer.isPrint ? 0.75 : 1;
|
134
135
|
this.renderer.setPadding(abctune);
|
135
|
-
this.engraver = new ABCJS.write.AbstractEngraver(abctune.formatting.bagpipes,this.renderer);
|
136
|
+
this.engraver = new ABCJS.write.AbstractEngraver(abctune.formatting.bagpipes,this.renderer, tuneNumber);
|
136
137
|
this.engraver.setStemHeight(this.renderer.spacing.stemHeight);
|
137
138
|
this.renderer.engraver = this.engraver; //TODO-PER: do we need this coupling? It's just used for the tempo
|
138
139
|
if (abctune.formatting.staffwidth) {
|
139
140
|
this.width = abctune.formatting.staffwidth * 1.33; // The width is expressed in pt; convert to px.
|
140
141
|
} else {
|
141
|
-
this.width =
|
142
|
+
this.width = this.renderer.isPrint ? this.staffwidthPrint : this.staffwidthScreen;
|
142
143
|
}
|
143
144
|
this.adjustNonScaledItems(scale);
|
144
145
|
|
@@ -198,7 +199,7 @@ ABCJS.write.EngraverController.prototype.engraveTune = function (abctune) {
|
|
198
199
|
this.engraveStaffLine(abcLine.staffGroup);
|
199
200
|
} else if (abcLine.subtitle && line !== 0) {
|
200
201
|
this.renderer.outputSubtitle(this.width, abcLine.subtitle);
|
201
|
-
} else if (abcLine.text) {
|
202
|
+
} else if (abcLine.text !== undefined) {
|
202
203
|
this.renderer.outputFreeText(abcLine.text);
|
203
204
|
}
|
204
205
|
}
|
@@ -266,7 +267,7 @@ ABCJS.write.EngraverController.prototype.engraveStaffLine = function (staffGroup
|
|
266
267
|
* Called by the Abstract Engraving Structure or any other (e.g. midi playback) to say it was selected (notehead clicked on)
|
267
268
|
* @protected
|
268
269
|
*/
|
269
|
-
ABCJS.write.EngraverController.prototype.notifySelect = function (abselem) {
|
270
|
+
ABCJS.write.EngraverController.prototype.notifySelect = function (abselem, tuneNumber) {
|
270
271
|
this.clearSelection();
|
271
272
|
if (abselem.highlight) {
|
272
273
|
this.selected = [abselem];
|
@@ -275,7 +276,7 @@ ABCJS.write.EngraverController.prototype.notifySelect = function (abselem) {
|
|
275
276
|
var abcelem = abselem.abcelem || {};
|
276
277
|
for (var i=0; i<this.listeners.length;i++) {
|
277
278
|
if (this.listeners[i].highlight)
|
278
|
-
this.listeners[i].highlight(abcelem);
|
279
|
+
this.listeners[i].highlight(abcelem, tuneNumber);
|
279
280
|
}
|
280
281
|
};
|
281
282
|
|
@@ -84,7 +84,7 @@ ABCJS.write.Glyphs = function() {
|
|
84
84
|
'r':{d:[['M',6.33,-9.12],['c',0.27,-0.03,0.93,0.00,1.20,0.06],['c',0.84,0.21,1.23,0.81,1.02,1.53],['c',-0.24,0.75,-0.90,1.17,-1.56,0.96],['c',-0.33,-0.09,-0.51,-0.30,-0.66,-0.75],['c',-0.03,-0.12,-0.09,-0.24,-0.12,-0.30],['c',-0.09,-0.15,-0.30,-0.24,-0.48,-0.24],['c',-0.57,0.00,-1.38,0.54,-1.65,1.08],['c',-0.06,0.15,-0.33,1.17,-0.90,3.27],['c',-0.57,2.31,-0.81,3.12,-0.87,3.21],['c',-0.03,0.06,-0.12,0.15,-0.18,0.21],['l',-0.12,0.06],['l',-0.81,0.03],['c',-0.69,0.00,-0.81,0.00,-0.90,-0.03],['c',-0.09,-0.06,-0.18,-0.21,-0.18,-0.30],['c',0.00,-0.06,0.39,-1.62,0.90,-3.51],['c',0.84,-3.24,0.87,-3.45,0.87,-3.72],['c',0.00,-0.21,0.00,-0.27,-0.03,-0.36],['c',-0.12,-0.15,-0.21,-0.24,-0.42,-0.24],['c',-0.24,0.00,-0.45,0.15,-0.78,0.42],['c',-0.33,0.36,-0.45,0.54,-0.72,1.14],['c',-0.03,0.12,-0.21,0.24,-0.36,0.27],['c',-0.12,0.00,-0.15,0.00,-0.24,-0.06],['c',-0.18,-0.12,-0.18,-0.21,-0.06,-0.54],['c',0.21,-0.57,0.42,-0.93,0.78,-1.32],['c',0.54,-0.51,1.20,-0.81,1.95,-0.87],['c',0.81,-0.03,1.53,0.30,1.92,0.87],['l',0.12,0.18],['l',0.09,-0.09],['c',0.57,-0.45,1.41,-0.84,2.19,-0.96],['z']],w:9.41,h:9.132},
|
85
85
|
's':{d:[['M',4.47,-8.73],['c',0.09,0.00,0.36,-0.03,0.57,-0.03],['c',0.75,0.03,1.29,0.24,1.71,0.63],['c',0.51,0.54,0.66,1.26,0.36,1.83],['c',-0.24,0.42,-0.63,0.57,-1.11,0.42],['c',-0.33,-0.09,-0.60,-0.36,-0.60,-0.57],['c',0.00,-0.03,0.06,-0.21,0.15,-0.39],['c',0.12,-0.21,0.15,-0.33,0.18,-0.48],['c',0.00,-0.24,-0.06,-0.48,-0.15,-0.60],['c',-0.15,-0.21,-0.42,-0.24,-0.75,-0.15],['c',-0.27,0.06,-0.48,0.18,-0.69,0.36],['c',-0.39,0.39,-0.51,0.96,-0.33,1.38],['c',0.09,0.21,0.42,0.51,0.78,0.72],['c',1.11,0.69,1.59,1.11,1.89,1.68],['c',0.21,0.39,0.24,0.78,0.15,1.29],['c',-0.18,1.20,-1.17,2.16,-2.52,2.52],['c',-1.02,0.24,-1.95,0.12,-2.70,-0.42],['c',-0.72,-0.51,-0.99,-1.47,-0.60,-2.19],['c',0.24,-0.48,0.72,-0.63,1.17,-0.42],['c',0.33,0.18,0.54,0.45,0.57,0.81],['c',0.00,0.21,-0.03,0.30,-0.33,0.51],['c',-0.33,0.24,-0.39,0.42,-0.27,0.69],['c',0.06,0.15,0.21,0.27,0.45,0.33],['c',0.30,0.09,0.87,0.09,1.20,0.00],['c',0.75,-0.21,1.23,-0.72,1.29,-1.35],['c',0.03,-0.42,-0.15,-0.81,-0.54,-1.20],['c',-0.24,-0.24,-0.48,-0.42,-1.41,-1.02],['c',-0.69,-0.42,-1.05,-0.93,-1.05,-1.47],['c',0.00,-0.39,0.12,-0.87,0.30,-1.23],['c',0.27,-0.57,0.78,-1.05,1.38,-1.35],['c',0.24,-0.12,0.63,-0.27,0.90,-0.30],['z']],w:6.632,h:8.758},
|
86
86
|
'z':{d:[['M',2.64,-7.95],['c',0.36,-0.09,0.81,-0.03,1.71,0.27],['c',0.78,0.21,0.96,0.27,1.74,0.30],['c',0.87,0.06,1.02,0.03,1.38,-0.21],['c',0.21,-0.15,0.33,-0.15,0.48,-0.06],['c',0.15,0.09,0.21,0.30,0.15,0.45],['c',-0.03,0.06,-1.26,1.26,-2.76,2.67],['l',-2.73,2.55],['l',0.54,0.03],['c',0.54,0.03,0.72,0.03,2.01,0.15],['c',0.36,0.03,0.90,0.06,1.20,0.09],['c',0.66,0.00,0.81,-0.03,1.02,-0.24],['c',0.30,-0.30,0.39,-0.72,0.27,-1.23],['c',-0.06,-0.27,-0.06,-0.27,-0.03,-0.39],['c',0.15,-0.30,0.54,-0.27,0.69,0.03],['c',0.15,0.33,0.27,1.02,0.27,1.50],['c',0.00,1.47,-1.11,2.70,-2.52,2.79],['c',-0.57,0.03,-1.02,-0.09,-2.01,-0.51],['c',-1.02,-0.42,-1.23,-0.48,-2.13,-0.54],['c',-0.81,-0.06,-0.96,-0.03,-1.26,0.18],['c',-0.12,0.06,-0.24,0.12,-0.27,0.12],['c',-0.27,0.00,-0.45,-0.30,-0.36,-0.51],['c',0.03,-0.06,1.32,-1.32,2.91,-2.79],['l',2.88,-2.73],['c',-0.03,0.00,-0.21,0.03,-0.42,0.06],['c',-0.21,0.03,-0.78,0.09,-1.23,0.12],['c',-1.11,0.12,-1.23,0.15,-1.95,0.27],['c',-0.72,0.15,-1.17,0.18,-1.29,0.09],['c',-0.27,-0.18,-0.21,-0.75,0.12,-1.26],['c',0.39,-0.60,0.93,-1.02,1.59,-1.20],['z']],w:8.573,h:8.743},
|
87
|
-
'+':{d:[['M',3.48,-
|
87
|
+
'+':{d:[['M',3.48,-9.3],['c',0.18,-0.09,0.36,-0.09,0.54,0.00],['c',0.18,0.09,0.24,0.15,0.33,0.30],['l',0.06,0.15],['l',0.00,1.29],['l',0.00,1.29],['l',1.29,0.00],['c',1.23,0.00,1.29,0.00,1.41,0.06],['c',0.06,0.03,0.15,0.09,0.18,0.12],['c',0.12,0.09,0.21,0.33,0.21,0.48],['c',0.00,0.15,-0.09,0.39,-0.21,0.48],['c',-0.03,0.03,-0.12,0.09,-0.18,0.12],['c',-0.12,0.06,-0.18,0.06,-1.41,0.06],['l',-1.29,0.00],['l',0.00,1.29],['c',0.00,1.23,0.00,1.29,-0.06,1.41],['c',-0.09,0.18,-0.15,0.24,-0.30,0.33],['c',-0.21,0.09,-0.39,0.09,-0.57,0.00],['c',-0.18,-0.09,-0.24,-0.15,-0.33,-0.33],['c',-0.06,-0.12,-0.06,-0.18,-0.06,-1.41],['l',0.00,-1.29],['l',-1.29,0.00],['c',-1.23,0.00,-1.29,0.00,-1.41,-0.06],['c',-0.18,-0.09,-0.24,-0.15,-0.33,-0.33],['c',-0.09,-0.18,-0.09,-0.36,0.00,-0.54],['c',0.09,-0.18,0.15,-0.24,0.33,-0.33],['l',0.15,-0.06],['l',1.26,0.00],['l',1.29,0.00],['l',0.00,-1.29],['c',0.00,-1.23,0.00,-1.29,0.06,-1.41],['c',0.09,-0.18,0.15,-0.24,0.33,-0.33],['z']],w:7.507,h:7.515},
|
88
88
|
',':{d:[['M',1.32,-3.36],['c',0.57,-0.15,1.17,0.03,1.59,0.45],['c',0.45,0.45,0.60,0.96,0.51,1.89],['c',-0.09,1.23,-0.42,2.46,-0.99,3.93],['c',-0.30,0.72,-0.72,1.62,-0.78,1.68],['c',-0.18,0.21,-0.51,0.18,-0.66,-0.06],['c',-0.03,-0.06,-0.06,-0.15,-0.06,-0.18],['c',0.00,-0.06,0.12,-0.33,0.24,-0.63],['c',0.84,-1.80,1.02,-2.61,0.69,-3.24],['c',-0.12,-0.24,-0.27,-0.36,-0.75,-0.60],['c',-0.36,-0.15,-0.42,-0.21,-0.60,-0.39],['c',-0.69,-0.69,-0.69,-1.71,0.00,-2.40],['c',0.21,-0.21,0.51,-0.39,0.81,-0.45],['z']],w:3.452,h:8.143},
|
89
89
|
'-':{d:[['M',0.18,-5.34],['c',0.09,-0.06,0.15,-0.06,2.31,-0.06],['c',2.46,0.00,2.37,0.00,2.46,0.21],['c',0.12,0.21,0.03,0.42,-0.15,0.54],['c',-0.09,0.06,-0.15,0.06,-2.28,0.06],['c',-2.16,0.00,-2.22,0.00,-2.31,-0.06],['c',-0.27,-0.15,-0.27,-0.54,-0.03,-0.69],['z']],w:5.001,h:0.81},
|
90
90
|
'.':{d:[['M',1.32,-3.36],['c',1.05,-0.27,2.10,0.57,2.10,1.65],['c',0.00,1.08,-1.05,1.92,-2.10,1.65],['c',-0.90,-0.21,-1.50,-1.14,-1.26,-2.04],['c',0.12,-0.63,0.63,-1.11,1.26,-1.26],['z']],w:3.413,h:3.402},
|
@@ -102,7 +102,7 @@ ABCJS.write.RelativeElement.prototype.draw = function (renderer, bartop) {
|
|
102
102
|
case "debug":
|
103
103
|
this.graphelem = renderer.renderText(this.x, renderer.calcY(15), ""+this.c, "debugfont", 'debug-msg', 'start'); break;
|
104
104
|
case "barNumber":
|
105
|
-
this.graphelem = renderer.renderText(this.x, y, ""+this.c, "measurefont", 'bar-number', "
|
105
|
+
this.graphelem = renderer.renderText(this.x, y, ""+this.c, "measurefont", 'bar-number', "middle");
|
106
106
|
break;
|
107
107
|
case "lyric":
|
108
108
|
this.graphelem = renderer.renderText(this.x, y, this.c, "vocalfont", 'abc-lyric', "middle");
|
@@ -130,7 +130,7 @@ ABCJS.write.Renderer.prototype.setPadding = function(abctune) {
|
|
130
130
|
self.padding[paddingKey] = abctune.formatting[formattingKey];
|
131
131
|
else if (self.paddingOverride[paddingKey] !== undefined)
|
132
132
|
self.padding[paddingKey] = self.paddingOverride[paddingKey];
|
133
|
-
else if (
|
133
|
+
else if (self.isPrint)
|
134
134
|
self.padding[paddingKey] = printDefault;
|
135
135
|
else
|
136
136
|
self.padding[paddingKey] = screenDefault;
|
@@ -138,7 +138,7 @@ ABCJS.write.Renderer.prototype.setPadding = function(abctune) {
|
|
138
138
|
// 1cm x 0.393701in/cm x 72pt/in x 1.33px/pt = 38px
|
139
139
|
// 1.8cm x 0.393701in/cm x 72pt/in x 1.33px/pt = 68px
|
140
140
|
setPaddingVariable(this, 'top', 'topmargin', 38, 15);
|
141
|
-
setPaddingVariable(this, 'bottom', '
|
141
|
+
setPaddingVariable(this, 'bottom', 'botmargin', 38, 15);
|
142
142
|
setPaddingVariable(this, 'left', 'leftmargin', 68, 15);
|
143
143
|
setPaddingVariable(this, 'right', 'rightmargin', 68, 15);
|
144
144
|
};
|
@@ -367,14 +367,24 @@ ABCJS.write.Renderer.prototype.engraveExtraText = function(width, abctune) {
|
|
367
367
|
* @param {array or string} text
|
368
368
|
*/
|
369
369
|
ABCJS.write.Renderer.prototype.outputFreeText = function (text) {
|
370
|
-
if (
|
370
|
+
if (text === "") { // we do want to print out blank lines if they have been specified.
|
371
|
+
var hash = this.getFontAndAttr('textfont', 'defined-text');
|
372
|
+
this.moveY(hash.attr['font-size'] * 2); // move the distance of the line, plus the distance of the margin, which is also one line.
|
373
|
+
} else if (typeof text === 'string')
|
371
374
|
this.outputTextIf(this.padding.left, text, 'textfont', 'defined-text', 0, 1, "start");
|
372
375
|
else {
|
373
376
|
var str = "";
|
377
|
+
var isCentered = false; // The structure is wrong here: it requires an array to do centering, but it shouldn't have.
|
374
378
|
for (var i = 0; i < text.length; i++) {
|
375
|
-
|
379
|
+
if (text[i].font)
|
380
|
+
str += "FONT(" + text[i].font + ")";
|
381
|
+
str += text[i].text;
|
382
|
+
if (text[i].center)
|
383
|
+
isCentered = true;
|
376
384
|
}
|
377
|
-
|
385
|
+
var alignment = isCentered ? 'middle' : 'start';
|
386
|
+
var x = isCentered ? this.controller.width / 2 : this.padding.left;
|
387
|
+
this.outputTextIf(x, str, 'textfont', 'defined-text', 0, 1, alignment);
|
378
388
|
}
|
379
389
|
};
|
380
390
|
|
@@ -548,7 +558,43 @@ ABCJS.write.Renderer.prototype.printPath = function (attrs) {
|
|
548
558
|
return ret;
|
549
559
|
};
|
550
560
|
|
551
|
-
ABCJS.write.Renderer.prototype.
|
561
|
+
ABCJS.write.Renderer.prototype.drawBrace = function(xLeft, yTop, yBottom) {//Tony
|
562
|
+
var yHeight = yBottom - yTop;
|
563
|
+
|
564
|
+
var xCurve = [7.5, -8, 21, 0, 18.5, -10.5, 7.5];
|
565
|
+
var yCurve = [0, yHeight/5.5, yHeight/3.14, yHeight/2, yHeight/2.93, yHeight/4.88, 0];
|
566
|
+
|
567
|
+
var pathString = ABCJS.write.sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z",
|
568
|
+
xLeft+xCurve[0], yTop+yCurve[0],
|
569
|
+
xLeft+xCurve[1], yTop+yCurve[1],
|
570
|
+
xLeft+xCurve[2], yTop+yCurve[2],
|
571
|
+
xLeft+xCurve[3], yTop+yCurve[3],
|
572
|
+
xLeft+xCurve[4], yTop+yCurve[4],
|
573
|
+
xLeft+xCurve[5], yTop+yCurve[5],
|
574
|
+
xLeft+xCurve[6], yTop+yCurve[6]);
|
575
|
+
var ret1 = this.paper.path().attr({path:pathString, stroke:"#000000", fill:"#000000", 'class': this.addClasses('brace')});
|
576
|
+
|
577
|
+
xCurve = [0, 17.5, -7.5, 6.6, -5, 20, 0];
|
578
|
+
yCurve = [yHeight/2, yHeight/1.46, yHeight/1.22, yHeight, yHeight/1.19, yHeight/1.42, yHeight/2];
|
579
|
+
|
580
|
+
pathString = ABCJS.write.sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z",
|
581
|
+
xLeft+xCurve[ 0], yTop+yCurve[0],
|
582
|
+
xLeft+xCurve[1], yTop+yCurve[1],
|
583
|
+
xLeft+xCurve[2], yTop+yCurve[2],
|
584
|
+
xLeft+xCurve[3], yTop+yCurve[3],
|
585
|
+
xLeft+xCurve[4], yTop+yCurve[4],
|
586
|
+
xLeft+xCurve[5], yTop+yCurve[5],
|
587
|
+
xLeft+xCurve[6], yTop+yCurve[6]);
|
588
|
+
var ret2 = this.paper.path().attr({path:pathString, stroke:"#000000", fill:"#000000", 'class': this.addClasses('brace')});
|
589
|
+
|
590
|
+
if (this.doRegression){
|
591
|
+
this.addToRegression(ret1);
|
592
|
+
this.addToRegression(ret2);
|
593
|
+
}
|
594
|
+
return ret1 + ret2;
|
595
|
+
};
|
596
|
+
|
597
|
+
ABCJS.write.Renderer.prototype.drawArc = function(x1, x2, pitch1, pitch2, above, klass) {
|
552
598
|
|
553
599
|
|
554
600
|
x1 = x1 + 6;
|
@@ -576,7 +622,11 @@ ABCJS.write.Renderer.prototype.drawArc = function(x1, x2, pitch1, pitch2, above)
|
|
576
622
|
var pathString = ABCJS.write.sprintf("M %f %f C %f %f %f %f %f %f C %f %f %f %f %f %f z", x1, y1,
|
577
623
|
controlx1, controly1, controlx2, controly2, x2, y2,
|
578
624
|
controlx2-thickness*uy, controly2+thickness*ux, controlx1-thickness*uy, controly1+thickness*ux, x1, y1);
|
579
|
-
|
625
|
+
if (klass)
|
626
|
+
klass += ' slur';
|
627
|
+
else
|
628
|
+
klass = 'slur';
|
629
|
+
var ret = this.paper.path().attr({path:pathString, stroke:"none", fill:"#000000", 'class': this.addClasses(klass)});
|
580
630
|
if (this.doRegression) this.addToRegression(ret);
|
581
631
|
|
582
632
|
return ret;
|
@@ -622,7 +672,7 @@ ABCJS.write.Renderer.prototype.getFontAndAttr = function(type, klass) {
|
|
622
672
|
var font = this.abctune.formatting[type];
|
623
673
|
// Raphael deliberately changes the font units to pixels for some reason, so we need to change points to pixels here.
|
624
674
|
if (font)
|
625
|
-
font = { face: font.face, size: font.size*4/3, decoration: font.decoration, style: font.style, weight: font.weight };
|
675
|
+
font = { face: font.face, size: font.size*4/3, decoration: font.decoration, style: font.style, weight: font.weight, box: font.box };
|
626
676
|
else
|
627
677
|
font = { face: "Arial", size: 12*4/3, decoration: "underline", style: "normal", weight: "normal" };
|
628
678
|
|
@@ -637,6 +687,8 @@ ABCJS.write.Renderer.prototype.getTextSize = function(text, type, klass) {
|
|
637
687
|
var hash = this.getFontAndAttr(type, klass);
|
638
688
|
var el = this.paper.text(0,0, text).attr(hash.attr);
|
639
689
|
var size = el.getBBox();
|
690
|
+
if (isNaN(size.height)) // This can happen if the element isn't visible.
|
691
|
+
size = { width: 0, height: 0};
|
640
692
|
el.remove();
|
641
693
|
return size;
|
642
694
|
};
|
@@ -651,9 +703,13 @@ ABCJS.write.Renderer.prototype.renderText = function(x, y, text, type, klass, an
|
|
651
703
|
// The text will be placed centered in vertical alignment, so we need to move the box down so that
|
652
704
|
// the top of the text is where we've requested.
|
653
705
|
var size = el.getBBox();
|
654
|
-
|
655
|
-
|
656
|
-
|
706
|
+
if (isNaN(size.height)) // This can happen if the element is hidden.
|
707
|
+
el.attr({ "y": y });
|
708
|
+
else {
|
709
|
+
el.attr({"y": y + size.height / 2});
|
710
|
+
if (hash.font.box) {
|
711
|
+
this.paper.rect(size.x - 1, size.y + size.height / 2 - 1, size.width + 2, size.height + 2).attr({"stroke": "#888888"});
|
712
|
+
}
|
657
713
|
}
|
658
714
|
}
|
659
715
|
if (type === 'debugfont') {
|
@@ -681,15 +737,31 @@ ABCJS.write.Renderer.prototype.outputTextIf = function(x, str, kind, klass, marg
|
|
681
737
|
if (marginTop)
|
682
738
|
this.moveY(marginTop);
|
683
739
|
var el = this.renderText(x, this.y, str, kind, klass, alignment);
|
740
|
+
var bb = el.getBBox(); // This can return NaN if the element isn't visible.
|
741
|
+
var width = isNaN(bb.width) ? 0 : bb.width;
|
742
|
+
var height = isNaN(bb.height) ? 0 : bb.height;
|
684
743
|
if (marginBottom !== null) {
|
685
744
|
var numLines = str.split("\n").length;
|
686
|
-
|
745
|
+
if (!isNaN(bb.height))
|
746
|
+
this.moveY(height/numLines, (numLines + marginBottom));
|
687
747
|
}
|
688
|
-
return [
|
748
|
+
return [width, height];
|
689
749
|
}
|
690
750
|
return [0,0];
|
691
751
|
};
|
692
752
|
|
753
|
+
ABCJS.write.Renderer.prototype.addInvisibleMarker = function (className) {
|
754
|
+
var dy = 0.35;
|
755
|
+
var fill = "rgba(0,0,0,0)";
|
756
|
+
var y = this.y;
|
757
|
+
y = Math.round(y);
|
758
|
+
var x1 = 0;
|
759
|
+
var x2 = 100;
|
760
|
+
var pathString = ABCJS.write.sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y-dy, x1+x2, y-dy,
|
761
|
+
x2, y+dy, x1, y+dy);
|
762
|
+
this.paper.path().attr({path:pathString, stroke:"none", fill:fill, 'class': this.addClasses(className), 'data-vertical': y }).toBack();
|
763
|
+
};
|
764
|
+
|
693
765
|
// For debugging, it is sometimes useful to know where you are vertically.
|
694
766
|
ABCJS.write.Renderer.prototype.printHorizontalLine = function (width, vertical, comment) {
|
695
767
|
var dy = 0.35;
|
@@ -52,6 +52,7 @@ if (!window.ABCJS.write)
|
|
52
52
|
ABCJS.write.StaffGroupElement = function() {
|
53
53
|
this.voices = [];
|
54
54
|
this.staffs = [];
|
55
|
+
this.brace = undefined; //tony
|
55
56
|
};
|
56
57
|
|
57
58
|
ABCJS.write.StaffGroupElement.prototype.setLimit = function(member, voice) {
|
@@ -217,6 +218,11 @@ ABCJS.write.StaffGroupElement.prototype.layout = function(spacing, renderer, deb
|
|
217
218
|
}
|
218
219
|
x=x+voiceheaderw*1.1; // When there is no voice header, 110% of 0 is 0
|
219
220
|
this.startx=x;
|
221
|
+
if (this.brace) {
|
222
|
+
this.brace.setLocation(this.startx);
|
223
|
+
x += this.brace.getWidth();
|
224
|
+
this.startx = x;
|
225
|
+
}
|
220
226
|
|
221
227
|
var currentduration = 0;
|
222
228
|
if (debug) console.log("init layout");
|
@@ -342,6 +348,9 @@ ABCJS.write.StaffGroupElement.prototype.draw = function (renderer) {
|
|
342
348
|
};
|
343
349
|
}
|
344
350
|
|
351
|
+
// An invisible marker is useful to be able to find where each system starts.
|
352
|
+
renderer.addInvisibleMarker("abcjs-top-of-system");
|
353
|
+
|
345
354
|
var startY = renderer.y; // So that it can be restored after we're done.
|
346
355
|
// Set the absolute Y position for each staff here, so the voice drawing below can just use if.
|
347
356
|
for (var j = 0; j < this.staffs.length; j++) {
|
@@ -391,6 +400,13 @@ ABCJS.write.StaffGroupElement.prototype.draw = function (renderer) {
|
|
391
400
|
// if (staff.bottom < 0)
|
392
401
|
// renderer.moveY(ABCJS.write.spacing.STEP, -staff.bottom);
|
393
402
|
}
|
403
|
+
if(this.brace) {//Tony
|
404
|
+
if (i === this.brace.length - 1) {
|
405
|
+
if (this.brace) {
|
406
|
+
this.brace.draw(renderer, topLine, bottomLine); //tony
|
407
|
+
}
|
408
|
+
}
|
409
|
+
}
|
394
410
|
}
|
395
411
|
renderer.measureNumber = null;
|
396
412
|
|