| 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; |
|
|