예제 #1
0
        private static FontDetails GetFont(
            string?name,
            FontWeight weight,
            FontStretch stretch,
            FontStyle style)
        {
            var skWeight = weight.ToSkiaWeight();
            // TODO: FontStretch not supported by Uno yet
            // var skWidth = FontStretch.ToSkiaWidth();
            var skWidth = SKFontStyleWidth.Normal;
            var skSlant = style.ToSkiaSlant();

            SKTypeface skTypeFace;

            if (name == null || string.Equals(name, "XamlAutoFontFamily", StringComparison.OrdinalIgnoreCase))
            {
                skTypeFace = SKTypeface.FromFamilyName(null, skWeight, skWidth, skSlant);
            }
            else if (name.StartsWith(XamlFilePathHelper.AppXIdentifier))
            {
                var path = new Uri(name).PathAndQuery;

                var filePath = global::System.IO.Path.Combine(Windows.Application­Model.Package.Current.Installed­Location.Path, path.TrimStart('/')
                                                              .Replace('/', global::System.IO.Path.DirectorySeparatorChar));

                skTypeFace = SKTypeface.FromFile(filePath);
            }
            else
            {
                skTypeFace = SKTypeface.FromFamilyName(name, skWeight, skWidth, skSlant);

                // FromFontFamilyName may return null: https://github.com/mono/SkiaSharp/issues/1058
                if (skTypeFace == null)
                {
                    if (typeof(Inline).Log().IsEnabled(LogLevel.Warning))
                    {
                        typeof(Inline).Log().LogWarning($"The font {name} could not be found, using system default");
                    }

                    skTypeFace = SKTypeface.FromFamilyName(null, skWeight, skWidth, skSlant);
                }
            }

            Blob?GetTable(Face face, Tag tag)
            {
                var size = skTypeFace.GetTableSize(tag);

                if (size == 0)
                {
                    return(null);
                }

                var data = Marshal.AllocCoTaskMem(size);

                var releaseDelegate = new ReleaseDelegate(() => Marshal.FreeCoTaskMem(data));

                var value = skTypeFace.TryGetTableData(tag, 0, size, data) ?
                            new Blob(data, size, MemoryMode.Writeable, releaseDelegate) : null;

                return(value);
            }

            var hbFace = new Face(GetTable);

            hbFace.UnitsPerEm = skTypeFace.UnitsPerEm;

            var hbFont = new Font(hbFace);

            hbFont.SetScale(FontScale, FontScale);
            hbFont.SetFunctionsOpenType();

            return(new(skTypeFace, hbFont, hbFace));
        }