mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-10 05:21:49 +00:00
feat: non-monospaced fonts support
This commit is contained in:
parent
93dbf34d15
commit
ae54ac9975
8 changed files with 90 additions and 46 deletions
|
|
@ -11,11 +11,11 @@
|
|||
|
||||
using namespace gui;
|
||||
|
||||
void LabelCache::prepare(std::ptrdiff_t fontId, FontMetrics metrics, size_t wrapWidth) {
|
||||
if (fontId != this->fontId) {
|
||||
void LabelCache::prepare(const std::shared_ptr<Font>& font, FontMetrics metrics, size_t wrapWidth) {
|
||||
if (!this->metrics.font.has_value() || font.get() != this->metrics.font.value().lock().get()) {
|
||||
resetFlag = true;
|
||||
this->fontId = fontId;
|
||||
this->metrics = metrics;
|
||||
this->metrics.font = font;
|
||||
}
|
||||
if (wrapWidth != this->wrapWidth) {
|
||||
resetFlag = true;
|
||||
|
|
@ -42,7 +42,8 @@ void LabelCache::update(std::wstring_view text, bool multiline, bool wrap) {
|
|||
lines.clear();
|
||||
lines.push_back(LineScheme {0, false});
|
||||
|
||||
if (fontId == 0) {
|
||||
auto font = metrics.font.has_value() ? metrics.font.value().lock() : nullptr;
|
||||
if (font == nullptr) {
|
||||
wrap = false;
|
||||
}
|
||||
|
||||
|
|
@ -61,26 +62,27 @@ void LabelCache::update(std::wstring_view text, bool multiline, bool wrap) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (fontId != 0) {
|
||||
int maxWidth = 0;
|
||||
for (int i = 0; i < lines.size() - 1; i++) {
|
||||
const auto& next = lines[i + 1];
|
||||
const auto& cur = lines[i];
|
||||
maxWidth = std::max(
|
||||
metrics.calcWidth(
|
||||
text.substr(cur.offset, next.offset - cur.offset)
|
||||
),
|
||||
maxWidth
|
||||
);
|
||||
}
|
||||
if (font == nullptr) {
|
||||
return;
|
||||
}
|
||||
int maxWidth = 0;
|
||||
for (int i = 0; i < lines.size() - 1; i++) {
|
||||
const auto& next = lines[i + 1];
|
||||
const auto& cur = lines[i];
|
||||
maxWidth = std::max(
|
||||
metrics.calcWidth(
|
||||
text.substr(lines[lines.size() - 1].offset)
|
||||
text.substr(cur.offset, next.offset - cur.offset)
|
||||
),
|
||||
maxWidth
|
||||
);
|
||||
multilineWidth = maxWidth;
|
||||
}
|
||||
maxWidth = std::max(
|
||||
metrics.calcWidth(
|
||||
text.substr(lines[lines.size() - 1].offset)
|
||||
),
|
||||
maxWidth
|
||||
);
|
||||
multilineWidth = maxWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +138,7 @@ void Label::setText(std::wstring text) {
|
|||
this->text = std::move(text);
|
||||
cache.update(this->text, multiline, textWrap);
|
||||
|
||||
if (cache.fontId != 0 && autoresize) {
|
||||
if (cache.metrics.font.has_value() && !cache.metrics.font->expired() && autoresize) {
|
||||
setSize(calcSize());
|
||||
}
|
||||
}
|
||||
|
|
@ -203,9 +205,9 @@ uint Label::getLinesNumber() const {
|
|||
|
||||
void Label::draw(const DrawContext& pctx, const Assets& assets) {
|
||||
auto batch = pctx.getBatch2D();
|
||||
auto font = assets.get<Font>(fontName);
|
||||
auto font = assets.getShared<Font>(fontName);
|
||||
cache.prepare(
|
||||
reinterpret_cast<ptrdiff_t>(font),
|
||||
font,
|
||||
font->getMetrics(),
|
||||
static_cast<size_t>(glm::abs(getSize().x))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ namespace gui {
|
|||
};
|
||||
|
||||
struct LabelCache {
|
||||
ptrdiff_t fontId = 0;
|
||||
FontMetrics metrics;
|
||||
|
||||
std::vector<LineScheme> lines;
|
||||
|
|
@ -24,7 +23,7 @@ namespace gui {
|
|||
size_t wrapWidth = -1;
|
||||
int multilineWidth = 0;
|
||||
|
||||
void prepare(std::ptrdiff_t fontId, FontMetrics metrics, size_t wrapWidth);
|
||||
void prepare(const std::shared_ptr<Font>& font, FontMetrics metrics, size_t wrapWidth);
|
||||
void update(std::wstring_view text, bool multiline, bool wrap);
|
||||
|
||||
size_t getTextLineOffset(size_t line) const;
|
||||
|
|
|
|||
|
|
@ -252,10 +252,12 @@ void TextBox::draw(const DrawContext& pctx, const Assets& assets) {
|
|||
|
||||
float time = gui.getWindow().time();
|
||||
|
||||
// drawing caret here
|
||||
if (isFocused() && editable && static_cast<int>((time - caretLastMove) * 2) % 2 == 0) {
|
||||
uint line = label->getLineByTextIndex(caret);
|
||||
auto linestart = label->getTextLineOffset(line);
|
||||
uint lcaret = caret - label->getTextLineOffset(line);
|
||||
int width = rawTextCache.metrics.calcWidth(input, 0, lcaret);
|
||||
int width = rawTextCache.metrics.calcWidth(input.substr(linestart), 0, lcaret);
|
||||
|
||||
batch->rect(
|
||||
lcoord.x + width,
|
||||
|
|
@ -264,6 +266,7 @@ void TextBox::draw(const DrawContext& pctx, const Assets& assets) {
|
|||
lineHeight
|
||||
);
|
||||
}
|
||||
// drawing selection
|
||||
if (selectionStart != selectionEnd) {
|
||||
auto selectionCtx = subctx.sub(batch);
|
||||
selectionCtx.setBlendMode(BlendMode::addition);
|
||||
|
|
@ -349,12 +352,8 @@ void TextBox::draw(const DrawContext& pctx, const Assets& assets) {
|
|||
}
|
||||
|
||||
void TextBox::drawBackground(const DrawContext& pctx, const Assets& assets) {
|
||||
auto font = assets.get<Font>(label->getFontName());
|
||||
rawTextCache.prepare(
|
||||
reinterpret_cast<ptrdiff_t>(font),
|
||||
font->getMetrics(),
|
||||
label->getSize().x
|
||||
);
|
||||
auto font = assets.getShared<Font>(label->getFontName());
|
||||
rawTextCache.prepare(font, font->getMetrics(), label->getSize().x);
|
||||
|
||||
glm::vec2 pos = calcPos();
|
||||
|
||||
|
|
@ -384,8 +383,11 @@ void TextBox::drawBackground(const DrawContext& pctx, const Assets& assets) {
|
|||
}
|
||||
|
||||
void TextBox::refreshLabel() {
|
||||
if (!rawTextCache.metrics.font.has_value()) {
|
||||
return;
|
||||
}
|
||||
rawTextCache.prepare(
|
||||
rawTextCache.fontId,
|
||||
rawTextCache.metrics.font.value().lock(),
|
||||
rawTextCache.metrics,
|
||||
static_cast<size_t>(getSize().x)
|
||||
);
|
||||
|
|
@ -425,7 +427,7 @@ void TextBox::refreshLabel() {
|
|||
lineNumbersLabel->setColor(glm::vec4(1, 1, 1, 0.25f));
|
||||
}
|
||||
|
||||
if (autoresize && rawTextCache.fontId) {
|
||||
if (autoresize) {
|
||||
auto size = getSize();
|
||||
int newy = glm::min(
|
||||
static_cast<int>(parent->getSize().y),
|
||||
|
|
@ -443,7 +445,7 @@ void TextBox::refreshLabel() {
|
|||
}
|
||||
}
|
||||
|
||||
if (multiline && rawTextCache.fontId) {
|
||||
if (multiline) {
|
||||
setScrollable(true);
|
||||
uint height = label->getLinesNumber() * rawTextCache.metrics.lineHeight *
|
||||
label->getLineInterval();
|
||||
|
|
@ -665,7 +667,7 @@ size_t TextBox::normalizeIndex(int index) {
|
|||
/// @param y screen Y position
|
||||
/// @return non-normalized character index
|
||||
int TextBox::calcIndexAt(int x, int y) const {
|
||||
if (rawTextCache.fontId == 0) return 0;
|
||||
if (!rawTextCache.metrics.font.has_value()) return 0;
|
||||
const auto& labelText = label->getText();
|
||||
glm::vec2 lcoord = label->calcPos();
|
||||
uint line = label->getLineByYOffset(y - lcoord.y);
|
||||
|
|
@ -682,7 +684,7 @@ int TextBox::calcIndexAt(int x, int y) const {
|
|||
}
|
||||
|
||||
int TextBox::getLineYOffset(int line) const {
|
||||
if (rawTextCache.fontId == 0) return 0;
|
||||
if (!rawTextCache.metrics.font.has_value()) return 0;
|
||||
return label->getLineYOffset(line);
|
||||
}
|
||||
|
||||
|
|
@ -1205,12 +1207,16 @@ size_t TextBox::getCaret() const {
|
|||
void TextBox::setCaret(size_t position) {
|
||||
const auto& labelText = label->getText();
|
||||
caret = std::min(static_cast<size_t>(position), input.length());
|
||||
if (rawTextCache.fontId == 0) {
|
||||
|
||||
auto font = rawTextCache.metrics.font.has_value()
|
||||
? rawTextCache.metrics.font->lock()
|
||||
: nullptr;
|
||||
if (font == nullptr) {
|
||||
return;
|
||||
}
|
||||
int width = label->getSize().x;
|
||||
|
||||
rawTextCache.prepare(rawTextCache.fontId, rawTextCache.metrics, width);
|
||||
rawTextCache.prepare(font, rawTextCache.metrics, width);
|
||||
rawTextCache.update(input, multiline, label->isTextWrapping());
|
||||
|
||||
caretLastMove = gui.getWindow().time();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue