void LyricsLine::layout() { if (lyrics()->ticks() > 0) { // melisma setLineWidth(Spatium(MELISMA_DEFAULT_LINE_THICKNESS)); // Lyrics::_ticks points to the beginning of the last spanned segment, // but the line shall include it: // include the duration of this last segment in the melisma duration bool ticksSet = false; Segment* lastSeg = score()->tick2segment(lyrics()->endTick(), false, Segment::Type::ChordRest, false); if (lastSeg) { // if last segment found, locate the first non-empty ChordRest // in the same staff of this LyricsLine and use its duration int firstTrack = (track() >> 2) << 2; int lastTrack = firstTrack + VOICES; for (int i = firstTrack; i < lastTrack; i++) { ChordRest* cr = static_cast<ChordRest*>(lastSeg->elementAt(i)); if (cr) { setTicks(lyrics()->ticks() + cr->durationTicks()); ticksSet = true; break; } } } // no suitable ChordRest found? go to the end of the last known segment if (!ticksSet) setTicks(lyrics()->ticks()); }
Note* nextChordNote(Note* note) { int track = note->track(); int fromTrack = (track / VOICES) * VOICES; int toTrack = fromTrack + VOICES; // TODO : limit to same instrument, not simply to same staff! Segment* seg = note->chord()->segment()->nextCR(track, true); while (seg) { Element* targetElement = seg->elementAt(track); // if a chord exists in the same track, return its top note if (targetElement && targetElement->isChord()) return toChord(targetElement)->upNote(); // if not, return topmost chord in track range for (int i = fromTrack ; i < toTrack; i++) { targetElement = seg->elementAt(i); if (targetElement && targetElement->isChord()) return toChord(targetElement)->upNote(); } seg = seg->nextCR(track, true); } return nullptr; }
Note* prevChordNote(Note* note) { int track = note->track(); int fromTrack = (track / VOICES) * VOICES; int toTrack = fromTrack + VOICES; // TODO : limit to same instrument, not simply to same staff! Segment* seg = note->chord()->segment()->prev1(); while (seg) { if (seg->segmentType() == Segment::Type::ChordRest) { Element* targetElement = seg->elementAt(track); // if a chord exists in the same track, return its top note if (targetElement != nullptr && targetElement->type() == Element::Type::CHORD) return static_cast<Chord*>(targetElement)->upNote(); // if not, return topmost chord in track range for (int i = fromTrack ; i < toTrack; i++) { targetElement = seg->elementAt(i); if (targetElement != nullptr && targetElement->type() == Element::Type::CHORD) return static_cast<Chord*>(targetElement)->upNote(); } } seg = seg->prev1(); } return nullptr; }