Use FontData everywhere

This commit is contained in:
Yousef Khadadeh 2025-11-16 10:42:01 +03:00
parent 4fe52ef7f6
commit a99b0e920d
14 changed files with 51 additions and 46 deletions

View file

@ -61,7 +61,7 @@ void DrawTextBox::update_from_delayed_ptr(const std::shared_ptr<DrawComponent>&
}
void DrawTextBox::init_text_box(DrawingProgram& drawP) {
textBox->set_font_collection(drawP.world.main.fonts.collection); // Getting a segfault relating to the paragraph cache means that the font collection hasn't been set yet
textBox->set_font_data(drawP.world.main.fonts); // Getting a segfault relating to the paragraph cache means that the font collection hasn't been set yet
textBox->set_width(d.p2.x() - d.p1.x() - TEXTBOX_PADDING * 2.0f);
}

View file

@ -17,8 +17,6 @@
#include <src/base/SkUTF.h>
bool fallbackOnEmoji = false;
FontData::FontData()
{
#ifdef __EMSCRIPTEN__
@ -48,17 +46,7 @@ FontData::FontData()
fallbackOnEmoji = !defaultEmojiFallback;
}
FontData::~FontData() {
}
Vector2f get_str_font_bounds(const SkFont& font, const std::string& str) {
SkFontMetrics metrics;
font.getMetrics(&metrics);
float nextText = font.measureText(str.data(), str.length(), SkTextEncoding::kUTF8, nullptr);
return Vector2f{nextText, - metrics.fAscent + metrics.fDescent};
}
const std::vector<SkString>& get_default_font_families() {
const std::vector<SkString>& FontData::get_default_font_families() const {
static std::vector<SkString> defaultFontFamilies;
if(defaultFontFamilies.empty()) {
defaultFontFamilies.emplace_back("Roboto");
@ -69,9 +57,19 @@ const std::vector<SkString>& get_default_font_families() {
return defaultFontFamilies;
}
void push_default_font_families(std::vector<SkString>& fontFamilies) {
void FontData::push_default_font_families(std::vector<SkString>& fontFamilies) const {
fontFamilies.emplace_back("Roboto");
if(fallbackOnEmoji)
fontFamilies.emplace_back("Noto Emoji");
fontFamilies.emplace_back("Noto Kufi Arabic");
}
FontData::~FontData() {
}
Vector2f get_str_font_bounds(const SkFont& font, const std::string& str) {
SkFontMetrics metrics;
font.getMetrics(&metrics);
float nextText = font.measureText(str.data(), str.length(), SkTextEncoding::kUTF8, nullptr);
return Vector2f{nextText, - metrics.fAscent + metrics.fDescent};
}

View file

@ -14,9 +14,10 @@ struct FontData {
sk_sp<SkFontMgr> localFontMgr;
sk_sp<skia::textlayout::FontCollection> collection;
std::unordered_map<std::string, sk_sp<SkTypeface>> map;
bool fallbackOnEmoji = false;
const std::vector<SkString>& get_default_font_families() const;
void push_default_font_families(std::vector<SkString>& fontFamilies) const;
~FontData();
};
Vector2f get_str_font_bounds(const SkFont& font, const std::string& str);
const std::vector<SkString>& get_default_font_families();
void push_default_font_families(std::vector<SkString>& fontFamilies);

View file

@ -6,6 +6,7 @@
#include <include/core/SkFont.h>
#include <include/core/SkFontMgr.h>
#include <include/core/SkTypeface.h>
#include "../../FontData.hpp"
#include <modules/skparagraph/include/FontCollection.h>
#include <modules/svg/include/SkSVGDOM.h>
#include <Helpers/SCollision.hpp>
@ -110,15 +111,12 @@ struct UpdateInputData {
uint16_t fontSize = 16;
sk_sp<skia::textlayout::FontCollection> fontCollection;
std::string textInput;
bool hoverObstructed = false;
bool acceptingTextInput = false;
float deltaTime = 0.0f;
sk_sp<SkFontMgr> textFontMgrLocal;
sk_sp<SkFontMgr> textFontMgrFallback;
std::shared_ptr<FontData> fonts;
sk_sp<SkTypeface> textTypeface;
DefaultStringArena* strArena;

View file

@ -12,17 +12,17 @@ bool GUIStuff::FontPicker::update(UpdateInputData& io, std::string* fontName, GU
auto icu = SkUnicodes::ICU::Make();
std::set<std::string> sortedFontSet;
for(int i = 0; i < io.textFontMgrLocal->countFamilies(); i++) {
for(int i = 0; i < io.fonts->localFontMgr->countFamilies(); i++) {
SkString familyNameSkString;
io.textFontMgrLocal->getFamilyName(i, &familyNameSkString);
io.fonts->localFontMgr->getFamilyName(i, &familyNameSkString);
if(familyNameSkString.isEmpty())
continue;
std::string familyName(familyNameSkString.c_str(), familyNameSkString.size());
sortedFontSet.emplace(familyName);
}
for(int i = 0; i < io.textFontMgrFallback->countFamilies(); i++) {
for(int i = 0; i < io.fonts->defaultFontMgr->countFamilies(); i++) {
SkString familyNameSkString;
io.textFontMgrFallback->getFamilyName(i, &familyNameSkString);
io.fonts->defaultFontMgr->getFamilyName(i, &familyNameSkString);
if(familyNameSkString.isEmpty())
continue;
std::string familyName(familyNameSkString.c_str(), familyNameSkString.size());
@ -115,7 +115,7 @@ bool GUIStuff::FontPicker::update(UpdateInputData& io, std::string* fontName, GU
tStyle.setForegroundColor(SkPaint{io.theme->frontColor1});
pStyle.setTextStyle(tStyle);
skia::textlayout::ParagraphBuilderImpl pBuilder(pStyle, io.fontCollection, SkUnicodes::ICU::Make());
skia::textlayout::ParagraphBuilderImpl pBuilder(pStyle, io.fonts->collection, SkUnicodes::ICU::Make());
tStyle.setFontStyle(SkFontStyle::Normal());
pBuilder.pushStyle(tStyle);

View file

@ -86,7 +86,7 @@ template <typename T> class TextBox : public Element {
paintOpts.cursorColor = {io.theme->fillColor1.fR, io.theme->fillColor1.fG, io.theme->fillColor1.fB};
skia::textlayout::TextStyle tStyle;
tStyle.setFontFamilies(get_default_font_families());
tStyle.setFontFamilies(io.fonts->get_default_font_families());
tStyle.setFontSize(io.fontSize);
tStyle.setForegroundPaint(SkPaint{io.theme->frontColor1});
textbox->set_initial_text_style(tStyle);
@ -103,7 +103,7 @@ template <typename T> class TextBox : public Element {
return;
textbox = std::make_shared<RichText::TextBox>();
textbox->set_font_collection(io.fontCollection);
textbox->set_font_data(io.fonts);
textbox->set_allow_newlines(false);
cur = std::make_shared<RichText::TextBox::Cursor>();

View file

@ -44,10 +44,10 @@ Clay_Dimensions GUIManager::clay_skia_measure_text(Clay_StringSlice str, Clay_Te
pStyle.setTextAlign(skia::textlayout::TextAlign::kLeft);
skia::textlayout::TextStyle tStyle;
tStyle.setFontSize(config->fontSize);
tStyle.setFontFamilies(get_default_font_families());
tStyle.setFontFamilies(window->io->fonts->get_default_font_families());
pStyle.setTextStyle(tStyle);
skia::textlayout::ParagraphBuilderImpl a(pStyle, window->io->fontCollection, SkUnicodes::ICU::Make());
skia::textlayout::ParagraphBuilderImpl a(pStyle, window->io->fonts->collection, SkUnicodes::ICU::Make());
a.addText(str.chars, str.length);
std::unique_ptr<skia::textlayout::Paragraph> p = a.Build();
p->layout(std::numeric_limits<float>::max());
@ -117,11 +117,11 @@ void GUIManager::draw(SkCanvas* canvas) {
pStyle.setTextAlign(skia::textlayout::TextAlign::kLeft);
skia::textlayout::TextStyle tStyle;
tStyle.setFontSize(config->fontSize);
tStyle.setFontFamilies(get_default_font_families());
tStyle.setFontFamilies(io->fonts->get_default_font_families());
tStyle.setColor(convert_vec4<SkColor4f>(config->textColor).toSkColor());
pStyle.setTextStyle(tStyle);
skia::textlayout::ParagraphBuilderImpl a(pStyle, io->fontCollection, SkUnicodes::ICU::Make());
skia::textlayout::ParagraphBuilderImpl a(pStyle, io->fonts->collection, SkUnicodes::ICU::Make());
a.addText(config->stringContents.chars, config->stringContents.length);
std::unique_ptr<skia::textlayout::Paragraph> p = a.Build();
p->layout(std::numeric_limits<float>::max());

View file

@ -37,6 +37,7 @@
#include <Helpers/Networking/NetLibrary.hpp>
MainProgram::MainProgram():
fonts(std::make_shared<FontData>()),
toolbar(*this)
{
displayName = Random::get().alphanumeric_str(10);

View file

@ -63,7 +63,7 @@ class MainProgram {
WorldScalar inverseScale;
} clipboard;
FontData fonts;
std::shared_ptr<FontData> fonts;
TimePoint deltaTime;
Toolbar toolbar;
std::shared_ptr<World> world;

View file

@ -794,9 +794,9 @@ void TextBox::set_allow_newlines(bool allow) {
newlinesAllowed = allow;
}
void TextBox::set_font_collection(const sk_sp<skia::textlayout::FontCollection>& fC) {
if(fontCollection != fC) {
fontCollection = fC;
void TextBox::set_font_data(const std::shared_ptr<FontData>& fD) {
if(fontData != fD) {
fontData = fD;
inputChangedTextBox = true;
needsRebuild = true;
}
@ -810,6 +810,8 @@ void TextBox::rebuild() {
skia::textlayout::TextStyle tStyle = initialTStyle;
FontFamiliesTextStyleModifier::globalFontData = fontData;
for(size_t pIndex = 0; pIndex < paragraphs.size(); pIndex++) {
ParagraphData& pData = paragraphs[pIndex];
skia::textlayout::ParagraphStyle pStyle = pData.pStyleData.get_paragraph_style();
@ -825,7 +827,7 @@ void TextBox::rebuild() {
}
size_t tIndex = 0;
skia::textlayout::ParagraphBuilderImpl a(pStyle, fontCollection, SkUnicodes::ICU::Make());
skia::textlayout::ParagraphBuilderImpl a(pStyle, fontData->collection, SkUnicodes::ICU::Make());
for(;;) {
if(nextTStyleModIt == tStyleMods.end() || nextTStyleModIt->pos.fParagraphIndex != pIndex) {

View file

@ -96,7 +96,7 @@ class TextBox {
void set_width(float newWidth);
TextPosition insert(TextPosition pos, std::string_view textToInsert, const std::optional<TextStyleModifier::ModifierMap>& inputModMap = std::nullopt);
TextPosition remove(TextPosition p1, TextPosition p2);
void set_font_collection(const sk_sp<skia::textlayout::FontCollection>& fC);
void set_font_data(const std::shared_ptr<FontData>& fD);
void paint(SkCanvas* canvas, const PaintOpts& paintOpts);
void set_allow_newlines(bool allow);
float get_height();
@ -174,7 +174,7 @@ class TextBox {
float width = 0.0f;
bool needsRebuild = true;
unsigned tabWidth = 8;
sk_sp<skia::textlayout::FontCollection> fontCollection;
std::shared_ptr<FontData> fontData;
struct ParagraphData {
std::string text;

View file

@ -170,6 +170,7 @@ bool SizeTextStyleModifier::equivalent_data(TextStyleModifier& modifier) const {
}
std::shared_ptr<FontData> FontFamiliesTextStyleModifier::globalFontData = nullptr;
FontFamiliesTextStyleModifier::FontFamiliesTextStyleModifier(const std::vector<SkString>& initFamilies): families(initFamilies) {}
@ -190,8 +191,11 @@ void FontFamiliesTextStyleModifier::load(cereal::PortableBinaryInputArchive& a)
}
void FontFamiliesTextStyleModifier::modify_text_style(skia::textlayout::TextStyle& style) const {
if(!globalFontData)
throw std::runtime_error("[FontFamiliesTextStyleModifier::modify_text_style] global font data not set");
auto familiesToPush = families;
push_default_font_families(familiesToPush);
globalFontData->push_default_font_families(familiesToPush);
style.setFontFamilies(familiesToPush);
}

View file

@ -4,6 +4,7 @@
#include <modules/skparagraph/include/TextStyle.h>
#include "cereal/archives/portable_binary.hpp"
#include "../SharedTypes.hpp"
#include "../FontData.hpp"
namespace RichText {
@ -108,6 +109,8 @@ class SizeTextStyleModifier : public TextStyleModifier {
class FontFamiliesTextStyleModifier : public TextStyleModifier {
public:
static std::shared_ptr<FontData> globalFontData;
FontFamiliesTextStyleModifier() = default;
FontFamiliesTextStyleModifier(const std::vector<SkString>& initFamilies);
virtual ModifierType get_type() const override;

View file

@ -39,10 +39,8 @@ Toolbar::Toolbar(MainProgram& initMain):
io(std::make_shared<GUIStuff::UpdateInputData>()),
main(initMain)
{
io->textTypeface = main.fonts.map["Roboto"];
io->textFontMgrLocal = main.fonts.localFontMgr;
io->textFontMgrFallback = main.fonts.defaultFontMgr;
io->fontCollection = main.fonts.collection;
io->textTypeface = main.fonts->map["Roboto"];
io->fonts = main.fonts;
load_default_palette();
load_default_theme();
@ -824,12 +822,12 @@ std::unique_ptr<skia::textlayout::Paragraph> Toolbar::build_paragraph_from_chat_
pStyle.setTextAlign(skia::textlayout::TextAlign::kLeft);
skia::textlayout::TextStyle tStyle;
tStyle.setFontSize(io->fontSize);
tStyle.setFontFamilies(get_default_font_families());
tStyle.setFontFamilies(main.fonts->get_default_font_families());
tStyle.setFontStyle(SkFontStyle::Bold());
tStyle.setForegroundColor(SkPaint{color_mul_alpha(message.type == ChatMessage::JOIN ? io->theme->warningColor : io->theme->frontColor1, alpha)});
pStyle.setTextStyle(tStyle);
skia::textlayout::ParagraphBuilderImpl a(pStyle, io->fontCollection, SkUnicodes::ICU::Make());
skia::textlayout::ParagraphBuilderImpl a(pStyle, io->fonts->collection, SkUnicodes::ICU::Make());
if(message.type == ChatMessage::JOIN) {
std::string messageName = message.name + " ";
a.addText(messageName.c_str(), messageName.length());