Add support for font scaling.

This commit is contained in:
Paul Chote
2016-12-23 20:41:52 +00:00
parent 6599aeb035
commit 5e7c816257
3 changed files with 31 additions and 11 deletions

View File

@@ -29,27 +29,37 @@ namespace OpenRA.Graphics
readonly Face face;
readonly Cache<Pair<char, Color>, 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<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
// PERF: Cache these delegates for Measure calls.
Func<char, float> 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);

View File

@@ -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<T> Keys { get { return cache.Keys; } }
public ICollection<U> Values { get { return cache.Values; } }
public IEnumerator<KeyValuePair<T, U>> GetEnumerator() { return cache.GetEnumerator(); }

View File

@@ -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)