[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