Browse Source

Merge pull request #2162 from Gillibald/feature/SkiaTypefaceFallback

Skia: FontWeight and FontStyle fallback for embedded fonts
osx/maximised-set-in-xaml-fix
Jumar Macato 7 years ago
committed by GitHub
parent
commit
b4fae84e81
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 79
      src/Skia/Avalonia.Skia/SKTypefaceCollection.cs
  2. 3
      src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs

79
src/Skia/Avalonia.Skia/SKTypefaceCollection.cs

@ -1,72 +1,115 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Media;
using SkiaSharp;
namespace Avalonia.Skia
{
internal class SKTypefaceCollection
{
private readonly ConcurrentDictionary<FontKey, SKTypeface> _cachedTypefaces =
new ConcurrentDictionary<FontKey, SKTypeface>();
private readonly ConcurrentDictionary<string, ConcurrentDictionary<FontKey, SKTypeface>> _fontFamilies =
new ConcurrentDictionary<string, ConcurrentDictionary<FontKey, SKTypeface>>();
public void AddTypeFace(SKTypeface typeface)
{
var key = new FontKey(typeface.FamilyName, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant);
var key = new FontKey((SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant);
_cachedTypefaces.TryAdd(key, typeface);
if (!_fontFamilies.TryGetValue(typeface.FamilyName, out var fontFamily))
{
fontFamily = new ConcurrentDictionary<FontKey, SKTypeface>();
_fontFamilies.TryAdd(typeface.FamilyName, fontFamily);
}
fontFamily.TryAdd(key, typeface);
}
public SKTypeface GetTypeFace(Typeface typeface)
{
SKFontStyleSlant skStyle = SKFontStyleSlant.Upright;
var styleSlant = SKFontStyleSlant.Upright;
switch (typeface.Style)
{
case FontStyle.Italic:
skStyle = SKFontStyleSlant.Italic;
styleSlant = SKFontStyleSlant.Italic;
break;
case FontStyle.Oblique:
skStyle = SKFontStyleSlant.Oblique;
styleSlant = SKFontStyleSlant.Oblique;
break;
}
var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle);
if (!_fontFamilies.TryGetValue(typeface.FontFamily.Name, out var fontFamily))
{
return TypefaceCache.Default;
}
var weight = (SKFontStyleWeight)typeface.Weight;
var key = new FontKey(weight, styleSlant);
return fontFamily.GetOrAdd(key, GetFallback(fontFamily, key));
}
private static SKTypeface GetFallback(IDictionary<FontKey, SKTypeface> fontFamily, FontKey key)
{
var keys = fontFamily.Keys.Where(
x => ((int)x.Weight <= (int)key.Weight || (int)x.Weight > (int)key.Weight) && x.Slant == key.Slant).ToArray();
if (!keys.Any())
{
keys = fontFamily.Keys.Where(
x => x.Weight == key.Weight && (x.Slant >= key.Slant || x.Slant < key.Slant)).ToArray();
if (!keys.Any())
{
keys = fontFamily.Keys.Where(
x => ((int)x.Weight <= (int)key.Weight || (int)x.Weight > (int)key.Weight) &&
(x.Slant >= key.Slant || x.Slant < key.Slant)).ToArray();
}
}
key = keys.FirstOrDefault();
fontFamily.TryGetValue(key, out var typeface);
return _cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : TypefaceCache.Default;
return typeface;
}
private struct FontKey
{
public readonly string Name;
public readonly SKFontStyleSlant Slant;
public readonly SKFontStyleWeight Weight;
public FontKey(string name, SKFontStyleWeight weight, SKFontStyleSlant slant)
public FontKey(SKFontStyleWeight weight, SKFontStyleSlant slant)
{
Name = name;
Slant = slant;
Weight = weight;
}
public override int GetHashCode()
{
int hash = 17;
hash = hash * 31 + Name.GetHashCode();
hash = hash * 31 + (int)Slant;
hash = hash * 31 + (int)Weight;
var hash = 17;
hash = (hash * 31) + (int)Slant;
hash = (hash * 31) + (int)Weight;
return hash;
}
public override bool Equals(object other)
{
return other is FontKey ? Equals((FontKey)other) : false;
return other is FontKey key && this.Equals(key);
}
private bool Equals(FontKey other)
{
return Name == other.Name && Slant == other.Slant &&
return Slant == other.Slant &&
Weight == other.Weight;
}
}

3
src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs

@ -1,3 +1,6 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.Concurrent;
using Avalonia.Media;
using Avalonia.Media.Fonts;

Loading…
Cancel
Save