diff --git a/OpenRA.Game/Graphics/Renderer.cs b/OpenRA.Game/Graphics/Renderer.cs index 04133779ab..6880fa30df 100644 --- a/OpenRA.Game/Graphics/Renderer.cs +++ b/OpenRA.Game/Graphics/Renderer.cs @@ -37,6 +37,8 @@ namespace OpenRA.Graphics readonly Queue> tempBuffers = new Queue>(); readonly Stack scissorState = new Stack(); + SheetBuilder fontSheetBuilder; + Size? lastResolution; int2? lastScroll; float? lastZoom; @@ -94,8 +96,13 @@ namespace OpenRA.Graphics public void InitializeFonts(Manifest m) { using (new Support.PerfTimer("SpriteFonts")) + { + if (fontSheetBuilder != null) + fontSheetBuilder.Dispose(); + fontSheetBuilder = new SheetBuilder(SheetType.BGRA); Fonts = m.Fonts.ToDictionary(x => x.Key, - x => new SpriteFont(Platform.ResolvePath(x.Value.First), x.Value.Second)).AsReadOnly(); + x => new SpriteFont(Platform.ResolvePath(x.Value.First), x.Value.Second, fontSheetBuilder)).AsReadOnly(); + } } public void BeginFrame(int2 scroll, float zoom) @@ -246,6 +253,8 @@ namespace OpenRA.Graphics foreach (var buffer in tempBuffers) buffer.Dispose(); tempBuffers.Clear(); + if (fontSheetBuilder != null) + fontSheetBuilder.Dispose(); } } } diff --git a/OpenRA.Game/Graphics/SheetBuilder.cs b/OpenRA.Game/Graphics/SheetBuilder.cs index 10644f58fc..5817f91f53 100644 --- a/OpenRA.Game/Graphics/SheetBuilder.cs +++ b/OpenRA.Game/Graphics/SheetBuilder.cs @@ -31,8 +31,8 @@ namespace OpenRA.Graphics public sealed class SheetBuilder : IDisposable { + public readonly SheetType Type; readonly List sheets = new List(); - readonly SheetType type; readonly Func allocateSheet; Sheet current; @@ -54,7 +54,7 @@ namespace OpenRA.Graphics public SheetBuilder(SheetType t, Func allocateSheet) { channel = TextureChannel.Red; - type = t; + Type = t; current = allocateSheet(); sheets.Add(current); this.allocateSheet = allocateSheet; @@ -93,7 +93,7 @@ namespace OpenRA.Graphics TextureChannel? NextChannel(TextureChannel t) { - var nextChannel = (int)t + (int)type; + var nextChannel = (int)t + (int)Type; if (nextChannel > (int)TextureChannel.Alpha) return null; diff --git a/OpenRA.Game/Graphics/SpriteFont.cs b/OpenRA.Game/Graphics/SpriteFont.cs index af409a0910..b2d1905448 100644 --- a/OpenRA.Game/Graphics/SpriteFont.cs +++ b/OpenRA.Game/Graphics/SpriteFont.cs @@ -19,26 +19,27 @@ namespace OpenRA.Graphics { public class SpriteFont { - static Library library = new Library(); - static SheetBuilder builder; + static readonly Library Library = new Library(); readonly int size; - + readonly SheetBuilder builder; readonly Func lineWidth; + readonly Face face; + readonly Cache, GlyphInfo> glyphs; - public SpriteFont(string name, int size) + public SpriteFont(string name, int size, SheetBuilder builder) { - this.size = size; + if (builder.Type != SheetType.BGRA) + throw new ArgumentException("The sheet builder must create BGRA sheets.", "builder"); - face = new Face(library, name); + this.size = size; + this.builder = builder; + + face = new Face(Library, name); face.SetPixelSizes((uint)size, (uint)size); glyphs = new Cache, GlyphInfo>(CreateGlyph, Pair.EqualityComparer); - // setup a SheetBuilder for our private use - // TODO: SheetBuilder state is leaked between mod switches - if (builder == null) - builder = new SheetBuilder(SheetType.BGRA); Func characterWidth = character => glyphs[Pair.New(character, Color.White)].Advance; lineWidth = line => line.Sum(characterWidth); @@ -96,9 +97,6 @@ namespace OpenRA.Graphics return new int2((int)Math.Ceiling(lines.Max(lineWidth)), lines.Length * size); } - Cache, GlyphInfo> glyphs; - Face face; - GlyphInfo CreateGlyph(Pair c) { face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal);