Skip to content

Commit

Permalink
Merge pull request #380 from SixLabors/js/fix-375
Browse files Browse the repository at this point in the history
Fix Woff2 bounds decompression and size measurement calculations.
  • Loading branch information
JimBobSquarePants authored Feb 9, 2024
2 parents fa8a4c9 + 7c23ae8 commit cda8d06
Show file tree
Hide file tree
Showing 24 changed files with 463 additions and 355 deletions.
40 changes: 24 additions & 16 deletions samples/DrawWithImageSharp/BoundingBoxes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,49 @@
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using IOPath = System.IO.Path;

namespace DrawWithImageSharp;

public static class BoundingBoxes
{
public static void Generate(string text, Font font)
public static void Generate(string text, TextOptions options)
{
using var img = new Image<Rgba32>(1000, 1000);
img.Mutate(x => x.Fill(Color.White));
FontRectangle bounds = TextMeasurer.MeasureBounds(text, options);
FontRectangle advance = TextMeasurer.MeasureAdvance(text, options);
using Image<Rgba32> image = new((int)Math.Ceiling(options.Origin.X + (Math.Max(advance.Width, bounds.Width) + 1)), (int)Math.Ceiling(options.Origin.Y + (Math.Max(advance.Height, bounds.Height) + 1)));
image.Mutate(x => x.Fill(Color.White));

TextOptions options = new(font);
FontRectangle box = TextMeasurer.MeasureBounds(text, options);
(IPathCollection paths, IPathCollection boxes) = GenerateGlyphsWithBox(text, options);

Rgba32 f = Color.Fuchsia;
f.A = 128;
Vector2 origin = options.Origin;

img.Mutate(x => x.Fill(Color.Black, paths)
.Draw(f, 1, boxes)
.Draw(Color.Lime, 1, new RectangularPolygon(box.Location, box.Size)));
FontRectangle size = TextMeasurer.MeasureSize(text, options);

img.Save("Output/Boxed.png");
(IPathCollection paths, IPathCollection boxes) = GenerateGlyphsWithBox(text, options);
image.Mutate(
x => x.Fill(Color.Black, paths)
.Draw(Color.Yellow, 1, boxes)
.Draw(Color.Purple, 1, new RectangularPolygon(bounds.X, bounds.Y, bounds.Width, bounds.Height))
.Draw(Color.Green, 1, new RectangularPolygon(size.X + bounds.X, size.Y + bounds.Y, size.Width, size.Height))
.Draw(Color.Red, 1, new RectangularPolygon(advance.X + origin.X, advance.Y + origin.Y, advance.Width, advance.Height)));

string path = IOPath.GetInvalidFileNameChars().Aggregate(text, (x, c) => x.Replace($"{c}", "-"));
string fullPath = IOPath.GetFullPath(IOPath.Combine($"Output/Boxed/{options.Font.Name}", IOPath.Combine(path)));
Directory.CreateDirectory(IOPath.GetDirectoryName(fullPath));

image.Save($"{fullPath}.png");
}

/// <summary>
/// Generates the shapes corresponding the glyphs described by the font and with the setting ing withing the FontSpan
/// Generates the shapes corresponding the glyphs described by the font and settings.
/// </summary>
/// <param name="text">The text to generate glyphs for</param>
/// <param name="options">The style and settings to use while rendering the glyphs</param>
/// <returns>The paths, boxes, and text box.</returns>
private static (IPathCollection Paths, IPathCollection Boxes) GenerateGlyphsWithBox(string text, TextOptions options)
{
var glyphBuilder = new CustomGlyphBuilder(Vector2.Zero);
CustomGlyphBuilder glyphBuilder = new();

var renderer = new TextRenderer(glyphBuilder);
TextRenderer renderer = new(glyphBuilder);

renderer.RenderText(text, options);

Expand Down
8 changes: 4 additions & 4 deletions samples/DrawWithImageSharp/CustomGlyphBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ public CustomGlyphBuilder(Vector2 origin)
/// <summary>
/// Gets the paths that have been rendered by this.
/// </summary>
public IPathCollection Boxes => new PathCollection(this.glyphBounds.Select(x => new RectangularPolygon(x.Location, x.Size)));
public IPathCollection Boxes => new PathCollection(this.glyphBounds.Select(x => new RectangularPolygon(x.X, x.Y, x.Width, x.Height)));

/// <summary>
/// Gets the paths that have been rendered by this builder.
/// </summary>
public IPath TextBox { get; private set; }

protected override void BeginText(in FontRectangle rect)
protected override void BeginText(in FontRectangle bounds)
{
this.TextBox = new RectangularPolygon(rect.Location, rect.Size);
base.BeginText(rect);
this.TextBox = new RectangularPolygon(bounds.X, bounds.Y, bounds.Width, bounds.Height);
base.BeginText(bounds);
}

protected override void BeginGlyph(in FontRectangle bounds, in GlyphRendererParameters parameters)
Expand Down
108 changes: 63 additions & 45 deletions samples/DrawWithImageSharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,21 @@ public static void Main(string[] args)
FontFamily wendyOne = fonts.Add(IOPath.Combine("Fonts", "WendyOne-Regular.ttf"));

Check warning on line 28 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, ubuntu-latest, net6.0, 6.0.x, -x64, false)

The behavior of 'FontCollection.Add(string)' could vary based on the current user's locale settings. Replace this call in 'Program.Main(string[])' with a call to 'FontCollection.Add(string, CultureInfo)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1304)

Check warning on line 28 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, macos-latest, net6.0, 6.0.x, -x64, false)

The behavior of 'FontCollection.Add(string)' could vary based on the current user's locale settings. Replace this call in 'Program.Main(string[])' with a call to 'FontCollection.Add(string, CultureInfo)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1304)
FontFamily whitneyBook = fonts.Add(IOPath.Combine("Fonts", "whitney-book.ttf"));
FontFamily colorEmoji = fonts.Add(IOPath.Combine("Fonts", "Twemoji Mozilla.ttf"));
FontFamily font2 = fonts.Add(IOPath.Combine("Fonts", "OpenSans-Regular.ttf"));
FontFamily openSans = fonts.Add(IOPath.Combine("Fonts", "OpenSans-Regular.ttf"));
FontFamily sunflower = fonts.Add(IOPath.Combine("Fonts", "Sunflower-Medium.ttf"));
FontFamily bugzilla = fonts.Add(IOPath.Combine("Fonts", "me_quran_volt_newmet.ttf"));

FontFamily notoKR = fonts.Add(IOPath.Combine("Fonts", "NotoSansKR-Regular.otf"));
FontFamily marker = fonts.Add(IOPath.Combine("Fonts", "PermanentMarker-Regular.ttf"));

FontFamily sEmji = fonts.Add(IOPath.Combine("Fonts", "seguiemj-win11.ttf"));
BoundingBoxes.Generate("\U0001F469\U0001F3FB\u200D\U0001F91D\u200D\U0001F469\U0001F3FC", new TextOptions(sEmji.CreateFont(72)) { LineSpacing = 1.4f });
BoundingBoxes.Generate("\U0001F46D\U0001F3FB", new TextOptions(sEmji.CreateFont(72)) { LineSpacing = 1.4f });
BoundingBoxes.Generate("È", new TextOptions(marker.CreateFont(142)) { LineSpacing = 1.4f });
BoundingBoxes.Generate("H", new TextOptions(whitneyBook.CreateFont(25)));

openSans.TryGetMetrics(FontStyle.Regular, out FontMetrics metrics);
BoundingBoxes.Generate("A\nA\nA\nA", new TextOptions(openSans.CreateFont(metrics.UnitsPerEm)) { LineSpacing = 1.5f });

RenderText(notoKR, "\uD734", pointSize: 72);
RenderText(notoKR, "Sphinx of black quartz, judge my vow!", pointSize: 72);
Expand All @@ -47,16 +57,28 @@ public static void Main(string[] args)

#if OS_WINDOWS

FontFamily arial = SystemFonts.Get("Arial");
FontFamily jhengHei = SystemFonts.Get("Microsoft JhengHei");
FontFamily emojiFont = SystemFonts.Get("Segoe UI Emoji");
FontFamily uiFont = SystemFonts.Get("Segoe UI");
FontFamily arabicFont = SystemFonts.Get("Dubai");

FontFamily tahoma = SystemFonts.Get("Tahoma");

RenderText(SystemFonts.Get("Arial"), "abcdefghijklmnopqrstuvwxyz", pointSize: 30);
RenderText(SystemFonts.Get("Arial"), "abcdefghijklmnopqrstuvwxyz\r\nabcdefghijklmnopqrstuvwxyz", pointSize: 30);
RenderText(SystemFonts.Get("Arial"), "abcdef ghijk lmnopq rstuvwxyz", pointSize: 30);
BoundingBoxes.Generate(
"This is a long and Honorificabilitudinitatibus califragilisticexpialidocious Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu グレートブリテンおよび北アイルランド連合王国という言葉は本当に長い言葉",
new TextOptions(arial.CreateFont(20))
{
WrappingLength = 400,
LayoutMode = LayoutMode.HorizontalBottomTop,
WordBreaking = WordBreaking.Standard,
FallbackFontFamilies = new[] { jhengHei }
});

return;
RenderText(arial, "abcdefghijklmnopqrstuvwxyz", pointSize: 30);

Check warning on line 78 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, windows-latest, net7.0, 7.0.x, true, -x64, false)

Unreachable code detected

Check warning on line 78 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, windows-latest, net6.0, 6.0.x, -x64, true)

Unreachable code detected
RenderText(arial, "abcdefghijklmnopqrstuvwxyz\r\nabcdefghijklmnopqrstuvwxyz", pointSize: 30);
RenderText(arial, "abcdef ghijk lmnopq rstuvwxyz", pointSize: 30);
// return;

Check warning on line 81 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, windows-latest, net7.0, 7.0.x, true, -x64, false)

Check warning on line 81 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, windows-latest, net7.0, 7.0.x, true, -x64, false)

Check warning on line 81 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, windows-latest, net6.0, 6.0.x, -x64, true)

Check warning on line 81 in samples/DrawWithImageSharp/Program.cs

View workflow job for this annotation

GitHub Actions / Build (false, windows-latest, net6.0, 6.0.x, -x64, true)


var textRuns = new List<RichTextRun>
{
Expand All @@ -80,19 +102,19 @@ public static void Main(string[] args)
};
RenderText(bugzilla, arabic, pointSize: 72, textRuns: textRuns);

RenderText(font2, "\uFB01", pointSize: 11.25F);
RenderText(openSans, "\uFB01", pointSize: 11.25F);
RenderText(fontWoff2, "\uFB01", pointSize: 11.25F);
RenderText(tahoma, "p", pointSize: 11.25F);
RenderText(tahoma, "Lorem ipsum dolor sit amet", pointSize: 11.25F);
RenderText(uiFont, "Soft\u00ADHyphen", pointSize: 72);

RenderText(uiFont, "Soft\u00ADHyphen", pointSize: 72);

RenderText(uiFont, "first\n\n\n\nl", pointSize: 20, fallbackFonts: new[] { font2 });
RenderText(uiFont, "first\n\n\n\nl", pointSize: 20, fallbackFonts: new[] { openSans });

RenderText(uiFont, "first\n\n\n\nlast", pointSize: 20, fallbackFonts: new[] { font2 });
RenderText(uiFont, "first\n\n\n\nlast", pointSize: 20, fallbackFonts: new[] { openSans });
RenderText(uiFont, "Testing", pointSize: 20);
RenderText(emojiFont, "👩🏽‍🚒a", pointSize: 72, fallbackFonts: new[] { font2 });
RenderText(emojiFont, "👩🏽‍🚒a", pointSize: 72, fallbackFonts: new[] { openSans });
RenderText(arabicFont, "English اَلْعَرَبِيَّةُ English", pointSize: 20);
RenderText(arabicFont, "English English", pointSize: 20);
RenderText(arabicFont, "اَلْعَرَبِيَّةُ اَلْعَرَبِيَّةُ", pointSize: 20);
Expand All @@ -102,70 +124,66 @@ public static void Main(string[] args)
RenderText(arabicFont, "English اَلْعَرَبِيَّةُ", pointSize: 20);

RenderTextProcessorWithAlignment(emojiFont, "😀A😀", pointSize: 20, fallbackFonts: new[] { colorEmoji });
RenderTextProcessorWithAlignment(uiFont, "this\nis\na\ntest", pointSize: 20, fallbackFonts: new[] { font2 });
RenderTextProcessorWithAlignment(uiFont, "first\n\n\n\nlast", pointSize: 20, fallbackFonts: new[] { font2 });
RenderTextProcessorWithAlignment(uiFont, "this\nis\na\ntest", pointSize: 20, fallbackFonts: new[] { openSans });
RenderTextProcessorWithAlignment(uiFont, "first\n\n\n\nlast", pointSize: 20, fallbackFonts: new[] { openSans });

RenderText(emojiFont, "😀", pointSize: 72, fallbackFonts: new[] { font2 });
RenderText(font2, string.Empty, pointSize: 72, fallbackFonts: new[] { emojiFont });
RenderText(font2, "😀 Hello World! 😀", pointSize: 72, fallbackFonts: new[] { emojiFont });
RenderText(emojiFont, "😀", pointSize: 72, fallbackFonts: new[] { openSans });
RenderText(openSans, string.Empty, pointSize: 72, fallbackFonts: new[] { emojiFont });
RenderText(openSans, "😀 Hello World! 😀", pointSize: 72, fallbackFonts: new[] { emojiFont });
#endif

// fallback font tests
RenderTextProcessor(colorEmoji, "a😀d", pointSize: 72, fallbackFonts: new[] { font2 });
RenderText(colorEmoji, "a😀d", pointSize: 72, fallbackFonts: new[] { font2 });
RenderTextProcessor(colorEmoji, "a😀d", pointSize: 72, fallbackFonts: new[] { openSans });
RenderText(colorEmoji, "a😀d", pointSize: 72, fallbackFonts: new[] { openSans });

RenderText(colorEmoji, "😀", pointSize: 72, fallbackFonts: new[] { font2 });
RenderText(colorEmoji, "😀", pointSize: 72, fallbackFonts: new[] { openSans });

//// general
RenderText(font, "abc", 72);
RenderText(font, "ABd", 72);
RenderText(fontWoff, "abe", 72);
RenderText(fontWoff, "ABf", 72);
RenderText(fontWoff2, "woff2", 72);
RenderText(font2, "ov", 72);
RenderText(font2, "a\ta", 72);
RenderText(font2, "aa\ta", 72);
RenderText(font2, "aaa\ta", 72);
RenderText(font2, "aaaa\ta", 72);
RenderText(font2, "aaaaa\ta", 72);
RenderText(font2, "aaaaaa\ta", 72);
RenderText(font2, "Hello\nWorld", 72);
RenderText(openSans, "ov", 72);
RenderText(openSans, "a\ta", 72);
RenderText(openSans, "aa\ta", 72);
RenderText(openSans, "aaa\ta", 72);
RenderText(openSans, "aaaa\ta", 72);
RenderText(openSans, "aaaaa\ta", 72);
RenderText(openSans, "aaaaaa\ta", 72);
RenderText(openSans, "Hello\nWorld", 72);
RenderText(carter, "Hello\0World", 72);
RenderText(wendyOne, "Hello\0World", 72);
RenderText(whitneyBook, "Hello\0World", 72);
RenderText(sunflower, "í", 30);

RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 4 }, "\t\tx");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 4 }, "\t\t\tx");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 4 }, "\t\t\t\tx");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 4 }, "\t\t\t\t\tx");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 4 }, "\t\tx");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 4 }, "\t\t\tx");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 4 }, "\t\t\t\tx");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 4 }, "\t\t\t\t\tx");

RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 0 }, "Zero\tTab");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 0 }, "Zero\tTab");

RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 0 }, "Zero\tTab");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 1 }, "One\tTab");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 6 }, "\tTab Then Words");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 1 }, "Tab Then Words");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 1 }, "Words Then Tab\t");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 1 }, " Spaces Then Words");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 1 }, "Words Then Spaces ");
RenderText(new RichTextOptions(new Font(font2, 72)) { TabWidth = 1 }, "\naaaabbbbccccddddeeee\n\t\t\t3 tabs\n\t\t\t\t\t5 tabs");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 0 }, "Zero\tTab");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 1 }, "One\tTab");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 6 }, "\tTab Then Words");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 1 }, "Tab Then Words");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 1 }, "Words Then Tab\t");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 1 }, " Spaces Then Words");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 1 }, "Words Then Spaces ");
RenderText(new RichTextOptions(new Font(openSans, 72)) { TabWidth = 1 }, "\naaaabbbbccccddddeeee\n\t\t\t3 tabs\n\t\t\t\t\t5 tabs");

#if OS_WINDOWS
RenderText(new Font(SystemFonts.Get("Arial"), 20f, FontStyle.Regular), "á é í ó ú ç ã õ", 200, 50);
RenderText(new Font(SystemFonts.Get("Arial"), 10f, FontStyle.Regular), "PGEP0JK867", 200, 50);
RenderText(new RichTextOptions(SystemFonts.CreateFont("consolas", 72)) { TabWidth = 4 }, "xxxxxxxxxxxxxxxx\n\txxxx\txxxx\n\t\txxxxxxxx\n\t\t\txxxx");
BoundingBoxes.Generate("a b c y q G H T", SystemFonts.CreateFont("arial", 40f));
BoundingBoxes.Generate("a b c y q G H T", new TextOptions(SystemFonts.CreateFont("arial", 40f)));
TextAlignmentSample.Generate(SystemFonts.CreateFont("arial", 50f));
TextAlignmentWrapped.Generate(SystemFonts.CreateFont("arial", 50f));

FontFamily simsum = SystemFonts.Get("SimSun");
RenderText(simsum, "这是一段长度超出设定的换行宽度的文本,但是没有在设定的宽度处换行。这段文本用于演示问题。希望可以修复。如果有需要可以联系我。", 16);

FontFamily jhengHei = SystemFonts.Get("Microsoft JhengHei");
RenderText(jhengHei, " ,;:!¥()?{}-=+\|~!@#%&", 16);

FontFamily arial = SystemFonts.Get("Arial");
RenderText(arial, "ìíîï", 72);
#endif
var sb = new StringBuilder();
Expand Down Expand Up @@ -211,7 +229,7 @@ public static void RenderText(Font font, string text, int width, int height)

public static void RenderText(RichTextOptions options, string text)
{
FontRectangle size = TextMeasurer.MeasureSize(text, options);
FontRectangle size = TextMeasurer.MeasureAdvance(text, options);
if (size == FontRectangle.Empty)
{
return;
Expand Down Expand Up @@ -253,7 +271,7 @@ public static void RenderTextProcessor(
textOptions.FallbackFontFamilies = fallbackFonts.ToArray();
}

FontRectangle textSize = TextMeasurer.MeasureSize(text, textOptions);
FontRectangle textSize = TextMeasurer.MeasureAdvance(text, textOptions);
textOptions.Origin = new PointF(5, 5);

using var img = new Image<Rgba32>((int)Math.Ceiling(textSize.Width) + 20, (int)Math.Ceiling(textSize.Height) + 20);
Expand Down
4 changes: 2 additions & 2 deletions src/SixLabors.Fonts/GlyphLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ internal GlyphLayout(
/// Gets a value indicating whether the glyph represents a whitespace character.
/// </summary>
/// <returns>The <see cref="bool"/>.</returns>
public bool IsWhiteSpace() => GlyphMetrics.ShouldRenderWhiteSpaceOnly(this.CodePoint);
public bool IsWhiteSpace() => UnicodeUtility.ShouldRenderWhiteSpaceOnly(this.CodePoint);

internal FontRectangle BoundingBox(float dpi)
{
Vector2 origin = (this.PenLocation + this.Offset) * dpi;
FontRectangle box = this.Glyph.BoundingBox(this.LayoutMode, Vector2.Zero, dpi);
FontRectangle box = this.Glyph.BoundingBox(this.LayoutMode, this.BoxLocation, dpi);

if (this.IsWhiteSpace())
{
Expand Down
34 changes: 1 addition & 33 deletions src/SixLabors.Fonts/GlyphMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,39 +401,7 @@ void SetDecoration(TextDecorations decorations, float thickness, float position)
/// <returns>The <see cref="bool"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected internal static bool ShouldSkipGlyphRendering(CodePoint codePoint)
=> UnicodeUtility.IsDefaultIgnorableCodePoint((uint)codePoint.Value) && !ShouldRenderWhiteSpaceOnly(codePoint);

/// <summary>
/// Gets a value indicating whether the specified code point should be rendered as a white space only.
/// </summary>
/// <param name="codePoint">The code point.</param>
/// <returns>The <see cref="bool"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool ShouldRenderWhiteSpaceOnly(CodePoint codePoint)
{
if (CodePoint.IsWhiteSpace(codePoint))
{
return true;
}

// Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
// we do NOT want to hide them, as the way Uniscribe has implemented them
// is with regular spacing glyphs, and that's the way fonts are made to work.
// As such, we make exceptions for those four.
// Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503
uint value = (uint)codePoint.Value;
if (value is 0x115F or 0x1160 or 0x3164 or 0xFFA0)
{
return true;
}

if (UnicodeUtility.IsInRangeInclusive(value, 0x1BCA0, 0x1BCA3))
{
return true;
}

return false;
}
=> UnicodeUtility.IsDefaultIgnorableCodePoint((uint)codePoint.Value) && !UnicodeUtility.ShouldRenderWhiteSpaceOnly(codePoint);

/// <summary>
/// Returns the size to render/measure the glyph based on the given size and resolution in px units.
Expand Down
Loading

0 comments on commit cda8d06

Please sign in to comment.