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).
pull/106/head
EvilSpirit 2017-01-10 09:52:51 +07:00 committed by whitequark
parent 33c9ffb5ca
commit fb667fb8bb
7 changed files with 31 additions and 23 deletions

View File

@ -800,7 +800,7 @@ void GraphicsWindow::Draw(Canvas *canvas) {
} }
void GraphicsWindow::Paint() { void GraphicsWindow::Paint() {
if (!canvas) return; if(!canvas) return;
havePainted = true; havePainted = true;

View File

@ -211,6 +211,13 @@ Canvas::hFill Canvas::GetFill(const Fill &fill) {
return fills.AddAndAssignId(&fillCopy); return fills.AddAndAssignId(&fillCopy);
} }
BitmapFont *Canvas::GetBitmapFont() {
if(bitmapFont.IsEmpty()) {
bitmapFont = BitmapFont::Create();
}
return &bitmapFont;
}
std::shared_ptr<BatchCanvas> Canvas::CreateBatch() { std::shared_ptr<BatchCanvas> Canvas::CreateBatch() {
return std::shared_ptr<BatchCanvas>(); return std::shared_ptr<BatchCanvas>();
} }
@ -292,7 +299,7 @@ void UiCanvas::DrawPixmap(std::shared_ptr<const Pixmap> pm, int x, int y, int zI
} }
void UiCanvas::DrawBitmapChar(char32_t codepoint, int x, int y, RgbaColor color, int zIndex) { 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 = {}; Canvas::Fill fill = {};
fill.layer = Canvas::Layer::NORMAL; 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) { 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)) { for(char32_t codepoint : ReadUTF8(str)) {
DrawBitmapChar(codepoint, x, y, color, zIndex); DrawBitmapChar(codepoint, x, y, color, zIndex);

View File

@ -137,12 +137,14 @@ public:
IdList<Stroke, hStroke> strokes; IdList<Stroke, hStroke> strokes;
IdList<Fill, hFill> fills; IdList<Fill, hFill> fills;
BitmapFont bitmapFont;
Canvas() : strokes(), fills() {} Canvas() : strokes(), fills(), bitmapFont() {}
virtual void Clear(); virtual void Clear();
hStroke GetStroke(const Stroke &stroke); hStroke GetStroke(const Stroke &stroke);
hFill GetFill(const Fill &fill); hFill GetFill(const Fill &fill);
BitmapFont *GetBitmapFont();
virtual const Camera &GetCamera() const = 0; virtual const Camera &GetCamera() const = 0;

View File

@ -645,22 +645,19 @@ size_t BitmapFont::GetWidth(const std::string &str) {
return width; return width;
} }
BitmapFont *BitmapFont::Builtin() { BitmapFont BitmapFont::Create() {
static BitmapFont Font; BitmapFont Font = BitmapFont::From(LoadStringFromGzip("fonts/unifont.hex.gz"));
if(Font.IsEmpty()) { // Unifont doesn't have a glyph for U+0020.
Font = BitmapFont::From(LoadStringFromGzip("fonts/unifont.hex.gz")); Font.AddGlyph(0x0020, Pixmap::Create(Pixmap::Format::RGB, 8, 16));
// Unifont doesn't have a glyph for U+0020. Font.AddGlyph(0xE000, LoadPng("fonts/private/0-check-false.png"));
Font.AddGlyph(0x0020, Pixmap::Create(Pixmap::Format::RGB, 8, 16)); Font.AddGlyph(0xE001, LoadPng("fonts/private/1-check-true.png"));
Font.AddGlyph(0xE000, LoadPng("fonts/private/0-check-false.png")); Font.AddGlyph(0xE002, LoadPng("fonts/private/2-radio-false.png"));
Font.AddGlyph(0xE001, LoadPng("fonts/private/1-check-true.png")); Font.AddGlyph(0xE003, LoadPng("fonts/private/3-radio-true.png"));
Font.AddGlyph(0xE002, LoadPng("fonts/private/2-radio-false.png")); Font.AddGlyph(0xE004, LoadPng("fonts/private/4-stipple-dot.png"));
Font.AddGlyph(0xE003, LoadPng("fonts/private/3-radio-true.png")); Font.AddGlyph(0xE005, LoadPng("fonts/private/5-stipple-dash-long.png"));
Font.AddGlyph(0xE004, LoadPng("fonts/private/4-stipple-dot.png")); Font.AddGlyph(0xE006, LoadPng("fonts/private/6-stipple-dash.png"));
Font.AddGlyph(0xE005, LoadPng("fonts/private/5-stipple-dash-long.png")); Font.AddGlyph(0xE007, LoadPng("fonts/private/7-stipple-zigzag.png"));
Font.AddGlyph(0xE006, LoadPng("fonts/private/6-stipple-dash.png")); return Font;
Font.AddGlyph(0xE007, LoadPng("fonts/private/7-stipple-zigzag.png"));
}
return &Font;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -62,7 +62,7 @@ public:
uint16_t nextPosition; uint16_t nextPosition;
static BitmapFont From(std::string &&unifontData); static BitmapFont From(std::string &&unifontData);
static BitmapFont *Builtin(); static BitmapFont Create();
bool IsEmpty() const { return unifontData.empty(); } bool IsEmpty() const { return unifontData.empty(); }
const Glyph &GetGlyph(char32_t codepoint); const Glyph &GetGlyph(char32_t codepoint);

View File

@ -292,6 +292,8 @@ void TextWindow::ClearScreen() {
} }
void TextWindow::Printf(bool halfLine, const char *fmt, ...) { void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
if(!canvas) return;
va_list vl; va_list vl;
va_start(vl, fmt); va_start(vl, fmt);
@ -429,7 +431,7 @@ void TextWindow::Printf(bool halfLine, const char *fmt, ...) {
} }
for(utf8_iterator it(buf); *it; ++it) { 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; if(c >= MAX_COLS) goto done;
text[r][c] = (i == 0) ? *it : ' '; text[r][c] = (i == 0) ? *it : ' ';
meta[r][c].fg = fg; meta[r][c].fg = fg;

View File

@ -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; th = SS.TW.LINE_HEIGHT + 2;
int ox = toolbarMouseX + 3, oy = toolbarMouseY + 3; int ox = toolbarMouseX + 3, oy = toolbarMouseY + 3;