aboutsummaryrefslogtreecommitdiff
path: root/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Jellyfin.Drawing.Skia/SkiaEncoder.cs')
-rw-r--r--src/Jellyfin.Drawing.Skia/SkiaEncoder.cs40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index 2dac5598f..99f7fa7f9 100644
--- a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.Linq;
using BlurHashSharp.SkiaSharp;
using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
@@ -24,6 +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;
#pragma warning disable CA1810
static SkiaEncoder()
@@ -46,6 +48,21 @@ public class SkiaEncoder : IImageEncoder
kernelOffset,
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
+ ];
}
/// <summary>
@@ -98,6 +115,11 @@ public class SkiaEncoder : IImageEncoder
=> new HashSet<ImageFormat> { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png, ImageFormat.Svg };
/// <summary>
+ /// Gets the default typeface to use.
+ /// </summary>
+ public static SKTypeface DefaultTypeFace => _typefaces.Last();
+
+ /// <summary>
/// Check if the native lib is available.
/// </summary>
/// <returns>True if the native lib is available, otherwise false.</returns>
@@ -705,4 +727,22 @@ public class SkiaEncoder : IImageEncoder
_logger.LogError(ex, "Error drawing indicator overlay");
}
}
+
+ /// <summary>
+ /// Return the typeface that contains the glyph for the given character.
+ /// </summary>
+ /// <param name="c">The text character.</param>
+ /// <returns>The typeface contains the character.</returns>
+ public static SKTypeface? GetFontForCharacter(string c)
+ {
+ foreach (var typeface in _typefaces)
+ {
+ if (typeface.ContainsGlyphs(c))
+ {
+ return typeface;
+ }
+ }
+
+ return null;
+ }
}