Browse Source

Use a default DesignEmHeight if the font doesn't have one (#20764)

* Add failing test for font without head table

* Use a default DesignEmHeight if the font doesn't have one

* Add new font to Should_AddGlyphTypeface_By_Stream
pull/19747/merge
Julien Lebosquain 3 weeks ago
committed by GitHub
parent
commit
f893d8a322
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      src/Avalonia.Base/Media/GlyphTypeface.cs
  2. 61
      tests/Avalonia.Base.UnitTests/Media/GlyphTypefaceTests.cs
  3. BIN
      tests/Avalonia.RenderTests/Assets/NISC18030.ttf
  4. 1
      tests/Avalonia.Skia.UnitTests/Media/CustomFontCollectionTests.cs

15
src/Avalonia.Base/Media/GlyphTypeface.cs

@ -122,10 +122,11 @@ namespace Avalonia.Media
var isFixedPitch = postTable.IsFixedPitch;
var underlineOffset = postTable.UnderlinePosition;
var underlineSize = postTable.UnderlineThickness;
var designEmHeight = GetFontDesignEmHeight(headTable);
Metrics = new FontMetrics
{
DesignEmHeight = headTable?.UnitsPerEm ?? 0,
DesignEmHeight = designEmHeight,
Ascent = ascent,
Descent = descent,
LineGap = lineGap,
@ -225,6 +226,18 @@ namespace Avalonia.Media
}
}
private static ushort GetFontDesignEmHeight(HeadTable? headTable)
{
var unitsPerEm = headTable?.UnitsPerEm ?? 0;
// Bitmap fonts may specify 0 or miss the head table completely.
// Use 2048 as sensible default (used by most fonts).
if (unitsPerEm == 0)
unitsPerEm = 2048;
return unitsPerEm;
}
internal static GlyphTypeface? TryCreate(IPlatformTypeface typeface, FontSimulations fontSimulations = FontSimulations.None)
{
try

61
tests/Avalonia.Base.UnitTests/Media/GlyphTypefaceTests.cs

@ -12,15 +12,16 @@ namespace Avalonia.Base.UnitTests.Media
{
public class GlyphTypefaceTests
{
private static readonly string s_InterFontUri = "resm:Avalonia.Base.UnitTests.Assets.Inter-Regular.ttf?assembly=Avalonia.Base.UnitTests";
private static readonly string s_blankFontUri = "resm:Avalonia.Base.UnitTests.Assets.AdobeBlank2VF.ttf?assembly=Avalonia.Base.UnitTests";
private const string InterFontUri = "resm:Avalonia.Base.UnitTests.Assets.Inter-Regular.ttf?assembly=Avalonia.Base.UnitTests";
private const string BlankFontUri = "resm:Avalonia.Base.UnitTests.Assets.AdobeBlank2VF.ttf?assembly=Avalonia.Base.UnitTests";
private const string GB18030FontUri = "resm:Avalonia.Base.UnitTests.Assets.NISC18030.ttf?assembly=Avalonia.Base.UnitTests";
[Fact]
public void Should_Load_Inter_Font()
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -32,7 +33,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -55,7 +56,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -75,12 +76,14 @@ namespace Avalonia.Base.UnitTests.Media
Assert.Equal(metrics.Width, advance);
}
[Fact]
public void Should_Have_Valid_FontMetrics()
[Theory]
[InlineData(InterFontUri)]
[InlineData(GB18030FontUri)] // Font without head table
public void Should_Have_Valid_FontMetrics(string fontUri)
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(fontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -97,7 +100,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -109,7 +112,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -124,7 +127,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream), FontSimulations.Bold);
@ -137,7 +140,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream), FontSimulations.Oblique);
@ -150,7 +153,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream),
FontSimulations.Bold | FontSimulations.Oblique);
@ -165,7 +168,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -177,7 +180,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -190,7 +193,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -203,7 +206,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -217,7 +220,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -232,7 +235,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -244,7 +247,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -259,7 +262,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -278,7 +281,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var platformTypeface = new CustomPlatformTypeface(stream);
var typeface = new GlyphTypeface(platformTypeface);
@ -292,7 +295,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -307,7 +310,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -327,7 +330,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_blankFontUri));
using var stream = assetLoader.Open(new Uri(BlankFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -347,7 +350,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -363,7 +366,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -382,7 +385,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));
@ -395,7 +398,7 @@ namespace Avalonia.Base.UnitTests.Media
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(s_InterFontUri));
using var stream = assetLoader.Open(new Uri(InterFontUri));
var typeface = new GlyphTypeface(new CustomPlatformTypeface(stream));

BIN
tests/Avalonia.RenderTests/Assets/NISC18030.ttf

Binary file not shown.

1
tests/Avalonia.Skia.UnitTests/Media/CustomFontCollectionTests.cs

@ -33,6 +33,7 @@ namespace Avalonia.Skia.UnitTests.Media
new FontAssetInfo($"{AssetsNamespace}.Inter-Regular.ttf", "Inter"),
new FontAssetInfo($"{AssetsNamespace}.Manrope-Light.ttf", "Manrope Light"),
new FontAssetInfo($"{AssetsNamespace}.MiSans-Normal.ttf", "MiSans Normal"),
new FontAssetInfo($"{AssetsNamespace}.NISC18030.ttf", "GB18030 Bitmap"),
new FontAssetInfo($"{AssetsNamespace}.NotoMono-Regular.ttf", "Noto Mono"),
new FontAssetInfo($"{AssetsNamespace}.NotoSans-Italic.ttf", "Noto Sans"),
new FontAssetInfo($"{AssetsNamespace}.NotoSansArabic-Regular.ttf", "Noto Sans Arabic"),

Loading…
Cancel
Save