diff --git a/src/fontcache/spritefontcache.cpp b/src/fontcache/spritefontcache.cpp index f7641cd169..171e5dd5d4 100644 --- a/src/fontcache/spritefontcache.cpp +++ b/src/fontcache/spritefontcache.cpp @@ -21,6 +21,16 @@ static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter. +/** + * Scale traditional pixel dimensions to font zoom level, for drawing sprite fonts. + * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). + * @return Pixel amount at _font_zoom (current interface size). + */ +static int ScaleFontTrad(int value) +{ + return UnScaleByZoom(value * ZOOM_LVL_BASE, _font_zoom); +} + /** * Create a new sprite font cache. * @param fs The font size to create the cache for. @@ -29,7 +39,7 @@ SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs), glyph_to_spriteid { this->InitializeUnicodeGlyphMap(); this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); - this->ascender = (this->height - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2; + this->ascender = (this->height - ScaleFontTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2; } /** @@ -107,7 +117,7 @@ void SpriteFontCache::ClearFontCache() { Layouter::ResetFontCache(this->fs); this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); - this->ascender = (this->height - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2; + this->ascender = (this->height - ScaleFontTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2; } const Sprite *SpriteFontCache::GetGlyph(GlyphID key) @@ -121,7 +131,7 @@ uint SpriteFontCache::GetGlyphWidth(GlyphID key) { SpriteID sprite = this->GetUnicodeGlyph(key); if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); - return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + ScaleSpriteTrad(this->fs != FS_NORMAL ? 1 : 0) : 0; + return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0; } bool SpriteFontCache::GetDrawGlyphShadow() diff --git a/src/gfx.cpp b/src/gfx.cpp index 1db7f632a9..3e8a0f15bb 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -101,9 +101,10 @@ static void GfxMainBlitter(const GfxBlitterCtx &ctx, const Sprite *sprite, int x static ReusableBuffer _cursor_backup; -ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level -int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%. -int _gui_scale_cfg; ///< GUI scale in config. +ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level +ZoomLevel _font_zoom = _gui_zoom; ///< Sprite font Zoom level (not clamped) +int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%. +int _gui_scale_cfg; ///< GUI scale in config. /** * The rect for repaint. @@ -2359,6 +2360,8 @@ void UpdateGUIZoom() } int8 new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_MIN : ZOOM_LVL_OUT_2X; + /* Font glyphs should not be clamped to min/max zoom. */ + _font_zoom = static_cast(new_zoom); /* Ensure the gui_zoom is clamped between min/max. */ new_zoom = Clamp(new_zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); _gui_zoom = static_cast(new_zoom); @@ -2377,17 +2380,20 @@ void UpdateGUIZoom() */ bool AdjustGUIZoom(AdjustGUIZoomMode mode) { - ZoomLevel old_zoom = _gui_zoom; + ZoomLevel old_gui_zoom = _gui_zoom; + ZoomLevel old_font_zoom = _font_zoom; int old_scale = _gui_scale; UpdateGUIZoom(); if (old_scale == _gui_scale) return false; /* Reload sprites if sprite zoom level has changed. */ - if (old_zoom != _gui_zoom) { + if (old_gui_zoom != _gui_zoom) { GfxClearSpriteCache(); VideoDriver::GetInstance()->ClearSystemSprites(); UpdateCursorSize(); if (mode != AGZM_STARTUP) UpdateRouteStepSpriteSize(); + } else if (old_font_zoom != _font_zoom) { + GfxClearFontSpriteCache(); } ClearFontCache(); @@ -2402,7 +2408,7 @@ bool AdjustGUIZoom(AdjustGUIZoomMode mode) /* Adjust all window sizes to match the new zoom level, so that they don't appear to move around when the application is moved to a screen with different DPI. */ - auto zoom_shift = old_zoom - _gui_zoom; + auto zoom_shift = old_gui_zoom - _gui_zoom; for (Window *w : Window::IterateFromBack()) { if (mode == AGZM_AUTOMATIC) { w->left = (w->left * _gui_scale) / old_scale; diff --git a/src/spritecache.cpp b/src/spritecache.cpp index fd7f215d0e..1633f86fb1 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -568,14 +568,14 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator, encoder); } - if (sprite->type == ST_FONT && ZOOM_LVL_GUI != ZOOM_LVL_NORMAL) { + if (sprite->type == ST_FONT && _font_zoom != ZOOM_LVL_NORMAL) { /* Make ZOOM_LVL_NORMAL be ZOOM_LVL_GUI */ - sprite[ZOOM_LVL_NORMAL].width = sprite[ZOOM_LVL_GUI].width; - sprite[ZOOM_LVL_NORMAL].height = sprite[ZOOM_LVL_GUI].height; - sprite[ZOOM_LVL_NORMAL].x_offs = sprite[ZOOM_LVL_GUI].x_offs; - sprite[ZOOM_LVL_NORMAL].y_offs = sprite[ZOOM_LVL_GUI].y_offs; - sprite[ZOOM_LVL_NORMAL].data = sprite[ZOOM_LVL_GUI].data; - sprite[ZOOM_LVL_NORMAL].colours = sprite[ZOOM_LVL_GUI].colours; + sprite[ZOOM_LVL_NORMAL].width = sprite[_font_zoom].width; + sprite[ZOOM_LVL_NORMAL].height = sprite[_font_zoom].height; + sprite[ZOOM_LVL_NORMAL].x_offs = sprite[_font_zoom].x_offs; + sprite[ZOOM_LVL_NORMAL].y_offs = sprite[_font_zoom].y_offs; + sprite[ZOOM_LVL_NORMAL].data = sprite[_font_zoom].data; + sprite[ZOOM_LVL_NORMAL].colours = sprite[_font_zoom].colours; } return encoder->Encode(sprite, allocator); @@ -1084,4 +1084,17 @@ void GfxClearSpriteCache() VideoDriver::GetInstance()->ClearSystemSprites(); } +/** + * Remove all encoded font sprites from the sprite cache without + * discarding sprite location information. + */ +void GfxClearFontSpriteCache() +{ + /* Clear sprite ptr for all cached font items */ + for (uint i = 0; i != _spritecache.size(); i++) { + SpriteCache *sc = GetSpriteCache(i); + if (sc->GetType() == ST_FONT && sc->GetPtr() != nullptr) DeleteEntryFromSpriteCache(i); + } +} + /* static */ ReusableBuffer SpriteLoader::Sprite::buffer[ZOOM_LVL_COUNT]; diff --git a/src/spritecache.h b/src/spritecache.h index da9cb01aa4..837028df56 100644 --- a/src/spritecache.h +++ b/src/spritecache.h @@ -61,6 +61,7 @@ static inline const byte *GetNonSprite(SpriteID sprite, SpriteType type) void GfxInitSpriteMem(); void GfxClearSpriteCache(); +void GfxClearFontSpriteCache(); void IncreaseSpriteLRU(); SpriteFile &OpenCachedSpriteFile(const std::string &filename, Subdirectory subdir, bool palette_remap); diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index 4c57eecb53..3861332c57 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -286,11 +286,12 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p if (sprite_type != ST_MAPGEN) { if (zoom < lengthof(zoom_lvl_map)) { is_wanted_zoom_lvl = true; - if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_2X && + ZoomLevel zoom_min = sprite_type == ST_FONT ? ZOOM_LVL_NORMAL : _settings_client.gui.sprite_zoom_min; + if (zoom_min >= ZOOM_LVL_OUT_2X && HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_2X) { is_wanted_zoom_lvl = false; } - if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_4X && + if (zoom_min >= ZOOM_LVL_OUT_4X && HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_4X) { is_wanted_zoom_lvl = false; } diff --git a/src/zoom_type.h b/src/zoom_type.h index e11e45ace9..9d4e5e7690 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -57,6 +57,7 @@ extern int _gui_scale; extern int _gui_scale_cfg; extern ZoomLevel _gui_zoom; +extern ZoomLevel _font_zoom; #define ZOOM_LVL_GUI (_gui_zoom) static const int MIN_INTERFACE_SCALE = 100;