Skip to content

Commit

Permalink
add chord symbol style options: full german, french, lwoer case bass,…
Browse files Browse the repository at this point in the history
… all caps note names
  • Loading branch information
MarcSabatella committed Dec 10, 2014
1 parent e690982 commit fbdd224
Show file tree
Hide file tree
Showing 23 changed files with 159 additions and 71 deletions.
8 changes: 4 additions & 4 deletions libmscore/ambitus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,9 +725,9 @@ Element* Ambitus::prevElement()
QString Ambitus::accessibleInfo()
{
return tr("%1; Top pitch: %2%3; Bottom pitch: %4%5").arg(Element::accessibleInfo())\
.arg(tpc2name(topTpc(), NoteSpellingType::STANDARD, false, false))\
.arg(tpc2name(topTpc(), NoteSpellingType::STANDARD, false, false, false))\
.arg(QString::number(topOctave()))\
.arg(tpc2name(bottomTpc(), NoteSpellingType::STANDARD, false, false))\
.arg(tpc2name(bottomTpc(), NoteSpellingType::STANDARD, false, false, false))\
.arg(QString::number(bottomOctave()));
}

Expand All @@ -738,9 +738,9 @@ QString Ambitus::accessibleInfo()
QString Ambitus::screenReaderInfo()
{
return tr("%1; Top pitch: %2%3; Bottom pitch: %4%5").arg(Element::screenReaderInfo())\
.arg(tpc2name(topTpc(), NoteSpellingType::STANDARD, false, true))\
.arg(tpc2name(topTpc(), NoteSpellingType::STANDARD, false, false, true))\
.arg(QString::number(topOctave()))\
.arg(tpc2name(bottomTpc(), NoteSpellingType::STANDARD, false, true))\
.arg(tpc2name(bottomTpc(), NoteSpellingType::STANDARD, false, false, true))\
.arg(QString::number(bottomOctave()));
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmscore/chordlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ QString HChord::name(int tpc) const
static const HChord C0(0,3,6,9);
static const HChord C1(0,3);

QString buf = tpc2name(tpc, NoteSpellingType::STANDARD, false);
QString buf = tpc2name(tpc, NoteSpellingType::STANDARD, false, false, false);
HChord c(*this);

int key = tpc2pitch(tpc);
Expand Down
59 changes: 31 additions & 28 deletions libmscore/harmony.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ QString Harmony::harmonyName()
s = "(";

if (_rootTpc != Tpc::TPC_INVALID)
r = tpc2name(_rootTpc, _rootSpelling, _rootLowerCase);
r = tpc2name(_rootTpc, _rootSpelling, _rootLowerCase, _noteUpperCase);

if (_textName != "") {
e = _textName;
Expand Down Expand Up @@ -70,7 +70,7 @@ QString Harmony::harmonyName()
}

if (_baseTpc != Tpc::TPC_INVALID)
b = "/" + tpc2name(_baseTpc, _baseSpelling, _baseLowerCase);
b = "/" + tpc2name(_baseTpc, _baseSpelling, _baseLowerCase, _noteUpperCase);

s += r + e + b;

Expand Down Expand Up @@ -360,18 +360,19 @@ void Harmony::read(XmlReader& e)
// determineRootBaseSpelling
//---------------------------------------------------------

void Harmony::determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& rootLowerCase, NoteSpellingType& baseSpelling, bool& baseLowerCase)
void Harmony::determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& rootLowerCase, NoteSpellingType& baseSpelling, bool& baseLowerCase, bool& noteUpperCase)
{
if (score()->styleB(StyleIdx::useStandardNoteNames))
rootSpelling = NoteSpellingType::STANDARD;
else if (score()->styleB(StyleIdx::useGermanNoteNames)) {
if (score()->styleB(StyleIdx::lowerCaseMinorChords))
rootSpelling = NoteSpellingType::GERMAN_PURE;
else
rootSpelling = NoteSpellingType::GERMAN;
}
else if (score()->styleB(StyleIdx::useGermanNoteNames))
rootSpelling = NoteSpellingType::GERMAN;
else if (score()->styleB(StyleIdx::useFullGermanNoteNames))
rootSpelling = NoteSpellingType::GERMAN_PURE;
else if (score()->styleB(StyleIdx::useSolfeggioNoteNames))
rootSpelling = NoteSpellingType::SOLFEGGIO;
else if (score()->styleB(StyleIdx::useFrenchNoteNames))
rootSpelling = NoteSpellingType::FRENCH;

baseSpelling = rootSpelling;
const ChordDescription* cd = descr();
if (cd) {
Expand All @@ -384,10 +385,8 @@ void Harmony::determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& ro
}
else
rootLowerCase = score()->styleB(StyleIdx::lowerCaseMinorChords);
if (baseSpelling == NoteSpellingType::GERMAN_PURE)
baseLowerCase = true;
else
baseLowerCase = false;
baseLowerCase = score()->styleB(StyleIdx::lowerCaseBassNotes);
noteUpperCase = score()->styleB(StyleIdx::allCapsNoteNames);
}

//---------------------------------------------------------
Expand All @@ -396,7 +395,7 @@ void Harmony::determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& ro

void Harmony::determineRootBaseSpelling()
{
determineRootBaseSpelling(_rootSpelling, _rootLowerCase, _baseSpelling, _baseLowerCase);
determineRootBaseSpelling(_rootSpelling, _rootLowerCase, _baseSpelling, _baseLowerCase, _noteUpperCase);
}

//---------------------------------------------------------
Expand All @@ -407,6 +406,7 @@ void Harmony::determineRootBaseSpelling()
static int convertRoot(const QString& s, NoteSpellingType spelling, int& idx)
{
bool useGerman = false;
bool useSolfeggio = false;
static const int spellings[] = {
// bb b - # ##
0, 7, 14, 21, 28, // C
Expand All @@ -422,7 +422,12 @@ static int convertRoot(const QString& s, NoteSpellingType spelling, int& idx)
int acci;
switch (spelling) {
case NoteSpellingType::SOLFEGGIO:
acci = 2;
case NoteSpellingType::FRENCH:
useSolfeggio = true;
if (s.toLower().startsWith("sol"))
acci = 3;
else
acci = 2;
break;
case NoteSpellingType::GERMAN:
case NoteSpellingType::GERMAN_PURE:
Expand Down Expand Up @@ -501,17 +506,17 @@ static int convertRoot(const QString& s, NoteSpellingType spelling, int& idx)
return Tpc::TPC_INVALID;
}
}
else if (spelling == NoteSpellingType::SOLFEGGIO) {
else if (useSolfeggio) {
QString ss = s.toLower().left(2);
if (ss == "do")
r = 0;
else if (ss == "re")
else if (ss == "re" || ss == "")
r = 1;
else if (ss == "mi")
r = 2;
else if (ss == "fa")
r = 3;
else if (ss == "sol")
else if (ss == "so") // sol, but only check first 2 characters
r = 4;
else if (ss == "la")
r = 5;
Expand Down Expand Up @@ -1211,7 +1216,7 @@ void Harmony::render(const QString& s, qreal& x, qreal& y)
// render
//---------------------------------------------------------

void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y, int tpc, NoteSpellingType spelling, bool lowerCase)
void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y, int tpc, NoteSpellingType spelling, bool lowerCase, bool upperCase)
{
ChordList* chordList = score()->style()->chordList();
QStack<QPointF> stack;
Expand Down Expand Up @@ -1250,7 +1255,7 @@ void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y,
else if (a.type == RenderAction::RenderActionType::NOTE) {
QString c;
int acc;
tpc2name(tpc, spelling, lowerCase, c, acc);
tpc2name(tpc, spelling, lowerCase, upperCase, c, acc);
TextSegment* ts = new TextSegment(fontList[fontIdx], x, y);
QString lookup = "note" + c;
ChordSymbol cs = chordList->symbol(lookup);
Expand All @@ -1269,13 +1274,11 @@ void Harmony::render(const QList<RenderAction>& renderList, qreal& x, qreal& y,
QString c;
QString acc;
QString context = "accidental";
tpc2name(tpc, spelling, lowerCase, c, acc);
tpc2name(tpc, spelling, lowerCase, upperCase, c, acc);
// German spelling - use special symbol for accidental in TPC_B_B
// to allow it to be rendered as either Bb or B
if (tpc == Tpc::TPC_B_B && spelling == NoteSpellingType::GERMAN) {
acc = "b";
if (tpc == Tpc::TPC_B_B && spelling == NoteSpellingType::GERMAN)
context = "german_B";
}
if (acc != "") {
TextSegment* ts = new TextSegment(fontList[fontIdx], x, y);
QString lookup = context + acc;
Expand Down Expand Up @@ -1335,7 +1338,7 @@ void Harmony::render(const TextStyle* st)

if (_rootTpc != Tpc::TPC_INVALID) {
// render root
render(chordList->renderListRoot, x, y, _rootTpc, _rootSpelling, _rootLowerCase);
render(chordList->renderListRoot, x, y, _rootTpc, _rootSpelling, _rootLowerCase, _noteUpperCase);
// render extension
const ChordDescription* cd = getDescription();
if (cd)
Expand All @@ -1346,7 +1349,7 @@ void Harmony::render(const TextStyle* st)

// render bass
if (_baseTpc != Tpc::TPC_INVALID)
render(chordList->renderListBase, x, y, _baseTpc, _baseSpelling, _baseLowerCase);
render(chordList->renderListBase, x, y, _baseTpc, _baseSpelling, _baseLowerCase, _noteUpperCase);

if (_rootTpc != Tpc::TPC_INVALID && capo > 0 && capo < 12) {
int tpcOffset[] = { 0, 5, -2, 3, -4, 1, 6, -1, 4, -3, 2, -5 };
Expand All @@ -1372,15 +1375,15 @@ void Harmony::render(const TextStyle* st)
}

render("(", x, y);
render(chordList->renderListRoot, x, y, capoRootTpc, _rootSpelling, _rootLowerCase);
render(chordList->renderListRoot, x, y, capoRootTpc, _rootSpelling, _rootLowerCase, _noteUpperCase);

// render extension
const ChordDescription* cd = getDescription();
if (cd)
render(cd->renderList, x, y, 0);

if (capoBassTpc != Tpc::TPC_INVALID)
render(chordList->renderListBase, x, y, capoBassTpc, _baseSpelling, _baseLowerCase);
render(chordList->renderListBase, x, y, capoBassTpc, _baseSpelling, _baseLowerCase, _noteUpperCase);
render(")", x, y);
}

Expand Down
6 changes: 3 additions & 3 deletions libmscore/harmony.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ class Harmony : public Text {
mutable QRectF _tbbox;

NoteSpellingType _rootSpelling, _baseSpelling;
bool _rootLowerCase, _baseLowerCase;
bool _rootLowerCase, _baseLowerCase, _noteUpperCase;

void determineRootBaseSpelling();
virtual void draw(QPainter*) const;
void render(const QString&, qreal&, qreal&);
void render(const QList<RenderAction>& renderList, qreal&, qreal&, int tpc, NoteSpellingType spelling = NoteSpellingType::STANDARD, bool lowerCase = false);
void render(const QList<RenderAction>& renderList, qreal&, qreal&, int tpc, NoteSpellingType spelling = NoteSpellingType::STANDARD, bool lowerCase = false, bool upperCase = false);
virtual void styleChanged() override { render(); }
virtual void setTextStyle(const TextStyle& st) override;

Expand All @@ -120,7 +120,7 @@ class Harmony : public Text {
const ChordDescription* getDescription(const QString&, const ParsedChord* pc = 0);
const ChordDescription* generateDescription();

void determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& rootLowerCase, NoteSpellingType& baseSpelling, bool& baseLowerCase);
void determineRootBaseSpelling(NoteSpellingType& rootSpelling, bool& rootLowerCase, NoteSpellingType& baseSpelling, bool& baseLowerCase, bool& noteUpperCase);

virtual void textChanged() override;
virtual void layout();
Expand Down
30 changes: 21 additions & 9 deletions libmscore/pitchspelling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,22 +225,22 @@ int tpc2alterByKey(int tpc, Key key) {
// return note name
//---------------------------------------------------------

QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool explicitAccidental)
QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool upperCase, bool explicitAccidental)
{
QString s;
QString acc;
tpc2name(tpc, spelling, lowerCase, s, acc, explicitAccidental);
tpc2name(tpc, spelling, lowerCase, upperCase, s, acc, explicitAccidental);
return s + (explicitAccidental ? " " : "") + acc;
}

//---------------------------------------------------------
// tpc2name
//---------------------------------------------------------

void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc, bool explicitAccidental)
void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool upperCase, QString& s, QString& acc, bool explicitAccidental)
{
int n;
tpc2name(tpc, spelling, lowerCase, s, n);
tpc2name(tpc, spelling, lowerCase, upperCase, s, n);
switch (n) {
case -2:
if (explicitAccidental) {
Expand Down Expand Up @@ -289,11 +289,11 @@ void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QS
// tpc2name
//---------------------------------------------------------

void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, int& acc)
void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool upperCase, QString& s, int& acc)
{
const char names[] = "FCGDAEB";
const char gnames[] = "FCGDAEH";
const QString inames[] = { "Fa", "Do", "Sol", "Re", "La", "Mi", "Si" };
const QString snames[] = { "Fa", "Do", "Sol", "Re", "La", "Mi", "Si" };

acc = ((tpc+1) / 7) - 2;
int idx = (tpc + 1) % 7;
Expand All @@ -303,14 +303,26 @@ void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, in
s = gnames[idx];
if (s == "H" && acc == -1) {
s = "B";
acc = 0;
if (spelling == NoteSpellingType::GERMAN_PURE)
acc = 0;
}
break;
case NoteSpellingType::SOLFEGGIO: s = inames[idx]; break;
default: s = names[idx]; break;
case NoteSpellingType::SOLFEGGIO:
s = snames[idx];
break;
case NoteSpellingType::FRENCH:
s = snames[idx];
if (s == "Re")
s = "";
break;
default:
s = names[idx];
break;
}
if (lowerCase)
s = s.toLower();
else if (upperCase)
s = s.toUpper();
}

//---------------------------------------------------------
Expand Down
8 changes: 4 additions & 4 deletions libmscore/pitchspelling.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ const int STEP_DELTA_OCTAVE = 7; // the number of steps in an octave
// pitch2tpc(pitch) replaced by pitch2tpc(pitch, Key::C, Prefer::NEAREST)

enum class Prefer : char { FLATS=8, NEAREST=11, SHARPS=13 };
enum class NoteSpellingType : char { STANDARD = 0, GERMAN, GERMAN_PURE, SOLFEGGIO };
enum class NoteSpellingType : char { STANDARD = 0, GERMAN, GERMAN_PURE, SOLFEGGIO, FRENCH };

extern int pitch2tpc(int pitch, Key, Prefer prefer);

extern void spell(QList<Event>& notes, int);
extern void spell(QList<Note*>& notes);
extern int computeWindow(const QList<Note*>& notes, int start, int end);
extern int tpc(int idx, int pitch, int opt);
extern QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool explicitAccidental = false);
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, QString& acc, bool explicitAccidental = false);
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, QString& s, int& acc);
extern QString tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase = false, bool upperCase = false, bool explicitAccidental = false);
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool upperCase, QString& s, QString& acc, bool explicitAccidental = false);
extern void tpc2name(int tpc, NoteSpellingType spelling, bool lowerCase, bool upperCase, QString& s, int& acc);
extern int step2tpc(const QString& stepName, AccidentalVal alter);
extern int step2tpc(int step);
extern int step2tpc(int step, AccidentalVal alter);
Expand Down
2 changes: 2 additions & 0 deletions libmscore/read114.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ static const StyleVal2 style114[] = {
{ StyleIdx::genCourtesyKeysig, QVariant(true) },
{ StyleIdx::useStandardNoteNames, QVariant(true) },
{ StyleIdx::useGermanNoteNames, QVariant(false) },
{ StyleIdx::useFullGermanNoteNames, QVariant(false) },
{ StyleIdx::useSolfeggioNoteNames, QVariant(false) },
{ StyleIdx::useFrenchNoteNames, QVariant(false) },
{ StyleIdx::chordDescriptionFile, QVariant(QString("stdchords.xml")) },
{ StyleIdx::chordStyle, QVariant(QString("custom")) },
{ StyleIdx::chordsXmlFile, QVariant(true) },
Expand Down
8 changes: 8 additions & 0 deletions libmscore/style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,12 @@ static const StyleTypes2 styleTypes2[] = {
{ StyleIdx::swingUnit, StyleType("swingUnit", StyleValueType::STRING) },
{ StyleIdx::useStandardNoteNames, StyleType("useStandardNoteNames", StyleValueType::BOOL) },
{ StyleIdx::useGermanNoteNames, StyleType("useGermanNoteNames", StyleValueType::BOOL) },
{ StyleIdx::useFullGermanNoteNames, StyleType("useFullGermanNoteNames", StyleValueType::BOOL) },
{ StyleIdx::useSolfeggioNoteNames, StyleType("useSolfeggioNoteNames", StyleValueType::BOOL) },
{ StyleIdx::useFrenchNoteNames, StyleType("useFrenchNoteNames", StyleValueType::BOOL) },
{ StyleIdx::lowerCaseMinorChords, StyleType("lowerCaseMinorChords", StyleValueType::BOOL) },
{ StyleIdx::lowerCaseBassNotes, StyleType("lowerCaseBassNotes", StyleValueType::BOOL) },
{ StyleIdx::allCapsNoteNames, StyleType("allCapsNoteNames", StyleValueType::BOOL) },
{ StyleIdx::chordStyle, StyleType("chordStyle", StyleValueType::STRING) },
{ StyleIdx::chordsXmlFile, StyleType("chordsXmlFile", StyleValueType::BOOL) },
{ StyleIdx::chordDescriptionFile, StyleType("chordDescriptionFile", StyleValueType::STRING) },
Expand Down Expand Up @@ -476,8 +480,12 @@ StyleData::StyleData()
{ StyleIdx::swingUnit, QVariant(QString("")) },
{ StyleIdx::useStandardNoteNames, QVariant(true) },
{ StyleIdx::useGermanNoteNames, QVariant(false) },
{ StyleIdx::useFullGermanNoteNames, QVariant(false) },
{ StyleIdx::useSolfeggioNoteNames, QVariant(false) },
{ StyleIdx::useFrenchNoteNames, QVariant(false) },
{ StyleIdx::lowerCaseMinorChords, QVariant(false) },
{ StyleIdx::lowerCaseBassNotes, QVariant(false) },
{ StyleIdx::allCapsNoteNames, QVariant(false) },
{ StyleIdx::chordStyle, QVariant(QString("std")) },
{ StyleIdx::chordsXmlFile, QVariant(false) },
{ StyleIdx::chordDescriptionFile, QVariant(QString("chords_std.xml")) },
Expand Down
4 changes: 4 additions & 0 deletions libmscore/style.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,12 @@ enum class StyleIdx : unsigned char {

useStandardNoteNames,
useGermanNoteNames,
useFullGermanNoteNames,
useSolfeggioNoteNames,
useFrenchNoteNames,
lowerCaseMinorChords,
lowerCaseBassNotes,
allCapsNoteNames,
chordStyle,
chordsXmlFile,
chordDescriptionFile,
Expand Down
Loading

0 comments on commit fbdd224

Please sign in to comment.