mono / SkiaSharp

SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
MIT License
4.51k stars 538 forks source link

SKTypeface.FromFamilyName does not change the font or text style in SkiaSharp.Views.Blazor #1902

Open harveytriana opened 2 years ago

harveytriana commented 2 years ago

Unexpected behavior when changing the text font when drawing text. If you query what type of text it should have after assigning Typeface, it is always typeFace: Noto Mono.

The following example illustrates the supposed issue,

@page "/drawing-text"
@using SkiaSharp
@using SkiaSharp.Views.Blazor

<SKCanvasView OnPaintSurface="OnPaintSurface"  />

@code {
    void OnPaintSurface(SKPaintSurfaceEventArgs e)
    {
        var canvas = e.Surface.Canvas;

        var fontFamily = "Tahoma"; // "Arial" | "Calibri" | ... none works?
        var typeFace = SKTypeface.FromFamilyName(fontFamily, SKFontStyle.BoldItalic);
        // query
        Console.WriteLine("typeFace: {0}", typeFace.FamilyName); //? typeFace: Noto Mono

        using SKPaint paint = new() {
                Style = SKPaintStyle.Fill,
                TextSize = 26,
                IsAntialias = true,
                Typeface = typeFace
            };

        canvas.DrawText("Fancy Text", 30, 30, paint); //? draw with Noto Mono
    }
}

The expected behavior is that the text is drawn with the text font and text style. I have tried the equivalent code in other scenarios and it works fine.

Gillibald commented 2 years ago

Skia's font manager is highly limited under wasm so you can't expect a functional font manager. It is better to load fonts explicitly via stream in a sandbox environment.

harveytriana commented 2 years ago

True Gillibald. Studying the «issue », it can be deduced that from WASM we do not have access to the Browser resources, so SKTypeface returns the Default, without warning. - Although I guess should be possible to do so, just like CSS you can use "Arial", to name something.

If anything, that's correct, I had already found a way to fix it.

RChrisCoble commented 2 years ago

This is a deal killer for using SkiaSharp on WASM if every font needs to be an embedded resource. We have a drawing package we're porting to Blazor WASM with SkiaSharp wherein the user picks as many fonts as they want in the design portion, with the runtime portion showing the designed graphics.

@mattleibow do we have options here?

Gillibald commented 2 years ago

MAUI does the same there is no way around it and that's how the web works. Usually those assets are provided via a webservice so font assets can be cached by the browser you don't have to bloat up your application size.

RChrisCoble commented 2 years ago

I'm fine pulling the fonts from a webservice, as long as there's some way to do it. So you're saying a WASM app pulls the fonts down in some capacity it can be generally loaded with "SKTypeface.FromStream" ?

Gillibald commented 2 years ago

Yes exactly. Javascript fetch API is available via JSInterop or directly via Emscripten so you will get caching out of the box as long as your service provides proper headers.

harveytriana commented 2 years ago

In this post, https://www.blazorspread.net/blogview/82, I show possibly one of the best ways to handle fonts in Blazor, of course, it also covers MAUI image

mattleibow commented 2 years ago

Can't you also hack the system and have a separate assembly with just fonts. And then use the feature of Blazor to load assemblies on demand? Is that even possible?

harveytriana commented 2 years ago

Yes

RChrisCoble commented 2 years ago

Is this even legal though?

Font redistribution FAQ - Typography | Microsoft Docs

Web fonts are fonts that are hosted on a web server. You do not have rights to:

copy fonts from a Windows installation to a web server, a process known as web font “self-hosting”. convert the font to the formats typically associated with web fonts, such as the WOFF or WOFF2 format.

jonchardy commented 2 years ago

This is a major pain point. I work on a diagramming library and we're hoping to add Blazor as a target. We need to provide our users with flexibility in fonts. How would one go about creating an SKTypeface dynamically, from a given family name, where we don't control what potential families may be used?

18779758522 commented 10 months ago

在这篇文章中,https://www.blazorspread.net/blogview/82,我展示了可能是 Blazor 中处理字体的最佳方法之一,当然,它还涵盖了 MAUI 图像

cannot access