implement furigana support for message window

This commit is contained in:
DeaTh-G 2025-01-28 20:43:34 +01:00
parent 66253bfd9e
commit 9c7fb185f0
4 changed files with 42 additions and 19 deletions

View file

@ -560,7 +560,7 @@ std::string RemoveAnnotationFromParagraphLine(const std::vector<TextSegment>& an
return result; return result;
} }
ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, std::vector<std::string> lines) ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, const std::vector<std::string>& lines)
{ {
auto x = 0.0f; auto x = 0.0f;
auto y = 0.0f; auto y = 0.0f;
@ -573,15 +573,17 @@ ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMar
annotationRemovedLines.emplace_back(RemoveAnnotationFromParagraphLine(line)); annotationRemovedLines.emplace_back(RemoveAnnotationFromParagraphLine(line));
} }
for (auto& line : annotationRemovedLines) for (size_t i = 0; i < annotationRemovedLines.size(); i++)
{ {
auto& line = annotationRemovedLines[i];
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, line.c_str()); auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, line.c_str());
auto annotationSize = font->CalcTextSizeA(fontSize * 0.55f, FLT_MAX, 0, ""); auto annotationSize = font->CalcTextSizeA(fontSize * ANNOTATION_FONT_SIZE_MODIFIER, FLT_MAX, 0, "");
x = std::max(x, textSize.x); x = std::max(x, textSize.x);
y += textSize.y + Scale(lineMargin); y += textSize.y + Scale(lineMargin);
if (annotatedLines.annotated && &line != &lines.back() && &line != &lines.front()) if (annotatedLines.annotated)
{ {
y += annotationSize.y; y += annotationSize.y;
} }
@ -601,13 +603,14 @@ void DrawRubyAnnotatedText(const ImFont* font, float fontSize, float maxWidth, c
const auto& input = RemoveRubyAnnotations(text); const auto& input = RemoveRubyAnnotations(text);
auto lines = Split(input.first.c_str(), font, fontSize, maxWidth); auto lines = Split(input.first.c_str(), font, fontSize, maxWidth);
auto paragraphSize = MeasureCentredParagraph(font, fontSize, lineMargin, lines);
float offsetY = 0.0f;
for (auto& line : lines) for (auto& line : lines)
{ {
line = ReAddRubyAnnotations(line, input.second); line = ReAddRubyAnnotations(line, input.second);
} }
auto paragraphSize = MeasureCentredParagraph(font, fontSize, lineMargin, lines);
float offsetY = 0.0f;
const auto& annotatedLines = CalculateAnnotatedParagraph(lines); const auto& annotatedLines = CalculateAnnotatedParagraph(lines);
@ -619,21 +622,20 @@ void DrawRubyAnnotatedText(const ImFont* font, float fontSize, float maxWidth, c
auto annotationSize = font->CalcTextSizeA(annotationFontSize, FLT_MAX, 0, ""); auto annotationSize = font->CalcTextSizeA(annotationFontSize, FLT_MAX, 0, "");
float textX = pos.x; float textX = pos.x;
float textY = pos.y + offsetY;
if (isCentred) if (isCentred)
{ {
textX = annotationRemovedLine.starts_with("- ") textX = annotationRemovedLine.starts_with("- ")
? pos.x - paragraphSize.x / 2 ? pos.x - paragraphSize.x / 2
: pos.x - textSize.x / 2; : pos.x - textSize.x / 2;
textY = pos.y - paragraphSize.y / 2 + offsetY;
} }
for (const auto& segment : annotatedLine) for (const auto& segment : annotatedLine)
{ {
textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, segment.text.c_str()); textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, segment.text.c_str());
float textY = pos.y + offsetY;
if (isCentred)
{
textY = pos.y - paragraphSize.y / 2 + offsetY;
}
if (segment.annotated) if (segment.annotated)
{ {

View file

@ -67,7 +67,7 @@ std::vector<std::string> Split(const char* strStart, const ImFont* font, float f
Paragraph CalculateAnnotatedParagraph(const std::vector<std::string>& lines); Paragraph CalculateAnnotatedParagraph(const std::vector<std::string>& lines);
std::vector<std::string> RemoveAnnotationFromParagraph(const std::vector<std::string>& lines); std::vector<std::string> RemoveAnnotationFromParagraph(const std::vector<std::string>& lines);
std::string RemoveAnnotationFromParagraphLine(const std::vector<TextSegment>& annotatedLine); std::string RemoveAnnotationFromParagraphLine(const std::vector<TextSegment>& annotatedLine);
ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, std::vector<std::string> lines); ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, const std::vector<std::string>& lines);
ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float maxWidth, float lineMargin, const char* text); ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float maxWidth, float lineMargin, const char* text);
void DrawRubyAnnotatedText(const ImFont* font, float fontSize, float maxWidth, const ImVec2& pos, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod, std::function<void(const char*, float, ImVec2)> annotationDrawMethod, bool isCentred = false); void DrawRubyAnnotatedText(const ImFont* font, float fontSize, float maxWidth, const ImVec2& pos, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod, std::function<void(const char*, float, ImVec2)> annotationDrawMethod, bool isCentred = false);
float Lerp(float a, float b, float t); float Lerp(float a, float b, float t);

View file

@ -343,12 +343,12 @@ static const int WIZARD_INSTALL_TEXTURE_INDEX[] =
// These are ordered from bottom to top in a 3x2 grid. // These are ordered from bottom to top in a 3x2 grid.
const char* LANGUAGE_TEXT[] = const char* LANGUAGE_TEXT[] =
{ {
"FRANÇAIS", // French "FRANÇAIS", // French
"DEUTSCH", // German "DEUTSCH", // German
"ENGLISH", // English "ENGLISH", // English
"ESPAÑOL", // Spanish "ESPAÑOL", // Spanish
"ITALIANO", // Italian "ITALIANO", // Italian
"日本語", // Japanese "日本語", // Japanese
}; };
const ELanguage LANGUAGE_ENUM[] = const ELanguage LANGUAGE_ENUM[] =

View file

@ -272,10 +272,31 @@ void MessageWindow::Draw()
auto maxWidth = Scale(820); auto maxWidth = Scale(820);
auto fontSize = Scale(28); auto fontSize = Scale(28);
auto textSize = MeasureCentredParagraph(g_fntSeurat, fontSize, maxWidth, 5, g_text.c_str());
const auto& input = RemoveRubyAnnotations(g_text.c_str());
auto lines = Split(input.first.c_str(), g_fntSeurat, fontSize, maxWidth);
for (auto& line : lines)
{
line = ReAddRubyAnnotations(line, input.second);
}
auto lineMargin = Config::Language != ELanguage::Japanese ? 5.0f : 5.5f;
auto textSize = MeasureCentredParagraph(g_fntSeurat, fontSize, lineMargin, lines);
auto textMarginX = Scale(37); auto textMarginX = Scale(37);
auto textMarginY = Scale(45); auto textMarginY = Scale(45);
auto textX = centre.x;
auto textY = centre.y + Scale(3);
if (Config::Language == ELanguage::Japanese)
{
textMarginX -= Scale(2.5f);
textMarginY -= Scale(7.5f);
textY += Scale(lines.size() % 2 == 0 ? 8.5f : 15.5f);
}
bool isController = hid::IsInputDeviceController(); bool isController = hid::IsInputDeviceController();
bool isKeyboard = hid::g_inputDevice == hid::EInputDevice::Keyboard; bool isKeyboard = hid::g_inputDevice == hid::EInputDevice::Keyboard;
@ -312,8 +333,8 @@ void MessageWindow::Draw()
g_fntSeurat, g_fntSeurat,
fontSize, fontSize,
maxWidth, maxWidth,
{ centre.x, centre.y + Scale(3) }, { textX, textY },
5, lineMargin,
g_text.c_str(), g_text.c_str(),
[=](const char* str, ImVec2 pos) [=](const char* str, ImVec2 pos)
@ -322,7 +343,7 @@ void MessageWindow::Draw()
}, },
[=](const char* str, float size, ImVec2 pos) [=](const char* str, float size, ImVec2 pos)
{ {
DrawTextWithShadow(g_fntSeurat, size, pos, IM_COL32(255, 255, 255, 255), str); DrawTextWithShadow(g_fntSeurat, size, pos, IM_COL32(255, 255, 255, 255), str, 1.0f);
}, },
true true