Skip to content

Commit 7c8956b

Browse files
backend: try to recognize title & composer if not explicitly stated
1 parent b72a591 commit 7c8956b

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

src/converter/internal/compat/notationmeta.cpp

+79
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "notationmeta.h"
2323

2424
#include <cmath>
25+
#include <climits>
2526

2627
#include <QJsonArray>
2728
#include <QJsonObject>
@@ -41,6 +42,76 @@ static QString boolToString(bool b)
4142
return b ? "true" : "false";
4243
}
4344

45+
static bool shouldTryRecognizeText(const Text* text)
46+
{
47+
const TextStyleType type = text->textStyleType();
48+
if (type == TextStyleType::DEFAULT || type == TextStyleType::FRAME) {
49+
return true;
50+
}
51+
52+
return (int)(type) >= (int)TextStyleType::USER1 && (int)(type) <= (int)TextStyleType::USER12;
53+
}
54+
55+
static QString recognizeTitle(const mu::engraving::Score* score)
56+
{
57+
const MeasureBase* mb = score->first();
58+
if (!mb || !mb->isVBox()) {
59+
return QString();
60+
}
61+
62+
const Text* titleText = nullptr;
63+
double maxFontSize = score->style().value(Sid::titleFontSize).toDouble();
64+
double minY = DBL_MAX;
65+
66+
for (const EngravingItem* item : mb->el()) {
67+
if (!item || !item->isText()) {
68+
continue;
69+
}
70+
71+
const Text* text = toText(item);
72+
if (!shouldTryRecognizeText(text)) {
73+
continue;
74+
}
75+
76+
if (RealIsEqualOrMore(text->size(), maxFontSize) && RealIsEqualOrLess(text->y(), minY)) {
77+
titleText = text;
78+
maxFontSize = text->size();
79+
minY = text->y();
80+
}
81+
}
82+
83+
return titleText ? titleText->plainText().toQString() : QString();
84+
}
85+
86+
static QString recognizeComposer(const mu::engraving::Score* score)
87+
{
88+
const MeasureBase* mb = score->first();
89+
if (!mb || !mb->isVBox()) {
90+
return QString();
91+
}
92+
93+
const Text* rightmostText = nullptr;
94+
double rightmostTextX = mb->ldata()->bbox().center().x();
95+
96+
for (const EngravingItem* item : mb->el()) {
97+
if (!item || !item->isText()) {
98+
continue;
99+
}
100+
101+
const Text* text = toText(item);
102+
if (!shouldTryRecognizeText(text)) {
103+
continue;
104+
}
105+
106+
if (text->x() > rightmostTextX) {
107+
rightmostText = text;
108+
rightmostTextX = text->x();
109+
}
110+
}
111+
112+
return rightmostText ? rightmostText->plainText().toQString() : QString();
113+
}
114+
44115
RetVal<std::string> NotationMeta::metaJson(notation::INotationPtr notation)
45116
{
46117
IF_ASSERT_FAILED(notation) {
@@ -98,6 +169,10 @@ QString NotationMeta::title(const mu::engraving::Score* score)
98169
title = score->metaTag(u"workTitle");
99170
}
100171

172+
if (title.isEmpty()) {
173+
title = recognizeTitle(score);
174+
}
175+
101176
if (title.isEmpty()) {
102177
title = score->name();
103178
}
@@ -128,6 +203,10 @@ QString NotationMeta::composer(const mu::engraving::Score* score)
128203
composer = score->metaTag(u"composer");
129204
}
130205

206+
if (composer.isEmpty()) {
207+
composer = recognizeComposer(score);
208+
}
209+
131210
return composer;
132211
}
133212

0 commit comments

Comments
 (0)