From fb667fb8bb3e79e44fdb973cf7f0be99f08ac841 Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Tue, 10 Jan 2017 09:52:51 +0700 Subject: [PATCH] Use a dedicated BitmapFont instance per Canvas. Before this commit, updates to the bitmap font in the graphics window cause missing characters in the text window and vice versa. This is because BitmapFont contains a texture that's mutated, and sharing it would also require sharing display lists between GL contexts, which is not done (and overly complicated for this case anyway). --- src/draw.cpp | 2 +- src/render/render.cpp | 11 +++++++++-- src/render/render.h | 4 +++- src/resource.cpp | 29 +++++++++++++---------------- src/resource.h | 2 +- src/textwin.cpp | 4 +++- src/toolbar.cpp | 2 +- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index 2adf4f4..b9fe1a8 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -800,7 +800,7 @@ void GraphicsWindow::Draw(Canvas *canvas) { } void GraphicsWindow::Paint() { - if (!canvas) return; + if(!canvas) return; havePainted = true; diff --git a/src/render/render.cpp b/src/render/render.cpp index 40e1f02..b6ca6c7 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -211,6 +211,13 @@ Canvas::hFill Canvas::GetFill(const Fill &fill) { return fills.AddAndAssignId(&fillCopy); } +BitmapFont *Canvas::GetBitmapFont() { + if(bitmapFont.IsEmpty()) { + bitmapFont = BitmapFont::Create(); + } + return &bitmapFont; +} + std::shared_ptr Canvas::CreateBatch() { return std::shared_ptr(); } @@ -292,7 +299,7 @@ void UiCanvas::DrawPixmap(std::shared_ptr pm, int x, int y, int zI } void UiCanvas::DrawBitmapChar(char32_t codepoint, int x, int y, RgbaColor color, int zIndex) { - BitmapFont *font = BitmapFont::Builtin(); + BitmapFont *font = canvas->GetBitmapFont(); Canvas::Fill fill = {}; fill.layer = Canvas::Layer::NORMAL; @@ -324,7 +331,7 @@ void UiCanvas::DrawBitmapChar(char32_t codepoint, int x, int y, RgbaColor color, } void UiCanvas::DrawBitmapText(const std::string &str, int x, int y, RgbaColor color, int zIndex) { - BitmapFont *font = BitmapFont::Builtin(); + BitmapFont *font = canvas->GetBitmapFont(); for(char32_t codepoint : ReadUTF8(str)) { DrawBitmapChar(codepoint, x, y, color, zIndex); diff --git a/src/render/render.h b/src/render/render.h index 1423c5e..07eeca4 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -137,12 +137,14 @@ public: IdList strokes; IdList fills; + BitmapFont bitmapFont; - Canvas() : strokes(), fills() {} + Canvas() : strokes(), fills(), bitmapFont() {} virtual void Clear(); hStroke GetStroke(const Stroke &stroke); hFill GetFill(const Fill &fill); + BitmapFont *GetBitmapFont(); virtual const Camera &GetCamera() const = 0; diff --git a/src/resource.cpp b/src/resource.cpp index b6467fd..423ae89 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -645,22 +645,19 @@ size_t BitmapFont::GetWidth(const std::string &str) { return width; } -BitmapFont *BitmapFont::Builtin() { - static BitmapFont Font; - if(Font.IsEmpty()) { - Font = BitmapFont::From(LoadStringFromGzip("fonts/unifont.hex.gz")); - // Unifont doesn't have a glyph for U+0020. - Font.AddGlyph(0x0020, Pixmap::Create(Pixmap::Format::RGB, 8, 16)); - Font.AddGlyph(0xE000, LoadPng("fonts/private/0-check-false.png")); - Font.AddGlyph(0xE001, LoadPng("fonts/private/1-check-true.png")); - Font.AddGlyph(0xE002, LoadPng("fonts/private/2-radio-false.png")); - Font.AddGlyph(0xE003, LoadPng("fonts/private/3-radio-true.png")); - Font.AddGlyph(0xE004, LoadPng("fonts/private/4-stipple-dot.png")); - Font.AddGlyph(0xE005, LoadPng("fonts/private/5-stipple-dash-long.png")); - Font.AddGlyph(0xE006, LoadPng("fonts/private/6-stipple-dash.png")); - Font.AddGlyph(0xE007, LoadPng("fonts/private/7-stipple-zigzag.png")); - } - return &Font; +BitmapFont BitmapFont::Create() { + BitmapFont Font = BitmapFont::From(LoadStringFromGzip("fonts/unifont.hex.gz")); + // Unifont doesn't have a glyph for U+0020. + Font.AddGlyph(0x0020, Pixmap::Create(Pixmap::Format::RGB, 8, 16)); + Font.AddGlyph(0xE000, LoadPng("fonts/private/0-check-false.png")); + Font.AddGlyph(0xE001, LoadPng("fonts/private/1-check-true.png")); + Font.AddGlyph(0xE002, LoadPng("fonts/private/2-radio-false.png")); + Font.AddGlyph(0xE003, LoadPng("fonts/private/3-radio-true.png")); + Font.AddGlyph(0xE004, LoadPng("fonts/private/4-stipple-dot.png")); + Font.AddGlyph(0xE005, LoadPng("fonts/private/5-stipple-dash-long.png")); + Font.AddGlyph(0xE006, LoadPng("fonts/private/6-stipple-dash.png")); + Font.AddGlyph(0xE007, LoadPng("fonts/private/7-stipple-zigzag.png")); + return Font; } //----------------------------------------------------------------------------- diff --git a/src/resource.h b/src/resource.h index 200f240..858e3b2 100644 --- a/src/resource.h +++ b/src/resource.h @@ -62,7 +62,7 @@ public: uint16_t nextPosition; static BitmapFont From(std::string &&unifontData); - static BitmapFont *Builtin(); + static BitmapFont Create(); bool IsEmpty() const { return unifontData.empty(); } const Glyph &GetGlyph(char32_t codepoint); diff --git a/src/textwin.cpp b/src/textwin.cpp index 2b9ace9..0e01418 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -292,6 +292,8 @@ void TextWindow::ClearScreen() { } void TextWindow::Printf(bool halfLine, const char *fmt, ...) { + if(!canvas) return; + va_list vl; va_start(vl, fmt); @@ -429,7 +431,7 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) { } for(utf8_iterator it(buf); *it; ++it) { - for(size_t i = 0; i < BitmapFont::Builtin()->GetWidth(*it); i++) { + for(size_t i = 0; i < canvas->GetBitmapFont()->GetWidth(*it); i++) { if(c >= MAX_COLS) goto done; text[r][c] = (i == 0) ? *it : ' '; meta[r][c].fg = fg; diff --git a/src/toolbar.cpp b/src/toolbar.cpp index ec3c4d7..d8e0070 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -239,7 +239,7 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, } } - int tw = BitmapFont::Builtin()->GetWidth(tooltip) * 8 + 10, + int tw = canvas->canvas->GetBitmapFont()->GetWidth(tooltip) * 8 + 10, th = SS.TW.LINE_HEIGHT + 2; int ox = toolbarMouseX + 3, oy = toolbarMouseY + 3;