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;
}
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);
}
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);
}
}
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;
}
Aggregations