Get the Ascender value from mod.yaml instead from the Font

This commit is contained in:
teinarss
2019-05-27 18:48:12 +02:00
committed by abcdefg30
parent a260b50ce1
commit 9982b01642
12 changed files with 81 additions and 46 deletions

37
OpenRA.Game/Fonts.cs Normal file
View File

@@ -0,0 +1,37 @@
#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 System.Collections.Generic;
namespace OpenRA
{
public class FontData
{
public readonly string Font;
public readonly int Size;
public readonly int Ascender;
}
public class Fonts : IGlobalModData
{
[FieldLoader.LoadUsing("LoadFonts")]
public readonly Dictionary<string, FontData> FontList;
static object LoadFonts(MiniYaml y)
{
var ret = new Dictionary<string, FontData>();
foreach (var node in y.Nodes)
ret.Add(node.Key, FieldLoader.Load<FontData>(node.Value));
return ret;
}
}
}

View File

@@ -133,9 +133,7 @@ namespace OpenRA
public interface IFont : IDisposable public interface IFont : IDisposable
{ {
FontGlyph CreateGlyph(char c); FontGlyph CreateGlyph(char c, int size, float deviceScale);
void SetSize(int size, float deviceScale);
int Height { get; }
} }
public struct FontGlyph public struct FontGlyph

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Graphics
float deviceScale; float deviceScale;
public SpriteFont(string name, byte[] data, int size, float scale, SheetBuilder builder) public SpriteFont(string name, byte[] data, int size, int ascender, 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");
@@ -38,7 +38,6 @@ 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);
@@ -49,17 +48,13 @@ namespace OpenRA.Graphics
if (size <= 24) if (size <= 24)
PrecacheColor(Color.White, name); PrecacheColor(Color.White, name);
TopOffset = size - font.Height; TopOffset = size - ascender;
} }
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)
@@ -139,7 +134,7 @@ namespace OpenRA.Graphics
GlyphInfo CreateGlyph(Pair<char, Color> c) GlyphInfo CreateGlyph(Pair<char, Color> c)
{ {
var glyph = font.CreateGlyph(c.First); var glyph = font.CreateGlyph(c.First, size, deviceScale);
if (glyph.Data == null) if (glyph.Data == null)
{ {

View File

@@ -66,7 +66,6 @@ namespace OpenRA
public readonly IReadOnlyDictionary<string, string> Packages; public readonly IReadOnlyDictionary<string, string> Packages;
public readonly IReadOnlyDictionary<string, string> MapFolders; public readonly IReadOnlyDictionary<string, string> MapFolders;
public readonly MiniYaml LoadScreen; public readonly MiniYaml LoadScreen;
public readonly Dictionary<string, Pair<string, int>> Fonts;
public readonly string[] SoundFormats = { }; public readonly string[] SoundFormats = { };
public readonly string[] SpriteFormats = { }; public readonly string[] SpriteFormats = { };
@@ -77,7 +76,7 @@ namespace OpenRA
"Metadata", "Folders", "MapFolders", "Packages", "Rules", "Metadata", "Folders", "MapFolders", "Packages", "Rules",
"Sequences", "ModelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons", "Sequences", "ModelSequences", "Cursors", "Chrome", "Assemblies", "ChromeLayout", "Weapons",
"Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions", "Hotkeys", "Voices", "Notifications", "Music", "Translations", "TileSets", "ChromeMetrics", "Missions", "Hotkeys",
"ServerTraits", "LoadScreen", "Fonts", "SupportsMapsFrom", "SoundFormats", "SpriteFormats", "ServerTraits", "LoadScreen", "SupportsMapsFrom", "SoundFormats", "SpriteFormats",
"RequiresMods", "PackageFormats" "RequiresMods", "PackageFormats"
}; };
@@ -123,12 +122,6 @@ namespace OpenRA
if (!yaml.TryGetValue("LoadScreen", out LoadScreen)) if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
throw new InvalidDataException("`LoadScreen` section is not defined."); throw new InvalidDataException("`LoadScreen` section is not defined.");
Fonts = yaml["Fonts"].ToDictionary(my =>
{
var nd = my.ToDictionary();
return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
});
// Allow inherited mods to import parent maps. // Allow inherited mods to import parent maps.
var compat = new List<string> { Id }; var compat = new List<string> { Id };

View File

@@ -90,9 +90,9 @@ namespace OpenRA
if (fontSheetBuilder != null) if (fontSheetBuilder != null)
fontSheetBuilder.Dispose(); fontSheetBuilder.Dispose();
fontSheetBuilder = new SheetBuilder(SheetType.BGRA, 512); fontSheetBuilder = new SheetBuilder(SheetType.BGRA, 512);
Fonts = modData.Manifest.Fonts.ToDictionary(x => x.Key, Fonts = modData.Manifest.Get<Fonts>().FontList.ToDictionary(x => x.Key,
x => new SpriteFont(x.Value.First, modData.DefaultFileSystem.Open(x.Value.First).ReadAllBytes(), x => new SpriteFont(x.Value.Font, modData.DefaultFileSystem.Open(x.Value.Font).ReadAllBytes(),
x.Value.Second, Window.WindowScale, fontSheetBuilder)).AsReadOnly(); x.Value.Size, x.Value.Ascender, Window.WindowScale, fontSheetBuilder)).AsReadOnly();
} }
Window.OnWindowScaleChanged += (before, after) => Window.OnWindowScaleChanged += (before, after) =>

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits.Render
void IRulesetLoaded<ActorInfo>.RulesetLoaded(Ruleset rules, ActorInfo info) void IRulesetLoaded<ActorInfo>.RulesetLoaded(Ruleset rules, ActorInfo info)
{ {
if (!Game.ModData.Manifest.Fonts.ContainsKey(Font)) if (!Game.ModData.Manifest.Get<Fonts>().FontList.ContainsKey(Font))
throw new YamlException("Font '{0}' is not listed in the mod.yaml's Fonts section".F(Font)); throw new YamlException("Font '{0}' is not listed in the mod.yaml's Fonts section".F(Font));
} }

View File

@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits.Render
public override void RulesetLoaded(Ruleset rules, ActorInfo ai) public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{ {
if (!Game.ModData.Manifest.Fonts.ContainsKey(Font)) if (!Game.ModData.Manifest.Get<Fonts>().FontList.ContainsKey(Font))
throw new YamlException("Font '{0}' is not listed in the mod.yaml's Fonts section".F(Font)); throw new YamlException("Font '{0}' is not listed in the mod.yaml's Fonts section".F(Font));
base.RulesetLoaded(rules, ai); base.RulesetLoaded(rules, ai);

View File

@@ -27,11 +27,6 @@ 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)
@@ -73,8 +68,6 @@ 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)
@@ -85,25 +78,12 @@ namespace OpenRA.Platforms.Default
throw new InvalidDataException("Failed to initialize font"); throw new InvalidDataException("Failed to initialize font");
} }
public void SetSize(int size, float deviceScale) public FontGlyph CreateGlyph(char c, 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)
throw new InvalidDataException("Failed to set size"); return EmptyGlyph;
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;

View File

@@ -168,27 +168,35 @@ Fonts:
Tiny: Tiny:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 10 Size: 10
Ascender: 8
TinyBold: TinyBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 10 Size: 10
Ascender: 8
Small: Small:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 12 Size: 12
Ascender: 9
Regular: Regular:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 14 Size: 14
Ascender: 11
Bold: Bold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 14 Size: 14
Ascender: 11
MediumBold: MediumBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 18 Size: 18
Ascender: 14
BigBold: BigBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 24 Size: 24
Ascender: 18
Title: Title:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 32 Size: 32
Ascender: 24
Missions: Missions:
./mods/cnc/missions.yaml ./mods/cnc/missions.yaml

View File

@@ -155,27 +155,35 @@ Fonts:
Tiny: Tiny:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 10 Size: 10
Ascender: 8
TinyBold: TinyBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 10 Size: 10
Ascender: 8
Small: Small:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 12 Size: 12
Ascender: 9
Regular: Regular:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 14 Size: 14
Ascender: 11
Bold: Bold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 14 Size: 14
Ascender: 11
MediumBold: MediumBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 18 Size: 18
Ascender: 14
BigBold: BigBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 24 Size: 24
Ascender: 18
Title: Title:
Font: d2k|Dune2k.ttf Font: d2k|Dune2k.ttf
Size: 32 Size: 32
Ascender: 23
Missions: Missions:
d2k|missions.yaml d2k|missions.yaml

View File

@@ -171,27 +171,35 @@ Fonts:
Tiny: Tiny:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 10 Size: 10
Ascender: 8
TinyBold: TinyBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 10 Size: 10
Ascender: 8
Small: Small:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 12 Size: 12
Ascender: 9
Regular: Regular:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 14 Size: 14
Ascender: 11
Bold: Bold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 14 Size: 14
Ascender: 11
MediumBold: MediumBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 18 Size: 18
Ascender: 14
BigBold: BigBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 24 Size: 24
Ascender: 18
Title: Title:
Font: ra|ZoodRangmah.ttf Font: ra|ZoodRangmah.ttf
Size: 48 Size: 48
Ascender: 26
Missions: Missions:
ra|missions.yaml ra|missions.yaml

View File

@@ -213,27 +213,35 @@ Fonts:
Tiny: Tiny:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 10 Size: 10
Ascender: 8
TinyBold: TinyBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 10 Size: 10
Ascender: 8
Small: Small:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 12 Size: 12
Ascender: 9
Regular: Regular:
Font: common|FreeSans.ttf Font: common|FreeSans.ttf
Size: 14 Size: 14
Ascender: 11
Bold: Bold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 14 Size: 14
Ascender: 11
MediumBold: MediumBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 18 Size: 18
Ascender: 14
BigBold: BigBold:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 24 Size: 24
Ascender: 18
Title: Title:
Font: common|FreeSansBold.ttf Font: common|FreeSansBold.ttf
Size: 32 Size: 32
Ascender: 24
SupportsMapsFrom: ts SupportsMapsFrom: ts