text: ##############################################################################
  #
  # Copyright (c) 2012 Zope Foundation and Contributors.
  # All Rights Reserved.
  #
  # This software is subject to the provisions of the Zope Public License,
  # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
  # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  # FOR A PARTICULAR PURPOSE.
  #
  ##############################################################################
  """ReportLab fixups.
  """
  __docformat__ = "reStructuredText"
  import copy
  from reportlab.pdfbase import pdfform, pdfmetrics, ttfonts
  from reportlab.pdfbase.pdfpattern import PDFPattern
  from reportlab.graphics import testshapes
  from reportlab.lib import fonts
  
  _ps2tt_map_original = copy.deepcopy(fonts._ps2tt_map)
  _tt2ps_map_original = copy.deepcopy(fonts._tt2ps_map)
  
  def resetPdfForm():
      pdfform.PDFDOCENC = PDFPattern(pdfform.PDFDocEncodingPattern)
      pdfform.ENCODING = PDFPattern(
          pdfform.EncodingPattern, PDFDocEncoding=pdfform.PDFDOCENC)
      pdfform.GLOBALFONTSDICTIONARY = pdfform.FormFontsDictionary()
      pdfform.GLOBALRESOURCES = pdfform.FormResources()
      pdfform.ZADB = PDFPattern(pdfform.ZaDbPattern)
  
  def resetFonts():
      # testshapes._setup registers the Vera fonts every time which is a little
      # slow on all platforms. On Windows it lists the entire system font
      # directory and registers them all which is very slow.
      pdfmetrics.registerFont(ttfonts.TTFont("Vera", "Vera.ttf"))
      pdfmetrics.registerFont(ttfonts.TTFont("VeraBd", "VeraBd.ttf"))
      pdfmetrics.registerFont(ttfonts.TTFont("VeraIt", "VeraIt.ttf"))
      pdfmetrics.registerFont(ttfonts.TTFont("VeraBI", "VeraBI.ttf"))
      for f in ('Times-Roman','Courier','Helvetica','Vera', 'VeraBd', 'VeraIt',
                'VeraBI'):
          if f not in testshapes._FONTS:
              testshapes._FONTS.append(f)
      fonts._ps2tt_map = copy.deepcopy(_ps2tt_map_original)
      fonts._tt2ps_map = copy.deepcopy(_tt2ps_map_original)
  
  def setSideLabels():
      from reportlab.graphics.charts import piecharts
      piecharts.Pie3d.sideLabels = 0
  setSideLabels()
  
  from reportlab.rl_config import register_reset
  register_reset(resetPdfForm)
  register_reset(resetFonts)
  del register_reset
  
  # Support more enumeration formats.
  
  from z3c.rml import num2words
  from reportlab.lib.sequencer import _type2formatter
  
  _type2formatter.update({
      'l': lambda v: num2words.num2words(v),
      'L': lambda v: num2words.num2words(v).upper(),
      'o': lambda v: num2words.num2words(v, ordinal=True),
      'O': lambda v: num2words.num2words(v, ordinal=True).upper(),
      'r': lambda v: num2words.toOrdinal(v),
      'R': lambda v: num2words.toOrdinal(v).upper(),
  })
  
  
  # Make sure that the counter gets increased for our new formatters as well.
  
  from reportlab.platypus.flowables import ListFlowable, LIIndenter, _LIParams, \
      _computeBulletWidth
  
  def ListFlowable_getContent(self):
      bt = self._bulletType
      value = self._start
      if isinstance(value,(list,tuple)):
          values = value
          value = values[0]
      else:
          values = [value]
      autov = values[0]
      # FIX TO ALLOW ALL FORMATTERS!!!
      inc = int(bt in self._numberStyles)
      if inc:
          try:
              value = int(value)
          except:
              value = 1
  
      bd = self._bulletDedent
      if bd=='auto':
          align = self._bulletAlign
          dir = self._bulletDir
          if dir=='ltr' and align=='left':
              bd = self._leftIndent
          elif align=='right':
              bd = self._rightIndent
          else:
              #we need to work out the maximum width of any of the labels
              tvalue = value
              maxW = 0
              for d,f in self._flowablesIter():
                  if d:
                      maxW = max(maxW,_computeBulletWidth(self,tvalue))
                      if inc: tvalue += inc
                  elif isinstance(f,LIIndenter):
                      b = f._bullet
                      if b:
                          if b.bulletType==bt:
                              maxW = max(maxW,_computeBulletWidth(b,b.value))
                              tvalue = int(b.value)
                      else:
                          maxW = max(maxW,_computeBulletWidth(self,tvalue))
                      if inc: tvalue += inc
              if dir=='ltr':
                  if align=='right':
                      bd = self._leftIndent - maxW
                  else:
                      bd = self._leftIndent - maxW*0.5
              elif align=='left':
                  bd = self._rightIndent - maxW
              else:
                  bd = self._rightIndent - maxW*0.5
  
      self._calcBulletDedent = bd
  
      S = []
      aS = S.append
      i=0
      for d,f in self._flowablesIter():
          if isinstance(f,ListFlowable):
              fstart = f._start
              if isinstance(fstart,(list,tuple)):
                  fstart = fstart[0]
              if fstart in values:
                  #my kind of ListFlowable
                  if f._auto:
                      autov = values.index(autov)+1
                      f._start = values[autov:]+values[:autov]
                      autov = f._start[0]
                      if inc: f._bulletType = autov
                  else:
                      autov = fstart
          fparams = {}
          if not i:
              i += 1
              spaceBefore = getattr(self,'spaceBefore',None)
              if spaceBefore is not None:
                  fparams['spaceBefore'] = spaceBefore
          if d:
              aS(self._makeLIIndenter(f,bullet=self._makeBullet(value),params=fparams))
              if inc: value += inc
          elif isinstance(f,LIIndenter):
              b = f._bullet
              if b:
                  if b.bulletType!=bt:
                      raise ValueError('Included LIIndenter bulletType=%s != OrderedList bulletType=%s' % (b.bulletType,bt))
                  value = int(b.value)
              else:
                  f._bullet = self._makeBullet(value,params=getattr(f,'params',None))
              if fparams:
                  f.__dict__['spaceBefore'] = max(f.__dict__.get('spaceBefore',0),spaceBefore)
              aS(f)
              if inc: value += inc
          elif isinstance(f,_LIParams):
              fparams.update(f.params)
              z = self._makeLIIndenter(f.flowable,bullet=None,params=fparams)
              if f.first:
                  if f.value is not None:
                      value = f.value
                      if inc: value = int(value)
                  z._bullet = self._makeBullet(value,f.params)
                  if inc: value += inc
              aS(z)
          else:
              aS(self._makeLIIndenter(f,bullet=None,params=fparams))
  
      spaceAfter = getattr(self,'spaceAfter',None)
      if spaceAfter is not None:
          f=S[-1]
          f.__dict__['spaceAfter'] = max(f.__dict__.get('spaceAfter',0),spaceAfter)
      return S
  
  ListFlowable._getContent = ListFlowable_getContent
  ListFlowable._numberStyles = _type2formatter.keys()
  