Move FreeType handling into the Platform dll.
This commit is contained in:
4
Makefile
4
Makefile
@@ -102,7 +102,7 @@ endif
|
||||
game_SRCS := $(shell find OpenRA.Game/ -iname '*.cs')
|
||||
game_TARGET = OpenRA.Game.exe
|
||||
game_KIND = winexe
|
||||
game_LIBS = $(COMMON_LIBS) $(game_DEPS) thirdparty/download/SharpFont.dll thirdparty/download/Open.Nat.dll
|
||||
game_LIBS = $(COMMON_LIBS) $(game_DEPS) thirdparty/download/Open.Nat.dll
|
||||
PROGRAMS += game
|
||||
game: $(game_TARGET)
|
||||
|
||||
@@ -111,7 +111,7 @@ pdefault_SRCS := $(shell find OpenRA.Platforms.Default/ -iname '*.cs')
|
||||
pdefault_TARGET = OpenRA.Platforms.Default.dll
|
||||
pdefault_KIND = library
|
||||
pdefault_DEPS = $(game_TARGET)
|
||||
pdefault_LIBS = $(COMMON_LIBS) thirdparty/download/SDL2-CS.dll thirdparty/download/OpenAL-CS.dll $(pdefault_DEPS)
|
||||
pdefault_LIBS = $(COMMON_LIBS) thirdparty/download/SDL2-CS.dll thirdparty/download/OpenAL-CS.dll thirdparty/download/SharpFont.dll $(pdefault_DEPS)
|
||||
PROGRAMS += pdefault
|
||||
platforms: $(pdefault_TARGET)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace OpenRA
|
||||
{
|
||||
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, int batchSize);
|
||||
ISoundEngine CreateSound(string device);
|
||||
IFont CreateFont(byte[] data);
|
||||
}
|
||||
|
||||
public interface IHardwareCursor : IDisposable { }
|
||||
@@ -129,4 +130,17 @@ namespace OpenRA
|
||||
Fullscreen,
|
||||
PseudoFullscreen,
|
||||
}
|
||||
|
||||
public interface IFont : IDisposable
|
||||
{
|
||||
FontGlyph CreateGlyph(char c, int size, float deviceScale);
|
||||
}
|
||||
|
||||
public struct FontGlyph
|
||||
{
|
||||
public int2 Offset;
|
||||
public Size Size;
|
||||
public float Advance;
|
||||
public byte[] Data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,18 +14,15 @@ using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Support;
|
||||
using OpenRA.Widgets;
|
||||
using SharpFont;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public sealed class SpriteFont : IDisposable
|
||||
{
|
||||
static readonly Library Library = new Library();
|
||||
|
||||
readonly int size;
|
||||
readonly SheetBuilder builder;
|
||||
readonly Func<string, float> lineWidth;
|
||||
readonly Face face;
|
||||
readonly IFont font;
|
||||
readonly Cache<Pair<char, Color>, GlyphInfo> glyphs;
|
||||
|
||||
float deviceScale;
|
||||
@@ -39,8 +36,7 @@ namespace OpenRA.Graphics
|
||||
this.size = size;
|
||||
this.builder = builder;
|
||||
|
||||
face = new Face(Library, data, 0);
|
||||
face.SetPixelSizes((uint)(size * deviceScale), (uint)(size * deviceScale));
|
||||
font = Game.Renderer.CreateFont(data);
|
||||
|
||||
glyphs = new Cache<Pair<char, Color>, GlyphInfo>(CreateGlyph, Pair<char, Color>.EqualityComparer);
|
||||
|
||||
@@ -55,7 +51,6 @@ namespace OpenRA.Graphics
|
||||
public void SetScale(float scale)
|
||||
{
|
||||
deviceScale = scale;
|
||||
face.SetPixelSizes((uint)(size * deviceScale), (uint)(size * deviceScale));
|
||||
glyphs.Clear();
|
||||
}
|
||||
|
||||
@@ -136,11 +131,9 @@ namespace OpenRA.Graphics
|
||||
|
||||
GlyphInfo CreateGlyph(Pair<char, Color> c)
|
||||
{
|
||||
try
|
||||
{
|
||||
face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal);
|
||||
}
|
||||
catch (FreeTypeException)
|
||||
var glyph = font.CreateGlyph(c.First, this.size, deviceScale);
|
||||
|
||||
if (glyph.Data == null)
|
||||
{
|
||||
return new GlyphInfo
|
||||
{
|
||||
@@ -150,44 +143,31 @@ namespace OpenRA.Graphics
|
||||
};
|
||||
}
|
||||
|
||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||
|
||||
var size = new Size((int)face.Glyph.Metrics.Width, (int)face.Glyph.Metrics.Height);
|
||||
var s = builder.Allocate(size);
|
||||
|
||||
var s = builder.Allocate(glyph.Size);
|
||||
var g = new GlyphInfo
|
||||
{
|
||||
Sprite = s,
|
||||
Advance = (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||
Offset = new int2(face.Glyph.BitmapLeft, -face.Glyph.BitmapTop)
|
||||
Advance = glyph.Advance,
|
||||
Offset = glyph.Offset
|
||||
};
|
||||
|
||||
// A new bitmap is generated each time this property is accessed, so we do need to dispose it.
|
||||
using (var bitmap = face.Glyph.Bitmap)
|
||||
var dest = s.Sheet.GetData();
|
||||
var destStride = s.Sheet.Size.Width * 4;
|
||||
|
||||
for (var j = 0; j < s.Size.Y; j++)
|
||||
{
|
||||
unsafe
|
||||
for (var i = 0; i < s.Size.X; i++)
|
||||
{
|
||||
var p = (byte*)bitmap.Buffer;
|
||||
var dest = s.Sheet.GetData();
|
||||
var destStride = s.Sheet.Size.Width * 4;
|
||||
|
||||
for (var j = 0; j < s.Size.Y; j++)
|
||||
var p = glyph.Data[j * glyph.Size.Width + i];
|
||||
if (p != 0)
|
||||
{
|
||||
for (var i = 0; i < s.Size.X; i++)
|
||||
{
|
||||
if (p[i] != 0)
|
||||
{
|
||||
var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
|
||||
var pmc = Util.PremultiplyAlpha(Color.FromArgb(p[i], c.Second));
|
||||
var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left);
|
||||
var pmc = Util.PremultiplyAlpha(Color.FromArgb(p, c.Second));
|
||||
|
||||
dest[q] = pmc.B;
|
||||
dest[q + 1] = pmc.G;
|
||||
dest[q + 2] = pmc.R;
|
||||
dest[q + 3] = pmc.A;
|
||||
}
|
||||
}
|
||||
|
||||
p += bitmap.Pitch;
|
||||
dest[q] = pmc.B;
|
||||
dest[q + 1] = pmc.G;
|
||||
dest[q + 2] = pmc.R;
|
||||
dest[q + 3] = pmc.A;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,7 +179,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
face.Dispose();
|
||||
font.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,11 +76,6 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="SharpFont">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\thirdparty\download\SharpFont.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Open.Nat">
|
||||
<HintPath>..\thirdparty\download\Open.Nat.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace OpenRA
|
||||
readonly Stack<Rectangle> scissorState = new Stack<Rectangle>();
|
||||
|
||||
SheetBuilder fontSheetBuilder;
|
||||
readonly IPlatform platform;
|
||||
|
||||
float depthScale;
|
||||
float depthOffset;
|
||||
@@ -51,6 +52,7 @@ namespace OpenRA
|
||||
|
||||
public Renderer(IPlatform platform, GraphicSettings graphicSettings)
|
||||
{
|
||||
this.platform = platform;
|
||||
var resolution = GetResolution(graphicSettings);
|
||||
|
||||
Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height), graphicSettings.Mode, graphicSettings.BatchSize);
|
||||
@@ -290,5 +292,10 @@ namespace OpenRA
|
||||
{
|
||||
get { return Context.GLVersion; }
|
||||
}
|
||||
|
||||
public IFont CreateFont(byte[] data)
|
||||
{
|
||||
return platform.CreateFont(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,5 +24,10 @@ namespace OpenRA.Platforms.Default
|
||||
{
|
||||
return new OpenAlSoundEngine(device);
|
||||
}
|
||||
|
||||
public IFont CreateFont(byte[] data)
|
||||
{
|
||||
return new FreeTypeFont(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
83
OpenRA.Platforms.Default/FreeTypeFont.cs
Normal file
83
OpenRA.Platforms.Default/FreeTypeFont.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Primitives;
|
||||
using SharpFont;
|
||||
|
||||
namespace OpenRA.Platforms.Default
|
||||
{
|
||||
public sealed class FreeTypeFont : IFont
|
||||
{
|
||||
static readonly Library Library = new Library();
|
||||
readonly Face face;
|
||||
|
||||
public FreeTypeFont(byte[] data)
|
||||
{
|
||||
face = new Face(Library, data, 0);
|
||||
}
|
||||
|
||||
public FontGlyph CreateGlyph(char c, int size, float deviceScale)
|
||||
{
|
||||
try
|
||||
{
|
||||
var scaledSize = (uint) (size * deviceScale);
|
||||
face.SetPixelSizes(scaledSize, scaledSize);
|
||||
|
||||
face.LoadChar(c, LoadFlags.Default, LoadTarget.Normal);
|
||||
face.Glyph.RenderGlyph(RenderMode.Normal);
|
||||
|
||||
var glyphSize = new Size((int)face.Glyph.Metrics.Width, (int)face.Glyph.Metrics.Height);
|
||||
|
||||
var g = new FontGlyph
|
||||
{
|
||||
Advance = (float)face.Glyph.Metrics.HorizontalAdvance,
|
||||
Offset = new int2(face.Glyph.BitmapLeft, -face.Glyph.BitmapTop),
|
||||
Size = glyphSize,
|
||||
Data = new byte[glyphSize.Width * glyphSize.Height]
|
||||
};
|
||||
|
||||
// A new bitmap is generated each time this property is accessed, so we do need to dispose it.
|
||||
using (var bitmap = face.Glyph.Bitmap)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
var p = (byte*)bitmap.Buffer;
|
||||
var k = 0;
|
||||
for (var j = 0; j < glyphSize.Height; j++)
|
||||
{
|
||||
for (var i = 0; i < glyphSize.Width; i++)
|
||||
g.Data[k++] = p[i];
|
||||
|
||||
p += bitmap.Pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
catch (FreeTypeException)
|
||||
{
|
||||
return new FontGlyph
|
||||
{
|
||||
Offset = int2.Zero,
|
||||
Size = new Size(0, 0),
|
||||
Advance = 0,
|
||||
Data = null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
face.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,11 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="SharpFont">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\thirdparty\download\SharpFont.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Eluant">
|
||||
<HintPath>..\thirdparty\download\Eluant.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -45,6 +50,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DefaultPlatform.cs" />
|
||||
<Compile Include="FreeTypeFont.cs" />
|
||||
<Compile Include="Sdl2PlatformWindow.cs" />
|
||||
<Compile Include="ITextureInternal.cs" />
|
||||
<Compile Include="Sdl2Input.cs" />
|
||||
|
||||
Reference in New Issue
Block a user