From 9a5fbe5ea56ad7203c25b71253b4a14703ae8176 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 Feb 2019 14:52:01 -0800 Subject: [PATCH] Savedata: Truncate detail if it's too long. We could add scrolling later, but this makes it more usable without ugly text overlap, at least. Fixes #11711. --- Core/Dialog/PSPMsgDialog.cpp | 4 +- Core/Dialog/PSPNetconfDialog.cpp | 2 +- Core/Dialog/PSPSaveDialog.cpp | 8 ++-- Core/Util/PPGeDraw.cpp | 77 ++++++++++++++++++++++++++------ Core/Util/PPGeDraw.h | 4 +- 5 files changed, 73 insertions(+), 22 deletions(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index b50dee2a9f96..302113b3b522 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -207,8 +207,8 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) ey = y2 + 25.0f; } - PPGeDrawTextWrapped(text.c_str(), 241.0f, y+2, WRAP_WIDTH, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(text.c_str(), 241.0f, y+2, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); sy = 125.0f - h2; PPGeDrawRect(40.0f, sy, 440.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(40.0f, ey, 440.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index d9f6ff1c5438..25c9d42bafc0 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -81,7 +81,7 @@ int PSPNetconfDialog::Update(int animSpeed) { StartDraw(); DrawBanner(); PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0x63636363)); - PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, PPGE_ALIGN_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, 0, CalcFadedColor(0xFFFFFFFF)); PPGeDrawText(di->T("OK"), 225, 252, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 09b32dcc01b6..c06a4361520c 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -458,8 +458,8 @@ void PSPSaveDialog::DisplaySaveDataInfo1() PPGeDrawText(timeTxt.c_str(), 180, 137, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawText(saveTitleTxt.c_str(), 176, 162, PPGE_ALIGN_LEFT, 0.55f, CalcFadedColor(0x80000000)); PPGeDrawText(saveTitleTxt.c_str(), 175, 159, PPGE_ALIGN_LEFT, 0.55f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(saveDetailTxt.c_str(), 176, 183, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawText(saveDetailTxt.c_str(), 175, 181, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(saveDetailTxt.c_str(), 176, 183, 480 - 175, 250 - 183, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0x80000000)); + PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } } @@ -573,8 +573,8 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) yesnoChoice = 0; } } - PPGeDrawTextWrapped(text.c_str(), 335.0f, y+2, WRAP_WIDTH, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(text.c_str(), 335.0f, y+2, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); float sy = 122.0f - h2, ey = 150.0f + h2; PPGeDrawRect(202.0f, sy, 466.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(202.0f, ey, 466.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index cb091c837a22..442ce268af6d 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -17,6 +17,7 @@ #include +#include "base/stringutil.h" #include "image/zim_load.h" #include "image/png_load.h" #include "util/text/utf8.h" @@ -377,7 +378,7 @@ static const AtlasChar *PPGeGetChar(const AtlasFont &atlasfont, unsigned int cva // Break a single text string into mutiple lines. static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, float x, float y, - int align, float scale, int wrapType, float wrapWidth, bool dryRun) + int align, float scale, float lineHeightScale, int wrapType, float wrapWidth, bool dryRun) { y += atlasfont.ascend * scale; float sx = x, sy = y; @@ -399,7 +400,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, int numLines = 1; float maxw = 0; - float lineHeight = atlasfont.height * scale; + float lineHeight = atlasfont.height * lineHeightScale; for (UTF8 utf(text); !utf.end(); ) { float lineWidth = 0; @@ -617,16 +618,16 @@ void PPGeMeasureText(float *w, float *h, int *n, const char *text, float scale, int WrapType, int wrapWidth) { const AtlasFont &atlasfont = *ppge_atlas.fonts[0]; - AtlasTextMetrics metrics = BreakLines(text, atlasfont, 0, 0, 0, scale, WrapType, wrapWidth, true); + AtlasTextMetrics metrics = BreakLines(text, atlasfont, 0, 0, 0, scale, scale, WrapType, wrapWidth, true); if (w) *w = metrics.maxWidth; if (h) *h = metrics.lineHeight; if (n) *n = metrics.numLines; } -void PPGePrepareText(const char *text, float x, float y, int align, float scale, int WrapType, int wrapWidth) +void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale, int WrapType, int wrapWidth) { const AtlasFont &atlasfont = *ppge_atlas.fonts[0]; - char_lines_metrics = BreakLines(text, atlasfont, x, y, align, scale, WrapType, wrapWidth, false); + char_lines_metrics = BreakLines(text, atlasfont, x, y, align, scale, lineHeightScale, WrapType, wrapWidth, false); } void PPGeMeasureCurrentText(float *x, float *y, float *w, float *h, int *n) @@ -638,6 +639,13 @@ void PPGeMeasureCurrentText(float *x, float *y, float *w, float *h, int *n) if (n) *n = char_lines_metrics.numLines; } +static void PPGeResetCurrentText() { + char_one_line.clear(); + char_lines.clear(); + AtlasTextMetrics zeroBox = { 0 }; + char_lines_metrics = zeroBox; +} + // Draws some text using the one font we have. // Mostly rewritten. void PPGeDrawCurrentText(u32 color) @@ -661,21 +669,64 @@ void PPGeDrawCurrentText(u32 color) } EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } - char_one_line.clear(); - char_lines.clear(); - AtlasTextMetrics zeroBox = { 0 }; - char_lines_metrics = zeroBox; + PPGeResetCurrentText(); } void PPGeDrawText(const char *text, float x, float y, int align, float scale, u32 color) { - PPGePrepareText(text, x, y, align, scale, PPGE_LINE_USE_ELLIPSIS); + PPGePrepareText(text, x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS); PPGeDrawCurrentText(color); } -void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, int align, float scale, u32 color) -{ - PPGePrepareText(text, x, y, align, scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); +static std::string StripTrailingWhite(const std::string &s) { + size_t lastChar = s.find_last_not_of(" \t\r\n"); + if (lastChar != s.npos) { + return s.substr(0, lastChar + 1); + } + return s; +} + +static std::string CropLinesToCount(const std::string &s, int numLines) { + std::vector lines; + SplitString(s, '\n', lines); + if ((int)lines.size() <= numLines) { + return s; + } + + size_t len = 0; + for (int i = 0; i < numLines; ++i) { + len += lines[i].length() + 1; + } + + return s.substr(0, len); +} + +void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, int align, float scale, u32 color) { + std::string s = text; + if (wrapHeight != 0) { + s = StripTrailingWhite(s); + } + + PPGePrepareText(s.c_str(), x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); + + int zoom = (PSP_CoreParameter().pixelHeight + 479) / 480; + float maxScaleDown = zoom == 1 ? 1.3f : 2.0f; + float actualHeight = char_lines_metrics.lineHeight * char_lines_metrics.numLines; + if (actualHeight > wrapHeight) { + if (actualHeight > wrapHeight * maxScaleDown) { + float maxLines = floor(wrapHeight * maxScaleDown / char_lines_metrics.lineHeight); + actualHeight = (maxLines + 1) * char_lines_metrics.lineHeight; + // Add an ellipsis if it's just too long to be readable. + // On a PSP, it does this without scaling it down. + s = StripTrailingWhite(CropLinesToCount(s, (int)maxLines)) + "\n..."; + } + + // Measure the text again after scaling down. + PPGeResetCurrentText(); + float reduced = scale * wrapHeight / actualHeight; + // Try to keep the font as large as possible, so reduce the line height some. + PPGePrepareText(s.c_str(), x, y, align, reduced * 1.15, reduced, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); + } PPGeDrawCurrentText(color); } diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index 8283d99f760b..df18dd0dbcbf 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -80,7 +80,7 @@ void PPGeMeasureText(float *w, float *h, int *n, const char *text, float scale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0); // Overwrite the current text lines buffer so it can be drawn later. -void PPGePrepareText(const char *text, float x, float y, int align, float scale, +void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0); // Get the metrics of the bounding box of the currently stated text. @@ -95,7 +95,7 @@ void PPGeDrawCurrentText(u32 color = 0xFFFFFFFF); // Draws some text using the one font we have. // Clears the text buffer when done. void PPGeDrawText(const char *text, float x, float y, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF); -void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF); +void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF); // Draws a "4-patch" for button-like things that can be resized. void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF);