diff --git a/OpenRA.Game/Graphics/SpriteFont.cs b/OpenRA.Game/Graphics/SpriteFont.cs index 77dda6180c..5a67268cc3 100644 --- a/OpenRA.Game/Graphics/SpriteFont.cs +++ b/OpenRA.Game/Graphics/SpriteFont.cs @@ -29,27 +29,37 @@ namespace OpenRA.Graphics readonly Face face; readonly Cache, GlyphInfo> glyphs; - public SpriteFont(string name, byte[] data, int size, SheetBuilder builder) + float deviceScale; + + public SpriteFont(string name, byte[] data, int size, float scale, SheetBuilder builder) { if (builder.Type != SheetType.BGRA) throw new ArgumentException("The sheet builder must create BGRA sheets.", "builder"); + deviceScale = scale; this.size = size; this.builder = builder; face = new Face(Library, data, 0); - face.SetPixelSizes((uint)size, (uint)size); + face.SetPixelSizes((uint)(size * deviceScale), (uint)(size * deviceScale)); glyphs = new Cache, GlyphInfo>(CreateGlyph, Pair.EqualityComparer); // PERF: Cache these delegates for Measure calls. Func characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance; - lineWidth = line => line.Sum(characterWidth); + lineWidth = line => line.Sum(characterWidth) / deviceScale; PrecacheColor(Color.White, name); PrecacheColor(Color.Red, name); } + public void SetScale(float scale) + { + deviceScale = scale; + face.SetPixelSizes((uint)(size * deviceScale), (uint)(size * deviceScale)); + glyphs.Clear(); + } + void PrecacheColor(Color c, string name) { using (new PerfTimer("PrecacheColor {0} {1}px {2}".F(name, size, c.Name))) @@ -75,9 +85,10 @@ namespace OpenRA.Graphics var g = glyphs[Pair.New(s, c)]; Game.Renderer.RgbaSpriteRenderer.DrawSprite(g.Sprite, new float2( - (int)Math.Round(p.X + g.Offset.X, 0), - p.Y + g.Offset.Y)); - p.X += g.Advance; + (int)Math.Round(p.X * deviceScale + g.Offset.X, 0) / deviceScale, + p.Y + g.Offset.Y / deviceScale), + g.Sprite.Size / deviceScale); + p.X += g.Advance / deviceScale; } } @@ -85,10 +96,10 @@ namespace OpenRA.Graphics { if (offset > 0) { - DrawText(text, location + new float2(-offset, 0), bg); - DrawText(text, location + new float2(offset, 0), bg); - DrawText(text, location + new float2(0, -offset), bg); - DrawText(text, location + new float2(0, offset), bg); + DrawText(text, location + new float2(-offset / deviceScale, 0), bg); + DrawText(text, location + new float2(offset / deviceScale, 0), bg); + DrawText(text, location + new float2(0, -offset / deviceScale), bg); + DrawText(text, location + new float2(0, offset / deviceScale), bg); } DrawText(text, location, fg); diff --git a/OpenRA.Game/Primitives/Cache.cs b/OpenRA.Game/Primitives/Cache.cs index 700991cc73..d162374b80 100644 --- a/OpenRA.Game/Primitives/Cache.cs +++ b/OpenRA.Game/Primitives/Cache.cs @@ -39,6 +39,8 @@ namespace OpenRA.Primitives public bool ContainsKey(T key) { return cache.ContainsKey(key); } public bool TryGetValue(T key, out U value) { return cache.TryGetValue(key, out value); } public int Count { get { return cache.Count; } } + public void Clear() { cache.Clear(); } + public ICollection Keys { get { return cache.Keys; } } public ICollection Values { get { return cache.Values; } } public IEnumerator> GetEnumerator() { return cache.GetEnumerator(); } diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index db29ea8543..fdddfbd0b2 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -86,8 +86,15 @@ namespace OpenRA fontSheetBuilder.Dispose(); fontSheetBuilder = new SheetBuilder(SheetType.BGRA); Fonts = modData.Manifest.Fonts.ToDictionary(x => x.Key, - x => new SpriteFont(x.Value.First, modData.DefaultFileSystem.Open(x.Value.First).ReadAllBytes(), x.Value.Second, Device.WindowScale, fontSheetBuilder)).AsReadOnly(); + x => new SpriteFont(x.Value.First, modData.DefaultFileSystem.Open(x.Value.First).ReadAllBytes(), + x.Value.Second, Device.WindowScale, fontSheetBuilder)).AsReadOnly(); } + + Device.OnWindowScaleChanged += (before, after) => + { + foreach (var f in Fonts) + f.Value.SetScale(after); + }; } public void InitializeDepthBuffer(MapGrid mapGrid)