Search in sources :

Example 1 with StaffStamping

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;
}
Also used : StaffStamping(com.xenoage.zong.musiclayout.stampings.StaffStamping) StaffTextStamping(com.xenoage.zong.musiclayout.stampings.StaffTextStamping) It(com.xenoage.utils.iterators.It)

Example 2 with StaffStamping

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);
}
Also used : StaffStamping(com.xenoage.zong.musiclayout.stampings.StaffStamping) FormattedText(com.xenoage.zong.core.text.FormattedText) ChordStampings(com.xenoage.zong.musiclayout.layouter.scoreframelayout.util.ChordStampings) Chord(com.xenoage.zong.core.music.chord.Chord) TupletStamping(com.xenoage.zong.musiclayout.stampings.TupletStamping)

Example 3 with StaffStamping

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;
}
Also used : SystemCursorStamping(com.xenoage.zong.musiclayout.stampings.SystemCursorStamping) StaffStamping(com.xenoage.zong.musiclayout.stampings.StaffStamping) ScoreFrameLayout(com.xenoage.zong.musiclayout.ScoreFrameLayout)

Example 4 with StaffStamping

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)));
        }
    }
}
Also used : MP(com.xenoage.zong.core.position.MP) StaffCursorStamping(com.xenoage.zong.musiclayout.stampings.StaffCursorStamping) StaffStamping(com.xenoage.zong.musiclayout.stampings.StaffStamping) ScoreFrameLayout(com.xenoage.zong.musiclayout.ScoreFrameLayout)

Example 5 with StaffStamping

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);
    }
}
Also used : StaffStamping(com.xenoage.zong.musiclayout.stampings.StaffStamping)

Aggregations

StaffStamping (com.xenoage.zong.musiclayout.stampings.StaffStamping)21 Point2f (com.xenoage.utils.math.geom.Point2f)10 BitmapStaff (com.xenoage.zong.musiclayout.stampings.bitmap.BitmapStaff)8 Color (com.xenoage.utils.color.Color)6 FormattedText (com.xenoage.zong.core.text.FormattedText)5 BitmapLine (com.xenoage.zong.musiclayout.stampings.bitmap.BitmapLine)5 StaffTextStamping (com.xenoage.zong.musiclayout.stampings.StaffTextStamping)3 BarlineGroup (com.xenoage.zong.core.music.group.BarlineGroup)2 FormattedTextStyle (com.xenoage.zong.core.text.FormattedTextStyle)2 ScoreFrameLayout (com.xenoage.zong.musiclayout.ScoreFrameLayout)2 BarlineStamping (com.xenoage.zong.musiclayout.stampings.BarlineStamping)2 StaffCursorStamping (com.xenoage.zong.musiclayout.stampings.StaffCursorStamping)2 SystemCursorStamping (com.xenoage.zong.musiclayout.stampings.SystemCursorStamping)2 TupletStamping (com.xenoage.zong.musiclayout.stampings.TupletStamping)2 MaybeNull (com.xenoage.utils.annotations.MaybeNull)1 It (com.xenoage.utils.iterators.It)1 Rectangle2f (com.xenoage.utils.math.geom.Rectangle2f)1 MeasureNumbering (com.xenoage.zong.core.format.MeasureNumbering)1 ColumnHeader (com.xenoage.zong.core.header.ColumnHeader)1 Barline (com.xenoage.zong.core.music.barline.Barline)1