Skip to content

Commit

Permalink
Merge branch 'main' into bp/anchor2
Browse files Browse the repository at this point in the history
  • Loading branch information
JimBobSquarePants authored Feb 26, 2022
2 parents bcf2bd3 + 0856c1f commit f4c9f35
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/SixLabors.Fonts/TextMeasurer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ public static FontRectangle MeasureBounds(ReadOnlySpan<char> text, TextOptions o
public static bool TryMeasureCharacterBounds(ReadOnlySpan<char> text, TextOptions options, out GlyphBounds[] characterBounds)
=> TextMeasurerInt.Default.TryMeasureCharacterBounds(text, options, out characterBounds);

/// <summary>
/// Gets the number of lines contained within the text.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="options">The style.</param>
/// <returns>The line count.</returns>
public static int CountLines(string text, TextOptions options)
=> TextMeasurerInt.Default.CountLines(text.AsSpan(), options);

/// <summary>
/// Gets the number of lines contained within the text.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="options">The style.</param>
/// <returns>The line count.</returns>
public static int CountLines(ReadOnlySpan<char> text, TextOptions options)
=> TextMeasurerInt.Default.CountLines(text, options);

internal static FontRectangle GetSize(IReadOnlyList<GlyphLayout> glyphLayouts, float dpi)
{
if (glyphLayouts.Count == 0)
Expand Down Expand Up @@ -195,6 +213,20 @@ internal FontRectangle Measure(ReadOnlySpan<char> text, TextOptions options)

return GetSize(glyphsToRender, options.Dpi);
}

/// <summary>
/// Gets the number of lines contained within the text.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="options">The style.</param>
/// <returns>The line count.</returns>
internal int CountLines(ReadOnlySpan<char> text, TextOptions options)
{
IReadOnlyList<GlyphLayout> glyphsToRender = this.layoutEngine.GenerateLayout(text, options);
int usedLines = glyphsToRender.Count(x => x.IsStartOfLine);

return usedLines;
}
}
}
}
45 changes: 45 additions & 0 deletions tests/SixLabors.Fonts.Tests/TextLayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,51 @@ public void MeasureTextLeadingFraction()
Assert.NotEqual(FontRectangle.Empty, measurement);
}

[Theory]
[InlineData("hello world", 1)]
[InlineData("hello world\nhello world", 2)]
[InlineData("hello world\nhello world\nhello world", 3)]
public void CountLines(string text, int usedLines)
{
Font font = CreateFont(text);
int count = TextMeasurer.CountLines(text, new TextOptions(font) { Dpi = font.FontMetrics.ScaleFactor });

Assert.Equal(usedLines, count);
}

[Fact]
public void CountLinesWithSpan()
{
Font font = CreateFont("hello\n!");

Span<char> text = stackalloc char[]
{
'h',
'e',
'l',
'l',
'o',
'\n',
'!'
};
int count = TextMeasurer.CountLines(text, new TextOptions(font) { Dpi = font.FontMetrics.ScaleFactor });

Assert.Equal(2, count);
}

[Theory]
[InlineData("This is a long and Honorificabilitudinitatibus califragilisticexpialidocious", 25, 7)]
[InlineData("This is a long and Honorificabilitudinitatibus califragilisticexpialidocious", 50, 7)]
[InlineData("This is a long and Honorificabilitudinitatibus califragilisticexpialidocious", 100, 6)]
[InlineData("This is a long and Honorificabilitudinitatibus califragilisticexpialidocious", 200, 6)]
public void CountLinesWrappingLength(string text, int wrappingLength, int usedLines)
{
Font font = CreateFont(text);
int count = TextMeasurer.CountLines(text, new TextOptions(font) { Dpi = font.FontMetrics.ScaleFactor, WrappingLength = wrappingLength });

Assert.Equal(usedLines, count);
}

public static Font CreateFont(string text)
{
var fc = (IFontMetricsCollection)new FontCollection();
Expand Down

0 comments on commit f4c9f35

Please sign in to comment.