package com.xenoage.zong.musiclayout.stamper; import static com.xenoage.utils.collections.CollectionUtils.alist; import static com.xenoage.utils.collections.CollectionUtils.getLast; import static com.xenoage.zong.core.text.FormattedText.fText; import java.util.List; import com.xenoage.utils.kernel.Range; import com.xenoage.zong.core.header.ColumnHeader; import com.xenoage.zong.core.header.ScoreHeader; import com.xenoage.zong.core.music.volta.Volta; import com.xenoage.zong.core.text.Alignment; import com.xenoage.zong.core.text.FormattedText; import com.xenoage.zong.core.text.FormattedTextStyle; import com.xenoage.zong.musiclayout.continued.ContinuedVolta; import com.xenoage.zong.musiclayout.continued.OpenVolta; import com.xenoage.zong.musiclayout.stampings.StaffStamping; import com.xenoage.zong.musiclayout.stampings.VoltaStamping; /** * Creates the {@link VoltaStamping} of a {@link Volta}. * * @author Andreas Wenger */ public class VoltaStamper { public static final VoltaStamper voltaStamper = new VoltaStamper(); /** * 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; } /** * Creates a {@link VoltaStamping} for the given volta. * * The start and end measure may be outside the staff. If the start measure is outside the * staff, no left hook and no caption is drawn, since the volta is continued. * If the end measure is outside the staff, no right hook is drawn, since the * volta is continued in the next system. */ public VoltaStamping stamp(Volta volta, StaffStamping staff, FormattedTextStyle textStyle) { boolean leftHook = true; boolean rightHook = volta.isRightHook(); boolean caption = true; //clip start measure to staff Range systemMeasures = staff.system.getMeasures(); int start = volta.getMP().measure; if (start < systemMeasures.getStart()) { start = systemMeasures.getStart(); leftHook = false; caption = false; } //clip end measure to staff int end = volta.getEndMeasureIndex(); if (end > systemMeasures.getStop()) { end = systemMeasures.getStop(); rightHook = false; } //create stamping return stampInStaff(volta, start, end, staff, textStyle, caption, leftHook, rightHook); } /** * Creates a {@link VoltaStamping} for the given volta spanning * from the given start measure to the given end measure on the given staff * (global measure indices). Left and right hooks and the caption are optional. * The measure indices must be within the staff. */ private VoltaStamping stampInStaff(Volta volta, int startMeasureIndex, int endMeasureIndex, StaffStamping staff, FormattedTextStyle textStyle, boolean drawCaption, boolean drawLeftHook, boolean drawRightHook) { //get start and end x coordinate of measure float x1 = staff.system.getMeasureStartMm(startMeasureIndex) + staff.is / 2; float x2 = staff.system.getMeasureEndMm(endMeasureIndex) - staff.is / 2; //line position of volta line: 5 IS over top line float lp = (staff.linesCount - 1 + 5) * 2; //caption FormattedText caption = null; if (drawCaption && volta.getCaption().length() > 0) { caption = fText(volta.getCaption(), textStyle, Alignment.Left); } //create stamping return new VoltaStamping(volta, lp, x1, x2, caption, drawLeftHook, drawRightHook, staff); } }