Backport pull request #16369 from jellyfin/release-10.11.z
Some checks failed
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled

Fix nullref ex in font handling

Original-merge: 41c2d51d8c

Merged-by: Bond-009 <bond.009@outlook.com>

Backported-by: Bond_009 <bond.009@outlook.com>
This commit is contained in:
Bond-009
2026-03-29 14:28:41 -04:00
committed by Bond_009
parent ea206f43a2
commit a3960b30c0

View File

@@ -25,7 +25,7 @@ public class SkiaEncoder : IImageEncoder
private readonly ILogger<SkiaEncoder> _logger;
private readonly IApplicationPaths _appPaths;
private static readonly SKImageFilter _imageFilter;
private static readonly SKTypeface[] _typefaces;
private static readonly SKTypeface?[] _typefaces = InitializeTypefaces();
/// <summary>
/// The default sampling options, equivalent to old high quality filter settings when upscaling.
@@ -37,9 +37,7 @@ public class SkiaEncoder : IImageEncoder
/// </summary>
public static readonly SKSamplingOptions DefaultSamplingOptions;
#pragma warning disable CA1810
static SkiaEncoder()
#pragma warning restore CA1810
{
var kernel = new[]
{
@@ -59,21 +57,6 @@ public class SkiaEncoder : IImageEncoder
SKShaderTileMode.Clamp,
true);
// Initialize the list of typefaces
// We have to statically build a list of typefaces because MatchCharacter only accepts a single character or code point
// But in reality a human-readable character (grapheme cluster) could be multiple code points. For example, 🚵🏻‍♀️ is a single emoji but 5 code points (U+1F6B5 + U+1F3FB + U+200D + U+2640 + U+FE0F)
_typefaces =
[
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, '鸡'), // CJK Simplified Chinese
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, '雞'), // CJK Traditional Chinese
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, ''), // CJK Japanese
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, '각'), // CJK Korean
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, 128169), // Emojis, 128169 is the 💩emoji
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, 'ז'), // Hebrew
SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, 'ي'), // Arabic
SKTypeface.FromFamilyName("sans-serif", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright) // Default font
];
// use cubic for upscaling
UpscaleSamplingOptions = new SKSamplingOptions(SKCubicResampler.Mitchell);
// use bilinear for everything else
@@ -132,7 +115,7 @@ public class SkiaEncoder : IImageEncoder
/// <summary>
/// Gets the default typeface to use.
/// </summary>
public static SKTypeface DefaultTypeFace => _typefaces.Last();
public static SKTypeface? DefaultTypeFace => _typefaces.Last();
/// <summary>
/// Check if the native lib is available.
@@ -152,6 +135,40 @@ public class SkiaEncoder : IImageEncoder
}
}
/// <summary>
/// Initialize the list of typefaces
/// We have to statically build a list of typefaces because MatchCharacter only accepts a single character or code point
/// But in reality a human-readable character (grapheme cluster) could be multiple code points. For example, 🚵🏻‍♀️ is a single emoji but 5 code points (U+1F6B5 + U+1F3FB + U+200D + U+2640 + U+FE0F)
/// </summary>
/// <returns>The list of typefaces.</returns>
private static SKTypeface?[] InitializeTypefaces()
{
int[] chars = [
'鸡', // CJK Simplified Chinese
'雞', // CJK Traditional Chinese
'', // CJK Japanese
'각', // CJK Korean
128169, // Emojis, 128169 is the Pile of Poo (💩) emoji
'ז', // Hebrew
'ي' // Arabic
];
var fonts = new List<SKTypeface>(chars.Length + 1);
foreach (var ch in chars)
{
var font = SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, ch);
if (font is not null)
{
fonts.Add(font);
}
}
// Default font
fonts.Add(SKTypeface.FromFamilyName("sans-serif", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright)
?? SKFontManager.Default.MatchCharacter(null, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright, null, 'a'));
return fonts.ToArray();
}
/// <summary>
/// Convert a <see cref="ImageFormat"/> to a <see cref="SKEncodedImageFormat"/>.
/// </summary>
@@ -809,7 +826,7 @@ public class SkiaEncoder : IImageEncoder
{
foreach (var typeface in _typefaces)
{
if (typeface.ContainsGlyphs(c))
if (typeface is not null && typeface.ContainsGlyphs(c))
{
return typeface;
}