[reportlab-users] Miscalculation when using keepWithNext

Robin Becker robin at reportlab.com
Tue Dec 14 05:17:00 EST 2021


Hi Pierre,

...........
> 
> I had a look at making a stable test case, and I disproved part of my initial analysis. There *is* a bug handling zero 
> width flowables. But there *is not* a bug handling spaceBefore.
> 
> The reason spaceBefore works is slight different from how the Frame does it though, which makes it non-obvious (but 
> correct):
> 
>   * The _ContainerSpace base class propagates requests for spaceBefore to the first element, which is the appropriate 
> thing to do
>   * The Frame looks at spaceBefore before calculating the available height it then gives to wrap() and split(), which is 
> also appropriate
>   * _listWrapOn() always ignores spaceBefore for the first element, since it is either irrelevant, or already included 
> in the available height calculated by the Frame
> 
> So it's just a bit non-obvious, but it seems correct. The problem is solely that zero width items are incorrectly 
> discarded, which in turn makes _listWrapOn() consider the next item to be at the top, which it is not.
> 
> The bug is fully present even without spacing though, so here is a test that exposes the issue as neatly as possible
> 
........

I will take a look at the 'bug' as exposed in your example.

I assume this is the line you want to change flowables.py:643

 > if w<=_FUZZ or h<=_FUZZ: continue

I believe this line has been there for a very long time since 1.21 at least (2008 vintage). It's supposed to ignore 
invisible items and is probably wrong for your purpose. It's too general. So far we never used the width for anything.

I modified some lines of your example

	zw = int(os.environ.get('ZW','0')) #here
	story = [
			XBox(4*inch, 50, 'top para'),
			KeepedXBox(zw, 20, 'spacer', keepWithNext=True), #here
			KeepedXBox(4*inch, 20, 'heading', keepWithNext=True),
			KeepedXBox(4*inch, 20, 'body para', keepWithNext=False),
			]

	doc = DocTemplate('test_pierre_ossman_%szerowidth.pdf' % ('non' if zw else '')) #here

to see what happens if the spacer is not invisible. Is there an issue that requires zero width for the spacer?

If the spacer is controlled by some other software then presumably a simple fix is just to change its class or to define 
an attribute which controls the w<=FUZZ issue.

I ran a render test (401 pdfs) with this line

if (w<=_FUZZ and False) or h<=_FUZZ: continue

and saw no changes. It does not mean that others will have the same result though.
-- 
Robin Becker


More information about the reportlab-users mailing list