[reportlab-users] How are split, wrap, wrapOn supposed to work?
Henning von Bargen
H.vonBargen at t-p.com
Wed Nov 19 03:10:36 EST 2014
Robin,
thanks for your investigation.
Robin Becker wrote:
> ...
> Any how here are the calls that were made to the standard paragraph
Wrap
> function
> (twordaxe)
C:\code\hg-repos\reportlab\tmp\twordaxe>timageandflowables.py
> Paragraph at 0303fe48.wrap(*(-3.000000000000057,
268435455),**{})-->(7.9135, 5352)
> ...
> so it appears as though the base Paragraph tries to lay out something
based
> on the negative width and returns an area that cannot fit.
> .......
...
>
> I fixed up to use the latest code and also tried to get the test
working
> with wordaxe. My logging wrapper fails to produce any output
presumably because
> we pass a negative width into the wrap call and then the i_wrap
function fails
> fairly badly ie loops forever.
Correct. That's why I added additional debug code (not in the SVN repo):
---
C:/Users/hvb/AppData/Local/Temp/NewParagraph.py-revBASE.svn000.tmp.py
Di Okt 28 18:03:54 2014
+++ C:/wordaxe-svn/wordaxe/rl/NewParagraph.py Mi Okt 29 16:25:21 2014
@@ -522,7 +522,7 @@
"""
Return the actually used size.
"""
- #print id(self), "wrap", availW, availH
+ print id(self), "wrap", availW, availH
avail = self._cache.get('avail')
if (avail is True # paragraph has no frags, only lines
or avail == (availW, availH)): # already wrapped to
this size
@@ -544,7 +544,7 @@
attribute _cache['lines'] (to improve performance).
TODO: Should StyledSpaces be ignored before or after
StyledNewLines?
"""
- #print id(self), "i_wrap", availW, availH
+ print id(self), "i_wrap", availW, availH, max_widths
lines = [] # lines so far
sumHeight = 0 # sum of lines heights so far
lineHeight = 0 # height of current line
@@ -559,9 +559,12 @@
while True: yield w
width_iter = iter_widths()
max_width = width_iter.next()
+ if max_width < 0:
+ raise ValueError("Paragraph id %s: Max width is < 0: %s.
Text: %s" % (id(self), max_width, self.text[:200]))
frags_remaining = self.frags[:]
while frags_remaining:
+ #print "%d frags remaining" % len(frags_remaining)
if sumHeight > availH:
#print "sumHeight > availH, break, lineFrags=%s" %
lineFrags
break
@@ -599,7 +602,7 @@
actions = [("ADD",frag)]
else:
# Some Meta Fragment
- action = ("ADD",frag)
+ actions = [("ADD",frag)]
for (act,afrag) in actions:
#print act, width
if act == "LINEFEED":
@@ -636,6 +639,7 @@
else:
width += getattr(afrag, "width", 0)
elif act == "PUSH":
+ #print "PUSH %s" % afrag
frags_remaining.insert(0, afrag)
else:
raise AssertionError("Action:%r Frag:" %
(act,afrag))
@@ -1142,6 +1146,7 @@
return max(self.P.getSpaceAfter(),self.I.getSpaceAfter())
def wrap(self,availWidth,availHeight):
+ print id(self), "ParagraphAndImage.wrap", availWidth,
availHeight
wI, hI = self.I.wrap(availWidth,availHeight)
self.wI = wI
self.hI = hI
The main difference is the addition of an exception in i_wrap
if max_width is negative.
> I think the platypus Paragraph wrap succeeds because the standard
breaklines
> (which computes the line breaks) always adds at least one 'word'
before
> failing.
> That at least makes the layout proceed even if nonsensically. The
result is
> that effectively when negative availWidth is passed to the wrap method
we
> split the line into individual words and ignore the width constraint.
> The returned width is then the maximum word width and the height is
> leading*len(words).
>
> I looked at your code, but was not able to figure out why the
assertion error
> doesn't get raised at line 594.
>
>> --
>> Robin Becker
Ok, I think I understand.
So I could just as well return a width of e.g. 4*emspace - a smaller
width
doesn't make sense anyway, and I don't want the text to be written
across
the margin/border.
However, I'll have to assure that this doesn't collide with the use case
of
a (New)Paragraph used inside a platypus.Table cell with a small column
width.
Henning
More information about the reportlab-users
mailing list