toptensoftware / RichTextKit

Rich text rendering for SkiaSharp
Other
361 stars 74 forks source link

Annoying style issue with paragraph separators #85

Open dbriard opened 1 year ago

dbriard commented 1 year ago

I run into an annoying issue when creating a RichTextBox from RichTextKit. The paragraph separators in the TextDocument have their own Style which is not the same as the previous text.

I am doing update to the TextDocument using range.Normalized.Clamp(Length - 1) so the final separator is never include in the update (I tried to include it but it crash). And so, when I change the style of the text, the separator's style do not change and stay with DefaultStyle. The FontMaper will always request the typeface of the separator font, even if it is not visible in the document. Moreover, when I select all text and replace it (by typing), it use the last separator style (or the default style?).

I have same issue between paragraph, if for example I select the text of a paragraph, its last character (separator) do not change style...

StyleRuns look like: if I have 3 styles A, B, C, there is still another style S at the end of paragraphs. Which is not always the same (if I update text by selecting text crossing N paragraphs).

AAAAAAAAAS BBBBBBBBBBS CCCCCCS

For my own use, I created a quick and dirty fix: FixEndOfParagraphStyle() function in TextDocument, which is called in Reset event, and in DocumentDidChange event, to always update the paragraph separator style with previous text style. I hope that do not affect the Undo/Redo...

public void FixEndOfParagraphStyle()
        {
            foreach (var paragraph in _paragraphs)
            {
                var textBlock = paragraph.TextBlock;
                var runs = textBlock.StyleRuns;
                if (runs.Count > 1)
                {
                    var lastRun = runs[runs.Count - 1];
                    if (lastRun.Length == 1)
                    {
                        Debug.Assert(lastRun.CodePoints[0] == '\u2029');
                        lastRun.Style = runs[runs.Count - 2].Style;
                    }
                }
            }
        }

I am not sure what would be the best way to resolve this issue in a clean way???

toptensoftware commented 1 year ago

I'm not sure off hand what's going on here, but you should be able to include the end separator in the range and update its style - if it's crashing that'd be a bug I think, but I'd need to debug through it to know for sure.