abcjs-rails 2.0 → 2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/abcjs/api/abc_animation.js +0 -19
  3. data/app/assets/javascripts/abcjs/api/abc_tunebook.js +0 -5
  4. data/app/assets/javascripts/abcjs/edit/abc_editor.js +0 -10
  5. data/app/assets/javascripts/abcjs/parse/abc_parse.js +11 -35
  6. data/app/assets/javascripts/abcjs/parse/abc_parse_directive.js +2 -18
  7. data/app/assets/javascripts/abcjs/write/abc_absolute_element.js +9 -25
  8. data/app/assets/javascripts/abcjs/write/abc_abstract_engraver.js +21 -16
  9. data/app/assets/javascripts/abcjs/write/abc_beam_element.js +5 -94
  10. data/app/assets/javascripts/abcjs/write/abc_crescendo_element.js +0 -16
  11. data/app/assets/javascripts/abcjs/write/abc_decoration.js +3 -2
  12. data/app/assets/javascripts/abcjs/write/abc_dynamic_decoration.js +0 -8
  13. data/app/assets/javascripts/abcjs/write/abc_ending_element.js +0 -20
  14. data/app/assets/javascripts/abcjs/write/abc_engraver_controller.js +1 -1
  15. data/app/assets/javascripts/abcjs/write/abc_relative_element.js +9 -46
  16. data/app/assets/javascripts/abcjs/write/abc_renderer.js +1 -1
  17. data/app/assets/javascripts/abcjs/write/abc_staff_group_element.js +4 -67
  18. data/app/assets/javascripts/abcjs/write/abc_tie_element.js +0 -24
  19. data/app/assets/javascripts/abcjs/write/abc_triplet_element.js +0 -54
  20. data/app/assets/javascripts/abcjs/write/abc_voice_element.js +24 -13
  21. data/lib/abcjs-rails/version.rb +1 -1
  22. metadata +2 -4
  23. data/app/assets/javascripts/abcjs/write/abc_layout.js +0 -1040
  24. data/app/assets/javascripts/abcjs/write/abc_write.js +0 -535
@@ -1,535 +0,0 @@
1
- // abc_write.js: Prints an abc file parsed by abc_parse.js
2
- // Copyright (C) 2010 Gregory Dyke (gregdyke at gmail dot com)
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
-
18
- /*global window, ABCJS, Math, Raphael */
19
-
20
- if (!window.ABCJS)
21
- window.ABCJS = {};
22
-
23
- if (!window.ABCJS.write)
24
- window.ABCJS.write = {};
25
-
26
- ABCJS.write.spacing = function() {};
27
- ABCJS.write.spacing.FONTEM = 360;
28
- ABCJS.write.spacing.FONTSIZE = 30;
29
- ABCJS.write.spacing.STEP = ABCJS.write.spacing.FONTSIZE*93/720;
30
- ABCJS.write.spacing.SPACE = 10;
31
- ABCJS.write.spacing.TOPNOTE = 20;
32
- ABCJS.write.spacing.STAVEHEIGHT = 100;
33
-
34
-
35
- //--------------------------------------------------------------------PRINTER
36
-
37
- ABCJS.write.Printer = function(paper, params) {
38
- params = params || {};
39
- this.y = 0;
40
- this.paper = paper;
41
- this.space = 3*ABCJS.write.spacing.SPACE;
42
- this.glyphs = new ABCJS.write.Glyphs();
43
- this.listeners = [];
44
- this.selected = [];
45
- this.ingroup = false;
46
- this.scale = params.scale || 1;
47
- this.staffwidth = params.staffwidth || 740;
48
- this.paddingtop = params.paddingtop || 15;
49
- this.paddingbottom = params.paddingbottom || 30;
50
- this.paddingright = params.paddingright || 50;
51
- this.paddingleft = params.paddingleft || 15;
52
- this.editable = params.editable || false;
53
- // HACK-PER: Raphael doesn't support setting the class of an element, so this adds that support. This doesn't work on IE8 or less, though.
54
- this.usingSvg = (window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? true : false); // Same test Raphael uses
55
- if (this.usingSvg && params.add_classes)
56
- Raphael._availableAttrs['class'] = "";
57
- Raphael._availableAttrs['text-decoration'] = "";
58
- };
59
-
60
- ABCJS.write.Printer.prototype.addClasses = function (c) {
61
- var ret = [];
62
- if (c.length > 0) ret.push(c);
63
- if (this.lineNumber !== null) ret.push("l"+this.lineNumber);
64
- if (this.measureNumber !== null) ret.push("m"+this.measureNumber);
65
- return ret.join(' ');
66
- };
67
-
68
- // notify all listeners that a graphical element has been selected
69
- ABCJS.write.Printer.prototype.notifySelect = function (abselem) {
70
- this.clearSelection();
71
- this.selected = [abselem];
72
- abselem.highlight();
73
- for (var i=0; i<this.listeners.length;i++) {
74
- this.listeners[i].highlight(abselem.abcelem);
75
- }
76
- };
77
-
78
- ABCJS.write.Printer.prototype.notifyChange = function (abselem) {
79
- for (var i=0; i<this.listeners.length;i++) {
80
- this.listeners[i].modelChanged();
81
- }
82
- };
83
-
84
- ABCJS.write.Printer.prototype.clearSelection = function () {
85
- for (var i=0;i<this.selected.length;i++) {
86
- this.selected[i].unhighlight();
87
- }
88
- this.selected = [];
89
- };
90
-
91
- ABCJS.write.Printer.prototype.addSelectListener = function (listener) {
92
- this.listeners[this.listeners.length] = listener;
93
- };
94
-
95
- ABCJS.write.Printer.prototype.rangeHighlight = function(start,end)
96
- {
97
- this.clearSelection();
98
- for (var line=0;line<this.staffgroups.length; line++) {
99
- var voices = this.staffgroups[line].voices;
100
- for (var voice=0;voice<voices.length;voice++) {
101
- var elems = voices[voice].children;
102
- for (var elem=0; elem<elems.length; elem++) {
103
- // Since the user can highlight more than an element, or part of an element, a hit is if any of the endpoints
104
- // is inside the other range.
105
- var elStart = elems[elem].abcelem.startChar;
106
- var elEnd = elems[elem].abcelem.endChar;
107
- if ((end>elStart && start<elEnd) || ((end===start) && end===elEnd)) {
108
- // if (elems[elem].abcelem.startChar>=start && elems[elem].abcelem.endChar<=end) {
109
- this.selected[this.selected.length]=elems[elem];
110
- elems[elem].highlight();
111
- }
112
- }
113
- }
114
- }
115
- };
116
-
117
- ABCJS.write.Printer.prototype.beginGroup = function () {
118
- this.path = [];
119
- this.lastM = [0,0];
120
- this.ingroup = true;
121
- };
122
-
123
- ABCJS.write.Printer.prototype.addPath = function (path) {
124
- path = path || [];
125
- if (path.length===0) return;
126
- path[0][0]="m";
127
- path[0][1]-=this.lastM[0];
128
- path[0][2]-=this.lastM[1];
129
- this.lastM[0]+=path[0][1];
130
- this.lastM[1]+=path[0][2];
131
- this.path.push(path[0]);
132
- for (var i=1,ii=path.length;i<ii;i++) {
133
- if (path[i][0]==="m") {
134
- this.lastM[0]+=path[i][1];
135
- this.lastM[1]+=path[i][2];
136
- }
137
- this.path.push(path[i]);
138
- }
139
- };
140
-
141
- ABCJS.write.Printer.prototype.endGroup = function (klass) {
142
- this.ingroup = false;
143
- if (this.path.length===0) return null;
144
- var ret = this.paper.path().attr({path:this.path, stroke:"none", fill:"#000000", 'class': this.addClasses(klass)});
145
- if (this.scale!==1) {
146
- ret.scale(this.scale, this.scale, 0, 0);
147
- }
148
- return ret;
149
- };
150
-
151
- ABCJS.write.Printer.prototype.printStaveLine = function (x1,x2, pitch) {
152
- var isIE=/*@cc_on!@*/false;//IE detector
153
- var dy = 0.35;
154
- var fill = "#000000";
155
- if (isIE) {
156
- dy = 1;
157
- fill = "#666666";
158
- }
159
- var y = this.calcY(pitch);
160
- var pathString = ABCJS.write.sprintf("M %f %f L %f %f L %f %f L %f %f z", x1, y-dy, x2, y-dy,
161
- x2, y+dy, x1, y+dy);
162
- var ret = this.paper.path().attr({path:pathString, stroke:"none", fill:fill, 'class': this.addClasses('staff')}).toBack();
163
- if (this.scale!==1) {
164
- ret.scale(this.scale, this.scale, 0, 0);
165
- }
166
- return ret;
167
- };
168
-
169
- ABCJS.write.Printer.prototype.printStem = function (x, dx, y1, y2) {
170
- if (dx<0) { // correct path "handedness" for intersection with other elements
171
- var tmp = y2;
172
- y2 = y1;
173
- y1 = tmp;
174
- }
175
- var isIE=/*@cc_on!@*/false;//IE detector
176
- var fill = "#000000";
177
- if (isIE && dx<1) {
178
- dx = 1;
179
- fill = "#666666";
180
- }
181
- if (~~x === x) x+=0.05; // raphael does weird rounding (for VML)
182
- var pathArray = [["M",x,y1],["L", x, y2],["L", x+dx, y2],["L",x+dx,y1],["z"]];
183
- if (!isIE && this.ingroup) {
184
- this.addPath(pathArray);
185
- } else {
186
- var ret = this.paper.path().attr({path:pathArray, stroke:"none", fill:fill, 'class': this.addClasses('stem')}).toBack();
187
- if (this.scale!==1) {
188
- ret.scale(this.scale, this.scale, 0, 0);
189
- }
190
- return ret;
191
- }
192
- };
193
-
194
- // assumes this.y is set appropriately
195
- // if symbol is a multichar string without a . (as in scripts.staccato) 1 symbol per char is assumed
196
- // not scaled if not in printgroup
197
- ABCJS.write.Printer.prototype.printSymbol = function(x, offset, symbol, scalex, scaley, klass) {
198
- var el;
199
- if (!symbol) return null;
200
- if (symbol.length>0 && symbol.indexOf(".")<0) {
201
- var elemset = this.paper.set();
202
- var dx =0;
203
- for (var i=0; i<symbol.length; i++) {
204
- var ycorr = this.glyphs.getYCorr(symbol.charAt(i));
205
- el = this.glyphs.printSymbol(x+dx, this.calcY(offset+ycorr), symbol.charAt(i), this.paper, klass);
206
- if (el) {
207
- elemset.push(el);
208
- dx+=this.glyphs.getSymbolWidth(symbol.charAt(i));
209
- } else {
210
- this.renderText(x, this.y, "no symbol:" +symbol, "debugfont", 'debug-msg', 'start');
211
- }
212
- }
213
- if (this.scale!==1) {
214
- elemset.scale(this.scale, this.scale, 0, 0);
215
- }
216
- return elemset;
217
- } else {
218
- var ycorr = this.glyphs.getYCorr(symbol);
219
- if (this.ingroup) {
220
- this.addPath(this.glyphs.getPathForSymbol(x, this.calcY(offset+ycorr), symbol, scalex, scaley));
221
- } else {
222
- el = this.glyphs.printSymbol(x, this.calcY(offset+ycorr), symbol, this.paper, klass);
223
- if (el) {
224
- if (this.scale!==1) {
225
- el.scale(this.scale, this.scale, 0, 0);
226
- }
227
- return el;
228
- } else
229
- this.renderText(x, this.y, "no symbol:" +symbol, "debugfont", 'debug-msg', 'start');
230
- }
231
- return null;
232
- }
233
- };
234
-
235
- ABCJS.write.Printer.prototype.printPath = function (attrs) {
236
- var ret = this.paper.path().attr(attrs);
237
- if (this.scale!==1) ret.scale(this.scale, this.scale, 0, 0);
238
- return ret;
239
- };
240
-
241
- ABCJS.write.Printer.prototype.drawArc = function(x1, x2, pitch1, pitch2, above) {
242
-
243
-
244
- x1 = x1 + 6;
245
- x2 = x2 + 4;
246
- pitch1 = pitch1 + ((above)?1.5:-1.5);
247
- pitch2 = pitch2 + ((above)?1.5:-1.5);
248
- var y1 = this.calcY(pitch1);
249
- var y2 = this.calcY(pitch2);
250
-
251
- //unit direction vector
252
- var dx = x2-x1;
253
- var dy = y2-y1;
254
- var norm= Math.sqrt(dx*dx+dy*dy);
255
- var ux = dx/norm;
256
- var uy = dy/norm;
257
-
258
- var flatten = norm/3.5;
259
- var curve = ((above)?-1:1)*Math.min(25, Math.max(4, flatten));
260
-
261
- var controlx1 = x1+flatten*ux-curve*uy;
262
- var controly1 = y1+flatten*uy+curve*ux;
263
- var controlx2 = x2-flatten*ux-curve*uy;
264
- var controly2 = y2-flatten*uy+curve*ux;
265
- var thickness = 2;
266
- 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,
267
- controlx1, controly1, controlx2, controly2, x2, y2,
268
- controlx2-thickness*uy, controly2+thickness*ux, controlx1-thickness*uy, controly1+thickness*ux, x1, y1);
269
- var ret = this.paper.path().attr({path:pathString, stroke:"none", fill:"#000000", 'class': this.addClasses('slur')});
270
- if (this.scale!==1) {
271
- ret.scale(this.scale, this.scale, 0, 0);
272
- }
273
- return ret;
274
- };
275
-
276
- ABCJS.write.Printer.prototype.renderText = function(x, y, text, type, klass, anchor) {
277
- var font = this.abctune.formatting[type];
278
- if (!font)
279
- font = { face: "Arial", size: 12, decoration: "underline", style: "normal", weight: "normal" };
280
- var attr = {"font-size": font.size*this.scale,
281
- "font-family": font.face, 'font-weight': font.weight, 'text-decoration': font.decoration,
282
- 'class': this.addClasses(klass) };
283
- if (anchor)
284
- attr["text-anchor"] = anchor;
285
- return this.paper.text(x, y*this.scale, text).attr(attr);
286
- };
287
-
288
- ABCJS.write.Printer.prototype.calcY = function(ofs) {
289
- return this.y+((ABCJS.write.spacing.TOPNOTE-ofs)*ABCJS.write.spacing.STEP);
290
- };
291
-
292
- ABCJS.write.Printer.prototype.printStave = function (startx, endx, numLines) { // PER: print out requested number of lines
293
- // If there is one line, it is the B line. Otherwise, the bottom line is the E line.
294
- if (numLines === 1) {
295
- this.printStaveLine(startx,endx,6);
296
- return;
297
- }
298
- for (var i = 0; i < numLines; i++) {
299
- this.printStaveLine(startx,endx,(i+1)*2);
300
- }
301
- // this.printStaveLine(startx,endx,2);
302
- // this.printStaveLine(startx,endx,4);
303
- // this.printStaveLine(startx,endx,6);
304
- // this.printStaveLine(startx,endx,8);
305
- // this.printStaveLine(startx,endx,10);
306
- };
307
-
308
- ABCJS.write.Printer.prototype.printABC = function(abctunes) {
309
- if (abctunes[0]===undefined) {
310
- abctunes = [abctunes];
311
- }
312
- this.y=0;
313
-
314
- for (var i = 0; i < abctunes.length; i++) {
315
- this.printTune(abctunes[i]);
316
- }
317
-
318
- };
319
-
320
- ABCJS.write.Printer.prototype.printTempo = function (tempo, paper, layouter, y, printer, x) {
321
- if (tempo.preString) {
322
- var text = this.renderText(x, this.y+20, tempo.preString, 'tempofont', 'tempo',"start");
323
- x += (text.getBBox().width + 20*printer.scale);
324
- }
325
- if (tempo.duration) {
326
- var temposcale = 0.75*printer.scale;
327
- var tempopitch = 14.5;
328
- var duration = tempo.duration[0]; // TODO when multiple durations
329
- var abselem = new ABCJS.write.AbsoluteElement(tempo, duration, 1, 'tempo');
330
- var durlog = Math.floor(Math.log(duration) / Math.log(2));
331
- var dot = 0;
332
- for (var tot = Math.pow(2, durlog), inc = tot / 2; tot < duration; dot++, tot += inc, inc /= 2);
333
- var c = layouter.chartable.note[-durlog];
334
- var flag = layouter.chartable.uflags[-durlog];
335
- var temponote = layouter.printNoteHead(abselem,
336
- c,
337
- {verticalPos:tempopitch},
338
- "up",
339
- 0,
340
- 0,
341
- flag,
342
- dot,
343
- 0,
344
- temposcale
345
- );
346
- abselem.addHead(temponote);
347
- if (duration < 1) {
348
- var p1 = tempopitch + 1 / 3 * temposcale;
349
- var p2 = tempopitch + 7 * temposcale;
350
- var dx = temponote.dx + temponote.w;
351
- var width = -0.6*printer.scale;
352
- abselem.addExtra(new ABCJS.write.RelativeElement(null, dx, 0, p1, {"type":"stem", "pitch2":p2, linewidth:width}));
353
- }
354
- abselem.x = x*(1/printer.scale); // TODO-PER: For some reason it scales this element twice, so just compensate.
355
- abselem.draw(printer, null);
356
- x += (abselem.w + 5*printer.scale);
357
- text = this.renderText(x, this.y+20, "= " + tempo.bpm, 'tempofont', 'tempo',"start");
358
- x += text.getBBox().width + 10*printer.scale;
359
- }
360
- if (tempo.postString) {
361
- this.renderText(x, this.y+20, tempo.postString, 'tempofont', 'tempo',"start");
362
- }
363
- y += 15*printer.scale;
364
- return y;
365
- };
366
-
367
- ABCJS.write.Printer.prototype.printTune = function (abctune) {
368
- this.lineNumber = null;
369
- this.abctune = abctune;
370
- this.measureNumber = null;
371
- this.layouter = new ABCJS.write.Layout(this.glyphs, abctune.formatting.bagpipes);
372
- this.layouter.printer = this; // TODO-PER: this is a hack to get access, but it tightens the coupling.
373
- if (abctune.media === 'print') {
374
- // TODO create the page the size of
375
- // tune.formatting.pageheight by tune.formatting.pagewidth
376
- // create margins the size of
377
- // TODO-PER: setting the defaults to 3/4" for now. What is the real value?
378
- var m = abctune.formatting.topmargin === undefined ? 54 : abctune.formatting.topmargin;
379
- this.y+=m;
380
- // TODO tune.formatting.botmargin
381
- // m = abctune.formatting.leftmargin === undefined ? 54 : abctune.formatting.leftmargin;
382
- // this.paddingleft = m;
383
- // m = abctune.formatting.rightmargin === undefined ? 54 : abctune.formatting.rightmargin;
384
- // this.paddingright = m;
385
- }
386
- else
387
- this.y+=this.paddingtop;
388
- if (abctune.formatting.staffwidth) {
389
- this.width=abctune.formatting.staffwidth;
390
- } else {
391
- this.width=this.staffwidth;
392
- }
393
- this.width+=this.paddingleft;
394
- if (abctune.formatting.scale) { this.scale=abctune.formatting.scale; }
395
- if (abctune.metaText.title)
396
- this.renderText(this.width/2, this.y, abctune.metaText.title, 'titlefont', 'title meta-top');
397
- this.y+=20*this.scale;
398
- if (abctune.lines[0] && abctune.lines[0].subtitle) {
399
- this.printSubtitleLine(abctune.lines[0]);
400
- this.y+=20*this.scale;
401
- }
402
- if (abctune.metaText.rhythm) {
403
- this.renderText(this.paddingleft, this.y, abctune.metaText.rhythm, 'infofont', 'meta-top', "start");
404
- if (!abctune.metaText.author && !abctune.metaText.origin && !abctune.metaText.composer)
405
- this.y+=15*this.scale;
406
- }
407
- var composerLine = "";
408
- if (abctune.metaText.composer) composerLine += abctune.metaText.composer;
409
- if (abctune.metaText.origin) composerLine += ' (' + abctune.metaText.origin + ')';
410
- if (composerLine.length > 0) {
411
- this.renderText(this.width, this.y, composerLine, 'composerfont', 'meta-top', "end");
412
- this.y+=15;
413
- }
414
- if (abctune.metaText.author) {
415
- this.renderText(this.width, this.y, abctune.metaText.author, 'composerfont', 'meta-top', "end");
416
- this.y+=15;
417
- }
418
- if (abctune.metaText.tempo && !abctune.metaText.tempo.suppress) {
419
- this.y = this.printTempo(abctune.metaText.tempo, this.paper, this.layouter, this.y, this, 50, -1);
420
- this.y += 20*this.scale;
421
- }
422
- this.staffgroups = [];
423
- var text2;
424
- var maxwidth = this.width;
425
- for(var line=0; line<abctune.lines.length; line++) {
426
- this.lineNumber = line;
427
- var abcline = abctune.lines[line];
428
- if (abcline.staff) {
429
- staffgroup = this.printStaffLine(abctune, abcline, line);
430
- if (staffgroup.w > maxwidth) maxwidth = staffgroup.w;
431
- } else if (abcline.subtitle && line!==0) {
432
- this.printSubtitleLine(abcline);
433
- this.y+=20*this.scale; //hardcoded
434
- } else if (abcline.text) {
435
- if (typeof abcline.text === 'string')
436
- text2 = this.renderText(this.paddingleft, this.y, abcline.text, "textfont", 'defined-text', "start");
437
- else {
438
- var str = "";
439
- for (var i = 0; i < abcline.text.length; i++) {
440
- str += " FONT " + abcline.text[i].text;
441
- }
442
- text2 = this.renderText(this.paddingleft, this.y, str, "textfont", 'defined-text', "start");
443
- }
444
- this.y += text2.getBBox().height + 10 * this.scale;
445
- }
446
- }
447
- this.lineNumber = null;
448
- this.measureNumber = null;
449
- if (abctune.metaText.partOrder) {
450
- text2 = this.renderText(this.paddingleft, this.y, "Part Order: " + abctune.metaText.partOrder, 'partsfont', 'meta-bottom');
451
- this.y += text2.getBBox().height + 10 * this.scale;
452
- }
453
- var extraText = "";
454
- if (abctune.metaText.unalignedWords) {
455
- for (var j = 0; j < abctune.metaText.unalignedWords.length; j++) {
456
- if (typeof abctune.metaText.unalignedWords[j] === 'string')
457
- extraText += abctune.metaText.unalignedWords[j] + "\n";
458
- else {
459
- for (var k = 0; k < abctune.metaText.unalignedWords[j].length; k++) {
460
- extraText += " FONT " + abctune.metaText.unalignedWords[j][k].text;
461
- }
462
- extraText += "\n";
463
- }
464
- }
465
- text2 = this.renderText(this.paddingleft + 50, this.y, extraText, 'wordsfont', 'meta-bottom', "start");
466
- this.y += text2.getBBox().height + 10 * this.scale;
467
- extraText = "";
468
- }
469
- if (abctune.metaText.book) extraText += "Book: " + abctune.metaText.book + "\n";
470
- if (abctune.metaText.source) extraText += "Source: " + abctune.metaText.source + "\n";
471
- if (abctune.metaText.discography) extraText += "Discography: " + abctune.metaText.discography + "\n";
472
- if (abctune.metaText.notes) extraText += "Notes: " + abctune.metaText.notes + "\n";
473
- if (abctune.metaText.transcription) extraText += "Transcription: " + abctune.metaText.transcription + "\n";
474
- if (abctune.metaText.history) extraText += "History: " + abctune.metaText.history + "\n";
475
- if (abctune.metaText['abc-copyright']) extraText += "Copyright: " + abctune.metaText['abc-copyright'] + "\n";
476
- if (abctune.metaText['abc-creator']) extraText += "Creator: " + abctune.metaText['abc-creator'] + "\n";
477
- if (abctune.metaText['abc-edited-by']) extraText += "Edited By: " + abctune.metaText['abc-edited-by'] + "\n";
478
- text2 = this.renderText(this.paddingleft, this.y, extraText, 'historyfont', 'meta-bottom', "start");
479
- this.y += text2.getBBox().height + 10 * this.scale;
480
- var sizetoset = {w: (maxwidth+this.paddingright)*this.scale,h: (this.y+this.paddingbottom)*this.scale};
481
- this.paper.setSize(sizetoset.w,sizetoset.h);
482
- // Correct for IE problem in calculating height
483
- var isIE=/*@cc_on!@*/false;//IE detector
484
- if (isIE) {
485
- this.paper.canvas.parentNode.style.width=sizetoset.w+"px";
486
- this.paper.canvas.parentNode.style.height=""+sizetoset.h+"px";
487
- } else
488
- this.paper.canvas.parentNode.setAttribute("style","width:"+sizetoset.w+"px");
489
- };
490
-
491
- ABCJS.write.Printer.prototype.printSubtitleLine = function(abcline) {
492
- this.renderText(this.width/2, this.y, abcline.subtitle, "subtitlefont", 'text meta-top');
493
- };
494
-
495
- function centerWholeRests(voices) {
496
- // whole rests are a special case: if they are by themselves in a measure, then they should be centered.
497
- // (If they are not by themselves, that is probably a user error, but we'll just center it between the two items to either side of it.)
498
- for (var i = 0; i < voices.length; i++) {
499
- var voice = voices[i];
500
- // Look through all of the elements except for the first and last. If the whole note appears there then there isn't anything to center it between anyway.
501
- for (var j = 1; j < voice.children.length-1; j++) {
502
- var absElem = voice.children[j];
503
- if (absElem.abcelem.rest && absElem.abcelem.rest.type === 'whole') {
504
- var before = voice.children[j-1];
505
- var after = voice.children[j+1];
506
- var midpoint = (after.x - before.x) / 2 + before.x;
507
- absElem.x = midpoint - absElem.w / 2;
508
-
509
- }
510
- }
511
- }
512
- }
513
-
514
- ABCJS.write.Printer.prototype.printStaffLine = function (abctune, abcline, line) {
515
- var staffgroup = this.layouter.printABCLine(abcline.staff);
516
- var newspace = this.space;
517
- for (var it = 0; it < 3; it++) { // TODO shouldn't need this triple pass any more
518
- staffgroup.layout(newspace, this, false);
519
- if (line && line === abctune.lines.length - 1 && staffgroup.w / this.width < 0.66 && !abctune.formatting.stretchlast) break; // don't stretch last line too much unless it is 1st
520
- var relspace = staffgroup.spacingunits * newspace;
521
- var constspace = staffgroup.w - relspace;
522
- if (staffgroup.spacingunits > 0) {
523
- newspace = (this.width - constspace) / staffgroup.spacingunits;
524
- if (newspace * staffgroup.minspace > 50) {
525
- newspace = 50 / staffgroup.minspace;
526
- }
527
- }
528
- }
529
- centerWholeRests(staffgroup.voices);
530
- staffgroup.draw(this, this.y);
531
- this.staffgroups[this.staffgroups.length] = staffgroup;
532
- this.y = staffgroup.y + staffgroup.height;
533
- this.y += ABCJS.write.spacing.STAVEHEIGHT * 0.2;
534
- return staffgroup;
535
- };