SkiaSharp: Can't draw text using default typeface on Linux

Description

Can’t draw text using SKTypeface.Default under WSL (Debian) or Docker, .NET Core 3.1, host Windows 10 Pro x64 1903.

Packages used are SkiaSharp and SkiaSharp.NativeAssets.Linux.NoDependencies, 1.68.2-preview.29 or older versions.

Explicitly loading a typeface fixes the problem.

Code

	using var surface = SKSurface.Create(new SKImageInfo(256, 256));
	using var canvas = surface.Canvas;
	canvas.Clear(SKColors.SkyBlue);

	using var paint = new SKPaint
	{
		Color = SKColors.Yellow, 
		TextAlign = SKTextAlign.Center, 
		TextSize = 64,
		Typeface = SKTypeface.Default
	};

	canvas.DrawText("foobar", 128, 128, paint);

	using var image = surface.Snapshot();
	image.SaveAs("test.png", SKPngEncoderOptions.Default);

Expected Behavior

The output should contain the text “foobar” on a skyblue background.

Actual Behavior

The output doesn’t contain any text, but the background is skyblue, so rendering did take place.

Basic Information

  • Version with issue: 1.68.2 preview
  • Last known good version: Can’t find any version that works.
  • IDE: Visual Studio 2019 Enterprise
  • Platform Target Frameworks:
    • Linux: WSL/Debian/10.2 or Docker mcr.microsoft.com/dotnet/core/sdk:3.1-buster

Reproduction Link

This commit shows the problem

This commit shows that loading a specific typeface solves the problem, but I guess the default typeface should work or at least throw an exception, so I consider this a bug

Maybe using the package SkiaSharp.NativeAssets.Linux that requires FontConfig etc also fixes this, but I haven’t tested that yet.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (16 by maintainers)

Most upvoted comments

So I just tested on the mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim Docker image, there are no fonts at all.

So how do we do this? You probably just want to copy your font files to the /usr/share/fonts/ directory.

This should fix it for you:

...
COPY --from=publish /app/publish/*.ttf /usr/share/fonts/
COPY --from=publish /app/publish .
...

If you copy the files there, you can just do this:

var paint = new SKPaint {
    Typeface = SKTypeface.FromFamilyName("Karla")
};

No need for files and all that. Just use the name.

You will get one heartthrob of an image:

test_Unix

After battling a bit I looked at the source and realized something. Linux is case-sensitive. Yay. In my tests, I was using the TIMES.TTF file that I copied from Windows.

Yay.

Ah, yeah. Or the first one.