1
0
Fork 0

Fix #10660: Sprite Font scale affected by viewport zoom level limits. (#10668)

pull/10476/merge
PeterN 2023-04-16 23:14:03 +01:00 committed by GitHub
parent e20a6f8ebb
commit db573c8742
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 18 deletions

View File

@ -21,6 +21,16 @@
static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter. 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. * Create a new sprite font cache.
* @param fs The font size to create the cache for. * @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->InitializeUnicodeGlyphMap();
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(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;
} }
/** /**
@ -106,7 +116,7 @@ void SpriteFontCache::ClearFontCache()
{ {
Layouter::ResetFontCache(this->fs); Layouter::ResetFontCache(this->fs);
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(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) const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
@ -120,7 +130,7 @@ uint SpriteFontCache::GetGlyphWidth(GlyphID key)
{ {
SpriteID sprite = this->GetUnicodeGlyph(key); SpriteID sprite = this->GetUnicodeGlyph(key);
if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleSpriteTrad(this->fs != FS_NORMAL ? 1 : 0) : 0; return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
} }
bool SpriteFontCache::GetDrawGlyphShadow() bool SpriteFontCache::GetDrawGlyphShadow()

View File

@ -61,9 +61,10 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode,
static ReusableBuffer<uint8> _cursor_backup; static ReusableBuffer<uint8> _cursor_backup;
ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level
int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%. ZoomLevel _font_zoom = _gui_zoom; ///< Sprite font Zoom level (not clamped)
int _gui_scale_cfg; ///< GUI scale in config. int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%.
int _gui_scale_cfg; ///< GUI scale in config.
/** /**
* The rect for repaint. * The rect for repaint.
@ -2049,6 +2050,8 @@ void UpdateGUIZoom()
} }
int8 new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_MIN : ZOOM_LVL_OUT_2X; 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<ZoomLevel>(new_zoom);
/* Ensure the gui_zoom is clamped between min/max. */ /* Ensure the gui_zoom is clamped between min/max. */
new_zoom = Clamp(new_zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); new_zoom = Clamp(new_zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max);
_gui_zoom = static_cast<ZoomLevel>(new_zoom); _gui_zoom = static_cast<ZoomLevel>(new_zoom);
@ -2062,16 +2065,19 @@ void UpdateGUIZoom()
*/ */
bool AdjustGUIZoom(bool automatic) bool AdjustGUIZoom(bool automatic)
{ {
ZoomLevel old_zoom = _gui_zoom; ZoomLevel old_gui_zoom = _gui_zoom;
ZoomLevel old_font_zoom = _font_zoom;
int old_scale = _gui_scale; int old_scale = _gui_scale;
UpdateGUIZoom(); UpdateGUIZoom();
if (old_scale == _gui_scale) return false; if (old_scale == _gui_scale) return false;
/* Reload sprites if sprite zoom level has changed. */ /* Reload sprites if sprite zoom level has changed. */
if (old_zoom != _gui_zoom) { if (old_gui_zoom != _gui_zoom) {
GfxClearSpriteCache(); GfxClearSpriteCache();
VideoDriver::GetInstance()->ClearSystemSprites(); VideoDriver::GetInstance()->ClearSystemSprites();
UpdateCursorSize(); UpdateCursorSize();
} else if (old_font_zoom != _font_zoom) {
GfxClearFontSpriteCache();
} }
ClearFontCache(); ClearFontCache();
@ -2080,7 +2086,7 @@ bool AdjustGUIZoom(bool automatic)
/* Adjust all window sizes to match the new zoom level, so that they don't appear /* 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. */ 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::Iterate()) { for (Window *w : Window::Iterate()) {
if (automatic) { if (automatic) {
w->left = (w->left * _gui_scale) / old_scale; w->left = (w->left * _gui_scale) / old_scale;

View File

@ -519,14 +519,14 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator, encoder); return (void*)GetRawSprite(SPR_IMG_QUERY, SpriteType::Normal, allocator, encoder);
} }
if (sprite->type == SpriteType::Font && ZOOM_LVL_GUI != ZOOM_LVL_NORMAL) { if (sprite->type == SpriteType::Font && _font_zoom != ZOOM_LVL_NORMAL) {
/* Make ZOOM_LVL_NORMAL be ZOOM_LVL_GUI */ /* Make ZOOM_LVL_NORMAL be ZOOM_LVL_GUI */
sprite[ZOOM_LVL_NORMAL].width = sprite[ZOOM_LVL_GUI].width; sprite[ZOOM_LVL_NORMAL].width = sprite[_font_zoom].width;
sprite[ZOOM_LVL_NORMAL].height = sprite[ZOOM_LVL_GUI].height; sprite[ZOOM_LVL_NORMAL].height = sprite[_font_zoom].height;
sprite[ZOOM_LVL_NORMAL].x_offs = sprite[ZOOM_LVL_GUI].x_offs; sprite[ZOOM_LVL_NORMAL].x_offs = sprite[_font_zoom].x_offs;
sprite[ZOOM_LVL_NORMAL].y_offs = sprite[ZOOM_LVL_GUI].y_offs; sprite[ZOOM_LVL_NORMAL].y_offs = sprite[_font_zoom].y_offs;
sprite[ZOOM_LVL_NORMAL].data = sprite[ZOOM_LVL_GUI].data; sprite[ZOOM_LVL_NORMAL].data = sprite[_font_zoom].data;
sprite[ZOOM_LVL_NORMAL].colours = sprite[ZOOM_LVL_GUI].colours; sprite[ZOOM_LVL_NORMAL].colours = sprite[_font_zoom].colours;
} }
return encoder->Encode(sprite, allocator); return encoder->Encode(sprite, allocator);
@ -1048,4 +1048,17 @@ void GfxClearSpriteCache()
VideoDriver::GetInstance()->ClearSystemSprites(); 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_items; i++) {
SpriteCache *sc = GetSpriteCache(i);
if (sc->type == SpriteType::Font && sc->ptr != nullptr) DeleteEntryFromSpriteCache(i);
}
}
/* static */ ReusableBuffer<SpriteLoader::CommonPixel> SpriteLoader::Sprite::buffer[ZOOM_LVL_COUNT]; /* static */ ReusableBuffer<SpriteLoader::CommonPixel> SpriteLoader::Sprite::buffer[ZOOM_LVL_COUNT];

View File

@ -58,6 +58,7 @@ static inline const byte *GetNonSprite(SpriteID sprite, SpriteType type)
void GfxInitSpriteMem(); void GfxInitSpriteMem();
void GfxClearSpriteCache(); void GfxClearSpriteCache();
void GfxClearFontSpriteCache();
void IncreaseSpriteLRU(); void IncreaseSpriteLRU();
SpriteFile &OpenCachedSpriteFile(const std::string &filename, Subdirectory subdir, bool palette_remap); SpriteFile &OpenCachedSpriteFile(const std::string &filename, Subdirectory subdir, bool palette_remap);

View File

@ -282,11 +282,12 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p
if (sprite_type != SpriteType::MapGen) { if (sprite_type != SpriteType::MapGen) {
if (zoom < lengthof(zoom_lvl_map)) { if (zoom < lengthof(zoom_lvl_map)) {
is_wanted_zoom_lvl = true; is_wanted_zoom_lvl = true;
if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_2X && ZoomLevel zoom_min = sprite_type == SpriteType::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) { 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; 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) { 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; is_wanted_zoom_lvl = false;
} }

View File

@ -52,6 +52,7 @@ extern int _gui_scale;
extern int _gui_scale_cfg; extern int _gui_scale_cfg;
extern ZoomLevel _gui_zoom; extern ZoomLevel _gui_zoom;
extern ZoomLevel _font_zoom;
#define ZOOM_LVL_GUI (_gui_zoom) #define ZOOM_LVL_GUI (_gui_zoom)
static const int MIN_INTERFACE_SCALE = 100; static const int MIN_INTERFACE_SCALE = 100;