Skip to content

Commit

Permalink
Inlined: simplified implementation and improved performance
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinZiabek committed May 15, 2024
1 parent d64d75f commit 56dd7d8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 25 deletions.
42 changes: 18 additions & 24 deletions Source/QuestPDF/Elements/Inlined.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@

namespace QuestPDF.Elements
{
internal sealed class InlinedElement : Container
{

}

internal enum InlinedAlignment
{
Left,
Expand All @@ -25,12 +20,12 @@ internal struct InlinedMeasurement
public SpacePlan Size { get; set; }
}

internal sealed class Inlined : Element, IStateResettable, IContentDirectionAware
internal sealed class Inlined : Element, IContentDirectionAware, IStateResettable
{
public ContentDirection ContentDirection { get; set; }

public List<InlinedElement> Elements { get; internal set; } = new List<InlinedElement>();
private Queue<InlinedElement> ChildrenQueue { get; set; }
public List<Element> Elements { get; internal set; } = new();
private int CurrentRenderingIndex { get; set; }

internal float VerticalSpacing { get; set; }
internal float HorizontalSpacing { get; set; }
Expand All @@ -40,7 +35,7 @@ internal sealed class Inlined : Element, IStateResettable, IContentDirectionAwar

public void ResetState()
{
ChildrenQueue = new Queue<InlinedElement>(Elements);
CurrentRenderingIndex = 0;
}

internal override IEnumerable<Element?> GetChildren()
Expand All @@ -52,7 +47,7 @@ internal override SpacePlan Measure(Size availableSpace)
{
SetDefaultAlignment();

if (!ChildrenQueue.Any())
if (CurrentRenderingIndex == Elements.Count)
return SpacePlan.FullRender(Size.Zero);

var lines = Compose(availableSpace);
Expand All @@ -74,12 +69,12 @@ internal override SpacePlan Measure(Size availableSpace)
var height = lineSizes.Sum(x => x.Height) + (lines.Count - 1) * VerticalSpacing;
var targetSize = new Size(width, height);

var isPartiallyRendered = lines.Sum(x => x.Count) != ChildrenQueue.Count;
var totalRenderedItems = CurrentRenderingIndex + lines.Sum(x => x.Count);
var willBeFullyRendered = totalRenderedItems == Elements.Count;

if (isPartiallyRendered)
return SpacePlan.PartialRender(targetSize);

return SpacePlan.FullRender(targetSize);
return willBeFullyRendered
? SpacePlan.FullRender(targetSize)
: SpacePlan.PartialRender(targetSize);
}

internal override void Draw(Size availableSpace)
Expand All @@ -100,10 +95,9 @@ internal override void Draw(Size availableSpace)
}

Canvas.Translate(new Position(0, -topOffset));
lines.SelectMany(x => x).ToList().ForEach(x => ChildrenQueue.Dequeue());

if (!ChildrenQueue.Any())
ResetState();
var fullyRenderedItems = lines.Sum(x => x.Count);
CurrentRenderingIndex += fullyRenderedItems;

void DrawLine(ICollection<InlinedMeasurement> lineMeasurements)
{
Expand Down Expand Up @@ -183,8 +177,8 @@ void SetDefaultAlignment()
ElementsAlignment = ContentDirection == ContentDirection.LeftToRight
? InlinedAlignment.Left
: InlinedAlignment.Right;
}

}

static Size GetLineSize(ICollection<InlinedMeasurement> measurements)
{
var width = measurements.Sum(x => x.Size.Width);
Expand All @@ -196,7 +190,7 @@ static Size GetLineSize(ICollection<InlinedMeasurement> measurements)
// list of lines, each line is a list of elements
private ICollection<ICollection<InlinedMeasurement>> Compose(Size availableSize)
{
var queue = new Queue<InlinedElement>(ChildrenQueue);
var localRenderingIndex = CurrentRenderingIndex;
var result = new List<ICollection<InlinedMeasurement>>();

var topOffset = 0f;
Expand Down Expand Up @@ -226,10 +220,10 @@ ICollection<InlinedMeasurement> GetNextLine()

while (true)
{
if (!queue.Any())
if (localRenderingIndex == Elements.Count)
break;

var element = queue.Peek();
var element = Elements[localRenderingIndex];
var size = element.Measure(new Size(availableSize.Width, Size.Max.Height));

if (size.Type == SpacePlanType.Wrap)
Expand All @@ -238,7 +232,7 @@ ICollection<InlinedMeasurement> GetNextLine()
if (leftOffset + size.Width > availableSize.Width + Size.Epsilon)
break;

queue.Dequeue();
localRenderingIndex++;
leftOffset += size.Width + HorizontalSpacing;

result.Add(new InlinedMeasurement
Expand Down
2 changes: 1 addition & 1 deletion Source/QuestPDF/Fluent/InlinedExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public void AlignSpaceAround()
/// <returns>The container of the newly created item.</returns>
public IContainer Item()
{
var container = new InlinedElement();
var container = new Constrained();
Inlined.Elements.Add(container);
return container;
}
Expand Down

0 comments on commit 56dd7d8

Please sign in to comment.