VisitChildren -> GetChildren traversal refactorization
This commit is contained in:
Родитель
7f651932b9
Коммит
eb297177ea
|
@ -11,6 +11,7 @@ using NUnit.Framework;
|
|||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Drawing.Proxy;
|
||||
using QuestPDF.Elements;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using QuestPDF.ReportSample.Layouts;
|
||||
|
||||
|
@ -55,7 +56,7 @@ namespace QuestPDF.ReportSample
|
|||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
Content.HandleVisitor(x =>
|
||||
Content.VisitChildren(x =>
|
||||
{
|
||||
if (x is ICacheable)
|
||||
x.CreateProxy(y => new CacheProxy(y));
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||
|
||||
public TestPlan CheckMeasureResult(SpacePlan expected)
|
||||
{
|
||||
Element.HandleVisitor(x => x?.Initialize(null, Canvas));
|
||||
Element.VisitChildren(x => x?.Initialize(null, Canvas));
|
||||
|
||||
var actual = Element.Measure(OperationInput);
|
||||
|
||||
|
@ -228,7 +228,7 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||
|
||||
public TestPlan CheckDrawResult()
|
||||
{
|
||||
Element.HandleVisitor(x => x?.Initialize(null, Canvas));
|
||||
Element.VisitChildren(x => x?.Initialize(null, Canvas));
|
||||
Element.Draw(OperationInput);
|
||||
return this;
|
||||
}
|
||||
|
@ -271,10 +271,10 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||
availableSpace ??= new Size(400, 300);
|
||||
|
||||
var canvas = new FreeCanvas();
|
||||
value.HandleVisitor(x => x.Initialize(null, canvas));
|
||||
value.VisitChildren(x => x.Initialize(null, canvas));
|
||||
var valueMeasure = value.Measure(availableSpace.Value);
|
||||
|
||||
expected.HandleVisitor(x => x.Initialize(null, canvas));
|
||||
expected.VisitChildren(x => x.Initialize(null, canvas));
|
||||
var expectedMeasure = expected.Measure(availableSpace.Value);
|
||||
|
||||
valueMeasure.Should().BeEquivalentTo(expectedMeasure);
|
||||
|
@ -285,11 +285,11 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||
availableSpace ??= new Size(400, 300);
|
||||
|
||||
var valueCanvas = new OperationRecordingCanvas();
|
||||
value.HandleVisitor(x => x.Initialize(null, valueCanvas));
|
||||
value.VisitChildren(x => x.Initialize(null, valueCanvas));
|
||||
value.Draw(availableSpace.Value);
|
||||
|
||||
var expectedCanvas = new OperationRecordingCanvas();
|
||||
expected.HandleVisitor(x => x.Initialize(null, expectedCanvas));
|
||||
expected.VisitChildren(x => x.Initialize(null, expectedCanvas));
|
||||
expected.Draw(availableSpace.Value);
|
||||
|
||||
valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations);
|
||||
|
|
|
@ -7,6 +7,8 @@ using QuestPDF.Drawing.Proxy;
|
|||
using QuestPDF.Elements;
|
||||
using QuestPDF.Elements.Text;
|
||||
using QuestPDF.Elements.Text.Items;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Drawing
|
||||
|
@ -42,6 +44,7 @@ namespace QuestPDF.Drawing
|
|||
var container = new DocumentContainer();
|
||||
document.Compose(container);
|
||||
var content = container.Compose();
|
||||
ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
|
||||
|
||||
var metadata = document.GetMetadata();
|
||||
var pageContext = new PageContext();
|
||||
|
@ -58,8 +61,8 @@ namespace QuestPDF.Drawing
|
|||
internal static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata, DebuggingState? debuggingState)
|
||||
where TCanvas : ICanvas, IRenderingCanvas
|
||||
{
|
||||
content.HandleVisitor(x => x?.Initialize(pageContext, canvas));
|
||||
content.HandleVisitor(x => (x as IStateResettable)?.ResetState());
|
||||
content.VisitChildren(x => x?.Initialize(pageContext, canvas));
|
||||
content.VisitChildren(x => (x as IStateResettable)?.ResetState());
|
||||
|
||||
canvas.BeginDocument();
|
||||
|
||||
|
@ -122,7 +125,7 @@ namespace QuestPDF.Drawing
|
|||
|
||||
private static void ApplyCaching(Container content)
|
||||
{
|
||||
content.HandleVisitor(x =>
|
||||
content.VisitChildren(x =>
|
||||
{
|
||||
if (x is ICacheable)
|
||||
x.CreateProxy(y => new CacheProxy(y));
|
||||
|
@ -133,7 +136,7 @@ namespace QuestPDF.Drawing
|
|||
{
|
||||
var debuggingState = new DebuggingState();
|
||||
|
||||
content.HandleVisitor(x =>
|
||||
content.VisitChildren(x =>
|
||||
{
|
||||
x.CreateProxy(y => new DebuggingProxy(debuggingState, y));
|
||||
});
|
||||
|
@ -141,26 +144,38 @@ namespace QuestPDF.Drawing
|
|||
return debuggingState;
|
||||
}
|
||||
|
||||
internal static void ApplyDefaultTextStyle(this Element content, TextStyle documentDefaultTextStyle)
|
||||
private static void ApplyDefaultTextStyle(this Element? content, TextStyle documentDefaultTextStyle)
|
||||
{
|
||||
documentDefaultTextStyle.ApplyGlobalStyle(TextStyle.LibraryDefault);
|
||||
|
||||
content.HandleVisitor(element =>
|
||||
{
|
||||
var text = element as TextBlock;
|
||||
|
||||
if (text == null)
|
||||
if (content == null)
|
||||
return;
|
||||
|
||||
foreach (var child in text.Children)
|
||||
if (content is TextBlock textBlock)
|
||||
{
|
||||
foreach (var textBlockItem in textBlock.Items)
|
||||
{
|
||||
if (textBlockItem is TextBlockSpan textSpan)
|
||||
{
|
||||
if (child is TextBlockSpan textSpan)
|
||||
textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle);
|
||||
|
||||
if (child is TextBlockElement textElement)
|
||||
}
|
||||
else if (textBlockItem is TextBlockElement textElement)
|
||||
{
|
||||
ApplyDefaultTextStyle(textElement.Element, documentDefaultTextStyle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var targetTextStyle = documentDefaultTextStyle;
|
||||
|
||||
if (content is DefaultTextStyle defaultTextStyleElement)
|
||||
{
|
||||
defaultTextStyleElement.TextStyle.ApplyParentStyle(documentDefaultTextStyle);
|
||||
targetTextStyle = defaultTextStyleElement.TextStyle;
|
||||
}
|
||||
|
||||
foreach (var child in content.GetChildren())
|
||||
ApplyDefaultTextStyle(child, targetTextStyle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
@ -17,12 +18,10 @@ namespace QuestPDF.Elements
|
|||
public Element ContentElement { get; set; } = Empty.Instance;
|
||||
public DecorationType Type { get; set; }
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
DecorationElement?.HandleVisitor(visit);
|
||||
ContentElement?.HandleVisitor(visit);
|
||||
|
||||
base.HandleVisitor(visit);
|
||||
yield return DecorationElement;
|
||||
yield return ContentElement;
|
||||
}
|
||||
|
||||
internal override void CreateProxy(Func<Element, Element> create)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Elements
|
||||
{
|
||||
internal class DefaultTextStyle : ContainerElement
|
||||
{
|
||||
public TextStyle TextStyle { get; set; } = TextStyle.Default;
|
||||
}
|
||||
}
|
|
@ -44,10 +44,9 @@ namespace QuestPDF.Elements
|
|||
ChildrenQueue = new Queue<InlinedElement>(Elements);
|
||||
}
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
Elements.ForEach(x => x.HandleVisitor(visit));
|
||||
base.HandleVisitor(visit);
|
||||
return Elements;
|
||||
}
|
||||
|
||||
internal override SpacePlan Measure(Size availableSpace)
|
||||
|
|
|
@ -15,10 +15,9 @@ namespace QuestPDF.Elements
|
|||
{
|
||||
public List<Layer> Children { get; set; } = new List<Layer>();
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
Children.ForEach(x => x.HandleVisitor(visit));
|
||||
base.HandleVisitor(visit);
|
||||
return Children;
|
||||
}
|
||||
|
||||
internal override SpacePlan Measure(Size availableSpace)
|
||||
|
|
|
@ -38,12 +38,10 @@ namespace QuestPDF.Elements
|
|||
IsRightRendered = false;
|
||||
}
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
Left.HandleVisitor(visit);
|
||||
Right.HandleVisitor(visit);
|
||||
|
||||
base.HandleVisitor(visit);
|
||||
yield return Left;
|
||||
yield return Right;
|
||||
}
|
||||
|
||||
internal override void CreateProxy(Func<Element?, Element?> create)
|
||||
|
@ -99,16 +97,15 @@ namespace QuestPDF.Elements
|
|||
{
|
||||
public float Spacing { get; set; } = 0;
|
||||
|
||||
public ICollection<RowElement> Children { get; internal set; } = new List<RowElement>();
|
||||
public ICollection<RowElement> Items { get; internal set; } = new List<RowElement>();
|
||||
private Element? RootElement { get; set; }
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
if (RootElement == null)
|
||||
ComposeTree();
|
||||
|
||||
RootElement.HandleVisitor(visit);
|
||||
base.HandleVisitor(visit);
|
||||
return Items;
|
||||
}
|
||||
|
||||
internal override SpacePlan Measure(Size availableSpace)
|
||||
|
@ -127,20 +124,20 @@ namespace QuestPDF.Elements
|
|||
|
||||
private void ComposeTree()
|
||||
{
|
||||
Children = AddSpacing(Children, Spacing);
|
||||
Items = AddSpacing(Items, Spacing);
|
||||
|
||||
var elements = Children.Cast<Element>().ToArray();
|
||||
var elements = Items.Cast<Element>().ToArray();
|
||||
RootElement = BuildTree(elements);
|
||||
}
|
||||
|
||||
private void UpdateElementsWidth(float availableWidth)
|
||||
{
|
||||
var constantWidth = Children.Sum(x => x.ConstantSize);
|
||||
var relativeWidth = Children.Sum(x => x.RelativeSize);
|
||||
var constantWidth = Items.Sum(x => x.ConstantSize);
|
||||
var relativeWidth = Items.Sum(x => x.RelativeSize);
|
||||
|
||||
var widthPerRelativeUnit = (relativeWidth > 0) ? (availableWidth - constantWidth) / relativeWidth : 0;
|
||||
|
||||
foreach (var row in Children)
|
||||
foreach (var row in Items)
|
||||
{
|
||||
row.SetWidth(row.ConstantSize + row.RelativeSize * widthPerRelativeUnit);
|
||||
}
|
||||
|
|
|
@ -16,12 +16,10 @@ namespace QuestPDF.Elements
|
|||
|
||||
internal bool IsFirstRendered { get; set; } = false;
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
First?.HandleVisitor(visit);
|
||||
Second?.HandleVisitor(visit);
|
||||
|
||||
base.HandleVisitor(visit);
|
||||
yield return First;
|
||||
yield return Second;
|
||||
}
|
||||
|
||||
public void ResetState()
|
||||
|
@ -97,12 +95,12 @@ namespace QuestPDF.Elements
|
|||
|
||||
internal class Stack : IComponent
|
||||
{
|
||||
public ICollection<Element> Children { get; } = new List<Element>();
|
||||
public ICollection<Element> Items { get; } = new List<Element>();
|
||||
public float Spacing { get; set; } = 0;
|
||||
|
||||
public void Compose(IContainer container)
|
||||
{
|
||||
var elements = AddSpacing(Spacing, Children);
|
||||
var elements = AddSpacing(Spacing, Items);
|
||||
|
||||
container
|
||||
.PaddingBottom(-Spacing)
|
||||
|
|
|
@ -12,51 +12,50 @@ namespace QuestPDF.Elements.Table
|
|||
internal class Table : Element, IStateResettable
|
||||
{
|
||||
public List<TableColumnDefinition> Columns { get; } = new List<TableColumnDefinition>();
|
||||
public List<TableCell> Children { get; } = new List<TableCell>();
|
||||
public List<TableCell> Cells { get; } = new List<TableCell>();
|
||||
public bool ExtendLastCellsToTableBottom { get; set; }
|
||||
|
||||
// cache for efficient cell finding
|
||||
// index of first array - number of row
|
||||
// nested array - collection of all cells starting at given row
|
||||
private TableCell[][] OrderedChildren { get; set; }
|
||||
private TableCell[][] OrderedCells { get; set; }
|
||||
|
||||
private int StartingRowsCount { get; set; }
|
||||
private int RowsCount { get; set; }
|
||||
private int CurrentRow { get; set; }
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
Children.ToList().ForEach(x => x.HandleVisitor(visit));
|
||||
base.HandleVisitor(visit);
|
||||
return Cells;
|
||||
}
|
||||
|
||||
public void ResetState()
|
||||
{
|
||||
if (StartingRowsCount == default)
|
||||
StartingRowsCount = Children.Select(x => x.Row).DefaultIfEmpty(0).Max();
|
||||
StartingRowsCount = Cells.Select(x => x.Row).DefaultIfEmpty(0).Max();
|
||||
|
||||
if (RowsCount == default)
|
||||
RowsCount = Children.Select(x => x.Row + x.RowSpan - 1).DefaultIfEmpty(0).Max();
|
||||
RowsCount = Cells.Select(x => x.Row + x.RowSpan - 1).DefaultIfEmpty(0).Max();
|
||||
|
||||
if (OrderedChildren == default)
|
||||
if (OrderedCells == default)
|
||||
{
|
||||
var groups = Children
|
||||
var groups = Cells
|
||||
.GroupBy(x => x.Row)
|
||||
.ToDictionary(x => x.Key, x => x.OrderBy(y => y.Column).ToArray());
|
||||
|
||||
OrderedChildren = Enumerable
|
||||
OrderedCells = Enumerable
|
||||
.Range(0, RowsCount + 1)
|
||||
.Select(x => groups.TryGetValue(x, out var output) ? output : Array.Empty<TableCell>())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
Children.ForEach(x => x.IsRendered = false);
|
||||
Cells.ForEach(x => x.IsRendered = false);
|
||||
CurrentRow = 1;
|
||||
}
|
||||
|
||||
internal override SpacePlan Measure(Size availableSpace)
|
||||
{
|
||||
if (!Children.Any())
|
||||
if (!Cells.Any())
|
||||
return SpacePlan.FullRender(Size.Zero);
|
||||
|
||||
UpdateColumnsWidth(availableSpace.Width);
|
||||
|
@ -149,16 +148,16 @@ namespace QuestPDF.Elements.Table
|
|||
{
|
||||
var rowBottomOffsets = new DynamicDictionary<int, float>();
|
||||
|
||||
var childrenToTry = Enumerable
|
||||
var cellsToTry = Enumerable
|
||||
.Range(CurrentRow, RowsCount - CurrentRow + 1)
|
||||
.SelectMany(x => OrderedChildren[x]);
|
||||
.SelectMany(x => OrderedCells[x]);
|
||||
|
||||
var currentRow = CurrentRow;
|
||||
var maxRenderingRow = RowsCount;
|
||||
|
||||
var commands = new List<TableCellRenderingCommand>();
|
||||
|
||||
foreach (var cell in childrenToTry)
|
||||
foreach (var cell in cellsToTry)
|
||||
{
|
||||
// update position of previous row
|
||||
if (cell.Row > currentRow)
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace QuestPDF.Elements.Table
|
|||
{
|
||||
public static void PlanCellPositions(this Table table)
|
||||
{
|
||||
PlanCellPositions(table.Columns.Count, table.Children);
|
||||
PlanCellPositions(table.Columns.Count, table.Cells);
|
||||
}
|
||||
|
||||
private static void PlanCellPositions(int columnsCount, ICollection<TableCell> cells)
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace QuestPDF.Elements.Table
|
|||
{
|
||||
public static void ValidateCellPositions(this Table table)
|
||||
{
|
||||
ValidateCellPositions(table.Columns.Count, table.Children);
|
||||
ValidateCellPositions(table.Columns.Count, table.Cells);
|
||||
}
|
||||
|
||||
private static void ValidateCellPositions(int columnsCount, ICollection<TableCell> cells)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Elements.Text.Calculation;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Elements.Text.Items
|
||||
|
@ -10,8 +11,8 @@ namespace QuestPDF.Elements.Text.Items
|
|||
|
||||
public TextMeasurementResult? Measure(TextMeasurementRequest request)
|
||||
{
|
||||
Element.HandleVisitor(x => (x as IStateResettable)?.ResetState());
|
||||
Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas));
|
||||
Element.VisitChildren(x => (x as IStateResettable)?.ResetState());
|
||||
Element.VisitChildren(x => x.Initialize(request.PageContext, request.Canvas));
|
||||
|
||||
var measurement = Element.Measure(new Size(request.AvailableWidth, Size.Max.Height));
|
||||
|
||||
|
@ -35,8 +36,8 @@ namespace QuestPDF.Elements.Text.Items
|
|||
|
||||
public void Draw(TextDrawingRequest request)
|
||||
{
|
||||
Element.HandleVisitor(x => (x as IStateResettable)?.ResetState());
|
||||
Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas));
|
||||
Element.VisitChildren(x => (x as IStateResettable)?.ResetState());
|
||||
Element.VisitChildren(x => x.Initialize(request.PageContext, request.Canvas));
|
||||
|
||||
request.Canvas.Translate(new Position(0, request.TotalAscent));
|
||||
Element.Draw(new Size(request.TextSize.Width, -request.TotalAscent));
|
||||
|
|
|
@ -11,16 +11,16 @@ namespace QuestPDF.Elements.Text
|
|||
internal class TextBlock : Element, IStateResettable
|
||||
{
|
||||
public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
|
||||
public List<ITextBlockItem> Children { get; set; } = new List<ITextBlockItem>();
|
||||
public List<ITextBlockItem> Items { get; set; } = new List<ITextBlockItem>();
|
||||
|
||||
public string Text => string.Join(" ", Children.Where(x => x is TextBlockSpan).Cast<TextBlockSpan>().Select(x => x.Text));
|
||||
public string Text => string.Join(" ", Items.Where(x => x is TextBlockSpan).Cast<TextBlockSpan>().Select(x => x.Text));
|
||||
|
||||
private Queue<ITextBlockItem> RenderingQueue { get; set; }
|
||||
private int CurrentElementIndex { get; set; }
|
||||
|
||||
public void ResetState()
|
||||
{
|
||||
RenderingQueue = new Queue<ITextBlockItem>(Children);
|
||||
RenderingQueue = new Queue<ITextBlockItem>(Items);
|
||||
CurrentElementIndex = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace QuestPDF.Fluent
|
|||
{
|
||||
var element = new RowElement(constantWidth, relativeWidth);
|
||||
|
||||
Row.Children.Add(element);
|
||||
Row.Items.Add(element);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace QuestPDF.Fluent
|
|||
public IContainer Item()
|
||||
{
|
||||
var container = new Container();
|
||||
Stack.Children.Add(container);
|
||||
Stack.Items.Add(container);
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,13 +61,13 @@ namespace QuestPDF.Fluent
|
|||
public ITableCellContainer Cell()
|
||||
{
|
||||
var cell = new TableCell();
|
||||
Table.Children.Add(cell);
|
||||
Table.Cells.Add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
internal void ApplyDefaultCellStyle()
|
||||
{
|
||||
foreach (var cell in Table.Children)
|
||||
foreach (var cell in Table.Cells)
|
||||
{
|
||||
var container = new Container();
|
||||
DefaultCellStyleFunc(container).Element(cell.Child);
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace QuestPDF.Fluent
|
|||
if (!TextBlocks.Any())
|
||||
TextBlocks.Add(new TextBlock());
|
||||
|
||||
TextBlocks.Last().Children.Add(item);
|
||||
TextBlocks.Last().Items.Add(item);
|
||||
}
|
||||
|
||||
public void Span(string? text, TextStyle? style = null)
|
||||
|
@ -73,7 +73,7 @@ namespace QuestPDF.Fluent
|
|||
.Skip(1)
|
||||
.Select(x => new TextBlock
|
||||
{
|
||||
Children = new List<ITextBlockItem> { x }
|
||||
Items = new List<ITextBlockItem> { x }
|
||||
})
|
||||
.ToList()
|
||||
.ForEach(TextBlocks.Add);
|
||||
|
@ -174,10 +174,7 @@ namespace QuestPDF.Fluent
|
|||
{
|
||||
TextBlocks.ToList().ForEach(x => x.Alignment = Alignment);
|
||||
|
||||
foreach (var textBlockSpan in TextBlocks.SelectMany(x => x.Children).Where(x => x is TextBlockSpan).Cast<TextBlockSpan>())
|
||||
textBlockSpan.Style.ApplyParentStyle(DefaultStyle);
|
||||
|
||||
container.Stack(stack =>
|
||||
container.DefaultTextStyle(DefaultStyle).Stack(stack =>
|
||||
{
|
||||
stack.Spacing(Spacing);
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace QuestPDF.Helpers
|
||||
{
|
||||
|
@ -41,5 +43,13 @@ namespace QuestPDF.Helpers
|
|||
{
|
||||
return Regex.Replace(text, @"([a-z])([A-Z])", "$1 $2");
|
||||
}
|
||||
|
||||
internal static void VisitChildren(this Element? element, Action<Element?> handler)
|
||||
{
|
||||
handler(element);
|
||||
|
||||
foreach (var child in element.GetChildren().Where(x => x != null))
|
||||
VisitChildren(child, handler);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Elements;
|
||||
|
||||
|
@ -14,10 +15,9 @@ namespace QuestPDF.Infrastructure
|
|||
set => Child = value as Element;
|
||||
}
|
||||
|
||||
internal override void HandleVisitor(Action<Element?> visit)
|
||||
internal override IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
Child?.HandleVisitor(visit);
|
||||
base.HandleVisitor(visit);
|
||||
yield return Child;
|
||||
}
|
||||
|
||||
internal override void CreateProxy(Func<Element?, Element?> create)
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace QuestPDF.Infrastructure
|
|||
internal IPageContext PageContext { get; set; }
|
||||
internal ICanvas Canvas { get; set; }
|
||||
|
||||
internal virtual void HandleVisitor(Action<Element?> visit)
|
||||
internal virtual IEnumerable<Element?> GetChildren()
|
||||
{
|
||||
visit(this);
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal void Initialize(IPageContext pageContext, ICanvas canvas)
|
||||
|
|
Загрузка…
Ссылка в новой задаче