File size: 3,224 Bytes
af6912c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
var drawStaffGroup = require('./staff-group');
var setPaperSize = require('./set-paper-size');
var nonMusic = require('./non-music');
var spacing = require('../helpers/spacing');
var Selectables = require('./selectables');

function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, selectTypes, tuneNumber, lineOffset) {
	var selectables = new Selectables(renderer.paper, selectTypes, tuneNumber);
	var groupClasses = {}
	if (classes.shouldAddClasses)
		groupClasses.klass = "abcjs-meta-top"
	renderer.paper.openGroup(groupClasses)
	renderer.moveY(renderer.padding.top);
	nonMusic(renderer, abcTune.topText, selectables);
	renderer.paper.closeGroup()
	renderer.moveY(renderer.spacing.music);
	var staffgroups = [];
	for (var line = 0; line < abcTune.lines.length; line++) {
		classes.incrLine();
		var abcLine = abcTune.lines[line];
		if (abcLine.staff) {
			if (classes.shouldAddClasses)
				groupClasses.klass = "abcjs-staff-wrapper abcjs-l" + classes.lineNumber
			renderer.paper.openGroup(groupClasses)
			if (abcLine.vskip) {
				renderer.moveY(abcLine.vskip);
			}
			if (staffgroups.length >= 1)
				addStaffPadding(renderer, renderer.spacing.staffSeparation, staffgroups[staffgroups.length - 1], abcLine.staffGroup);
			var staffgroup = engraveStaffLine(renderer, abcLine.staffGroup, selectables, line);
			staffgroup.line = lineOffset + line; // If there are non-music lines then the staffgroup array won't line up with the line array, so this keeps track.
			staffgroups.push(staffgroup);
			renderer.paper.closeGroup()
		} else if (abcLine.nonMusic) {
			if (classes.shouldAddClasses)
				groupClasses.klass = "abcjs-non-music"
			renderer.paper.openGroup(groupClasses)
			nonMusic(renderer, abcLine.nonMusic, selectables);
			renderer.paper.closeGroup()
		}
	}

	classes.reset();
	if (abcTune.bottomText && abcTune.bottomText.rows && abcTune.bottomText.rows.length > 0) {
		if (classes.shouldAddClasses)
			groupClasses.klass = "abcjs-meta-bottom"
		renderer.paper.openGroup(groupClasses)
		renderer.moveY(24); // TODO-PER: Empirically discovered. What variable should this be?
		nonMusic(renderer, abcTune.bottomText, selectables);
		renderer.paper.closeGroup()
	}
	setPaperSize(renderer, maxWidth, scale, responsive);
	return { staffgroups: staffgroups, selectables: selectables.getElements() };
}

function engraveStaffLine(renderer, staffGroup, selectables, lineNumber) {
	drawStaffGroup(renderer, staffGroup, selectables, lineNumber);
	var height = staffGroup.height * spacing.STEP;
	renderer.y += height;
	return staffGroup;
}

function addStaffPadding(renderer, staffSeparation, lastStaffGroup, thisStaffGroup) {
	var lastStaff = lastStaffGroup.staffs[lastStaffGroup.staffs.length - 1];
	var lastBottomLine = -(lastStaff.bottom - 2); // The 2 is because the scale goes to 2 below the last line.
	var nextTopLine = thisStaffGroup.staffs[0].top - 10; // Because 10 represents the top line.
	var naturalSeparation = nextTopLine + lastBottomLine; // This is how far apart they'd be without extra spacing
	var separationInPixels = naturalSeparation * spacing.STEP;
	if (separationInPixels < staffSeparation)
		renderer.moveY(staffSeparation - separationInPixels);
}

module.exports = draw;