mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #19178 from hrydgard/text-draw-refactor
Text draw refactor part #1
This commit is contained in:
commit
a04ad1c7f7
12 changed files with 75 additions and 83 deletions
|
@ -141,7 +141,7 @@ void WordWrapper::AppendWord(int endIndex, int lastChar, bool addNewline) {
|
|||
|
||||
// This will include the newline.
|
||||
if (x_ <= maxW_) {
|
||||
out_.append(str_ + lastWordStartIndex, str_ + endIndex);
|
||||
out_.append(str_.data() + lastWordStartIndex, str_.data() + endIndex);
|
||||
} else {
|
||||
scanForNewline_ = true;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void WordWrapper::AppendWord(int endIndex, int lastChar, bool addNewline) {
|
|||
|
||||
if (lastLineStart_ != out_.size()) {
|
||||
// To account for kerning around spaces, we recalculate the entire line width.
|
||||
x_ = MeasureWidth(out_.c_str() + lastLineStart_, out_.size() - lastLineStart_);
|
||||
x_ = MeasureWidth(std::string_view(out_.c_str() + lastLineStart_, out_.size() - lastLineStart_));
|
||||
} else {
|
||||
x_ = 0.0f;
|
||||
}
|
||||
|
@ -178,10 +178,10 @@ void WordWrapper::AppendWord(int endIndex, int lastChar, bool addNewline) {
|
|||
|
||||
void WordWrapper::Wrap() {
|
||||
// First, let's check if it fits as-is.
|
||||
size_t len = strlen(str_);
|
||||
if (MeasureWidth(str_, len) <= maxW_) {
|
||||
size_t len = str_.length();
|
||||
if (MeasureWidth(str_) <= maxW_) {
|
||||
// If it fits, we don't need to go through each character.
|
||||
out_ = str_;
|
||||
out_ = std::string(str_);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ void WordWrapper::Wrap() {
|
|||
out_.reserve(len + len / 16);
|
||||
|
||||
if (flags_ & FLAG_ELLIPSIZE_TEXT) {
|
||||
ellipsisWidth_ = MeasureWidth("...", 3);
|
||||
ellipsisWidth_ = MeasureWidth("...");
|
||||
}
|
||||
|
||||
for (UTF8 utf(str_); !utf.end(); ) {
|
||||
|
@ -219,7 +219,7 @@ void WordWrapper::Wrap() {
|
|||
}
|
||||
|
||||
// Measure the entire word for kerning purposes. May not be 100% perfect.
|
||||
float newWordWidth = MeasureWidth(str_ + lastIndex_, afterIndex - lastIndex_);
|
||||
float newWordWidth = MeasureWidth(str_.substr(lastIndex_, afterIndex - lastIndex_));
|
||||
|
||||
// Is this the end of a word (space)? We'll also output up to a soft hyphen.
|
||||
if (wordWidth_ > 0.0f && IsSpaceOrShy(c)) {
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
class WordWrapper {
|
||||
public:
|
||||
WordWrapper(const char *str, float maxW, int flags)
|
||||
WordWrapper(std::string_view str, float maxW, int flags)
|
||||
: str_(str), maxW_(maxW), flags_(flags) {
|
||||
}
|
||||
virtual ~WordWrapper() {}
|
||||
|
||||
// TODO: This should return a vector of std::string_view for the lines, instead of building up a new string.
|
||||
std::string Wrapped();
|
||||
|
||||
protected:
|
||||
virtual float MeasureWidth(const char *str, size_t bytes) = 0;
|
||||
virtual float MeasureWidth(std::string_view str) = 0;
|
||||
|
||||
void Wrap();
|
||||
bool WrapBeforeWord();
|
||||
void AppendWord(int endIndex, int lastChar, bool addNewline);
|
||||
|
@ -26,7 +29,7 @@ protected:
|
|||
return IsSpace(c) || IsShy(c);
|
||||
}
|
||||
|
||||
const char *const str_;
|
||||
const std::string_view str_;
|
||||
const float maxW_;
|
||||
const int flags_;
|
||||
std::string out_;
|
||||
|
|
|
@ -446,19 +446,20 @@ void DrawBuffer::DrawImage2GridH(ImageID atlas_image, float x1, float y1, float
|
|||
class AtlasWordWrapper : public WordWrapper {
|
||||
public:
|
||||
// Note: maxW may be height if rotated.
|
||||
AtlasWordWrapper(const AtlasFont &atlasfont, float scale, const char *str, float maxW, int flags) : WordWrapper(str, maxW, flags), atlasfont_(atlasfont), scale_(scale) {
|
||||
AtlasWordWrapper(const AtlasFont &atlasfont, float scale, std::string_view str, float maxW, int flags)
|
||||
: WordWrapper(str, maxW, flags), atlasfont_(atlasfont), scale_(scale) {
|
||||
}
|
||||
|
||||
protected:
|
||||
float MeasureWidth(const char *str, size_t bytes) override;
|
||||
float MeasureWidth(std::string_view str) override;
|
||||
|
||||
const AtlasFont &atlasfont_;
|
||||
const float scale_;
|
||||
};
|
||||
|
||||
float AtlasWordWrapper::MeasureWidth(const char *str, size_t bytes) {
|
||||
float AtlasWordWrapper::MeasureWidth(std::string_view str) {
|
||||
float w = 0.0f;
|
||||
for (UTF8 utf(str); utf.byteIndex() < (int)bytes; ) {
|
||||
for (UTF8 utf(str); !utf.end(); ) {
|
||||
uint32_t c = utf.next();
|
||||
if (c == '&') {
|
||||
// Skip ampersand prefixes ("&&" is an ampersand.)
|
||||
|
@ -473,7 +474,7 @@ float AtlasWordWrapper::MeasureWidth(const char *str, size_t bytes) {
|
|||
return w;
|
||||
}
|
||||
|
||||
void DrawBuffer::MeasureTextCount(FontID font, const char *text, int count, float *w, float *h) {
|
||||
void DrawBuffer::MeasureText(FontID font, std::string_view text, float *w, float *h) {
|
||||
const AtlasFont *atlasfont = fontAtlas_->getFont(font);
|
||||
if (!atlasfont)
|
||||
atlasfont = atlas->getFont(font);
|
||||
|
@ -491,7 +492,7 @@ void DrawBuffer::MeasureTextCount(FontID font, const char *text, int count, floa
|
|||
while (true) {
|
||||
if (utf.end())
|
||||
break;
|
||||
if (utf.byteIndex() >= count)
|
||||
if (utf.byteIndex() >= text.length())
|
||||
break;
|
||||
cval = utf.next();
|
||||
// Translate non-breaking space to space.
|
||||
|
@ -517,14 +518,14 @@ void DrawBuffer::MeasureTextCount(FontID font, const char *text, int count, floa
|
|||
if (h) *h = atlasfont->height * fontscaley * lines;
|
||||
}
|
||||
|
||||
void DrawBuffer::MeasureTextRect(FontID font_id, const char *text, int count, const Bounds &bounds, float *w, float *h, int align) {
|
||||
if (!text || font_id.isInvalid()) {
|
||||
void DrawBuffer::MeasureTextRect(FontID font_id, std::string_view text, const Bounds &bounds, float *w, float *h, int align) {
|
||||
if (text.empty() || font_id.isInvalid()) {
|
||||
*w = 0.0f;
|
||||
*h = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string toMeasure = std::string(text, count);
|
||||
std::string toMeasure = std::string(text);
|
||||
int wrap = align & (FLAG_WRAP_TEXT | FLAG_ELLIPSIZE_TEXT);
|
||||
if (wrap) {
|
||||
const AtlasFont *font = fontAtlas_->getFont(font_id);
|
||||
|
@ -535,17 +536,13 @@ void DrawBuffer::MeasureTextRect(FontID font_id, const char *text, int count, co
|
|||
*h = 0.0f;
|
||||
return;
|
||||
}
|
||||
AtlasWordWrapper wrapper(*font, fontscalex, toMeasure.c_str(), bounds.w, wrap);
|
||||
AtlasWordWrapper wrapper(*font, fontscalex, toMeasure, bounds.w, wrap);
|
||||
toMeasure = wrapper.Wrapped();
|
||||
}
|
||||
MeasureTextCount(font_id, toMeasure.c_str(), (int)toMeasure.length(), w, h);
|
||||
MeasureText(font_id, toMeasure, w, h);
|
||||
}
|
||||
|
||||
void DrawBuffer::MeasureText(FontID font, const char *text, float *w, float *h) {
|
||||
return MeasureTextCount(font, text, (int)strlen(text), w, h);
|
||||
}
|
||||
|
||||
void DrawBuffer::DrawTextShadow(FontID font, const char *text, float x, float y, Color color, int flags) {
|
||||
void DrawBuffer::DrawTextShadow(FontID font, std::string_view text, float x, float y, Color color, int flags) {
|
||||
uint32_t alpha = (color >> 1) & 0xFF000000;
|
||||
DrawText(font, text, x + 2, y + 2, alpha, flags);
|
||||
DrawText(font, text, x, y, color, flags);
|
||||
|
@ -562,9 +559,8 @@ void DrawBuffer::DoAlign(int flags, float *x, float *y, float *w, float *h) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Actually use the rect properly, take bounds.
|
||||
void DrawBuffer::DrawTextRect(FontID font, const char *text, float x, float y, float w, float h, Color color, int align) {
|
||||
void DrawBuffer::DrawTextRect(FontID font, std::string_view text, float x, float y, float w, float h, Color color, int align) {
|
||||
if (align & ALIGN_HCENTER) {
|
||||
x += w / 2;
|
||||
} else if (align & ALIGN_RIGHT) {
|
||||
|
@ -576,18 +572,18 @@ void DrawBuffer::DrawTextRect(FontID font, const char *text, float x, float y, f
|
|||
y += h;
|
||||
}
|
||||
|
||||
std::string toDraw = text;
|
||||
std::string toDraw(text);
|
||||
int wrap = align & (FLAG_WRAP_TEXT | FLAG_ELLIPSIZE_TEXT);
|
||||
const AtlasFont *atlasfont = fontAtlas_->getFont(font);
|
||||
if (!atlasfont)
|
||||
atlasfont = atlas->getFont(font);
|
||||
if (wrap && atlasfont) {
|
||||
AtlasWordWrapper wrapper(*atlasfont, fontscalex, toDraw.c_str(), w, wrap);
|
||||
AtlasWordWrapper wrapper(*atlasfont, fontscalex, toDraw, w, wrap);
|
||||
toDraw = wrapper.Wrapped();
|
||||
}
|
||||
|
||||
float totalWidth, totalHeight;
|
||||
MeasureTextRect(font, toDraw.c_str(), (int)toDraw.size(), Bounds(x, y, w, h), &totalWidth, &totalHeight, align);
|
||||
MeasureTextRect(font, toDraw, Bounds(x, y, w, h), &totalWidth, &totalHeight, align);
|
||||
|
||||
std::vector<std::string> lines;
|
||||
SplitString(toDraw, '\n', lines);
|
||||
|
@ -606,21 +602,22 @@ void DrawBuffer::DrawTextRect(FontID font, const char *text, float x, float y, f
|
|||
DrawText(font, line.c_str(), x, baseY, color, align);
|
||||
|
||||
float tw, th;
|
||||
MeasureText(font, line.c_str(), &tw, &th);
|
||||
MeasureText(font, line, &tw, &th);
|
||||
baseY += th;
|
||||
}
|
||||
}
|
||||
|
||||
// ROTATE_* doesn't yet work right.
|
||||
void DrawBuffer::DrawText(FontID font, const char *text, float x, float y, Color color, int align) {
|
||||
void DrawBuffer::DrawText(FontID font, std::string_view text, float x, float y, Color color, int align) {
|
||||
// rough estimate
|
||||
size_t textLen = strlen(text);
|
||||
int textLen = (int)text.length();
|
||||
if (count_ + textLen * 6 > MAX_VERTS) {
|
||||
Flush(true);
|
||||
if (textLen * 6 >= MAX_VERTS) {
|
||||
textLen = std::min(MAX_VERTS / 6 - 10, (int)textLen);
|
||||
}
|
||||
}
|
||||
text = text.substr(0, textLen);
|
||||
|
||||
const AtlasFont *atlasfont = fontAtlas_->getFont(font);
|
||||
if (!atlasfont)
|
||||
|
|
|
@ -131,15 +131,13 @@ public:
|
|||
// This is only 6 triangles, much cheaper.
|
||||
void DrawImage2GridH(ImageID atlas_image, float x1, float y1, float x2, Color color = COLOR(0xFFFFFF), float scale = 1.0);
|
||||
|
||||
void MeasureText(FontID font, const char *text, float *w, float *h);
|
||||
void MeasureText(FontID font, std::string_view text, float *w, float *h);
|
||||
|
||||
// NOTE: Count is in plain chars not utf-8 chars!
|
||||
void MeasureTextCount(FontID font, const char *text, int count, float *w, float *h);
|
||||
void MeasureTextRect(FontID font, const char *text, int count, const Bounds &bounds, float *w, float *h, int align = 0);
|
||||
void MeasureTextRect(FontID font, std::string_view text, const Bounds &bounds, float *w, float *h, int align = 0);
|
||||
|
||||
void DrawTextRect(FontID font, const char *text, float x, float y, float w, float h, Color color = 0xFFFFFFFF, int align = 0);
|
||||
void DrawText(FontID font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0);
|
||||
void DrawTextShadow(FontID font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0);
|
||||
void DrawTextRect(FontID font, std::string_view text, float x, float y, float w, float h, Color color = 0xFFFFFFFF, int align = 0);
|
||||
void DrawText(FontID font, std::string_view text, float x, float y, Color color = 0xFFFFFFFF, int align = 0);
|
||||
void DrawTextShadow(FontID font, std::string_view text, float x, float y, Color color = 0xFFFFFFFF, int align = 0);
|
||||
|
||||
void SetFontScale(float xs, float ys) {
|
||||
fontscalex = xs;
|
||||
|
|
|
@ -20,13 +20,13 @@ TextDrawer::TextDrawer(Draw::DrawContext *draw) : draw_(draw) {
|
|||
TextDrawer::~TextDrawer() {
|
||||
}
|
||||
|
||||
float TextDrawerWordWrapper::MeasureWidth(const char *str, size_t bytes) {
|
||||
float TextDrawerWordWrapper::MeasureWidth(std::string_view str) {
|
||||
float w, h;
|
||||
drawer_->MeasureString(str, bytes, &w, &h);
|
||||
drawer_->MeasureString(str.data(), str.length(), &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
void TextDrawer::WrapString(std::string &out, const char *str, float maxW, int flags) {
|
||||
void TextDrawer::WrapString(std::string &out, std::string_view str, float maxW, int flags) {
|
||||
TextDrawerWordWrapper wrapper(this, str, maxW, flags);
|
||||
out = wrapper.Wrapped();
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ protected:
|
|||
|
||||
Draw::DrawContext *draw_;
|
||||
virtual void ClearCache() = 0;
|
||||
void WrapString(std::string &out, const char *str, float maxWidth, int flags);
|
||||
void WrapString(std::string &out, std::string_view str, float maxWidth, int flags);
|
||||
|
||||
struct CacheKey {
|
||||
bool operator < (const CacheKey &other) const {
|
||||
|
@ -90,11 +90,11 @@ protected:
|
|||
|
||||
class TextDrawerWordWrapper : public WordWrapper {
|
||||
public:
|
||||
TextDrawerWordWrapper(TextDrawer *drawer, const char *str, float maxW, int flags)
|
||||
TextDrawerWordWrapper(TextDrawer *drawer, std::string_view str, float maxW, int flags)
|
||||
: WordWrapper(str, maxW, flags), drawer_(drawer) {}
|
||||
|
||||
protected:
|
||||
float MeasureWidth(const char *str, size_t bytes) override;
|
||||
float MeasureWidth(std::string_view str) override;
|
||||
|
||||
TextDrawer *drawer_;
|
||||
};
|
||||
|
|
|
@ -206,35 +206,30 @@ void UIContext::SetFontStyle(const UI::FontStyle &fontStyle) {
|
|||
}
|
||||
}
|
||||
|
||||
void UIContext::MeasureText(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, float *x, float *y, int align) const {
|
||||
_dbg_assert_(str != nullptr);
|
||||
MeasureTextCount(style, scaleX, scaleY, str, (int)strlen(str), x, y, align);
|
||||
}
|
||||
|
||||
void UIContext::MeasureTextCount(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, float *x, float *y, int align) const {
|
||||
_dbg_assert_(str != nullptr);
|
||||
void UIContext::MeasureText(const UI::FontStyle &style, float scaleX, float scaleY, std::string_view str, float *x, float *y, int align) const {
|
||||
_dbg_assert_(str.data() != nullptr);
|
||||
if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) {
|
||||
float sizeFactor = (float)style.sizePts / 24.0f;
|
||||
Draw()->SetFontScale(scaleX * sizeFactor, scaleY * sizeFactor);
|
||||
Draw()->MeasureTextCount(style.atlasFont, str, count, x, y);
|
||||
Draw()->MeasureText(style.atlasFont, str, x, y);
|
||||
} else {
|
||||
textDrawer_->SetFont(style.fontName.c_str(), style.sizePts, style.flags);
|
||||
textDrawer_->SetFontScale(scaleX, scaleY);
|
||||
textDrawer_->MeasureString(str, count, x, y);
|
||||
textDrawer_->MeasureString(str.data(), str.length(), x, y);
|
||||
textDrawer_->SetFont(fontStyle_->fontName.c_str(), fontStyle_->sizePts, fontStyle_->flags);
|
||||
}
|
||||
}
|
||||
|
||||
void UIContext::MeasureTextRect(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, const Bounds &bounds, float *x, float *y, int align) const {
|
||||
_dbg_assert_(str != nullptr);
|
||||
void UIContext::MeasureTextRect(const UI::FontStyle &style, float scaleX, float scaleY, std::string_view str, const Bounds &bounds, float *x, float *y, int align) const {
|
||||
_dbg_assert_(str.data() != nullptr);
|
||||
if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) {
|
||||
float sizeFactor = (float)style.sizePts / 24.0f;
|
||||
Draw()->SetFontScale(scaleX * sizeFactor, scaleY * sizeFactor);
|
||||
Draw()->MeasureTextRect(style.atlasFont, str, count, bounds, x, y, align);
|
||||
Draw()->MeasureTextRect(style.atlasFont, str, bounds, x, y, align);
|
||||
} else {
|
||||
textDrawer_->SetFont(style.fontName.c_str(), style.sizePts, style.flags);
|
||||
textDrawer_->SetFontScale(scaleX, scaleY);
|
||||
textDrawer_->MeasureStringRect(str, count, bounds, x, y, align);
|
||||
textDrawer_->MeasureStringRect(str.data(), str.length(), bounds, x, y, align);
|
||||
textDrawer_->SetFont(fontStyle_->fontName.c_str(), fontStyle_->sizePts, fontStyle_->flags);
|
||||
}
|
||||
}
|
||||
|
@ -291,10 +286,10 @@ void UIContext::DrawTextRect(const char *str, const Bounds &bounds, uint32_t col
|
|||
|
||||
static constexpr float MIN_TEXT_SCALE = 0.7f;
|
||||
|
||||
float UIContext::CalculateTextScale(const char *text, float availWidth, float availHeight) const {
|
||||
float UIContext::CalculateTextScale(std::string_view str, float availWidth, float availHeight) const {
|
||||
float actualWidth, actualHeight;
|
||||
Bounds availBounds(0, 0, availWidth, availHeight);
|
||||
MeasureTextRect(theme->uiFont, 1.0f, 1.0f, text, (int)strlen(text), availBounds, &actualWidth, &actualHeight, ALIGN_VCENTER);
|
||||
MeasureTextRect(theme->uiFont, 1.0f, 1.0f, str, availBounds, &actualWidth, &actualHeight, ALIGN_VCENTER);
|
||||
if (actualWidth > availWidth) {
|
||||
return std::max(MIN_TEXT_SCALE, availWidth / actualWidth);
|
||||
}
|
||||
|
|
|
@ -82,9 +82,8 @@ public:
|
|||
void SetFontStyle(const UI::FontStyle &style);
|
||||
const UI::FontStyle &GetFontStyle() { return *fontStyle_; }
|
||||
void SetFontScale(float scaleX, float scaleY);
|
||||
void MeasureTextCount(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, float *x, float *y, int align = 0) const;
|
||||
void MeasureText(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, float *x, float *y, int align = 0) const;
|
||||
void MeasureTextRect(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, const Bounds &bounds, float *x, float *y, int align = 0) const;
|
||||
void MeasureText(const UI::FontStyle &style, float scaleX, float scaleY, std::string_view str, float *x, float *y, int align = 0) const;
|
||||
void MeasureTextRect(const UI::FontStyle &style, float scaleX, float scaleY, std::string_view str, const Bounds &bounds, float *x, float *y, int align = 0) const;
|
||||
void DrawText(const char *str, float x, float y, uint32_t color, int align = 0);
|
||||
void DrawTextShadow(const char *str, float x, float y, uint32_t color, int align = 0);
|
||||
void DrawTextRect(const char *str, const Bounds &bounds, uint32_t color, int align = 0);
|
||||
|
@ -92,7 +91,7 @@ public:
|
|||
// Will squeeze the text into the bounds if needed.
|
||||
void DrawTextRectSqueeze(const char *str, const Bounds &bounds, uint32_t color, int align = 0);
|
||||
|
||||
float CalculateTextScale(const char *text, float availWidth, float availHeight) const;
|
||||
float CalculateTextScale(std::string_view str, float availWidth, float availHeight) const;
|
||||
|
||||
void FillRect(const UI::Drawable &drawable, const Bounds &bounds);
|
||||
void DrawRectDropShadow(const Bounds &bounds, float radius, float alpha, uint32_t color = 0);
|
||||
|
|
|
@ -596,7 +596,7 @@ void AbstractChoiceWithValueDisplay::GetContentDimensionsBySpec(const UIContext
|
|||
Bounds availBounds(0, 0, availWidth, vert.size);
|
||||
|
||||
float valueW, valueH;
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, valueText.c_str(), (int)valueText.size(), availBounds, &valueW, &valueH, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, valueText, availBounds, &valueW, &valueH, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT);
|
||||
valueW += paddingX;
|
||||
|
||||
// Give the choice itself less space to grow in, so it shrinks if needed.
|
||||
|
@ -641,7 +641,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) {
|
|||
|
||||
float w, h;
|
||||
Bounds availBounds(0, 0, availWidth, bounds_.h);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, valueText.c_str(), (int)valueText.size(), availBounds, &w, &h, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, valueText, availBounds, &w, &h, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT);
|
||||
textPadding_.right = w + paddingX;
|
||||
|
||||
Choice::Draw(dc);
|
||||
|
@ -662,10 +662,10 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) {
|
|||
}
|
||||
}
|
||||
|
||||
float AbstractChoiceWithValueDisplay::CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const {
|
||||
float AbstractChoiceWithValueDisplay::CalculateValueScale(const UIContext &dc, std::string_view valueText, float availWidth) const {
|
||||
float actualWidth, actualHeight;
|
||||
Bounds availBounds(0, 0, availWidth, bounds_.h);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, 1.0f, 1.0f, valueText.c_str(), (int)valueText.size(), availBounds, &actualWidth, &actualHeight);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, 1.0f, 1.0f, valueText, availBounds, &actualWidth, &actualHeight);
|
||||
if (actualWidth > availWidth) {
|
||||
return std::max(0.8f, availWidth / actualWidth);
|
||||
}
|
||||
|
|
|
@ -483,10 +483,10 @@ void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz,
|
|||
}
|
||||
if (horiz.type != EXACTLY && layoutParams_->width > 0.0f && availWidth > layoutParams_->width)
|
||||
availWidth = layoutParams_->width;
|
||||
float scale = dc.CalculateTextScale(text_.c_str(), availWidth, bounds_.h);
|
||||
float scale = dc.CalculateTextScale(text_, availWidth, bounds_.h);
|
||||
Bounds availBounds(0, 0, availWidth, vert.size);
|
||||
float textW = 0.0f, textH = 0.0f;
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, text_.c_str(), (int)text_.size(), availBounds, &textW, &textH, FLAG_WRAP_TEXT);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, text_, availBounds, &textW, &textH, FLAG_WRAP_TEXT);
|
||||
totalH = std::max(totalH, textH);
|
||||
totalW += textW;
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ void InfoItem::Draw(UIContext &dc) {
|
|||
Bounds padBounds = bounds_.Expand(-paddingX, 0);
|
||||
|
||||
float leftWidth, leftHeight;
|
||||
dc.MeasureTextRect(dc.theme->uiFont, 1.0f, 1.0f, text_.c_str(), (int)text_.size(), padBounds, &leftWidth, &leftHeight, ALIGN_VCENTER);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, 1.0f, 1.0f, text_, padBounds, &leftWidth, &leftHeight, ALIGN_VCENTER);
|
||||
|
||||
dc.SetFontStyle(dc.theme->uiFont);
|
||||
dc.DrawTextRect(text_.c_str(), padBounds, style.fgColor, ALIGN_VCENTER);
|
||||
|
@ -616,7 +616,7 @@ void ItemHeader::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec hor
|
|||
bounds.h = vert.size == 0 ? MAX_ITEM_SIZE : vert.size;
|
||||
}
|
||||
ApplyBoundsBySpec(bounds, horiz, vert);
|
||||
dc.MeasureTextRect(dc.theme->uiFontSmall, 1.0f, 1.0f, text_.c_str(), (int)text_.length(), bounds, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
dc.MeasureTextRect(dc.theme->uiFontSmall, 1.0f, 1.0f, text_, bounds, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
}
|
||||
|
||||
std::string ItemHeader::DescribeText() const {
|
||||
|
@ -658,7 +658,7 @@ void CollapsibleHeader::GetContentDimensionsBySpec(const UIContext &dc, MeasureS
|
|||
bounds.h = vert.size == 0 ? MAX_ITEM_SIZE : vert.size;
|
||||
}
|
||||
ApplyBoundsBySpec(bounds, horiz, vert);
|
||||
dc.MeasureTextRect(dc.theme->uiFontSmall, 1.0f, 1.0f, text_.c_str(), (int)text_.length(), bounds, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
dc.MeasureTextRect(dc.theme->uiFontSmall, 1.0f, 1.0f, text_, bounds, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
}
|
||||
|
||||
void CollapsibleHeader::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
|
||||
|
@ -840,11 +840,11 @@ void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) con
|
|||
}
|
||||
|
||||
if (!text_.empty()) {
|
||||
float scale = dc.CalculateTextScale(text_.c_str(), availWidth, bounds_.h);
|
||||
float scale = dc.CalculateTextScale(text_, availWidth, bounds_.h);
|
||||
|
||||
float actualWidth, actualHeight;
|
||||
Bounds availBounds(0, 0, availWidth, bounds_.h);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, text_.c_str(), (int)text_.size(), availBounds, &actualWidth, &actualHeight, ALIGN_VCENTER | FLAG_WRAP_TEXT);
|
||||
dc.MeasureTextRect(dc.theme->uiFont, scale, scale, text_, availBounds, &actualWidth, &actualHeight, ALIGN_VCENTER | FLAG_WRAP_TEXT);
|
||||
h = std::max(actualHeight, ITEM_HEIGHT);
|
||||
} else {
|
||||
h = std::max(imageH, ITEM_HEIGHT);
|
||||
|
@ -1043,7 +1043,7 @@ void TextView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz
|
|||
if (bullet_) {
|
||||
bounds.w -= bulletOffset;
|
||||
}
|
||||
dc.MeasureTextRect(small_ ? dc.theme->uiFontSmall : dc.theme->uiFont, 1.0f, 1.0f, text_.c_str(), (int)text_.length(), bounds, &w, &h, textAlign_);
|
||||
dc.MeasureTextRect(small_ ? dc.theme->uiFontSmall : dc.theme->uiFont, 1.0f, 1.0f, text_, bounds, &w, &h, textAlign_);
|
||||
w += pad_ * 2.0f;
|
||||
h += pad_ * 2.0f;
|
||||
if (bullet_) {
|
||||
|
@ -1141,7 +1141,7 @@ void TextEdit::Draw(UIContext &dc) {
|
|||
|
||||
if (HasFocus()) {
|
||||
// Hack to find the caret position. Might want to find a better way...
|
||||
dc.MeasureTextCount(dc.theme->uiFont, 1.0f, 1.0f, text_.c_str(), caret_, &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_);
|
||||
dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.substr(0, caret_), &w, &h, ALIGN_VCENTER | ALIGN_LEFT | align_);
|
||||
float caretX = w - scrollPos_;
|
||||
if (caretX > bounds_.w) {
|
||||
scrollPos_ += caretX - bounds_.w;
|
||||
|
|
|
@ -826,7 +826,7 @@ public:
|
|||
protected:
|
||||
virtual std::string ValueText() const = 0;
|
||||
|
||||
float CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const;
|
||||
float CalculateValueScale(const UIContext &dc, std::string_view valueText, float availWidth) const;
|
||||
|
||||
bool passwordDisplay_ = false;
|
||||
};
|
||||
|
|
|
@ -788,15 +788,15 @@ static bool TestAndroidContentURI() {
|
|||
|
||||
class UnitTestWordWrapper : public WordWrapper {
|
||||
public:
|
||||
UnitTestWordWrapper(const char *str, float maxW, int flags)
|
||||
UnitTestWordWrapper(std::string_view str, float maxW, int flags)
|
||||
: WordWrapper(str, maxW, flags) {
|
||||
}
|
||||
|
||||
protected:
|
||||
float MeasureWidth(const char *str, size_t bytes) override {
|
||||
float MeasureWidth(std::string_view str) override {
|
||||
// Simple case for unit testing.
|
||||
int w = 0;
|
||||
for (UTF8 utf(str); !utf.end() && (size_t)utf.byteIndex() < bytes; ) {
|
||||
for (UTF8 utf(str); !utf.end(); ) {
|
||||
uint32_t c = utf.next();
|
||||
switch (c) {
|
||||
case ' ':
|
||||
|
|
Loading…
Add table
Reference in a new issue