|
|
var VoiceElement = function VoiceElements() { } |
|
|
|
|
|
VoiceElement.beginLayout = function (startx, voice) { |
|
|
voice.i = 0; |
|
|
voice.durationindex = 0; |
|
|
|
|
|
voice.startx = startx; |
|
|
voice.minx = startx; |
|
|
voice.nextx = startx; |
|
|
voice.spacingduration = 0; |
|
|
}; |
|
|
|
|
|
VoiceElement.layoutEnded = function (voice) { |
|
|
return (voice.i >= voice.children.length); |
|
|
}; |
|
|
|
|
|
VoiceElement.getNextX = function (voice) { |
|
|
return Math.max(voice.minx, voice.nextx); |
|
|
}; |
|
|
|
|
|
|
|
|
VoiceElement.getSpacingUnits = function (voice) { |
|
|
return Math.sqrt(voice.spacingduration * 8); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VoiceElement.layoutOneItem = function (x, spacing, voice, minPadding, firstVoice) { |
|
|
var child = voice.children[voice.i]; |
|
|
if (!child) return 0; |
|
|
var er = x - voice.minx; |
|
|
var pad = voice.durationindex + child.duration > 0 ? minPadding : 0; |
|
|
|
|
|
if (child.abcelem.el_type === "note" && !child.abcelem.rest && voice.voicenumber !== 0 && firstVoice) { |
|
|
var firstChild = firstVoice.children[firstVoice.i]; |
|
|
|
|
|
|
|
|
var overlaps = firstChild && |
|
|
((child.abcelem.maxpitch <= firstChild.abcelem.maxpitch + 1 && child.abcelem.maxpitch >= firstChild.abcelem.minpitch - 1) || |
|
|
(child.abcelem.minpitch <= firstChild.abcelem.maxpitch + 1 && child.abcelem.minpitch >= firstChild.abcelem.minpitch - 1)) |
|
|
|
|
|
if (overlaps && child.abcelem.minpitch === firstChild.abcelem.minpitch && child.abcelem.maxpitch === firstChild.abcelem.maxpitch && |
|
|
firstChild.heads && firstChild.heads.length > 0 && child.heads && child.heads.length > 0 && |
|
|
firstChild.heads[0].c === child.heads[0].c) |
|
|
overlaps = false; |
|
|
|
|
|
if (overlaps) { |
|
|
|
|
|
|
|
|
var firstChildNoteWidth = firstChild.heads && firstChild.heads.length > 0 ? firstChild.heads[0].realWidth : firstChild.fixed.w; |
|
|
if (!child.adjustedWidth) |
|
|
child.adjustedWidth = firstChildNoteWidth + child.w; |
|
|
child.w = child.adjustedWidth |
|
|
for (var j = 0; j < child.children.length; j++) { |
|
|
var relativeChild = child.children[j]; |
|
|
if (relativeChild.name.indexOf("accidental") < 0) { |
|
|
if (!relativeChild.adjustedWidth) |
|
|
relativeChild.adjustedWidth = relativeChild.dx + firstChildNoteWidth; |
|
|
relativeChild.dx = relativeChild.adjustedWidth |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
var extraWidth = getExtraWidth(child, pad); |
|
|
if (er < extraWidth) { |
|
|
|
|
|
if (voice.i === 0 || child.type !== 'bar' || (voice.children[voice.i - 1].type !== 'part' && voice.children[voice.i - 1].type !== 'tempo')) |
|
|
x += extraWidth - er; |
|
|
} |
|
|
child.setX(x); |
|
|
|
|
|
voice.spacingduration = child.duration; |
|
|
|
|
|
voice.minx = x + getMinWidth(child); |
|
|
if (voice.i !== voice.children.length - 1) voice.minx += child.minspacing; |
|
|
|
|
|
this.updateNextX(x, spacing, voice); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return x; |
|
|
}; |
|
|
|
|
|
VoiceElement.shiftRight = function (dx, voice) { |
|
|
var child = voice.children[voice.i]; |
|
|
if (!child) return; |
|
|
child.setX(child.x + dx); |
|
|
voice.minx += dx; |
|
|
voice.nextx += dx; |
|
|
}; |
|
|
|
|
|
|
|
|
VoiceElement.updateNextX = function (x, spacing, voice) { |
|
|
voice.nextx = x + (spacing * this.getSpacingUnits(voice)); |
|
|
}; |
|
|
|
|
|
VoiceElement.updateIndices = function (voice) { |
|
|
if (!this.layoutEnded(voice)) { |
|
|
voice.durationindex += voice.children[voice.i].duration; |
|
|
if (voice.children[voice.i].type === 'bar') voice.durationindex = Math.round(voice.durationindex * 64) / 64; |
|
|
voice.i++; |
|
|
} |
|
|
}; |
|
|
|
|
|
function getExtraWidth(child, minPadding) { |
|
|
var padding = 0; |
|
|
if (child.type === 'note' || child.type === 'bar') |
|
|
padding = minPadding; |
|
|
return -child.extraw + padding; |
|
|
} |
|
|
|
|
|
function getMinWidth(child) { |
|
|
return child.w; |
|
|
} |
|
|
|
|
|
module.exports = VoiceElement; |
|
|
|