Re: How are split, wrap, wrapOn supposed to work?
"Henning von Bargen" <[email protected]>
| Newsgroups | gmane.comp.python.reportlab.user |
|---|---|
| Message-ID | <[email protected]> |
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 > [email protected](*(-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