phax / ph-pdf-layout

Java library for creating fluid page layouts with Apache PDFBox. Supporting multi-page tables, different page layouts etc.
Apache License 2.0
64 stars 11 forks source link

Need to determine how many table rows can fit on the current page #33

Closed NeilAgg2001 closed 1 year ago

NeilAgg2001 commented 1 year ago

I am trying to create the content for a book of puzzles which are like crosswords but are numeric and based on a hexagonal grid.

Each page will have:

  1. An image of the puzzle grid.
  2. A list of clues grouped by direction (In my case, the clues will have Across, Up, and Down groupings).

The layout of the clues depends on what I can fit on a single page. The pages are 6" by 9" so they are pretty tight.

Here is what I am thinking so far:

  1. Have all the clues listed in columns if they will all fit on the same page as the puzzle image.
  2. Have the clues "flow" from the first column, into the second, and then the third if they will fit on the page that way.
  3. Put all the clues on the opposite (facing) page if they don't fit on the page with the puzzle image and will fit on one page.
  4. If nothing else works, put as many clues as I can per page in three columns. Then, on subsequent pages, put whatever remaining clues I need to, but change the heading of the column to indicate it is a continuation like "Across (continued)".

The first step to coding this is to figure out the size of the table containing clues.

I created some test code which creates a table with one cell and then calls table.getPreparedHeight(). But, I get an error: Cannot invoke "com.helger.pdflayout.spec.SizeSpec.getHeight()" because the return value of "com.helger.pdflayout.base.IPLRenderableObject.getPreparedSize()" is null

I get a similar error if I try to use table.getRenderedHeight().

I guess I need to call something to prepare the table. I see table.prepare(), but that requires a context and I don't see how to get that. I tried looking through the examples but I don't see anywhere which uses it.

It seems this should be simple, but I need someone to point me in the right direction.

Thanks in advance!

NeilAgg2001 commented 1 year ago

Here is my sample code: TableHeightTest.txt

phax commented 1 year ago

The basic idea of the library is a 3-step rendering process.

Therefore the "prepared size" is only available after rendering. I created some new API that allows you to previously "prepare" all existing page sets, but that means, that the page set cannot be modified afterwards. Does that make sense to you?

NeilAgg2001 commented 1 year ago

It seems like I can't know how things are going to lay out until they are rendered and then I can't modify things if the rendering gives an undesirable result. Is that what you are saying?

phax commented 1 year ago

Yes, that is what I am trying to say :) Except if you add some additional logic and create new PageSets until you are satisfied with the layout. Via addPageSet and removePageSet you are quite flexibel in that regard. But of course, the programming effort may be relatively high...

NeilAgg2001 commented 1 year ago

I could try that, but I think it might be a lot more effort than creating my own code using PDFBox directly. I think I will try that first. Thank you for the follow-up!

phax commented 1 year ago

Okay, good luck - I totally understand your point :) Closing this issue then

NeilAgg2001 commented 1 year ago

I just thought of something - if I can get the size of the table after step 2, I might be able to modify the table and repeat. Is that possible?

phax commented 1 year ago

Unfortunately not, as the object tree is nested, each object gets manually prepared and then this state is persisted. An "undo" is theoretically possible but the effort would be too high for just your use case. Maybe you can make the computations aforehand and then just build the PDF when you know it works?

NeilAgg2001 commented 1 year ago

Any suggestions on how to make the computations before?

phax commented 1 year ago

That heavily depends on your needs :) You need to figure that out by yourself