Search in sources :

Example 6 with ColumnSpacing

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

the class ColumnsSpacer method compute.

public List<ColumnSpacing> compute(Notations notations, Context context) {
    context.saveMp();
    List<ColumnSpacing> ret = alist();
    for (int iMeasure : range(context.score.getMeasuresCount())) {
        context.mp = MP.atMeasure(iMeasure);
        ColumnSpacing column = columnSpacer.compute(context, noLeading, notations);
        ret.add(column);
    }
    context.restoreMp();
    return ret;
}
Also used : ColumnSpacing(com.xenoage.zong.musiclayout.spacing.ColumnSpacing)

Example 7 with ColumnSpacing

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

the class ScoreLayouter method createLayoutWithExceptions.

/**
 * Computes the whole layout and returns it.
 * If something fails, an exception is thrown.
 */
public ScoreLayout createLayoutWithExceptions() {
    // notations of elements
    Notations notations = notator.computeAll(context);
    // compute optimal measure column spacings
    List<ColumnSpacing> columns = columnsSpacer.compute(notations, context);
    // break columns into systems and frames
    FramesSpacing frames = framesSpacer.compute(columns, target, context, notations);
    // system stretching (horizontal)
    fillSystemsHorizontally(frames, target);
    // frame filling (vertical)
    fillFramesVertically(frames, target, context.score);
    // compute beam spacings. these are computed only now, after the horizontal
    // and vertical spacing of the score is fixed, since the beam slants depend on the
    // exact spacings
    Map<Beam, BeamSpacing> beams = beamsSpacer.compute(context.score, notations, frames);
    // create score frame layouts from the collected information
    List<ScoreFrameLayout> scoreFrameLayouts = createScoreFrameLayouts(frames, notations, context, beams);
    // create score layout
    return new ScoreLayout(context.score, scoreFrameLayouts, context.symbols, context.settings);
}
Also used : Beam(com.xenoage.zong.core.music.beam.Beam) FramesSpacing(com.xenoage.zong.musiclayout.spacing.FramesSpacing) BeamSpacing(com.xenoage.zong.musiclayout.spacing.BeamSpacing) ColumnSpacing(com.xenoage.zong.musiclayout.spacing.ColumnSpacing) Notations(com.xenoage.zong.musiclayout.notation.Notations) ScoreLayout(com.xenoage.zong.musiclayout.ScoreLayout) ScoreFrameLayout(com.xenoage.zong.musiclayout.ScoreFrameLayout)

Example 8 with ColumnSpacing

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

the class SystemSpacer method compute.

/**
 * Arranges an optimum number of measures columns in a system, beginning at the given measure,
 * if possible.
 * @param context        the context of the layouter, with the {@link MP} set to the start measure
 * @param usableSizeMm   the usable size within the score frame in mm
 * @param offsetYMm      the vertical offset of the system in mm
 * @param systemIndex    the global system index (over all frames)
 * @param isFirst        true, iff this system is the first one in a score frame
 * @param isAdditional   true, iff this system is created for an additional frame, which is created
 *                       for a complete score layout, but is not part of the defined layout
 * @param measureColumnSpacings  a list of all measure column spacings without leading spacings
 * @param notations      the notations of the elements, needed when a column has to be recomputed
 *                       because of a leading spacing
 */
public Optional<SystemSpacing> compute(Context context, Size2f usableSizeMm, float offsetYMm, int systemIndex, boolean isFirst, boolean isAdditional, List<ColumnSpacing> measureColumnSpacings, Notations notations) {
    int startMeasure = context.mp.measure;
    // test if there is enough height for the system
    Score score = context.score;
    ScoreFormat scoreFormat = score.getFormat();
    ScoreHeader scoreHeader = score.getHeader();
    // compute spacing of staves
    StavesSpacing stavesSpacing = stavesSpacer.compute(score, systemIndex);
    // enough space?
    if (offsetYMm + stavesSpacing.getTotalHeightMm() > usableSizeMm.height) {
        // when the system is the first one in an additional frame, we force it into the frame
        if (false == (isFirst && isAdditional))
            // not enough space
            return absent();
    }
    // compute the usable width for the system
    float systemLeftMarginMm = getLeftMarginMm(systemIndex, scoreFormat, scoreHeader);
    float systemRightMarginMm = getRightMarginMm(systemIndex, scoreFormat, scoreHeader);
    float usableWidthMm = usableSizeMm.width - systemLeftMarginMm - systemRightMarginMm;
    // append system measure-by-measure, until there is no space any more
    // or until there are no measures left
    int measuresCount = score.getMeasuresCount();
    List<ColumnSpacing> system = alist();
    float usedWidthMm = 0;
    int iMeasure;
    while (startMeasure + system.size() < measuresCount) {
        iMeasure = startMeasure + system.size();
        // decide if to add a leading spacing to the current measure or not
        boolean firstMeasure = system.size() == 0;
        ColumnSpacing column;
        if (firstMeasure) {
            // first measure within this system: add leading elements (clef, time sig.)
            column = columnSpacer.compute(context, true, /* leading! */
            notations);
        } else {
            // otherwise: use the precomputed spacing (without leading spacing)
            column = measureColumnSpacings.get(iMeasure);
        }
        // this system is created for a complete score layout
        if (false == canAppend(column, iMeasure, usableWidthMm, usedWidthMm, scoreHeader, firstMeasure)) {
            if (system.size() == 0 && isAdditional) {
                // force the single measure in this system
                usedWidthMm += column.getWidthMm();
                system.add(column);
            } else {
                // no more space for another measure
                break;
            }
        } else {
            usedWidthMm += column.getWidthMm();
            system.add(column);
        }
    }
    // we are finished
    if (system.size() == 0) {
        // not enough space for the system on this area
        return absent();
    } else {
        SystemSpacing ret = new SystemSpacing(system, systemLeftMarginMm, systemRightMarginMm, usedWidthMm, stavesSpacing, offsetYMm);
        return of(ret);
    }
}
Also used : ScoreFormat(com.xenoage.zong.core.format.ScoreFormat) Score(com.xenoage.zong.core.Score) ScoreHeader(com.xenoage.zong.core.header.ScoreHeader) StavesSpacing(com.xenoage.zong.musiclayout.spacing.StavesSpacing) ColumnSpacing(com.xenoage.zong.musiclayout.spacing.ColumnSpacing) SystemSpacing(com.xenoage.zong.musiclayout.spacing.SystemSpacing)

Example 9 with ColumnSpacing

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

the class StretchMeasuresTest method createSystemWith1MeasureGrace.

/**
 * Creates and returns a simple {@link SystemSpacing} with only one
 * measure and three notes: two main notes and two grace notes between them.
 */
public static SystemSpacing createSystemWith1MeasureGrace(float offsetChord1, float offsetChord2, float offsetMeasureEnd, float graceDistance) {
    Chord chord1 = chord(Companion.pi(0, 0, 4), Companion.fr(2, 4));
    Chord chord2grace = graceChord(Companion.pi(1, 0, 4));
    Chord chord3grace = graceChord(Companion.pi(2, 0, 4));
    Chord chord4 = chord(Companion.pi(3, 0, 4), Companion.fr(2, 4));
    Voice voice = new Voice(alist(chord1, chord2grace, chord3grace, chord4));
    List<BeatOffset> beatOffsets = alist(new BeatOffset(Companion.fr(0, 4), offsetChord1), new BeatOffset(Companion.fr(2, 4), offsetChord2), new BeatOffset(Companion.fr(4, 4), offsetMeasureEnd));
    float is = 1;
    List<VoiceSpacing> voiceSpacings = alist(new VoiceSpacing(voice, is, alist(new ChordSpacing(new ChordNotation(chord1), beatOffsets.get(0).getBeat(), beatOffsets.get(0).getOffsetMm()), new ChordSpacing(new ChordNotation(chord2grace), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm() - 2 * graceDistance), new ChordSpacing(new ChordNotation(chord3grace), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm() - 1 * graceDistance), new ChordSpacing(new ChordNotation(chord4), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm()))));
    MeasureSpacing measureSpacing = new MeasureSpacing(atMeasure(0, 0), is, voiceSpacings, empty, null);
    ColumnSpacing mcs = new ColumnSpacing(-1, alist(measureSpacing), beatOffsets, alist(new BeatOffset(Companion.fr(0, 4), 0), new BeatOffset(Companion.fr(4, 4), offsetMeasureEnd)));
    SystemSpacing system = new SystemSpacing(alist(mcs), 0, 0, offsetMeasureEnd, null, 0);
    return system;
}
Also used : ChordSpacing(com.xenoage.zong.musiclayout.spacing.ChordSpacing) ChordNotation(com.xenoage.zong.musiclayout.notation.ChordNotation) ColumnSpacing(com.xenoage.zong.musiclayout.spacing.ColumnSpacing) MeasureSpacing(com.xenoage.zong.musiclayout.spacing.MeasureSpacing) BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) SystemSpacing(com.xenoage.zong.musiclayout.spacing.SystemSpacing) VoiceSpacing(com.xenoage.zong.musiclayout.spacing.VoiceSpacing) ChordFactory.graceChord(com.xenoage.zong.core.music.chord.ChordFactory.graceChord) Chord(com.xenoage.zong.core.music.chord.Chord) Voice(com.xenoage.zong.core.music.Voice)

Aggregations

ColumnSpacing (com.xenoage.zong.musiclayout.spacing.ColumnSpacing)9 VoiceSpacing (com.xenoage.zong.musiclayout.spacing.VoiceSpacing)6 SystemSpacing (com.xenoage.zong.musiclayout.spacing.SystemSpacing)5 BeatOffset (com.xenoage.zong.musiclayout.spacing.BeatOffset)4 MeasureSpacing (com.xenoage.zong.musiclayout.spacing.MeasureSpacing)4 Voice (com.xenoage.zong.core.music.Voice)3 Chord (com.xenoage.zong.core.music.chord.Chord)2 ChordFactory.graceChord (com.xenoage.zong.core.music.chord.ChordFactory.graceChord)2 ChordNotation (com.xenoage.zong.musiclayout.notation.ChordNotation)2 ChordSpacing (com.xenoage.zong.musiclayout.spacing.ChordSpacing)2 ElementSpacing (com.xenoage.zong.musiclayout.spacing.ElementSpacing)2 Test (org.junit.Test)2 Fraction (com.xenoage.utils.math.Fraction)1 Score (com.xenoage.zong.core.Score)1 ScoreFormat (com.xenoage.zong.core.format.ScoreFormat)1 ColumnHeader (com.xenoage.zong.core.header.ColumnHeader)1 ScoreHeader (com.xenoage.zong.core.header.ScoreHeader)1 Measure (com.xenoage.zong.core.music.Measure)1 Beam (com.xenoage.zong.core.music.beam.Beam)1 Column (com.xenoage.zong.core.music.util.Column)1