title: Resize reportlab.platypus.Paragraph flowable?
body: <p>I've got the following code that attempts to resize the font size of a reportlab Platypus flowable's text until it fits into the available height I have given it. But I'm finding that the Paragraph flowable is not saving its style.fontSize attribute in each loop of the recursion, and python baulks with an infinite recursion.</p>
  
  <pre><code>def fits_space(w,h,aW,aH,p):
      """
      Determines if inputted text fits in the space given for a paragraph
      and if it doesn't, reduces the font-size until it does.
  
      """
      if w&lt;=aW and h&lt;=aH:
          # return font size to apply it to the para again
          print "final font_size: %d" % p.style.fontSize
          return p # now render the paragraph in the doctemplate
      else: 
          p.style.fontSize -= 1
          w,h = p.wrap(aW, aH)
          fits_space(w,h,aW,aH,p)
  
  def renderPage(name, text):
      doc = SimpleDocTemplate("%s.pdf" % name)
      parts = []
      style = ParagraphStyle(name='fancy')
      style.fontSize = 150
      p = Paragraph(text, style)
      aW = PAGE_WIDTH-4*inch  # available width and height 
      aH = PAGE_HEIGHT-4*inch 
      w,h = p.wrap(aW, aH) # find required space
      p = fits_space(w,h,aW,aH,p) # recursively fit the font size to the text
      parts.append(p)
      doc.build(parts)
  </code></pre>
  
  <p>Can anyone let me know why - in the fits_space() function, in the else clause, when I call p.wrap(aW, aH), the outputted value is the same as before I decremented the paragraph's fontSize by 1? Surely the wrapped height should be less if I reduce the font size? </p>
  
  <p>Any ideas where I'm going wrong?</p>
  
  <p><strong>UPDATE</strong>
  Nitzie's code below <em>almost worked</em> just needed to add a resizer to the style.leading too in my case:</p>
  
  <pre><code>def shrink_font_size(aW, aH, text, style):
      """Shrinks font size by using pdfmetrics to calculate the height
      of a paragraph, given the font name, size, and available width."""
      def break_lines(text, aW):
          # simpleSplit calculates how reportlab will break up the lines for
          # display in a paragraph, by using width/fontsize.
          return simpleSplit(text, style.fontName, style.fontSize, aW)
  
      def line_wrap(lines, style):
          # Get overall width of text by getting stringWidth of longest line
          width = stringWidth(max(lines), style.fontName, style.fontSize)
          # Paragraph height can be calculated via line spacing and number of lines.
          height = style.leading * len(lines)
          return width, height
  
      lines = break_lines(text, aW)
      width, height = line_wrap(lines, style)
  
      while height &gt; aH or width &gt; aW:
          style.fontSize -= 1
          style.leading -= 1 # do this if you're leading is based on the fontSize
          lines = break_lines(text, aW)
          width, height = line_wrap(lines, style)
  </code></pre>
  
  <p>TIA</p>