Search in sources :

Example 1 with BorderSpacing

use of com.xenoage.zong.musiclayout.spacing.BorderSpacing in project Zong by Xenoage.

the class SingleVoiceSpacer method compute.

VoiceSpacing compute(Voice voice, float interlineSpace, Fraction measureBeats, int staffLinesCount, Notations notations, LayoutSettings layoutSettings) {
    LinkedList<ElementSpacing> ret = llist();
    // special case: no elements in the measure.
    if (voice.getElements().size() == 0) {
        return new VoiceSpacing(voice, interlineSpace, alist((ElementSpacing) new BorderSpacing(Fraction.Companion.get_0(), 0), new BorderSpacing(measureBeats, layoutSettings.spacings.widthMeasureEmpty)));
    }
    // we compute the spacings in reverse order. this is easier, since grace chords
    // use shared space when possible, but are aligned to the right. so we begin
    // at position 0, and create the spacings in reverse direction (thus we find negative positions).
    // at the end, we shift the voice spacing to the right to be aligned at the left measure border,
    // which is position 0.
    // last symbol offset:
    // real offset where the last element's symbol started
    // since we do not know the right border yet, we start at 0
    float lastSymbolOffset = 0;
    // front gap offset:
    // offset where the last element (including front gap) started.
    float lastFrontGapOffset = lastSymbolOffset;
    // last full element offset:
    // lastSymbolOffset of the last full (non-grace) element
    float lastFullSymbolOffset = lastSymbolOffset;
    // at last beat
    Fraction curBeat = voice.getFilledBeats();
    ret.addFirst(new BorderSpacing(curBeat, lastFrontGapOffset));
    // iterate through the elements in reverse order
    for (VoiceElement element : Companion.reverseIt(voice.getElements())) {
        // get the notation
        Notation notation = notations.get(element);
        if (notation == null)
            throw new IllegalStateException("No notation for element " + element);
        // get the width of the element (front gap, symbol's width, rear gap, lyric's width)
        ElementWidth elementWidth = notation.getWidth();
        // add spacing for voice element
        float symbolOffset;
        boolean grace = !element.getDuration().isGreater0();
        if (!grace) {
            // full element
            // share this rear gap and the front gap of the following
            // element + the space of following grace elements, when possible
            // (but use at least minimal distance)
            symbolOffset = Math.min(lastFrontGapOffset - layoutSettings.spacings.widthDistanceMin, lastFullSymbolOffset - elementWidth.rearGap) - elementWidth.symbolWidth;
            lastFullSymbolOffset = symbolOffset;
            // update beat cursor
            curBeat = curBeat.sub(element.getDuration());
        } else {
            // grace element
            // share this rear gap and the front gap of the following element, when possible
            symbolOffset = Math.min(lastFrontGapOffset, lastSymbolOffset - elementWidth.rearGap) - elementWidth.symbolWidth;
        }
        ElementSpacing elementSpacing = null;
        if (notation instanceof RestNotation) {
            // rest spacing
            elementSpacing = restSpacer.compute((RestNotation) notation, curBeat, symbolOffset, staffLinesCount);
        } else {
            // chord spacing
            elementSpacing = new ChordSpacing((ChordNotation) notation, curBeat, symbolOffset);
        }
        ret.addFirst(elementSpacing);
        lastFrontGapOffset = symbolOffset - elementWidth.frontGap;
        lastSymbolOffset = symbolOffset;
    }
    // shift spacings to the right
    float shift = (-lastFrontGapOffset) + layoutSettings.offsetMeasureStart;
    for (ElementSpacing e : ret) e.xIs += shift;
    return new VoiceSpacing(voice, interlineSpace, ilist(ret));
}
Also used : ElementWidth(com.xenoage.zong.musiclayout.spacing.ElementWidth) ChordNotation(com.xenoage.zong.musiclayout.notation.ChordNotation) RestNotation(com.xenoage.zong.musiclayout.notation.RestNotation) Fraction(com.xenoage.utils.math.Fraction) Notation(com.xenoage.zong.musiclayout.notation.Notation) RestNotation(com.xenoage.zong.musiclayout.notation.RestNotation) ChordNotation(com.xenoage.zong.musiclayout.notation.ChordNotation) ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) ChordSpacing(com.xenoage.zong.musiclayout.spacing.ChordSpacing) BorderSpacing(com.xenoage.zong.musiclayout.spacing.BorderSpacing) VoiceElement(com.xenoage.zong.core.music.VoiceElement) VoiceSpacing(com.xenoage.zong.musiclayout.spacing.VoiceSpacing)

Aggregations

Fraction (com.xenoage.utils.math.Fraction)1 VoiceElement (com.xenoage.zong.core.music.VoiceElement)1 ChordNotation (com.xenoage.zong.musiclayout.notation.ChordNotation)1 Notation (com.xenoage.zong.musiclayout.notation.Notation)1 RestNotation (com.xenoage.zong.musiclayout.notation.RestNotation)1 BorderSpacing (com.xenoage.zong.musiclayout.spacing.BorderSpacing)1 ChordSpacing (com.xenoage.zong.musiclayout.spacing.ChordSpacing)1 ElementSpacing (com.xenoage.zong.musiclayout.spacing.ElementSpacing)1 ElementWidth (com.xenoage.zong.musiclayout.spacing.ElementWidth)1 VoiceSpacing (com.xenoage.zong.musiclayout.spacing.VoiceSpacing)1