Search in sources :

Example 1 with SP

use of com.xenoage.zong.core.music.format.SP in project Zong by Xenoage.

the class BeamStamper method stamp.

/**
 * Computes the stampings for the given beam and returns them.
 * @param beam    the beam to stamp
 * @param staff   the staff stamping of the first chord of the beam
 */
public List<BeamStamping> stamp(BeamSpacing beam, StaffStamping staff) {
    int beamSize = beam.chords.size();
    val leftEndSp = beam.getLeftSp();
    val rightEndSp = beam.getRightSp();
    val primaryStemDir = beam.getStemDirection(0);
    // number of beam lines
    int linesCount = beam.notation.getLinesCount();
    // first guess of the size (is correct for simple beams)
    List<BeamStamping> ret = alist(linesCount);
    // first line (8th line) is always continuous
    val beam8th = new BeamStamping(beam, staff, leftEndSp, rightEndSp, primaryStemDir);
    ret.add(beam8th);
    // this is stored in the notation
    for (int i : range(beam.notation.linesFragments)) {
        int line = i + 1;
        float lineLp = -1 * primaryStemDir.getSign() * (lineHeightIs + beam.notation.gapIs) * 2 * line;
        val beamLinePoints = new LinearInterpolationPoints(leftEndSp.lp + lineLp, rightEndSp.lp + lineLp, leftEndSp.xMm, rightEndSp.xMm);
        // create the line stampings
        float startXMm = 0;
        Fragments fragments = beam.notation.linesFragments.get(i);
        for (int iChord : range(fragments)) {
            Fragment fragment = fragments.get(iChord);
            float stemXMm = beam.getStemEndSp(iChord).xMm;
            if (fragment == Start) {
                // begin a new beam line
                startXMm = stemXMm;
            } else if (fragment == Stop) {
                // end the beam line and stem it
                float stopXMm = stemXMm;
                SP leftSp = sp(startXMm, INSTANCE.interpolateLinear(beamLinePoints, startXMm));
                SP rightSp = sp(stopXMm, INSTANCE.interpolateLinear(beamLinePoints, stopXMm));
                val stamping = new BeamStamping(beam, staff, leftSp, rightSp, primaryStemDir);
                ret.add(stamping);
            } else if (fragment == HookLeft || fragment == HookRight) {
                // left or right hook
                float lengthMm = hookLengthIs * staff.is;
                float x1Mm = (fragment == HookLeft ? stemXMm - lengthMm : stemXMm);
                float x2Mm = (fragment == HookLeft ? stemXMm : stemXMm + lengthMm);
                SP leftSp = sp(x1Mm, INSTANCE.interpolateLinear(beamLinePoints, x1Mm));
                SP rightSp = sp(x2Mm, INSTANCE.interpolateLinear(beamLinePoints, x2Mm));
                val stamping = new BeamStamping(beam, staff, leftSp, rightSp, primaryStemDir);
                ret.add(stamping);
            }
        }
    }
    return ret;
}
Also used : lombok.val(lombok.val) BeamStamping(com.xenoage.zong.musiclayout.stampings.BeamStamping) Fragments(com.xenoage.zong.musiclayout.notation.beam.Fragments) LinearInterpolationPoints(com.xenoage.utils.math.MathUtils.LinearInterpolationPoints) Fragment(com.xenoage.zong.musiclayout.notation.beam.Fragment) SP(com.xenoage.zong.core.music.format.SP)

Example 2 with SP

use of com.xenoage.zong.core.music.format.SP in project Zong by Xenoage.

the class DirectionStamper method createDynamics.

/**
 * Creates a {@link StaffTextStamping} for the given {@link Dynamic}s
 * below the given {@link Chord} and its {@link ChordStampings}.
 */
public StaffTextStamping createDynamics(Dynamic dynamics, Chord chord, ChordStampings chordStampings, SymbolPool symbolPool) {
    StaffStamping staff = chordStampings.staff;
    // positioning
    // below (default): 3 IS below the base line, or 2 IS below the lowest note
    // above: 2 IS above the top line, or 1 IS above the highest note
    float defaultLPBelow = -3f * 2;
    float defaultLPAbove = (staff.linesCount - 1) * 2 + 2 * 2;
    if (chordStampings.noteheads.length > 0) {
        defaultLPBelow = Math.min(defaultLPBelow, chordStampings.getFirstNotehead().position.lp - 2 * 2);
        defaultLPAbove = Math.max(defaultLPAbove, chordStampings.getLastNotehead().position.lp + 1 * 2);
    }
    SP sp = computePosition(dynamics, staff, defaultLPBelow, defaultLPAbove, defaultLPBelow);
    // create text
    CList<FormattedTextElement> elements = clist();
    for (CommonSymbol s : CommonSymbol.getDynamics(dynamics.getValue())) {
        Symbol symbol = symbolPool.getSymbol(s);
        elements.add(new FormattedTextSymbol(symbol, staff.is * FONT_SIZE_IN_IS, FormattedTextStyle.Companion.getDefaultColor()));
    }
    elements.close();
    FormattedTextParagraph paragraph = new FormattedTextParagraph(elements, Alignment.Center);
    FormattedText text = Companion.fText(paragraph);
    // create stamping
    return new StaffTextStamping(text, sp, staff, dynamics);
}
Also used : CommonSymbol(com.xenoage.zong.symbols.common.CommonSymbol) Symbol(com.xenoage.zong.symbols.Symbol) StaffStamping(com.xenoage.zong.musiclayout.stampings.StaffStamping) StaffTextStamping(com.xenoage.zong.musiclayout.stampings.StaffTextStamping) SP(com.xenoage.zong.core.music.format.SP) CommonSymbol(com.xenoage.zong.symbols.common.CommonSymbol)

Example 3 with SP

use of com.xenoage.zong.core.music.format.SP in project Zong by Xenoage.

the class DirectionStamper method createPedal.

/**
 * Creates a {@link StaffSymbolStamping} for the given {@link Pedal}.
 */
public StaffSymbolStamping createPedal(Pedal pedal, StamperContext context) {
    val staff = context.getCurrentStaffStamping();
    // positioning
    // below (default): 4 IS below the base line
    // above: 3 IS above the top line
    float defaultLPBelow = -4f * 2;
    float defaultLPAbove = (staff.linesCount - 1) * 2 + 3 * 2;
    SP sp = computePosition(pedal, staff, defaultLPBelow, defaultLPAbove, defaultLPBelow);
    // create stamping
    Symbol symbol = context.getSymbol(CommonSymbol.getPedal(pedal.getType()));
    return new StaffSymbolStamping(null, staff, symbol, null, sp, 1, false);
}
Also used : lombok.val(lombok.val) CommonSymbol(com.xenoage.zong.symbols.common.CommonSymbol) Symbol(com.xenoage.zong.symbols.Symbol) StaffSymbolStamping(com.xenoage.zong.musiclayout.stampings.StaffSymbolStamping) SP(com.xenoage.zong.core.music.format.SP)

Example 4 with SP

use of com.xenoage.zong.core.music.format.SP in project Zong by Xenoage.

the class SlurStamper method createStartForFirstSystem.

/**
 * Creates a {@link SlurStamping} for a curved line that
 * starts at this system but spans at least one other system.
 */
SlurStamping createStartForFirstSystem(StaffStamping staff, SP defaultSp, Slur slur) {
    SlurWaypoint wp1 = slur.getStart();
    // end points of the bezier curve
    SP p1 = computeEndPoint(slur, defaultSp, wp1.getBezierPoint());
    SP p2 = sp(staff.positionMm.x + staff.lengthMm, p1.lp);
    // control points of the bezier curve
    BezierPoint b1 = wp1.getBezierPoint();
    SP c1 = (// custom formatting
    b1 != null && b1.getControl() != null ? // custom formatting
    b1.getControl() : // default formatting
    computeLeftControlPoint(slur, p1, p2, staff));
    // default formatting
    SP c2 = computeRightControlPoint(slur, p1, p2, staff);
    return new SlurStamping(slur, p1, p2, c1, c2, staff, staff);
}
Also used : BezierPoint(com.xenoage.zong.core.music.format.BezierPoint) SlurStamping(com.xenoage.zong.musiclayout.stampings.SlurStamping) SP(com.xenoage.zong.core.music.format.SP) SlurWaypoint(com.xenoage.zong.core.music.slur.SlurWaypoint)

Example 5 with SP

use of com.xenoage.zong.core.music.format.SP in project Zong by Xenoage.

the class ChordStamper method stampAll.

/**
 * Returns all the stampings for the given {@link Chord}, including beams,
 * tuplets, slurs and other attachments.
 *
 * The given {@link OpenSlursCache},
 * {@link OpenLyricsCache}, {@link LastLyrics} and {@link OpenTupletsCache} may be modified.
 */
public List<Stamping> stampAll(ChordNotation chord, float xMm, BeamSpacing beam, StaffStampings staffStampings, StamperContext context, FormattedTextStyle defaultLyricStyle, OpenSlursCache openSlursCache, OpenLyricsCache openLyricsCache, LastLyrics lastLyrics, OpenTupletsCache openTupletsCache) {
    List<Stamping> ret = alist();
    Chord element = chord.getElement();
    int staffIndex = context.staffIndex;
    int systemIndex = context.systemIndex;
    // noteheads, leger lines, dots, accidentals, stem, flags, articulations
    ChordStampings chordSt = stampCore(chord, xMm, context);
    chordSt.addAllTo(ret);
    // beam
    if (beam != null) {
        // stamp the whole beam (when we find the beginning of the beam)
        // TIDY: create/store beam stampings elsewhere?
        Beam beamElement = beam.notation.element;
        int chordIndex = beamElement.getWaypointIndex(element);
        if (chordIndex == 0) {
            ret.addAll(beamStamper.stamp(beam, context.getCurrentStaffStamping()));
        }
    }
    // ties and slurs
    for (Slur slur : element.getSlurs()) {
        SlurWaypoint wp = slur.getWaypoint(element);
        WaypointPosition pos = slur.getWaypointPosition(element);
        // TODO: choose top/bottom
        int noteIndex = notNull(wp.getNoteIndex(), 0);
        NoteheadStamping notehead = chordSt.noteheads[noteIndex];
        // define the placement: above or below (TODO: better strategy)
        VSide side = slurStamper.getSide(slur);
        // compute position
        val staff = staffStampings.get(systemIndex, notehead.parentStaff.staffIndex);
        val slurCache = openSlursCache.getOrCreate(slur);
        float distanceIs = slurStamper.getAdditionalDistanceIs(chord, slur.getSide());
        SP defaultSp = sp(notehead.position.xMm, notehead.position.lp + side.getDir() * distanceIs * 2);
        if (pos == WaypointPosition.Start)
            slurCache.setStart(defaultSp, staff, systemIndex);
        else
            slurCache.setStop(defaultSp, staff, systemIndex);
    }
    // lyric
    List<Lyric> lyrics = element.getLyrics();
    if (lyrics.size() > 0) {
        float baseLine = -10;
        for (Lyric lyric : lyrics) {
            if (lyric != null) {
                SyllableType lyricType = lyric.getSyllableType();
                StaffTextStamping lastLyric = lastLyrics.get(staffIndex, lyric.getVerse());
                if (lyricType == SyllableType.Extend) {
                    // extend
                    if (// TODO: frame breaks...
                    lastLyric != null) {
                        // remember it
                        openLyricsCache.setUnderscore((Lyric) lastLyric.getElement(), lastLyric, chordSt.noteheads[0], /* TODO*/
                        staffIndex);
                    }
                } else {
                    // normal lyric
                    // create text stamping
                    StaffTextStamping sts = lyricStamper.createSyllableStamping(lyric, defaultLyricStyle, context.getCurrentStaffStamping(), chordSt.noteheads[0].position.xMm, baseLine);
                    ret.add(sts);
                    // when middle or end syllable, add a hypen between the preceding syllable and this syllable
                    if (// TODO: frame breaks...
                    lastLyric != null) {
                        if (lyricType == SyllableType.Middle || lyricType == SyllableType.End) {
                            StaffTextStamping hyphenStamping = lyricStamper.createHyphenStamping(lastLyric, sts, defaultLyricStyle);
                            ret.add(hyphenStamping);
                        }
                    }
                    // remember this lyric as the currently last one in the current staff and verse
                    lastLyrics.set(staffIndex, lyric.getVerse(), sts);
                }
            }
            baseLine += -5;
        }
    }
    // directions
    ret.addAll(directionStamper.stampForChord(chordSt, context.layouter.symbols));
    // tuplet
    Tuplet tuplet = element.getTuplet();
    if (tuplet != null) {
        openTupletsCache.addChord(element, tuplet, chordSt);
    }
    return ret;
}
Also used : lombok.val(lombok.val) WaypointPosition(com.xenoage.zong.core.music.WaypointPosition) SlurWaypoint(com.xenoage.zong.core.music.slur.SlurWaypoint) SlurWaypoint(com.xenoage.zong.core.music.slur.SlurWaypoint) VSide(com.xenoage.utils.math.VSide) Beam(com.xenoage.zong.core.music.beam.Beam) Tuplet(com.xenoage.zong.core.music.tuplet.Tuplet) Slur(com.xenoage.zong.core.music.slur.Slur) Lyric(com.xenoage.zong.core.music.lyric.Lyric) SyllableType(com.xenoage.zong.core.music.lyric.SyllableType) Chord(com.xenoage.zong.core.music.chord.Chord) ChordStampings(com.xenoage.zong.musiclayout.layouter.scoreframelayout.util.ChordStampings) SP(com.xenoage.zong.core.music.format.SP)

Aggregations

SP (com.xenoage.zong.core.music.format.SP)13 lombok.val (lombok.val)7 BezierPoint (com.xenoage.zong.core.music.format.BezierPoint)4 SlurWaypoint (com.xenoage.zong.core.music.slur.SlurWaypoint)4 SlurStamping (com.xenoage.zong.musiclayout.stampings.SlurStamping)4 StaffTextStamping (com.xenoage.zong.musiclayout.stampings.StaffTextStamping)4 Symbol (com.xenoage.zong.symbols.Symbol)4 CommonSymbol (com.xenoage.zong.symbols.common.CommonSymbol)4 VSide (com.xenoage.utils.math.VSide)2 Slur (com.xenoage.zong.core.music.slur.Slur)2 StaffSymbolStamping (com.xenoage.zong.musiclayout.stampings.StaffSymbolStamping)2 MaybeNull (com.xenoage.utils.annotations.MaybeNull)1 LinearInterpolationPoints (com.xenoage.utils.math.MathUtils.LinearInterpolationPoints)1 WaypointPosition (com.xenoage.zong.core.music.WaypointPosition)1 Beam (com.xenoage.zong.core.music.beam.Beam)1 Chord (com.xenoage.zong.core.music.chord.Chord)1 Lyric (com.xenoage.zong.core.music.lyric.Lyric)1 SyllableType (com.xenoage.zong.core.music.lyric.SyllableType)1 Tuplet (com.xenoage.zong.core.music.tuplet.Tuplet)1 ContinuedSlur (com.xenoage.zong.musiclayout.continued.ContinuedSlur)1