File size: 3,883 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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//    abc_relative_element.js: Definition of the RelativeElement class.

var RelativeElement = function RelativeElement(c, dx, w, pitch, opt) {
	opt = opt || {};
	this.x = 0;
	this.c = c;      // character or path or string
	this.dx = dx;    // relative x position
	this.w = w;      // minimum width taken up by this element (can include gratuitous space)
	this.pitch = pitch; // relative y position by pitch
	this.scalex = opt.scalex || 1; // should the character/path be scaled?
	this.scaley = opt.scaley || 1; // should the character/path be scaled?
	this.type = opt.type || "symbol"; // cheap types.
	this.pitch2 = opt.pitch2;
	this.linewidth = opt.linewidth;
	this.klass = opt.klass;
	this.anchor = opt.anchor ? opt.anchor : 'middle'
	this.top = pitch;
	if (this.pitch2 !== undefined && this.pitch2 > this.top) this.top = this.pitch2;
	this.bottom = pitch;
	if (this.pitch2 !== undefined && this.pitch2 < this.bottom) this.bottom = this.pitch2;
	if (opt.thickness) {
		this.top += opt.thickness / 2;
		this.bottom -= opt.thickness / 2;
	}
	if (opt.stemHeight) {
		if (opt.stemHeight > 0)
			this.top += opt.stemHeight;
		else
			this.bottom += opt.stemHeight;
	}
	if (opt.dim)
		this.dim = opt.dim;
	if (opt.position)
		this.position = opt.position;
	this.height = opt.height ? opt.height : 4; // The +1 is to give a little bit of padding.
	if (opt.top)
		this.top = opt.top;
	if (opt.bottom)
		this.bottom = opt.bottom;
	if (opt.name)
		this.name = opt.name;
	else if (this.c)
		this.name = this.c;
	else
		this.name = this.type;
	if (opt.realWidth)
		this.realWidth = opt.realWidth;
	else
		this.realWidth = this.w;
	this.centerVertically = false;
	switch (this.type) {
		case "debug":
			this.chordHeightAbove = this.height;
			break;
		case "lyric":
			if (opt.position && opt.position === 'below')
				this.lyricHeightBelow = this.height;
			else
				this.lyricHeightAbove = this.height;
			break;
		case "chord":
			if (opt.position && opt.position === 'below')
				this.chordHeightBelow = this.height;
			else
				this.chordHeightAbove = this.height;
			break;
		case "text":
			if (this.pitch === undefined) {
				if (opt.position && opt.position === 'below')
					this.chordHeightBelow = this.height;
				else
					this.chordHeightAbove = this.height;
			} else
				this.centerVertically = true;
			break;
		case "part": this.partHeightAbove = this.height; break;
	}
};

RelativeElement.prototype.getChordDim = function () {
	if (this.type === "debug")
		return null;
	if (!this.chordHeightAbove && !this.chordHeightBelow)
		return null;
	// Chords are centered, annotations are left justified.
	// NOTE: the font reports extra space to the left and right anyway, so there is a built in margin.
	// We add a little margin so that items can't touch - we use half the font size as the margin, so that is 1/4 on each side.
	// if there is only one character that we're printing, use half of that margin.
	// var margin = this.dim.font.size/4;
	// if (this.c.length === 1)
	// 	margin = margin / 2;
	var margin = 0;

	var offset = this.type === "chord" ? this.realWidth / 2 : 0;
	var left = this.x - offset - margin;
	var right = left + this.realWidth + margin;
	return { left: left, right: right };
};

RelativeElement.prototype.invertLane = function (total) {
	if (this.lane === undefined)
		this.lane = 0;
	this.lane = total - this.lane - 1;
};

RelativeElement.prototype.putChordInLane = function (i) {
	this.lane = i;
	// Add some extra space to account for the character's descenders.
	if (this.chordHeightAbove)
		this.chordHeightAbove = (this.height * 1.25) * this.lane;
	else
		this.chordHeightBelow = (this.height * 1.25) * this.lane;
};

RelativeElement.prototype.getLane = function () {
	if (this.lane === undefined)
		return 0;
	return this.lane;
};

RelativeElement.prototype.setX = function (x) {
	this.x = x + this.dx;
};

module.exports = RelativeElement;