Scale OSD text according to display scale

fixes #2605
This commit is contained in:
CasualPokePlayer 2024-06-07 23:00:07 -07:00
parent ffa5bb9b74
commit e8c957a7a8
7 changed files with 79 additions and 62 deletions

View File

@ -1,5 +1,5 @@
//http://www.angelcode.com/products/bmfont/
//http://cyotek.com/blog/angelcode-bitmap-font-parsing-using-csharp
// https://www.angelcode.com/products/bmfont/
// https://devblog.cyotek.com/post/angelcode-bitmap-font-parsing-using-csharp
using System;
using System.Collections.Generic;
@ -19,10 +19,24 @@ namespace BizHawk.Bizware.Graphics
FontInfo.LoadXml(xml);
// load textures
for (var i=0; i<FontInfo.Pages.Length; i++)
for (var i = 0; i < FontInfo.Pages.Length; i++)
{
TexturePages.Add(owner.LoadTexture(textures[i]));
}
// precalc texcoords
foreach (var bfc in FontInfo)
{
var tex = TexturePages[bfc.TexturePage];
var w = (float)tex.Width;
var h = (float)tex.Height;
var bounds = new Rectangle(bfc.X, bfc.Y, bfc.Width, bfc.Height);
var u0 = bounds.Left / w;
var v0 = bounds.Top / h;
var u1 = bounds.Right / w;
var v1 = bounds.Bottom / h;
CharTexCoords.Add(bfc.Char, new(u0, v0, u1, v1));
}
}
public void Dispose()
@ -35,10 +49,10 @@ namespace BizHawk.Bizware.Graphics
TexturePages = null;
}
public SizeF Measure(string str)
public SizeF Measure(string str, int scale)
{
float x = 0;
float y = FontInfo.LineHeight;
float y = FontInfo.LineHeight * scale;
var ox = x;
var len = str.Length;
@ -67,18 +81,18 @@ namespace BizHawk.Bizware.Graphics
}
x = 0;
y += FontInfo.LineHeight;
y += FontInfo.LineHeight * scale;
continue;
}
var bfc = FontInfo[c];
x += bfc.XAdvance;
x += bfc.XAdvance * scale;
}
return new(Math.Max(x, ox), y);
}
public void RenderString(IGuiRenderer renderer, float x, float y, string str)
public void RenderString(IGuiRenderer renderer, float x, float y, string str, int scale)
{
if (Owner != renderer.Owner)
{
@ -108,33 +122,28 @@ namespace BizHawk.Bizware.Graphics
if (c == '\n')
{
x = ox;
y += FontInfo.LineHeight;
y += FontInfo.LineHeight * scale;
continue;
}
var bfc = FontInfo[c];
// calculate texcoords (we shouldve already had this cached, but im speedcoding now)
var tex = TexturePages[bfc.TexturePage];
var w = (float)tex.Width;
var h = (float)tex.Height;
var bounds = new Rectangle(bfc.X, bfc.Y, bfc.Width, bfc.Height);
var u0 = bounds.Left / w;
var v0 = bounds.Top / h;
var u1 = bounds.Right / w;
var v1 = bounds.Bottom / h;
var gx = x + bfc.XOffset * scale;
var gy = y + bfc.YOffset * scale;
var charTexCoords = CharTexCoords[bfc.Char];
renderer.DrawSubrect(tex, gx, gy, bfc.Width * scale, bfc.Height * scale,
charTexCoords.U0, charTexCoords.V0, charTexCoords.U1, charTexCoords.V1);
var gx = x + bfc.XOffset;
var gy = y + bfc.YOffset;
renderer.DrawSubrect(tex, gx, gy, bfc.Width, bfc.Height, u0, v0, u1, v1);
x += bfc.XAdvance;
x += bfc.XAdvance * scale;
}
}
public IGL Owner { get; }
private readonly BitmapFont FontInfo;
private List<ITexture2D> TexturePages = new();
private List<ITexture2D> TexturePages = [ ];
private readonly Dictionary<char, TexCoords> CharTexCoords = [ ];
private record TexCoords(float U0, float V0, float U1, float V1);
}
}

View File

@ -440,6 +440,8 @@ namespace BizHawk.Client.Common
protected abstract Size GetGraphicsControlSize();
protected abstract int GetGraphicsControlDpi();
/// <summary>
/// This will receive an emulated output frame from an IVideoProvider and run it through the complete frame processing pipeline
/// Then it will stuff it into the bound PresentationPanel.
@ -811,6 +813,8 @@ namespace BizHawk.Client.Common
filterProgram.GuiRenderer = _renderer;
filterProgram.GL = _gl;
filterProgram.ControlDpi = GetGraphicsControlDpi();
//setup the source image filter
var fInput = (SourceImage)filterProgram["input"];
fInput.Texture = videoTexture;

View File

@ -71,6 +71,10 @@ namespace BizHawk.Client.Common.FilterManager
public IRenderTarget CurrRenderTarget;
// DPI / 96.0 indicates the display scaling
// this is mainly relevant for OSD
public int ControlDpi;
public IRenderTarget GetTempTarget(int width, int height)
{
return RenderTargetProvider.Get(new(width, height));

View File

@ -613,9 +613,10 @@ namespace BizHawk.Client.Common.Filters
}
var size = FindInput().SurfaceFormat.Size;
FilterProgram.GuiRenderer.Begin(size.Width, size.Height);
var blitter = new OSDBlitter(_font, FilterProgram.GuiRenderer, new(0, 0, size.Width, size.Height));
var scale = (int)Math.Round(FilterProgram.ControlDpi / 96.0f);
var blitter = new OSDBlitter(_font, FilterProgram.GuiRenderer, new(0, 0, size.Width, size.Height), scale);
FilterProgram.GuiRenderer.EnableBlending();
_manager.DrawScreenInfo(blitter);
_manager.DrawMessages(blitter);
@ -627,24 +628,27 @@ namespace BizHawk.Client.Common.Filters
private readonly StringRenderer _font;
private readonly IGuiRenderer _renderer;
public OSDBlitter(StringRenderer font, IGuiRenderer renderer, Rectangle clipBounds)
public OSDBlitter(StringRenderer font, IGuiRenderer renderer, Rectangle clipBounds, int scale)
{
_font = font;
_renderer = renderer;
ClipBounds = clipBounds;
Scale = scale;
}
public void DrawString(string s, Color color, float x, float y)
{
_renderer.SetModulateColor(color);
_font.RenderString(_renderer, x, y, s);
_font.RenderString(_renderer, x, y, s, Scale);
_renderer.SetModulateColorWhite();
}
public SizeF MeasureString(string s)
=> _font.Measure(s);
=> _font.Measure(s, Scale);
public Rectangle ClipBounds { get; }
public int Scale { get; }
}
}
}

View File

@ -14,5 +14,7 @@ namespace BizHawk.Client.Common
SizeF MeasureString(string s);
Rectangle ClipBounds { get; }
public int Scale { get; }
}
}

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
@ -36,17 +37,18 @@ namespace BizHawk.Client.Common
public Color FixedMessagesColor => Color.FromArgb(_config.MessagesColor);
public Color FixedAlertMessageColor => Color.FromArgb(_config.AlertMessageColor);
private PointF GetCoordinates(IBlitter g, MessagePosition position, string message)
private static PointF GetCoordinates(IBlitter g, MessagePosition position, string message)
{
var size = g.MeasureString(message);
float x = position.Anchor.IsLeft()
var x = position.Anchor.IsLeft()
? position.X
: g.ClipBounds.Width - position.X - size.Width;
float y = position.Anchor.IsTop()
var y = position.Anchor.IsTop()
? position.Y
: g.ClipBounds.Height - position.Y - size.Height;
return new PointF(x, y);
}
@ -78,9 +80,9 @@ namespace BizHawk.Client.Common
return _emulator.Frame.ToString();
}
private readonly List<UIMessage> _messages = new List<UIMessage>(5);
private readonly List<UIDisplay> _guiTextList = new List<UIDisplay>();
private readonly List<UIDisplay> _ramWatchList = new List<UIDisplay>();
private readonly List<UIMessage> _messages = new(5);
private readonly List<UIDisplay> _guiTextList = [ ];
private readonly List<UIDisplay> _ramWatchList = [ ];
public void AddMessage(string message, int? duration = null)
=> _messages.Add(new() {
@ -89,9 +91,7 @@ namespace BizHawk.Client.Common
});
public void ClearRamWatches()
{
_ramWatchList.Clear();
}
=> _ramWatchList.Clear();
public void AddRamWatch(string message, MessagePosition pos, Color backGround, Color foreColor)
{
@ -116,9 +116,7 @@ namespace BizHawk.Client.Common
}
public void ClearGuiText()
{
_guiTextList.Clear();
}
=> _guiTextList.Clear();
private void DrawMessage(IBlitter g, UIMessage message, int yOffset)
{
@ -140,10 +138,10 @@ namespace BizHawk.Client.Common
{
if (_config.StackOSDMessages)
{
int line = 1;
for (int i = _messages.Count - 1; i >= 0; i--, line++)
var line = 1;
for (var i = _messages.Count - 1; i >= 0; i--, line++)
{
int yOffset = (line - 1) * 18;
var yOffset = (line - 1) * 18 * g.Scale;
if (!_config.Messages.Anchor.IsTop())
{
yOffset = 0 - yOffset;
@ -154,7 +152,7 @@ namespace BizHawk.Client.Common
}
else
{
var message = _messages[_messages.Count - 1];
var message = _messages[^1];
DrawMessage(g, message, 0);
}
}
@ -175,14 +173,10 @@ namespace BizHawk.Client.Common
}
public string InputStrMovie()
{
return MakeStringFor(_movieSession.MovieController, cache: true);
}
=> MakeStringFor(_movieSession.MovieController, cache: true);
public string InputStrImmediate()
{
return MakeStringFor(_inputManager.AutofireStickyXorAdapter, cache: true);
}
=> MakeStringFor(_inputManager.AutofireStickyXorAdapter, cache: true);
public string InputPrevious()
{
@ -235,10 +229,8 @@ namespace BizHawk.Client.Common
: "";
}
private void DrawOsdMessage(IBlitter g, string message, Color color, float x, float y)
{
g.DrawString(message, color, x, y);
}
private static void DrawOsdMessage(IBlitter g, string message, Color color, float x, float y)
=> g.DrawString(message, color, x, y);
/// <summary>
/// Display all screen info objects like fps, frame counter, lag counter, and input display
@ -247,7 +239,7 @@ namespace BizHawk.Client.Common
{
if (_config.DisplayFrameCounter && !_emulator.IsNull())
{
string message = MakeFrameCounter();
var message = MakeFrameCounter();
var point = GetCoordinates(g, _config.FrameCounter, message);
DrawOsdMessage(g, message, Color.FromArgb(_config.MessagesColor), point.X, point.Y);
@ -266,14 +258,14 @@ namespace BizHawk.Client.Common
{
var input = InputStrMovie();
var point = GetCoordinates(g, _config.InputDisplay, input);
Color c = Color.FromArgb(_config.MovieInput);
var c = Color.FromArgb(_config.MovieInput);
g.DrawString(input, c, point.X, point.Y);
}
if (!moviePlaying) // TODO: message config -- allow setting of "mixed", and "auto"
{
var previousColor = Color.FromArgb(_config.LastInputColor);
Color immediateColor = Color.FromArgb(_config.MessagesColor);
var immediateColor = Color.FromArgb(_config.MessagesColor);
var autoColor = Color.Pink;
var changedColor = Color.PeachPuff;
@ -325,7 +317,7 @@ namespace BizHawk.Client.Common
if (_config.DisplayRerecordCount)
{
string rerecordCount = MakeRerecordCount();
var rerecordCount = MakeRerecordCount();
var point = GetCoordinates(g, _config.ReRecordCounter, rerecordCount);
DrawOsdMessage(g, rerecordCount, FixedMessagesColor, point.X, point.Y);
}
@ -334,12 +326,12 @@ namespace BizHawk.Client.Common
{
var sb = new StringBuilder("Held: ");
foreach (string sticky in _inputManager.StickyXorAdapter.CurrentStickies)
foreach (var sticky in _inputManager.StickyXorAdapter.CurrentStickies)
{
sb.Append(sticky).Append(' ');
}
foreach (string autoSticky in _inputManager.AutofireStickyXorAdapter.CurrentStickies)
foreach (var autoSticky in _inputManager.AutofireStickyXorAdapter.CurrentStickies)
{
sb
.Append("Auto-")

View File

@ -51,6 +51,8 @@ namespace BizHawk.Client.EmuHawk
public override Size GetPanelNativeSize() => _presentationPanel.NativeSize;
protected override int GetGraphicsControlDpi() => _graphicsControl.DeviceDpi;
protected override Point GraphicsControlPointToClient(Point p) => _graphicsControl.PointToClient(p);
protected override void SwapBuffersOfGraphicsControl() => _graphicsControl.SwapBuffers();