diff --git a/src/dlangui/graphics/fonts.d b/src/dlangui/graphics/fonts.d index 20e87aaa..4fbc0c1f 100644 --- a/src/dlangui/graphics/fonts.d +++ b/src/dlangui/graphics/fonts.d @@ -426,6 +426,8 @@ class Font : RefCountedObject { abstract void checkpoint(); /// removes entries not used after last call of checkpoint() or cleanup() abstract void cleanup(); + /// clears glyph cache + abstract void clearGlyphCache(); void clear() {} @@ -510,6 +512,11 @@ struct FontList { for (int i = 0; i < _len; i++) _list[i].checkpoint(); } + /// clears glyph cache + void clearGlyphCache() { + for (int i = 0; i < _len; i++) + _list[i].clearGlyphCache(); + } } /// default min font size for antialiased fonts (e.g. if 16 is set, for 16+ sizes antialiasing will be used, for sizes <=15 - antialiasing will be off) @@ -564,7 +571,11 @@ class FontManager { /// set new min font size for antialiased fonts - fonts with size >= specified value will be antialiased (0 means antialiasing always on, some big value = always off) static @property void minAnitialiasedFontSize(int size) { - _minAnitialiasedFontSize = size; + if (_minAnitialiasedFontSize != size) { + _minAnitialiasedFontSize = size; + if (_instance) + _instance.clearGlyphCaches(); + } } /// get current hinting mode (Normal, AutoHint, Disabled) @@ -574,7 +585,11 @@ class FontManager { /// set hinting mode (Normal, AutoHint, Disabled) static @property void hintingMode(HintingMode mode) { - _hintingMode = mode; + if (_hintingMode != mode) { + _hintingMode = mode; + if (_instance) + _instance.clearGlyphCaches(); + } } /// get current subpixel rendering mode for fonts (aka ClearType) @@ -596,9 +611,17 @@ class FontManager { v = 0.1; else if (v > 4) v = 4; - _fontGamma = v; - _gamma65.gamma = v; - _gamma256.gamma = v; + if (_fontGamma != v) { + _fontGamma = v; + _gamma65.gamma = v; + _gamma256.gamma = v; + if (_instance) + _instance.clearGlyphCaches(); + } + } + + void clearGlyphCaches() { + // override to clear glyph caches } ~this() { @@ -656,7 +679,7 @@ struct GlyphCache void cleanup() { foreach(part; _glyphs) { if (part !is null) - foreach(item; part) { + foreach(ref item; part) { if (item && !item.lastUsage) { version (USE_OPENGL) { // notify about destroyed glyphs @@ -665,6 +688,7 @@ struct GlyphCache } } destroy(item); + item = null; } } } @@ -685,7 +709,7 @@ struct GlyphCache void clear() { foreach(part; _glyphs) { if (part !is null) - foreach(item; part) { + foreach(ref item; part) { if (item) { version (USE_OPENGL) { // notify about destroyed glyphs @@ -694,6 +718,7 @@ struct GlyphCache } } destroy(item); + item = null; } } } diff --git a/src/dlangui/graphics/ftfonts.d b/src/dlangui/graphics/ftfonts.d index f5d1df1a..1051c1d8 100644 --- a/src/dlangui/graphics/ftfonts.d +++ b/src/dlangui/graphics/ftfonts.d @@ -83,6 +83,15 @@ private class FontFileItem { return _activeFonts.add(font); } + void clearGlyphCaches() { + _activeFonts.clearGlyphCache(); + } + void checkpoint() { + _activeFonts.checkpoint(); + } + void cleanup() { + _activeFonts.cleanup(); + } } class FreeTypeFontFile { @@ -437,6 +446,11 @@ class FreeTypeFont : Font { _glyphCache.cleanup(); } + /// clears glyph cache + override void clearGlyphCache() { + _glyphCache.clear(); + } + @property override int size() { return _size; } @property override int height() { return _files.length > 0 ? _files[0].height : _size; } @property override int weight() { return _fontItem.def.weight; } @@ -536,12 +550,26 @@ class FreeTypeFontManager : FontManager { /// clear usage flags for all entries override void checkpoint() { + foreach(ref ff; _fontFiles) { + ff.checkpoint(); + } } /// removes entries not used after last call of checkpoint() or cleanup() override void cleanup() { + foreach(ref ff; _fontFiles) { + ff.cleanup(); + } } + /// clears glyph cache + override void clearGlyphCaches() { + foreach(ref ff; _fontFiles) { + ff.clearGlyphCaches(); + } + } + + /// register freetype font by filename - optinally font properties can be passed if known (e.g. from libfontconfig). bool registerFont(string filename, FontFamily family = FontFamily.SansSerif, string face = null, bool italic = false, int weight = 0) { if (_library is null) diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 4a559e8f..5c16b962 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -768,6 +768,19 @@ class Window { return false; } + /// handle theme change: e.g. reload some themed resources + void dispatchThemeChanged() { + if (_mainWidget) + _mainWidget.onThemeChanged(); + // draw popups + foreach(p; _popups) { + p.onThemeChanged(); + } + if (_tooltip.popup) + _tooltip.popup.onThemeChanged(); + } + + /// post event to handle in UI thread (this method can be used from background thread) void postEvent(CustomEvent event) { // override to post event into window message queue @@ -1242,6 +1255,7 @@ class Platform { i18n.load("en.ini"); //"ru.ini", "en.ini" else i18n.load(langCode ~ ".ini", "en.ini"); + onThemeChanged(); requestLayout(); return this; } @@ -1262,6 +1276,7 @@ class Platform { Log.i("Applying loaded theme ", theme.id); } currentTheme = theme; + onThemeChanged(); requestLayout(); return this; } @@ -1302,6 +1317,12 @@ class Platform { //// TODO: support other platforms //return res; } + + /// handle theme change: e.g. reload some themed resources + void onThemeChanged() { + // override and call dispatchThemeChange for all windows + } + } /// get current platform object instance diff --git a/src/dlangui/platforms/sdl/sdlapp.d b/src/dlangui/platforms/sdl/sdlapp.d index 4c1f1ac2..75773ea7 100644 --- a/src/dlangui/platforms/sdl/sdlapp.d +++ b/src/dlangui/platforms/sdl/sdlapp.d @@ -843,6 +843,11 @@ class SDLPlatform : Platform { } } + /// handle theme change: e.g. reload some themed resources + override void onThemeChanged() { + foreach(w; _windowMap) + w.dispatchThemeChanged(); + } private uint _redrawEventId; diff --git a/src/dlangui/platforms/windows/win32fonts.d b/src/dlangui/platforms/windows/win32fonts.d index a1f9735e..3e36e2b0 100644 --- a/src/dlangui/platforms/windows/win32fonts.d +++ b/src/dlangui/platforms/windows/win32fonts.d @@ -469,6 +469,11 @@ class Win32Font : Font { _glyphCache.cleanup(); } + /// clears glyph cache + override void clearGlyphCache() { + _glyphCache.clear(); + } + @property override int size() { return _size; } @property override int height() { return _height; } @property override int weight() { return _weight; } @@ -627,6 +632,11 @@ class Win32FontManager : FontManager { _activeFonts.cleanup(); //_list.cleanup(); } + + /// clears glyph cache + override void clearGlyphCaches() { + _activeFonts.clearGlyphCache(); + } } FontFamily pitchAndFamilyToFontFamily(ubyte flags) { diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 13a6f0c5..47840523 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -790,6 +790,12 @@ class Win32Platform : Platform { } } + /// handle theme change: e.g. reload some themed resources + override void onThemeChanged() { + foreach(w; _windowMap) + w.dispatchThemeChanged(); + } + Win32Window _windowToClose; /// close window diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index e1d953ef..1e0b74e5 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -242,6 +242,13 @@ class Widget { return _ownStyle; } + /// handle theme change: e.g. reload some themed resources + void onThemeChanged() { + // default implementation: call recursive for children + for (int i = 0; i < childCount; i++) + child(i).onThemeChanged(); + } + /// returns widget id, null if not set @property string id() const { return _id; } /// set widget id