From 4a7f9385c4b1da5481a853537fd2bca66ad4a30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zi=C4=85bek?= Date: Wed, 28 Apr 2021 23:49:22 +0200 Subject: [PATCH] Improved text positioning --- QuestPDF.Examples/TextExample.cs | 75 +++++++++++++--------------- QuestPDF/Elements/TextElement.cs | 4 -- QuestPDF/Elements/TextRun.cs | 28 +++++++---- QuestPDF/Helpers/Placeholders.cs | 38 +++++++------- QuestPDF/Infrastructure/TextStyle.cs | 3 +- 5 files changed, 74 insertions(+), 74 deletions(-) diff --git a/QuestPDF.Examples/TextExample.cs b/QuestPDF.Examples/TextExample.cs index 7c9dd0b..c5e0e5a 100644 --- a/QuestPDF.Examples/TextExample.cs +++ b/QuestPDF.Examples/TextExample.cs @@ -6,13 +6,14 @@ using QuestPDF.Examples.Engine; using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; +using SkiaSharp; namespace QuestPDF.Examples { public class TextExample : ExampleTestBase { [ShowResult] - [ImageSize(1200, 500)] + [ImageSize(1600, 500)] public void Test(IContainer container) { List Lorem() @@ -21,36 +22,32 @@ namespace QuestPDF.Examples { new TextElement() { - Style = TextStyle.Default.Size(32).BackgroundColor(Colors.Red.Lighten3), + Style = TextStyle.Default.Size(32).BackgroundColor(Placeholders.BackgroundColor()), Text = "Lorem ipsum " }, new TextElement() { - Style = TextStyle.Default.Size(24).BackgroundColor(Colors.Orange.Lighten3), + Style = TextStyle.Default.Size(24).BackgroundColor(Placeholders.BackgroundColor()), Text = " dolor " }, new TextElement() { - Style = TextStyle.Default.Size(64).BackgroundColor(Colors.Yellow.Lighten3), - Text = " sit " + Style = TextStyle.Default.Size(64).BackgroundColor(Placeholders.BackgroundColor()), + Text = " sijt " }, new TextElement() { - Style = TextStyle.Default.Size(32).BackgroundColor(Colors.Green.Lighten3), + Style = TextStyle.Default.Size(32).BackgroundColor(Placeholders.BackgroundColor()), Text = " amet" } }; } - Func> Source = Lorem ; - + Func> Source = () => Split(RandomText()); + container .Padding(50) - .Stack(row => - { - row.Spacing(50); - - row.Element().Box().Border(1).Stack(stack => + .Box().Border(1).Stack(stack => { stack .Element() @@ -69,58 +66,62 @@ namespace QuestPDF.Examples { Elements = Source() }); - + stack .Element() .Box() //.Background(Placeholders.BackgroundColor()) .Element(new TextRun() { - Elements = Split(Source()) - }); - }); - - row.Element().Box().Border(1).Stack(stack => - { - stack - .Element() - .Box() - .Background(Placeholders.BackgroundColor()) - .Element(new TextRun() - { - Elements = Dense(Source()) + Elements = Source() }); stack .Element() .Box() - .Background(Placeholders.BackgroundColor()) + //.Background(Placeholders.BackgroundColor()) .Element(new TextRun() { - Elements = Dense(Source()) + Elements = Source() }); - + stack .Element() .Box() - .Background(Placeholders.BackgroundColor()) + //.Background(Placeholders.BackgroundColor()) .Element(new TextRun() { - Elements = Dense(Split(Source())) + Elements = Source() + }); + + stack + .Element() + .Box() + //.Background(Placeholders.BackgroundColor()) + .Element(new TextRun() + { + Elements = Source() }); }); - }); } List RandomText() { + var sizes = new[] { 24, 32, 48, 64}; + return Placeholders .Sentence() .Split(" ") .Select(x => new TextElement { Text = $"{x} ", - Style = TextStyle.Default.Size(Placeholders.Random.Next(24, 64)) + Style = TextStyle + .Default + //.Size(sizes[Placeholders.Random.Next(0, 3)]) + .Size(24) + .BackgroundColor(Placeholders.BackgroundColor()) + //.LineHeight((float)Placeholders.Random.NextDouble() / 2 + 1f) + .LineHeight(1.2f) }) .ToList(); } @@ -137,11 +138,5 @@ namespace QuestPDF.Examples })) .ToList(); } - - List Dense(List elements) - { - elements.ForEach(x => x.Style.IsDense = true); - return elements; - } } } \ No newline at end of file diff --git a/QuestPDF/Elements/TextElement.cs b/QuestPDF/Elements/TextElement.cs index 7294d34..c9dd032 100644 --- a/QuestPDF/Elements/TextElement.cs +++ b/QuestPDF/Elements/TextElement.cs @@ -10,7 +10,6 @@ namespace QuestPDF.Elements public struct TextMeasurement { public float Width { get; set; } - public float Height { get; set; } public SKRect Position { get; set; } } @@ -44,9 +43,6 @@ namespace QuestPDF.Elements return new TextMeasurement { Position = rect, - Height = style.IsDense - ? rect.Bottom + rect.Height - : style.LineHeight * style.Size, Width = width }; }); diff --git a/QuestPDF/Elements/TextRun.cs b/QuestPDF/Elements/TextRun.cs index e3ee5ff..3808000 100644 --- a/QuestPDF/Elements/TextRun.cs +++ b/QuestPDF/Elements/TextRun.cs @@ -16,9 +16,9 @@ namespace QuestPDF.Elements var width = measurements.Sum(x => x.Width); //var height = measurements.Max(x => x.Height); - var height = measurements.Max(x => x.Position.Bottom) + measurements.Max(x => x.Position.Height); - - + //var height = measurements.Max(x => x.Position.Bottom) + measurements.Max(x => x.Position.Height); + var height = Elements.Max(x => x.Style.Size * x.Style.LineHeight); + return new FullRender(width, height); } @@ -26,23 +26,33 @@ namespace QuestPDF.Elements { var measurements = Elements.Select(x => x.Measure()).ToList(); - var top = measurements.Max(x => x.Position.Height); - var bottom = measurements.Max(x => x.Position.Bottom); + var lineHeight = Elements.Max(x => x.Style.Size * x.Style.LineHeight); + var textHeight = Elements.Max(x => x.Style.Size); + + var lineHeightOffset = (lineHeight - textHeight) / 2; + var baselineOffset = measurements.Max(x => -x.Position.Top); + var offset = lineHeightOffset + baselineOffset; - var offset = measurements.Min(x => x.Position.Top); - canvas.Translate(new Position(0, -offset)); foreach (var textElement in Elements) { var size = textElement.Measure(); - canvas.DrawRectangle(new Position(0, -top), new Size(size.Width, bottom + top), textElement.Style.BackgroundColor); + //canvas.DrawRectangle(new Position(0, 0), new Size(size.Width, lineHeight), textElement.Style.BackgroundColor); //canvas.DrawRectangle(new Position(size.Position.Left, size.Position.Top), new Size(size.Position.Width, size.Position.Height), textElement.Style.BackgroundColor); + + canvas.Translate(new Position(0, offset)); textElement.Draw(canvas); + canvas.Translate(new Position(0, -offset)); + canvas.Translate(new Position(size.Width, 0)); } - canvas.Translate(new Position(-measurements.Sum(x => x.Width), offset)); + canvas.Translate(new Position(-measurements.Sum(x => x.Width), 0)); + + + + // } } } \ No newline at end of file diff --git a/QuestPDF/Helpers/Placeholders.cs b/QuestPDF/Helpers/Placeholders.cs index d7bfc64..be26650 100644 --- a/QuestPDF/Helpers/Placeholders.cs +++ b/QuestPDF/Helpers/Placeholders.cs @@ -155,25 +155,25 @@ namespace QuestPDF.Helpers private static readonly string[] BackgroundColors = { - Colors.Red.Lighten2, - Colors.Pink.Lighten2, - Colors.Purple.Lighten2, - Colors.DeepPurple.Lighten2, - Colors.Indigo.Lighten2, - Colors.Blue.Lighten2, - Colors.LightBlue.Lighten2, - Colors.Cyan.Lighten2, - Colors.Teal.Lighten2, - Colors.Green.Lighten2, - Colors.LightGreen.Lighten2, - Colors.Lime.Lighten2, - Colors.Yellow.Lighten2, - Colors.Amber.Lighten2, - Colors.Orange.Lighten2, - Colors.DeepOrange.Lighten2, - Colors.Brown.Lighten2, - Colors.Grey.Lighten2, - Colors.BlueGrey.Lighten2 + Colors.Red.Lighten3, + Colors.Pink.Lighten3, + Colors.Purple.Lighten3, + Colors.DeepPurple.Lighten3, + Colors.Indigo.Lighten3, + Colors.Blue.Lighten3, + Colors.LightBlue.Lighten3, + Colors.Cyan.Lighten3, + Colors.Teal.Lighten3, + Colors.Green.Lighten3, + Colors.LightGreen.Lighten3, + Colors.Lime.Lighten3, + Colors.Yellow.Lighten3, + Colors.Amber.Lighten3, + Colors.Orange.Lighten3, + Colors.DeepOrange.Lighten3, + Colors.Brown.Lighten3, + Colors.Grey.Lighten3, + Colors.BlueGrey.Lighten3 }; public static string BackgroundColor() diff --git a/QuestPDF/Infrastructure/TextStyle.cs b/QuestPDF/Infrastructure/TextStyle.cs index 0eadab3..684d2d4 100644 --- a/QuestPDF/Infrastructure/TextStyle.cs +++ b/QuestPDF/Infrastructure/TextStyle.cs @@ -12,13 +12,12 @@ namespace QuestPDF.Infrastructure internal HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left; internal FontWeight FontWeight { get; set; } = FontWeight.Normal; internal bool IsItalic { get; set; } = false; - internal bool IsDense { get; set; } public static TextStyle Default => new TextStyle(); public override string ToString() { - return $"{Color}|{BackgroundColor}|{FontType}|{Size}|{LineHeight}|{Alignment}|{FontWeight}|{IsItalic}|{IsDense}"; + return $"{Color}|{BackgroundColor}|{FontType}|{Size}|{LineHeight}|{Alignment}|{FontWeight}|{IsItalic}"; } internal TextStyle Clone() => (TextStyle)MemberwiseClone();