Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite Line Breaker. #438

Merged
merged 11 commits into from
Jan 8, 2025
Merged

Rewrite Line Breaker. #438

merged 11 commits into from
Jan 8, 2025

Conversation

JimBobSquarePants
Copy link
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following matches the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

A complete rewrite of the line breaker to fix a series of issues including #434 I've not benchmarked this but in addition to fixing bugs the code is now doing far less work per code point so should be faster.

I've also added testing that will generate output using ImageSharp.Drawing which allows us to better visualize the layout. Adding this helped identify multiple issues. The generation code is togglable via a compiler condition introduced via the csproj file. This allows us to turn them off should we introduce breaking changes.

All output has been sense checked and compared to browser output to ensure correctness.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 46 out of 66 changed files in this pull request and generated no comments.

Files not reviewed (20)
  • tests/Images/ReferenceOutput/CountLinesWrappingLength_100-4.png: Language not supported
  • tests/Images/ReferenceOutput/CountLinesWrappingLength_200-3.png: Language not supported
  • tests/Images/ReferenceOutput/CountLinesWrappingLength_25-6.png: Language not supported
  • tests/Images/ReferenceOutput/CountLinesWrappingLength_50-5.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalBottomTop-wordBreaking_BreakAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalBottomTop-wordBreaking_BreakWord.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalBottomTop-wordBreaking_KeepAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalBottomTop-wordBreaking_Standard.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalTopBottom-wordBreaking_BreakAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalTopBottom-wordBreaking_BreakWord.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalTopBottom-wordBreaking_KeepAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreakMatchesMDN_238-layoutMode_HorizontalTopBottom-wordBreaking_Standard.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalBottomTop-wordBreaking_BreakAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalBottomTop-wordBreaking_BreakWord.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalBottomTop-wordBreaking_KeepAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalBottomTop-wordBreaking_Standard.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalTopBottom-wordBreaking_BreakAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalTopBottom-wordBreaking_BreakWord.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalTopBottom-wordBreaking_KeepAll.png: Language not supported
  • tests/Images/ReferenceOutput/MeasureTextWordBreak_500-layoutMode_HorizontalTopBottom-wordBreaking_Standard.png: Language not supported
tocsoft
tocsoft previously approved these changes Jan 7, 2025
Copy link
Member

@tocsoft tocsoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm 👍

@JimBobSquarePants JimBobSquarePants merged commit bcea187 into main Jan 8, 2025
8 checks passed
@JimBobSquarePants JimBobSquarePants deleted the js/fix-line-break branch January 8, 2025 09:53
@jez9999
Copy link

jez9999 commented Jan 8, 2025

I've tried 2.0.8 against my bugs #431 and #434 and it seems to have fixed both issues. 👍

I would note however that it appears to have changed what ImageSharp considers to be the bounding box of the rendered text, based on WrappingLength. The first imgTest1 output from #431 now wraps after "Lorem ipsullll" unless I slightly increase the WrappingLength. Maybe the original behaviour was a bug that's also been fixed.

@JimBobSquarePants
Copy link
Member Author

I've tried 2.0.8 against my bugs #431 and #434 and it seems to have fixed both issues. 👍

I would note however that it appears to have changed what ImageSharp considers to be the bounding box of the rendered text, based on WrappingLength. The first imgTest1 output from #431 now wraps after "Lorem ipsullll" unless I slightly increase the WrappingLength. Maybe the original behaviour was a bug that's also been fixed.

I'm not sure I understand what you are saying. In your original issue the text wrapped following "Lorem ipsullll"

testImg1

@jez9999
Copy link

jez9999 commented Jan 9, 2025

With 2.0.6 I got:

testImg1

With 2.0.8 I get:

testImg1

@JimBobSquarePants
Copy link
Member Author

I see this in my tests.

[Fact]
public void ShouldNotInsertExtraLineBreaks()
{
    if (SystemFonts.TryGet("Arial", out FontFamily family))
    {
        Font font = family.CreateFont(60);
        const string text = "- Lorem ipsullll\ndolor sit amet\n-consectetur elit";

        TextOptions options = new(font)
        {
            Origin = new Vector2(50, 20),
            WrappingLength = 400,
        };

        int lineCount = TextMeasurer.CountLines(text, options);
        Assert.Equal(4, lineCount);

        IReadOnlyList<GlyphLayout> layout = TextLayout.GenerateLayout(text, options);
        Assert.Equal(46, layout.Count);

        TextLayoutTestUtilities.TestLayout(text, options);
    }
}

ShouldNotInsertExtraLineBreaks__WrappingLength_400_

@jez9999
Copy link

jez9999 commented Jan 9, 2025

Hmm, well I can't easily use TextLayoutTestUtilities because it's internal. Can't it just be made public?

@jez9999
Copy link

jez9999 commented Jan 9, 2025

Also I noticed your test string is - Lorem ipsullll\ndolor sit amet\n-consectetur elit, instead try - Lorem ipsullll dolor sit amet\n-consectetur elit without the explicit newline and it wraps. I think it's not considering a space at the end of a line to be a zero-width character, which it should be.

@JimBobSquarePants
Copy link
Member Author

Hmm, well I can't easily use TextLayoutTestUtilities because it's internal. Can't it just be made public?

Why would I make a test utility that doesn’t get published with any code public? You know the code is right here yeah? You can simply clone the repo and run it?

Please stop changing the goal posts and drip feeding me examples. I’m testing the strings provided in your issues and each test takes a lot of my time of which I have a limited capacity.

This is not only not helpful but incredibly frustrating.

@jez9999
Copy link

jez9999 commented Jan 9, 2025

OK well I'm sorry, I didn't intend that.

I tested it with the string - Lorem ipsullll dolor sit amet\n-consectetur elit and it appears to incorrectly line wrap the "ipsullll" in 2.0.8:

testImg1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants