ph-pdf-layout icon indicating copy to clipboard operation
ph-pdf-layout copied to clipboard

No splitting performed when nesting non-splittable within splittable PLVBox

Open hwanders opened this issue 2 years ago • 3 comments

Info: I'm using ph-pdf-layout 7.0.0.

When creating a splittable PLVBox and adding some large non-splittable PLVBoxes as rows, the calculations for vertical splitting seems to go wrong (or at least behaves in a way which I did not expect). This culminates in a debug message Cannot split because no vertical splittable elements are contained and an error of the form The value of 'StartTop' must be >= 0! The current value is: <negative number>.

By debugging I can see that the PLVBox elements do have too many rows (in m_aRows) which do not fit on the page such that fCurY becomes negative.

I guess, the problem lies in AbstractPLVBox.splitElementVert(...) which uses containsAnyVertSplittableElement() to determine whether splitting can be performed. My expectation is that splitting should be done if each contained row fits in the available height, even if those rows' contents are not splittable.

I have found that there is also a simple workaround for this: just wrap the inner (non-splittable) PLVBox with another splittable one which only contains that inner box.

This is a simple reproduction of the error, the workaround is added as comment in the loop:

public static void main(String[] args) throws Exception {
  var font = new FontSpec(PreloadFont.REGULAR, 10);
  var pageSet = new PLPageSet(new SizeSpec(100, 700));

  var list = new PLVBox(); // splittable
  pageSet.addElement(list);

  for (var i = 0; i < 3; i++) {
    var subList = new PLVBox().setVertSplittable(false); // non-splittable
    subList.addRow(new PLText("test", font).setExactHeight(700));
    list.addRow(subList); // workaround: list.addRow(new PLVBox(subList));
  }

  var pdf = new PageLayoutPDF().addPageSet(pageSet);
  // The following throws an "Internal error" with reason
  // "The value of 'StartTop' must be >= 0! The current value is: -700.0"
  pdf.renderTo(new ByteArrayOutputStream());
}

hwanders avatar Apr 29 '23 20:04 hwanders

To reformulate my expectation: I think if the PLVBox's rows are not vert-splittable themselves, it should consider the rows as whole elements and try to split those.

hwanders avatar Apr 29 '23 23:04 hwanders

I just played around a bit with the source code and just removing the block checking for vert-splittable elements did work in my case.

Probably the code is there for some reason, but after removing the code (and making the tests deterministic by using fixed date/time values and seeds for Random), all generated PDFs files remain exactly the same, so at least no existing tests are breaking. On the other hand, the block is never entered in any of the tests.

hwanders avatar Apr 30 '23 00:04 hwanders

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 07 '24 12:01 stale[bot]