Skip to content

Commit 13742f4

Browse files
authored
Merge pull request #4402 from sonovice/fix/harm-rend-sup
Fix harmony superscript positioning
2 parents e246b7b + 975f7c2 commit 13742f4

3 files changed

Lines changed: 13 additions & 15 deletions

File tree

include/vrv/svgdevicecontext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ class SvgDeviceContext : public DeviceContext {
358358

359359
bool m_committed; // did we flushed the file?
360360
int m_originX, m_originY;
361+
/** Current text baseline, used to express vertical moves as relative SVG dy values. */
362+
int m_textY;
361363

362364
// Here we hold references to all different glyphs used so far,
363365
// including any glyph for the same code but from different fonts.

src/svgdevicecontext.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ SvgDeviceContext::SvgDeviceContext(const std::string &docId) : DeviceContext(SVG
4141

4242
m_originX = 0;
4343
m_originY = 0;
44+
m_textY = 0;
4445

4546
m_smuflGlyphs.clear();
4647

@@ -1016,6 +1017,7 @@ void SvgDeviceContext::StartText(int x, int y, data_HORIZONTALALIGNMENT alignmen
10161017
m_svgNodeStack.push_back(m_currentNode);
10171018
if (x) m_currentNode.append_attribute("x") = x;
10181019
if (y) m_currentNode.append_attribute("y") = y;
1020+
m_textY = y;
10191021
// unless dx, dy have a value they don't need to be set
10201022
// m_currentNode.append_attribute("dx") = 0;
10211023
// m_currentNode.append_attribute("dy") = 0;
@@ -1051,6 +1053,7 @@ void SvgDeviceContext::MoveTextTo(int x, int y, data_HORIZONTALALIGNMENT alignme
10511053
{
10521054
m_currentNode.append_attribute("x") = x;
10531055
m_currentNode.append_attribute("y") = y;
1056+
m_textY = y;
10541057
if (alignment != HORIZONTALALIGNMENT_NONE) {
10551058
std::string anchor = "start";
10561059
if (alignment == HORIZONTALALIGNMENT_right) {
@@ -1065,7 +1068,10 @@ void SvgDeviceContext::MoveTextTo(int x, int y, data_HORIZONTALALIGNMENT alignme
10651068

10661069
void SvgDeviceContext::MoveTextVerticallyTo(int y)
10671070
{
1068-
m_currentNode.append_attribute("y") = y;
1071+
// An absolute y starts a new anchored text chunk in SVG. Use a relative shift so
1072+
// superscripts and subscripts remain part of the surrounding horizontal text run.
1073+
m_currentNode.append_attribute("dy") = y - m_textY;
1074+
m_textY = y;
10691075
}
10701076

10711077
void SvgDeviceContext::EndText()

src/view_text.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,12 @@ void View::DrawHarmString(DeviceContext *dc, const std::u32string &str, TextDraw
157157
assert(dc);
158158
assert(dc->HasFont());
159159

160-
int toDcX = this->ToDeviceContextX(params.m_x);
161-
int toDcY = this->ToDeviceContextY(params.m_y);
162-
163160
size_t prevPos = 0, pos;
164161
while ((pos = str.find_first_of(VRV_TEXT_HARM, prevPos)) != std::wstring::npos) {
165162
// If pos is > than the previous, it is the substring to extract
166163
if (pos > prevPos) {
167164
std::u32string substr = str.substr(prevPos, pos - prevPos);
168-
dc->DrawText(UTF32to8(substr), substr, toDcX, toDcY);
169-
// Once we have rendered the some text to not pass x / y anymore
170-
toDcX = VRV_UNSET;
171-
toDcY = VRV_UNSET;
165+
dc->DrawText(UTF32to8(substr), substr);
172166
}
173167

174168
// if it is the same or we still have space, it is the accidental
@@ -201,23 +195,19 @@ void View::DrawHarmString(DeviceContext *dc, const std::u32string &str, TextDraw
201195
bool isFallbackNeeded = (m_doc->GetResources()).IsSmuflFallbackNeeded(smuflAccid);
202196
vrvTxt.SetSmuflWithFallback(isFallbackNeeded);
203197
dc->SetFont(&vrvTxt);
204-
// Once we have rendered the some text to not pass x / y anymore
205-
dc->DrawText(UTF32to8(smuflAccid), smuflAccid, toDcX, toDcY);
198+
dc->DrawText(UTF32to8(smuflAccid), smuflAccid);
206199
dc->ResetFont();
207-
toDcX = VRV_UNSET;
208-
toDcY = VRV_UNSET;
209200
}
210201
// Skip the accidental and continue
211202
prevPos = pos + 1;
212203
}
213204
// Print the remainder of the string, or the full string if no accid
214205
if (prevPos < str.length()) {
215206
std::u32string substr = str.substr(prevPos, std::wstring::npos);
216-
dc->DrawText(UTF32to8(substr), substr, toDcX, toDcY);
207+
dc->DrawText(UTF32to8(substr), substr);
217208
}
218209

219-
// Disable x for what is coming next as child of <f>
220-
// The value is reset in DrawFb
210+
// Continue subsequent harmony children in the current text run.
221211
params.m_x = VRV_UNSET;
222212
}
223213

0 commit comments

Comments
 (0)