mirror of
https://github.com/microtherion/VocalEasel.git
synced 2025-01-03 17:04:00 +00:00
Much smarter lyrics layout
This commit is contained in:
parent
19cea3837c
commit
f503e03cc3
|
@ -114,22 +114,78 @@ void VLTextLayout::AddSyllable(const VLSyllable & syll, float x)
|
||||||
typedef std::vector<VLLayoutSyll>::iterator VLSyllIter;
|
typedef std::vector<VLLayoutSyll>::iterator VLSyllIter;
|
||||||
|
|
||||||
#define NARROW_SPACE "\xE2\x80\x89"
|
#define NARROW_SPACE "\xE2\x80\x89"
|
||||||
|
#define PRE_DASH "-" NARROW_SPACE
|
||||||
|
#define POST_DASH NARROW_SPACE "-"
|
||||||
|
|
||||||
void VLTextLayout::DrawLine(float y)
|
void VLTextLayout::DrawLine(float y)
|
||||||
{
|
{
|
||||||
|
if (fSyllables.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const float kDashW = fRegularFont->Width("-");
|
||||||
|
const float kSpaceW = fRegularFont->Width(NARROW_SPACE);
|
||||||
VLSyllIter syll = fSyllables.begin();
|
VLSyllIter syll = fSyllables.begin();
|
||||||
VLSyllIter end = fSyllables.end();
|
VLSyllIter end = fSyllables.end();
|
||||||
|
float nextW = fRegularFont->Width(syll->fText.c_str());
|
||||||
|
float nextX = syll->fX-0.5*nextW;
|
||||||
|
|
||||||
|
if (syll->fKind & VLSyllable::kHasPrev)
|
||||||
|
fRegularFont->Draw(nextX-fRegularFont->Width(PRE_DASH), y, PRE_DASH);
|
||||||
|
|
||||||
while (syll != end) {
|
while (syll != end) {
|
||||||
std::string text = syll->fText;
|
std::string text = syll->fText;
|
||||||
float x = syll->fX-0.5*fRegularFont->Width(text.c_str());
|
VLSyllIter next = syll+1;
|
||||||
if (syll == fSyllables.begin() && syll->fKind & VLSyllable::kHasPrev)
|
float curW = nextW;
|
||||||
text = "-" NARROW_SPACE + text;
|
float curX = nextX;
|
||||||
if (syll->fKind & VLSyllable::kHasNext)
|
|
||||||
text += NARROW_SPACE "-";
|
|
||||||
|
|
||||||
fRegularFont->Draw(x, y, text.c_str());
|
while (next != end) {
|
||||||
|
nextW = fRegularFont->Width(next->fText.c_str());
|
||||||
|
nextX = next->fX-0.5*nextW;
|
||||||
|
if (next->fKind & VLSyllable::kHasPrev) {
|
||||||
|
if (curX+curW+kDashW < nextX) {
|
||||||
|
//
|
||||||
|
// Plenty of space, draw dashes
|
||||||
|
//
|
||||||
|
float dashSpace = 0.5*(nextX-curX-curW-kDashW);
|
||||||
|
fRegularFont->Draw(curX, y, text.c_str());
|
||||||
|
fRegularFont->Draw(curX+curW+dashSpace, y, "-");
|
||||||
|
|
||||||
++syll;
|
goto nextText;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Fuse & continue
|
||||||
|
//
|
||||||
|
text += next->fText;
|
||||||
|
curW = fRegularFont->Width(text.c_str());
|
||||||
|
if (++next != end) {
|
||||||
|
nextW = fRegularFont->Width(next->fText.c_str());
|
||||||
|
nextX = next->fX-0.5*nextW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (curX+curW+kSpaceW < nextX) {
|
||||||
|
//
|
||||||
|
// Enough space, draw regular
|
||||||
|
//
|
||||||
|
fRegularFont->Draw(curX, y, text.c_str());
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Tight space, draw narrow & adjust
|
||||||
|
//
|
||||||
|
fNarrowFont->Draw(curX, y, text.c_str());
|
||||||
|
text += NARROW_SPACE;
|
||||||
|
nextX = std::max(nextX, curX+fNarrowFont->Width(text.c_str()));
|
||||||
|
}
|
||||||
|
goto nextText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// At end of line
|
||||||
|
//
|
||||||
|
if ((end-1)->fKind & VLSyllable::kHasNext)
|
||||||
|
text += POST_DASH;
|
||||||
|
fRegularFont->Draw(curX, y, text.c_str());
|
||||||
|
nextText:
|
||||||
|
syll = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user