From 9fed84ed2d03b298e76a816423b033f8a9e6766e Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Wed, 16 Mar 2022 15:34:34 -0700 Subject: [PATCH] Handle newlines in FormattedText --- src/Eto.Gtk/Drawing/FormattedTextHandler.cs | 212 +++++++++++++++--- src/Eto.Gtk/Drawing/GraphicsHandler.cs | 7 +- src/Eto.Mac/Drawing/FormattedTextHandler.cs | 70 ++++-- .../Drawing/FormattedTextHandler.cs | 106 +++++---- src/Eto.Wpf/Drawing/FormattedTextHandler.cs | 53 ++++- .../Sections/Behaviors/AllControlsBase.cs | 32 ++- .../Sections/Controls/LabelSection.cs | 2 +- .../Sections/Controls/RichTextAreaSection.cs | 2 +- .../Sections/Controls/TextAreaSection.cs | 2 +- .../Sections/Drawing/FormattedTextSection.cs | 65 +++++- test/Eto.Test/UnitTests/Drawing/FontTests.cs | 13 +- test/Eto.Test/UnitTests/Forms/WindowTests.cs | 2 +- test/Eto.Test/Utility.cs | 5 +- 13 files changed, 455 insertions(+), 116 deletions(-) diff --git a/src/Eto.Gtk/Drawing/FormattedTextHandler.cs b/src/Eto.Gtk/Drawing/FormattedTextHandler.cs index 5908156612..e4f675680c 100644 --- a/src/Eto.Gtk/Drawing/FormattedTextHandler.cs +++ b/src/Eto.Gtk/Drawing/FormattedTextHandler.cs @@ -1,47 +1,182 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using Eto.Drawing; namespace Eto.GtkSharp.Drawing { public class FormattedTextHandler : WidgetHandler, FormattedText.IHandler { - public FormattedTextWrapMode Wrap { get; set; } - public FormattedTextTrimming Trimming { get; set; } - public string Text { get; set; } - public SizeF MaximumSize { get; set; } = SizeF.MaxValue; - public Font Font { get; set; } - public Brush ForegroundBrush { get; set; } = new SolidBrush(SystemColors.ControlText); - public FormattedTextAlignment Alignment { get; set; } - public int MaximumLineCount { get; set; } + FormattedTextWrapMode _wrap; + FormattedTextTrimming _trimming; + string _text; + SizeF _maximumSize = SizeF.MaxValue; + Font _font; + Brush _foregroundBrush = new SolidBrush(SystemColors.ControlText); + FormattedTextAlignment _alignment; + int _maximumLineCount; + bool _shouldClip; + + public FormattedTextWrapMode Wrap + { + get => _wrap; + set + { + if (_wrap != value) + { + _wrap = value; + Invalidate(); + } + } + } + public FormattedTextTrimming Trimming + { + get => _trimming; + set + { + if (_trimming != value) + { + _trimming = value; + Invalidate(); + } + } + } + public string Text + { + get => _text; + set + { + if (_text != value) + { + _text = value; + Invalidate(); + } + } + } + + public SizeF MaximumSize + { + get => _maximumSize; + set + { + if (_maximumSize != value) + { + _maximumSize = value; + Invalidate(); + } + } + } + + public Font Font + { + get => _font; + set + { + if (_font != value) + { + _font = value; + Invalidate(); + } + } + } + + public Brush ForegroundBrush + { + get => _foregroundBrush; + set + { + if (_foregroundBrush != value) + { + _foregroundBrush = value; + Invalidate(); + } + } + } + + public FormattedTextAlignment Alignment + { + get => _alignment; + set + { + if (_alignment != value) + { + _alignment = value; + Invalidate(); + } + } + } + public int MaximumLineCount + { + get => _maximumLineCount; + set + { + if (_maximumLineCount != value) + { + _maximumLineCount = value; + Invalidate(); + } + } + } + + void Invalidate() + { + _layout?.Dispose(); + _layout = null; + } public SizeF Measure() { // can we do this more lightweight than creating a control? - using (var ctl = new Gtk.Label()) - using (var layout = new Pango.Layout(ctl.PangoContext)) + if (_layout == null) { - Setup(layout); - layout.GetPixelSize(out var width, out var height); - return new SizeF(width, height); + EnsureLayout(new Gtk.Label().PangoContext); } + _layout.GetPixelSize(out var width, out var height); + var size = new SizeF(width, height); + if (Wrap == FormattedTextWrapMode.None && IsUnlimited(MaximumSize.Width)) + size.Width = Math.Min(MaximumSize.Width, width); + return size; } + const int MaxLayoutSize = 1000000; + void Setup(Pango.Layout layout) { Font.Apply(layout); - layout.Width = (int)(MaximumSize.Width * Pango.Scale.PangoScale); + var hasNewlines = Text.IndexOf('\n') != -1; + _shouldClip = false; + var isRightOrCenter = Alignment == FormattedTextAlignment.Right || Alignment == FormattedTextAlignment.Center; + var size = SizeF.Min(MaximumSize, new SizeF(MaxLayoutSize, MaxLayoutSize)); + if (size.Width <= 0) + size.Width = MaxLayoutSize; + if (size.Height <= 0) + size.Height = MaxLayoutSize; + + layout.Width = (int)(size.Width * Pango.Scale.PangoScale); + #if GTK3 - layout.Height = (int)(MaximumSize.Height * Pango.Scale.PangoScale); + layout.Height = (int)(size.Height * Pango.Scale.PangoScale); #endif layout.Ellipsize = Trimming == FormattedTextTrimming.None ? Pango.EllipsizeMode.None : Pango.EllipsizeMode.End; switch (Wrap) { case FormattedTextWrapMode.None: - // only draw one line!! layout.Wrap = Pango.WrapMode.Char; + + if (Trimming == FormattedTextTrimming.None || hasNewlines || (isRightOrCenter && !hasNewlines)) + { + _shouldClip = true; + layout.Width = (int)(MaxLayoutSize * Pango.Scale.PangoScale); + } + // if (_shouldClip) + // layout.Width = (int)(MaxLayoutSize * Pango.Scale.PangoScale); #if GTK3 - layout.Height = (int)((double)layout.FontDescription.Size / (double)Pango.Scale.PangoScale); + // only draw a single line so we can do ellipsizing + if (!hasNewlines) + layout.Height = layout.FontDescription.Size; #endif + break; case FormattedTextWrapMode.Word: layout.Wrap = Pango.WrapMode.Word; @@ -67,16 +202,18 @@ void Setup(Pango.Layout layout) break; } layout.SetText(Text); - if (Wrap == FormattedTextWrapMode.None && layout.LineCount > 1) + if ((layout.Width >= MaxLayoutSize || !hasNewlines) && isRightOrCenter) { - // line includes the full last word so keep shrinking until it isn't wrapped - var len = layout.GetLine(0).Length; - while (len > 0 && layout.IsWrapped) - { - layout.SetText(Text.Substring(0, len--)); - } + layout.GetPixelSize(out var width, out var height); + if (hasNewlines) + layout.Width = (int)(width * Pango.Scale.PangoScale); + else if (IsUnlimited(MaximumSize.Width)) + layout.Width = (int)(Math.Max(width, MaximumSize.Width) * Pango.Scale.PangoScale); + else + layout.Width = (int)(Math.Min(width, MaximumSize.Width) * Pango.Scale.PangoScale); + } - if (Trimming == FormattedTextTrimming.None && layout.LineCount > 1) + if (Trimming == FormattedTextTrimming.None && layout.LineCount > 1 && IsUnlimited(MaximumSize.Height)) { layout.GetPixelSize(out _, out var height); while (layout.LineCount > 1 && height > MaximumSize.Height) @@ -106,15 +243,34 @@ void Setup(Pango.Layout layout) } } - public void Draw(GraphicsHandler graphics, Pango.Layout layout, Cairo.Context context, PointF location) + Pango.Layout _layout; + + bool IsUnlimited(float value) => value < float.MaxValue || value <= 0; + + public void Draw(GraphicsHandler graphics, Cairo.Context context, PointF location) { - Setup(layout); + EnsureLayout(graphics.PangoContext); context.Save(); + if (_shouldClip && IsUnlimited(MaximumSize.Width)) + { + context.Rectangle(new Cairo.Rectangle(location.X, location.Y, Math.Min(MaxLayoutSize, MaximumSize.Width), Math.Min(MaxLayoutSize, MaximumSize.Height))); + context.Clip(); + } ForegroundBrush.Apply(graphics); context.MoveTo(location.X, location.Y); - Pango.CairoHelper.LayoutPath(context, layout); + Pango.CairoHelper.LayoutPath(context, _layout); context.Fill(); context.Restore(); } + + private void EnsureLayout(Pango.Context context) + { + if (_layout == null || _layout.Context.Handle != context.Handle) + { + _layout?.Dispose(); + _layout = new Pango.Layout(context); + Setup(_layout); + } + } } } diff --git a/src/Eto.Gtk/Drawing/GraphicsHandler.cs b/src/Eto.Gtk/Drawing/GraphicsHandler.cs index 28fadf9b38..f74f85a6b6 100644 --- a/src/Eto.Gtk/Drawing/GraphicsHandler.cs +++ b/src/Eto.Gtk/Drawing/GraphicsHandler.cs @@ -403,11 +403,8 @@ public void DrawText(FormattedText formattedText, PointF location) var oldAA = AntiAlias; AntiAlias = true; SetOffset(false); - using (var layout = CreateLayout()) - { - var handler = (FormattedTextHandler)formattedText.Handler; - handler.Draw(this, layout, Control, location); - } + var handler = (FormattedTextHandler)formattedText.Handler; + handler.Draw(this, Control, location); AntiAlias = oldAA; } diff --git a/src/Eto.Mac/Drawing/FormattedTextHandler.cs b/src/Eto.Mac/Drawing/FormattedTextHandler.cs index 7d2add069a..c27d1f51fd 100644 --- a/src/Eto.Mac/Drawing/FormattedTextHandler.cs +++ b/src/Eto.Mac/Drawing/FormattedTextHandler.cs @@ -107,6 +107,7 @@ public class FormattedTextHandler : WidgetHandler container.ContainerSize.ToEto(); - set => container.ContainerSize = value.ToNS(); + get => _maximumSize; + set + { + _maximumSize = value; + SetMaxSize(); + } + } + + private void SetMaxSize() + { + var size = _maximumSize; + if (size.Width >= float.MaxValue && Alignment != FormattedTextAlignment.Left) + { + // need a width to support aligning + size.Width = GetMaxTextWidth(); + } + size.Width = Math.Min(int.MaxValue, size.Width); + size.Height = Math.Min(int.MaxValue, size.Height); + container.Size = size.ToNS(); + } + + private float GetMaxTextWidth() + { + float maxWidth = 0; + char newline = '\n'; + int newlineIndex = _text.IndexOf(newline); + if (newlineIndex == -1) + { + return _maximumSize.Width; + } + int startIndex = 0; + container.Size = new CGSize(0, 0); + while (newlineIndex >= 0) + { + var glyphRange = new NSRange(startIndex, newlineIndex - startIndex); + var rect = Control.BoundingRectForGlyphRange(glyphRange, container).Size.ToEto(); + maxWidth = Math.Max(maxWidth, rect.Width); + startIndex = newlineIndex + 1; + newlineIndex = _text.IndexOf(newline, startIndex); + } + return maxWidth; } public Font Font @@ -192,19 +232,8 @@ private NSAttributedString CreateAttributedString() private NSParagraphStyle CreateParagraphStyle() { var style = new NSMutableParagraphStyle(); - //style.LineBreakMode = Trimming.ToNS(); - container.MaximumNumberOfLines = 0; if (Wrap == FormattedTextWrapMode.None) - { - if (Trimming != FormattedTextTrimming.None) - style.LineBreakMode = Trimming.ToNS(); - else - { - // hm, setting style.LineBreakMode to Clipping doesn't appear to clip, so we wrap by character and set max lines to 1 - style.LineBreakMode = NSLineBreakMode.CharWrapping; - container.MaximumNumberOfLines = 1; - } - } + style.LineBreakMode = Trimming.ToNS(); else style.LineBreakMode = Wrap.ToNS(); @@ -217,6 +246,7 @@ void EnsureString() if (invalid) { storage.SetString(CreateAttributedString()); + SetMaxSize(); invalid = false; } } @@ -230,11 +260,8 @@ public int MaximumLineCount public SizeF Measure() { EnsureString(); - var size = Control.BoundingRectForGlyphRange(new NSRange(0, (int)_text.Length), container).Size.ToEto(); - /*if (Wrap == FormattedTextWrapMode.None && Trimming != FormattedTextTrimming.None && Alignment != FormattedTextAlignment.Left) - { - size.Width = MaximumSize.Width; - }*/ + // var size = Control.BoundingRectForGlyphRange(new NSRange(0, (int)_text.Length), container).Size.ToEto(); + var size = storage.BoundingRectWithSize(container.Size, NSStringDrawingOptions.UsesLineFragmentOrigin).Size.ToEto(); return size; } @@ -245,7 +272,7 @@ public FormattedTextHandler() #if OSX Control.BackgroundLayoutEnabled = false; #endif - container = new NSTextContainer { LineFragmentPadding = 0f }; + container = new NSTextContainer { LineFragmentPadding = 0f, Size = new CGSize(int.MaxValue, int.MaxValue) }; Control.AddTextContainer(container); storage.AddLayoutManager(Control); } @@ -255,7 +282,8 @@ public void DrawText(GraphicsHandler graphics, PointF location) EnsureString(); Control.CurrentGraphics = graphics; var ctx = graphics.Control; - Control.DrawGlyphs(new NSRange(0, (int)_text.Length), location.ToNS()); + storage.DrawString(new CGRect(location.ToNS(), container.Size), NSStringDrawingOptions.UsesLineFragmentOrigin | NSStringDrawingOptions.TruncatesLastVisibleLine); + // Control.DrawGlyphs(new NSRange(0, (int)_text.Length), location.ToNS()); } } } \ No newline at end of file diff --git a/src/Eto.WinForms/Drawing/FormattedTextHandler.cs b/src/Eto.WinForms/Drawing/FormattedTextHandler.cs index efe1b49751..bee2c313e9 100644 --- a/src/Eto.WinForms/Drawing/FormattedTextHandler.cs +++ b/src/Eto.WinForms/Drawing/FormattedTextHandler.cs @@ -12,7 +12,12 @@ public class FormattedTextHandler : WidgetHandler new sd.StringFormat(); + protected override sd.StringFormat CreateControl() + { + var control = new sd.StringFormat(); + control.FormatFlags |= sd.StringFormatFlags.LineLimit; + return control; + } public FormattedTextWrapMode Wrap { @@ -113,59 +118,84 @@ void DrawJustifiedLines(GraphicsHandler graphics, RectangleF rect) { var brush = ForegroundBrush.ToSD(rect); var font = Font.ToSD(); - - string[] words = Text.Split(' '); - - // get widths of each word - float[] wordWidths = new float[words.Length]; - for (int i = 0; i < words.Length; i++) - { - var size = graphics.Control.MeasureString(words[i], font); - wordWidths[i] = size.Width; - } - + var text = Text; var lineHeight = font.GetHeight(graphics.Control); - int currentWord = 0; - float y = rect.Top; var format = new sd.StringFormat(Control); format.Trimming = sd.StringTrimming.None; // no ellipsis - while (true) + float y = rect.Top; + + void DrawParagraph(string paragraph) { - float x = rect.Left; - float lineWidth = 0; - int wordsToDraw = 0; - for (int i = currentWord; i < words.Length; i++) + string[] words = paragraph.Split(' '); + + // get widths of each word + float[] wordWidths = new float[words.Length]; + for (int i = 0; i < words.Length; i++) + { + var size = graphics.Control.MeasureString(words[i], font); + wordWidths[i] = size.Width; + } + + int currentWord = 0; + while (true) { - var width = wordWidths[i]; - if (x + lineWidth + width > MaximumSize.Width) + float x = rect.Left; + float lineWidth = 0; + int wordsToDraw = 0; + bool justify = false; + for (int i = currentWord; i < words.Length; i++) { + var width = wordWidths[i]; + if (x + lineWidth + width > MaximumSize.Width) + { + justify = true; + break; + } + wordsToDraw++; + lineWidth += width; + } + if (wordsToDraw == 0) + break; + if (!justify) + { + var lastLine = string.Join(" ", words.Skip(currentWord).Take(wordsToDraw)); + graphics.Control.DrawString(lastLine, font, brush, x, y, format); + y += lineHeight; break; } - wordsToDraw++; - lineWidth += width; - } - if (wordsToDraw == 0) - break; - float spacing = rect.Width - lineWidth; - if (wordsToDraw > 1) spacing /= (wordsToDraw - 1); + float spacing = rect.Width - lineWidth; + if (wordsToDraw > 1) spacing /= (wordsToDraw - 1); - for (int i = 0; i < wordsToDraw; i++) - { - var idx = currentWord + i; - graphics.Control.DrawString(words[idx], font, brush, x, y, format); + for (int i = 0; i < wordsToDraw; i++) + { + var idx = currentWord + i; + graphics.Control.DrawString(words[idx], font, brush, x, y, format); + + x += wordWidths[idx] + spacing; + } + y += lineHeight; - x += wordWidths[idx] + spacing; + if (y + lineHeight > rect.Bottom) + break; + + currentWord += wordsToDraw; } - y += lineHeight; + } + + + var lines = text.Split('\n'); + for (int i = 0; i < lines.Length; i++) + { if (y + lineHeight > rect.Bottom) break; - - currentWord += wordsToDraw; + + string line = lines[i]; + DrawParagraph(line); } } - + public void Draw(GraphicsHandler graphics, PointF location) { var size = Measure(); @@ -174,7 +204,7 @@ public void Draw(GraphicsHandler graphics, PointF location) size.Width = MaximumSize.Width; var rect = new RectangleF(location.X, location.Y, size.Width, size.Height); - if (Alignment == FormattedTextAlignment.Justify && rect.Width < int.MaxValue) + if (Wrap != FormattedTextWrapMode.None && Alignment == FormattedTextAlignment.Justify && rect.Width < int.MaxValue) { DrawJustifiedLines(graphics, rect); } diff --git a/src/Eto.Wpf/Drawing/FormattedTextHandler.cs b/src/Eto.Wpf/Drawing/FormattedTextHandler.cs index d3858c7948..e950263c86 100644 --- a/src/Eto.Wpf/Drawing/FormattedTextHandler.cs +++ b/src/Eto.Wpf/Drawing/FormattedTextHandler.cs @@ -17,10 +17,12 @@ public class FormattedTextHandler : WidgetHandler _wrap; @@ -68,7 +70,10 @@ public Font Font { _font = value; if (HasControl) + { SetFont(Control); + SetMaxSize(Control); + } } } public Brush ForegroundBrush @@ -88,14 +93,21 @@ public FormattedTextAlignment Alignment { _alignment = value; if (HasControl) + { SetTextAlignment(Control); + SetMaxSize(Control); + } } } public SizeF Measure() { var control = Control; - return new SizeF((float)control.WidthIncludingTrailingWhitespace, (float)control.Height); + double width = control.WidthIncludingTrailingWhitespace; + if (_shouldClip) + width = Math.Min(width, MaximumSize.Width); + + return new SizeF((float)width, (float)control.Height); } void Invalidate() @@ -105,9 +117,10 @@ void Invalidate() protected override swm.FormattedText CreateControl() { - var font = SystemFonts.Default(); + var font = Font; var text = Text ?? string.Empty; text = SetWrap(text); + _hasNewLines = text.IndexOf('\n') != -1; #pragma warning disable CS0618 // 'FormattedText.FormattedText(string, CultureInfo, FlowDirection, Typeface, double, Brush)' is obsolete: 'Use the PixelsPerDip override' var formattedText = new swm.FormattedText( @@ -118,19 +131,30 @@ protected override swm.FormattedText CreateControl() font.Size, ForegroundBrush.ToWpf()); #pragma warning restore CS0618 // 'FormattedText.FormattedText(string, CultureInfo, FlowDirection, Typeface, double, Brush)' is obsolete: 'Use the PixelsPerDip override' + + // support correctly showing ellipsis when there's a single line if (Wrap == FormattedTextWrapMode.None) - formattedText.MaxLineCount = 1; + { + if (!_hasNewLines) + formattedText.MaxLineCount = 1; + else + { + // can't show ellipsis when there's multiple lines currently.. + formattedText.MaxLineCount = int.MaxValue; + _shouldClip = true; + } + } SetTextAlignment(formattedText); SetFont(formattedText); - SetMaxSize(formattedText); SetTrimming(formattedText); + SetMaxSize(formattedText); return formattedText; } string SetWrap(string text) { // character wrap only works with no trimming. - if (Wrap == FormattedTextWrapMode.Character && Trimming == FormattedTextTrimming.None) + if ((Wrap == FormattedTextWrapMode.Character || Wrap == FormattedTextWrapMode.None) && Trimming == FormattedTextTrimming.None) { // wpf will always word wrap, so we replace spaces with nbsp // so that it is forced to wrap at the character level @@ -168,7 +192,10 @@ void SetFont(swm.FormattedText formattedText) void SetMaxSize(swm.FormattedText formattedText) { - formattedText.MaxTextWidth = Math.Min(3579139, MaximumSize.Width); + if ((Alignment == FormattedTextAlignment.Left || MaximumSize.Width < float.MaxValue) && (Wrap != FormattedTextWrapMode.None || !_hasNewLines)) + formattedText.MaxTextWidth = Math.Min(3579139, MaximumSize.Width); + else + formattedText.MaxTextWidth = formattedText.WidthIncludingTrailingWhitespace; formattedText.MaxTextHeight = Math.Min(3579139, MaximumSize.Height); } void SetTrimming(swm.FormattedText formattedText) @@ -207,7 +234,17 @@ public void DrawText(GraphicsHandler handler, PointF location) handler.Control.DrawGlyphRun(Brushes.Red.ToWpf(), glyphRun); } /**/ - handler.Control.DrawText(Control, location.ToWpf()); + if (_shouldClip) + { + // a better way here would be to draw each line separately so alignment works on a per-paragraph basis + // but this is an edge case we don't fully support yet. + var rect = new sw.Rect(location.X, location.Y, Math.Min(MaximumSize.Width, Control.WidthIncludingTrailingWhitespace), Control.Height); + handler.Control.PushClip(new swm.RectangleGeometry(rect)); + handler.Control.DrawText(Control, location.ToWpf()); + handler.Control.Pop(); + } + else + handler.Control.DrawText(Control, location.ToWpf()); } diff --git a/test/Eto.Test/Sections/Behaviors/AllControlsBase.cs b/test/Eto.Test/Sections/Behaviors/AllControlsBase.cs index 7652a76208..218bd0b48a 100644 --- a/test/Eto.Test/Sections/Behaviors/AllControlsBase.cs +++ b/test/Eto.Test/Sections/Behaviors/AllControlsBase.cs @@ -41,7 +41,16 @@ protected override void OnPreLoad(EventArgs e) layout.Add(GroupBoxControl()); layout.Add(TableLayoutControl()); layout.EndHorizontal(); + + layout.BeginHorizontal(); + layout.AddSpace(); + layout.Add(ExpanderControl()); + layout.EndHorizontal(); + layout.EndVertical(); + + + layout.Add(null); Content = layout; @@ -54,6 +63,27 @@ protected virtual Control CreateOptions() return null; } + Control ExpanderControl() + { + var control = new Expander + { + Header = "Expander", + Expanded = true, + Content = new Panel + { + Size = new Size(100, 100), + Content = new Label + { + VerticalAlignment = VerticalAlignment.Center, + TextAlignment = TextAlignment.Center, + Text = "Content" + } + } + }; + LogEvents(control); + return control; + } + Control LabelControl() { var control = new Label { Text = "Label" }; @@ -210,7 +240,7 @@ Control PanelControl() Control DrawableControl() { var control = new Drawable { Size = new Size(100, 30), CanFocus = true }; - control.Paint += delegate(object sender, PaintEventArgs pe) + control.Paint += delegate (object sender, PaintEventArgs pe) { pe.Graphics.FillRectangle(Brushes.Blue, pe.ClipRectangle); var size = pe.Graphics.MeasureString(SystemFonts.Label(), "Drawable"); diff --git a/test/Eto.Test/Sections/Controls/LabelSection.cs b/test/Eto.Test/Sections/Controls/LabelSection.cs index 7adb58f8ea..374ec99efa 100644 --- a/test/Eto.Test/Sections/Controls/LabelSection.cs +++ b/test/Eto.Test/Sections/Controls/LabelSection.cs @@ -129,7 +129,7 @@ Control WrapLabel() { var label = new Label { - Text = Utility.LoremText + Text = Utility.LoremTextWithTwoParagraphs }; var wrapDropDown = new EnumDropDown(); diff --git a/test/Eto.Test/Sections/Controls/RichTextAreaSection.cs b/test/Eto.Test/Sections/Controls/RichTextAreaSection.cs index 425a219a80..9dcce10a98 100644 --- a/test/Eto.Test/Sections/Controls/RichTextAreaSection.cs +++ b/test/Eto.Test/Sections/Controls/RichTextAreaSection.cs @@ -12,7 +12,7 @@ public class RichTextAreaSection : Panel { public static string RtfString = "{\\rtf1\\ansi\\ansicpg1252\\cocoartf1343\\cocoasubrtf160\r\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\r\n{\\colortbl;\\red255\\green255\\blue255;}\r\n\\margl1440\\margr1440\\vieww10800\\viewh8400\\viewkind0\r\n\\pard\\tx566\\tx1133\\tx1700\\tx2267\\tx2834\\tx3401\\tx3968\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural\r\n\r\n\\f0\\fs24 \\cf0 This is some \r\n\\b bold\r\n\\b0 , \r\n\\i italic\r\n\\i0 , and \\ul underline\\ulnone text! \\\r\n\\\r\n\\pard\\tx566\\tx1133\\tx1700\\tx2267\\tx2834\\tx3401\\tx3968\\tx4535\\tx5102\\tx5669\\tx6236\\tx6803\\pardirnatural\\qr\r\n\\cf0 Some other text}"; - static string LastText = Utility.LoremText; + static string LastText = Utility.LoremTextWithTwoParagraphs; public RichTextAreaSection() { diff --git a/test/Eto.Test/Sections/Controls/TextAreaSection.cs b/test/Eto.Test/Sections/Controls/TextAreaSection.cs index f120bbde80..eb8d9736b3 100644 --- a/test/Eto.Test/Sections/Controls/TextAreaSection.cs +++ b/test/Eto.Test/Sections/Controls/TextAreaSection.cs @@ -15,7 +15,7 @@ public TextAreaSection() Control Default() { - var text = new TextArea { Text = Utility.LoremText }; + var text = new TextArea { Text = Utility.LoremTextWithTwoParagraphs }; LogEvents(text); return new TableLayout diff --git a/test/Eto.Test/Sections/Drawing/FormattedTextSection.cs b/test/Eto.Test/Sections/Drawing/FormattedTextSection.cs index 1ea87cc941..9f104d654f 100644 --- a/test/Eto.Test/Sections/Drawing/FormattedTextSection.cs +++ b/test/Eto.Test/Sections/Drawing/FormattedTextSection.cs @@ -10,13 +10,36 @@ public class FormattedTextSection : Scrollable { public FormattedTextSection() { + Styles.Add