Announcing Fonts 1.0.0

Fonts v1 - We control the horizontal and the vertical

We are very excited to announce the release of SixLabors.Fonts 1.0.0 final. You can download it today.

SixLabors.Fonts is a cross-platform font loading and text layout library for .NET. It's designed to be fast, lightweight, and easy to use. It supports TrueType, OpenType, and WOFF fonts on Windows, Linux, and macOS. It's also the font engine behind SixLabors.ImageSharp.Drawing.

This release is a monumental work, the culmination of 6 years of effort and we're really proud of what we have achieved.

SixLabors.Fonts supports a wide range of font features including:

  • Kerning
  • Ligatures
  • Complex shaping
  • Bidirectional text
  • Font and glyph metrics

It also supports a wide range of text layout features including:

  • Text wrapping
  • Text alignment
  • Text justification
  • Vertical text (including mixed layout)
  • Measuring individual glyphs and text.
  • Rich text formatting (underline, overline, strikethrough, superscript, subscript, etc)

Not only that it provides APIs that allow:

  • Enumeration of codepoints within a string.
  • Provision of details about each codepoint.
  • Enumeration of graphemes within a string.
  • Enumeration of line breaks within a string.

SixLabors.Fonts provides an API that is easy to use and understand. It's designed to be familiar to anyone who has used the System.Drawing and SkiaSharp .NET drawing APIs but with far greater flexibility. It can be used to render text to any .NET drawing surface by providing a simple interface IGlyphRenderer.

This is an extraordinarily powerful library, brimming with rock solid features and as we promised back
in July 2022 we're making sure that all v1.x releases are Open Source and free to use.

v1.x is licensed under the Apache 2.0 license.

Examples #

Measuring text is easy: In the following example we measure the advance, size, and bounds of the text "Hello World!" using the Open Sans font.

FontFamily family = new FontCollection().Add(TestFonts.OpenSansFile);
family.TryGetMetrics(FontStyle.Regular, out FontMetrics metrics);

TextOptions options = new(family.CreateFont(metrics.UnitsPerEm))
{
    LineSpacing = 1.5F
};

const string text = "Hello World!";
FontRectangle advance = TextMeasurer.MeasureAdvance(text, options);
FontRectangle size = TextMeasurer.MeasureSize(text, options);
FontRectangle bounds = TextMeasurer.MeasureBounds(text, options);

You can even measure those properties for individual glyphs:

FontFamily family = new FontCollection().Add(TestFonts.OpenSansFile);
family.TryGetMetrics(FontStyle.Regular, out FontMetrics metrics);

TextOptions options = new(family.CreateFont(metrics.UnitsPerEm))
{
    LineSpacing = 1.5F
};

const string text = "Hello World!";

TextMeasurer.TryMeasureCharacterAdvances(text, options, out ReadOnlySpan<GlyphBounds> advances);
TextMeasurer.TryMeasureCharacterSizes(text, options, out ReadOnlySpan<GlyphBounds> sizes);
TextMeasurer.TryMeasureCharacterBounds(text, options, out ReadOnlySpan<GlyphBounds> bounds);

Want to know whether a code point indicates a mandatory break? No problem!
This xUnit test demonstrates how to use the CodePoint type to determine whether a code point is a mandatory line break

[Fact]
public void CodePointIsMandatoryBreak()
{
    static bool IsLineBreakClassBreak(uint value)
    {
        // See https://www.unicode.org/standard/reports/tr13/tr13-5.html
        switch (value)
        {
            case 0x000A: // LINE FEED (LF)
            case 0x000B: // LINE TABULATION (VT)
            case 0x000C: // FORM FEED (FF)
            case 0x000D: // CARRIAGE RETURN (CR)
            case 0x0085: // NEXT LINE (NEL)
            case 0x2028: // LINE SEPARATOR (LS)
            case 0x2029: // PARAGRAPH SEPARATOR (PS)
                return true;
            default:
                return false;
        }
    }

    for (uint i = 0; i <= 0x10FFFFu; i++)
    {
        Assert.Equal(CodePoint.IsNewLine(new CodePoint(i)), IsLineBreakClassBreak(i));
    }
}

Please explore the API documentation. There's a lot to discover and we'll continue to update the supplementary documentation to provide further examples.

Before we sign off here's a preview of some of the cool things we've been able to do with ImageSharp.Drawing and Fonts:

Rich Text

Rich text

Emoji font rendering

Emoji font rendering

Complex shaping of Rich Arabic text

Complex shaping of Arabic text

The Future #

We'll be publishing new releases over the next few weeks of all our libraries that depend on SixLabors.Fonts. That means the first major version of SixLabors.ImageSharp.Drawing.

Closing #

Thanks again for all the feedback and usage. It's been a pleasure to build SixLabors.Fonts so far and to see so many people try it out; we really appreciate it. Please continue exploring the product and learning what it's capable of.