use of com.xenoage.zong.musiclayout.stampings.StaffStamping in project Zong by Xenoage.
the class LyricStamper method createUnderscoreStampings.
/**
* Creates and returns at least one {@link StaffTextStamping} containing
* an underscore line ("___") behind the given lyric stamping
* up to the given notehead stamping.
* If more than one line is needed, a stamping for each line is returned.
*
* A list of consecutive staff stampings must be given, containing at least
* the beginning and the ending staff of the underscore. If the underscore needs
* only one staff, it may also be null.
*
* The left syllable must be given, even if it is not in the current frame.
* The right notehead is optional. If not given, the underscore is drawn over
* all given following staves.
*/
public IList<StaffTextStamping> createUnderscoreStampings(StaffTextStamping syllableLeft, NoteheadStamping noteheadRight, FormattedTextStyle style, List<StaffStamping> staffStampings) {
if (syllableLeft == null)
throw new IllegalArgumentException("Left syllable must be given");
CList<StaffTextStamping> ret = clist();
// measure width of "_"
float widthU = Companion.fText("_", style, Alignment.Center).getFirstParagraph().getMetrics().getWidth();
// compute the horizontal start position, base line and element
float widthLeft = syllableLeft.getText().getFirstParagraph().getMetrics().getWidth();
// widthU / 4: just some distance
float startX = syllableLeft.position.xMm + widthLeft / 2 + widthU / 4;
float baseLine = syllableLeft.position.lp;
Object element = syllableLeft.element;
// if end notehead is given, compute the end position
float endX = 0;
if (noteheadRight != null) {
endX = noteheadRight.position.xMm;
}
// underscore line on a single staff?
if (noteheadRight != null && syllableLeft.parentStaff == noteheadRight.parentStaff) {
// simple case
ret.add(createUnderscoreStamping(startX, endX, baseLine, widthU, style, syllableLeft.parentStaff, element));
} else {
It<StaffStamping> staves = new It<>(staffStampings);
StaffStamping currentStaff = null;
// only true, when start stamping is found
boolean firstStaffFound = false;
// only true, when stop stamping is found
boolean lastStaffFound = false;
// find the start staff
StaffStamping s1 = syllableLeft.parentStaff;
while (staves.hasNext()) {
currentStaff = staves.next();
if (currentStaff == s1) {
firstStaffFound = true;
break;
}
}
// if not found, begin at the very beginning
if (!firstStaffFound) {
staves = new It<>(staffStampings);
}
// first staff (if any): begin at the stamping, go to the end of the system
if (firstStaffFound) {
ret.add(createUnderscoreStamping(startX, currentStaff.positionMm.x + currentStaff.lengthMm, baseLine, widthU, style, currentStaff, element));
}
// to the end of the system
while (staves.hasNext()) {
currentStaff = staves.next();
if (noteheadRight != null && currentStaff == noteheadRight.parentStaff) {
// stop, because this is the last staff, where we have the stop notehead
lastStaffFound = true;
break;
}
// create underscore over whole staff
ret.add(createUnderscoreStamping(currentStaff.positionMm.x, currentStaff.positionMm.x + currentStaff.lengthMm, baseLine, widthU, style, currentStaff, element));
}
// system, stop at the notehead
if (lastStaffFound) {
ret.add(createUnderscoreStamping(currentStaff.positionMm.x, noteheadRight.position.xMm, baseLine, widthU, style, currentStaff, element));
}
}
return ret;
}
use of com.xenoage.zong.musiclayout.stampings.StaffStamping in project Zong by Xenoage.
the class TupletStamper method createTupletStamping.
/**
* Computes the {@link TupletStamping} for the given {@link ChordStampings}
* and returns it.
*/
public TupletStamping createTupletStamping(Tuplet tuplet, OpenTupletsCache cache, SymbolPool symbolPool) {
StaffStamping ss = cache.getChord(tuplet.getChords().get(0), tuplet).staff;
// horizontal position of the bracket
float xDistance = ss.is / 4;
float x1Mm = cache.getChord(tuplet.getFirstChord(), tuplet).xMm - xDistance;
ChordStampings cs2 = cache.getChord(tuplet.getLastChord(), tuplet);
// TODO: notehead width!
float cs2Width = ss.is * 1.2f;
float x2Mm = cs2.xMm + cs2Width + xDistance;
// vertical position of the bracket (above or below) depends on the directions
// of the majority of the stems
int stemDir = 0;
for (Chord chord : tuplet.getChords()) {
ChordStampings cs = cache.getChord(chord, tuplet);
if (cs.stem != null) {
stemDir += cs.stem.direction.getSign();
}
}
// 1: above, -1: below
int placement = (stemDir < 0 ? 1 : -1);
// compute position of start and end point
// by default, the bracket is 1.5 IS away from the end of the stems
// when there is no stem, the innermost notehead is used
// TODO: if stems of inner chords are longer, correct!
float distanceLp = 1.5f * 2;
float y1Lp = computeBracketLP(cache.getChord(tuplet.getFirstChord(), tuplet), placement, distanceLp);
float y2Lp = computeBracketLP(cache.getChord(tuplet.getLastChord(), tuplet), placement, distanceLp);
// at least 2 IS over top barline / under bottom barline
if (// above staff
placement == 1) {
y1Lp = Math.max(y1Lp, (ss.linesCount - 1) * 2 + 4);
y2Lp = Math.max(y1Lp, (ss.linesCount - 1) * 2 + 4);
} else // below staff
{
y1Lp = Math.min(y1Lp, 0 - 4);
y2Lp = Math.min(y1Lp, 0 - 4);
}
// text
float fontSize = 10 * ss.is / 1.6f;
FormattedText text = createText(tuplet.getActualNotes(), fontSize, symbolPool);
// return result
return new TupletStamping(sp(x1Mm, y1Lp), sp(x2Mm, y2Lp), true, text, ss);
}
use of com.xenoage.zong.musiclayout.stampings.StaffStamping in project Zong by Xenoage.
the class PlaybackLayouter method createCursorAt.
/**
* Returns a new {@link SystemCursorStamping} at the given {@link Time},
* representing the current playback position, or null if there is none.
*/
public SystemCursorStamping createCursorAt(Time time) {
ScoreFrameLayout frame = scoreLayout.getScoreFrameLayout(time.getMeasure());
if (frame != null) {
StaffStamping topStaff = frame.getStaffStamping(0, time.getMeasure());
StaffStamping bottomStaff = frame.getStaffStamping(scoreLayout.score.getStavesCount() - 1, time.getMeasure());
if (topStaff != null && bottomStaff != null)
return new SystemCursorStamping(topStaff, bottomStaff, frame.getPositionX(time));
}
return null;
}
use of com.xenoage.zong.musiclayout.stampings.StaffStamping in project Zong by Xenoage.
the class ScoreSelectionLayouter method setCursor.
/**
* Sets a {@link StaffCursorStamping} for the given {@link Cursor}.
*/
private void setCursor(Cursor cursor) {
// remove old stampings
removeSelectionStampings();
// find frame
MP mp = cursor.getMP();
int measure = mp.measure;
ScoreFrameLayout frame = scoreLayout.getScoreFrameLayout(measure);
if (frame != null) {
StaffStamping staff = frame.getStaffStamping(mp.staff, measure);
if (staff != null) {
frame.setSelectionStampings(ilist(new StaffCursorStamping(frame.getPositionX(mp.getTime()), -0.5f, staff)));
}
}
}
use of com.xenoage.zong.musiclayout.stampings.StaffStamping in project Zong by Xenoage.
the class ScoreLayout method getMP.
/**
* Computes and returns the appropriate musical position
* to the given metric position, or null, if unknown.
*/
public MP getMP(ScoreLayoutPos coordinates) {
if (coordinates == null)
return null;
// first test, if there is a staff element.
ScoreFrameLayout frame = frames.get(coordinates.frameIndex);
StaffStamping staff = frame.getStaffStampingAt(coordinates.pMm);
// if there is no staff, return null
if (staff == null) {
return null;
} else // otherwise, compute the beat at this position and return it
{
float posX = coordinates.pMm.x - staff.positionMm.x;
return staff.getMpAtX(posX);
}
}
Aggregations