示例#1
0
        public SKTypeface GetTypeFace(Typeface typeface)
        {
            var styleSlant = SKFontStyleSlant.Upright;

            switch (typeface.Style)
            {
            case FontStyle.Italic:
                styleSlant = SKFontStyleSlant.Italic;
                break;

            case FontStyle.Oblique:
                styleSlant = SKFontStyleSlant.Oblique;
                break;
            }

            if (!_fontFamilies.TryGetValue(typeface.FontFamily.Name, out var fontFamily))
            {
                return(TypefaceCache.GetTypeface(TypefaceCache.DefaultFamilyName, typeface.Style, typeface.Weight));
            }

            var weight = (SKFontStyleWeight)typeface.Weight;

            var key = new FontKey(weight, styleSlant);

            return(fontFamily.GetOrAdd(key, GetFallback(fontFamily, key)));
        }
示例#2
0
        public static TypefaceCollectionEntry Get(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
        {
            if (fontFamily.Key != null)
            {
                return(SKTypefaceCollectionCache.GetOrAddTypefaceCollection(fontFamily)
                       .Get(fontFamily.Name, fontWeight, fontStyle));
            }

            var typefaceCollection = s_cache.GetOrAdd(fontFamily.Name, new ConcurrentDictionary <FontKey, TypefaceCollectionEntry>());

            var key = new FontKey(fontWeight, fontStyle);

            if (typefaceCollection.TryGetValue(key, out var entry))
            {
                return(entry);
            }

            var skTypeface = SKTypeface.FromFamilyName(fontFamily.Name, (SKFontStyleWeight)fontWeight,
                                                       SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle) ?? SKTypeface.Default;

            var typeface = new Typeface(fontFamily.Name, fontWeight, fontStyle);

            entry = new TypefaceCollectionEntry(typeface, skTypeface);

            typefaceCollection[key] = entry;

            return(entry);
        }
        unsafe static SKTypeface GetTypeface(string name, FontKey key)
        {
            if (name == null)
            {
                name = "Arial";
            }

            Dictionary <FontKey, SKTypeface> entry;

            if (!Cache.TryGetValue(name, out entry))
            {
                Cache[name] = entry = new Dictionary <FontKey, SKTypeface>();
            }

            SKTypeface typeface = null;

            if (!entry.TryGetValue(key, out typeface))
            {
                typeface = SKTypeface.FromFamilyName(name, key.Weight, SKFontStyleWidth.Normal, key.Slant);

                if (typeface == null)
                {
                    typeface = SKTypeface.FromFamilyName(null, SKTypefaceStyle.Normal);
                }

                entry[key] = typeface;
            }

            return(typeface);
        }
示例#4
0
        public TypefaceCollectionEntry Get(string familyName, FontWeight fontWeight, FontStyle fontStyle)
        {
            var key = new FontKey(fontWeight, fontStyle);

            return(_fontFamilies.TryGetValue(familyName, out var fontFamily) ?
                   fontFamily.GetOrAdd(key, GetFallback(fontFamily, key)) :
                   new TypefaceCollectionEntry(Typeface.Default, SkiaSharp.SKTypeface.Default));
        }
示例#5
0
        public void AddEntry(string familyName, FontKey key, TypefaceCollectionEntry entry)
        {
            if (!_fontFamilies.TryGetValue(familyName, out var fontFamily))
            {
                fontFamily = new ConcurrentDictionary <FontKey, TypefaceCollectionEntry>();

                _fontFamilies.TryAdd(familyName, fontFamily);
            }

            fontFamily.TryAdd(key, entry);
        }
示例#6
0
        public void AddTypeFace(SKTypeface typeface)
        {
            var key = new FontKey((SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant);

            if (!_fontFamilies.TryGetValue(typeface.FamilyName, out var fontFamily))
            {
                fontFamily = new ConcurrentDictionary <FontKey, SKTypeface>();

                _fontFamilies.TryAdd(typeface.FamilyName, fontFamily);
            }

            fontFamily.TryAdd(key, typeface);
        }
示例#7
0
        public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle,
                                      FontFamily fontFamily, CultureInfo culture, out FontKey fontKey)
        {
            if (culture == null)
            {
                culture = CultureInfo.CurrentUICulture;
            }

            if (t_languageTagBuffer == null)
            {
                t_languageTagBuffer = new string[2];
            }

            t_languageTagBuffer[0] = culture.TwoLetterISOLanguageName;
            t_languageTagBuffer[1] = culture.ThreeLetterISOLanguageName;

            if (fontFamily != null)
            {
                foreach (var familyName in fontFamily.FamilyNames)
                {
                    var skTypeface = _skFontManager.MatchCharacter(familyName, (SKFontStyleWeight)fontWeight,
                                                                   SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, t_languageTagBuffer, codepoint);

                    if (skTypeface == null)
                    {
                        continue;
                    }

                    fontKey = new FontKey(new FontFamily(familyName), fontWeight, fontStyle);

                    return(true);
                }
            }
            else
            {
                var skTypeface = _skFontManager.MatchCharacter(null, (SKFontStyleWeight)fontWeight,
                                                               SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, t_languageTagBuffer, codepoint);

                if (skTypeface != null)
                {
                    fontKey = new FontKey(new FontFamily(skTypeface.FamilyName), fontWeight, fontStyle);

                    return(true);
                }
            }

            fontKey = default;

            return(false);
        }
        private static SKTypeface GetTypeface(string name, FontKey key)
        {
            var familyKey = name;

            if (!s_cache.TryGetValue(familyKey, out var entry))
            {
                s_cache[familyKey] = entry = new Dictionary <FontKey, SKTypeface>();
            }

            if (!entry.TryGetValue(key, out var typeface))
            {
                typeface = SKTypeface.FromFamilyName(familyKey, key.Weight, SKFontStyleWidth.Normal, key.Slant) ??
                           GetTypeface(DefaultFamilyName, key);

                entry[key] = typeface;
            }

            return(typeface);
        }
示例#9
0
        public SKTypeface GetTypeFace(Typeface typeface)
        {
            SKFontStyleSlant skStyle = SKFontStyleSlant.Upright;

            switch (typeface.Style)
            {
            case FontStyle.Italic:
                skStyle = SKFontStyleSlant.Italic;
                break;

            case FontStyle.Oblique:
                skStyle = SKFontStyleSlant.Oblique;
                break;
            }

            var key = new FontKey(typeface.FontFamily.Name, (SKFontStyleWeight)typeface.Weight, skStyle);

            return(_cachedTypefaces.TryGetValue(key, out var skTypeface) ? skTypeface : TypefaceCache.Default);
        }
示例#10
0
        /// <summary>
        /// Creates the custom font collection.
        /// </summary>
        /// <param name="fontFamily">The font family.</param>
        /// <returns></returns>
        private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily)
        {
            var fontAssets = FontFamilyLoader.LoadFontAssets(fontFamily.Key);

            var typeFaceCollection = new SKTypefaceCollection();

            var assetLoader = AvaloniaLocator.Current.GetService <IAssetLoader>();

            foreach (var asset in fontAssets)
            {
                var assetStream = assetLoader.Open(asset);

                var typeface = SKTypeface.FromStream(assetStream);

                var key = new FontKey(fontFamily, (FontWeight)typeface.FontWeight, (FontStyle)typeface.FontSlant);

                typeFaceCollection.AddTypeface(key, typeface);
            }

            return(typeFaceCollection);
        }
示例#11
0
        /// <summary>
        /// Creates the custom font collection.
        /// </summary>
        /// <param name="fontFamily">The font family.</param>
        /// <returns></returns>
        private static SKTypefaceCollection CreateCustomFontCollection(FontFamily fontFamily)
        {
            var fontAssets = FontFamilyLoader.LoadFontAssets(fontFamily.Key);

            var typeFaceCollection = new SKTypefaceCollection();

            var assetLoader = AvaloniaLocator.Current.GetService <IAssetLoader>();

            foreach (var asset in fontAssets)
            {
                var assetStream = assetLoader.Open(asset);

                if (assetStream == null)
                {
                    throw new InvalidOperationException("Asset could not be loaded.");
                }

                var typeface = SKTypeface.FromStream(assetStream);

                if (typeface == null)
                {
                    throw new InvalidOperationException("Typeface could not be loaded.");
                }

                if (typeface.FamilyName != fontFamily.Name)
                {
                    continue;
                }

                var key = new FontKey(fontFamily.Name, typeface.FontSlant.ToAvalonia(),
                                      (FontWeight)typeface.FontWeight);

                typeFaceCollection.AddTypeface(key, typeface);
            }

            return(typeFaceCollection);
        }
示例#12
0
 private bool Equals(FontKey other)
 {
     return(Name == other.Name && Slant == other.Slant &&
            Weight == other.Weight);
 }
 public bool Equals(FontKey other)
 {
     return(Slant == other.Slant &&
            Weight == other.Weight);
 }
示例#14
0
        private static SKTypeface GetNearestMatch(IDictionary <FontKey, SKTypeface> typefaces, FontKey key)
        {
            if (typefaces.TryGetValue(new FontKey(key.FamilyName, key.Style, key.Weight), out var typeface))
            {
                return(typeface);
            }

            var weight = (int)key.Weight;

            weight -= weight % 100; // make sure we start at a full weight

            for (var i = (int)key.Style; i < 2; i++)
            {
                // only try 2 font weights in each direction
                for (var j = 0; j < 200; j += 100)
                {
                    if (weight - j >= 100)
                    {
                        if (typefaces.TryGetValue(new FontKey(key.FamilyName, (FontStyle)i, (FontWeight)(weight - j)), out typeface))
                        {
                            return(typeface);
                        }
                    }

                    if (weight + j > 900)
                    {
                        continue;
                    }

                    if (typefaces.TryGetValue(new FontKey(key.FamilyName, (FontStyle)i, (FontWeight)(weight + j)), out typeface))
                    {
                        return(typeface);
                    }
                }
            }

            //Nothing was found so we use the first typeface we can get.
            return(typefaces.Values.FirstOrDefault());
        }
示例#15
0
        public SKTypeface Get(Typeface typeface)
        {
            var key = new FontKey(typeface.FontFamily.Name, typeface.Style, typeface.Weight);

            return(GetNearestMatch(_typefaces, key));
        }
示例#16
0
 public void AddTypeface(FontKey key, SKTypeface typeface)
 {
     _typefaces.TryAdd(key, typeface);
 }
示例#17
0
        private static SKTypeface GetNearestMatch(IDictionary <FontKey, SKTypeface> typefaces, FontKey key)
        {
            if (typefaces.ContainsKey(key))
            {
                return(typefaces[key]);
            }

            var keys = typefaces.Keys.Where(
                x => ((int)x.Weight <= (int)key.Weight || (int)x.Weight > (int)key.Weight) && x.Style == key.Style).ToArray();

            if (!keys.Any())
            {
                keys = typefaces.Keys.Where(
                    x => x.Weight == key.Weight && (x.Style >= key.Style || x.Style < key.Style)).ToArray();

                if (!keys.Any())
                {
                    keys = typefaces.Keys.Where(
                        x => ((int)x.Weight <= (int)key.Weight || (int)x.Weight > (int)key.Weight) &&
                        (x.Style >= key.Style || x.Style < key.Style)).ToArray();
                }
            }

            if (keys.Length == 0)
            {
                return(SKTypeface.Default);
            }

            key = keys[0];

            return(typefaces[key]);
        }
示例#18
0
        public SKTypeface Get(FontFamily fontFamily, FontWeight fontWeight, FontStyle fontStyle)
        {
            var key = new FontKey(fontFamily, fontWeight, fontStyle);

            return(GetNearestMatch(_typefaces, key));
        }
示例#19
0
        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(typeface);
        }
示例#20
0
        private static TypefaceCollectionEntry GetFallback(IDictionary <FontKey, TypefaceCollectionEntry> fontFamily, FontKey key)
        {
            var keys = fontFamily.Keys.Where(
                x => ((int)x.Weight <= (int)key.Weight || (int)x.Weight > (int)key.Weight) && x.Style == key.Style).ToArray();

            if (!keys.Any())
            {
                keys = fontFamily.Keys.Where(
                    x => x.Weight == key.Weight && (x.Style >= key.Style || x.Style < key.Style)).ToArray();

                if (!keys.Any())
                {
                    keys = fontFamily.Keys.Where(
                        x => ((int)x.Weight <= (int)key.Weight || (int)x.Weight > (int)key.Weight) &&
                        (x.Style >= key.Style || x.Style < key.Style)).ToArray();
                }
            }

            key = keys.FirstOrDefault();

            fontFamily.TryGetValue(key, out var entry);

            return(entry);
        }
示例#21
0
        public bool TryMatchCharacter(int codepoint, FontStyle fontStyle,
                                      FontWeight fontWeight,
                                      FontFamily fontFamily, CultureInfo culture, out FontKey fontKey)
        {
            SKFontStyle skFontStyle;

            switch (fontWeight)
            {
            case FontWeight.Normal when fontStyle == FontStyle.Normal:
                skFontStyle = SKFontStyle.Normal;
                break;

            case FontWeight.Normal when fontStyle == FontStyle.Italic:
                skFontStyle = SKFontStyle.Italic;
                break;

            case FontWeight.Bold when fontStyle == FontStyle.Normal:
                skFontStyle = SKFontStyle.Bold;
                break;

            case FontWeight.Bold when fontStyle == FontStyle.Italic:
                skFontStyle = SKFontStyle.BoldItalic;
                break;

            default:
                skFontStyle = new SKFontStyle((SKFontStyleWeight)fontWeight, SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle);
                break;
            }

            if (culture == null)
            {
                culture = CultureInfo.CurrentUICulture;
            }

            if (t_languageTagBuffer == null)
            {
                t_languageTagBuffer = new string[2];
            }

            t_languageTagBuffer[0] = culture.TwoLetterISOLanguageName;
            t_languageTagBuffer[1] = culture.ThreeLetterISOLanguageName;

            if (fontFamily != null && fontFamily.FamilyNames.HasFallbacks)
            {
                var familyNames = fontFamily.FamilyNames;

                for (var i = 1; i < familyNames.Count; i++)
                {
                    var skTypeface =
                        _skFontManager.MatchCharacter(familyNames[i], skFontStyle, t_languageTagBuffer, codepoint);

                    if (skTypeface == null)
                    {
                        continue;
                    }

                    fontKey = new FontKey(skTypeface.FamilyName, fontStyle, fontWeight);

                    return(true);
                }
            }
            else
            {
                var skTypeface = _skFontManager.MatchCharacter(null, skFontStyle, t_languageTagBuffer, codepoint);

                if (skTypeface != null)
                {
                    fontKey = new FontKey(skTypeface.FamilyName, fontStyle, fontWeight);

                    return(true);
                }
            }

            fontKey = default;

            return(false);
        }
示例#22
0
        public void AddTypeFace(SKTypeface typeface)
        {
            var key = new FontKey(typeface.FamilyName, (SKFontStyleWeight)typeface.FontWeight, typeface.FontSlant);

            _cachedTypefaces.TryAdd(key, typeface);
        }