Add support for font scaling.
This commit is contained in:
@@ -29,27 +29,37 @@ namespace OpenRA.Graphics
|
|||||||
readonly Face face;
|
readonly Face face;
|
||||||
readonly Cache<Pair<char, Color>, GlyphInfo> glyphs;
|
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)
|
if (builder.Type != SheetType.BGRA)
|
||||||
throw new ArgumentException("The sheet builder must create BGRA sheets.", "builder");
|
throw new ArgumentException("The sheet builder must create BGRA sheets.", "builder");
|
||||||
|
|
||||||
|
deviceScale = scale;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
|
|
||||||
face = new Face(Library, data, 0);
|
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);
|
glyphs = new Cache<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
|
||||||
|
|
||||||
// PERF: Cache these delegates for Measure calls.
|
// PERF: Cache these delegates for Measure calls.
|
||||||
Func<char, float> characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance;
|
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.White, name);
|
||||||
PrecacheColor(Color.Red, 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)
|
void PrecacheColor(Color c, string name)
|
||||||
{
|
{
|
||||||
using (new PerfTimer("PrecacheColor {0} {1}px {2}".F(name, size, c.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)];
|
var g = glyphs[Pair.New(s, c)];
|
||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(g.Sprite,
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(g.Sprite,
|
||||||
new float2(
|
new float2(
|
||||||
(int)Math.Round(p.X + g.Offset.X, 0),
|
(int)Math.Round(p.X * deviceScale + g.Offset.X, 0) / deviceScale,
|
||||||
p.Y + g.Offset.Y));
|
p.Y + g.Offset.Y / deviceScale),
|
||||||
p.X += g.Advance;
|
g.Sprite.Size / deviceScale);
|
||||||
|
p.X += g.Advance / deviceScale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,10 +96,10 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
{
|
{
|
||||||
DrawText(text, location + new float2(-offset, 0), bg);
|
DrawText(text, location + new float2(-offset / deviceScale, 0), bg);
|
||||||
DrawText(text, location + new float2(offset, 0), bg);
|
DrawText(text, location + new float2(offset / deviceScale, 0), bg);
|
||||||
DrawText(text, location + new float2(0, -offset), bg);
|
DrawText(text, location + new float2(0, -offset / deviceScale), bg);
|
||||||
DrawText(text, location + new float2(0, offset), bg);
|
DrawText(text, location + new float2(0, offset / deviceScale), bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText(text, location, fg);
|
DrawText(text, location, fg);
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ namespace OpenRA.Primitives
|
|||||||
public bool ContainsKey(T key) { return cache.ContainsKey(key); }
|
public bool ContainsKey(T key) { return cache.ContainsKey(key); }
|
||||||
public bool TryGetValue(T key, out U value) { return cache.TryGetValue(key, out value); }
|
public bool TryGetValue(T key, out U value) { return cache.TryGetValue(key, out value); }
|
||||||
public int Count { get { return cache.Count; } }
|
public int Count { get { return cache.Count; } }
|
||||||
|
public void Clear() { cache.Clear(); }
|
||||||
|
|
||||||
public ICollection<T> Keys { get { return cache.Keys; } }
|
public ICollection<T> Keys { get { return cache.Keys; } }
|
||||||
public ICollection<U> Values { get { return cache.Values; } }
|
public ICollection<U> Values { get { return cache.Values; } }
|
||||||
public IEnumerator<KeyValuePair<T, U>> GetEnumerator() { return cache.GetEnumerator(); }
|
public IEnumerator<KeyValuePair<T, U>> GetEnumerator() { return cache.GetEnumerator(); }
|
||||||
|
|||||||
@@ -86,8 +86,15 @@ namespace OpenRA
|
|||||||
fontSheetBuilder.Dispose();
|
fontSheetBuilder.Dispose();
|
||||||
fontSheetBuilder = new SheetBuilder(SheetType.BGRA);
|
fontSheetBuilder = new SheetBuilder(SheetType.BGRA);
|
||||||
Fonts = modData.Manifest.Fonts.ToDictionary(x => x.Key,
|
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)
|
public void InitializeDepthBuffer(MapGrid mapGrid)
|
||||||
|
|||||||
Reference in New Issue
Block a user