diff --git a/QuestPDF/Elements/Text/Calculation/TextDrawingRequest.cs b/QuestPDF/Elements/Text/Calculation/TextDrawingRequest.cs new file mode 100644 index 0000000..ef16075 --- /dev/null +++ b/QuestPDF/Elements/Text/Calculation/TextDrawingRequest.cs @@ -0,0 +1,16 @@ +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements.Text.Calculation +{ + internal class TextDrawingRequest + { + public ICanvas Canvas { get; set; } + public IPageContext PageContext { get; set; } + + public int StartIndex { get; set; } + public int EndIndex { get; set; } + + public float TotalAscent { get; set; } + public Size TextSize { get; set; } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Calculation/TextLine.cs b/QuestPDF/Elements/Text/Calculation/TextLine.cs new file mode 100644 index 0000000..5688099 --- /dev/null +++ b/QuestPDF/Elements/Text/Calculation/TextLine.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Linq; +using QuestPDF.Elements.Text.Items; + +namespace QuestPDF.Elements.Text.Calculation +{ + internal class TextLine + { + public ICollection Elements { get; set; } + + public float TextHeight => Elements.Max(x => x.Measurement.Height); + public float LineHeight => Elements.Max(x => x.Measurement.LineHeight * x.Measurement.Height); + + public float Ascent => Elements.Min(x => x.Measurement.Ascent) - (LineHeight - TextHeight) / 2; + public float Descent => Elements.Max(x => x.Measurement.Descent) + (LineHeight - TextHeight) / 2; + + public float Width => Elements.Sum(x => x.Measurement.Width); + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Calculation/TextLineElement.cs b/QuestPDF/Elements/Text/Calculation/TextLineElement.cs new file mode 100644 index 0000000..bccdc6d --- /dev/null +++ b/QuestPDF/Elements/Text/Calculation/TextLineElement.cs @@ -0,0 +1,10 @@ +using QuestPDF.Elements.Text.Calculation; + +namespace QuestPDF.Elements.Text.Items +{ + internal class TextLineElement + { + public ITextBlockElement Element { get; set; } + public TextMeasurementResult Measurement { get; set; } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Calculation/TextMeasurementRequest.cs b/QuestPDF/Elements/Text/Calculation/TextMeasurementRequest.cs new file mode 100644 index 0000000..69278a1 --- /dev/null +++ b/QuestPDF/Elements/Text/Calculation/TextMeasurementRequest.cs @@ -0,0 +1,13 @@ +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements.Text.Calculation +{ + internal class TextMeasurementRequest + { + public ICanvas Canvas { get; set; } + public IPageContext PageContext { get; set; } + + public int StartIndex { get; set; } + public float AvailableWidth { get; set; } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Calculation/TextMeasurementResult.cs b/QuestPDF/Elements/Text/Calculation/TextMeasurementResult.cs new file mode 100644 index 0000000..a831ae4 --- /dev/null +++ b/QuestPDF/Elements/Text/Calculation/TextMeasurementResult.cs @@ -0,0 +1,21 @@ +using System; + +namespace QuestPDF.Elements.Text.Calculation +{ + internal class TextMeasurementResult + { + public float Width { get; set; } + public float Height => Math.Abs(Descent) + Math.Abs(Ascent); + + public float Ascent { get; set; } + public float Descent { get; set; } + + public float LineHeight { get; set; } + + public int StartIndex { get; set; } + public int EndIndex { get; set; } + public int TotalIndex { get; set; } + + public bool IsLast => EndIndex == TotalIndex; + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Items/ITextBlockElement.cs b/QuestPDF/Elements/Text/Items/ITextBlockElement.cs new file mode 100644 index 0000000..f049933 --- /dev/null +++ b/QuestPDF/Elements/Text/Items/ITextBlockElement.cs @@ -0,0 +1,10 @@ +using QuestPDF.Elements.Text.Calculation; + +namespace QuestPDF.Elements.Text.Items +{ + internal interface ITextBlockElement + { + TextMeasurementResult? Measure(TextMeasurementRequest request); + void Draw(TextDrawingRequest request); + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Items/TextBlockElement.cs b/QuestPDF/Elements/Text/Items/TextBlockElement.cs new file mode 100644 index 0000000..af7ed7e --- /dev/null +++ b/QuestPDF/Elements/Text/Items/TextBlockElement.cs @@ -0,0 +1,48 @@ +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements.Text.Calculation; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements.Text.Items +{ + internal class TextBlockElement : ITextBlockElement + { + public Element Element { get; set; } = Empty.Instance; + + public TextMeasurementResult? Measure(TextMeasurementRequest request) + { + Element.HandleVisitor(x => (x as IStateResettable)?.ResetState()); + Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas)); + + var measurement = Element.Measure(new Size(request.AvailableWidth, Size.Max.Height)); + + if (measurement is Wrap || measurement is PartialRender) + return null; + + var elementSize = measurement as Size; + + return new TextMeasurementResult + { + Width = elementSize.Width, + + Ascent = -elementSize.Height, + Descent = 0, + + LineHeight = 1, + + StartIndex = 0, + EndIndex = 0, + TotalIndex = 0 + }; + } + + public void Draw(TextDrawingRequest request) + { + Element.HandleVisitor(x => (x as IStateResettable)?.ResetState()); + Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas)); + + request.Canvas.Translate(new Position(0, request.TotalAscent)); + Element.Draw(new Size(request.TextSize.Width, -request.TotalAscent)); + request.Canvas.Translate(new Position(0, -request.TotalAscent)); + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Items/TextBlockExternalLink.cs b/QuestPDF/Elements/Text/Items/TextBlockExternalLink.cs new file mode 100644 index 0000000..5c9356f --- /dev/null +++ b/QuestPDF/Elements/Text/Items/TextBlockExternalLink.cs @@ -0,0 +1,35 @@ +using QuestPDF.Elements.Text.Calculation; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements.Text.Items +{ + internal class TextBlockExternalLink : ITextBlockElement + { + public TextStyle Style { get; set; } = new TextStyle(); + public string Text { get; set; } + public string Url { get; set; } + + public TextMeasurementResult? Measure(TextMeasurementRequest request) + { + return GetItem().MeasureWithoutCache(request); + } + + public void Draw(TextDrawingRequest request) + { + request.Canvas.Translate(new Position(0, request.TotalAscent)); + request.Canvas.DrawExternalLink(Url, new Size(request.TextSize.Width, request.TextSize.Height)); + request.Canvas.Translate(new Position(0, -request.TotalAscent)); + + GetItem().Draw(request); + } + + private TextItem GetItem() + { + return new TextItem + { + Style = Style, + Text = Text + }; + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Items/TextBlockInternalLink.cs b/QuestPDF/Elements/Text/Items/TextBlockInternalLink.cs new file mode 100644 index 0000000..08b25e7 --- /dev/null +++ b/QuestPDF/Elements/Text/Items/TextBlockInternalLink.cs @@ -0,0 +1,35 @@ +using QuestPDF.Elements.Text.Calculation; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements.Text.Items +{ + internal class TextBlockInternalLink : ITextBlockElement + { + public TextStyle Style { get; set; } = new TextStyle(); + public string Text { get; set; } + public string LocationName { get; set; } + + public TextMeasurementResult? Measure(TextMeasurementRequest request) + { + return GetItem().MeasureWithoutCache(request); + } + + public void Draw(TextDrawingRequest request) + { + request.Canvas.Translate(new Position(0, request.TotalAscent)); + request.Canvas.DrawLocationLink(LocationName, new Size(request.TextSize.Width, request.TextSize.Height)); + request.Canvas.Translate(new Position(0, -request.TotalAscent)); + + GetItem().Draw(request); + } + + private TextItem GetItem() + { + return new TextItem + { + Style = Style, + Text = Text + }; + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Items/TextBlockPageNumber.cs b/QuestPDF/Elements/Text/Items/TextBlockPageNumber.cs new file mode 100644 index 0000000..8e97313 --- /dev/null +++ b/QuestPDF/Elements/Text/Items/TextBlockPageNumber.cs @@ -0,0 +1,36 @@ +using QuestPDF.Elements.Text.Calculation; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements.Text.Items +{ + internal class TextBlockPageNumber : ITextBlockElement + { + public TextStyle Style { get; set; } = new TextStyle(); + public string SlotName { get; set; } + + public TextMeasurementResult? Measure(TextMeasurementRequest request) + { + return GetItem(request.PageContext).MeasureWithoutCache(request); + } + + public void Draw(TextDrawingRequest request) + { + GetItem(request.PageContext).Draw(request); + } + + private TextItem GetItem(IPageContext context) + { + var pageNumberPlaceholder = 123; + + var pageNumber = context.GetRegisteredLocations().Contains(SlotName) + ? context.GetLocationPage(SlotName) + : pageNumberPlaceholder; + + return new TextItem + { + Style = Style, + Text = pageNumber.ToString() + }; + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/Items/TextItem.cs b/QuestPDF/Elements/Text/Items/TextItem.cs new file mode 100644 index 0000000..feb3b39 --- /dev/null +++ b/QuestPDF/Elements/Text/Items/TextItem.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using QuestPDF.Drawing; +using QuestPDF.Elements.Text.Calculation; +using QuestPDF.Infrastructure; +using Size = QuestPDF.Infrastructure.Size; + +namespace QuestPDF.Elements.Text.Items +{ + internal class TextItem : ITextBlockElement + { + public string Text { get; set; } + public TextStyle Style { get; set; } = new TextStyle(); + + private Dictionary<(int startIndex, float availableWidth), TextMeasurementResult?> MeasureCache = + new Dictionary<(int startIndex, float availableWidth), TextMeasurementResult?>(); + + public TextMeasurementResult? Measure(TextMeasurementRequest request) + { + var cacheKey = (request.StartIndex, request.AvailableWidth); + + if (!MeasureCache.ContainsKey(cacheKey)) + MeasureCache[cacheKey] = MeasureWithoutCache(request); + + return MeasureCache[cacheKey]; + } + + internal TextMeasurementResult? MeasureWithoutCache(TextMeasurementRequest request) + { + var paint = Style.ToPaint(); + var fontMetrics = Style.ToFontMetrics(); + + // start breaking text from requested position + var text = Text.Substring(request.StartIndex); + var breakingIndex = (int)paint.BreakText(text, request.AvailableWidth); + + if (breakingIndex <= 0) + return null; + + // break text only on spaces + if (breakingIndex < text.Length) + { + breakingIndex = text.Substring(0, breakingIndex).LastIndexOf(" "); + + if (breakingIndex <= 0) + return null; + + breakingIndex += 1; + } + + text = text.Substring(0, breakingIndex); + + // measure final text + var width = paint.MeasureText(text); + + return new TextMeasurementResult + { + Width = width, + + Ascent = fontMetrics.Ascent, + Descent = fontMetrics.Descent, + + LineHeight = Style.LineHeight, + + StartIndex = request.StartIndex, + EndIndex = request.StartIndex + breakingIndex, + TotalIndex = Text.Length + }; + } + + public void Draw(TextDrawingRequest request) + { + var fontMetrics = Style.ToFontMetrics(); + + var text = Text.Substring(request.StartIndex, request.EndIndex - request.StartIndex); + + request.Canvas.DrawRectangle(new Position(0, request.TotalAscent), new Size(request.TextSize.Width, request.TextSize.Height), Style.BackgroundColor); + request.Canvas.DrawText(text, Position.Zero, Style); + + // draw underline + if (Style.IsUnderlined && fontMetrics.UnderlinePosition.HasValue) + DrawLine(fontMetrics.UnderlinePosition.Value, fontMetrics.UnderlineThickness.Value); + + // draw stroke + if (Style.IsStroked && fontMetrics.StrikeoutPosition.HasValue) + DrawLine(fontMetrics.StrikeoutPosition.Value, fontMetrics.StrikeoutThickness.Value); + + void DrawLine(float offset, float thickness) + { + request.Canvas.DrawRectangle(new Position(0, offset - thickness / 2f), new Size(request.TextSize.Width, thickness), Style.Color); + } + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Text/TextBlock.cs b/QuestPDF/Elements/Text/TextBlock.cs index a883c4f..1b1df3d 100644 --- a/QuestPDF/Elements/Text/TextBlock.cs +++ b/QuestPDF/Elements/Text/TextBlock.cs @@ -1,40 +1,23 @@ using System.Collections.Generic; using System.Linq; using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements.Text.Calculation; +using QuestPDF.Elements.Text.Items; using QuestPDF.Infrastructure; namespace QuestPDF.Elements.Text { - internal class TextLineElement - { - public ITextElement Element { get; set; } - public TextMeasurementResult Measurement { get; set; } - } - - internal class TextLine - { - public ICollection Elements { get; set; } - - public float TextHeight => Elements.Max(x => x.Measurement.Height); - public float LineHeight => Elements.Max(x => x.Measurement.LineHeight * x.Measurement.Height); - - public float Ascent => Elements.Min(x => x.Measurement.Ascent) - (LineHeight - TextHeight) / 2; - public float Descent => Elements.Max(x => x.Measurement.Descent) + (LineHeight - TextHeight) / 2; - - public float Width => Elements.Sum(x => x.Measurement.Width); - } - internal class TextBlock : Element, IStateResettable { public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left; - public List Children { get; set; } = new List(); + public List Children { get; set; } = new List(); - public Queue RenderingQueue { get; set; } + public Queue RenderingQueue { get; set; } public int CurrentElementIndex { get; set; } public void ResetState() { - RenderingQueue = new Queue(Children); + RenderingQueue = new Queue(Children); CurrentElementIndex = 0; } @@ -137,7 +120,7 @@ namespace QuestPDF.Elements.Text public IEnumerable DivideTextItemsIntoLines(float availableWidth, float availableHeight) { - var queue = new Queue(RenderingQueue); + var queue = new Queue(RenderingQueue); var currentItemIndex = CurrentElementIndex; var currentHeight = 0f; diff --git a/QuestPDF/Elements/Text/TextItem.cs b/QuestPDF/Elements/Text/TextItem.cs deleted file mode 100644 index 4919f4d..0000000 --- a/QuestPDF/Elements/Text/TextItem.cs +++ /dev/null @@ -1,271 +0,0 @@ -using System; -using System.Collections.Generic; -using QuestPDF.Drawing; -using QuestPDF.Drawing.SpacePlan; -using QuestPDF.Infrastructure; -using Size = QuestPDF.Infrastructure.Size; - -namespace QuestPDF.Elements.Text -{ - internal class TextMeasurementRequest - { - public ICanvas Canvas { get; set; } - public IPageContext PageContext { get; set; } - - public int StartIndex { get; set; } - public float AvailableWidth { get; set; } - } - - internal class TextMeasurementResult - { - public float Width { get; set; } - public float Height => Math.Abs(Descent) + Math.Abs(Ascent); - - public float Ascent { get; set; } - public float Descent { get; set; } - - public float LineHeight { get; set; } - - public int StartIndex { get; set; } - public int EndIndex { get; set; } - public int TotalIndex { get; set; } - - public bool IsLast => EndIndex == TotalIndex; - } - - internal class TextDrawingRequest - { - public ICanvas Canvas { get; set; } - public IPageContext PageContext { get; set; } - - public int StartIndex { get; set; } - public int EndIndex { get; set; } - - public float TotalAscent { get; set; } - public Size TextSize { get; set; } - } - - internal interface ITextElement - { - TextMeasurementResult? Measure(TextMeasurementRequest request); - void Draw(TextDrawingRequest request); - } - - internal class TextItem : ITextElement - { - public string Text { get; set; } - public TextStyle Style { get; set; } = new TextStyle(); - - private Dictionary<(int startIndex, float availableWidth), TextMeasurementResult?> MeasureCache = - new Dictionary<(int startIndex, float availableWidth), TextMeasurementResult?>(); - - public TextMeasurementResult? Measure(TextMeasurementRequest request) - { - var cacheKey = (request.StartIndex, request.AvailableWidth); - - if (!MeasureCache.ContainsKey(cacheKey)) - MeasureCache[cacheKey] = MeasureWithoutCache(request); - - return MeasureCache[cacheKey]; - } - - internal TextMeasurementResult? MeasureWithoutCache(TextMeasurementRequest request) - { - var paint = Style.ToPaint(); - var fontMetrics = Style.ToFontMetrics(); - - // start breaking text from requested position - var text = Text.Substring(request.StartIndex); - var breakingIndex = (int)paint.BreakText(text, request.AvailableWidth); - - if (breakingIndex <= 0) - return null; - - // break text only on spaces - if (breakingIndex < text.Length) - { - breakingIndex = text.Substring(0, breakingIndex).LastIndexOf(" "); - - if (breakingIndex <= 0) - return null; - - breakingIndex += 1; - } - - text = text.Substring(0, breakingIndex); - - // measure final text - var width = paint.MeasureText(text); - - return new TextMeasurementResult - { - Width = width, - - Ascent = fontMetrics.Ascent, - Descent = fontMetrics.Descent, - - LineHeight = Style.LineHeight, - - StartIndex = request.StartIndex, - EndIndex = request.StartIndex + breakingIndex, - TotalIndex = Text.Length - }; - } - - public void Draw(TextDrawingRequest request) - { - var fontMetrics = Style.ToFontMetrics(); - - var text = Text.Substring(request.StartIndex, request.EndIndex - request.StartIndex); - - request.Canvas.DrawRectangle(new Position(0, request.TotalAscent), new Size(request.TextSize.Width, request.TextSize.Height), Style.BackgroundColor); - request.Canvas.DrawText(text, Position.Zero, Style); - - // draw underline - if (Style.IsUnderlined && fontMetrics.UnderlinePosition.HasValue) - DrawLine(fontMetrics.UnderlinePosition.Value, fontMetrics.UnderlineThickness.Value); - - // draw stroke - if (Style.IsStroked && fontMetrics.StrikeoutPosition.HasValue) - DrawLine(fontMetrics.StrikeoutPosition.Value, fontMetrics.StrikeoutThickness.Value); - - void DrawLine(float offset, float thickness) - { - request.Canvas.DrawRectangle(new Position(0, offset - thickness / 2f), new Size(request.TextSize.Width, thickness), Style.Color); - } - } - } - - internal class PageNumberTextItem : ITextElement - { - public TextStyle Style { get; set; } = new TextStyle(); - public string SlotName { get; set; } - - public TextMeasurementResult? Measure(TextMeasurementRequest request) - { - return GetItem(request.PageContext).MeasureWithoutCache(request); - } - - public void Draw(TextDrawingRequest request) - { - GetItem(request.PageContext).Draw(request); - } - - private TextItem GetItem(IPageContext context) - { - var pageNumberPlaceholder = 123; - - var pageNumber = context.GetRegisteredLocations().Contains(SlotName) - ? context.GetLocationPage(SlotName) - : pageNumberPlaceholder; - - return new TextItem - { - Style = Style, - Text = pageNumber.ToString() - }; - } - } - - internal class InternalLinkTextItem : ITextElement - { - public TextStyle Style { get; set; } = new TextStyle(); - public string Text { get; set; } - public string LocationName { get; set; } - - public TextMeasurementResult? Measure(TextMeasurementRequest request) - { - return GetItem().MeasureWithoutCache(request); - } - - public void Draw(TextDrawingRequest request) - { - request.Canvas.Translate(new Position(0, request.TotalAscent)); - request.Canvas.DrawLocationLink(LocationName, new Size(request.TextSize.Width, request.TextSize.Height)); - request.Canvas.Translate(new Position(0, -request.TotalAscent)); - - GetItem().Draw(request); - } - - private TextItem GetItem() - { - return new TextItem - { - Style = Style, - Text = Text - }; - } - } - - internal class ExternalLinkTextItem : ITextElement - { - public TextStyle Style { get; set; } = new TextStyle(); - public string Text { get; set; } - public string Url { get; set; } - - public TextMeasurementResult? Measure(TextMeasurementRequest request) - { - return GetItem().MeasureWithoutCache(request); - } - - public void Draw(TextDrawingRequest request) - { - request.Canvas.Translate(new Position(0, request.TotalAscent)); - request.Canvas.DrawExternalLink(Url, new Size(request.TextSize.Width, request.TextSize.Height)); - request.Canvas.Translate(new Position(0, -request.TotalAscent)); - - GetItem().Draw(request); - } - - private TextItem GetItem() - { - return new TextItem - { - Style = Style, - Text = Text - }; - } - } - - internal class ElementTextItem : ITextElement - { - public Element Element { get; set; } = Empty.Instance; - - public TextMeasurementResult? Measure(TextMeasurementRequest request) - { - Element.HandleVisitor(x => (x as IStateResettable)?.ResetState()); - Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas)); - - var measurement = Element.Measure(new Size(request.AvailableWidth, Size.Max.Height)); - - if (measurement is Wrap || measurement is PartialRender) - return null; - - var elementSize = measurement as Size; - - return new TextMeasurementResult - { - Width = elementSize.Width, - - Ascent = -elementSize.Height, - Descent = 0, - - LineHeight = 1, - - StartIndex = 0, - EndIndex = 0, - TotalIndex = 0 - }; - } - - public void Draw(TextDrawingRequest request) - { - Element.HandleVisitor(x => (x as IStateResettable)?.ResetState()); - Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas)); - - request.Canvas.Translate(new Position(0, request.TotalAscent)); - Element.Draw(new Size(request.TextSize.Width, -request.TotalAscent)); - request.Canvas.Translate(new Position(0, -request.TotalAscent)); - } - } -} \ No newline at end of file diff --git a/QuestPDF/Fluent/TextExtensions.cs b/QuestPDF/Fluent/TextExtensions.cs index 79b2602..b817012 100644 --- a/QuestPDF/Fluent/TextExtensions.cs +++ b/QuestPDF/Fluent/TextExtensions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using QuestPDF.Elements; using QuestPDF.Elements.Text; +using QuestPDF.Elements.Text.Items; using QuestPDF.Infrastructure; namespace QuestPDF.Fluent @@ -39,7 +40,7 @@ namespace QuestPDF.Fluent Spacing = value; } - private void AddItemToLastTextBlock(ITextElement element) + private void AddItemToLastTextBlock(ITextBlockElement element) { if (!TextBlocks.Any()) TextBlocks.Add(new TextBlock()); @@ -69,7 +70,7 @@ namespace QuestPDF.Fluent .Skip(1) .Select(x => new TextBlock { - Children = new List { x } + Children = new List { x } }) .ToList() .ForEach(TextBlocks.Add); @@ -84,7 +85,7 @@ namespace QuestPDF.Fluent { style ??= DefaultStyle; - AddItemToLastTextBlock(new PageNumberTextItem() + AddItemToLastTextBlock(new TextBlockPageNumber() { Style = style, SlotName = slotName @@ -110,7 +111,7 @@ namespace QuestPDF.Fluent { style ??= DefaultStyle; - AddItemToLastTextBlock(new InternalLinkTextItem + AddItemToLastTextBlock(new TextBlockInternalLink { Style = style, Text = text, @@ -122,7 +123,7 @@ namespace QuestPDF.Fluent { style ??= DefaultStyle; - AddItemToLastTextBlock(new ExternalLinkTextItem + AddItemToLastTextBlock(new TextBlockExternalLink { Style = style, Text = text, @@ -134,7 +135,7 @@ namespace QuestPDF.Fluent { var container = new Container(); - AddItemToLastTextBlock(new ElementTextItem + AddItemToLastTextBlock(new TextBlockElement { Element = container });