2012-05-26 14:26:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
|
|
|
// Music Composition & Notation
|
|
|
|
//
|
|
|
|
// Copyright (C) 2002-2011 Werner Schweer
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2
|
|
|
|
// as published by the Free Software Foundation and appearing in
|
|
|
|
// the file LICENCE.GPL
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "lyrics.h"
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
|
|
|
|
#include "chord.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
#include "score.h"
|
|
|
|
#include "sym.h"
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
#include "system.h"
|
|
|
|
#include "xml.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
namespace Ms {
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
// all in sp. units:
|
|
|
|
static const qreal MELISMA_DEFAULT_LINE_THICKNESS = 0.10; // for melisma line only;
|
|
|
|
static const qreal MELISMA_DEFAULT_PAD = 0.10; // the empty space before a melisma line
|
|
|
|
static const qreal LYRICS_DASH_DEFAULT_STEP = 16.0; // the max. distance between dashes
|
|
|
|
static const qreal LYRICS_DASH_DEFAULT_PAD = 0.05; // the min. empty space before and after a dash
|
|
|
|
static const qreal LYRICS_DASH_MIN_LENGTH = 0.25; // below this length, the dash is skipped
|
|
|
|
// These values are used when USE_FONT_DASH_METRIC is not defined in lyrics.h
|
|
|
|
static const qreal LYRICS_DASH_DEFAULT_LENGHT = 0.80; // in sp. units
|
|
|
|
static const qreal LYRICS_DASH_DEFAULT_LINE_THICKNESS = 0.15; // in sp. units
|
|
|
|
static const qreal LYRICS_DASH_Y_POS_RATIO = 0.25; // the fraction of lyrics font tot. height to
|
|
|
|
// raise the dashes above text base line;
|
|
|
|
// this usually raises at about 2/3 of x-height
|
|
|
|
// sone useful values:
|
|
|
|
static const qreal HALF = 0.5;
|
|
|
|
static const qreal TWICE = 2.0;
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
// searchNextLyrics
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
static Lyrics* searchNextLyrics(Segment* s, int staffIdx, int verse)
|
|
|
|
{
|
|
|
|
Lyrics* l = 0;
|
|
|
|
while ((s = s->next1(Segment::Type::ChordRest))) {
|
|
|
|
int strack = staffIdx * VOICES;
|
|
|
|
int etrack = strack + VOICES;
|
|
|
|
// search through all tracks of current staff looking for a lyric in specified verse
|
|
|
|
for (int track = strack; track < etrack; ++track) {
|
|
|
|
ChordRest* cr = static_cast<ChordRest*>(s->element(track));
|
|
|
|
if (cr && !cr->lyricsList().isEmpty()) {
|
|
|
|
// cr with lyrics found, but does it have a syllable in specified verse?
|
|
|
|
l = cr->lyricsList().value(verse);
|
|
|
|
if (l)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (l)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// Lyrics
|
|
|
|
//=========================================================
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
Lyrics::Lyrics(Score* s)
|
|
|
|
: Text(s)
|
|
|
|
{
|
2014-05-30 10:13:29 +02:00
|
|
|
setTextStyleType(TextStyleType::LYRIC1);
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
_no = 0;
|
|
|
|
_ticks = 0;
|
|
|
|
_syllabic = Syllabic::SINGLE;
|
|
|
|
_separator = nullptr;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Lyrics::Lyrics(const Lyrics& l)
|
|
|
|
: Text(l)
|
|
|
|
{
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
_no = l._no;
|
|
|
|
_ticks = l._ticks;
|
|
|
|
_syllabic = l._syllabic;
|
2014-12-18 21:53:46 +01:00
|
|
|
#if 0
|
|
|
|
// if we copy lines at all, they need to be parented to new lyric
|
|
|
|
// but they will be regenerated upon layout anyhow
|
|
|
|
for (const Line* line : l._separator) {
|
|
|
|
Line* nline = new Line(*line);
|
|
|
|
nline->setParent(this);
|
|
|
|
_separator.append(nline);
|
|
|
|
}
|
|
|
|
#endif
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
_separator = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Lyrics::~Lyrics()
|
|
|
|
{
|
|
|
|
if (_separator != nullptr) {
|
|
|
|
_separator->unchain();
|
|
|
|
delete _separator;
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// scanElements
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
void Lyrics::scanElements(void* data, void (*func)(void*, Element*), bool /*all*/)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
func(data, this);
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
/* DO NOT ADD EITHER THE LYRICSLINE OR THE SEGMENTS: segments are added through the system each belongs to;
|
|
|
|
LyricsLine is not needed, as it is internally manged.
|
|
|
|
if (_separator != nullptr)
|
|
|
|
_separator->scanElements(data, func, all); */
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// write
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::write(Xml& xml) const
|
|
|
|
{
|
2014-08-15 17:20:20 +02:00
|
|
|
if (!xml.canWrite(this))
|
|
|
|
return;
|
2012-05-26 14:26:10 +02:00
|
|
|
xml.stag("Lyrics");
|
|
|
|
if (_no)
|
|
|
|
xml.tag("no", _no);
|
2014-05-22 21:51:34 +02:00
|
|
|
if (_syllabic != Syllabic::SINGLE) {
|
2012-05-26 14:26:10 +02:00
|
|
|
static const char* sl[] = {
|
|
|
|
"single", "begin", "end", "middle"
|
|
|
|
};
|
2014-05-22 21:51:34 +02:00
|
|
|
xml.tag("syllabic", sl[int(_syllabic)]);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2014-08-27 10:31:52 +02:00
|
|
|
writeProperty(xml, P_ID::LYRIC_TICKS);
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
Text::writeProperties(xml);
|
|
|
|
xml.etag();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// read
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-01-11 18:10:18 +01:00
|
|
|
void Lyrics::read(XmlReader& e)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
int iEndTick = 0; // used for backward compatibility
|
2014-10-22 12:08:39 +02:00
|
|
|
Text* _verseNumber = 0;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2013-01-11 18:10:18 +01:00
|
|
|
while (e.readNextStartElement()) {
|
|
|
|
const QStringRef& tag(e.name());
|
2012-05-26 14:26:10 +02:00
|
|
|
if (tag == "no")
|
2013-01-11 18:10:18 +01:00
|
|
|
_no = e.readInt();
|
2012-05-26 14:26:10 +02:00
|
|
|
else if (tag == "syllabic") {
|
2013-01-11 18:10:18 +01:00
|
|
|
QString val(e.readElementText());
|
2012-05-26 14:26:10 +02:00
|
|
|
if (val == "single")
|
2014-05-22 21:51:34 +02:00
|
|
|
_syllabic = Syllabic::SINGLE;
|
2012-05-26 14:26:10 +02:00
|
|
|
else if (val == "begin")
|
2014-05-22 21:51:34 +02:00
|
|
|
_syllabic = Syllabic::BEGIN;
|
2012-05-26 14:26:10 +02:00
|
|
|
else if (val == "end")
|
2014-05-22 21:51:34 +02:00
|
|
|
_syllabic = Syllabic::END;
|
2012-05-26 14:26:10 +02:00
|
|
|
else if (val == "middle")
|
2014-05-22 21:51:34 +02:00
|
|
|
_syllabic = Syllabic::MIDDLE;
|
2012-05-26 14:26:10 +02:00
|
|
|
else
|
|
|
|
qDebug("bad syllabic property");
|
|
|
|
}
|
|
|
|
else if (tag == "endTick") { // obsolete
|
|
|
|
// store <endTick> tag value until a <ticks> tag has been read
|
|
|
|
// which positions this lyrics element in the score
|
2013-01-11 18:10:18 +01:00
|
|
|
iEndTick = e.readInt();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
else if (tag == "ticks")
|
2013-01-11 18:10:18 +01:00
|
|
|
_ticks = e.readInt();
|
2014-10-22 12:08:39 +02:00
|
|
|
else if (tag == "Number") { // obsolete
|
|
|
|
Text* _verseNumber = new Text(score());
|
2012-05-26 14:26:10 +02:00
|
|
|
_verseNumber->read(e);
|
|
|
|
_verseNumber->setParent(this);
|
|
|
|
}
|
|
|
|
else if (!Text::readProperties(e))
|
2013-01-11 18:10:18 +01:00
|
|
|
e.unknown();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
// if any endTick, make it relative to current tick
|
|
|
|
if (iEndTick) {
|
2013-01-21 20:21:41 +01:00
|
|
|
_ticks = iEndTick - e.tick();
|
2012-05-26 14:26:10 +02:00
|
|
|
// qDebug("Lyrics::endTick: %d ticks %d", iEndTick, _ticks);
|
|
|
|
}
|
2014-10-22 12:08:39 +02:00
|
|
|
if (_verseNumber) {
|
|
|
|
// TODO: add text to main text
|
|
|
|
}
|
|
|
|
|
|
|
|
delete _verseNumber;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// add
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::add(Element* el)
|
|
|
|
{
|
|
|
|
el->setParent(this);
|
2014-06-24 18:36:02 +02:00
|
|
|
if (el->type() == Element::Type::LINE)
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
// _separator.append((Line*)el); // ignore! Internally managed
|
|
|
|
;
|
2012-05-26 14:26:10 +02:00
|
|
|
else
|
|
|
|
qDebug("Lyrics::add: unknown element %s", el->name());
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// remove
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::remove(Element* el)
|
|
|
|
{
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
if (el->type() == Element::Type::LYRICSLINE) {
|
|
|
|
_separator->unchain();
|
|
|
|
delete _separator;
|
|
|
|
_separator = nullptr;
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
else
|
|
|
|
qDebug("Lyrics::remove: unknown element %s", el->name());
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// draw
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
/* As the lyrics line is now drawn by the system it belongs to, standard Text drawing is enough.
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
void Lyrics::draw(QPainter* painter) const
|
|
|
|
{
|
|
|
|
Text::draw(painter);
|
|
|
|
}
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
*/
|
2015-01-12 21:51:37 +01:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
// isMelisma
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-09-17 04:44:26 +02:00
|
|
|
bool Lyrics::isMelisma() const
|
|
|
|
{
|
|
|
|
// entered as melisma using underscore?
|
|
|
|
if (_ticks > 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// hyphenated?
|
2015-01-12 21:51:37 +01:00
|
|
|
// if so, it is a melisma only if there is no lyric in same verse on next CR
|
2014-09-17 04:44:26 +02:00
|
|
|
if (_syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) {
|
|
|
|
// find next CR on same track and check for existence of lyric in same verse
|
|
|
|
ChordRest* cr = chordRest();
|
|
|
|
Segment* s = cr->segment()->next1();
|
|
|
|
ChordRest* ncr = s ? s->nextChordRest(cr->track()) : nullptr;
|
2015-01-12 21:51:37 +01:00
|
|
|
if (ncr && !ncr->lyrics(_no))
|
2014-09-17 04:44:26 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// default - not a melisma
|
2015-01-12 21:51:37 +01:00
|
|
|
return false;
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::layout()
|
|
|
|
{
|
|
|
|
// setPos(_textStyle.offset(spatium()));
|
|
|
|
layout1();
|
|
|
|
QPointF rp(readPos());
|
|
|
|
if (!rp.isNull()) {
|
|
|
|
if (score()->mscVersion() <= 114) {
|
|
|
|
rp.ry() += lineSpacing() + 2;
|
|
|
|
rp.rx() += bbox().width() * .5;
|
|
|
|
}
|
|
|
|
setUserOff(rp - ipos());
|
|
|
|
setReadPos(QPointF());
|
|
|
|
}
|
2014-09-17 04:44:26 +02:00
|
|
|
}
|
|
|
|
|
2014-02-19 12:18:44 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout1
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
#if defined (USE_FONT_DASH_METRIC)
|
|
|
|
static QString g_fontFamily = QString();
|
|
|
|
static qreal g_fontSize = -1;
|
|
|
|
static qreal g_cachedDashY;
|
|
|
|
static qreal g_cachedDashLength;
|
|
|
|
#if defined(USE_FONT_DASH_TICKNESS)
|
|
|
|
static qreal g_cachedDashThickness;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2014-02-19 12:18:44 +01:00
|
|
|
void Lyrics::layout1()
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2014-03-10 10:50:12 +01:00
|
|
|
setPos(textStyle().offset(spatium()));
|
2012-10-26 20:44:13 +02:00
|
|
|
Text::layout1();
|
2012-10-25 13:51:57 +02:00
|
|
|
if (!parent()) // palette & clone trick
|
2012-05-26 14:26:10 +02:00
|
|
|
return;
|
2012-10-26 20:44:13 +02:00
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
ChordRest* cr = chordRest();
|
|
|
|
const QList<Lyrics*>* ll = &(cr->lyricsList());
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2014-05-26 15:31:36 +02:00
|
|
|
qreal lh = lineSpacing() * score()->styleD(StyleIdx::lyricsLineHeight);
|
2012-05-26 14:26:10 +02:00
|
|
|
int line = ll->indexOf(this);
|
2014-05-26 15:31:36 +02:00
|
|
|
qreal y = lh * line + point(score()->styleS(StyleIdx::lyricsDistance));
|
2012-10-23 14:42:00 +02:00
|
|
|
qreal x = 0.0;
|
2014-09-08 16:38:26 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//
|
2014-10-18 04:02:33 +02:00
|
|
|
// parse leading verse number and/or punctuation, so we can factor it into layout separately
|
|
|
|
// TODO: provide a way to disable this
|
2012-05-26 14:26:10 +02:00
|
|
|
//
|
2014-10-22 12:08:39 +02:00
|
|
|
bool hasNumber = false; // _verseNumber;
|
2014-10-18 04:02:33 +02:00
|
|
|
qreal adjust = 0.0;
|
2014-11-30 16:05:19 +01:00
|
|
|
QString s = plainText(true);
|
2014-10-18 04:02:33 +02:00
|
|
|
// find:
|
|
|
|
// 1) string of numbers and non-word characters at start of syllable
|
|
|
|
// 2) at least one other character (indicating start of actual lyric)
|
2014-10-19 22:36:08 +02:00
|
|
|
QRegularExpression leadingPattern("(^[\\d\\W]+)([^\\d\\W]+)");
|
|
|
|
QRegularExpressionMatch leadingMatch = leadingPattern.match(s);
|
|
|
|
if (leadingMatch.hasMatch()) {
|
2014-10-18 04:02:33 +02:00
|
|
|
// leading string
|
2014-10-19 22:36:08 +02:00
|
|
|
QString s1 = leadingMatch.captured(1);
|
|
|
|
// actual lyric
|
|
|
|
//QString s2 = leadingMatch.captured(2);
|
2014-10-18 04:02:33 +02:00
|
|
|
Text leading(*this);
|
|
|
|
leading.setPlainText(s1);
|
|
|
|
leading.layout1();
|
|
|
|
adjust = leading.width();
|
|
|
|
if (!s1.isEmpty() && s1[0].isDigit())
|
|
|
|
hasNumber = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (textStyle().align() & AlignmentFlags::HCENTER) {
|
|
|
|
//
|
|
|
|
// center under notehead, not origin
|
|
|
|
// however, lyrics that are melismas or have verse numbers will be forced to left alignment
|
|
|
|
// TODO: provide a way to disable the automatic left alignment
|
|
|
|
//
|
|
|
|
qreal maxWidth;
|
|
|
|
if (cr->type() == Element::Type::CHORD)
|
|
|
|
maxWidth = static_cast<Chord*>(cr)->maxHeadWidth();
|
|
|
|
else
|
|
|
|
maxWidth = cr->width(); // TODO: exclude ledger line for multivoice rest?
|
|
|
|
qreal nominalWidth = symWidth(SymId::noteheadBlack);
|
|
|
|
if (!isMelisma() && !hasNumber) // center under notehead
|
|
|
|
x += nominalWidth * .5 - cr->x() - adjust * 0.5;
|
|
|
|
else // force left alignment
|
|
|
|
x += (width() + nominalWidth - maxWidth) * .5 - cr->x() - adjust;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// even for left aligned syllables, ignore leading verse numbers and/or punctuation
|
|
|
|
x -= adjust;
|
|
|
|
}
|
2014-09-17 04:44:26 +02:00
|
|
|
|
2012-10-23 14:42:00 +02:00
|
|
|
rxpos() += x;
|
|
|
|
rypos() += y;
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
|
2015-01-12 21:51:37 +01:00
|
|
|
if (_ticks > 0 || _syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) {
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
if (_separator == nullptr) {
|
|
|
|
_separator = new LyricsLine(score());
|
|
|
|
_separator->setTick(cr->tick());
|
|
|
|
score()->addUnmanagedSpanner(_separator);
|
|
|
|
}
|
|
|
|
_separator->setParent(this);
|
|
|
|
_separator->setTick(cr->tick());
|
|
|
|
_separator->setTrack(track());
|
|
|
|
_separator->setTrack2(track());
|
|
|
|
#if defined(USE_FONT_DASH_METRIC)
|
|
|
|
// if font parameters different from font cached values, compute new dash values from font metrics
|
|
|
|
if (textStyle().family() != g_fontFamily && textStyle().size() != g_fontSize) {
|
|
|
|
QFontMetricsF fm = textStyle().fontMetrics(spatium());
|
|
|
|
QRectF r = fm.tightBoundingRect("\u2013"); // U+2013 EN DASH
|
|
|
|
g_cachedDashY = _dashY = r.y() + (r.height() * HALF);
|
|
|
|
g_cachedDashLength = _dashLength = r.width();
|
|
|
|
#if defined(USE_FONT_DASH_TICKNESS)
|
|
|
|
g_cachedDashThickness = _dashThickness = r.height();
|
|
|
|
#endif
|
|
|
|
g_fontFamily = textStyle().family();
|
|
|
|
g_fontSize = textStyle().size();
|
|
|
|
}
|
|
|
|
// if same font, use cached values
|
|
|
|
else {
|
|
|
|
_dashY = g_cachedDashY;
|
|
|
|
_dashLength = g_cachedDashLength;
|
|
|
|
#if defined(USE_FONT_DASH_TICKNESS)
|
|
|
|
_dashThickness = g_cachedDashThickness;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (_separator != nullptr) {
|
|
|
|
_separator->unchain();
|
|
|
|
delete _separator;
|
|
|
|
_separator = nullptr;
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// paste
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-03-22 14:54:15 +01:00
|
|
|
void Lyrics::paste(MuseScoreView* scoreview)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2013-05-16 16:12:22 +02:00
|
|
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
2012-05-26 14:26:10 +02:00
|
|
|
QClipboard::Mode mode = QClipboard::Clipboard;
|
|
|
|
#else
|
|
|
|
QClipboard::Mode mode = QClipboard::Selection;
|
|
|
|
#endif
|
|
|
|
QString txt = QApplication::clipboard()->text(mode);
|
|
|
|
QStringList sl = txt.split(QRegExp("\\s+"), QString::SkipEmptyParts);
|
|
|
|
if (sl.isEmpty())
|
|
|
|
return;
|
2014-08-13 21:01:21 +02:00
|
|
|
|
2014-03-22 14:54:15 +01:00
|
|
|
QStringList hyph = sl[0].split("-");
|
|
|
|
bool minus = false;
|
|
|
|
if(hyph.length() > 1) {
|
|
|
|
insertText(hyph[0]);
|
|
|
|
hyph.removeFirst();
|
|
|
|
sl[0] = hyph.join("-");
|
|
|
|
minus = true;
|
|
|
|
}
|
|
|
|
else if (sl.length() > 1 && sl[1] == "-") {
|
|
|
|
insertText(sl[0]);
|
|
|
|
sl.removeFirst();
|
|
|
|
sl.removeFirst();
|
|
|
|
minus = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
insertText(sl[0]);
|
|
|
|
sl.removeFirst();
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
|
|
layout();
|
|
|
|
score()->setLayoutAll(true);
|
|
|
|
score()->end();
|
|
|
|
txt = sl.join(" ");
|
|
|
|
|
|
|
|
QApplication::clipboard()->setText(txt, mode);
|
2014-03-22 14:54:15 +01:00
|
|
|
if (minus)
|
|
|
|
scoreview->lyricsMinus();
|
|
|
|
else
|
|
|
|
scoreview->lyricsTab(false, false, true);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// endTick
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Lyrics::endTick() const
|
|
|
|
{
|
|
|
|
return segment()->tick() + ticks();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// acceptDrop
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-08-13 21:01:21 +02:00
|
|
|
bool Lyrics::acceptDrop(const DropData& data) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2014-10-19 15:16:24 +02:00
|
|
|
return data.element->type() == Element::Type::TEXT || Text::acceptDrop(data);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// drop
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Element* Lyrics::drop(const DropData& data)
|
|
|
|
{
|
2014-10-19 15:16:24 +02:00
|
|
|
Element::Type type = data.element->type();
|
|
|
|
if (type == Element::Type::SYMBOL || type == Element::Type::FSYMBOL) {
|
|
|
|
Text::drop(data);
|
|
|
|
return 0;
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
Text* e = static_cast<Text*>(data.element);
|
2014-10-19 15:16:24 +02:00
|
|
|
if (!(type == Element::Type::TEXT && e->textStyle().name() == "Lyrics Verse Number")) {
|
2012-05-26 14:26:10 +02:00
|
|
|
delete e;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
e->setParent(this);
|
|
|
|
score()->undoAddElement(e);
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setNo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::setNo(int n)
|
|
|
|
{
|
|
|
|
_no = n;
|
2012-10-06 13:40:42 +02:00
|
|
|
// adjust beween LYRICS1 and LYRICS2 only; keep other styles as they are
|
|
|
|
// (_no is 0-based, so odd _no means even line and viceversa)
|
2014-06-24 18:36:02 +02:00
|
|
|
if (type() == Element::Type::LYRICS) {
|
2014-05-30 10:13:29 +02:00
|
|
|
if( (_no & 1) && textStyleType() == TextStyleType::LYRIC1)
|
|
|
|
setTextStyleType(TextStyleType::LYRIC2);
|
|
|
|
if( !(_no & 1) && textStyleType() == TextStyleType::LYRIC2)
|
|
|
|
setTextStyleType(TextStyleType::LYRIC1);
|
2012-10-06 13:40:42 +02:00
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2012-10-25 14:50:17 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// endEdit
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::endEdit()
|
|
|
|
{
|
|
|
|
Text::endEdit();
|
|
|
|
score()->setLayoutAll(true);
|
|
|
|
}
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// removeFromScore
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Lyrics::removeFromScore()
|
|
|
|
{
|
|
|
|
if (_separator) {
|
|
|
|
_separator->unchain();
|
|
|
|
delete _separator;
|
|
|
|
_separator = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-31 10:15:45 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// getProperty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QVariant Lyrics::getProperty(P_ID propertyId) const
|
|
|
|
{
|
2014-08-27 10:31:52 +02:00
|
|
|
switch (propertyId) {
|
|
|
|
case P_ID::SYLLABIC:
|
|
|
|
return int(_syllabic);
|
|
|
|
case P_ID::LYRIC_TICKS:
|
|
|
|
return _ticks;
|
2012-10-31 10:15:45 +01:00
|
|
|
default:
|
|
|
|
return Text::getProperty(propertyId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setProperty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Lyrics::setProperty(P_ID propertyId, const QVariant& v)
|
|
|
|
{
|
2014-08-27 10:31:52 +02:00
|
|
|
switch (propertyId) {
|
|
|
|
case P_ID::SYLLABIC:
|
|
|
|
_syllabic = Syllabic(v.toInt());
|
|
|
|
break;
|
|
|
|
case P_ID::LYRIC_TICKS:
|
|
|
|
_ticks = v.toInt();
|
|
|
|
break;
|
2012-10-31 10:15:45 +01:00
|
|
|
default:
|
|
|
|
if (!Text::setProperty(propertyId, v))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
score()->setLayoutAll(true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// propertyDefault
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QVariant Lyrics::propertyDefault(P_ID id) const
|
|
|
|
{
|
2014-08-27 10:31:52 +02:00
|
|
|
switch (id) {
|
|
|
|
case P_ID::SYLLABIC:
|
|
|
|
return int(Syllabic::SINGLE);
|
|
|
|
case P_ID::LYRIC_TICKS:
|
|
|
|
return 0;
|
2012-10-31 14:21:13 +01:00
|
|
|
default: return Text::propertyDefault(id);
|
2012-10-31 10:15:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
//=========================================================
|
|
|
|
// LyricsLine
|
|
|
|
//=========================================================
|
|
|
|
|
|
|
|
LyricsLine::LyricsLine(Score* s)
|
|
|
|
: SLine(s)
|
|
|
|
{
|
|
|
|
setFlags(0);
|
|
|
|
|
|
|
|
setGenerated(true); // no need to save it, as it can be re-generated
|
|
|
|
setDiagonal(false);
|
|
|
|
setLineWidth(Spatium(LYRICS_DASH_DEFAULT_LINE_THICKNESS));
|
|
|
|
setAnchor(Spanner::Anchor::SEGMENT);
|
|
|
|
_nextLyrics = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
LyricsLine::LyricsLine(const LyricsLine& g)
|
|
|
|
: SLine(g)
|
|
|
|
{
|
|
|
|
_nextLyrics = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
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,
|
2015-01-12 21:03:03 +01:00
|
|
|
// but the line shall include it:
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
// include the duration of this last segment in the melisma duration
|
2015-01-14 00:50:47 +01:00
|
|
|
Segment* lyricsSegment = lyrics()->segment();
|
|
|
|
int lyricsStartTick = lyricsSegment->tick();
|
|
|
|
int lyricsEndTick = lyrics()->endTick();
|
|
|
|
int lyricsTrack = lyrics()->track();
|
|
|
|
// find segment with tick >= endTick
|
|
|
|
Segment* s = lyricsSegment;
|
|
|
|
while (s && s->tick() < lyricsEndTick)
|
|
|
|
s = s->nextCR();
|
|
|
|
if (!s) {
|
|
|
|
// user probably deleted measures at end of score, leaving this melisma too long
|
|
|
|
// set s to last segment and reset lyricsEndTick to trigger FIXUP code below
|
|
|
|
s = score()->lastSegment();
|
|
|
|
lyricsEndTick = -1;
|
|
|
|
}
|
|
|
|
Element* se = s->element(lyricsTrack);
|
|
|
|
// everything is OK if we have reached a chord at right tick on right track
|
|
|
|
if (s->tick() == lyricsEndTick && se && se->type() == Element::Type::CHORD) {
|
|
|
|
// advance to next CR, or last segment if no next CR
|
|
|
|
s = s->nextCR();
|
|
|
|
if (!s)
|
|
|
|
s = score()->lastSegment();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// FIXUP - lyrics tick count not valid
|
|
|
|
// this happens if edits to score have removed the original end segment
|
|
|
|
// so let's fix it here
|
|
|
|
// s is already pointing to segment past endTick (or to last segment)
|
|
|
|
// we should shorten the lyrics tick count to make this work
|
|
|
|
Segment* ns = s;
|
|
|
|
Segment* ps = s->prev1(Segment::Type::ChordRest);
|
|
|
|
while (ps && ps != lyricsSegment) {
|
|
|
|
Element* pe = ps->element(lyricsTrack);
|
|
|
|
// we're looking for an actual chord on this track
|
|
|
|
if (pe && pe->type() == Element::Type::CHORD)
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
break;
|
2015-01-14 00:50:47 +01:00
|
|
|
s = ps;
|
|
|
|
ps = ps->prev1(Segment::Type::ChordRest);
|
|
|
|
}
|
|
|
|
if (!ps || ps == lyricsSegment) {
|
|
|
|
// no valid previous CR, so try to lengthen melisma instead
|
|
|
|
ps = ns;
|
|
|
|
s = ps->nextCR(lyricsTrack);
|
|
|
|
Element* e = s ? s->element(lyricsTrack) : nullptr;
|
|
|
|
// check to make sure we have a chord
|
|
|
|
if (!e || e->type() != Element::Type::CHORD) {
|
|
|
|
// nothing to do but set ticks to 0
|
|
|
|
// this will result in melisma being deleted later
|
|
|
|
lyrics()->undoChangeProperty(P_ID::LYRIC_TICKS, 0);
|
|
|
|
setTicks(0);
|
|
|
|
return;
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
}
|
|
|
|
}
|
2015-01-14 00:50:47 +01:00
|
|
|
lyrics()->undoChangeProperty(P_ID::LYRIC_TICKS, ps->tick() - lyricsStartTick);
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
}
|
2015-01-14 00:50:47 +01:00
|
|
|
setTicks(s->tick() - lyricsStartTick);
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
}
|
|
|
|
else { // dash(es)
|
|
|
|
#if defined(USE_FONT_DASH_TICKNESS)
|
|
|
|
setLineWidth(Spatium(lyrics()->dashThickness() / spatium()));
|
|
|
|
#endif
|
|
|
|
_nextLyrics = searchNextLyrics(lyrics()->segment(), staffIdx(), lyrics()->no());
|
|
|
|
setTick2(_nextLyrics != nullptr ? _nextLyrics->segment()->tick() : tick());
|
|
|
|
}
|
|
|
|
if (ticks()) // only do layout if some time span
|
|
|
|
SLine::layout();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// createLineSegment
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
LineSegment* LyricsLine::createLineSegment()
|
|
|
|
{
|
|
|
|
LyricsLineSegment* seg = new LyricsLineSegment(score());
|
|
|
|
seg->setTrack(track());
|
|
|
|
seg->setColor(color());
|
|
|
|
return seg;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// unchain
|
|
|
|
//
|
|
|
|
// Remove the LyricsLine and its segments from objects which may know about them
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void LyricsLine::unchain()
|
|
|
|
{
|
|
|
|
for (SpannerSegment* ss : spannerSegments())
|
|
|
|
if (ss->system())
|
|
|
|
ss->system()->remove(ss);
|
|
|
|
score()->removeUnmanagedSpanner(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// LyricsLineSegment
|
|
|
|
//=========================================================
|
|
|
|
|
|
|
|
LyricsLineSegment::LyricsLineSegment(Score* s)
|
|
|
|
: LineSegment(s)
|
|
|
|
{
|
|
|
|
setFlags(ElementFlag::SEGMENT | ElementFlag::ON_STAFF);
|
|
|
|
setGenerated(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void LyricsLineSegment::layout()
|
|
|
|
{
|
|
|
|
Lyrics* lyr;
|
|
|
|
System* sys;
|
|
|
|
bool isEndMelisma = lyricsLine()->lyrics()->ticks() > 0;
|
|
|
|
qreal sp = spatium();
|
|
|
|
|
|
|
|
if (lyricsLine()->ticks() <= 0) { // if no span,
|
|
|
|
_numOfDashes = 0; // nothing to draw
|
|
|
|
return; // and do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
// HORIZONTAL POSITION
|
|
|
|
// A) if line precedes a syllable, advance line end to right before the next syllable text
|
|
|
|
// if not a melisma and there is a next syllable;
|
|
|
|
if (!isEndMelisma && lyricsLine()->nextLyrics() != nullptr
|
|
|
|
&& (spannerSegmentType() == SpannerSegmentType::END
|
|
|
|
|| spannerSegmentType() == SpannerSegmentType::SINGLE)) {
|
|
|
|
lyr = lyricsLine()->nextLyrics();
|
|
|
|
sys = lyr->segment()->system();
|
|
|
|
// if next lyrics is on a different sytem, this line segment is at the end of its system:
|
|
|
|
// do not adjust for next lyrics position
|
|
|
|
if (sys == system()) {
|
|
|
|
qreal lyrX = lyr->bbox().x();
|
|
|
|
qreal lyrXp = lyr->pagePos().x();
|
|
|
|
qreal sysXp = sys->pagePos().x();
|
|
|
|
qreal offsetX = lyrXp - sysXp + lyrX - pos().x() - pos2().x();
|
|
|
|
// syst.rel. X pos. | as a delta from current end pos.
|
|
|
|
offsetX -= LYRICS_DASH_DEFAULT_PAD * sp; // add ending padding
|
|
|
|
rxpos2() += offsetX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// B) if line follows a syllable, advance line start to after the syllable text
|
|
|
|
lyr = lyricsLine()->lyrics();
|
|
|
|
sys = lyr->segment()->system();
|
|
|
|
if (spannerSegmentType() == SpannerSegmentType::BEGIN || spannerSegmentType() == SpannerSegmentType::SINGLE) {
|
|
|
|
qreal lyrX = lyr->bbox().x();
|
|
|
|
qreal lyrXp = lyr->pagePos().x();
|
|
|
|
qreal lyrW = lyr->bbox().width();
|
|
|
|
qreal sysXp = sys->pagePos().x();
|
|
|
|
qreal offsetX = lyrXp - sysXp + lyrX + lyrW - pos().x();
|
|
|
|
// syst.rel. X pos. | lyr.advance | as a delta from current pos.
|
|
|
|
// add initial padding
|
|
|
|
offsetX += (isEndMelisma ? MELISMA_DEFAULT_PAD : LYRICS_DASH_DEFAULT_PAD) * sp;
|
|
|
|
rxpos() += offsetX;
|
|
|
|
rxpos2() -= offsetX;
|
|
|
|
}
|
|
|
|
|
2015-01-14 00:50:47 +01:00
|
|
|
// VERTICAL POSITION: at the base line of the syllable text
|
|
|
|
rypos() = lyr->y();
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
|
|
|
|
// MELISMA vs. DASHES
|
|
|
|
if (isEndMelisma) { // melisma
|
|
|
|
_numOfDashes = 1;
|
|
|
|
rypos() -= lyricsLine()->lineWidth().val() * sp * HALF; // let the line 'sit on' the base line
|
2015-01-14 00:50:47 +01:00
|
|
|
qreal offsetX = score()->styleD(StyleIdx::minNoteDistance) * sp;
|
|
|
|
// if final segment, extend slightly after the chord, otherwise shorten it
|
|
|
|
rxpos2() +=
|
|
|
|
(spannerSegmentType() == SpannerSegmentType::BEGIN ||
|
|
|
|
spannerSegmentType() == SpannerSegmentType::MIDDLE)
|
|
|
|
? -offsetX : +offsetX;
|
|
|
|
|
Lyrics multi-system melisma and dashes
Implements melisma and dash lines for lyrics spanning several systems.
The melisma and dash line is based on the `SLine` class and its segments on the `LineSegment` class. Both the whole line and its segments are not selectable, marked as generated and not saved in the score file, which is not changed in any way.
For very wide dash segments, several dashes are drawn; the distance between the dashes is not configurable.
Lyrics layout code in `Measure` class and in `layout.cpp` file has been commented out as the lyrics line layout is all contained in the lyrics.cpp file
The line is registered with the `Score` (to have its layout delayed until all elements are positioned) with a mechanism similar to other `Spanner`'s, but in a different container (`_unmanagedSpanner`), as the owning `Lyrics` should decide when create, register, unregister and delete its line.
The line segments are registered with the `System` they belong to (to have them drawn), in the same way as other `Spanner`'s.
There is code for using the dash metrics of the lyrics font, but it is turned off via a conditional directive, as there does not seem to be a reliable way to determine the dash metrics; conventional values (determined by trials and errors and based on my taste!) are used when the conditional directive is off.
2015-01-11 10:11:44 +01:00
|
|
|
}
|
|
|
|
else { // dash(es)
|
|
|
|
#if defined(USE_FONT_DASH_METRIC)
|
|
|
|
rypos() += lyr->dashY();
|
|
|
|
_dashLength = lyr->dashLength();
|
|
|
|
#else
|
|
|
|
rypos() -= lyr->bbox().height() * LYRICS_DASH_Y_POS_RATIO; // set conventional dash Y pos
|
|
|
|
_dashLength = LYRICS_DASH_DEFAULT_LENGHT * sp; // and dash length
|
|
|
|
#endif
|
|
|
|
qreal len = pos2().x();
|
|
|
|
if (len < LYRICS_DASH_MIN_LENGTH * sp) // if no room for a dash
|
|
|
|
_numOfDashes = 0; // draw no dash
|
|
|
|
else if (len < (LYRICS_DASH_DEFAULT_STEP * TWICE * sp)) { // if no room for two dashes
|
|
|
|
_numOfDashes = 1; // draw one dash
|
|
|
|
if (_dashLength > len) // if no room for a full dash
|
|
|
|
_dashLength = len; // shorten it
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_numOfDashes = len / (LYRICS_DASH_DEFAULT_STEP * sp); // draw several dashes
|
|
|
|
}
|
|
|
|
|
|
|
|
// set bounding box
|
|
|
|
QRectF r = QRectF(0.0, 0.0, pos2().x(), pos2().y()).normalized();
|
|
|
|
qreal lw = spatium() * lyricsLine()->lineWidth().val() * HALF;
|
|
|
|
setbbox(r.adjusted(-lw, -lw, lw, lw));
|
|
|
|
adjustReadPos();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// draw
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void LyricsLineSegment::draw(QPainter* painter) const
|
|
|
|
{
|
|
|
|
if (_numOfDashes < 1) // nothing to draw
|
|
|
|
return;
|
|
|
|
qreal _spatium = spatium();
|
|
|
|
|
|
|
|
QPen pen(lyricsLine()->curColor());
|
|
|
|
pen.setWidthF(lyricsLine()->lineWidth().val() * _spatium);
|
|
|
|
pen.setCapStyle(Qt::FlatCap);
|
|
|
|
painter->setPen(pen);
|
|
|
|
if (lyricsLine()->lyrics()->ticks() > 0) // melisma
|
|
|
|
painter->drawLine(QPointF(), pos2());
|
|
|
|
else { // dash(es)
|
|
|
|
qreal step = pos2().x() / (_numOfDashes+1);
|
|
|
|
qreal x = step - _dashLength * HALF;
|
|
|
|
for (int i = 0; i < _numOfDashes; i++, x += step)
|
|
|
|
painter->drawLine(QPointF(x, 0.0), QPointF(x + _dashLength, 0.0));
|
|
|
|
}
|
|
|
|
}
|
2012-10-31 10:15:45 +01:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
}
|
|
|
|
|