Text: rendering custom elements inside text
This commit is contained in:
@@ -17,6 +17,7 @@ namespace QuestPDF.Examples
|
||||
.PageSize(PageSizes.A4)
|
||||
.FileName()
|
||||
.ProducePdf()
|
||||
.ShowResults()
|
||||
.Render(container =>
|
||||
{
|
||||
container
|
||||
@@ -30,17 +31,22 @@ namespace QuestPDF.Examples
|
||||
text.Span("Then something bigger. ", TextStyle.Default.Size(28).Color(Colors.DeepOrange.Darken2).BackgroundColor(Colors.Yellow.Lighten3).Underlined());
|
||||
text.Span("And tiny teeny-tiny. ", TextStyle.Default.Size(6));
|
||||
text.Span("Stroked text also works fine. ", TextStyle.Default.Size(14).Stroked().BackgroundColor(Colors.Grey.Lighten4));
|
||||
//text.NewLine();
|
||||
|
||||
text.NewLine();
|
||||
text.Span("Is it time for lorem ipsum? ", TextStyle.Default.Size(12).Underlined().BackgroundColor(Colors.Grey.Lighten3));
|
||||
text.Span(Placeholders.LoremIpsum(), TextStyle.Default.Size(12));
|
||||
|
||||
//text.NewLine();
|
||||
text.Span("And now some colors: ", TextStyle.Default.Size(16).Color(Colors.Green.Medium));
|
||||
text.Span("Before element - ");
|
||||
text.Element().PaddingBottom(-10).Background(Colors.Red.Lighten4).Width(50).Height(20);
|
||||
text.Span(" - end of element.");
|
||||
|
||||
foreach (var i in Enumerable.Range(1, 100))
|
||||
{
|
||||
text.Span($"{i}: {Placeholders.Sentence()} ", TextStyle.Default.Size(12 + i / 5).LineHeight(2.75f - i / 50f).Color(Placeholders.Color()).BackgroundColor(Placeholders.BackgroundColor()));
|
||||
}
|
||||
text.NewLine();
|
||||
// text.Span("And now some colors: ", TextStyle.Default.Size(16).Color(Colors.Green.Medium));
|
||||
//
|
||||
// foreach (var i in Enumerable.Range(1, 100))
|
||||
// {
|
||||
// text.Span($"{i}: {Placeholders.Sentence()} ", TextStyle.Default.Size(12 + i / 5).LineHeight(2.75f - i / 50f).Color(Placeholders.Color()).BackgroundColor(Placeholders.BackgroundColor()));
|
||||
// }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Drawing.SpacePlan;
|
||||
using QuestPDF.Infrastructure;
|
||||
using Size = QuestPDF.Infrastructure.Size;
|
||||
|
||||
@@ -225,4 +226,46 @@ namespace QuestPDF.Elements.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,14 @@ namespace QuestPDF.Fluent
|
||||
{
|
||||
Spacing = value;
|
||||
}
|
||||
|
||||
private void AddItemToLastTextBlock(ITextElement element)
|
||||
{
|
||||
if (!TextBlocks.Any())
|
||||
TextBlocks.Add(new TextBlock());
|
||||
|
||||
TextBlocks.Last().Children.Add(element);
|
||||
}
|
||||
|
||||
public void Span(string text, TextStyle? style = null)
|
||||
{
|
||||
@@ -55,10 +63,7 @@ namespace QuestPDF.Fluent
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (!TextBlocks.Any())
|
||||
TextBlocks.Add(new TextBlock());
|
||||
|
||||
TextBlocks.First().Children.Add(items.First());
|
||||
AddItemToLastTextBlock(items.First());
|
||||
|
||||
items
|
||||
.Skip(1)
|
||||
@@ -79,10 +84,7 @@ namespace QuestPDF.Fluent
|
||||
{
|
||||
style ??= DefaultStyle;
|
||||
|
||||
if (!TextBlocks.Any())
|
||||
TextBlocks.Add(new TextBlock());
|
||||
|
||||
TextBlocks.First().Children.Add(new PageNumberTextItem()
|
||||
AddItemToLastTextBlock(new PageNumberTextItem()
|
||||
{
|
||||
Style = style,
|
||||
SlotName = slotName
|
||||
@@ -108,10 +110,7 @@ namespace QuestPDF.Fluent
|
||||
{
|
||||
style ??= DefaultStyle;
|
||||
|
||||
if (!TextBlocks.Any())
|
||||
TextBlocks.Add(new TextBlock());
|
||||
|
||||
TextBlocks.First().Children.Add(new InternalLinkTextItem
|
||||
AddItemToLastTextBlock(new InternalLinkTextItem
|
||||
{
|
||||
Style = style,
|
||||
Text = text,
|
||||
@@ -123,10 +122,7 @@ namespace QuestPDF.Fluent
|
||||
{
|
||||
style ??= DefaultStyle;
|
||||
|
||||
if (!TextBlocks.Any())
|
||||
TextBlocks.Add(new TextBlock());
|
||||
|
||||
TextBlocks.First().Children.Add(new ExternalLinkTextItem
|
||||
AddItemToLastTextBlock(new ExternalLinkTextItem
|
||||
{
|
||||
Style = style,
|
||||
Text = text,
|
||||
@@ -134,6 +130,18 @@ namespace QuestPDF.Fluent
|
||||
});
|
||||
}
|
||||
|
||||
public IContainer Element()
|
||||
{
|
||||
var container = new Container();
|
||||
|
||||
AddItemToLastTextBlock(new ElementTextItem
|
||||
{
|
||||
Element = container
|
||||
});
|
||||
|
||||
return container.Box();
|
||||
}
|
||||
|
||||
internal void Compose(IContainer container)
|
||||
{
|
||||
TextBlocks.ToList().ForEach(x => x.Alignment = Alignment);
|
||||
|
||||
Reference in New Issue
Block a user