Skip to content

Commit

Permalink
Fixed QuestPDF#609: the page number functionality for sections do not…
Browse files Browse the repository at this point in the history
… work (QuestPDF#612)

Refactoring: handling of page numbers in sections
  • Loading branch information
MarcinZiabek authored Jul 20, 2023
1 parent cedeaae commit 594f358
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 55 deletions.
58 changes: 26 additions & 32 deletions Source/QuestPDF/Drawing/DocumentGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,12 @@ private static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document,
private static void RenderSingleDocument<TCanvas>(TCanvas canvas, IDocument document, DocumentSettings settings)
where TCanvas : ICanvas, IRenderingCanvas
{
const int documentId = 0;

var debuggingState = new DebuggingState();
var useOriginalImages = canvas is ImageCanvas;

var content = ConfigureContent(document, settings, debuggingState, 0, useOriginalImages);
var content = ConfigureContent(document, settings, debuggingState, documentId, useOriginalImages);

var pageContext = new PageContext();
RenderPass(pageContext, new FreeCanvas(), content, debuggingState);
Expand All @@ -122,31 +124,43 @@ private static void RenderMergedDocument<TCanvas>(TCanvas canvas, MergedDocument
var debuggingState = new DebuggingState();
var useOriginalImages = canvas is ImageCanvas;

var documentContents = Enumerable
var documentParts = Enumerable
.Range(0, document.Documents.Count)
.Select(index => ConfigureContent(document.Documents[index], settings, debuggingState, index, useOriginalImages))
.Select(index => new
{
DocumentId = index,
Content = ConfigureContent(document.Documents[index], settings, debuggingState, index, useOriginalImages)
})
.ToList();

if (document.PageNumberStrategy == MergedDocumentPageNumberStrategy.Continuous)
{
var documentPageContext = new PageContext();

foreach (var content in documentContents)
RenderPass(documentPageContext, new FreeCanvas(), content, debuggingState);

foreach (var documentPart in documentParts)
{
documentPageContext.SetDocumentId(documentPart.DocumentId);
RenderPass(documentPageContext, new FreeCanvas(), documentPart.Content, debuggingState);
}

documentPageContext.ResetPageNumber();

foreach (var content in documentContents)
RenderPass(documentPageContext, canvas, content, debuggingState);

foreach (var documentPart in documentParts)
{
documentPageContext.SetDocumentId(documentPart.DocumentId);
RenderPass(documentPageContext, canvas, documentPart.Content, debuggingState);
}
}
else
{
foreach (var content in documentContents)
foreach (var documentPart in documentParts)
{
var pageContext = new PageContext();
RenderPass(pageContext, new FreeCanvas(), content, debuggingState);
pageContext.SetDocumentId(documentPart.DocumentId);

RenderPass(pageContext, new FreeCanvas(), documentPart.Content, debuggingState);
pageContext.ResetPageNumber();
RenderPass(pageContext, canvas, content, debuggingState);
RenderPass(pageContext, canvas, documentPart.Content, debuggingState);
}
}
}
Expand All @@ -158,7 +172,6 @@ private static Container ConfigureContent(IDocument document, DocumentSettings s

var content = container.Compose();

content.ApplyDocumentId(documentIndex);
content.ApplyInheritedAndGlobalTexStyle(TextStyle.Default);
content.ApplyContentDirection(settings.ContentDirection);
content.ApplyDefaultImageConfiguration(settings.ImageRasterDpi, settings.ImageCompressionQuality, useOriginalImages);
Expand Down Expand Up @@ -341,24 +354,5 @@ internal static void ApplyInheritedAndGlobalTexStyle(this Element? content, Text
foreach (var child in content.GetChildren())
ApplyInheritedAndGlobalTexStyle(child, documentDefaultTextStyle);
}

/// <summary>
/// This method is important when merging multiple documents together.
/// Applying unique document Id to all section names and associated links, prevents from name collisions.
/// </summary>
internal static void ApplyDocumentId(this Element? content, int documentId = 0)
{
content.VisitChildren(x =>
{
if (x is Section section)
section.DocumentId = documentId;

else if (x is SectionLink sectionLink)
sectionLink.DocumentId = documentId;

else if (x is DynamicHost dynamicHost)
dynamicHost.DocumentId = documentId;
});
}
}
}
9 changes: 2 additions & 7 deletions Source/QuestPDF/Elements/Dynamic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ internal class DynamicHost : Element, IStateResettable, IContentDirectionAware
internal TextStyle TextStyle { get; set; } = TextStyle.Default;
public ContentDirection ContentDirection { get; set; }

internal int DocumentId { get; set; }

internal int? ImageTargetDpi { get; set; }
internal ImageCompressionQuality? ImageCompressionQuality { get; set; }
internal bool UseOriginalImage { get; set; }
Expand Down Expand Up @@ -60,7 +58,6 @@ private DynamicComponentComposeResult GetContent(Size availableSize, bool accept
{
PageContext = PageContext,
Canvas = Canvas,
DocumentId = DocumentId,

TextStyle = TextStyle,
ContentDirection = ContentDirection,
Expand All @@ -70,7 +67,7 @@ private DynamicComponentComposeResult GetContent(Size availableSize, bool accept
UseOriginalImage = UseOriginalImage,

PageNumber = PageContext.CurrentPage,
TotalPages = PageContext.GetLocation(Infrastructure.PageContext.DocumentLocation).PageEnd,
TotalPages = PageContext.DocumentLength,
AvailableSize = availableSize
};

Expand All @@ -87,8 +84,7 @@ public class DynamicContext
{
internal IPageContext PageContext { get; set; }
internal ICanvas Canvas { get; set; }
internal int DocumentId { get; set; }


internal TextStyle TextStyle { get; set; }
internal ContentDirection ContentDirection { get; set; }

Expand All @@ -105,7 +101,6 @@ public IDynamicElement CreateElement(Action<IContainer> content)
var container = new DynamicElement();
content(container);

container.ApplyDocumentId(DocumentId);
container.ApplyInheritedAndGlobalTexStyle(TextStyle);
container.ApplyContentDirection(ContentDirection);
container.ApplyDefaultImageConfiguration(ImageTargetDpi, ImageCompressionQuality, UseOriginalImage);
Expand Down
11 changes: 2 additions & 9 deletions Source/QuestPDF/Elements/Section.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ namespace QuestPDF.Elements
{
internal class Section : ContainerElement, IStateResettable
{
public int DocumentId { get; set; }
public string SectionName { get; set; }
private bool IsRendered { get; set; }

Expand All @@ -15,21 +14,15 @@ public void ResetState()

internal override void Draw(Size availableSpace)
{
var targetName = GetTargetName(DocumentId, SectionName);

if (!IsRendered)
{
var targetName = PageContext.GetDocumentLocationName(SectionName);
Canvas.DrawSection(targetName);
IsRendered = true;
}

PageContext.SetSectionPage(targetName);
PageContext.SetSectionPage(SectionName);
base.Draw(availableSpace);
}

internal static string GetTargetName(int documentId, string locationName)
{
return $"{documentId} | {locationName}";
}
}
}
3 changes: 1 addition & 2 deletions Source/QuestPDF/Elements/SectionLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ namespace QuestPDF.Elements
{
internal class SectionLink : ContainerElement
{
public int DocumentId { get; set; }
public string SectionName { get; set; }

internal override void Draw(Size availableSpace)
Expand All @@ -15,7 +14,7 @@ internal override void Draw(Size availableSpace)
if (targetSize.Type == SpacePlanType.Wrap)
return;

var targetName = Section.GetTargetName(DocumentId, SectionName);
var targetName = PageContext.GetDocumentLocationName(SectionName);
Canvas.DrawSectionLink(targetName, targetSize);
base.Draw(availableSpace);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/QuestPDF/Fluent/TextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public TextPageNumberDescriptor CurrentPageNumber()

public TextPageNumberDescriptor TotalPages()
{
return PageNumber(x => x.GetLocation(PageContext.DocumentLocation)?.Length);
return PageNumber(x => x.DocumentLength);
}

[Obsolete("This element has been renamed since version 2022.3. Please use the BeginPageNumberOfSection method.")]
Expand Down
3 changes: 3 additions & 0 deletions Source/QuestPDF/Infrastructure/IPageContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace QuestPDF.Infrastructure
{
internal class DocumentLocation
{
public int DocumentId { get; set; }
public string Name { get; set; }
public int PageStart { get; set; }
public int PageEnd { get; set; }
Expand All @@ -12,8 +13,10 @@ internal class DocumentLocation

internal interface IPageContext
{
int DocumentLength { get; }
int CurrentPage { get; }
void SetSectionPage(string name);
DocumentLocation? GetLocation(string name);
string GetDocumentLocationName(string locationName);
}
}
20 changes: 16 additions & 4 deletions Source/QuestPDF/Infrastructure/PageContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ namespace QuestPDF.Infrastructure
{
internal class PageContext : IPageContext
{
public const string DocumentLocation = "document";

public int DocumentLength { get; private set; }
private List<DocumentLocation> Locations { get; } = new();

public int CurrentDocumentId { get; private set; }
public int CurrentPage { get; private set; }

internal void SetDocumentId(int id)
{
CurrentDocumentId = id;
}

internal void ResetPageNumber()
{
CurrentPage = 0;
Expand All @@ -19,7 +25,7 @@ internal void ResetPageNumber()
internal void IncrementPageNumber()
{
CurrentPage++;
SetSectionPage(DocumentLocation);
DocumentLength = Math.Max(DocumentLength, CurrentPage);
}

public void SetSectionPage(string name)
Expand All @@ -30,6 +36,7 @@ public void SetSectionPage(string name)
{
location = new DocumentLocation
{
DocumentId = CurrentDocumentId,
Name = name,
PageStart = CurrentPage,
PageEnd = CurrentPage
Expand All @@ -44,7 +51,12 @@ public void SetSectionPage(string name)

public DocumentLocation? GetLocation(string name)
{
return Locations.Find(x => x.Name == name);
return Locations.Find(x => x.DocumentId == CurrentDocumentId && x.Name == name);
}

public string GetDocumentLocationName(string locationName)
{
return $"{CurrentDocumentId} | {locationName}";
}
}
}

0 comments on commit 594f358

Please sign in to comment.