Hello community,

here is the log from the commit of package python-reportlab for 
openSUSE:Factory checked in at 2019-07-28 10:19:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-reportlab (Old)
 and      /work/SRC/openSUSE:Factory/.python-reportlab.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-reportlab"

Sun Jul 28 10:19:08 2019 rev:21 rq:717981 version:3.5.23

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-reportlab/python-reportlab.changes        
2019-05-22 10:52:26.563285430 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-reportlab.new.4126/python-reportlab.changes  
    2019-07-28 10:19:10.088601549 +0200
@@ -1,0 +2,15 @@
+Tue Jul 23 18:12:53 UTC 2019 - Todd R <toddrme2...@gmail.com>
+
+- version update to 3.5.23
+  * fix rendering to stdout doesn't work in python3
+  * fix relative links within pdf broken 
+  * fix paragraph justification broken in the presence of no-break spaces
+  * add wordSpace keyword to Canvas draw methods
+  * fix an extra blank page shows up between two KeepTogether() groups
+- version update to 3.5.22
+  * Allow kewords in PDFResourceDictionary
+  * fix DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats
+  * Allow AcroForm to have SigFlags
+  * Bug Fixes and tests
+
+-------------------------------------------------------------------

Old:
----
  reportlab-3.5.21.tar.gz

New:
----
  reportlab-3.5.23.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-reportlab.spec ++++++
--- /var/tmp/diff_new_pack.NlBw5g/_old  2019-07-28 10:19:11.524601550 +0200
+++ /var/tmp/diff_new_pack.NlBw5g/_new  2019-07-28 10:19:11.532601550 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define oldpython python
 Name:           python-reportlab
-Version:        3.5.21
+Version:        3.5.23
 Release:        0
 Url:            http://www.reportlab.com/
 Summary:        The Reportlab Toolkit


++++++ reportlab-3.5.21.tar.gz -> reportlab-3.5.23.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/CHANGES.md 
new/reportlab-3.5.23/CHANGES.md
--- old/reportlab-3.5.21/CHANGES.md     2019-05-03 13:59:36.000000000 +0200
+++ new/reportlab-3.5.23/CHANGES.md     2019-05-31 15:00:30.000000000 +0200
@@ -11,6 +11,21 @@
 The contributors lists are in no order and apologies to those accidentally not
 mentioned. If we missed you, please let us know!
 
+RELEASE 3.5.23 31/05/2019
+--------------------------
+       * fix issue #180 raised by Christoph Berg
+       * fix issue #181 raised by Daniel Terecuk
+       * brutalist fix for Marius Gedminas' issue #183
+       * add wordSpace keyword to Canvas draw methods
+       * fix for Marius Gedminas' issue #184
+
+RELEASE 3.5.22 23/05/2019
+--------------------------
+       * Allow kewords in PDFResourceDictionary
+       * pr #58 issue #174 contribution by Marius Gedminas
+       * Allow AcroForm to have SigFlags
+       * Bug Fixes and tests
+
 RELEASE 3.5.21  3/05/2019
 --------------------------
        * fix bug in legends
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/PKG-INFO 
new/reportlab-3.5.23/PKG-INFO
--- old/reportlab-3.5.21/PKG-INFO       2019-05-03 14:00:14.000000000 +0200
+++ new/reportlab-3.5.23/PKG-INFO       2019-05-31 15:01:08.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: reportlab
-Version: 3.5.21
+Version: 3.5.23
 Summary: The Reportlab Toolkit
 Home-page: http://www.reportlab.com/
 Author: Andy Robinson, Robin Becker, the ReportLab team and the community
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/docs/userguide/ch2_graphics.py 
new/reportlab-3.5.23/docs/userguide/ch2_graphics.py
--- old/reportlab-3.5.21/docs/userguide/ch2_graphics.py 2017-11-06 
10:30:20.000000000 +0100
+++ new/reportlab-3.5.23/docs/userguide/ch2_graphics.py 2019-05-31 
15:00:30.000000000 +0200
@@ -76,7 +76,7 @@
 
 disc("""The $filename$ argument controls the
 name of the final PDF file.  You
-may also pass in any open file object (such as $sys.stdout$, the python 
process standard output)
+may also pass in any open binary stream (such as $sys.stdout$, the python 
process standard output with a binary encoding)
 and the PDF document will be written to that.  Since PDF
 is a binary format, you should take care when writing other
 stuff before or after it; you can't deliver PDF documents
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/__init__.py 
new/reportlab-3.5.23/src/reportlab/__init__.py
--- old/reportlab-3.5.21/src/reportlab/__init__.py      2019-05-03 
13:59:36.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/__init__.py      2019-05-31 
15:00:30.000000000 +0200
@@ -1,9 +1,9 @@
 #Copyright ReportLab Europe Ltd. 2000-2018
 #see license.txt for license details
 __doc__="""The Reportlab PDF generation library."""
-Version = "3.5.21"
+Version = "3.5.23"
 __version__=Version
-__date__='20190503'
+__date__='20190531'
 
 import sys, os
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reportlab-3.5.21/src/reportlab/graphics/charts/barcharts.py 
new/reportlab-3.5.23/src/reportlab/graphics/charts/barcharts.py
--- old/reportlab-3.5.21/src/reportlab/graphics/charts/barcharts.py     
2018-09-21 16:57:24.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/graphics/charts/barcharts.py     
2019-05-31 15:00:30.000000000 +0200
@@ -15,7 +15,7 @@
 from reportlab.lib.validators import isNumber, isNumberOrNone, isColor, 
isColorOrNone, isString,\
             isListOfStrings, SequenceOf, isBoolean, isNoneOrShape, 
isStringOrNone,\
             NoneOr, isListOfNumbersOrNone, EitherOr, OneOf, isInt
-from reportlab.lib.utils import flatten
+from reportlab.lib.utils import flatten, isStr
 from reportlab.graphics.widgets.markers import uSymbol2Symbol, isSymbol
 from reportlab.lib.formatters import Formatter
 from reportlab.lib.attrmap import AttrMap, AttrMapValue
@@ -492,7 +492,7 @@
             labelText = None
         elif labelFmt == 'values':
             labelText = self.barLabelArray[rowNo][colNo]
-        elif type(labelFmt) is str:
+        elif isStr(labelFmt):
             labelText = labelFmt % self.data[rowNo][colNo]
         elif hasattr(labelFmt,'__call__'):
             labelText = labelFmt(self.data[rowNo][colNo])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/pdfbase/acroform.py 
new/reportlab-3.5.23/src/reportlab/pdfbase/acroform.py
--- old/reportlab-3.5.21/src/reportlab/pdfbase/acroform.py      2018-04-16 
16:03:40.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/pdfbase/acroform.py      2019-05-31 
15:00:30.000000000 +0200
@@ -157,6 +157,7 @@
         self._radios = {}
         self._refMap = {}
         self._pdfdocenc = {}
+        self.sigFlags = None
 
     @property
     def canv(self):
@@ -172,6 +173,7 @@
         d = dict(
                 Fields = PDFArray([self.getRef(f) for f in self.fields]),
                 )
+        if self.sigFlags: d['SigFlags'] = self.sigFlags
         if self.fonts:
             FK = list(sorted(self.fonts.keys()))
             F = [self.fontRef(f) for f in FK]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/pdfbase/pdfdoc.py 
new/reportlab-3.5.23/src/reportlab/pdfbase/pdfdoc.py
--- old/reportlab-3.5.21/src/reportlab/pdfbase/pdfdoc.py        2019-04-15 
13:09:36.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/pdfbase/pdfdoc.py        2019-05-31 
15:00:30.000000000 +0200
@@ -593,7 +593,7 @@
         s = self.s
         enc = getattr(self,'enc','auto')
         if isBytes(s):
-            if enc is 'auto':
+            if enc == 'auto':
                 try:
                     if s.startswith(codecs.BOM_UTF16_BE):
                         u = s.decode('utf_16_be')
@@ -612,7 +612,7 @@
                         stderr.write('Error in %s' % (repr(s),))
                         raise
         elif isUnicode(s):
-            if enc is 'auto':
+            if enc == 'auto':
                 if _checkPdfdoc(s):
                     s = s.encode('pdfdoc')
                 else:
@@ -1858,17 +1858,13 @@
 
 class PDFResourceDictionary(PDFObject):
     """each element *could* be reset to a reference if desired"""
-    def __init__(self):
-        self.ColorSpace = {}
-        self.XObject = {}
-        self.ExtGState = {}
-        self.Font = {}
-        self.Pattern = {}
-        self.ProcSet = []
-        self.Properties = {}
-        self.Shading = {}
-        # ?by default define the basicprocs
+    def __init__(self,**kwds):
+        for _ in self.dict_attributes:
+            setattr(self,_,kwds.pop(_,{}))
+        # define the basicprocs
         self.basicProcs()
+        if 'ProcSet' in kwds:
+            self.ProcSet= kwds.pop('ProcSet')
     stdprocs = [PDFName(s) for s in "PDF Text ImageB ImageC ImageI".split()]
     dict_attributes = ("ColorSpace", "XObject", "ExtGState", "Font", 
"Pattern", "Properties", "Shading")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/pdfbase/ttfonts.py 
new/reportlab-3.5.23/src/reportlab/pdfbase/ttfonts.py
--- old/reportlab-3.5.21/src/reportlab/pdfbase/ttfonts.py       2019-01-15 
17:23:27.000000000 +0100
+++ new/reportlab-3.5.23/src/reportlab/pdfbase/ttfonts.py       2019-05-31 
15:00:30.000000000 +0200
@@ -808,7 +808,7 @@
         # (needs data from hhea, maxp, and cmap tables)
         self.seek_table("hmtx")
         aw = None
-        self.charWidths = {}
+        self.charWidths = charWidths = {}
         self.hmetrics = []
         for glyph in xrange(numberOfHMetrics):
             # advance width and left side bearing.  lsb is actually signed
@@ -820,7 +820,7 @@
                 self.defaultWidth = aw
             if glyph in glyphToChar:
                 for char in glyphToChar[glyph]:
-                    self.charWidths[char] = aw
+                    charWidths[char] = aw
         for glyph in xrange(numberOfHMetrics, numGlyphs):
             # the rest of the table only lists advance left side bearings.
             # so we reuse aw set by the last iteration of the previous loop
@@ -828,7 +828,7 @@
             self.hmetrics.append((aw, lsb))
             if glyph in glyphToChar:
                 for char in glyphToChar[glyph]:
-                    self.charWidths[char] = aw
+                    charWidths[char] = aw
 
         # loca - Index to location
         self.seek_table('loca')
@@ -841,6 +841,12 @@
                 self.glyphPos.append(self.read_ulong())
         else:
             raise TTFError('Unknown location table format (%d)' % 
indexToLocFormat)
+        if 0x20 in charToGlyph:
+            charToGlyph[0xa0] = charToGlyph[0x20]
+            charWidths[0xa0] = charWidths[0x20]
+        elif 0xa0 in charToGlyph:
+            charToGlyph[0x20] = charToGlyph[0xa0]
+            charWidths[0x20] = charWidths[0xa0]
 
     # Subsetting
 
@@ -1111,6 +1117,7 @@
             self.frozen = 0
             if getattr(getattr(ttf,'face',None),'_full_font',None):
                 C = set(self.charToGlyph.keys())
+                if 0xa0 in C: C.remove(0xa0)
                 for n in xrange(256):
                     if n in C:
                         A[n] = n
@@ -1187,6 +1194,7 @@
         subsets = state.subsets
         reserveTTFNotdef = rl_config.reserveTTFNotdef
         for code in map(ord,text):
+            if code==0xa0: code = 32    #map nbsp into space
             if code in assignments:
                 n = assignments[code]
             else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/pdfgen/canvas.py 
new/reportlab-3.5.23/src/reportlab/pdfgen/canvas.py
--- old/reportlab-3.5.21/src/reportlab/pdfgen/canvas.py 2019-04-15 
13:09:36.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/pdfgen/canvas.py 2019-05-31 
15:00:30.000000000 +0200
@@ -1558,7 +1558,7 @@
         # use PDFTextObject for multi-line text.
         ##################################################
 
-    def drawString(self, x, y, text, mode=None, charSpace=0, direction=None):
+    def drawString(self, x, y, text, mode=None, charSpace=0, direction=None, 
wordSpace=None):
         """Draws a string in the current text styles."""
         if sys.version_info[0] == 3 and not isinstance(text, str):
             text = text.decode('utf-8')
@@ -1566,26 +1566,31 @@
         t = self.beginText(x, y, direction=direction)
         if mode is not None: t.setTextRenderMode(mode)
         if charSpace: t.setCharSpace(charSpace)
+        if wordSpace: t.setWordSpace(wordSpace)
         t.textLine(text)
         if charSpace: t.setCharSpace(0)
+        if wordSpace: t.setWordSpace(0)
         if mode is not None: t.setTextRenderMode(0)
         self.drawText(t)
 
-    def drawRightString(self, x, y, text, mode=None, charSpace=0, 
direction=None):
+    def drawRightString(self, x, y, text, mode=None, charSpace=0, 
direction=None, wordSpace=None):
         """Draws a string right-aligned with the x coordinate"""
         if sys.version_info[0] == 3 and not isinstance(text, str):
             text = text.decode('utf-8')
         width = self.stringWidth(text, self._fontname, self._fontsize)
         if charSpace: width += (len(text)-1)*charSpace
+        if wordSpace: width += (text.count(u' 
')+text.count(u'\xa0')-1)*wordSpace
         t = self.beginText(x - width, y, direction=direction)
         if mode is not None: t.setTextRenderMode(mode)
         if charSpace: t.setCharSpace(charSpace)
+        if wordSpace: t.setWordSpace(wordSpace)
         t.textLine(text)
         if charSpace: t.setCharSpace(0)
+        if wordSpace: t.setWordSpace(0)
         if mode is not None: t.setTextRenderMode(0)
         self.drawText(t)
 
-    def drawCentredString(self, x, y, text, mode=None, charSpace=0, 
direction=None):
+    def drawCentredString(self, x, y, text, mode=None, charSpace=0, 
direction=None, wordSpace=None):
         """Draws a string centred on the x coordinate. 
         
         We're British, dammit, and proud of our spelling!"""
@@ -1593,15 +1598,18 @@
             text = text.decode('utf-8')
         width = self.stringWidth(text, self._fontname, self._fontsize)
         if charSpace: width += (len(text)-1)*charSpace
+        if wordSpace: width += (text.count(u' 
')+text.count(u'\xa0')-1)*wordSpace
         t = self.beginText(x - 0.5*width, y, direction=direction)
         if mode is not None: t.setTextRenderMode(mode)
         if charSpace: t.setCharSpace(charSpace)
+        if wordSpace: t.setWordSpace(wordSpace)
         t.textLine(text)
         if charSpace: t.setCharSpace(0)
+        if wordSpace: t.setWordSpace(0)
         if mode is not None: t.setTextRenderMode(0)
         self.drawText(t)
 
-    def drawAlignedString(self, x, y, text, pivotChar=rl_config.decimalSymbol, 
mode=None, charSpace=0, direction=None):
+    def drawAlignedString(self, x, y, text, pivotChar=rl_config.decimalSymbol, 
mode=None, charSpace=0, direction=None, wordSpace=None):
         """Draws a string aligned on the first '.' (or other pivot character).
 
         The centre position of the pivot character will be used as x.
@@ -1642,16 +1650,20 @@
                 rightText = leftText[-1] + rightText
                 leftText = leftText[0:-1]
 
-            self.drawRightString(x-0.5*pivW, y, leftText, mode=mode, 
charSpace=charSpace, direction=direction)
-            self.drawString(x-0.5*pivW, y, rightText, mode=mode, 
charSpace=charSpace, direction=direction)
+            self.drawRightString(x-0.5*pivW, y, leftText, mode=mode, 
charSpace=charSpace,
+                    direction=direction, wordSpace=wordSpace)
+            self.drawString(x-0.5*pivW, y, rightText, mode=mode, 
charSpace=charSpace,
+                    direction=direction, wordSpace=wordSpace)
 
         else:
             #normal case
             leftText = parts[0]
-            self.drawRightString(x-0.5*pivW, y, leftText, mode=mode, 
charSpace=charSpace, direction=direction)
+            self.drawRightString(x-0.5*pivW, y, leftText, mode=mode, 
charSpace=charSpace,
+                    direction=direction, wordSpace=wordSpace)
             if len(parts) > 1:
                 rightText = pivotChar + parts[1]
-                self.drawString(x-0.5*pivW, y, rightText, mode=mode, 
charSpace=charSpace, direction=direction)
+                self.drawString(x-0.5*pivW, y, rightText, mode=mode, 
charSpace=charSpace,
+                        direction=direction, wordSpace=wordSpace)
 
     def getAvailableFonts(self):
         """Returns the list of PostScript font names available.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/platypus/flowables.py 
new/reportlab-3.5.23/src/reportlab/platypus/flowables.py
--- old/reportlab-3.5.21/src/reportlab/platypus/flowables.py    2019-04-04 
14:04:18.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/platypus/flowables.py    2019-05-31 
15:00:30.000000000 +0200
@@ -708,22 +708,25 @@
     def split(self, aW, aH):
         if getattr(self,'_wrapInfo',None)!=(aW,aH): self.wrap(aW,aH)
         S = self._content[:]
-        cf = getattr(self,'_frame',None)
-        if cf: atTop = getattr(cf,'_atTop',None)
+        cf = atTop = getattr(self,'_frame',None)
+        if cf:
+            atTop = getattr(cf,'_atTop',None)
+            cAW = cf._width
+            cAH = cf._height
         C0 = self._H>aH and (not self._maxHeight or aH>self._maxHeight)
         C1 = (self._H0>aH) or C0 and atTop
         if C0 or C1:
             fb = False
+            panf = self._doctemplateAttr('_peekNextFrame')
+            if cf and panf:
+                nf = panf()
+                nAW = nf._width
+                nAH = nf._height
             if C0 and not (self.splitAtTop and atTop):
+                fb = not (atTop and cf and nf and cAW>=nAW and cAH>=nAH)
+            elif nf and nAW>=cf._width and nAH>=self._H:
                 fb = True
-            else:
-                panf = self._doctemplateAttr('_peekNextFrame')
-                if cf and panf:
-                    nf = panf()
-                    nAW = nf._width
-                    nAH = nf._height
-                    if nAW>=cf._width and nAH>=self._H:
-                        fb = True
+
             S.insert(0,(self.FrameBreak if fb else self.NullActionFlowable)())
         return S
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/platypus/paragraph.py 
new/reportlab-3.5.23/src/reportlab/platypus/paragraph.py
--- old/reportlab-3.5.21/src/reportlab/platypus/paragraph.py    2019-04-25 
10:31:12.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/platypus/paragraph.py    2019-05-31 
15:00:30.000000000 +0200
@@ -13,7 +13,7 @@
 from operator import truth
 from unicodedata import category
 from reportlab.pdfbase.pdfmetrics import stringWidth, getFont, getAscentDescent
-from reportlab.platypus.paraparser import ParaParser, _PCT, _num as 
_parser_num, _re_us_value, _LinkValue
+from reportlab.platypus.paraparser import ParaParser, _PCT, _num as 
_parser_num, _re_us_value
 from reportlab.platypus.flowables import Flowable
 from reportlab.lib.colors import Color
 from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
@@ -1235,18 +1235,20 @@
 
 _scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$')
 def _doLink(tx,link,rect):
-    parts = link.split(':',1)
-    scheme = len(parts)==2 and parts[0].lower() or ''
-    if _scheme_re.match(scheme) and scheme!='document' or 
isinstance(link,_LinkValue):
-        kind=scheme.lower()=='pdf' and 'GoToR' or 'URI'
-        if kind=='GoToR': link = parts[1]
-        tx._canvas.linkURL(link, rect, relative=1, kind=kind)
-    else:
-        if not link: return
-        if link[0]=='#':
-            link = link[1:]
-            scheme=''
-        tx._canvas.linkRect("", scheme!='document' and link or parts[1], rect, 
relative=1)
+    if not link: return
+    if link.startswith('#'):
+        tx._canvas.linkRect("", link[1:], rect, relative=1)
+    else:
+        parts = link.split(':',1)
+        scheme = len(parts)==2 and parts[0].lower() or ''
+        if scheme=='document':
+            tx._canvas.linkRect("", parts[1], rect, relative=1)
+        elif _scheme_re.match(scheme):
+            kind=scheme.lower()=='pdf' and 'GoToR' or 'URI'
+            if kind=='GoToR': link = parts[1]
+            tx._canvas.linkURL(link, rect, relative=1, kind=kind)
+        else:
+            tx._canvas.linkURL(link, rect, relative=1, kind='URI')
 
 def _do_link_line(i, t_off, ws, tx):
     xs = tx.XtraState
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reportlab-3.5.21/src/reportlab/platypus/paraparser.py 
new/reportlab-3.5.23/src/reportlab/platypus/paraparser.py
--- old/reportlab-3.5.21/src/reportlab/platypus/paraparser.py   2019-04-25 
10:31:12.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab/platypus/paraparser.py   2019-05-31 
15:00:30.000000000 +0200
@@ -107,9 +107,6 @@
     def __deepcopy__(self,mem):
         return self.__copy__()
 
-class _LinkValue(unicodeT):
-    pass
-
 def fontSizeNormalize(frag,attr,default):
     if not hasattr(frag,attr): return default
     v = _numpct(getattr(frag,attr),allowRelative=True)
@@ -2670,7 +2667,7 @@
         underline = A.pop('underline',self._defaultLinkUnderline)
         A['link'] = self._stack[-1].link + [(
                         self.nlinks,
-                        _LinkValue(A.pop('link','').strip()),
+                        A.pop('link','').strip(),
                         )]
         self.nlinks += 1
         self._push(tag,**A)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab/rl_settings.py 
new/reportlab-3.5.23/src/reportlab/rl_settings.py
--- old/reportlab-3.5.21/src/reportlab/rl_settings.py   2019-01-15 
17:23:27.000000000 +0100
+++ new/reportlab-3.5.23/src/reportlab/rl_settings.py   2019-05-31 
15:00:30.000000000 +0200
@@ -148,7 +148,7 @@
                                                     #is attempted. suggested 
value = 0.3
 embeddedHyphenation=0                               #if true attempt 
hypenation of words with embedded hyphens
 hyphenationMinWordLength=5                          #minimum length of words 
that can be hyphenated
-reserveTTFNotdef=0                                  #if true force subset 
elemement 0 to be zero(.notdef)
+reserveTTFNotdef=0                                  #if true force subset 
element 0 to be zero(.notdef)
                                                     #helps to fix bug in edge
 
 # places to look for T1Font information
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab.egg-info/PKG-INFO 
new/reportlab-3.5.23/src/reportlab.egg-info/PKG-INFO
--- old/reportlab-3.5.21/src/reportlab.egg-info/PKG-INFO        2019-05-03 
14:00:14.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab.egg-info/PKG-INFO        2019-05-31 
15:01:08.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: reportlab
-Version: 3.5.21
+Version: 3.5.23
 Summary: The Reportlab Toolkit
 Home-page: http://www.reportlab.com/
 Author: Andy Robinson, Robin Becker, the ReportLab team and the community
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/reportlab.egg-info/SOURCES.txt 
new/reportlab-3.5.23/src/reportlab.egg-info/SOURCES.txt
--- old/reportlab-3.5.21/src/reportlab.egg-info/SOURCES.txt     2019-05-03 
14:00:14.000000000 +0200
+++ new/reportlab-3.5.23/src/reportlab.egg-info/SOURCES.txt     2019-05-31 
15:01:08.000000000 +0200
@@ -424,6 +424,7 @@
 tests/test_hello.py
 tests/test_images.py
 tests/test_invariant.py
+tests/test_issues.py
 tests/test_lib_colors.py
 tests/test_lib_normaldate.py
 tests/test_lib_pdfencrypt.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/rl_addons/renderPM/_renderPM.c 
new/reportlab-3.5.23/src/rl_addons/renderPM/_renderPM.c
--- old/reportlab-3.5.21/src/rl_addons/renderPM/_renderPM.c     2018-08-20 
15:59:21.000000000 +0200
+++ new/reportlab-3.5.23/src/rl_addons/renderPM/_renderPM.c     2019-05-31 
15:00:30.000000000 +0200
@@ -1,3 +1,4 @@
+#define PY_SSIZE_T_CLEAN
 #include "Python.h"
 #if PY_MAJOR_VERSION >= 3
 #      define isPy3
@@ -20,7 +21,7 @@
 #endif
 
 
-#define VERSION "3.01"
+#define VERSION "3.02"
 #define MODULENAME "_renderPM"
 #ifdef isPy3
 #      define PyInt_FromLong   PyLong_FromLong
@@ -92,7 +93,8 @@
 static PyObject* parse_utf8(PyObject* self, PyObject* args)
 {
        char            *c, *msg;
-       int                     n, i;
+       Py_ssize_t      n;
+       int                     i;
        unsigned        first, second, third;
        PyObject        *r;
     if(!PyArg_ParseTuple(args, "t#:parse_utf8", &c, &n)) return NULL;
@@ -185,7 +187,7 @@
        _data = PyObject_GetAttrString(face,"_ttf_data");
        Py_DECREF(face);
        if(!_data) goto RET;
-       error = FT_New_Memory_Face(ft_library, (unsigned char 
*)PyBytes_AsString(_data), PyBytes_GET_SIZE(_data), 0, &ft_face->face);
+       error = FT_New_Memory_Face(ft_library, (unsigned char 
*)PyBytes_AsString(_data), (FT_Long)PyBytes_GET_SIZE(_data), 0, &ft_face->face);
        Py_DECREF(_data);
        if(error){
                PyErr_Format(PyExc_IOError, "FT_New_Memory_Face(%s) Failed!", 
fontName);
@@ -260,7 +262,7 @@
                        p->width = w;
                        p->height = h;
                        p->nchan = nchan;
-                       p->rowstride = stride;
+                       p->rowstride = (int)stride;
 
                        /*set up the background*/
                        if(bg.stride==0){       /*simple color case*/
@@ -835,7 +837,8 @@
        A2DMX   orig, trans = {1,0,0,1,0,0}, scaleMat = {1,0,0,1,0,0};
        double  scaleFactor, x, y, w;
        char*   text;
-       int             c, textlen, i;
+       int             c, i;
+       Py_ssize_t      textlen;
        ArtBpath        *saved_path, *path;
        void    *font = self->font;
        PyObject        *textObj, *obj0;
@@ -1055,7 +1058,8 @@
        char*   text;
        PyObject *P, *p;
        ArtBpath        *path, *pp;
-       int             textlen, i, c;
+       Py_ssize_t      textlen;
+       int             i, c;
        void    *font = self->font;
        PyObject        *textObj, *obj0;
 #ifdef RENDERPM_FT
@@ -1140,7 +1144,7 @@
                                pp->y3 = pp->y3*s+y;
                                pp++;
                                }
-                       p = _get_gstatePath(pp-path,path);
+                       p = _get_gstatePath((int)(pp-path),path);
 #ifdef RENDERPM_FT
                        if(!ft_font && path!=notdefPath)
 #endif
@@ -1326,7 +1330,8 @@
                return 1;
                }
        else {
-               int     n_dash, i, r=0;
+               Py_ssize_t      n_dash;
+               int i, r=0;
                PyObject        *v=NULL, *pDash=NULL;
                double          offset, *dash=NULL;
                if(!PySequence_Check(value) || PySequence_Length(value)!=2){
@@ -1349,7 +1354,7 @@
 
                /*everything checks out release current thing and set new one*/
                _dashFree(self);
-               self->dash.n_dash = n_dash;
+               self->dash.n_dash = (int)n_dash;
                self->dash.offset = offset;
                self->dash.dash = dash;
                r = 1;
@@ -1428,7 +1433,7 @@
 {
        int     i;
        if(PySequence_Check(value)){
-               size_t  len;
+               Py_ssize_t      len;
                i = 
PyArg_Parse(value,"(iis#)",&c->width,&c->height,&c->buf,&len);
                if(i){
                        /*we assume depth 3*/
@@ -1753,7 +1758,7 @@
                /*the file should have been read as binary*/
                if(PyBytes_Check(result)){
                        char    *pystr = PyBytes_AS_STRING(result);
-                       int             size = PyBytes_GET_SIZE(result);
+                       int             size = (int)PyBytes_GET_SIZE(result);
                        *psize = size;
                        memcpy(pfb=gt1_alloc(size),pystr,size);
                        }
@@ -1821,7 +1826,7 @@
                        rfunc.data = reader;
                        rfunc.reader = my_pfb_reader;
                        }
-               if(!gt1_create_encoded_font(name,pfbPath,names,N,prfunc)){
+               if(!gt1_create_encoded_font(name,pfbPath,names,(int)N,prfunc)){
                        PyErr_SetString(PyExc_ValueError, 
"_renderPM.makeT1Font: can't make font");
                        ok = 0;
                        }
@@ -1958,7 +1963,7 @@
                }
        if (count > 0) *p++ = counttochar(count);
 
-       packcols = p - packed;          /* how many did we write? */
+       packcols = (int)(p - packed);           /* how many did we write? */
        if (cols > 250){
                pict_putShort(fd, packcols);
                oc = packcols + 2;
@@ -1980,7 +1985,9 @@
 static PyObject* pil2pict(PyObject* self, PyObject* args)
 {
        PyObject *result;
-       int             rows, cols, colors, i, row, oc, len, npixels, tc=-1;
+       Py_ssize_t      npixels, colors;
+       int             rows, cols, i, row, oc, tc=-1;
+       size_t  len;
        char    *packed;
        long    lpos;
        pixel   *palette, *pixels;
@@ -2047,7 +2054,7 @@
        pict_putLong(obs, 0L);  /* pmReserved */
        pict_putLong(obs, 0L);  /* ctSeed */
        pict_putShort(obs, 0);  /* ctFlags */
-       pict_putShort(obs, colors-1);   /* ctSize */
+       pict_putShort(obs, (int)(colors-1));    /* ctSize */
 
        /*Write out the colormap*/
        for (i = 0; i < colors; i++){
@@ -2072,7 +2079,7 @@
        pict_putShort(obs, PICT_EndOfPicture);
 
        len = obs->p-obs->buf;
-       lpos = (obs->p-obs->buf) - HEADER_SIZE;
+       lpos = (int)(obs->p-obs->buf) - HEADER_SIZE;
        obs->p = obs->buf + HEADER_SIZE;
        pict_putShort(obs, (short)(lpos & 0xffff));
        result = PyBytes_FromStringAndSize((const char *)obs->buf,len);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/src/rl_addons/rl_accel/_rl_accel.c 
new/reportlab-3.5.23/src/rl_addons/rl_accel/_rl_accel.c
--- old/reportlab-3.5.21/src/rl_addons/rl_accel/_rl_accel.c     2018-07-23 
09:27:39.000000000 +0200
+++ new/reportlab-3.5.23/src/rl_addons/rl_accel/_rl_accel.c     2019-05-31 
15:00:30.000000000 +0200
@@ -5,6 +5,7 @@
 * for details.
 * history 
http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/lib/_rl_accel.c
 */
+#define PY_SSIZE_T_CLEAN
 #include "Python.h"
 #if PY_MAJOR_VERSION >= 3
 #      define isPy3
@@ -29,7 +30,7 @@
 #ifndef min
 #      define min(a,b) ((a)<(b)?(a):(b))
 #endif
-#define VERSION "0.74"
+#define VERSION "0.75"
 #define MODULE "_rl_accel"
 
 struct module_state    {
@@ -107,7 +108,8 @@
 PyObject *_a85_encode(PyObject *module, PyObject *args)
 {
        unsigned char   *inData;
-       int                             length, blocks, extra, i, k, lim;
+       Py_ssize_t              length, blocks, extra;
+       int                             i, k, lim;
        unsigned long   block, res;
        char                    *buf;
        PyObject                *retVal=NULL, *inObj, *_o1=NULL;
@@ -136,7 +138,7 @@
        extra = length % 4;
 
        buf = (char*)malloc((blocks+1)*5+3);
-       lim = 4*blocks;
+       lim = 4*(int)blocks;
 
        for(k=i=0; i<lim; i += 4){
                /*
@@ -230,7 +232,7 @@
                ERROR_EXIT();
                }
        inData = PyBytes_AsString(inObj);
-       length = PyBytes_GET_SIZE(inObj);
+       length = (unsigned int)PyBytes_GET_SIZE(inObj);
        for(k=0,q=inData, p=q+length;q<p && (q=(unsigned char*)strchr((const 
char*)q,'z'));k++, q++);   /*count 'z'*/
        length += k*4;
        tmp = q = (unsigned char*)malloc(length+1);
@@ -245,7 +247,7 @@
                        *q++ = k;
                }
        inData = tmp;
-       length = q - inData;
+       length = (unsigned int)(q - inData);
        buf = inData+length-2;
        if(buf[0]!='~' || buf[1]!='>'){
                PyErr_SetString(PyExc_ValueError, "Invalid terminator for Ascii 
Base 85 Stream");
@@ -333,7 +335,7 @@
                else l = 6;
                sprintf(s,_fp_fmts[l], d);
                if(l){
-                       l = strlen(s)-1;
+                       l = (int)strlen(s)-1;
                        while(l && s[l]=='0') l--;
                        if(s[l]=='.' || s[l]==',') s[l]=0;
                        else {
@@ -351,11 +353,10 @@
 
 PyObject *_fp_str(PyObject *module, PyObject *args)
 {
-       int                             aL;
+       Py_ssize_t              i, aL;
        PyObject                *retVal;
        char                    *pD;
        char                    *buf, *pB;
-       int                             i;
 
        if((aL=PySequence_Length(args))>=0){
                if(aL==1){
@@ -402,7 +403,7 @@
                }
 }
 
-static PyObject *_escapePDF(unsigned char* text, int textlen)
+static PyObject *_escapePDF(unsigned char* text, Py_ssize_t textlen)
 {
        unsigned char*  out = PyMem_Malloc((textlen<<2)+1);
        int                             j=0, i=0;
@@ -435,7 +436,7 @@
 static PyObject *escapePDF(PyObject *module, PyObject* args)
 {
        unsigned char   *text;
-       int                             textLen;
+       Py_ssize_t              textLen;
 
        if (!PyArg_ParseTuple(args, "s#:escapePDF", &text, &textLen)) return 
NULL;
        return _escapePDF(text,textLen);
@@ -480,7 +481,7 @@
 static PyObject *ttfonts_calcChecksum(PyObject *module, PyObject* args)
 {
        unsigned char   *data;
-       int                             dataLen;
+       Py_ssize_t              dataLen;
        unsigned long   Sum = 0L;
        unsigned char   *EndPtr;
        unsigned long n;
@@ -555,7 +556,7 @@
 /* Get a UTF8 encoded string buffer, the return value is the PyObject
    holding the memory for the buffer and should be decrefed to free
    memory */
-static PyObject *_GetStringBuf(PyObject *obj, char **buf)
+static PyObject *_GetStringBuf(PyObject *obj, const char **buf)
 {
        PyObject *res;
 
@@ -563,7 +564,7 @@
 #ifdef isPy3
                res = obj;
                Py_INCREF(res);
-               *buf = PyUnicode_AsUTF8(res);
+               *buf = (const char *)PyUnicode_AsUTF8(res);
 #else
                res = PyUnicode_AsUTF8String(obj);
                if (!res) {
@@ -732,7 +733,8 @@
        unsigned char *b;
        PyObject *encObj = NULL;
        const char *encStr;
-       int n, m, i, j, s, _i1;
+       Py_ssize_t n, m;
+       int     i, j, s, _i1;
        static char *argnames[]={"self","text","size","encoding",0};
        if(!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|O", argnames, &self, 
&text, &size, &encoding)) return 0;
        Py_INCREF(text);
@@ -831,7 +833,8 @@
        PyObject *self, *text, *size, *res,
                                *encoding = 0, *_o1=NULL, *_o2=NULL, *_o3=NULL;
        Py_UNICODE *b;
-       int n, i;
+       Py_ssize_t n;
+       int     i;
        double s, _d1, dw;
        static char *argnames[]={"self","text","size","encoding",0};
        if(!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|O", argnames, &self, 
&text, &size, &_o1)) return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/tests/test_charts_textlabels.py 
new/reportlab-3.5.23/tests/test_charts_textlabels.py
--- old/reportlab-3.5.21/tests/test_charts_textlabels.py        2017-03-07 
11:17:00.000000000 +0100
+++ new/reportlab-3.5.23/tests/test_charts_textlabels.py        2019-05-31 
15:00:30.000000000 +0200
@@ -165,16 +165,23 @@
         story.append(PageBreak())
 
         # Round 1c
-        story.append(Paragraph('Helvetica 18pt, multi-line', h3))
+        try:
+            from reportlab.pdfbase.pdfmetrics import registerFont
+            from reportlab.pdfbase.ttfonts import TTFont
+            fontName = 'Vera'
+            registerFont(TTFont(fontName, "Vera.ttf"))
+        except:
+            fontName = 'Helvetica'
+        story.append(Paragraph('%s 18pt, multi-line' % fontName, h3))
         story.append(Spacer(0, 0.5*cm))
 
         w, h = drawWidth, drawHeight = 400, 100
         protoLabel = self._makeProtoLabel()
         protoLabel.setOrigin(drawWidth*0.5, drawHeight*0.5)
         protoLabel.textAnchor = 'start'
-        protoLabel.fontName = 'Helvetica'
+        protoLabel.fontName = fontName
         protoLabel.fontSize = 18
-        drawings = self._makeDrawings(protoLabel, text='Hello\nWorld!')
+        drawings = self._makeDrawings(protoLabel, text=u'Hello\nW\xf6rld!')
         for d in drawings:
             story.append(d)
             story.append(Spacer(0, 1*cm))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/tests/test_graphics_charts.py 
new/reportlab-3.5.23/tests/test_graphics_charts.py
--- old/reportlab-3.5.21/tests/test_graphics_charts.py  2018-11-20 
16:13:08.000000000 +0100
+++ new/reportlab-3.5.23/tests/test_graphics_charts.py  2019-05-31 
15:00:30.000000000 +0200
@@ -35,6 +35,17 @@
 except ImportError:
     _renderPM = None
 
+def getFontName():
+    try:
+        from reportlab.pdfbase.pdfmetrics import registerFont
+        from reportlab.pdfbase.ttfonts import TTFont
+        fontName = 'Vera'
+        registerFont(TTFont(fontName, "Vera.ttf"))
+    except:
+        fontName = 'Helvetica'
+    return fontName
+fontName = getFontName()
+
 def myMainPageFrame(canvas, doc):
     "The page frame used for all PDF documents."
 
@@ -81,8 +92,12 @@
     bc.categoryAxis.labels.dx = 8
     bc.categoryAxis.labels.dy = -2
     bc.categoryAxis.labels.angle = 30
+    bc.categoryAxis.labels.fontName = fontName
+    bc.barLabels.fontName = fontName
+    bc.barLabelFormat = u'\xc5%s'
 
-    catNames = 'Jan Feb Mar Apr May Jun Jul Aug'.split( ' ')
+    catNames = u'J\xe4n Feb M\xe4r \xc4pr M\xe4y J\xfcn J\xfcl 
\xc4\xfcg'.split( ' ')
+    bc.barLabelArray = catNames
     catNames = [n+'-99' for n in catNames]
     bc.categoryAxis.categoryNames = catNames
     drawing.add(bc)
@@ -157,13 +172,14 @@
     pc.x = 150
     pc.y = 50
     pc.data = [1, 50, 100, 100, 100, 100, 100, 100, 100, 50]
-    pc.labels = ['0','a','b','c','d','e','f','g','h','i']
+    pc.labels = u'0 \xe4 b c d e f g h i'.split()
     pc.slices.strokeWidth=0.5
     pc.slices[3].popout = 20
     pc.slices[3].strokeWidth = 2
     pc.slices[3].strokeDashArray = [2,2]
     pc.slices[3].labelRadius = 1.75
     pc.slices[3].fontColor = colors.red
+    pc.slices[1].fontName = fontName
     d.add(pc)
     legend = Legend()
     legend.x = width-5
@@ -199,6 +215,11 @@
         legend.swatchMarker.size = 10
     elif i=='swatch auto':
         legend.swatchMarker=Auto(chart=chart)
+    else:
+        cnp = legend.colorNamePairs
+        legend.fontName = fontName
+        legend.colorNamePairs = [(cnp[0][0],u'r\xf6t')] + cnp[1:]
+
     d = Drawing(width,height)
     d.background = 
Rect(0,0,width,height,strokeWidth=1,strokeColor=colors.red,fillColor=None)
     m = makeMarker('Cross')
@@ -264,7 +285,6 @@
 h1 = styleSheet['Heading1']
 h2 = styleSheet['Heading2']
 h3 = styleSheet['Heading3']
-FINISHED = 0
 
 def run_samples(S,kind='axes'):
     outDir = outputfile('charts-out')
@@ -276,22 +296,19 @@
 class ChartTestCase(unittest.TestCase):
     "Test chart classes."
 
-    def setUp(self):
+    @classmethod
+    def setUpClass(cls):
         "Hook method for setting up the test fixture before exercising it."
+        cls.story = []
+        cls.story.append(Paragraph('Tests for chart classes', h1))
 
-        global STORY
-        self.story = STORY
-
-        if self.story == []:
-            self.story.append(Paragraph('Tests for chart classes', h1))
-
-    def tearDown(self):
+    @classmethod
+    def tearDownClass(cls):
         "Hook method for deconstructing the test fixture after testing it."
 
-        if FINISHED:
-            path=outputfile('test_graphics_charts.pdf')
-            doc = MyDocTemplate(path)
-            doc.build(self.story)
+        path=outputfile('test_graphics_charts.pdf')
+        doc = MyDocTemplate(path)
+        doc.build(cls.story)
 
     def test0(self):
         "Test bar charts."
@@ -488,10 +505,6 @@
             for sa in (225, 180, 135, 90, 45, 0, -45, -90):
                 subtest(sa,d)
 
-        # This triggers the document build operation (hackish).
-        global FINISHED
-        FINISHED = 1
-
     def test801(self):
         '''test for bitbucket issue 105 reported by Johann Du Toit'''
         from reportlab.graphics.charts.doughnut import Doughnut
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/tests/test_issues.py 
new/reportlab-3.5.23/tests/test_issues.py
--- old/reportlab-3.5.21/tests/test_issues.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/reportlab-3.5.23/tests/test_issues.py   2019-05-31 15:00:30.000000000 
+0200
@@ -0,0 +1,109 @@
+#Copyright ReportLab Europe Ltd. 2000-2017
+#see license.txt for license details
+"""Tests for the reportlab.platypus.paragraphs module.
+"""
+__version__='3.5.23'
+from reportlab.lib.testutils import setOutDir,makeSuiteForClasses, outputfile, 
printLocation
+setOutDir(__name__)
+import sys, os, unittest
+
+class IssueTestCase(unittest.TestCase):
+    def test_issue183(self):
+        '''issue 183 raised by Marius Gedminas'''
+        from reportlab.pdfgen.canvas import Canvas
+        from reportlab.platypus.paragraph import Paragraph
+        from reportlab.lib.styles import ParagraphStyle
+        from reportlab.pdfbase.pdfmetrics import registerFont
+        from reportlab.pdfbase.ttfonts import TTFont
+        from reportlab.lib.enums import TA_JUSTIFY
+        sty = ParagraphStyle('A')
+        sty.fontSize = 11
+        sty.leading = sty.fontSize*1.2
+        sty.fontName = 'Helvetica'
+        sty.alignment = TA_JUSTIFY
+        canv = Canvas(outputfile('test_issue183.pdf'))
+        aW = 440
+        text = u'''AAAAAAAAAAAA BBBBB C Dddd EEEEEEEE\xa0\u2014 FF GGGGGG 
HHHHHHHHH III JJJJJJJJJ KKK
+LLLLLLLLL MMMMMM NNNNN O PPPPPP Q RRRRR SSSSSS TTTTTTTTTTT. UUUUUUU VVVVVVVV
+WWWWWWWWWWWW XXX YYYYYY ABBBBB BCCCCCCCCCCC.'''
+        def do1(x,y,text,sty):
+            p = Paragraph(text,sty)
+            w,h=p.wrap(aW,1000000)
+            y -= h
+            p.drawOn(canv,x,y)
+            canv.saveState()
+            canv.setLineWidth(0.5)
+            canv.setStrokeColor((1,0,0))
+            canv.rect(x,y,aW,h,stroke=1,fill=0)
+            canv.restoreState()
+            return y
+
+        def do2(x,y,text,sty):
+            y = do1(x,y,text,sty)
+            return do1(x,y-10,text.replace(u'\xa0\u2014',u'&nbsp;&mdash;'),sty)
+
+        fonts = set()
+        fonts.add('Helvetica')
+        for fontName, fontPath in (('Vera','Vera.ttf'),
+                ('Times','/usr/share/fonts/TTF/times.ttf')):
+            try:
+                registerFont(TTFont(fontName, fontPath))
+                fonts.add(fontName)
+            except:
+                pass
+
+        y = canv._pagesize[1] - 72
+        y = do2(72,y,text,sty)
+        if 'Vera' in fonts:
+            styv = sty.clone('AV',fontName='Vera')
+            y = do2(72,y-10,text,styv)
+
+        if 'Times' in fonts:
+            styv = sty.clone('AV',fontName='Times')
+            y = do2(72,y-10,text,styv)
+
+        text = u'|A B C D E F G H I J K L|'
+        y -= 13.1
+        offs = None
+        for fontName in 'Helvetica Vera Times'.split():
+            if fontName not in fonts: continue
+            for ws in 0, -1, 1:
+                for s in (u' ',u'\xa0'):
+                    canv.saveState()
+                    canv.setFont('Courier',11)
+                    lab = '%-9s ws=%2d %s:' % (fontName,ws,s==u' ' and 'soft' 
or 'hard')
+                    if offs == None:
+                        offs = 72+canv.stringWidth(lab)+2
+                    canv.drawString(72,y,lab)
+                    canv.setFont(fontName,11)
+                    canv.drawString(offs,y,text.replace(u' ',s),wordSpace=ws)
+                    canv.restoreState()
+                    y -= 13.1
+
+        canv.showPage()
+        canv.save()
+
+    def test_issue181(self):
+        '''issue #181 rasied by Daniel Turecek'''
+        from reportlab.lib.styles import ParagraphStyle as PS
+        from reportlab.platypus import Paragraph, SimpleDocTemplate, PageBreak
+        style = PS(fontname='Helvetica', name='Title', fontSize=10, 
leading=12, alignment=1)
+        add = [].append
+        add(Paragraph('<a name="top"/>Top', style))
+        add(Paragraph('<a href="#test">Local Link</a>', style))
+        add(Paragraph('<a href="document:test">Document Link</a>', style))
+        add(Paragraph('<a href="www.reportlab.com">website</a>', style))
+        add(PageBreak())
+        add(Paragraph('<a name="test"/>Anchor', style))
+        add(Paragraph('<a href="#top">top</a>', style))
+        doc = SimpleDocTemplate(outputfile("test_issue181.pdf"))
+        doc.build(add.__self__)
+
+#noruntests
+def makeSuite():
+    return makeSuiteForClasses(IssueTestCase)
+
+#noruntests
+if __name__ == "__main__":
+    unittest.TextTestRunner().run(makeSuite())
+    printLocation()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reportlab-3.5.21/tests/test_pdfbase_ttfonts.py 
new/reportlab-3.5.23/tests/test_pdfbase_ttfonts.py
--- old/reportlab-3.5.21/tests/test_pdfbase_ttfonts.py  2019-01-15 
17:23:27.000000000 +0100
+++ new/reportlab-3.5.23/tests/test_pdfbase_ttfonts.py  2019-05-31 
15:00:30.000000000 +0200
@@ -309,10 +309,9 @@
         font = TTFont("Vera", "Vera.ttf")
         text = b"".join(utf8(i) for i in range(511))
         allchars = b"".join(int2Byte(i) for i in range(256))
-        if rl_config.reserveTTFNotdef:
-            chunks = [(0, allchars), (1, allchars[1:32] + allchars[33:]), (2, 
b'\x01')]
-        else:
-            chunks = [(0, allchars), (1, allchars[:32] + allchars[33:])]
+        chunks = [(0, allchars[:0xa0]+b' '+allchars[0xa0:])] + [
+                (1, allchars[1:32] + allchars[33:]) if 
rl_config.reserveTTFNotdef else
+                (1, allchars[:32] + allchars[33:-1])]
         self.assertEqual(font.splitString(text, doc), chunks)
         # Do it twice
         self.assertEqual(font.splitString(text, doc), chunks)


Reply via email to