docs: def drawPara(self, debug=0):
          """Draws a paragraph according to the given style.
          Returns the final y position at the bottom. Not safe for
          paragraphs without spaces e.g. Japanese; wrapping
          algorithm will go infinite."""
  
          if self.debug:
              print (id(self), "drawPara", self.blPara.kind)
  
          #stash the key facts locally for speed
          canvas = self.canv
          style = self.style
          blPara = self.blPara
          lines = blPara.lines
          leading = style.leading
          autoLeading = getattr(self, 'autoLeading', getattr(style, 'autoLeading', ''))
  
          #work out the origin for line 1
          leftIndent = style.leftIndent
          cur_x = leftIndent
  
          if debug:
              bw = 0.5
              bc = Color(1, 1, 0)
              bg = Color(0.9, 0.9, 0.9)
          else:
              bw = getattr(style, 'borderWidth', None)
              bc = getattr(style, 'borderColor', None)
              bg = style.backColor
  
          #if has a background or border, draw it
          if bg or (bc and bw):
              canvas.saveState()
              op = canvas.rect
              kwds = dict(fill=0, stroke=0)
              if bc and bw:
                  canvas.setStrokeColor(bc)
                  canvas.setLineWidth(bw)
                  kwds['stroke'] = 1
                  br = getattr(style, 'borderRadius', 0)
                  if br and not debug:
                      op = canvas.roundRect
                      kwds['radius'] = br
              if bg:
                  canvas.setFillColor(bg)
                  kwds['fill'] = 1
              bp = getattr(style, 'borderPadding', 0)
              op(leftIndent - bp,
                 -bp,
                 self.width - (leftIndent + style.rightIndent) + 2 * bp,
                 self.height + 2 * bp,
                 **kwds)
              canvas.restoreState()
  
          nLines = len(lines)
          bulletText = self.bulletText
          if nLines > 0:
              _offsets = getattr(self, '_offsets', [0])
              _offsets += (nLines - len(_offsets)) * [_offsets[-1]]
              canvas.saveState()
              alignment = style.alignment
              offset = style.firstLineIndent + _offsets[0]
              lim = nLines - 1
              noJustifyLast = not (hasattr(self, '_JustifyLast') and self._JustifyLast)
  
              if blPara.kind == 0:
                  if alignment == TA_LEFT:
                      dpl = _leftDrawParaLine
                  elif alignment == TA_CENTER:
                      dpl = _centerDrawParaLine
                  elif self.style.alignment == TA_RIGHT:
                      dpl = _rightDrawParaLine
                  elif self.style.alignment == TA_JUSTIFY:
                      dpl = _justifyDrawParaLine
                  f = blPara
                  cur_y = self.height - getattr(f, 'ascent', f.fontSize)    # TODO fix XPreformatted to remove this hack
                  if bulletText:
                      offset = _drawBullet(canvas, offset, cur_y, bulletText, style)
  
                  #set up the font etc.
                  canvas.setFillColor(f.textColor)
  
                  tx = self.beginText(cur_x, cur_y)
                  if autoLeading == 'max':
                      leading = max(leading, LEADING_FACTOR * f.fontSize)
                  elif autoLeading == 'min':
                      leading = LEADING_FACTOR * f.fontSize
  
                  #now the font for the rest of the paragraph
                  tx.setFont(f.fontName, f.fontSize, leading)
                  ws = getattr(tx, '_wordSpace', 0)  
                  t_off = dpl(tx, offset, ws, lines[0][1], noJustifyLast and nLines == 1)
                  if f.underline or f.link or f.strike:
                      xs = tx.XtraState = ABag()
                      xs.cur_y = cur_y
                      xs.f = f
                      xs.style = style
                      xs.lines = lines
                      xs.underlines = []
                      xs.underlineColor = None
                      # XXX Modified for XHTML2PDF
                      xs.backgrounds = []
                      xs.backgroundColor = None
                      xs.backgroundFontSize = None
                      xs.strikes = []
                      xs.strikeColor = None
                      # XXX Modified for XHTML2PDF
                      xs.strikeFontSize = None
                      xs.links = []
                      xs.link = f.link
                      canvas.setStrokeColor(f.textColor)
                      dx = t_off + leftIndent
                      if dpl != _justifyDrawParaLine: ws = 0
                      # XXX Never underline!
                      underline = f.underline
                      strike = f.strike
                      link = f.link
                      if underline:
                          _do_under_line(0, dx, ws, tx)
                      if strike:
                          _do_under_line(0, dx, ws, tx, lm=0.125)
                      if link: _do_link_line(0, dx, ws, tx)
  
                      #now the middle of the paragraph, aligned with the left margin which is our origin.
                      for i in six.moves.range(1, nLines):
                          ws = lines[i][0]
                          t_off = dpl(tx, _offsets[i], ws, lines[i][1], noJustifyLast and i == lim)
                          if dpl != _justifyDrawParaLine: ws = 0
                          if underline: _do_under_line(i, t_off + leftIndent, ws, tx)
                          if strike: _do_under_line(i, t_off + leftIndent, ws, tx, lm=0.125)
                          if link: _do_link_line(i, t_off + leftIndent, ws, tx)
                  else:
                      for i in six.moves.range(1, nLines):
                          dpl(tx, _offsets[i], lines[i][0], lines[i][1], noJustifyLast and i == lim)
              else:
                  f = lines[0]
                  cur_y = self.height - getattr(f, 'ascent', f.fontSize)    # TODO fix XPreformatted to remove this hack
                  # default?
                  dpl = _leftDrawParaLineX
                  if bulletText:
                      offset = _drawBullet(canvas, offset, cur_y, bulletText, style)
                  if alignment == TA_LEFT:
                      dpl = _leftDrawParaLineX
                  elif alignment == TA_CENTER:
                      dpl = _centerDrawParaLineX
                  elif self.style.alignment == TA_RIGHT:
                      dpl = _rightDrawParaLineX
                  elif self.style.alignment == TA_JUSTIFY:
                      dpl = _justifyDrawParaLineX
                  else:
                      raise ValueError("bad align %s" % repr(alignment))
  
                  #set up the font etc.
                  tx = self.beginText(cur_x, cur_y)
                  xs = tx.XtraState = ABag()
                  xs.textColor = None
                  # XXX Modified for XHTML2PDF
                  xs.backColor = None
                  xs.rise = 0
                  xs.underline = 0
                  xs.underlines = []
                  xs.underlineColor = None
                  # XXX Modified for XHTML2PDF
                  xs.background = 0
                  xs.backgrounds = []
                  xs.backgroundColor = None
                  xs.backgroundFontSize = None
                  xs.strike = 0
                  xs.strikes = []
                  xs.strikeColor = None
                  # XXX Modified for XHTML2PDF
                  xs.strikeFontSize = None
                  xs.links = []
                  xs.link = None
                  xs.leading = style.leading
                  xs.leftIndent = leftIndent
                  tx._leading = None
                  tx._olb = None
                  xs.cur_y = cur_y
                  xs.f = f
                  xs.style = style
                  xs.autoLeading = autoLeading
  
                  tx._fontname, tx._fontsize = None, None
                  dpl(tx, offset, lines[0], noJustifyLast and nLines == 1)
                  _do_post_text(tx)
  
                  #now the middle of the paragraph, aligned with the left margin which is our origin.
                  for i in six.moves.range(1, nLines):
                      f = lines[i]
                      dpl(tx, _offsets[i], f, noJustifyLast and i == lim)
                      _do_post_text(tx)
  
              canvas.drawText(tx)
              canvas.restoreState()