Skip to content

Commit

Permalink
Font and resource loading changes
Browse files Browse the repository at this point in the history
  • Loading branch information
dpjudas committed Jan 10, 2024
1 parent 2832f0b commit 8113ffb
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 22 deletions.
10 changes: 8 additions & 2 deletions include/zwidget/core/resourcedata.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@
#include <cstdint>
#include <string>

std::vector<uint8_t> LoadWidgetFontData(const std::string& name);
std::vector<uint8_t> LoadWidgetImageData(const std::string& name);
struct SingleFontData
{
std::vector<uint8_t> fontdata;
std::string language;
};

std::vector<SingleFontData> LoadWidgetFontData(const std::string& name);
std::vector<uint8_t> LoadWidgetData(const std::string& name);
3 changes: 3 additions & 0 deletions include/zwidget/widgets/checkboxlabel/checkboxlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class CheckboxLabel : public Widget
void Toggle();

double GetPreferredHeight() const;
std::function<void(bool)> FuncChanged;
void SetRadioStyle(bool on) { radiostyle = on; }

protected:
void OnPaint(Canvas* canvas) override;
Expand All @@ -27,5 +29,6 @@ class CheckboxLabel : public Widget
private:
std::string text;
bool checked = false;
bool radiostyle = false;
bool mouseDownActive = false;
};
1 change: 1 addition & 0 deletions include/zwidget/widgets/listview/listview.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ListView : public Widget

void Activate();

std::function<void(int)> OnChanged;
std::function<void()> OnActivated;

protected:
Expand Down
2 changes: 1 addition & 1 deletion include/zwidget/widgets/textedit/textedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class TextEdit : public Widget

bool select_all_on_focus_gain = false;

std::shared_ptr<Font> font = Font::Create("Segoe UI", 12.0);
std::shared_ptr<Font> font = Font::Create("NotoSans", 12.0);

template<typename T>
static T clamp(T val, T minval, T maxval) { return std::max<T>(std::min<T>(val, maxval), minval); }
Expand Down
74 changes: 63 additions & 11 deletions src/core/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ class CanvasGlyph
class CanvasFont
{
public:
CanvasFont(const std::string& fontname, double height) : fontname(fontname), height(height)
CanvasFont(const std::string& fontname, double height, std::vector<uint8_t> data) : fontname(fontname), height(height)
{
ttf = std::make_unique<TrueTypeFont>(std::make_shared<TrueTypeFontFileData>(LoadWidgetFontData(fontname)));
auto tdata = std::make_shared<TrueTypeFontFileData>(std::move(data));
ttf = std::make_unique<TrueTypeFont>(tdata);
textmetrics = ttf->GetTextMetrics(height);
}

Expand All @@ -54,6 +55,7 @@ class CanvasFont
CanvasGlyph* getGlyph(uint32_t utfchar)
{
uint32_t glyphIndex = ttf->GetGlyphIndex(utfchar);
if (glyphIndex == 0) return nullptr;

auto& glyph = glyphs[glyphIndex];
if (glyph)
Expand Down Expand Up @@ -120,6 +122,52 @@ class CanvasFont
std::unordered_map<uint32_t, std::unique_ptr<CanvasGlyph>> glyphs;
};

class CanvasFontGroup
{
public:
struct SingleFont
{
std::unique_ptr<CanvasFont> font;
std::string language;
};
CanvasFontGroup(const std::string& fontname, double height) : height(height)
{
auto fontdata = LoadWidgetFontData(fontname);
fonts.resize(fontdata.size());
for (size_t i = 0; i < fonts.size(); i++)
{
fonts[i].font = std::make_unique<CanvasFont>(fontname, height, fontdata[i].fontdata);
fonts[i].language = fontdata[i].language;
}
}

CanvasGlyph* getGlyph(uint32_t utfchar, const char* lang = nullptr)
{
for (int i = 0; i < 2; i++)
{
for (auto& fd : fonts)
{
if (i == 1 || lang == nullptr || *lang == 0 || fd.language.empty() || fd.language == lang)
{
auto g = fd.font->getGlyph(utfchar);
if (g) return g;
}
}
}

return nullptr;
}

TrueTypeTextMetrics& GetTextMetrics()
{
return fonts[0].font->textmetrics;
}

double height;
std::vector<SingleFont> fonts;

};

class BitmapCanvas : public Canvas
{
public:
Expand Down Expand Up @@ -172,14 +220,16 @@ class BitmapCanvas : public Canvas
int getClipMaxX() const;
int getClipMaxY() const;

void setLanguage(const char* lang) { language = lang; }

std::unique_ptr<CanvasTexture> createTexture(int width, int height, const void* pixels, ImageFormat format = ImageFormat::B8G8R8A8);

template<typename T>
static T clamp(T val, T minval, T maxval) { return std::max<T>(std::min<T>(val, maxval), minval); }

DisplayWindow* window = nullptr;

std::unique_ptr<CanvasFont> font;
std::unique_ptr<CanvasFontGroup> font;
std::unique_ptr<CanvasTexture> whiteTexture;

Point origin;
Expand All @@ -191,14 +241,15 @@ class BitmapCanvas : public Canvas
std::vector<uint32_t> pixels;

std::unordered_map<std::shared_ptr<Image>, std::unique_ptr<CanvasTexture>> imageTextures;
std::string language;
};

BitmapCanvas::BitmapCanvas(DisplayWindow* window) : window(window)
{
uiscale = window->GetDpiScale();
uint32_t white = 0xffffffff;
whiteTexture = createTexture(1, 1, &white);
font = std::make_unique<CanvasFont>("Segoe UI", 13.0*uiscale);
font = std::make_unique<CanvasFontGroup>("NotoSans", 13.0 * uiscale);
}

BitmapCanvas::~BitmapCanvas()
Expand Down Expand Up @@ -358,8 +409,8 @@ void BitmapCanvas::drawText(const Point& pos, const Colorf& color, const std::st
UTF8Reader reader(text.data(), text.size());
while (!reader.is_end())
{
CanvasGlyph* glyph = font->getGlyph(reader.character());
if (!glyph->texture)
CanvasGlyph* glyph = font->getGlyph(reader.character(), language.c_str());
if (!glyph || !glyph->texture)
{
glyph = font->getGlyph(32);
}
Expand All @@ -379,13 +430,13 @@ void BitmapCanvas::drawText(const Point& pos, const Colorf& color, const std::st
Rect BitmapCanvas::measureText(const std::string& text)
{
double x = 0.0;
double y = font->textmetrics.ascender - font->textmetrics.descender;
double y = font->GetTextMetrics().ascender - font->GetTextMetrics().descender;

UTF8Reader reader(text.data(), text.size());
while (!reader.is_end())
{
CanvasGlyph* glyph = font->getGlyph(reader.character());
if (!glyph->texture)
CanvasGlyph* glyph = font->getGlyph(reader.character(), language.c_str());
if (!glyph || !glyph->texture)
{
glyph = font->getGlyph(32);
}
Expand All @@ -401,8 +452,9 @@ VerticalTextPosition BitmapCanvas::verticalTextAlign()
{
VerticalTextPosition align;
align.top = 0.0f;
align.baseline = font->textmetrics.ascender / uiscale;
align.bottom = (font->textmetrics.ascender - font->textmetrics.descender) / uiscale;
auto tm = font->GetTextMetrics();
align.baseline = tm.ascender / uiscale;
align.bottom = (tm.ascender - tm.descender) / uiscale;
return align;
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ std::shared_ptr<Image> Image::LoadResource(const std::string& resourcename, doub

if (extension == "png")
{
auto filedata = LoadWidgetImageData(resourcename);
auto filedata = LoadWidgetData(resourcename);

std::vector<unsigned char> pixels;
unsigned long width = 0, height = 0;
Expand All @@ -74,7 +74,7 @@ std::shared_ptr<Image> Image::LoadResource(const std::string& resourcename, doub
}
else if (extension == "svg")
{
auto filedata = LoadWidgetImageData(resourcename);
auto filedata = LoadWidgetData(resourcename);
filedata.push_back(0);

NSVGimage* svgimage = nsvgParse((char*)filedata.data(), "px", (float)(96.0 * dpiscale));
Expand Down
9 changes: 9 additions & 0 deletions src/core/nanosvg/nanosvg.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ void nsvgDelete(NSVGimage* image);
#include <stdio.h>
#include <math.h>

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4244)
#endif

#define NSVG_PI (3.14159265358979323846264338327f)
#define NSVG_KAPPA90 (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs.

Expand Down Expand Up @@ -3093,6 +3098,10 @@ void nsvgDelete(NSVGimage* image)
free(image);
}

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#endif // NANOSVG_IMPLEMENTATION

#endif // NANOSVG_H
14 changes: 8 additions & 6 deletions src/widgets/checkboxlabel/checkboxlabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ void CheckboxLabel::OnPaint(Canvas* canvas)
{
if (checked)
{
canvas->fillRect(Rect::xywh(0.0, GetHeight() * 0.5 - 5.0, 10.0, 10.0), Colorf::fromRgba8(100, 100, 100));
canvas->fillRect(Rect::xywh(1.0, GetHeight() * 0.5 - 4.0, 8.0, 8.0), Colorf::fromRgba8(51, 51, 51));
canvas->fillRect(Rect::xywh(2.0, GetHeight() * 0.5 - 3.0, 6.0, 6.0), Colorf::fromRgba8(226, 223, 219));
canvas->fillRect(Rect::xywh(0.0, GetHeight() * 0.5 - 6.0, 10.0, 10.0), Colorf::fromRgba8(100, 100, 100));
canvas->fillRect(Rect::xywh(1.0, GetHeight() * 0.5 - 5.0, 8.0, 8.0), Colorf::fromRgba8(51, 51, 51));
canvas->fillRect(Rect::xywh(2.0, GetHeight() * 0.5 - 4.0, 6.0, 6.0), Colorf::fromRgba8(226, 223, 219));
}
else
{
canvas->fillRect(Rect::xywh(0.0, GetHeight() * 0.5 - 5.0, 10.0, 10.0), Colorf::fromRgba8(68, 68, 68));
canvas->fillRect(Rect::xywh(1.0, GetHeight() * 0.5 - 4.0, 8.0, 8.0), Colorf::fromRgba8(51, 51, 51));
canvas->fillRect(Rect::xywh(0.0, GetHeight() * 0.5 - 6.0, 10.0, 10.0), Colorf::fromRgba8(99, 99, 99));
canvas->fillRect(Rect::xywh(1.0, GetHeight() * 0.5 - 5.0, 8.0, 8.0), Colorf::fromRgba8(51, 51, 51));
}

canvas->drawText(Point(14.0, GetHeight() - 5.0), Colorf::fromRgba8(255, 255, 255), text);
Expand Down Expand Up @@ -83,6 +83,8 @@ void CheckboxLabel::OnKeyUp(EInputKey key)

void CheckboxLabel::Toggle()
{
checked = !checked;
bool oldchecked = checked;
checked = radiostyle? true : !checked;
Update();
if (checked != oldchecked && FuncChanged) FuncChanged(checked);
}
1 change: 1 addition & 0 deletions src/widgets/listview/listview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void ListView::SetSelectedItem(int index)
if (selectedItem != index && index >= 0 && index < items.size())
{
selectedItem = index;
if (OnChanged) OnChanged(selectedItem);
Update();
}
}
Expand Down

0 comments on commit 8113ffb

Please sign in to comment.