Hello community, here is the log from the commit of package python-reportlab for openSUSE:Factory checked in at 2020-12-12 20:29:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-reportlab (Old) and /work/SRC/openSUSE:Factory/.python-reportlab.new.2328 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-reportlab" Sat Dec 12 20:29:37 2020 rev:28 rq:854304 version:3.5.56 Changes: -------- --- /work/SRC/openSUSE:Factory/python-reportlab/python-reportlab.changes 2020-10-29 09:46:24.004060587 +0100 +++ /work/SRC/openSUSE:Factory/.python-reportlab.new.2328/python-reportlab.changes 2020-12-12 20:32:07.253836799 +0100 @@ -1,0 +2,10 @@ +Wed Dec 9 15:56:35 UTC 2020 - Markéta Machová <mmach...@suse.com> + +- Update to 3.5.56 + * allow setting initial template cycle + * fix for pillow 8.0.x + * added trustedHosts & trustedSchemes settings + * allow Drawing.outDir to be a callable +- Rebased reportlab-missing-includes.patch + +------------------------------------------------------------------- Old: ---- reportlab-3.5.51.tar.gz New: ---- reportlab-3.5.56.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-reportlab.spec ++++++ --- /var/tmp/diff_new_pack.FH3x64/_old 2020-12-12 20:32:08.125837709 +0100 +++ /var/tmp/diff_new_pack.FH3x64/_new 2020-12-12 20:32:08.125837709 +0100 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define oldpython python Name: python-reportlab -Version: 3.5.51 +Version: 3.5.56 Release: 0 Summary: The Reportlab Toolkit License: BSD-3-Clause ++++++ reportlab-3.5.51.tar.gz -> reportlab-3.5.56.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/.appveyor.yml new/reportlab-3.5.56/.appveyor.yml --- old/reportlab-3.5.51/.appveyor.yml 2019-11-07 12:37:59.000000000 +0100 +++ new/reportlab-3.5.56/.appveyor.yml 2020-10-29 17:06:02.000000000 +0100 @@ -13,39 +13,39 @@ CITOOLS_USER: rl-wheelbuilder CITOOLS_PASSWORD: secure: xbq9uLuFeus1N1x8xSF9f5kAYXY4lkvU4UveYwgcMkM= - FIRST: 27 - LAST: 38-x64 + FIRST: 39 + LAST: 27-x64 RLCACHE: windows/reportlab matrix: - - PYVER: 27 + - PYVER: 39 ARCH: X86 - - PYVER: 27-x64 + - PYVER: 39-x64 ARCH: AMD64 - - PYVER: 35 + - PYVER: 38 ARCH: X86 - - PYVER: 35-x64 + - PYVER: 38-x64 ARCH: AMD64 - - PYVER: 36 + - PYVER: 37 ARCH: X86 - - PYVER: 36-x64 + - PYVER: 37-x64 ARCH: AMD64 - - PYVER: 37 + - PYVER: 36 ARCH: X86 - - PYVER: 37-x64 + - PYVER: 36-x64 ARCH: AMD64 - - PYVER: 38 + - PYVER: 27 ARCH: X86 - - PYVER: 38-x64 + - PYVER: 27-x64 ARCH: AMD64 matrix: @@ -104,12 +104,14 @@ - c:\Python37-x64\python.exe -mvirtualenv -p C:\Python%PYVER%\python.exe c:\projects\testenv - c:\projects\testenv\scripts\python.exe -mpip install -U pip setuptools wheel - c:\projects\testenv\scripts\pip.exe --version - - c:\projects\testenv\scripts\pip.exe install pillow + - c:\projects\testenv\scripts\pip.exe install pillow pyphen - c:\projects\testenv\scripts\pip.exe install --cache-dir=dist --find-links file:dist --pre reportlab #- c:\projects\myenv\scripts\python.exe -mrl_ci_tools info --recur c:\projects\testenv\Lib\site-packages #- c:\projects\myenv\scripts\python.exe -mrl_ci_tools info --recur c:\projects\testenv\Lib\site-packages\reportlab\fonts - set OLDCD=%CD% - cd tests + - echo "=============================== Python%PYVER% tests" + - c:\projects\testenv\Scripts\python.exe --version - c:\projects\testenv\Scripts\python.exe .\runAll.py - cd %OLDCD% - echo "=============================== Python%PYVER% TEST END" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/.travis.yml new/reportlab-3.5.56/.travis.yml --- old/reportlab-3.5.51/.travis.yml 2020-09-18 15:27:00.000000000 +0200 +++ new/reportlab-3.5.56/.travis.yml 2020-10-29 13:35:05.000000000 +0100 @@ -11,7 +11,7 @@ - PLAT=x86_64 - UNICODE_WIDTH=32 - BUILD_DEPENDS="" - - TEST_DEPENDS="pillow" + - TEST_DEPENDS="pillow pyphen" - TWINE_USERNAME=MrRLBitBucket - CITOOLS_USER=rl-wheelbuilder - RLCACHE=manylinux/reportlab @@ -49,13 +49,6 @@ - PLAT=i686 - os: linux env: - - MB_PYTHON_VERSION=3.5 - - os: linux - env: - - MB_PYTHON_VERSION=3.5 - - PLAT=i686 - - os: linux - env: - MB_PYTHON_VERSION=3.6 - os: linux env: @@ -75,14 +68,17 @@ env: - MB_PYTHON_VERSION=3.8 - PLAT=i686 - - os: osx - language: generic + - os: linux env: - - MB_PYTHON_VERSION=2.7 + - MB_PYTHON_VERSION=3.9 + - os: linux + env: + - MB_PYTHON_VERSION=3.9 + - PLAT=i686 - os: osx language: generic env: - - MB_PYTHON_VERSION=3.5 + - MB_PYTHON_VERSION=2.7 - os: osx language: generic env: @@ -96,10 +92,15 @@ env: - MB_PYTHON_VERSION=3.8 - MB_PYTHON_OSX_VER=10.9 + - os: osx + language: generic + env: + - MB_PYTHON_VERSION=3.9 + - MB_PYTHON_OSX_VER=10.9 before_install: - git clone https://github.com/matthew-brett/multibuild $MULTIBUILD_DIR - cd $MULTIBUILD_DIR -- git checkout b943f33a92772fd52c2fa38c03d08aac974c53bd +- git checkout ec386efaa9e6840b552d845dfc4d597f6b97a2b7 - cd .. - git clone https://github.com/MrBitBucket/reportlab-mirror $REPO_DIR - source $MULTIBUILD_DIR/common_utils.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/CHANGES.md new/reportlab-3.5.56/CHANGES.md --- old/reportlab-3.5.51/CHANGES.md 2020-09-24 15:27:24.000000000 +0200 +++ new/reportlab-3.5.56/CHANGES.md 2020-12-01 17:29:04.000000000 +0100 @@ -11,6 +11,31 @@ 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.56 01/12/2020 +--------------------------- + * micro changes for Big Sur in C extensions + * allow Drawing.outDir to be a callable for more control in save method + +RELEASE 3.5.55 29/10/2020 +--------------------------- + * add trustedHosts and trustedSchemes for url management + * drop 3.5 support + +RELEASE 3.5.54 23/10/2020 +--------------------------- + * Allow extra fields in AcroForm suggested by Chris Else ubuntu247 at gmail.com + * Allow DocTemplate.\_firstPageTemplateIndex to be a list of PageTemplate ids + * improve PageBreak repr + * minor changes to travis & appveyor scripts; drop forml support for python 3.5 + +RELEASE 3.5.53 02/10/2020 +--------------------------- + * Fix bug that allowed type 0 postscript commands to persist + +RELEASE 3.5.52 01/10/2020 +--------------------------- + * add support for DataMatrix barcode + RELEASE 3.5.51 24/09/2020 --------------------------- * fix malloc(0) issue in \_rl_accel.c \_fp_str thanks to Hans-Peter Jansen <h...@urpla.net> @ openSUSE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/PKG-INFO new/reportlab-3.5.56/PKG-INFO --- old/reportlab-3.5.51/PKG-INFO 2020-09-24 15:27:52.000000000 +0200 +++ new/reportlab-3.5.56/PKG-INFO 2020-12-01 17:29:31.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: reportlab -Version: 3.5.51 +Version: 3.5.56 Summary: The Reportlab Toolkit Home-page: http://www.reportlab.com/ Author: Andy Robinson, Robin Becker, the ReportLab team and the community @@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/docs/userguide/ch1_intro.py new/reportlab-3.5.56/docs/userguide/ch1_intro.py --- old/reportlab-3.5.51/docs/userguide/ch1_intro.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/docs/userguide/ch1_intro.py 2020-10-29 13:35:05.000000000 +0100 @@ -260,11 +260,11 @@ heading2("Installation and Setup") disc("""To avoid duplication, the installation instructions are kept in the README file -in our distribution, which can be viewed online at ^http://bitbucket.org/rptlab/reportlab/^""") +in our distribution, which can be viewed online at ^https://hg.reportlab.com/hg-public/reportlab/^""") -disc("""This release (3.0) of ReportLab requires Python versions 2.7, 3.3 or higher. - If you need to use Python 2.5 or 2.6, please use the latest ReportLab 2.x package. -""") +disc("""This release (%s) of ReportLab requires Python versions 2.7, %s.%s+ or higher. + If you need to use Python 2.5 or 2.6, please use the latest ReportLab 2.7 package. +""" % ((reportlab.Version,)+reportlab.__min_python_version__)) @@ -302,7 +302,7 @@ and contributions. The mailing list is the place to report bugs and get support. """) -disc("""The code now lives on BitBucket ($http://bitbucket.org/rptlab/reportlab/$) +disc("""The code now lives on our website ($http://hg.reportlab.com/hg-public/reportlab/$) in a Mercurial repository, along with an issue tracker and wiki. Everyone should feel free to contribute, but if you are working actively on some improvements or want to draw attention to an issue, please use the mailing list to let us know.""") @@ -311,8 +311,13 @@ heading2("Site Configuration") disc("""There are a number of options which most likely need to be configured globally for a site. -The python script module $reportlab/rl_config.py$ may be edited to change the values of several -important sitewide properties.""") +The python script module $reportlab/rl_config.py$ aggregates the various settings files. You may want inspect the file $reportlab/$rl_settings.py$ which +contains defaults for the currently used variables. There are several overrides for $rl_settings" +modules $reportlab.local_rl_settings$, $reportlab_settings$ (a script file anywhere on the python path) +and finally the file $~/.reportlab_settings$ (note no .py). Temporary changes can be made using evironment variables which +are the variables from $rl_settings.py" prefixed with $RL_$ eg $RL_verbose=1$. +""") +heading3("Useful rl_config variables") bullet("""verbose: set to integer values to control diagnostic output.""") bullet("""shapeChecking: set this to zero to turn off a lot of error checking in the graphics modules""") bullet("""defaultEncoding: set this to WinAnsiEncoding or MacRomanEncoding.""") @@ -328,9 +333,16 @@ may be queried for information on font code maps.""") bullet("""showBoundary: set to non-zero to get boundary lines drawn.""") bullet("""ZLIB_WARNINGS: set to non-zero to get warnings if the Python compression extension is not found.""") -bullet("""pageComression: set to non-zero to try and get compressed PDF.""") +bullet("""pageCompression: set to non-zero to try and get compressed PDF.""") bullet("""allowtableBoundsErrors: set to 0 to force an error on very large Platypus table elements""") bullet("""emptyTableAction: Controls behaviour for empty tables, can be 'error' (default), 'indicate' or 'ignore'.""") +bullet("""trustedHosts: if not $None$ a list of glob patterns of trusted hosts; these may be used in places like <img> tags in paragraph texts.""") +bullet("""trustedSchemes: a list of allowed $URL$ schemes used with $trustedHosts$""") +disc("""For the full list of variables see the file $reportlab/rl_settings.py$.""") +heading3("Other modifications") +disc("""More complex modifications to the reportlab toolkit environment may be made using one +of the modules $rep[ortlab.local_rl_mods$ (.py script in reportlab folder), +$reportlab_mods$ (.py file on the python path) or $~/.reportlab_mods$ (note no .py).""") heading2("Learning More About Python") @@ -384,11 +396,10 @@ of major Python packages now run on Python 3. """) - -bullet("""Python 3.x compatibility. A single line of code should run on 2.7 and 3.3""") -bullet(""" __init__.py restricts to 2.7 or >=3.3""") +bullet("""Python 3.x compatibility. A single line of code should run on 2.7 and 3.6""") +bullet(""" __init__.py restricts to 2.7 or >=3.6""") bullet("""__init__.py allow the import of on optional reportlab.local_rl_mods to allow monkey patching etc.""") -bullet("""rl_config now imports rl_settings & optionally local_rl_settings""") +bullet("""rl_config now imports rl_settings, optionally local_rl_settings, reportlab_settings.py & finally ~/.reportlab_settings""") bullet("""ReportLab C extensions now live inside reportlab; _rl_accel is no longer required. All _rl_accel imports now pass through reportlab.lib.rl_accel""") bullet("""xmllib is gone, alongside the paraparser stuff that caused issues in favour of HTMLParser.""") bullet("""some obsolete C extensions (sgmlop and pyHnj) are gone""") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/docs/userguide/ch2a_fonts.py new/reportlab-3.5.56/docs/userguide/ch2a_fonts.py --- old/reportlab-3.5.51/docs/userguide/ch2a_fonts.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/docs/userguide/ch2a_fonts.py 2020-10-29 13:35:05.000000000 +0100 @@ -216,7 +216,7 @@ disc(""" Unfortunately, there is no reliable standard yet for such locations (not even on the same platform) and, hence, you might -have to edit the file $reportlab/rl_config.py$ to modify the +have to edit one of the files $reportlab_settings.py$ or $~/.reportlab_settings$ to modify the value of the $T1SearchPath$ identifier to contain additional directories. Our own recommendation is to use the ^reportlab/fonts^ folder in development; and to have any needed fonts as packaged parts of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/docs/userguide/ch5_paragraphs.py new/reportlab-3.5.56/docs/userguide/ch5_paragraphs.py --- old/reportlab-3.5.51/docs/userguide/ch5_paragraphs.py 2020-07-20 09:39:52.000000000 +0200 +++ new/reportlab-3.5.56/docs/userguide/ch5_paragraphs.py 2020-12-01 17:29:04.000000000 +0100 @@ -344,6 +344,11 @@ This <img/> <img src="../images/testimg.gif" valign="+4"/> is aligned <b>+4</b>.<br/><br/> This <img/> <img src="../images/testimg.gif" width="10"/> has width <b>10</b>.<br/><br/> </para>""","Inline images") +disc("""The $src$ attribute can refer to a remote location eg $src="https://www.reportlab.com/images/logo.gif"$. By default we set $rl_config.trustedShemes$ to $['https','http', 'file', 'data', 'ftp']$ and +$rl_config.trustedHosts=None$ the latter meaning no-restriction. You can modify these variables using one of the override files eg $reportlab_settings.py$ or $~/.reportlab_settings$. Or as comma seprated strings in the +environment variables $RL_trustedSchemes$ & $RL_trustedHosts$. Note that the $trustedHosts$ values may contain <b>glob</b> wild cars so <i>*.reportlab.com</i> will match the obvious domains. +<br/><span color="red"><b>*NB*</b></span> use of <i>trustedHosts</i> and or <i>trustedSchemes</i> may not control behaviour & actions when $URI$ patterns +are detected by the viewer application.""") heading3("The $<u>$ & $<strike>$ tags") disc("""These tags can be used to carry out explicit underlineing or strikethroughs. These tags have diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/setup.py new/reportlab-3.5.56/setup.py --- old/reportlab-3.5.51/setup.py 2020-09-18 15:27:00.000000000 +0200 +++ new/reportlab-3.5.56/setup.py 2020-12-01 17:29:04.000000000 +0100 @@ -1,6 +1,6 @@ #Copyright ReportLab Europe Ltd. 2000-2017 #see license.txt for license details -__version__='3.5.48' +__version__='3.5.56' import os, sys, glob, shutil, re def specialOption(n): v = False @@ -631,10 +631,10 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', ], #this probably only works for setuptools, but distutils seems to ignore it diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/__init__.py new/reportlab-3.5.56/src/reportlab/__init__.py --- old/reportlab-3.5.51/src/reportlab/__init__.py 2020-09-24 15:27:24.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/__init__.py 2020-12-01 17:29:04.000000000 +0100 @@ -1,16 +1,17 @@ #Copyright ReportLab Europe Ltd. 2000-2018 #see license.txt for license details __doc__="""The Reportlab PDF generation library.""" -Version = "3.5.51" +Version = "3.5.56" __version__=Version -__date__='20200924' +__date__='20201201' import sys, os -if sys.version_info[0:2]!=(2, 7) and sys.version_info<(3, 5): - raise ImportError("""reportlab requires Python 2.7+ or 3.5+; 3.0-3.4 are not supported. +__min_python_version__ = (3,6) +if sys.version_info[0:2]!=(2, 7) and sys.version_info< __min_python_version__: + raise ImportError("""reportlab requires Python 2.7+ or %s.%s+; other versions are unsupported. If you want to try with other python versions edit line 10 of reportlab/__init__ -to remove this error.""") +to remove this error.""" % (__min_python_version__)) #define these early in reportlab's life isPy3 = sys.version_info[0]==3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/graphics/barcode/__init__.py new/reportlab-3.5.56/src/reportlab/graphics/barcode/__init__.py --- old/reportlab-3.5.51/src/reportlab/graphics/barcode/__init__.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/graphics/barcode/__init__.py 2020-10-01 19:30:51.000000000 +0200 @@ -69,6 +69,10 @@ BarcodeECC200DataMatrix, ): registerWidget(widget) + from reportlab.graphics.barcode import dmtx + if dmtx.pylibdmtx: + registerWidget(dmtx.DataMatrixWidget) + _reset() from reportlab.rl_config import register_reset register_reset(_reset) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/graphics/barcode/common.py new/reportlab-3.5.56/src/reportlab/graphics/barcode/common.py --- old/reportlab-3.5.51/src/reportlab/graphics/barcode/common.py 2020-09-02 14:34:06.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/graphics/barcode/common.py 2020-10-01 19:30:51.000000000 +0200 @@ -177,6 +177,12 @@ getattr(canv,func)(x,y,text) canv.restoreState() + def _checkVal(self, name, v, allowed): + if v not in allowed: + raise ValueError('%s attribute %s is invalid %r\nnot in allowed %r' % ( + self.__class__.__name__, name, v, allowed)) + return v + class MultiWidthBarcode(Barcode): """Base for variable-bar-width codes like Code93 and Code128""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/graphics/barcode/dmtx.py new/reportlab-3.5.56/src/reportlab/graphics/barcode/dmtx.py --- old/reportlab-3.5.51/src/reportlab/graphics/barcode/dmtx.py 1970-01-01 01:00:00.000000000 +0100 +++ new/reportlab-3.5.56/src/reportlab/graphics/barcode/dmtx.py 2020-10-01 19:30:51.000000000 +0200 @@ -0,0 +1,273 @@ +try: + from pylibdmtx import pylibdmtx +except ImportError: + pylibdmtx = None + __all__ = () +else: + __all__=('DataMatrix',) + +from reportlab.graphics.barcode.common import Barcode +from reportlab.lib.utils import asBytes +from reportlab.platypus.paraparser import _num as paraparser_num +from reportlab.graphics.widgetbase import Widget +from reportlab.lib.validators import isColor, isString, isColorOrNone, isNumber, isBoxAnchor +from reportlab.lib.attrmap import AttrMap, AttrMapValue +from reportlab.lib.colors import toColor +from reportlab.graphics.shapes import Group, Rect + +def _numConv(x): + return x if isinstance(x,(int,float)) else paraparser_num(x) + +class _DMTXCheck(object): + @classmethod + def pylibdmtx_check(cls): + if not pylibdmtx: + raise ValueError('The %s class requires package pylibdmtx' % cls.__name__) + +class DataMatrix(Barcode,_DMTXCheck): + def __init__(self, value='', **kwds): + self.pylibdmtx_check() + self._recalc = True + self.value = value + self.cellSize = kwds.pop('cellSize','5x5') + self.size = kwds.pop('size','SquareAuto') + self.encoding = kwds.pop('encoding','Ascii') + self.anchor = kwds.pop('anchor','sw') + self.color = kwds.pop('color',(0,0,0)) + self.bgColor = kwds.pop('bgColor',None) + self.x = kwds.pop('x',0) + self.y = kwds.pop('y',0) + self.border = kwds.pop('border',5) + + @property + def value(self): + return self._value + + @value.setter + def value(self,v): + self._value = asBytes(v) + self._recalc = True + + @property + def size(self): + return self._size + + @size.setter + def size(self,v): + self._size = self._checkVal('size', v, pylibdmtx.ENCODING_SIZE_NAMES) + self._recalc = True + + @property + def border(self): + return self._border + + @border.setter + def border(self,v): + self._border = _numConv(v) + self._recalc = True + + @property + def x(self): + return self._x + + @x.setter + def x(self,v): + self._x = _numConv(v) + self._recalc = True + + @property + def y(self): + return self._y + + @y.setter + def y(self,v): + self._y = _numConv(v) + self._recalc = True + + @property + def cellSize(self): + return self._cellSize + + @size.setter + def cellSize(self,v): + self._cellSize = v + self._recalc = True + + @property + def encoding(self): + return self._encoding + + @encoding.setter + def encoding(self,v): + self._encoding = self._checkVal('encoding', v, pylibdmtx.ENCODING_SCHEME_NAMES) + self._recalc = True + + @property + def anchor(self): + return self._anchor + + @anchor.setter + def anchor(self,v): + self._anchor = self._checkVal('anchor', v, ('n','ne','e','se','s','sw','w','nw','c')) + self._recalc = True + + def recalc(self): + if not self._recalc: return + data = self._value + size = self._size + encoding = self._encoding + e = pylibdmtx.encode(data, size=size, scheme=encoding) + iW = e.width + iH = e.height + p = e.pixels + iCellSize = 5 + bpp = 3 #bytes per pixel + rowLen = iW*bpp + cellLen = iCellSize*bpp + assert len(p)//rowLen == iH + matrix = list(filter(None, + (''.join( + (('x' if p[j:j+bpp] != b'\xff\xff\xff' else ' ') + for j in range(i,i+rowLen,cellLen))).strip() + for i in range(0,iH*rowLen,rowLen*iCellSize)))) + self._nRows = len(matrix) + self._nCols = len(matrix[-1]) + self._matrix = '\n'.join(matrix) + + cellWidth = self._cellSize + if cellWidth: + cellWidth = cellWidth.split('x') + if len(cellWidth)>2: + raise ValueError('cellSize needs to be distance x distance not %r' % self._cellSize) + elif len(cellWidth)==2: + cellWidth, cellHeight = cellWidth + else: + cellWidth = cellHeight = cellWidth[0] + cellWidth = _numConv(cellWidth) + cellHeight = _numConv(cellHeight) + else: + cellWidth = cellHeight = iCellSize + self._cellWidth = cellWidth + self._cellHeight = cellHeight + self._recalc = False + self._bord = max(self.border,cellWidth,cellHeight) + self._width = cellWidth*self._nCols + 2*self._bord + self._height = cellHeight*self._nRows + 2*self._bord + + @property + def matrix(self): + self.recalc() + return self._matrix + + @property + def width(self): + self.recalc() + return self._width + + @property + def height(self): + self.recalc() + return self._height + + @property + def cellWidth(self): + self.recalc() + return self._cellWidth + + @property + def cellHeight(self): + self.recalc() + return self._cellHeight + + def draw(self): + self.recalc() + canv = self.canv + w = self.width + h = self.height + x = self.x + y = self.y + b = self._bord + + anchor = self.anchor + if anchor in ('nw','n','ne'): + y -= h + elif anchor in ('c','e','w'): + y -= h//2 + if anchor in ('ne','e','se'): + x -= w + elif anchor in ('n','c','s'): + x -= w//2 + + canv.saveState() + if self.bgColor: + canv.setFillColor(toColor(self.bgColor)) + canv.rect(x, y-h, w, h, fill=1, stroke=0) + canv.setFillColor(toColor(self.color)) + canv.setStrokeColor(None) + + cellWidth = self.cellWidth + cellHeight = self.cellHeight + yr = y - b - cellHeight + x += b + for row in self.matrix.split('\n'): + xr = x + for c in row: + if c=='x': + canv.rect(xr, yr, cellWidth, cellHeight, fill=1, stroke=0) + xr += cellWidth + yr -= cellHeight + canv.restoreState() + + +class DataMatrixWidget(Widget,_DMTXCheck): + codeName = "DataMatrix" + _attrMap = AttrMap( + BASE = Widget, + value = AttrMapValue(isString, desc='Datamatrix data'), + x = AttrMapValue(isNumber, desc='x-coord'), + y = AttrMapValue(isNumber, desc='y-coord'), + color = AttrMapValue(isColor, desc='foreground color'), + bgColor = AttrMapValue(isColorOrNone, desc='background color'), + encoding = AttrMapValue(isString, desc='encoding'), + size = AttrMapValue(isString, desc='size'), + cellSize = AttrMapValue(isString, desc='cellSize'), + anchor = AttrMapValue(isBoxAnchor, desc='anchor pooint for x,y'), + ) + + _defaults = dict( + x = ('0',_numConv), + y = ('0',_numConv), + color = ('black',toColor), + bgColor = (None,lambda _: toColor(_) if _ is not None else _), + encoding = ('Ascii',None), + size = ('SquareAuto',None), + cellSize = ('5x5',None), + anchor = ('sw', None), + ) + def __init__(self,value='Hello Cruel World!', **kwds): + self.pylibdmtx_check() + self.value = value + for k,(d,c) in self._defaults.items(): + v = kwds.pop(k,d) + if c: v = c(v) + setattr(self,k,v) + + def rect(self, x, y, w, h, fill=1, stroke=0): + self._gadd(Rect(x,y,w,h,strokeColor=None,fillColor=self._fillColor)) + + def saveState(self,*args,**kwds): + pass + + restoreState = setStrokeColor = saveState + + def setFillColor(self,c): + self._fillColor = c + + def draw(self): + m = DataMatrix(value=self.value,**{k: getattr(self,k) for k in self._defaults}) + m.canv = self + m.y += m.height + g = Group() + self._gadd = g.add + m.draw() + return g diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/graphics/barcode/test.py new/reportlab-3.5.56/src/reportlab/graphics/barcode/test.py --- old/reportlab-3.5.51/src/reportlab/graphics/barcode/test.py 2019-10-24 17:16:28.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/graphics/barcode/test.py 2020-10-01 19:30:51.000000000 +0200 @@ -10,6 +10,7 @@ from reportlab.graphics.barcode.usps import * from reportlab.graphics.barcode.usps4s import USPS_4State from reportlab.graphics.barcode.qr import QrCodeWidget +from reportlab.graphics.barcode.dmtx import DataMatrixWidget, pylibdmtx from reportlab.platypus import Spacer, SimpleDocTemplate, Table, TableStyle, Preformatted, PageBreak @@ -114,6 +115,11 @@ storyAdd(Paragraph('QR', styleN)) storyAdd(createBarcodeDrawing('QR', value='01234567094987654321',x=30,y=50)) + def addCross(d,x,y,w=5,h=5, strokeColor='black', strokeWidth=0.5): + w *= 0.5 + h *= 0.5 + d.add(Line(x-w,y,x+w,y,strokeWidth=0.5,strokeColor=colors.blue)) + d.add(Line(x, y-h, x, y+h,strokeWidth=0.5,strokeColor=colors.blue)) storyAdd(Paragraph('QR in drawing at (0,0)', styleN)) d = Drawing(100,100) d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) @@ -123,8 +129,7 @@ storyAdd(Paragraph('QR in drawing at (10,10)', styleN)) d = Drawing(100,100) d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) - d.add(Line(7.5,10,12.5,10,strokeWidth=0.5,strokeColor=colors.blue)) - d.add(Line(10,7.5, 10, 12.5,strokeWidth=0.5,strokeColor=colors.blue)) + addCross(d,10,10) d.add(QrCodeWidget(value='01234567094987654321',x=10,y=10)) storyAdd(d) @@ -133,6 +138,28 @@ storyAdd(Paragraph('Label Size', styleN)) storyAdd(XBox((1.75)*inch, .5 * inch, '1/2x1-3/4"')) + + if pylibdmtx: + storyAdd(PageBreak()) + storyAdd(Paragraph('DataMatrix in drawing at (10,10)', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,10,10) + d.add(DataMatrixWidget(value='1234567890',x=10,y=10)) + storyAdd(d) + storyAdd(Paragraph('DataMatrix in drawing at (10,10)', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,10,10) + d.add(DataMatrixWidget(value='1234567890',x=10,y=10,color='black',bgColor='lime')) + storyAdd(d) + + storyAdd(Paragraph('DataMatrix in drawing at (90,90) anchor=ne', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,90,90) + d.add(DataMatrixWidget(value='1234567890',x=90,y=90,color='darkblue',bgColor='yellow', anchor='ne')) + storyAdd(d) SimpleDocTemplate('out.pdf').build(story) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/graphics/renderPM.py new/reportlab-3.5.56/src/reportlab/graphics/renderPM.py --- old/reportlab-3.5.51/src/reportlab/graphics/renderPM.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/graphics/renderPM.py 2020-10-26 09:33:02.000000000 +0100 @@ -306,7 +306,7 @@ def toPIL(self): im = _getImage().new('RGB', size=(self._gs.width, self._gs.height)) - getattr(im,'frombytes',getattr(im,'fromstring'))(self._gs.pixBuf) + (getattr(im,'frombytes',None) or getattr(im,'fromstring'))(self._gs.pixBuf) return im def saveToFile(self,fn,fmt=None): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/graphics/shapes.py new/reportlab-3.5.56/src/reportlab/graphics/shapes.py --- old/reportlab-3.5.51/src/reportlab/graphics/shapes.py 2020-06-03 11:03:01.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/graphics/shapes.py 2020-12-01 17:29:04.000000000 +0100 @@ -767,6 +767,10 @@ #check a substring if str(err).find('not all arguments converted') < 0: raise + if outDir is None: + outDir = getattr(self,'outDir',None) + if hasattr(outDir,'__call__'): + outDir = outDir(self) if os.path.isabs(fnRoot): outDir, fnRoot = os.path.split(fnRoot) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/lib/utils.py new/reportlab-3.5.56/src/reportlab/lib/utils.py --- old/reportlab-3.5.51/src/reportlab/lib/utils.py 2020-02-26 15:58:03.000000000 +0100 +++ new/reportlab-3.5.56/src/reportlab/lib/utils.py 2020-10-29 13:35:05.000000000 +0100 @@ -609,59 +609,73 @@ if 'b' not in mode and os.linesep!='\n': s = s.replace(os.linesep,'\n') return getBytesIO(s) -if not isPy3: - import urllib2, urllib - urlopen=urllib2.urlopen - def datareader(url,opener=urllib.URLopener().open): - return opener(url).read() - del urllib, urllib2 -else: - from urllib.request import urlopen - from urllib.parse import unquote - import base64 - #copied here from urllib.URLopener.open_data because - # 1) they want to remove it - # 2) the existing one is borken - def datareader(url, unquote=unquote, decodebytes=base64.decodebytes): - """Use "data" URL.""" - # ignore POSTed data - # - # syntax of data URLs: - # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data - # mediatype := [ type "/" subtype ] *( ";" parameter ) - # data := *urlchar - # parameter := attribute "=" value +def open_for_read(name,mode='b'): + #auto initialized function` + if not isPy3: + import urllib2, urllib + from urlparse import urlparse + urlopen=urllib2.urlopen + def datareader(url,opener=urllib.URLopener().open): + return opener(url).read() + del urllib, urllib2 + else: + from urllib.request import urlopen + from urllib.parse import unquote, urlparse + #copied here from urllib.URLopener.open_data because + # 1) they want to remove it + # 2) the existing one is borken + def datareader(url, unquote=unquote): + """Use "data" URL.""" + # ignore POSTed data + # + # syntax of data URLs: + # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + # mediatype := [ type "/" subtype ] *( ";" parameter ) + # data := *urlchar + # parameter := attribute "=" value + try: + typ, data = url.split(',', 1) + except ValueError: + raise IOError('data error', 'bad data URL') + if not typ: + typ = 'text/plain;charset=US-ASCII' + semi = typ.rfind(';') + if semi >= 0 and '=' not in typ[semi:]: + encoding = typ[semi+1:] + typ = typ[:semi] + else: + encoding = '' + if encoding == 'base64': + # XXX is this encoding/decoding ok? + data = base64_decodebytes(data.encode('ascii')) + else: + data = unquote(data).encode('latin-1') + return data + from reportlab.rl_config import trustedHosts, trustedSchemes + if trustedHosts: + import re, fnmatch + def xre(s): + s = fnmatch.translate(s) + return s[4:-3] if s.startswith('(?s:') else s[:-7] + trustedHosts = re.compile(''.join(('^(?:', + '|'.join(map(xre,trustedHosts)), + ')\\Z'))) + def open_for_read(name,mode='b'): + '''attempt to open a file or URL for reading''' + if hasattr(name,'read'): return name try: - typ, data = url.split(',', 1) - except ValueError: - raise IOError('data error', 'bad data URL') - if not typ: - typ = 'text/plain;charset=US-ASCII' - semi = typ.rfind(';') - if semi >= 0 and '=' not in typ[semi:]: - encoding = typ[semi+1:] - typ = typ[:semi] - else: - encoding = '' - if encoding == 'base64': - # XXX is this encoding/decoding ok? - data = decodebytes(data.encode('ascii')) - else: - data = unquote(data).encode('latin-1') - return data - del unquote, base64 - -def open_for_read(name,mode='b', urlopen=urlopen, datareader=datareader): - '''attempt to open a file or URL for reading''' - if hasattr(name,'read'): return name - try: - return open_for_read_by_name(name,mode) - except: - try: - return getBytesIO(datareader(name) if name[:5].lower()=='data:' else urlopen(name).read()) + return open_for_read_by_name(name,mode) except: - raise IOError('Cannot open resource "%s"' % name) -del urlopen, datareader + try: + if trustedHosts is not None: + purl = urlparse(name) + if purl[0] and not ((purl[0] in ('data','file') or trustedHosts.match(purl[1])) and (purl[0] in trustedSchemes)): + raise ValueError('Attempted untrusted host access') + return getBytesIO(datareader(name) if name[:5].lower()=='data:' else urlopen(name).read()) + except: + raise IOError('Cannot open resource "%s"' % name) + globals()['open_for_read'] = open_for_read + return open_for_read(name,mode) def open_and_read(name,mode='b'): f = open_for_read(name,mode) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/lib/validators.py new/reportlab-3.5.56/src/reportlab/lib/validators.py --- old/reportlab-3.5.51/src/reportlab/lib/validators.py 2020-02-07 15:10:09.000000000 +0100 +++ new/reportlab-3.5.56/src/reportlab/lib/validators.py 2020-10-01 19:30:51.000000000 +0200 @@ -336,6 +336,7 @@ self._dpLen = dpLen return self + isAuto = Auto() isBoolean = _isBoolean() isString = _isString() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/pdfbase/acroform.py new/reportlab-3.5.56/src/reportlab/pdfbase/acroform.py --- old/reportlab-3.5.51/src/reportlab/pdfbase/acroform.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/pdfbase/acroform.py 2020-10-26 09:33:02.000000000 +0100 @@ -1,5 +1,6 @@ __all__=('AcroForm',) -from reportlab.pdfbase.pdfdoc import PDFObject, PDFArray, PDFDictionary, PDFString, pdfdocEnc, PDFName, PDFStream, PDFStreamFilterZCompress, escapePDF +from reportlab.pdfbase.pdfdoc import (PDFObject, PDFArray, PDFDictionary, PDFString, pdfdocEnc, + PDFName, PDFStream, PDFStreamFilterZCompress, escapePDF) from reportlab.pdfgen.canvas import Canvas from reportlab.pdfbase.pdfmetrics import stringWidth from reportlab.lib.colors import Color, CMYKColor, Whiter, Blacker, opaqueColor @@ -158,6 +159,7 @@ self._refMap = {} self._pdfdocenc = {} self.sigFlags = None + self.extras = {} @property def canv(self): @@ -179,6 +181,7 @@ F = [self.fontRef(f) for f in FK] d['DA'] = PDFString('/%s 0 Tf 0 g' % FK[0]) d['DR'] = PDFFromString('<< /Encoding\n<<\n/RLAFencoding\n%s\n>>\n%s\n>>' % (self.encRefStr,'\n'.join(F))) + d.update(self.extras) r = PDFDictionary(d).format(doc) return r diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/pdfgen/canvas.py new/reportlab-3.5.56/src/reportlab/pdfgen/canvas.py --- old/reportlab-3.5.51/src/reportlab/pdfgen/canvas.py 2020-09-18 15:27:00.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/pdfgen/canvas.py 2020-10-02 17:51:34.000000000 +0200 @@ -1022,6 +1022,7 @@ else: self._code = [] # ready for more... self._psCommandsAfterPage = [] + self._psCommandsBeforePage = [] self._currentPageHasImages = 1 # for safety... self._formsinuse = [] self._annotationrefs = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/platypus/doctemplate.py new/reportlab-3.5.56/src/reportlab/platypus/doctemplate.py --- old/reportlab-3.5.51/src/reportlab/platypus/doctemplate.py 2020-09-02 14:34:06.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/platypus/doctemplate.py 2020-10-26 09:33:02.000000000 +0100 @@ -600,7 +600,11 @@ def handle_documentBegin(self): '''implement actions at beginning of document''' self._hanging = [PageBegin] - self.pageTemplate = self.pageTemplates[self._firstPageTemplateIndex] + if isinstance(self._firstPageTemplateIndex,list): + self.handle_nextPageTemplate(self._firstPageTemplateIndex) + self._setPageTemplate() + else: + self.pageTemplate = self.pageTemplates[self._firstPageTemplateIndex] self.page = 0 self.beforeDocument() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/platypus/flowables.py new/reportlab-3.5.56/src/reportlab/platypus/flowables.py --- old/reportlab-3.5.51/src/reportlab/platypus/flowables.py 2020-08-18 14:00:34.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/platypus/flowables.py 2020-10-26 09:33:02.000000000 +0100 @@ -570,6 +570,9 @@ def __init__(self,nextTemplate=None): self.nextTemplate = nextTemplate + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__,repr(self.nextTemplate) if self.nextTemplate else '') + class SlowPageBreak(PageBreak): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/rl_config.py new/reportlab-3.5.56/src/reportlab/rl_config.py --- old/reportlab-3.5.51/src/reportlab/rl_config.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/rl_config.py 2020-10-29 13:35:05.000000000 +0100 @@ -104,8 +104,12 @@ globals()[k] = list(filter(rl_isdir,globals()[k])) else: v = _SAVED[k] - if isinstance(v,(int,float)): conv = type(v) - elif k=='defaultPageSize': conv = lambda v,M=pagesizes: getattr(M,v) + if isinstance(v,(int,float)): + conv = type(v) + elif k=='defaultPageSize': + conv = lambda v,M=pagesizes: getattr(M,v) + elif k in ('trustedHosts','trustedSchemes'): + conv = lambda v: None if v is None else [y for y in [x.strip() for x in v.split(',')] if y] if isinstance(v,str) else v else: conv = None _setOpt(k,v,conv) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab/rl_settings.py new/reportlab-3.5.56/src/reportlab/rl_settings.py --- old/reportlab-3.5.51/src/reportlab/rl_settings.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab/rl_settings.py 2020-10-29 13:35:05.000000000 +0100 @@ -65,7 +65,9 @@ hyphenationMinWordLength reserveTTFNotdef documentLang -encryptionStrength'''.split()) +encryptionStrength +trustedHosts +trustedSchemes'''.split()) allowTableBoundsErrors = 1 # set to 0 to die on too large elements in tables in debug (recommend 1 for production use) shapeChecking = 1 @@ -154,7 +156,11 @@ #helps to fix bug in edge documentLang=None #pdf document catalog Lang value xx-xx not ee_xx encryptionStrength=40 #the bits for standard encryption 40, 128 or 256 (AES) - +trustedHosts=None #set to a list of trusted for access hosts None means + #all are trusted glob patterns eg *.reportlab.com are + #allowed. In environment use a comma separated string. +trustedSchemes=['file', 'rml', 'data', 'https', #these url schemes are trusted + 'http', 'ftp'] # places to look for T1Font information T1SearchPath = ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab.egg-info/PKG-INFO new/reportlab-3.5.56/src/reportlab.egg-info/PKG-INFO --- old/reportlab-3.5.51/src/reportlab.egg-info/PKG-INFO 2020-09-24 15:27:52.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab.egg-info/PKG-INFO 2020-12-01 17:29:31.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: reportlab -Version: 3.5.51 +Version: 3.5.56 Summary: The Reportlab Toolkit Home-page: http://www.reportlab.com/ Author: Andy Robinson, Robin Becker, the ReportLab team and the community @@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/reportlab.egg-info/SOURCES.txt new/reportlab-3.5.56/src/reportlab.egg-info/SOURCES.txt --- old/reportlab-3.5.51/src/reportlab.egg-info/SOURCES.txt 2020-09-24 15:27:52.000000000 +0200 +++ new/reportlab-3.5.56/src/reportlab.egg-info/SOURCES.txt 2020-12-01 17:29:31.000000000 +0100 @@ -124,6 +124,7 @@ src/reportlab/graphics/barcode/code39.py src/reportlab/graphics/barcode/code93.py src/reportlab/graphics/barcode/common.py +src/reportlab/graphics/barcode/dmtx.py src/reportlab/graphics/barcode/eanbc.py src/reportlab/graphics/barcode/ecc200datamatrix.py src/reportlab/graphics/barcode/fourstate.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/rl_addons/renderPM/gt1/gt1-misc.h new/reportlab-3.5.56/src/rl_addons/renderPM/gt1/gt1-misc.h --- old/reportlab-3.5.51/src/rl_addons/renderPM/gt1/gt1-misc.h 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/rl_addons/renderPM/gt1/gt1-misc.h 2020-12-01 17:29:04.000000000 +0100 @@ -4,7 +4,7 @@ #define __GT1_MISC_H__ #include <stdlib.h> /* for malloc, etc. */ -#if defined(macintosh) || defined (__linux__) || defined(__FreeBSD_kernel__) || (__GNU__) +#if defined(macintosh) || defined(__APPLE__) || defined (__linux__) || defined(__FreeBSD_kernel__) || defined(__GNU__) # include <string.h> /* for memcpy() */ #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/rl_addons/renderPM/gt1/gt1-namecontext.c new/reportlab-3.5.56/src/rl_addons/renderPM/gt1/gt1-namecontext.c --- old/reportlab-3.5.51/src/rl_addons/renderPM/gt1/gt1-namecontext.c 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/rl_addons/renderPM/gt1/gt1-namecontext.c 2020-12-01 17:29:04.000000000 +0100 @@ -3,7 +3,7 @@ #include "gt1-misc.h" #include "gt1-namecontext.h" -#if defined(_WIN32) || defined(macintosh) +#if defined(_WIN32) || defined(macintosh) || defined(__APPLE__) # include <string.h> #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/rl_addons/renderPM/gt1/parseAFM.c new/reportlab-3.5.56/src/rl_addons/renderPM/gt1/parseAFM.c --- old/reportlab-3.5.51/src/rl_addons/renderPM/gt1/parseAFM.c 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/rl_addons/renderPM/gt1/parseAFM.c 2020-12-01 17:29:04.000000000 +0100 @@ -71,7 +71,7 @@ #include <stdio.h> #include <stdlib.h> #include <errno.h> -#if !defined(_WIN32) && !defined(macintosh) +#if !defined(_WIN32) && !defined(macintosh) && !defined(__APPLE__) # include <sys/file.h> #endif #include <math.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/src/rl_addons/renderPM/libart_lgpl/config.h new/reportlab-3.5.56/src/rl_addons/renderPM/libart_lgpl/config.h --- old/reportlab-3.5.51/src/rl_addons/renderPM/libart_lgpl/config.h 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/src/rl_addons/renderPM/libart_lgpl/config.h 2020-12-01 17:29:04.000000000 +0100 @@ -3,7 +3,7 @@ /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ -#ifdef macintosh +#if defined(macintosh) || defined(__APPLE__) # define WORDS_BIGENDIAN #else /* #undef WORDS_BIGENDIAN */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/tests/runAll.py new/reportlab-3.5.56/tests/runAll.py --- old/reportlab-3.5.51/tests/runAll.py 2020-01-28 14:14:57.000000000 +0100 +++ new/reportlab-3.5.56/tests/runAll.py 2020-10-29 13:35:05.000000000 +0100 @@ -11,6 +11,7 @@ #directory and run this directly if __name__=='__main__': P=[] + os.environ['RL_trustedHosts'] = '*.reportlab.com' try: from reportlab.lib.testutils import setOutDir except ImportError: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/tests/test_graphics_barcode.py new/reportlab-3.5.56/tests/test_graphics_barcode.py --- old/reportlab-3.5.51/tests/test_graphics_barcode.py 2019-10-01 17:38:11.000000000 +0200 +++ new/reportlab-3.5.56/tests/test_graphics_barcode.py 2020-10-26 09:33:02.000000000 +0100 @@ -5,7 +5,266 @@ """ from reportlab.lib.testutils import setOutDir,makeSuiteForClasses, outputfile, printLocation setOutDir(__name__) -import unittest, os, sys, glob +import unittest, os, sys, glob, time + +from reportlab import Version as __RL_Version__ +from reportlab.graphics.barcode.common import * +from reportlab.graphics.barcode.code39 import * +from reportlab.graphics.barcode.code93 import * +from reportlab.graphics.barcode.code128 import * +from reportlab.graphics.barcode.usps import * +from reportlab.graphics.barcode.usps4s import USPS_4State +from reportlab.graphics.barcode.qr import QrCodeWidget +from reportlab.graphics.barcode.dmtx import DataMatrixWidget, pylibdmtx + + +from reportlab.platypus import Spacer, SimpleDocTemplate, Table, TableStyle, Preformatted, PageBreak +from reportlab.lib.units import inch, cm +from reportlab.lib import colors +from reportlab.lib.utils import TimeStamp + +from reportlab.pdfgen.canvas import Canvas +from reportlab.lib.styles import getSampleStyleSheet +from reportlab.platypus.paragraph import Paragraph +from reportlab.platypus.frames import Frame +from reportlab.platypus.flowables import XBox, KeepTogether +from reportlab.graphics.shapes import Drawing, Rect, Line + +from reportlab.graphics.barcode import getCodes, getCodeNames, createBarcodeDrawing, createBarcodeImageInMemory +def run(fileName): + styles = getSampleStyleSheet() + styleN = styles['Normal'] + styleH = styles['Heading1'] + story = [] + storyAdd = story.append + + #for codeNames in code + storyAdd(Paragraph('I2of5', styleN)) + storyAdd(I2of5(1234, barWidth = inch*0.02, checksum=0)) + + storyAdd(Paragraph('MSI', styleN)) + storyAdd(MSI(1234)) + + storyAdd(Paragraph('Codabar', styleN)) + storyAdd(Codabar("A012345B", barWidth = inch*0.02)) + + storyAdd(Paragraph('Code 11', styleN)) + storyAdd(Code11("01234545634563")) + + storyAdd(Paragraph('Code 39', styleN)) + storyAdd(Standard39("A012345B%R")) + + storyAdd(Paragraph('Extended Code 39', styleN)) + storyAdd(Extended39("A012345B}")) + + storyAdd(Paragraph('Code93', styleN)) + storyAdd(Standard93("CODE 93")) + + storyAdd(Paragraph('Extended Code93', styleN)) + storyAdd(Extended93("L@@K! Code 93 :-)")) #, barWidth=0.005 * inch)) + + storyAdd(Paragraph('Code 128', styleN)) + storyAdd(Code128("AB-12345678")) + + storyAdd(Paragraph('Code 128 Auto', styleN)) + storyAdd(Code128Auto("AB-12345678")) + + storyAdd(Paragraph('USPS FIM', styleN)) + storyAdd(FIM("A")) + + storyAdd(Paragraph('USPS POSTNET', styleN)) + storyAdd(POSTNET('78247-1043')) + + storyAdd(Paragraph('USPS 4 State', styleN)) + storyAdd(USPS_4State('01234567094987654321','01234567891')) + + from reportlab.graphics.barcode import createBarcodeDrawing + + storyAdd(Paragraph('EAN13', styleN)) + storyAdd(createBarcodeDrawing('EAN13', value='123456789012')) + + storyAdd(Paragraph('EAN13 quiet=False', styleN)) + storyAdd(createBarcodeDrawing('EAN13', value='123456789012', quiet=False)) + + storyAdd(Paragraph('EAN8', styleN)) + storyAdd(createBarcodeDrawing('EAN8', value='1234567')) + + storyAdd(PageBreak()) + + storyAdd(Paragraph('EAN5 price=True', styleN)) + storyAdd(createBarcodeDrawing('EAN5', value='11299', price=True)) + + storyAdd(Paragraph('EAN5 price=True quiet=False', styleN)) + storyAdd(createBarcodeDrawing('EAN5', value='11299', price=True, quiet=False)) + + storyAdd(Paragraph('EAN5 price=False', styleN)) + storyAdd(createBarcodeDrawing('EAN5', value='11299', price=False)) + + storyAdd(Paragraph('ISBN alone', styleN)) + storyAdd(createBarcodeDrawing('ISBN', value='9781565924796')) + + storyAdd(Paragraph('ISBN with ean5 price', styleN)) + storyAdd(createBarcodeDrawing('ISBN', value='9781565924796',price='01299')) + + storyAdd(Paragraph('ISBN with ean5 price, quiet=False', styleN)) + storyAdd(createBarcodeDrawing('ISBN', value='9781565924796',price='01299',quiet=False)) + + storyAdd(Paragraph('UPCA', styleN)) + storyAdd(createBarcodeDrawing('UPCA', value='03600029145')) + + storyAdd(Paragraph('USPS_4State', styleN)) + storyAdd(createBarcodeDrawing('USPS_4State', value='01234567094987654321',routing='01234567891')) + + storyAdd(Paragraph('QR', styleN)) + storyAdd(createBarcodeDrawing('QR', value='01234567094987654321')) + + storyAdd(Paragraph('QR', styleN)) + storyAdd(createBarcodeDrawing('QR', value='01234567094987654321',x=30,y=50)) + + def addCross(d,x,y,w=5,h=5, strokeColor='black', strokeWidth=0.5): + w *= 0.5 + h *= 0.5 + d.add(Line(x-w,y,x+w,y,strokeWidth=0.5,strokeColor=colors.blue)) + d.add(Line(x, y-h, x, y+h,strokeWidth=0.5,strokeColor=colors.blue)) + storyAdd(Paragraph('QR in drawing at (0,0)', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + d.add(QrCodeWidget(value='01234567094987654321')) + storyAdd(d) + + storyAdd(Paragraph('QR in drawing at (10,10)', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,10,10) + d.add(QrCodeWidget(value='01234567094987654321',x=10,y=10)) + storyAdd(d) + + storyAdd(Paragraph('Label Size', styleN)) + storyAdd(XBox((2.0 + 5.0/8.0)*inch, 1 * inch, '1x2-5/8"')) + + storyAdd(Paragraph('Label Size', styleN)) + storyAdd(XBox((1.75)*inch, .5 * inch, '1/2x1-3/4"')) + + if pylibdmtx: + storyAdd(PageBreak()) + storyAdd(Paragraph('DataMatrix in drawing at (10,10)', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,10,10) + d.add(DataMatrixWidget(value='1234567890',x=10,y=10)) + storyAdd(d) + storyAdd(Paragraph('DataMatrix in drawing at (10,10)', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,10,10) + d.add(DataMatrixWidget(value='1234567890',x=10,y=10,color='black',bgColor='lime')) + storyAdd(d) + + storyAdd(Paragraph('DataMatrix in drawing at (90,90) anchor=ne', styleN)) + d = Drawing(100,100) + d.add(Rect(0,0,100,100,strokeWidth=1,strokeColor=colors.red,fillColor=None)) + addCross(d,90,90) + d.add(DataMatrixWidget(value='1234567890',x=90,y=90,color='darkblue',bgColor='yellow', anchor='ne')) + storyAdd(d) + + + SimpleDocTemplate(fileName).build(story) + +def fullTest(fileName): + """Creates large-ish test document with a variety of parameters""" + + story = [] + + styles = getSampleStyleSheet() + styleN = styles['Normal'] + styleH = styles['Heading1'] + styleH2 = styles['Heading2'] + story = [] + + story.append(Paragraph('ReportLab %s Barcode Test Suite - full output' % __RL_Version__,styleH)) + story.append(Paragraph('Generated at %s' % TimeStamp().asctime, styleN)) + + story.append(Paragraph('About this document', styleH2)) + story.append(Paragraph('History and Status', styleH2)) + + story.append(Paragraph(""" + This is the test suite and docoumentation for the ReportLab open source barcode API. + """, styleN)) + + story.append(Paragraph(""" + Several years ago Ty Sarna contributed a barcode module to the ReportLab community. + Several of the codes were used by him in hiw work and to the best of our knowledge + this was correct. These were written as flowable objects and were available in PDFs, + but not in our graphics framework. However, we had no knowledge of barcodes ourselves + and did not advertise or extend the package. + """, styleN)) + + story.append(Paragraph(""" + We "wrapped" the barcodes to be usable within our graphics framework; they are now available + as Drawing objects which can be rendered to EPS files or bitmaps. For the last 2 years this + has been available in our Diagra and Report Markup Language products. However, we did not + charge separately and use was on an "as is" basis. + """, styleN)) + + story.append(Paragraph(""" + A major licensee of our technology has kindly agreed to part-fund proper productisation + of this code on an open source basis in Q1 2006. This has involved addition of EAN codes + as well as a proper testing program. Henceforth we intend to publicise the code more widely, + gather feedback, accept contributions of code and treat it as "supported". + """, styleN)) + + story.append(Paragraph(""" + This involved making available both downloads and testing resources. This PDF document + is the output of the current test suite. It contains codes you can scan (if you use a nice sharp + laser printer!), and will be extended over coming weeks to include usage examples and notes on + each barcode and how widely tested they are. This is being done through documentation strings in + the barcode objects themselves so should always be up to date. + """, styleN)) + + story.append(Paragraph('Usage examples', styleH2)) + story.append(Paragraph(""" + To be completed + """, styleN)) + + story.append(Paragraph('The codes', styleH2)) + story.append(Paragraph(""" + Below we show a scannable code from each barcode, with and without human-readable text. + These are magnified about 2x from the natural size done by the original author to aid + inspection. This will be expanded to include several test cases per code, and to add + explanations of checksums. Be aware that (a) if you enter numeric codes which are too + short they may be prefixed for you (e.g. "123" for an 8-digit code becomes "00000123"), + and that the scanned results and readable text will generally include extra checksums + at the end. + """, styleN)) + + codeNames = getCodeNames() + from reportlab.lib.utils import flatten + width = [float(x[8:]) for x in sys.argv if x.startswith('--width=')] + height = [float(x[9:]) for x in sys.argv if x.startswith('--height=')] + isoScale = [int(x[11:]) for x in sys.argv if x.startswith('--isoscale=')] + options = {} + if width: options['width'] = width[0] + if height: options['height'] = height[0] + if isoScale: options['isoScale'] = isoScale[0] + scales = [x[8:].split(',') for x in sys.argv if x.startswith('--scale=')] + scales = list(map(float,scales and flatten(scales) or [1])) + scales = list(map(float,scales and flatten(scales) or [1])) + for scale in scales: + story.append(PageBreak()) + story.append(Paragraph('Scale = %.1f'%scale, styleH2)) + story.append(Spacer(36, 12)) + for codeName in codeNames: + s = [Paragraph('Code: ' + codeName, styleH2)] + for hr in (0,1): + s.append(Spacer(36, 12)) + dr = createBarcodeDrawing(codeName, humanReadable=hr,**options) + dr.renderScale = scale + s.append(dr) + s.append(Spacer(36, 12)) + s.append(Paragraph('Barcode should say: ' + dr._bc.value, styleN)) + story.append(KeepTogether(s)) + + SimpleDocTemplate(fileName).build(story) try: from reportlab.graphics import _renderPM @@ -18,6 +277,7 @@ @classmethod def setUpClass(cls): cls.outDir = outDir = outputfile('barcode-out') + cls.makeFn = lambda _, fn: os.path.join(outDir,fn) if not os.path.isdir(outDir): os.makedirs(outDir) for x in glob.glob(os.path.join(outDir,'*')): @@ -70,6 +330,18 @@ if not klass.valid(c): raise ValueError('%s.valid(%r) does not match' % (klass.__name__,c)) + def createSample(self,name,memory): + f = open(self.makeFn(name),'wb') + f.write(memory) + f.close() + def test_graphics_barcode(self): + run(self.makeFn('graphics-barcode-out.pdf')) + fullTest(self.makeFn('graphics-barcode-full.pdf')) + self.createSample('test_cbcim.png',createBarcodeImageInMemory('EAN13', value='123456789012')) + self.createSample('test_cbcim.gif',createBarcodeImageInMemory('EAN8', value='1234567', format='gif')) + self.createSample('test_cbcim.pdf',createBarcodeImageInMemory('UPCA', value='03600029145',format='pdf', barHeight=40)) + self.createSample('test_cbcim.tiff',createBarcodeImageInMemory('USPS_4State', value='01234567094987654321',routing='01234567891',format='tiff')) + def makeSuite(): return makeSuiteForClasses(BarcodeWidgetTestCase) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/tests/test_lib_rl_safe_eval.py new/reportlab-3.5.56/tests/test_lib_rl_safe_eval.py --- old/reportlab-3.5.51/tests/test_lib_rl_safe_eval.py 2020-01-14 10:10:36.000000000 +0100 +++ new/reportlab-3.5.56/tests/test_lib_rl_safe_eval.py 2020-10-29 13:35:05.000000000 +0100 @@ -107,7 +107,7 @@ tfmt = 'test_ExpectedTo%s_%%02d' % kind.capitalize() for i, expr in enumerate(_data): if expr is None: - test = genTest('skip','') + continue #test = genTest('skip','') else: expr, kwds = expr if isinstance(expr,tuple) else (expr,{}) test = genTest(kind, expr,**kwds) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/tests/test_platypus_paragraphs.py new/reportlab-3.5.56/tests/test_platypus_paragraphs.py --- old/reportlab-3.5.51/tests/test_platypus_paragraphs.py 2020-06-26 19:07:54.000000000 +0200 +++ new/reportlab-3.5.56/tests/test_platypus_paragraphs.py 2020-10-29 17:06:02.000000000 +0100 @@ -24,7 +24,7 @@ from reportlab.platypus.tableofcontents import TableOfContents from reportlab.platypus.tables import TableStyle, Table from reportlab.platypus.paragraph import Paragraph, _getFragWords, _splitWord, _fragWordSplitRep, ABag, pyphen -from reportlab.rl_config import rtlSupport +from reportlab.rl_config import rtlSupport, trustedHosts, trustedSchemes def myMainPageFrame(canvas, doc): "The page frame used for all PDF documents." @@ -676,6 +676,35 @@ """<unichar code="open('/tmp/test.txt','w').write('Hello from unichar')"/>""", normal) + @unittest.skipUnless(trustedHosts,'s') + def test_badUri0(self): + """test we catch bad hosts""" + normal = getSampleStyleSheet()['BodyText'] + self.assertRaises(Exception,Paragraph, + """<img src='https://badhost.com'/>""", + normal) + self.assertRaises(Exception,Paragraph, + """<img src='https://127.0.0.1:5000'/>""", + normal) + self.assertRaises(Exception,Paragraph, + """<img src='https://www.reportlab.com:5000'/>""", + normal) + + @unittest.skipUnless(trustedSchemes,'s') + def test_badUri1(self): + """test we catch bad schemes""" + normal = getSampleStyleSheet()['BodyText'] + self.assertRaises(Exception,Paragraph, + """<img src='badscheme://badhost.com'/>""", + normal) + self.assertRaises(Exception,Paragraph, + """<img src='badscheme://127.0.0.1:5000'/>""", + normal) + self.assertRaises(Exception,Paragraph, + """<img src='myscheme://www.reportlab.com'/>""", + normal) + + class TwoFrameDocTemplate(BaseDocTemplate): "Define a simple document with two frames per page." @@ -943,6 +972,7 @@ firstLineIndent=0, spaceBefore = 9.5, fontSize=10, + hyphenationLang="en_GB", ) sty1=ParagraphStyle( name="base", @@ -952,13 +982,16 @@ firstLineIndent=0, spaceBefore = 9.5, fontSize=10, + hyphenationLang="en_GB", ) - styN = ParagraphStyle('normal') + styN = ParagraphStyle('normal', hyphenationLang="en_GB") styF=ParagraphStyle( name = 'styF', fontName='Courier', fontSize=8, - leading=9.6) + leading=9.6, + hyphenationLang="en_GB", + ) def box(x, y, aW, h): canv.saveState() canv.setDash(1,1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/reportlab-3.5.51/tests/test_platypus_tables.py new/reportlab-3.5.56/tests/test_platypus_tables.py --- old/reportlab-3.5.51/tests/test_platypus_tables.py 2019-10-30 16:29:25.000000000 +0100 +++ new/reportlab-3.5.56/tests/test_platypus_tables.py 2020-12-01 17:29:04.000000000 +0100 @@ -961,6 +961,20 @@ doc = SimpleDocTemplate(outputfile('test_platypus_tables_issue74.pdf'), showBoundary=0, pagesize=landscape(A4)) doc.build([t]) + data34 = [ + ['001', '01', '02', '03', '04', '05'], + ['002', '01', '02', '03', '04', '05'], + ['003', '01', '02', '03', '04', '05'], + ['004', '01', '02', '03', '04', '05'], + ['005', '01', '02', '03', '04', '05'], + ['006', '01', '02', '03', '04', '05'], + ['007', '01', '02', '03', '04', '05'], + ['008', '01', '02', '03', '04', '05'], + ['009', '01', '02', '03', '04', '05'], + ['010', '01', '02', '03', '04', '05'], + ['011', '01', '02', '03', '04', '05'], + ['012', '01', '02', '03', '04', '05'], + ] def test3(self): '''bug reported by David VanEe <david.va...@convergent.ca>''' story = [] @@ -977,20 +991,7 @@ ('LINEBELOW', (0,1), (-1,1), 2, colors.orange), ('FONT', (2,2), (5,8), 'Times-Bold'), ] - data = [ - ['001', '01', '02', '03', '04', '05'], - ['002', '01', '02', '03', '04', '05'], - ['003', '01', '02', '03', '04', '05'], - ['004', '01', '02', '03', '04', '05'], - ['005', '01', '02', '03', '04', '05'], - ['006', '01', '02', '03', '04', '05'], - ['007', '01', '02', '03', '04', '05'], - ['008', '01', '02', '03', '04', '05'], - ['009', '01', '02', '03', '04', '05'], - ['010', '01', '02', '03', '04', '05'], - ['011', '01', '02', '03', '04', '05'], - ['012', '01', '02', '03', '04', '05'], - ] + data = self.data34 from reportlab.platypus import Paragraph, Table, SimpleDocTemplate, PageBreak from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle styleSheet = getSampleStyleSheet() @@ -1026,6 +1027,45 @@ doc = SimpleDocTemplate(outputfile('test_platypus_tables_repeatrows_bgsplit.pdf'), showBoundary=0) doc.build(story) + def test4(self): + '''test splitting row colour cycles''' + story = [] + story_add = story.append + ts_tables = [ + ('BACKGROUND',(0,0),(-1,0),colors.pink), + ('BACKGROUND',(0,1),(-1,1),colors.lightblue), + ('ROWBACKGROUNDS',(0,2),(-1,-1),(colors.lightgrey,None)), + ('TEXTCOLOR',(0,0),(-1,0),colors.green), + ('TEXTCOLOR',(0,1),(-1,1),colors.red), + ('LINEABOVE', (0,0), (-1,0), 1, colors.purple), + ('LINEBELOW', (0,0), (-1,0), 2, colors.purple), + ('LINEABOVE', (0,1), (-1,1), 1, colors.orange), + ('LINEBELOW', (0,1), (-1,1), 2, colors.orange), + ('FONT', (2,2), (5,8), 'Times-Bold'), + ] + data = self.data34 + from reportlab.platypus import Paragraph, Table, SimpleDocTemplate, PageBreak + from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle + styleSheet = getSampleStyleSheet() + bodyText = styleSheet['BodyText'] + + story_add(Paragraph('The whole table',bodyText)) + t = Table(data, style=ts_tables, repeatRows=2) + story_add(t) + t = Table(data, style=ts_tables, repeatRows=2) + T = t.split(4*72,90) + story_add(Paragraph('The split table part 0',bodyText)) + story_add(T[0]) + story_add(Paragraph('The split table part 1',bodyText)) + story_add(T[1]) + self.assertIn(('BACKGROUND', (0, 0), (-1, 0), colors.pink),T[1]._bkgrndcmds) + self.assertIn(('BACKGROUND', (0, 1), (-1, 1), colors.lightblue),T[1]._bkgrndcmds) + self.assertIn(('ROWBACKGROUNDS', (0, 2), (-1, 8), (colors.lightgrey,None)),T[1]._bkgrndcmds) + self.assertEqual(len(T[1]._bkgrndcmds),3) + doc = SimpleDocTemplate(outputfile('test_platypus_tables_repeatrows_bgsplit_1.pdf'), showBoundary=0) + self.assertEqual(len(T[1]._bkgrndcmds),3) + doc.build(story) + def makeSuite(): return makeSuiteForClasses(TablesTestCase) ++++++ reportlab-missing-includes.patch ++++++ --- /var/tmp/diff_new_pack.FH3x64/_old 2020-12-12 20:32:08.453838052 +0100 +++ /var/tmp/diff_new_pack.FH3x64/_new 2020-12-12 20:32:08.457838055 +0100 @@ -1,5 +1,7 @@ ---- a/src/rl_addons/renderPM/gt1/gt1-namecontext.c -+++ b/src/rl_addons/renderPM/gt1/gt1-namecontext.c +Index: reportlab-3.5.56/src/rl_addons/renderPM/gt1/gt1-namecontext.c +=================================================================== +--- reportlab-3.5.56.orig/src/rl_addons/renderPM/gt1/gt1-namecontext.c ++++ reportlab-3.5.56/src/rl_addons/renderPM/gt1/gt1-namecontext.c @@ -1,6 +1,10 @@ /* A module for a simple "name context", i.e. lisp-style atoms */ @@ -10,4 +12,4 @@ +#include <sys/socket.h> #include "gt1-namecontext.h" - #if defined(_WIN32) || defined(macintosh) + #if defined(_WIN32) || defined(macintosh) || defined(__APPLE__) _______________________________________________ openSUSE Commits mailing list -- commit@lists.opensuse.org To unsubscribe, email commit-le...@lists.opensuse.org List Netiquette: https://en.opensuse.org/openSUSE:Mailing_list_netiquette List Archives: https://lists.opensuse.org/archives/list/commit@lists.opensuse.org