У меня есть приложение Xamarin Forms, в которое я включил файл шрифта с именем Roboto-Regular.ttf в папку Assets проекта Android. Его действие сборки установлено на AndroidAsset.

Используя пакет NuGet SixLabors.Fonts, я пытаюсь загрузить этот шрифт, чтобы использовать его для водяных знаков.

Однако при попытке установить шрифт с помощью потока ресурсов возникает исключение:

System.NotSupportedException: указанный метод не поддерживается.

var fonts = new FontCollection();

FontFamily fontFamily;

using (var fontStream = Assets.Open("Roboto-Regular.ttf"))
{
    fontFamily = fonts.Install(fontStream); // Fails with "method not supported"
}

return fontFamily;

Есть идеи, что может быть причиной этого, или есть ли лучший способ загрузить шрифты для использования с пакетом SixLabors.ImageSharp?

Изменить: я попробовал предложенный ниже вариант от SushiHangover, но он дал тот же результат:

Android asset stream in Xamarin

1
Ted Nyberg 19 Сен 2018 в 13:18

2 ответа

Лучший ответ

Похоже, что у базового Stream не было свойств Length или Position (что объясняет исключение), поэтому сейчас я прибег к преобразованию в доступный для поиска MemoryStream:

using (var assetStreamReader = new StreamReader(Assets.Open("Roboto-Regular.ttf"))
{   
    using (var ms = new MemoryStream())
    {
        assetStreamReader.BaseStream.CopyTo(ms);

        ms.Position = 0;

        var fontFamily = new FontCollection().Install(ms);
    }
}

Если посмотреть на реализацию FontReader, ошибка становится еще более понятной: https://github.com/SixLabors/Fonts/blob/master/src/SixLabors.Fonts/FontReader.cs

Однако я не уверен, почему Assets не возвращает доступный для поиска поток?

0
Ted Nyberg 25 Сен 2018 в 10:34

Существует два метода Assets.Open, один из которых предоставляет accessMode (установлен флаг перечисления доступа C #):

using (var fontStream = Assets.Open("Roboto-Regular.ttf", Android.Content.Res.Access.Random))
{
    fontFamily = fonts.Install(fontStream); 
}

Re: https: //developer.android.com/reference/android/content/res/AssetManager.html#open(java.lang.String,%20int )

public enum Access
{
    [IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_BUFFER")]
    Buffer = 3,
    [IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_RANDOM")]
    Random = 1,
    [IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_STREAMING")]
    Streaming,
    [IntDefinition (null, JniField = "android/content/res/AssetManager.ACCESS_UNKNOWN")]
    Unknown = 0
}
0
SushiHangover 19 Сен 2018 в 16:07