...
 
Commits (4)
    https://gitcode.net/jobily/QuestPDF/-/commit/cedeaaef7a15b206aec4b1a725b7627ae793ac52 Fix: incorrect layout exception when debugging is disabled 2023-07-20T18:48:57+02:00 MarcinZiabek marcin@ziabek.com https://gitcode.net/jobily/QuestPDF/-/commit/594f35810fd9825017ea51fc60dcf6bdb5881913 Fixed #609: the page number functionality for sections do not work (#612) 2023-07-20T18:49:54+02:00 Marcin Ziąbek marcin@ziabek.com Refactoring: handling of page numbers in sections https://gitcode.net/jobily/QuestPDF/-/commit/2a3e6fcbaa3624b293f15998ef91913d5bfaa906 Improvement: enhanced the message about the QuestPDF Previewer application ve... 2023-07-20T19:06:32+02:00 MarcinZiabek marcin@ziabek.com https://gitcode.net/jobily/QuestPDF/-/commit/b24efd26b4101c1e832c4c1831eff31ab0a28728 2023.6.1 2023-07-20T19:06:44+02:00 MarcinZiabek marcin@ziabek.com
......@@ -60,6 +60,7 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 360)
.EnableDebugging()
.Render(container =>
{
container
......
......@@ -105,10 +105,12 @@ namespace QuestPDF.Drawing
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);
......@@ -122,31 +124,43 @@ namespace QuestPDF.Drawing
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);
}
}
}
......@@ -158,7 +172,6 @@ namespace QuestPDF.Drawing
var content = container.Compose();
content.ApplyDocumentId(documentIndex);
content.ApplyInheritedAndGlobalTexStyle(TextStyle.Default);
content.ApplyContentDirection(settings.ContentDirection);
content.ApplyDefaultImageConfiguration(settings.ImageRasterDpi, settings.ImageCompressionQuality, useOriginalImages);
......@@ -341,24 +354,5 @@ namespace QuestPDF.Drawing
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;
});
}
}
}
......@@ -11,7 +11,7 @@ namespace QuestPDF.Drawing.Proxy
{
internal class DebuggingState
{
private DebugStackItem Root { get; set; }
private DebugStackItem? Root { get; set; }
private Stack<DebugStackItem> Stack { get; set; }
public DebuggingState()
......@@ -59,6 +59,9 @@ namespace QuestPDF.Drawing.Proxy
public string BuildTrace()
{
if (Root == null)
return null;
var builder = new StringBuilder();
var nestingLevel = 0;
......
......@@ -14,8 +14,6 @@ namespace QuestPDF.Elements
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; }
......@@ -60,7 +58,6 @@ namespace QuestPDF.Elements
{
PageContext = PageContext,
Canvas = Canvas,
DocumentId = DocumentId,
TextStyle = TextStyle,
ContentDirection = ContentDirection,
......@@ -70,7 +67,7 @@ namespace QuestPDF.Elements
UseOriginalImage = UseOriginalImage,
PageNumber = PageContext.CurrentPage,
TotalPages = PageContext.GetLocation(Infrastructure.PageContext.DocumentLocation).PageEnd,
TotalPages = PageContext.DocumentLength,
AvailableSize = availableSize
};
......@@ -87,8 +84,7 @@ namespace QuestPDF.Elements
{
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; }
......@@ -105,7 +101,6 @@ namespace QuestPDF.Elements
var container = new DynamicElement();
content(container);
container.ApplyDocumentId(DocumentId);
container.ApplyInheritedAndGlobalTexStyle(TextStyle);
container.ApplyContentDirection(ContentDirection);
container.ApplyDefaultImageConfiguration(ImageTargetDpi, ImageCompressionQuality, UseOriginalImage);
......
......@@ -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; }
......@@ -15,21 +14,15 @@ namespace QuestPDF.Elements
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}";
}
}
}
\ No newline at end of file
......@@ -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)
......@@ -15,7 +14,7 @@ namespace QuestPDF.Elements
if (targetSize.Type == SpacePlanType.Wrap)
return;
var targetName = Section.GetTargetName(DocumentId, SectionName);
var targetName = PageContext.GetDocumentLocationName(SectionName);
Canvas.DrawSectionLink(targetName, targetSize);
base.Draw(availableSpace);
}
......
......@@ -163,7 +163,7 @@ namespace QuestPDF.Fluent
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.")]
......
......@@ -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; }
......@@ -12,8 +13,10 @@ namespace QuestPDF.Infrastructure
internal interface IPageContext
{
int DocumentLength { get; }
int CurrentPage { get; }
void SetSectionPage(string name);
DocumentLocation? GetLocation(string name);
string GetDocumentLocationName(string locationName);
}
}
\ No newline at end of file
......@@ -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;
......@@ -19,7 +25,7 @@ namespace QuestPDF.Infrastructure
internal void IncrementPageNumber()
{
CurrentPage++;
SetSectionPage(DocumentLocation);
DocumentLength = Math.Max(DocumentLength, CurrentPage);
}
public void SetSectionPage(string name)
......@@ -30,6 +36,7 @@ namespace QuestPDF.Infrastructure
{
location = new DocumentLocation
{
DocumentId = CurrentDocumentId,
Name = name,
PageStart = CurrentPage,
PageEnd = CurrentPage
......@@ -44,7 +51,12 @@ namespace QuestPDF.Infrastructure
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}";
}
}
}
\ No newline at end of file
......@@ -99,10 +99,15 @@ namespace QuestPDF.Previewer
{
if (version.Major == RequiredPreviewerVersionMajor && version.Minor == RequiredPreviewerVersionMinor)
return;
var newLine = Environment.NewLine;
var newParagraph = newLine + newLine;
throw new Exception($"Previewer version is not compatible. Possible solutions: " +
$"1) Update the QuestPDF library to newer version. " +
$"2) Update the QuestPDF previewer tool using the following command: 'dotnet tool update --global QuestPDF.Previewer --version {RequiredPreviewerVersionMajor}.{RequiredPreviewerVersionMinor}'");
throw new Exception($"The QuestPDF Previewer application is not compatible. Possible solutions: {newParagraph}" +
$"1) Change the QuestPDF library to the {version.Major}.{version.Minor}.X version to match the Previewer application version. {newParagraph}" +
$"2) Recommended: install the QuestPDF Previewer tool in a proper version using the following commands: {newParagraph}"+
$"dotnet tool uninstall --global QuestPDF.Previewer {newLine}"+
$"dotnet tool update --global QuestPDF.Previewer --version {RequiredPreviewerVersionMajor}.{RequiredPreviewerVersionMinor} {newParagraph}");
}
private async Task WaitForConnection()
......
......@@ -3,7 +3,7 @@
<Authors>MarcinZiabek</Authors>
<Company>CodeFlint</Company>
<PackageId>QuestPDF</PackageId>
<Version>2023.6.0</Version>
<Version>2023.6.1</Version>
<PackageDescription>QuestPDF is an open-source, modern and battle-tested library that can help you with generating PDF documents by offering friendly, discoverable and predictable C# fluent API. Easily generate PDF reports, invoices, exports, etc.</PackageDescription>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/Resources/ReleaseNotes.txt"))</PackageReleaseNotes>
<LangVersion>9</LangVersion>
......
......@@ -2,3 +2,8 @@ Version 2023.6.0
- Improvement: the library received a final version of the licensing model, which has been enhanced to be more accommodating to both the business and community.
- Feature: generating merged PDF documents.
- Improvement: image loading exception better describes the failure reason.
Version 2023.6.1
- Fix: incorrect layout exception when debugging is disabled
- Fix: the page number functionality for sections do not work (#609)
- Improvement: enhanced the message about the QuestPDF Previewer application version incompatibility