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' —'),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)