Open MichelMichels opened 1 year ago
Hi 😁
I am afraid that QuestPDF does not offer out-of-the-box support for this type of layout. I am planning to introduce it but it may require some serious architectural changes.
As an alternative, you can try to utilise the DynamicComponent
approach but this may be slightly more difficult.
No problem. I'll look into DynamicComponent.
Any idea how this could be implemented natively in QuestPDF? Some kind of flow layout? If you need help, I can offer some of my time.
Yes, I am thinking about this topic for a couple of month already 😁
Right now, QuestPDF uses the measure-draw approach. That means, the parent can measure
its children many times, with varying available space provided. And then, once everything is set, the parent can perform the draw
operation. It draws the child to the canvas and also updates its state (e.g. for the column element, it updates information which items were drawn).
What is important, the draw
operation can be (usually) performed only once per page. We need to be able to measure elements with various states. So, in your example, we need to perform the measure-draw operation twice, for the left and right sides of the document.
If I need to name the process, the current architecture uses 1-step probing, while we need to have many-step probing.
One of ideas that I have, is to expose elements state. So the parent can save current state of its children, then perform measurement operations, maybe change the state somehow, measure again, etc. This way, we can perform more advanced measurement operations, without actually drawing anything on the canvas. Please notice, that state consists of not only direct children but all descendants. And not all elements have state. This suddenly involves tree traversal, apaplying IDs to elements, using dictionaries to store state, etc. Quite complex stuff.
I am not sure if anything above makes sense 😅 This is a pretty rough idea, and quite difficult to describe. I have done this type of state exposing in the DynamicComponent approach, where the library saves / changes / restores state of the component many times per page drawing step, in order to best predict its size and position.
I'm trying to understand but I think it's hard because I'm not familiar with the internal codebase of QuestPDF 😄. I'll look into the DynamicComponent approach and maybe that will help me understand.
@MichelMichels have you tried the DynamicComponent
approach yet? I have tried the approach of measuring the text and reducing the length till it fits in the container by using the DyamicContext
.CreateElement
method but, it's gotten nowhere because I have other requirements that cannot be met using this approach. Maybe you've had better luck with this?
Hey @Azuf , I followed another path. I calculated the character count and made 3 columns where I put text in, but there's no automatic wrapping. It adds pages when overflowing the columns. But in my use case, this was not a problem as the content where a lot of paragraphs with titles which didn't need an order to be printed.
So I'm afraid this doesn't help you very much... Anyway, here's the code I used:
container
.Column(column =>
{
column.Item().Row(row =>
{
row.RelativeItem()
.ShowOnce()
.Text(text =>
{
AddTitledParagraph(text, "title", content);
// Statically repeated code above
});
row
.AutoItem()
.PaddingHorizontal(5f, Unit.Millimetre)
.LineVertical(0.1f)
.LineColor(Colors.Grey.Lighten1);
row.RelativeItem()
.ShowOnce()
.Text(text =>
{
AddTitledParagraph(text, "title", content);
// Statically repeated code above
});
row
.AutoItem()
.PaddingHorizontal(5f, Unit.Millimetre)
.LineVertical(0.1f)
.LineColor(Colors.Grey.Lighten1);
row.RelativeItem()
.ShowOnce()
.Text(text =>
{
AddTitledParagraph(text, "title", content);
// Statically repeated code above
});
});
});
Is your feature request related to a problem? Please describe. Is it at the moment possible to have multiple text columns with wrapped text? See screenshot in additional context.
Describe alternatives you've considered I could measure the length of the text, but this feels janky.
Additional context