Decompile 2 functions in Source/UI/Window/UIWindow.cpp, Source/UI/Window/UIWindow.h, ...

Batch #5472 by Yommy: 0 byte-identical, 2 confirmed by peer review.

- fn_16977 UIWindow::FitDisplayText: logic confirmed by peer review
- fn_16978 UIWindow::FitVerticalDisplayText: logic confirmed by peer review

Peer-reviewed-by: ragnarok-clanker, willerthal
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
ragnarok-clanker 2026-10-30 13:23:42 +00:00
commit 2f72e3aada
3 changed files with 125 additions and 0 deletions

View file

@ -34,6 +34,8 @@ struct UITextViewerContext {
};
class UITextViewer : public UIListBox {
friend class UIWindow;
public:
UITextViewer(UIWindowContext& windows, UITextViewerContext& text);
~UITextViewer() override;

View file

@ -26,6 +26,9 @@
#include "UI/Lists/UIScrollBar.h"
#include "UI/Lists/UIScrollBarNavi.h"
#include "UI/Text/ColoredText.h"
#include "UI/Text/NavigationLink.h"
#include "UI/Text/TextMarkup.h"
#include "UI/Text/UITextViewer.h"
#include "UI/UIStaticBitmap.h"
#include "UI/Navigation/UINavigationV4Wnd.h"
#include "UI/Navigation/UIPrivateAirplaneWnd.h"
@ -35,8 +38,10 @@
#include "UI/Window/WindowManagerWindows.h"
#include "UI/Window/WindowPolicy.h"
#include "UI/Window/WindowRegistration.h"
#include "Utility/Text/StringUtil.h"
#include <algorithm>
#include <atlconv.h>
#include <bit>
#include <cstdlib>
#include <cstdio>
@ -1340,6 +1345,118 @@ int UIWindow::FormattedTextWidth(std::string text, int family, int height, unsig
return total;
}
// OFFSET: 0x00A80880
// FUNCTION: fn_16977
std::string UIWindow::FitDisplayText(int width, const char* text, int family, int height, unsigned char bold) {
std::string display = DisplayTextTag(std::string(text), "<URL>", "</URL>");
display = DisplayTextTag(std::move(display), "<NAVI>", "</NAVI>");
display = DisplayTextTag(std::move(display), "<TIPBOX>", "</TIPBOX>");
display = DisplayTextTag(std::move(display), "<ITEM>", "</ITEM>");
display = RemoveTextLinkInfo(std::move(display));
if (this->m_context->chatConverter) {
display = this->m_context->chatConverter->ConvertChat(std::move(display));
}
std::string navigation;
DisplayNavigationLink(navigation, display);
display = std::move(navigation);
display = DisplayTextTag(std::move(display), "<QUEST>", "</QUEST>");
const auto textWidth = [this, family, height, bold](const char* value) {
if (!value) {
return 0;
}
const unsigned bytes = static_cast<unsigned>(std::strlen(value));
if (!bytes) {
return 0;
}
TextContext context(*this->geometry.surface);
context.SetFont(family, height, bold, 0);
return static_cast<int>(context.Measure(value, bytes).cx);
};
const int extent = textWidth(display.c_str());
{
TextContext context(*this->geometry.surface);
context.SetFont(family, height, bold, 0);
context.Measure("...", 3);
}
if (extent <= width) {
return display;
}
std::string fitted(display);
ATL::CA2WEX<128> wide(display.c_str(), CP_THREAD_ACP);
std::wstring remaining(wide);
while (remaining.size() > 1) {
std::size_t length = remaining.size() - 1;
if ((remaining[remaining.size() - 2] & 0x80) != 0 && (remaining[remaining.size() - 1] & 0x80) != 0) {
--length;
}
remaining.resize(length);
ATL::CW2AEX<128> converted(remaining.c_str(), CP_THREAD_ACP);
fitted = std::string(converted) + "...";
if (textWidth(fitted.c_str()) <= width) {
return fitted;
}
}
ATL::CW2AEX<128> converted(remaining.c_str(), CP_THREAD_ACP);
fitted = std::string(converted) + "...";
return fitted;
}
// OFFSET: 0x00A81400
// FUNCTION: fn_16978
std::string UIWindow::FitVerticalDisplayText(int height, const char* text, int family, int fontHeight, unsigned char bold) {
std::string display = DisplayTextTag(std::string(text), "<URL>", "</URL>");
display = DisplayTextTag(std::move(display), "<NAVI>", "</NAVI>");
display = DisplayTextTag(std::move(display), "<TIPBOX>", "</TIPBOX>");
display = DisplayTextTag(std::move(display), "<ITEM>", "</ITEM>");
display = RemoveTextLinkInfo(std::move(display));
if (this->m_context->chatConverter) {
display = this->m_context->chatConverter->ConvertChat(std::move(display));
}
std::string navigation;
DisplayNavigationLink(navigation, display);
display = std::move(navigation);
display = DisplayTextTag(std::move(display), "<QUEST>", "</QUEST>");
if (this->VerticalTextHeight(this->m_context->fonts, this->m_context->locale, display.c_str(), display.size(), family, fontHeight, bold) <= height) {
return display;
}
const char* begin = display.c_str();
std::size_t length = display.size();
std::string fitted(display);
int extent;
do {
fitted.resize(length);
fitted += ".";
if (CountCharacters(static_cast<WORD>(g_textCodePage), begin, begin + length) <= 1) {
break;
}
extent = this->VerticalTextHeight(this->m_context->fonts, this->m_context->locale, fitted.c_str(), fitted.size(), family, fontHeight, bold);
length = CharPrevExA(static_cast<WORD>(g_textCodePage), begin, begin + length, 0) - begin;
} while (height < extent);
return fitted;
}
// OFFSET: 0x00A7E120
// FUNCTION: fn_16959
std::list<int> UIWindow::WrapFormattedText(std::string text, std::list<std::string>* lines, int maxWidth, int family, int height, unsigned char bold) {

View file

@ -31,6 +31,7 @@ struct SpriteFrameCell;
class CBitmapRes;
class CActRes;
class TextureCache;
class UITextViewer;
struct WindowReplayRecorder;
struct UIWindowContext {
@ -43,6 +44,9 @@ struct UIWindowContext {
WindowRegistration& registration;
UIWindowMgr& windowMgr;
std::unordered_set<UIWindow*>& deferredDeletion;
UITextViewer* const& chatConverter;
FontCache& fonts;
const TextLocale& locale;
void DestroyDeferredChildren();
};
@ -175,6 +179,8 @@ public:
FontCache& fonts, const TextLocale& locale, const char* text, unsigned bytes, int family, int height, unsigned char bold, unsigned char italic
);
int FormattedTextWidth(std::string text, int family, int height, unsigned char bold);
std::string FitDisplayText(int width, const char* text, int family, int height, unsigned char bold);
std::string FitVerticalDisplayText(int height, const char* text, int family, int fontHeight, unsigned char bold);
std::list<int> WrapFormattedText(std::string text, std::list<std::string>* lines, int maxWidth, int family, int height, unsigned char bold);
int RecordEditTexts(WindowReplayRecorder& recorder);
int RestoreEditTexts(const unsigned char* data);