use of com.xenoage.zong.core.header.ColumnHeader in project Zong by Xenoage.
the class ScoreDocScoreView method updateScreen.
@Override
public void updateScreen(Size2i screenSizePx, float zoom) {
this.screenSizePx = screenSizePx;
this.zoom = zoom;
// recompute the layout, so that each page fits into the available screen space
Size2f pageSizeMm = pxToMm(screenSizePx, zoom);
float marginMm = pxToMm(marginPx, zoom);
PageFormat pageFormat = new PageFormat(pageSizeMm, new PageMargins(marginMm, marginMm, marginMm, marginMm));
Size2f frameSizeMm = new Size2f(pageFormat.getUseableWidth(), pageFormat.getUseableHeight());
// first page needs space for title text
titleTextHeightPx = screenSizePx.height / 20f;
float firstFrameOffsetY = pxToMm(titleTextHeightPx, zoom);
Size2f firstFrameSizeMm = new Size2f(frameSizeMm.width, frameSizeMm.height - firstFrameOffsetY);
// delete unnecessary layout information, like system distances or system breaks
Score score = doc.getScore();
score.setFormat(new ScoreFormat());
ScoreHeader header = score.getHeader();
for (int i : range(header.getSystemLayouts())) {
SystemLayout sl = header.getSystemLayout(i);
if (sl != null)
sl.setDistance(SystemLayout.defaultDistance);
}
for (int i : range(header.getColumnHeaders())) {
ColumnHeader ch = header.getColumnHeader(i);
if (ch.getMeasureBreak() != null)
ch.setBreak(null);
}
// layout the score to find out the needed space
Context context = new Context(score, App.getSymbolPool(), doc.getLayout().getDefaults().getLayoutSettings());
Target target = new Target(alist(new ScoreLayoutArea(firstFrameSizeMm)), new ScoreLayoutArea(frameSizeMm), true);
ScoreLayouter layouter = new ScoreLayouter(context, target);
ScoreLayout scoreLayout = layouter.createScoreLayout();
// create and fill at least one page
Layout layout = new Layout(doc.getLayout().getDefaults());
ScoreFrameChain chain = null;
for (int i = 0; i < scoreLayout.frames.size(); i++) {
Page page = new Page(pageFormat);
Point2f position;
Size2f size;
if (i == 0) {
// first page
position = new Point2f(pageSizeMm.width / 2, pageSizeMm.height / 2 + firstFrameOffsetY);
size = firstFrameSizeMm;
} else {
// other pages
position = new Point2f(pageSizeMm.width / 2, pageSizeMm.height / 2);
size = frameSizeMm;
}
ScoreFrame frame = new ScoreFrame();
frame.setPosition(position);
frame.setSize(size);
page.addFrame(frame);
layout.addPage(page);
if (chain == null) {
chain = new ScoreFrameChain(score);
chain.setScoreLayout(scoreLayout);
}
chain.add(frame);
}
this.layout = layout;
}
use of com.xenoage.zong.core.header.ColumnHeader in project Zong by Xenoage.
the class ColumnSpacer method compute.
/**
* Computes a {@link ColumnSpacing} from a measure column.
* @param context the current context, with the current {@link MP} and precomputed
* element {@link Notation}s
* @param createLeading true, if a leading spacing has to be created, otherwise false
* @param notations the precomputed notations of the measure and voice elements
*/
public ColumnSpacing compute(Context context, boolean createLeading, Notations notations) {
context.saveMp();
int measureIndex = context.mp.measure;
Column column = context.score.getColumn(measureIndex);
ColumnHeader columnHeader = context.score.getHeader().getColumnHeader(measureIndex);
// compute the optimal spacings for each voice separately
List<List<VoiceSpacing>> voiceSpacingsByStaff = alist();
for (int iStaff : range(column)) {
List<VoiceSpacing> vss = alist();
Measure measure = column.get(iStaff);
for (Voice voice : measure.getVoices()) {
context.mp = MP.atVoice(iStaff, measureIndex, measure.getVoices().indexOf(voice));
VoiceSpacing vs = singleVoiceSpacer.compute(context, notations);
vss.add(vs);
}
voiceSpacingsByStaff.add(vss);
}
// compute the measure elements (like inner clefs) and accordingly updated voice spacings
ArrayList<List<ElementSpacing>> optimalMeasureElementsSpacingsByStaff = alist();
for (int iStaff : range(column)) {
context.mp = MP.atMeasure(iStaff, measureIndex);
List<ElementSpacing> measureSpacing = measureElementsSpacer.compute(context, createLeading, voiceSpacingsByStaff.get(iStaff), notations);
optimalMeasureElementsSpacingsByStaff.add(measureSpacing);
}
// compute the common beat offsets of this measure column
Fraction measureBeats = context.score.getMeasureBeats(measureIndex);
VoiceSpacingsByStaff voiceSpacings = new VoiceSpacingsByStaff(voiceSpacingsByStaff);
List<BeatOffset> beatOffsets = voicesBeatOffsetter.compute(voiceSpacings.getAll(), measureBeats, context.settings.offsetBeatsMinimal);
// recompute beat offsets with respect to barlines
BarlinesBeatOffsetter.Result offsets = barlinesBeatOffsetter.compute(beatOffsets, columnHeader, context.score.getMaxIS());
beatOffsets = offsets.voiceElementOffsets;
List<BeatOffset> barlineOffsets = offsets.barlineOffsets;
// compute the spacings for the whole column, so that equal beats are aligned
ArrayList<List<ElementSpacing>> alignedMeasureElementsSpacingsByStaff = alist();
for (int iStaff : range(column)) {
Measure measure = column.get(iStaff);
// voice spacings
for (int iVoice : range(measure.getVoices())) alignedVoicesSpacer.compute(voiceSpacings.get(iStaff, iVoice), beatOffsets);
// measure elements, based on the aligned voice spacings
context.mp = atMeasure(iStaff, measureIndex);
alignedMeasureElementsSpacingsByStaff.add(measureElementsSpacer.compute(context, createLeading, voiceSpacings.getStaff(iStaff), notations));
}
// compute spacings for each staff
List<MeasureSpacing> measureSpacings = alist(column.size());
for (int iStaff : range(column)) {
// create leading spacing, if needed
LeadingSpacing leadingSpacing = null;
if (createLeading) {
context.mp = atBeat(iStaff, measureIndex, 0, Fraction.Companion.get_0());
leadingSpacing = leadingSpacer.compute(context, notations);
}
// create measure spacing
float interlineSpace = context.score.getInterlineSpace(iStaff);
measureSpacings.add(new MeasureSpacing(atMeasure(iStaff, measureIndex), interlineSpace, voiceSpacings.getStaff(iStaff), alignedMeasureElementsSpacingsByStaff.get(iStaff), leadingSpacing));
}
context.restoreMp();
return new ColumnSpacing(measureIndex, measureSpacings, beatOffsets, barlineOffsets);
}
use of com.xenoage.zong.core.header.ColumnHeader in project Zong by Xenoage.
the class ScoreTest method testColumnElements.
private static <T> void testColumnElements(List<Tuple2<MP, T>> expectedElements, Score score, BiFunction<ColumnHeader, Fraction, T> getElementAtBeat) {
for (Tuple2<MP, T> expectedElement : expectedElements) {
MP mp = expectedElement.get1();
ColumnHeader columnHeader = score.getColumnHeader(mp.measure);
T element = getElementAtBeat.apply(columnHeader, mp.beat);
assertNotNull("" + mp, element);
assertEquals("" + mp, expectedElement.get2(), element);
}
}
use of com.xenoage.zong.core.header.ColumnHeader in project Zong by Xenoage.
the class VoltaStamper method stampSystem.
/**
* Creates all volta stampings in the given system, including the voltas which
* are still open from the last system.
* @param openVolta input and output parameter: voltas, which are still open from the
* last system. After the method returns, it contains the voltas which
* are still open after this system
*/
public List<VoltaStamping> stampSystem(StaffStamping systemFirstStaff, OpenVolta openVolta, ScoreHeader header, FormattedTextStyle textStyle) {
List<VoltaStamping> ret = alist();
// stamp open volta
if (openVolta.volta != null) {
ret.add(stamp(openVolta.volta.element, systemFirstStaff, textStyle));
}
// stamp voltas beginning in this system
for (int iMeasure : systemFirstStaff.system.getMeasures()) {
ColumnHeader columnHeader = header.getColumnHeader(iMeasure);
if (columnHeader.getVolta() != null) {
ret.add(stamp(columnHeader.getVolta(), systemFirstStaff, textStyle));
}
}
// remember open volta
int systemEndMeasureIndex = systemFirstStaff.system.getEndMeasure();
if (ret.size() > 0 && getLast(ret).element.getEndMeasureIndex() > systemEndMeasureIndex) {
openVolta.volta = new ContinuedVolta(getLast(ret).element);
} else {
openVolta.volta = null;
}
return ret;
}
use of com.xenoage.zong.core.header.ColumnHeader in project Zong by Xenoage.
the class ColumnElementRemoveTest method test.
@Test
public void test() {
Score score = ScoreFactory.create1Staff4Measures();
CommandPerformer cmd = score.getCommandPerformer();
ColumnHeader column2 = score.getColumnHeader(2);
// write middle barline
Barline b = Barline.Companion.barline(BarlineStyle.LightHeavy);
cmd.execute(new ColumnElementWrite(b, column2, Companion.fr(1, 4), null));
// remove it
cmd.execute(new ColumnElementRemove(column2, b));
assertEquals(0, column2.getMiddleBarlines().size());
// undo. should be here again
cmd.undo();
assertEquals(b, column2.getMiddleBarlines().get(Companion.fr(1, 4)));
}
Aggregations