Calculate font size correctly
This commit is contained in:
@@ -133,7 +133,9 @@ namespace OpenRA
|
|||||||
|
|
||||||
public interface IFont : IDisposable
|
public interface IFont : IDisposable
|
||||||
{
|
{
|
||||||
FontGlyph CreateGlyph(char c, int size, float deviceScale);
|
FontGlyph CreateGlyph(char c);
|
||||||
|
void SetSize(int size, float deviceScale);
|
||||||
|
int Height { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct FontGlyph
|
public struct FontGlyph
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
public sealed class SpriteFont : IDisposable
|
public sealed class SpriteFont : IDisposable
|
||||||
{
|
{
|
||||||
|
public int TopOffset { get; private set; }
|
||||||
readonly int size;
|
readonly int size;
|
||||||
readonly SheetBuilder builder;
|
readonly SheetBuilder builder;
|
||||||
readonly Func<string, float> lineWidth;
|
readonly Func<string, float> lineWidth;
|
||||||
@@ -37,6 +38,7 @@ namespace OpenRA.Graphics
|
|||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
|
|
||||||
font = Game.Renderer.CreateFont(data);
|
font = Game.Renderer.CreateFont(data);
|
||||||
|
font.SetSize(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);
|
||||||
|
|
||||||
@@ -46,12 +48,18 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
if (size <= 24)
|
if (size <= 24)
|
||||||
PrecacheColor(Color.White, name);
|
PrecacheColor(Color.White, name);
|
||||||
|
|
||||||
|
TopOffset = size - font.Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetScale(float scale)
|
public void SetScale(float scale)
|
||||||
{
|
{
|
||||||
deviceScale = scale;
|
deviceScale = scale;
|
||||||
|
|
||||||
|
font.SetSize(size, scale);
|
||||||
glyphs.Clear();
|
glyphs.Clear();
|
||||||
|
|
||||||
|
TopOffset = size - font.Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrecacheColor(Color c, string name)
|
void PrecacheColor(Color c, string name)
|
||||||
@@ -131,7 +139,7 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
GlyphInfo CreateGlyph(Pair<char, Color> c)
|
GlyphInfo CreateGlyph(Pair<char, Color> c)
|
||||||
{
|
{
|
||||||
var glyph = font.CreateGlyph(c.First, this.size, deviceScale);
|
var glyph = font.CreateGlyph(c.First);
|
||||||
|
|
||||||
if (glyph.Data == null)
|
if (glyph.Data == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ namespace OpenRA.Platforms.Default
|
|||||||
internal const int FT_LOAD_RENDER = 0x04;
|
internal const int FT_LOAD_RENDER = 0x04;
|
||||||
|
|
||||||
internal static readonly int FaceRecGlyphOffset = IntPtr.Size == 8 ? 152 : 84; // offsetof(FT_FaceRec, glyph)
|
internal static readonly int FaceRecGlyphOffset = IntPtr.Size == 8 ? 152 : 84; // offsetof(FT_FaceRec, glyph)
|
||||||
|
internal static readonly int FaceRecSizeOffset = IntPtr.Size == 8 ? 160 : 88; // offsetof(FT_FaceRec, size)
|
||||||
|
internal static readonly int SizeRecMetricsOffset = IntPtr.Size == 8 ? 24 : 12; // offsetof(FT_SizeRec, metrics)
|
||||||
|
internal static readonly int SizeMetricsAscenderOffset = IntPtr.Size == 8 ? 24 : 12; // offsetof(FT_Size_Metrics, ascender)
|
||||||
|
internal static readonly int SizeMetricsDescenderOffset = IntPtr.Size == 8 ? 32 : 16; // offsetof(FT_Size_Metrics, descender)
|
||||||
|
|
||||||
internal static readonly int GlyphSlotMetricsOffset = IntPtr.Size == 8 ? 48 : 24; // offsetof(FT_GlyphSlotRec, metrics)
|
internal static readonly int GlyphSlotMetricsOffset = IntPtr.Size == 8 ? 48 : 24; // offsetof(FT_GlyphSlotRec, metrics)
|
||||||
internal static readonly int GlyphSlotBitmapOffset = IntPtr.Size == 8 ? 152 : 76; // offsetof(FT_GlyphSlotRec, bitmap)
|
internal static readonly int GlyphSlotBitmapOffset = IntPtr.Size == 8 ? 152 : 76; // offsetof(FT_GlyphSlotRec, bitmap)
|
||||||
internal static readonly int GlyphSlotBitmapLeftOffset = IntPtr.Size == 8 ? 192 : 100; // offsetof(FT_GlyphSlotRec, bitmap_left)
|
internal static readonly int GlyphSlotBitmapLeftOffset = IntPtr.Size == 8 ? 192 : 100; // offsetof(FT_GlyphSlotRec, bitmap_left)
|
||||||
@@ -68,6 +73,8 @@ namespace OpenRA.Platforms.Default
|
|||||||
readonly IntPtr face;
|
readonly IntPtr face;
|
||||||
bool disposed;
|
bool disposed;
|
||||||
|
|
||||||
|
public int Height { get; private set; }
|
||||||
|
|
||||||
public FreeTypeFont(byte[] data)
|
public FreeTypeFont(byte[] data)
|
||||||
{
|
{
|
||||||
if (library == IntPtr.Zero && FreeType.FT_Init_FreeType(out library) != FreeType.OK)
|
if (library == IntPtr.Zero && FreeType.FT_Init_FreeType(out library) != FreeType.OK)
|
||||||
@@ -78,12 +85,25 @@ namespace OpenRA.Platforms.Default
|
|||||||
throw new InvalidDataException("Failed to initialize font");
|
throw new InvalidDataException("Failed to initialize font");
|
||||||
}
|
}
|
||||||
|
|
||||||
public FontGlyph CreateGlyph(char c, int size, float deviceScale)
|
public void SetSize(int size, float deviceScale)
|
||||||
{
|
{
|
||||||
var scaledSize = (uint)(size * deviceScale);
|
var scaledSize = (uint)(size * deviceScale);
|
||||||
if (FreeType.FT_Set_Pixel_Sizes(face, scaledSize, scaledSize) != FreeType.OK)
|
if (FreeType.FT_Set_Pixel_Sizes(face, scaledSize, scaledSize) != FreeType.OK)
|
||||||
return EmptyGlyph;
|
throw new InvalidDataException("Failed to set size");
|
||||||
|
|
||||||
|
var faceSize = Marshal.ReadIntPtr(IntPtr.Add(face, FreeType.FaceRecSizeOffset)); // face->size
|
||||||
|
var metrics = IntPtr.Add(faceSize, FreeType.SizeRecMetricsOffset); // face->size->metrics
|
||||||
|
var ascender = Marshal.ReadIntPtr(IntPtr.Add(metrics, FreeType.SizeMetricsAscenderOffset)); // face->size->metrics.ascender
|
||||||
|
var descender = Marshal.ReadIntPtr(IntPtr.Add(metrics, FreeType.SizeMetricsDescenderOffset)); // face->size->metrics.descender
|
||||||
|
|
||||||
|
var ascenderValue = (int)ascender >> 6;
|
||||||
|
var descenderValue = (int)descender >> 6;
|
||||||
|
|
||||||
|
Height = (int)((ascenderValue - Math.Abs(descenderValue)) / deviceScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontGlyph CreateGlyph(char c)
|
||||||
|
{
|
||||||
if (FreeType.FT_Load_Char(face, c, FreeType.FT_LOAD_RENDER) != FreeType.OK)
|
if (FreeType.FT_Load_Char(face, c, FreeType.FT_LOAD_RENDER) != FreeType.OK)
|
||||||
return EmptyGlyph;
|
return EmptyGlyph;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user