src/reportlab/platypus/flowables.py
author robin
Thu, 24 Oct 2019 16:07:15 +0100
changeset 4551 d357e2acc856
parent 4535 6f649f4056b5
child 4559 51a521ad7dd3
permissions -rw-r--r--
improve usage of eval/exec; version --> 3.5.32
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4330
617ffa6bbdc8 changes for release 3.4.0
robin <robin@reportlab.com>
parents: 4328
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2017
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 445
diff changeset
     2
#see license.txt for license details
4528
e09377955af8 try to eliminate changed bitbucket.org references
robin
parents: 4514
diff changeset
     3
#history https://hg.reportlab.com/hg-public/reportlab/log/tip/src/reportlab/platypus/flowables.py
4252
fe660f227cac changes for release 3.3.0
robin
parents: 4228
diff changeset
     4
__version__='3.3.0'
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
     5
__doc__="""
268
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
     6
A flowable is a "floating element" in a document whose exact position is determined by the
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
     7
other elements that precede it, such as a paragraph, a diagram interspersed between paragraphs,
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
     8
a section header, etcetera.  Examples of non-flowables include page numbering annotations,
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
     9
headers, footers, fixed diagrams or logos, among others.
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    10
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    11
Flowables are defined here as objects which know how to determine their size and which
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    12
can draw themselves onto a page with respect to a relative "origin" position determined
426
36a228f3e085 Changing to packer led positioning
rgbecker
parents: 368
diff changeset
    13
at a higher level. The object's draw() method should assume that (0,0) corresponds to the
36a228f3e085 Changing to packer led positioning
rgbecker
parents: 368
diff changeset
    14
bottom left corner of the enclosing rectangle that will contain the object. The attributes
36a228f3e085 Changing to packer led positioning
rgbecker
parents: 368
diff changeset
    15
vAlign and hAlign may be used by 'packers' as hints as to how the object should be placed.
36a228f3e085 Changing to packer led positioning
rgbecker
parents: 368
diff changeset
    16
36a228f3e085 Changing to packer led positioning
rgbecker
parents: 368
diff changeset
    17
Some Flowables also know how to "split themselves".  For example a
268
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    18
long paragraph might split itself between one page and the next.
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    19
1490
d6d958390ff0 Added api instructions
rgbecker
parents: 1486
diff changeset
    20
Packers should set the canv attribute during wrap, split & draw operations to allow
d6d958390ff0 Added api instructions
rgbecker
parents: 1486
diff changeset
    21
the flowable to work out sizes etc in the proper context.
d6d958390ff0 Added api instructions
rgbecker
parents: 1486
diff changeset
    22
268
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    23
The "text" of a document usually consists mainly of a sequence of flowables which
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    24
flow into a document from top to bottom (with column and page breaks controlled by
8414113fa500 more documentation changes
aaron_watters
parents: 255
diff changeset
    25
higher level components).
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    26
"""
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    27
import os
2834
8bafca0cc650 flowables.py: use semi-deep copy for PTO split
rgbecker
parents: 2788
diff changeset
    28
from copy import deepcopy, copy
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
    29
from reportlab.lib.colors import red, gray, lightgrey
3781
df8b57380768 import from reportlab.lib.lib.rl_accel
robin
parents: 3750
diff changeset
    30
from reportlab.lib.rl_accel import fp_str
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
    31
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
3368
afa025c34493 reportlab: new base font mechanism more fully applied
rgbecker
parents: 3366
diff changeset
    32
from reportlab.lib.styles import _baseFontName
4551
d357e2acc856 improve usage of eval/exec; version --> 3.5.32
robin
parents: 4535
diff changeset
    33
from reportlab.lib.utils import strTypes, safer_globals
4486
b5673e9d2876 fix frame background stroking for the container case. version --> 3.5.16
robin <robin@reportlab.com>
parents: 4485
diff changeset
    34
from reportlab.lib.abag import ABag
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    35
from reportlab.pdfbase import pdfutils
3415
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
    36
from reportlab.pdfbase.pdfmetrics import stringWidth
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
    37
from reportlab.rl_config import _FUZZ, overlapAttachedSpace, ignoreContainerActions, listWrapOnFakeWidth
4367
9960d82643bf remove ascii, cmp & xrange builtins abuse; version-->3.4.15
robin <robin@reportlab.com>
parents: 4362
diff changeset
    38
from reportlab import xrange
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3686
diff changeset
    39
import collections
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    40
4485
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
    41
__all__ = '''AnchorFlowable BalancedColumns BulletDrawer CallerMacro CondPageBreak DDIndenter DocAssert
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
    42
        DocAssign DocExec DocIf DocPara DocWhile FailOnDraw FailOnWrap Flowable FrameBG FrameSplitter
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
    43
        HRFlowable Image ImageAndFlowables KeepInFrame KeepTogether LIIndenter ListFlowable ListItem
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
    44
        Macro NullDraw PTOContainer PageBreak PageBreakIfNotEmpty ParagraphAndImage Preformatted
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
    45
        SetPageTopFlowables SetTopFlowables SlowPageBreak Spacer TopPadder TraceInfo UseUpSpace XBox
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
    46
        splitLine splitLines'''.split()
4279
f69571262c74 fix fake KeepTogether setup in handle_keepWithNext; version--> 3.3.13
robin
parents: 4278
diff changeset
    47
2113
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    48
class TraceInfo:
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    49
    "Holder for info about where an object originated"
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    50
    def __init__(self):
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    51
        self.srcFile = '(unknown)'
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    52
        self.startLineNo = -1
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    53
        self.startLinePos = -1
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    54
        self.endLineNo = -1
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    55
        self.endLinePos = -1
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2192
diff changeset
    56
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    57
#############################################################
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    58
#   Flowable Objects - a base class and a few examples.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    59
#   One is just a box to get some metrics.  We also have
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    60
#   a paragraph, an image and a special 'page break'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    61
#   object which fills the space.
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    62
#############################################################
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    63
class Flowable:
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    64
    """Abstract base class for things to be drawn.  Key concepts:
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
    65
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    66
    1. It knows its size
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    67
    2. It draws in its own coordinate system (this requires the
3031
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 3017
diff changeset
    68
       base API to provide a translate() function.
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
    69
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    70
    """
1917
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
    71
    _fixedWidth = 0         #assume wrap results depend on arguments?
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
    72
    _fixedHeight = 0
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
    73
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    74
    def __init__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    75
        self.width = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    76
        self.height = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    77
        self.wrapped = 0
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
    78
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    79
        #these are hints to packers/frames as to how the floable should be positioned
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    80
        self.hAlign = 'LEFT'    #CENTER/CENTRE or RIGHT
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    81
        self.vAlign = 'BOTTOM'  #MIDDLE or TOP
426
36a228f3e085 Changing to packer led positioning
rgbecker
parents: 368
diff changeset
    82
2113
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    83
        #optional holder for trace info
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
    84
        self._traceInfo = None
2158
e9c34b93e317 Whoops, platform specific slashes.
andy_robinson
parents: 2113
diff changeset
    85
        self._showBoundary = None
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2192
diff changeset
    86
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
    87
        #many flowables handle text and must be processed in the
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
    88
        #absence of a canvas.  tagging them with their encoding
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
    89
        #helps us to get conversions right.  Use Python codec names.
2762
48eadc6faff2 platypus: added in NotAtTopPageBreak and support
rgbecker
parents: 2750
diff changeset
    90
        self.encoding = None
1494
b0707e45102e Added _drawOn method
rgbecker
parents: 1491
diff changeset
    91
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    92
    def _drawOn(self,canv):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    93
        '''ensure canv is set on and then draw'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    94
        self.canv = canv
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    95
        self.draw()#this is the bit you overload
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
    96
        del self.canv
1494
b0707e45102e Added _drawOn method
rgbecker
parents: 1491
diff changeset
    97
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
    98
    def _hAlignAdjust(self,x,sW=0):
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
    99
        if sW and hasattr(self,'hAlign'):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   100
            a = self.hAlign
2773
b7dff8053a35 flowablse.py: allow TA_LEFT/CENTER/RIGHT as hAligns
rgbecker
parents: 2769
diff changeset
   101
            if a in ('CENTER','CENTRE', TA_CENTER):
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   102
                x += 0.5*sW
2773
b7dff8053a35 flowablse.py: allow TA_LEFT/CENTER/RIGHT as hAligns
rgbecker
parents: 2769
diff changeset
   103
            elif a in ('RIGHT',TA_RIGHT):
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   104
                x += sW
2773
b7dff8053a35 flowablse.py: allow TA_LEFT/CENTER/RIGHT as hAligns
rgbecker
parents: 2769
diff changeset
   105
            elif a not in ('LEFT',TA_LEFT):
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3686
diff changeset
   106
                raise ValueError("Bad hAlign value "+str(a))
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   107
        return x
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   108
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   109
    def drawOn(self, canvas, x, y, _sW=0):
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   110
        "Tell it to draw itself on the canvas.  Do not override"
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   111
        x = self._hAlignAdjust(x,_sW)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   112
        canvas.saveState()
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   113
        canvas.translate(x, y)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   114
        self._drawOn(canvas)
2158
e9c34b93e317 Whoops, platform specific slashes.
andy_robinson
parents: 2113
diff changeset
   115
        if hasattr(self, '_showBoundary') and self._showBoundary:
e9c34b93e317 Whoops, platform specific slashes.
andy_robinson
parents: 2113
diff changeset
   116
            #diagnostic tool support
e9c34b93e317 Whoops, platform specific slashes.
andy_robinson
parents: 2113
diff changeset
   117
            canvas.setStrokeColor(gray)
e9c34b93e317 Whoops, platform specific slashes.
andy_robinson
parents: 2113
diff changeset
   118
            canvas.rect(0,0,self.width, self.height)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   119
        canvas.restoreState()
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   120
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   121
    def wrapOn(self, canv, aW, aH):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   122
        '''intended for use by packers allows setting the canvas on
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   123
        during the actual wrap'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   124
        self.canv = canv
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   125
        w, h = self.wrap(aW,aH)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   126
        del self.canv
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   127
        return w, h
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   128
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   129
    def wrap(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   130
        """This will be called by the enclosing frame before objects
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   131
        are asked their size, drawn or whatever.  It returns the
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   132
        size actually used."""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   133
        return (self.width, self.height)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   134
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   135
    def minWidth(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   136
        """This should return the minimum required width"""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   137
        return getattr(self,'_minWidth',self.width)
954
bf9f434cb08a added minWidth method to Flowable, Paragraph
rgbecker
parents: 760
diff changeset
   138
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   139
    def splitOn(self, canv, aW, aH):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   140
        '''intended for use by packers allows setting the canvas on
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   141
        during the actual split'''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   142
        self.canv = canv
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   143
        S = self.split(aW,aH)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   144
        del self.canv
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   145
        return S
1491
8cb77f6ac40d Introduce wrapOn & splitOn
rgbecker
parents: 1490
diff changeset
   146
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   147
    def split(self, availWidth, availheight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   148
        """This will be called by more sophisticated frames when
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   149
        wrap fails. Stupid flowables should return []. Clever flowables
3017
172b16456b86 better docstring for Flowable.split
andy
parents: 3009
diff changeset
   150
        should split themselves and return a list of flowables.
172b16456b86 better docstring for Flowable.split
andy
parents: 3009
diff changeset
   151
        If they decide that nothing useful can be fitted in the
172b16456b86 better docstring for Flowable.split
andy
parents: 3009
diff changeset
   152
        available space (e.g. if you have a table and not enough
172b16456b86 better docstring for Flowable.split
andy
parents: 3009
diff changeset
   153
        space for the first row), also return []"""
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   154
        return []
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   155
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   156
    def getKeepWithNext(self):
1879
c1dc90e2f470 Fix trivial spelling burble
rgbecker
parents: 1768
diff changeset
   157
        """returns boolean determining whether the next flowable should stay with this one"""
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   158
        if hasattr(self,'keepWithNext'): return self.keepWithNext
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   159
        elif hasattr(self,'style') and hasattr(self.style,'keepWithNext'): return self.style.keepWithNext
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   160
        else: return 0
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   161
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   162
    def getSpaceAfter(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   163
        """returns how much space should follow this item if another item follows on the same page."""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   164
        if hasattr(self,'spaceAfter'): return self.spaceAfter
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   165
        elif hasattr(self,'style') and hasattr(self.style,'spaceAfter'): return self.style.spaceAfter
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   166
        else: return 0
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   167
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   168
    def getSpaceBefore(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   169
        """returns how much space should precede this item if another item precedess on the same page."""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   170
        if hasattr(self,'spaceBefore'): return self.spaceBefore
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   171
        elif hasattr(self,'style') and hasattr(self.style,'spaceBefore'): return self.style.spaceBefore
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   172
        else: return 0
1426
377351bbe539 Add getKeepWithNext to Flowable
rgbecker
parents: 1360
diff changeset
   173
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   174
    def isIndexing(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   175
        """Hook for IndexingFlowables - things which have cross references"""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   176
        return 0
512
c12ae96634d5 Added working table of contents framework
andy_robinson
parents: 496
diff changeset
   177
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   178
    def identity(self, maxLen=None):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   179
        '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   180
        This method should attempt to return a string that can be used to identify
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   181
        a particular flowable uniquely. The result can then be used for debugging
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   182
        and or error printouts
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   183
        '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   184
        if hasattr(self, 'getPlainText'):
2172
2740f571bd24 Fixes to cope with rml2pdf weirds
rgbecker
parents: 2158
diff changeset
   185
            r = self.getPlainText(identify=1)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   186
        elif hasattr(self, 'text'):
2461
9c24d39d05e8 enhanced decimal alignment
andy
parents: 2451
diff changeset
   187
            r = str(self.text)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   188
        else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   189
            r = '...'
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   190
        if r and maxLen:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   191
            r = r[:maxLen]
2531
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
   192
        return "<%s at %s%s>%s" % (self.__class__.__name__, hex(id(self)), self._frameName(), r)
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
   193
4494
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   194
    @property
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   195
    def _doctemplate(self):
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   196
        return getattr(getattr(self,'canv',None),'_doctemplate',None)
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   197
2950
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   198
    def _doctemplateAttr(self,a):
4494
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   199
        return getattr(self._doctemplate,a,None)
2950
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   200
2531
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
   201
    def _frameName(self):
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
   202
        f = getattr(self,'_frame',None)
2950
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   203
        if not f: f = self._doctemplateAttr('frame')
2531
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
   204
        if f and f.id: return ' frame=%s' % f.id
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
   205
        return ''
1103
857af510186d Added identity method to Flowables
rgbecker
parents: 1036
diff changeset
   206
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   207
class XBox(Flowable):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   208
    """Example flowable - a box with an x through it and a caption.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   209
    This has a known size, so does not need to respond to wrap()."""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   210
    def __init__(self, width, height, text = 'A Box'):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   211
        Flowable.__init__(self)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   212
        self.width = width
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   213
        self.height = height
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   214
        self.text = text
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   215
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   216
    def __repr__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   217
        return "XBox(w=%s, h=%s, t=%s)" % (self.width, self.height, self.text)
541
33de80b3655c added __repr__s and enhanced exception messages for debugging
aaron_watters
parents: 512
diff changeset
   218
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   219
    def draw(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   220
        self.canv.rect(0, 0, self.width, self.height)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   221
        self.canv.line(0, 0, self.width, self.height)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   222
        self.canv.line(0, self.height, self.width, 0)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   223
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   224
        #centre the text
3368
afa025c34493 reportlab: new base font mechanism more fully applied
rgbecker
parents: 3366
diff changeset
   225
        self.canv.setFont(_baseFontName,12)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   226
        self.canv.drawCentredString(0.5*self.width, 0.5*self.height, self.text)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   227
445
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   228
def _trimEmptyLines(lines):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   229
    #don't want the first or last to be empty
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   230
    while len(lines) and lines[0].strip() == '':
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   231
        lines = lines[1:]
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   232
    while len(lines) and lines[-1].strip() == '':
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   233
        lines = lines[:-1]
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   234
    return lines
445
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   235
442
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 426
diff changeset
   236
def _dedenter(text,dedent=0):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   237
    '''
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   238
    tidy up text - carefully, it is probably code.  If people want to
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   239
    indent code within a source script, you can supply an arg to dedent
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   240
    and it will chop off that many character, otherwise it leaves
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   241
    left edge intact.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   242
    '''
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   243
    lines = text.split('\n')
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   244
    if dedent>0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   245
        templines = _trimEmptyLines(lines)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   246
        lines = []
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   247
        for line in templines:
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   248
            line = line[dedent:].rstrip()
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   249
            lines.append(line)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   250
    else:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   251
        lines = _trimEmptyLines(lines)
445
8b64b9812ca6 Fixes to _dedenter
rgbecker
parents: 442
diff changeset
   252
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   253
    return lines
442
e3eac15cddbd XPreformatted first fixes; now runs
rgbecker
parents: 426
diff changeset
   254
3599
62ffe97aa327 Updated preforatted text wrapping function in Platypus
guillaume
parents: 3596
diff changeset
   255
62ffe97aa327 Updated preforatted text wrapping function in Platypus
guillaume
parents: 3596
diff changeset
   256
SPLIT_CHARS = "[{( ,.;:/\\-"
62ffe97aa327 Updated preforatted text wrapping function in Platypus
guillaume
parents: 3596
diff changeset
   257
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   258
def splitLines(lines, maximum_length, split_characters, new_line_characters):
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   259
    if split_characters is None:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   260
        split_characters = SPLIT_CHARS
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   261
    if new_line_characters is None:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   262
        new_line_characters = ""
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   263
    # Return a table of lines
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   264
    lines_splitted = []
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   265
    for line in lines:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   266
        if len(line) > maximum_length:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   267
            splitLine(line, lines_splitted, maximum_length, \
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   268
            split_characters, new_line_characters)
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   269
        else:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   270
            lines_splitted.append(line)
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   271
    return lines_splitted
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   272
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   273
def splitLine(line_to_split, lines_splitted, maximum_length, \
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   274
split_characters, new_line_characters):
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   275
    # Used to implement the characters added
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   276
    #at the beginning of each new line created
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   277
    first_line = True
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   278
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   279
    # Check if the text can be splitted
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   280
    while line_to_split and len(line_to_split)>0:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   281
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   282
        # Index of the character where we can split
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   283
        split_index = 0
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   284
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   285
        # Check if the line length still exceeds the maximum length
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   286
        if len(line_to_split) <= maximum_length:
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   287
            # Return the remaining of the line
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   288
            split_index = len(line_to_split)
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   289
        else:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   290
            # Iterate for each character of the line
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   291
            for line_index in range(maximum_length):
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   292
                # Check if the character is in the list
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   293
                # of allowed characters to split on
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   294
                if line_to_split[line_index] in split_characters:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   295
                    split_index = line_index + 1
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   296
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   297
        # If the end of the line was reached
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   298
        # with no character to split on
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   299
        if split_index==0:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   300
            split_index = line_index + 1
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   301
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   302
        if first_line:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   303
            lines_splitted.append(line_to_split[0:split_index])
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   304
            first_line = False
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   305
            maximum_length -= len(new_line_characters)
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   306
        else:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   307
            lines_splitted.append(new_line_characters + \
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   308
            line_to_split[0:split_index])
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   309
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   310
        # Remaining text to split
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   311
        line_to_split = line_to_split[split_index:]
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   312
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   313
class Preformatted(Flowable):
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   314
    """This is like the HTML <PRE> tag.
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   315
    It attempts to display text exactly as you typed it in a fixed width "typewriter" font.
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   316
    By default the line breaks are exactly where you put them, and it will not be wrapped.
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   317
    You can optionally define a maximum line length and the code will be wrapped; and
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   318
    extra characters to be inserted at the beginning of each wrapped line (e.g. '> ').
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   319
    """
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   320
    def __init__(self, text, style, bulletText = None, dedent=0, maxLineLength=None, splitChars=None, newLineChars=""):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   321
        """text is the text to display. If dedent is set then common leading space
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   322
        will be chopped off the front (for example if the entire text is indented
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   323
        6 spaces or more then each line will have 6 spaces removed from the front).
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   324
        """
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   325
        self.style = style
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   326
        self.bulletText = bulletText
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   327
        self.lines = _dedenter(text,dedent)
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   328
        if text and maxLineLength:
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   329
            self.lines = splitLines(
4333
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   330
                                self.lines,
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   331
                                maxLineLength,
c1e804dfeef8 add BalancedColumns flowable; version-->3.4.1
robin <robin@reportlab.com>
parents: 4330
diff changeset
   332
                                splitChars,
3596
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   333
                                newLineChars
1f525cd79c3c Added paragraph wrapping for preformatted text in Platypus
guillaume
parents: 3567
diff changeset
   334
                        )
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   335
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   336
    def __repr__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   337
        bT = self.bulletText
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   338
        H = "Preformatted("
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   339
        if bT is not None:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   340
            H = "Preformatted(bulletText=%s," % repr(bT)
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   341
        return "%s'''\\ \n%s''')" % (H, '\n'.join(self.lines))
541
33de80b3655c added __repr__s and enhanced exception messages for debugging
aaron_watters
parents: 512
diff changeset
   342
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   343
    def wrap(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   344
        self.width = availWidth
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   345
        self.height = self.style.leading*len(self.lines)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   346
        return (self.width, self.height)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   347
3415
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
   348
    def minWidth(self):
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
   349
        style = self.style
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
   350
        fontSize = style.fontSize
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
   351
        fontName = style.fontName
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
   352
        return max([stringWidth(line,fontName,fontSize) for line in self.lines])
bfc4e14f4122 flowables.py: add Preformatted.minWidth inspired by Michael Hipp
rgbecker
parents: 3368
diff changeset
   353
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   354
    def split(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   355
        #returns two Preformatted objects
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   356
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   357
        #not sure why they can be called with a negative height
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   358
        if availHeight < self.style.leading:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   359
            return []
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   360
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   361
        linesThatFit = int(availHeight * 1.0 / self.style.leading)
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   362
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   363
        text1 = '\n'.join(self.lines[0:linesThatFit])
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   364
        text2 = '\n'.join(self.lines[linesThatFit:])
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   365
        style = self.style
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   366
        if style.firstLineIndent != 0:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   367
            style = deepcopy(style)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   368
            style.firstLineIndent = 0
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   369
        return [Preformatted(text1, self.style), Preformatted(text2, style)]
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   370
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   371
    def draw(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   372
        #call another method for historical reasons.  Besides, I
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   373
        #suspect I will be playing with alternate drawing routines
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   374
        #so not doing it here makes it easier to switch.
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   375
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   376
        cur_x = self.style.leftIndent
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   377
        cur_y = self.height - self.style.fontSize
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   378
        self.canv.addLiteral('%PreformattedPara')
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   379
        if self.style.textColor:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   380
            self.canv.setFillColor(self.style.textColor)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   381
        tx = self.canv.beginText(cur_x, cur_y)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   382
        #set up the font etc.
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   383
        tx.setFont( self.style.fontName,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   384
                    self.style.fontSize,
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   385
                    self.style.leading)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   386
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   387
        for text in self.lines:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   388
            tx.textLine(text)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   389
        self.canv.drawText(tx)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   390
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   391
class Image(Flowable):
2045
cc042609c62e hack to ImageReader
rgbecker
parents: 2023
diff changeset
   392
    """an image (digital picture).  Formats supported by PIL/Java 1.4 (the Python/Java Imaging Library
4162
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   393
       are supported. Images as flowables may be aligned horizontally in the
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   394
       frame with the hAlign parameter - accepted values are 'CENTER',
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   395
       'LEFT' or 'RIGHT' with 'CENTER' being the default.
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   396
       We allow for two kinds of lazyness to allow for many images in a document
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   397
       which could lead to file handle starvation.
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   398
       lazy=1 don't open image until required.
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   399
       lazy=2 open image when required then shut it.
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   400
    """
1917
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
   401
    _fixedWidth = 1
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
   402
    _fixedHeight = 1
4162
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   403
    def __init__(self, filename, width=None, height=None, kind='direct',
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   404
                 mask="auto", lazy=1, hAlign='CENTER'):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   405
        """If size to draw at not specified, get it from the image."""
4162
93b711694015 Allow to set the horizontal alignment for reportlab.platypus.flowables.Image
Julien Pages <j.parkous@gmail.com>
parents: 4153
diff changeset
   406
        self.hAlign = hAlign
1880
5444027dd195 Allow for image transparancy mask
rgbecker
parents: 1879
diff changeset
   407
        self._mask = mask
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   408
        fp = hasattr(filename,'read')
4314
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   409
        self._drawing = None
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   410
        if fp:
2237
005d070deb87 Fix up more Image cases
rgbecker
parents: 2200
diff changeset
   411
            self._file = filename
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3321
diff changeset
   412
            self.filename = repr(filename)
4314
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   413
        elif hasattr(filename,'_renderPy'):
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   414
            self._drawing = filename
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   415
            self.filename=repr(filename)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   416
            self._file = None
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   417
            self._img = None
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   418
            fp = True
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   419
        else:
2237
005d070deb87 Fix up more Image cases
rgbecker
parents: 2200
diff changeset
   420
            self._file = self.filename = filename
2851
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   421
        if not fp and os.path.splitext(filename)[1] in ['.jpg', '.JPG', '.jpeg', '.JPEG']:
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   422
            # if it is a JPEG, will be inlined within the file -
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   423
            # but we still need to know its size now
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   424
            from reportlab.lib.utils import open_for_read
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   425
            f = open_for_read(filename, 'b')
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   426
            try:
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   427
                try:
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   428
                    info = pdfutils.readJPEGInfo(f)
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   429
                except:
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   430
                    #couldn't read as a JPEG, try like normal
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   431
                    self._setup(width,height,kind,lazy)
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   432
                    return
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   433
            finally:
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   434
                f.close()
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   435
            self.imageWidth = info[0]
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   436
            self.imageHeight = info[1]
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   437
            self._img = None
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   438
            self._setup(width,height,kind,0)
09d164c60442 flowables.py: restore attempted jpeg read as a memory saver, but alow to fail
rgbecker
parents: 2850
diff changeset
   439
        elif fp:
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   440
            self._setup(width,height,kind,0)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   441
        else:
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   442
            self._setup(width,height,kind,lazy)
1477
dc5c2ba1005a Allow for various Image kinds
rgbecker
parents: 1426
diff changeset
   443
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   444
    def _setup(self,width,height,kind,lazy):
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   445
        self._lazy = lazy
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   446
        self._width = width
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   447
        self._height = height
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   448
        self._kind = kind
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   449
        if lazy<=0: self._setup_inner()
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   450
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   451
    def _setup_inner(self):
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   452
        width = self._width
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   453
        height = self._height
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   454
        kind = self._kind
2404
8bc8743cc5ec flowables.py: fix no PIL jpg problem reported by Martin.Zohlhuber@tttech.com
rgbecker
parents: 2403
diff changeset
   455
        img = self._img
4314
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   456
        if img:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   457
            self.imageWidth, self.imageHeight = img.getSize()
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   458
        elif self._drawing:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   459
            self.imageWidth, self.imageHeight = self._drawing.width,self._drawing.height
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   460
        if self._lazy>=2: del self._img
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   461
        if kind in ['direct','absolute']:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   462
            self.drawWidth = width or self.imageWidth
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   463
            self.drawHeight = height or self.imageHeight
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   464
        elif kind in ['percentage','%']:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   465
            self.drawWidth = self.imageWidth*width*0.01
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   466
            self.drawHeight = self.imageHeight*height*0.01
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   467
        elif kind in ['bound','proportional']:
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   468
            factor = min(float(width)/self.imageWidth,float(height)/self.imageHeight)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   469
            self.drawWidth = self.imageWidth*factor
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   470
            self.drawHeight = self.imageHeight*factor
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   471
3319
f4b996498929 flowables.py: added Image._restrictSize and use in ImageAndFLowables
rgbecker
parents: 3272
diff changeset
   472
    def _restrictSize(self,aW,aH):
3321
7a54d0735311 flowables.py: fix restrict to return draw size
rgbecker
parents: 3319
diff changeset
   473
        if self.drawWidth>aW+_FUZZ or self.drawHeight>aH+_FUZZ:
3344
c707722c1640 flowables.py: attempt to fix bad behaviour in ImageAndFlowables
rgbecker
parents: 3342
diff changeset
   474
            self._oldDrawSize = self.drawWidth, self.drawHeight
3321
7a54d0735311 flowables.py: fix restrict to return draw size
rgbecker
parents: 3319
diff changeset
   475
            factor = min(float(aW)/self.drawWidth,float(aH)/self.drawHeight)
7a54d0735311 flowables.py: fix restrict to return draw size
rgbecker
parents: 3319
diff changeset
   476
            self.drawWidth *= factor
7a54d0735311 flowables.py: fix restrict to return draw size
rgbecker
parents: 3319
diff changeset
   477
            self.drawHeight *= factor
7a54d0735311 flowables.py: fix restrict to return draw size
rgbecker
parents: 3319
diff changeset
   478
        return self.drawWidth, self.drawHeight
3319
f4b996498929 flowables.py: added Image._restrictSize and use in ImageAndFLowables
rgbecker
parents: 3272
diff changeset
   479
3344
c707722c1640 flowables.py: attempt to fix bad behaviour in ImageAndFlowables
rgbecker
parents: 3342
diff changeset
   480
    def _unRestrictSize(self):
c707722c1640 flowables.py: attempt to fix bad behaviour in ImageAndFlowables
rgbecker
parents: 3342
diff changeset
   481
        dwh = getattr(self,'_oldDrawSize',None)
c707722c1640 flowables.py: attempt to fix bad behaviour in ImageAndFlowables
rgbecker
parents: 3342
diff changeset
   482
        if dwh:
c707722c1640 flowables.py: attempt to fix bad behaviour in ImageAndFlowables
rgbecker
parents: 3342
diff changeset
   483
            self.drawWidth, self.drawHeight = dwh
c707722c1640 flowables.py: attempt to fix bad behaviour in ImageAndFlowables
rgbecker
parents: 3342
diff changeset
   484
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   485
    def __getattr__(self,a):
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   486
        if a=='_img':
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   487
            from reportlab.lib.utils import ImageReader  #this may raise an error
2237
005d070deb87 Fix up more Image cases
rgbecker
parents: 2200
diff changeset
   488
            self._img = ImageReader(self._file)
4352
fd9ca874bf30 fix _bulletFormat; version --> 3.4.8
robin <robin@reportlab.com>
parents: 4348
diff changeset
   489
            if not isinstance(self._file,strTypes):
4122
5ed6b5e02226 flowables.py: attempted fix of Image bug related to lazy==2 reported by V Hoke bb issue #41; bump to 3.1.24
robin
parents: 4108
diff changeset
   490
                self._file = None
5ed6b5e02226 flowables.py: attempted fix of Image bug related to lazy==2 reported by V Hoke bb issue #41; bump to 3.1.24
robin
parents: 4108
diff changeset
   491
                if self._lazy>=2: self._lazy = 1    #here we're assuming we cannot read again
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   492
            return self._img
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   493
        elif a in ('drawWidth','drawHeight','imageWidth','imageHeight'):
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   494
            self._setup_inner()
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   495
            return self.__dict__[a]
3342
ce7e1ab56a22 flowables.py small improvement to exception texts
rgbecker
parents: 3326
diff changeset
   496
        raise AttributeError("<Image @ 0x%x>.%s" % (id(self),a))
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   497
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   498
    def wrap(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   499
        #the caller may decide it does not fit.
3321
7a54d0735311 flowables.py: fix restrict to return draw size
rgbecker
parents: 3319
diff changeset
   500
        return self.drawWidth, self.drawHeight
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   501
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   502
    def draw(self):
4314
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   503
        dx = getattr(self,'_offs_x',0)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   504
        dy = getattr(self,'_offs_y',0)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   505
        d = self._drawing
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   506
        if d:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   507
            sx = self.drawWidth / float(self.imageWidth)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   508
            sy = self.drawHeight / float(self.imageHeight)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   509
            otrans = d.transform
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   510
            try:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   511
                d.scale(sx,sy)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   512
                d.drawOn(self.canv,dx,dy)
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   513
            finally:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   514
                d.transform = otrans
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   515
        else:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   516
            lazy = self._lazy
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   517
            if lazy>=2: self._lazy = 1
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   518
            self.canv.drawImage(    self._img or self.filename,
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   519
                                    dx,
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   520
                                    dy,
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   521
                                    self.drawWidth,
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   522
                                    self.drawHeight,
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   523
                                    mask=self._mask,
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   524
                                    )
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   525
            if lazy>=2:
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   526
                self._img = self._file = None
27d3ed39ad3e support Image with drawing instance image; version-->3.3.30
robin <robin@reportlab.com>
parents: 4285
diff changeset
   527
                self._lazy = lazy
1103
857af510186d Added identity method to Flowables
rgbecker
parents: 1036
diff changeset
   528
2192
955d4bf3b9d2 Candidate fix for infinite looping
andy_robinson
parents: 2172
diff changeset
   529
    def identity(self,maxLen=None):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   530
        r = Flowable.identity(self,maxLen)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3686
diff changeset
   531
        if r[-4:]=='>...' and isinstance(self.filename,str):
2080
39156f56ab6f Added in lazy Image stuff
rgbecker
parents: 2045
diff changeset
   532
            r = "%s filename=%s>" % (r[:-4],self.filename)
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   533
        return r
1103
857af510186d Added identity method to Flowables
rgbecker
parents: 1036
diff changeset
   534
2955
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   535
class NullDraw(Flowable):
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   536
    def draw(self):
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   537
        pass
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   538
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   539
class Spacer(NullDraw):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   540
    """A spacer just takes up space and doesn't draw anything - it guarantees
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   541
       a gap between objects."""
1917
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
   542
    _fixedWidth = 1
25b37daf5ab7 Prepare for a more general idea of cell size
rgbecker
parents: 1882
diff changeset
   543
    _fixedHeight = 1
3537
187f4e0c072a flowables.py: fix KeepTogether to work better, allow Spacer to be glue
rgbecker
parents: 3528
diff changeset
   544
    def __init__(self, width, height, isGlue=False):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   545
        self.width = width
3537
187f4e0c072a flowables.py: fix KeepTogether to work better, allow Spacer to be glue
rgbecker
parents: 3528
diff changeset
   546
        if isGlue:
187f4e0c072a flowables.py: fix KeepTogether to work better, allow Spacer to be glue
rgbecker
parents: 3528
diff changeset
   547
            self.height = 1e-4
187f4e0c072a flowables.py: fix KeepTogether to work better, allow Spacer to be glue
rgbecker
parents: 3528
diff changeset
   548
            self.spacebefore = height
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   549
        self.height = height
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   550
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   551
    def __repr__(self):
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   552
        return "%s(%s, %s)" % (self.__class__.__name__,self.width, self.height)
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   553
2955
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   554
class UseUpSpace(NullDraw):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   555
    def __init__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   556
        pass
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   557
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   558
    def __repr__(self):
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   559
        return "%s()" % self.__class__.__name__
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   560
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   561
    def wrap(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   562
        self.width = availWidth
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   563
        self.height = availHeight
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   564
        return (availWidth,availHeight-1e-8)  #step back a point
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   565
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   566
class PageBreak(UseUpSpace):
4279
f69571262c74 fix fake KeepTogether setup in handle_keepWithNext; version--> 3.3.13
robin
parents: 4278
diff changeset
   567
    locChanger=1
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   568
    """Move on to the next page in the document.
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   569
       This works by consuming all remaining space in the frame!"""
4145
f14cb807aa3d platypus: support setting template with PageBreak & add PageBreakIfNotEmpty; version --> 3.1.40
robin
parents: 4139
diff changeset
   570
    def __init__(self,nextTemplate=None):
f14cb807aa3d platypus: support setting template with PageBreak & add PageBreakIfNotEmpty; version --> 3.1.40
robin
parents: 4139
diff changeset
   571
        self.nextTemplate = nextTemplate
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   572
2408
1c5e79611b59 flowables: add SlowPageBreak
rgbecker
parents: 2404
diff changeset
   573
class SlowPageBreak(PageBreak):
1c5e79611b59 flowables: add SlowPageBreak
rgbecker
parents: 2404
diff changeset
   574
    pass
1c5e79611b59 flowables: add SlowPageBreak
rgbecker
parents: 2404
diff changeset
   575
4145
f14cb807aa3d platypus: support setting template with PageBreak & add PageBreakIfNotEmpty; version --> 3.1.40
robin
parents: 4139
diff changeset
   576
class PageBreakIfNotEmpty(PageBreak):
f14cb807aa3d platypus: support setting template with PageBreak & add PageBreakIfNotEmpty; version --> 3.1.40
robin
parents: 4139
diff changeset
   577
    pass
f14cb807aa3d platypus: support setting template with PageBreak & add PageBreakIfNotEmpty; version --> 3.1.40
robin
parents: 4139
diff changeset
   578
307
c439e402b404 Added CondPageBreak
rgbecker
parents: 268
diff changeset
   579
class CondPageBreak(Spacer):
4279
f69571262c74 fix fake KeepTogether setup in handle_keepWithNext; version--> 3.3.13
robin
parents: 4278
diff changeset
   580
    locChanger=1
2950
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   581
    """use up a frame if not enough vertical space effectively CondFrameBreak"""
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   582
    def __init__(self, height):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   583
        self.height = height
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   584
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   585
    def __repr__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   586
        return "CondPageBreak(%s)" %(self.height,)
307
c439e402b404 Added CondPageBreak
rgbecker
parents: 268
diff changeset
   587
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   588
    def wrap(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   589
        if availHeight<self.height:
2950
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   590
            f = self._doctemplateAttr('frame')
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   591
            if not f: return availWidth, availHeight
3975
4a3599863c11 eliminate from . imports in favour of absolutes to allow running modules
robin
parents: 3781
diff changeset
   592
            from reportlab.platypus.doctemplate import FrameBreak
2950
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   593
            f.add_generated_content(FrameBreak)
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   594
        return 0, 0
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   595
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   596
    def identity(self,maxLen=None):
6c243412b06c platypus: add support for FramSplitter flowable
rgbecker
parents: 2903
diff changeset
   597
        return repr(self).replace(')',',frame=%s)'%self._frameName())
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   598
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
   599
def _listWrapOn(F,availWidth,canv,mergeSpace=1,obj=None,dims=None,fakeWidth=None):
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   600
    '''return max width, required height for a list of flowables F'''
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   601
    doct = getattr(canv,'_doctemplate',None)
3158
a5ecc0cae476 flowables.py: fix special case of doctemplate with no frames
rgbecker
parents: 3031
diff changeset
   602
    cframe = getattr(doct,'frame',None)
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
   603
    if fakeWidth is None:
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
   604
        fakeWidth = listWrapOnFakeWidth
3158
a5ecc0cae476 flowables.py: fix special case of doctemplate with no frames
rgbecker
parents: 3031
diff changeset
   605
    if cframe:
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   606
        from reportlab.platypus.doctemplate import _addGeneratedContent, Indenter
3158
a5ecc0cae476 flowables.py: fix special case of doctemplate with no frames
rgbecker
parents: 3031
diff changeset
   607
        doct_frame = cframe
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   608
        cframe = doct.frame = deepcopy(doct_frame)
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   609
        cframe._generated_content = None
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   610
        del cframe._generated_content
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   611
    try:
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   612
        W = 0
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   613
        H = 0
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   614
        pS = 0
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   615
        atTop = 1
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   616
        F = F[:]
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   617
        while F:
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   618
            f = F.pop(0)
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   619
            if hasattr(f,'frameAction'):
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   620
                from reportlab.platypus.doctemplate import Indenter
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   621
                if isinstance(f,Indenter):
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   622
                    availWidth -= f.left+f.right
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   623
                continue
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   624
            w,h = f.wrapOn(canv,availWidth,0xfffffff)
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   625
            if dims is not None: dims.append((w,h))
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   626
            if cframe:
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   627
                _addGeneratedContent(F,cframe)
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   628
            if w<=_FUZZ or h<=_FUZZ: continue
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
   629
            W = max(W,min(w,availWidth) if fakeWidth else w)
2561
a2409b6627e6 reportlab: added FlowablesAndImage
rgbecker
parents: 2557
diff changeset
   630
            H += h
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   631
            if not atTop:
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   632
                h = f.getSpaceBefore()
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   633
                if mergeSpace:
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   634
                    if getattr(f,'_SPACETRANSFER',False):
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   635
                        h = pS
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   636
                    h = max(h-pS,0)
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   637
                H += h
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   638
            else:
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   639
                if obj is not None: obj._spaceBefore = f.getSpaceBefore()
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   640
                atTop = 0
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   641
            s = f.getSpaceAfter()
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   642
            if getattr(f,'_SPACETRANSFER',False):
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   643
                s = pS
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   644
            pS = s
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   645
            H += pS
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   646
        if obj is not None: obj._spaceAfter = pS
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   647
        return W, H-pS
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   648
    finally:
3158
a5ecc0cae476 flowables.py: fix special case of doctemplate with no frames
rgbecker
parents: 3031
diff changeset
   649
        if cframe:
3009
71ae9bbac9fb reportlab: attempt fix to docIf vs keepTogether
rgbecker
parents: 3007
diff changeset
   650
            doct.frame = doct_frame
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   651
2449
47b15f941325 platypus: attempt to make KeepTogether/keepWithNext more robust
rgbecker
parents: 2408
diff changeset
   652
def _flowableSublist(V):
2392
6c59b0eb312d table color cycle changes
andy
parents: 2388
diff changeset
   653
    "if it isn't a list or tuple, wrap it in a list"
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   654
    if not isinstance(V,(list,tuple)): V = V is not None and [V] or []
3975
4a3599863c11 eliminate from . imports in favour of absolutes to allow running modules
robin
parents: 3781
diff changeset
   655
    from reportlab.platypus.doctemplate import LCActionFlowable
2451
19bf750c3c26 flowables.py: fix 2.1 breakage
rgbecker
parents: 2450
diff changeset
   656
    assert not [x for x in V if isinstance(x,LCActionFlowable)],'LCActionFlowables not allowed in sublists'
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   657
    return V
558
f9013e25af9d Added a random text module
andy_robinson
parents: 557
diff changeset
   658
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   659
class _ContainerSpace:  #Abstract some common container like behaviour
4485
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
   660
    def getSpaceBefore(self,content=None):
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
   661
        for c in (self._content if content is None else content):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   662
            if not hasattr(c,'frameAction'):
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   663
                return c.getSpaceBefore()
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   664
        return 0
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   665
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   666
    def getSpaceAfter(self,content=None):
4485
25ccda4eb3d3 use dodgy backpatching to allow FrameBG to have a border; version-->3.5.15
robin <robin@reportlab.com>
parents: 4478
diff changeset
   667
        for c in reversed(self._content if content is None else content):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   668
            if not hasattr(c,'frameAction'):
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   669
                return c.getSpaceAfter()
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   670
        return 0
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   671
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   672
class KeepTogether(_ContainerSpace,Flowable):
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   673
    splitAtTop = False
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   674
1994
fdb2334c338a Attempt to allow for overlong KeepTogethers
rgbecker
parents: 1917
diff changeset
   675
    def __init__(self,flowables,maxHeight=None):
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   676
        if not hasattr(KeepTogether,'NullActionFlowable'):
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   677
            #cache these on the class
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   678
            from reportlab.platypus.doctemplate import NullActionFlowable
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   679
            from reportlab.platypus.doctemplate import FrameBreak
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   680
            from reportlab.lib.utils import annotateException
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   681
            KeepTogether.NullActionFlowable = NullActionFlowable
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   682
            KeepTogether.FrameBreak = FrameBreak
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   683
            KeepTogether.annotateException = annotateException
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   684
4278
5aa80e7cdba8 add NullActionFlowable, fix empty KeepTogether, version-->3.3.12
robin
parents: 4252
diff changeset
   685
        if not flowables:
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   686
            flowables = [self.NullActionFlowable()]
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   687
        self._content = _flowableSublist(flowables)
1994
fdb2334c338a Attempt to allow for overlong KeepTogethers
rgbecker
parents: 1917
diff changeset
   688
        self._maxHeight = maxHeight
367
ca1adb0294f0 Added KeepTogether
rgbecker
parents: 307
diff changeset
   689
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   690
    def __repr__(self):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   691
        f = self._content
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3686
diff changeset
   692
        L = list(map(repr,f))
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   693
        L = "\n"+"\n".join(L)
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   694
        L = L.replace("\n", "\n  ")
3342
ce7e1ab56a22 flowables.py small improvement to exception texts
rgbecker
parents: 3326
diff changeset
   695
        return "%s(%s,maxHeight=%s)" % (self.__class__.__name__,L,self._maxHeight)
541
33de80b3655c added __repr__s and enhanced exception messages for debugging
aaron_watters
parents: 512
diff changeset
   696
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   697
    def wrap(self, aW, aH):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   698
        dims = []
4279
f69571262c74 fix fake KeepTogether setup in handle_keepWithNext; version--> 3.3.13
robin
parents: 4278
diff changeset
   699
        try:
f69571262c74 fix fake KeepTogether setup in handle_keepWithNext; version--> 3.3.13
robin
parents: 4278
diff changeset
   700
            W,H = _listWrapOn(self._content,aW,self.canv,dims=dims)
f69571262c74 fix fake KeepTogether setup in handle_keepWithNext; version--> 3.3.13
robin
parents: 4278
diff changeset
   701
        except:
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   702
            self.annotateException('\nraised by class %s(%s)@0x%8.8x wrap\n' % (self.__class__.__name__,self.__class__.__module__,id(self)))
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   703
        self._H = H
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   704
        self._H0 = dims and dims[0][1] or 0
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   705
        self._wrapInfo = aW,aH
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   706
        return W, 0xffffff  # force a split
367
ca1adb0294f0 Added KeepTogether
rgbecker
parents: 307
diff changeset
   707
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   708
    def split(self, aW, aH):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   709
        if getattr(self,'_wrapInfo',None)!=(aW,aH): self.wrap(aW,aH)
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   710
        S = self._content[:]
4514
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   711
        cf = atTop = getattr(self,'_frame',None)
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   712
        if cf:
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   713
            atTop = getattr(cf,'_atTop',None)
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   714
            cAW = cf._width
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   715
            cAH = cf._height
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   716
        C0 = self._H>aH and (not self._maxHeight or aH>self._maxHeight)
3537
187f4e0c072a flowables.py: fix KeepTogether to work better, allow Spacer to be glue
rgbecker
parents: 3528
diff changeset
   717
        C1 = (self._H0>aH) or C0 and atTop
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   718
        if C0 or C1:
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   719
            fb = False
4514
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   720
            panf = self._doctemplateAttr('_peekNextFrame')
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   721
            if cf and panf:
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   722
                nf = panf()
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   723
                nAW = nf._width
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   724
                nAH = nf._height
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   725
            if C0 and not (self.splitAtTop and atTop):
4514
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   726
                fb = not (atTop and cf and nf and cAW>=nAW and cAH>=nAH)
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   727
            elif nf and nAW>=cf._width and nAH>=self._H:
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   728
                fb = True
4514
465cf62799ef attempt to fix Marius Gedminas' issue 184; version --> 3.5.23
robin <robin@reportlab.com>
parents: 4494
diff changeset
   729
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   730
            S.insert(0,(self.FrameBreak if fb else self.NullActionFlowable)())
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   731
        return S
367
ca1adb0294f0 Added KeepTogether
rgbecker
parents: 307
diff changeset
   732
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   733
    def identity(self, maxLen=None):
3342
ce7e1ab56a22 flowables.py small improvement to exception texts
rgbecker
parents: 3326
diff changeset
   734
        msg = "<%s at %s%s> containing :%s" % (self.__class__.__name__,hex(id(self)),self._frameName(),"\n".join([f.identity() for f in self._content]))
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   735
        if maxLen:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   736
            return msg[0:maxLen]
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   737
        else:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   738
            return msg
2461
9c24d39d05e8 enhanced decimal alignment
andy
parents: 2451
diff changeset
   739
4380
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   740
class KeepTogetherSplitAtTop(KeepTogether):
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   741
    '''
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   742
    Same as KeepTogether, but it will split content immediately if it cannot
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   743
    fit at the top of a frame.
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   744
    '''
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   745
    splitAtTop = True
831ee16f2338 improvements to keepTogether & added peek frame/template methods; issue started by Андрија Зарић lisandrija @ bitbucket.org
rptlab
parents: 4370
diff changeset
   746
253
cfcf8d555a2c Platypus re-organisation
rgbecker
parents:
diff changeset
   747
class Macro(Flowable):
1677
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   748
    """This is not actually drawn (i.e. it has zero height)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   749
    but is executed when it would fit in the frame.  Allows direct
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   750
    access to the canvas through the object 'canvas'"""
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   751
    def __init__(self, command):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   752
        self.command = command
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   753
    def __repr__(self):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   754
        return "Macro(%s)" % repr(self.command)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   755
    def wrap(self, availWidth, availHeight):
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   756
        return (0,0)
1450177dd19e Exterminated all tab characters and added a test to make sure
andy_robinson
parents: 1554
diff changeset
   757
    def draw(self):
4551
d357e2acc856 improve usage of eval/exec; version --> 3.5.32
robin
parents: 4535
diff changeset
   758
        exec(self.command, safer_globals(), {'canvas':self.canv})
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   759
4139
4ccb98329659 flowables.py: fix CallableMacro repr
robin
parents: 4122
diff changeset
   760
def _nullCallable(*args,**kwds):
4ccb98329659 flowables.py: fix CallableMacro repr
robin
parents: 4122
diff changeset
   761
    pass
4ccb98329659 flowables.py: fix CallableMacro repr
robin
parents: 4122
diff changeset
   762
2403
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   763
class CallerMacro(Flowable):
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   764
    '''
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   765
    like Macro, but with callable command(s)
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   766
    drawCallable(self)
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   767
    wrapCallable(self,aW,aH)
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   768
    '''
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   769
    def __init__(self, drawCallable=None, wrapCallable=None):
4139
4ccb98329659 flowables.py: fix CallableMacro repr
robin
parents: 4122
diff changeset
   770
        self._drawCallable = drawCallable or _nullCallable
4ccb98329659 flowables.py: fix CallableMacro repr
robin
parents: 4122
diff changeset
   771
        self._wrapCallable = wrapCallable or _nullCallable
2403
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   772
    def __repr__(self):
4139
4ccb98329659 flowables.py: fix CallableMacro repr
robin
parents: 4122
diff changeset
   773
        return "CallerMacro(%r,%r)" % (self._drawCallable,self._wrapCallable)
2403
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   774
    def wrap(self, aW, aH):
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   775
        self._wrapCallable(self,aW,aH)
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   776
        return (0,0)
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   777
    def draw(self):
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   778
        self._drawCallable(self)
cbfa501fb840 canvasadapter.py fixes
rgbecker
parents: 2392
diff changeset
   779
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   780
class ParagraphAndImage(Flowable):
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   781
    '''combine a Paragraph and an Image'''
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   782
    def __init__(self,P,I,xpad=3,ypad=3,side='right'):
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   783
        self.P = P
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   784
        self.I = I
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   785
        self.xpad = xpad
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   786
        self.ypad = ypad
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   787
        self._side = side
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   788
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   789
    def getSpaceBefore(self):
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   790
        return max(self.P.getSpaceBefore(),self.I.getSpaceBefore())
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   791
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   792
    def getSpaceAfter(self):
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   793
        return max(self.P.getSpaceAfter(),self.I.getSpaceAfter())
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   794
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   795
    def wrap(self,availWidth,availHeight):
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   796
        wI, hI = self.I.wrap(availWidth,availHeight)
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   797
        self.wI = wI
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   798
        self.hI = hI
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   799
        # work out widths array for breaking
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   800
        self.width = availWidth
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   801
        P = self.P
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   802
        style = P.style
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   803
        xpad = self.xpad
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   804
        ypad = self.ypad
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   805
        leading = style.leading
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   806
        leftIndent = style.leftIndent
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   807
        later_widths = availWidth - leftIndent - style.rightIndent
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   808
        intermediate_widths = later_widths - xpad - wI
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   809
        first_line_width = intermediate_widths - style.firstLineIndent
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   810
        P.width = 0
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3321
diff changeset
   811
        nIW = int((hI+ypad)/(leading*1.0))
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   812
        P.blPara = P.breakLines([first_line_width] + nIW*[intermediate_widths]+[later_widths])
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   813
        if self._side=='left':
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   814
            self._offsets = [wI+xpad]*(1+nIW)+[0]
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   815
        P.height = len(P.blPara.lines)*leading
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   816
        self.height = max(hI,P.height)
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   817
        return (self.width, self.height)
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   818
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   819
    def split(self,availWidth, availHeight):
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   820
        P, wI, hI, ypad = self.P, self.wI, self.hI, self.ypad
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   821
        if hI+ypad>availHeight or len(P.frags)<=0: return []
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   822
        S = P.split(availWidth,availHeight)
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   823
        if not S: return S
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   824
        P = self.P = S[0]
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   825
        del S[0]
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   826
        style = P.style
1768
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   827
        P.height = len(self.P.blPara.lines)*style.leading
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   828
        self.height = max(hI,P.height)
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   829
        return [self]+S
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   830
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   831
    def draw(self):
ea95b92748cc Added ParagraphAndImage
rgbecker
parents: 1683
diff changeset
   832
        canv = self.canv
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   833
        if self._side=='left':
4285
401929501337 fix ypad use in ParagraphAndImage contrib annamarianfr@bitbucket, version-->3.3.16
robin
parents: 4279
diff changeset
   834
            self.I.drawOn(canv,0,self.height-self.hI-self.ypad)
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   835
            self.P._offsets = self._offsets
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   836
            try:
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   837
                self.P.drawOn(canv,0,0)
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   838
            finally:
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   839
                del self.P._offsets
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   840
        else:
4285
401929501337 fix ypad use in ParagraphAndImage contrib annamarianfr@bitbucket, version-->3.3.16
robin
parents: 4279
diff changeset
   841
            self.I.drawOn(canv,self.width-self.wI-self.xpad,self.height-self.hI-self.ypad)
2557
d84c18fb377f added _offsets handling to paragraph for flow around on left side
rgbecker
parents: 2542
diff changeset
   842
            self.P.drawOn(canv,0,0)
2113
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   843
2955
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   844
class FailOnWrap(NullDraw):
2113
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   845
    def wrap(self, availWidth, availHeight):
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   846
        raise ValueError("FailOnWrap flowable wrapped and failing as ordered!")
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2192
diff changeset
   847
2113
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   848
class FailOnDraw(Flowable):
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   849
    def wrap(self, availWidth, availHeight):
2955
cc16265295fb reportlab: start of doc programming
rgbecker
parents: 2950
diff changeset
   850
        return 0,0
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2192
diff changeset
   851
2113
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   852
    def draw(self):
e82d8b3880d8 Preliminary support for tracing through doc builds
andy_robinson
parents: 2080
diff changeset
   853
        raise ValueError("FailOnDraw flowable drawn, and failing as ordered!")
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   854
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   855
class HRFlowable(Flowable):
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   856
    '''Like the hr tag'''
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   857
    def __init__(self,
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   858
            width="80%",
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   859
            thickness=1,
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   860
            lineCap='round',
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   861
            color=lightgrey,
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   862
            spaceBefore=1, spaceAfter=1,
2523
0473810aff11 platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents: 2461
diff changeset
   863
            hAlign='CENTER', vAlign='BOTTOM',
0473810aff11 platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents: 2461
diff changeset
   864
            dash=None):
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   865
        Flowable.__init__(self)
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   866
        self.width = width
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   867
        self.lineWidth = thickness
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   868
        self.lineCap=lineCap
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   869
        self.spaceBefore = spaceBefore
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   870
        self.spaceAfter = spaceAfter
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   871
        self.color = color
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   872
        self.hAlign = hAlign
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   873
        self.vAlign = vAlign
2523
0473810aff11 platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents: 2461
diff changeset
   874
        self.dash = dash
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   875
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   876
    def __repr__(self):
2284
b181b45c6792 Minor changes
rgbecker
parents: 2276
diff changeset
   877
        return "HRFlowable(width=%s, height=%s)" % (self.width, self.height)
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   878
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   879
    def wrap(self, availWidth, availHeight):
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   880
        w = self.width
4352
fd9ca874bf30 fix _bulletFormat; version --> 3.4.8
robin <robin@reportlab.com>
parents: 4348
diff changeset
   881
        if isinstance(w,strTypes):
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   882
            w = w.strip()
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   883
            if w.endswith('%'): w = availWidth*float(w[:-1])*0.01
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   884
            else: w = float(w)
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   885
        w = min(w,availWidth)
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   886
        self._width = w
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   887
        return w, self.lineWidth
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   888
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   889
    def draw(self):
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   890
        canv = self.canv
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   891
        canv.saveState()
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   892
        canv.setLineWidth(self.lineWidth)
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   893
        canv.setLineCap({'butt':0,'round':1, 'square': 2}[self.lineCap.lower()])
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   894
        canv.setStrokeColor(self.color)
2523
0473810aff11 platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents: 2461
diff changeset
   895
        if self.dash: canv.setDash(self.dash)
2276
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   896
        canv.line(0, 0, self._width, self.height)
10fc2ce1114f Added HRFlowable
rgbecker
parents: 2241
diff changeset
   897
        canv.restoreState()
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   898
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   899
class _PTOInfo:
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   900
    def __init__(self,trailer,header):
2449
47b15f941325 platypus: attempt to make KeepTogether/keepWithNext more robust
rgbecker
parents: 2408
diff changeset
   901
        self.trailer = _flowableSublist(trailer)
47b15f941325 platypus: attempt to make KeepTogether/keepWithNext more robust
rgbecker
parents: 2408
diff changeset
   902
        self.header = _flowableSublist(header)
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   903
2873
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   904
def cdeepcopy(obj):
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   905
    if hasattr(obj,'deepcopy'):
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   906
        return obj.deepcopy()
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   907
    else:
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   908
        return deepcopy(obj)
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   909
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
   910
class _Container(_ContainerSpace):  #Abstract some common container like behaviour
2561
a2409b6627e6 reportlab: added FlowablesAndImage
rgbecker
parents: 2557
diff changeset
   911
    def drawOn(self, canv, x, y, _sW=0, scale=1.0, content=None, aW=None):
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   912
        '''we simulate being added to a frame'''
3975
4a3599863c11 eliminate from . imports in favour of absolutes to allow running modules
robin
parents: 3781
diff changeset
   913
        from reportlab.platypus.doctemplate import ActionFlowable, Indenter
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   914
        x0 = x
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   915
        y0 = y
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   916
        pS = 0
2561
a2409b6627e6 reportlab: added FlowablesAndImage
rgbecker
parents: 2557
diff changeset
   917
        if aW is None: aW = self.width
3182
511218046ef9 flowables.py: try and fix positioning in KeepInFrame
rgbecker
parents: 3158
diff changeset
   918
        aW *= scale
2561
a2409b6627e6 reportlab: added FlowablesAndImage
rgbecker
parents: 2557
diff changeset
   919
        if content is None:
a2409b6627e6 reportlab: added FlowablesAndImage
rgbecker
parents: 2557
diff changeset
   920
            content = self._content
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   921
        x = self._hAlignAdjust(x,_sW*scale)
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   922
        y += self.height*scale
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   923
        yt = y
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   924
        frame = getattr(self,'_frame',None)
2561
a2409b6627e6 reportlab: added FlowablesAndImage
rgbecker
parents: 2557
diff changeset
   925
        for c in content:
3366
352fcf51cb21 reportlab: added in ignoreContainerFlowables
rgbecker
parents: 3344
diff changeset
   926
            if not ignoreContainerActions and isinstance(c,ActionFlowable):
4486
b5673e9d2876 fix frame background stroking for the container case. version --> 3.5.16
robin <robin@reportlab.com>
parents: 4485
diff changeset
   927
                c.apply(canv._doctemplate)
3366
352fcf51cb21 reportlab: added in ignoreContainerFlowables
rgbecker
parents: 3344
diff changeset
   928
                continue
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   929
            if isinstance(c,Indenter):
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   930
                x += c.left*scale
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   931
                aW -= (c.left+c.right)*scale
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   932
                continue
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   933
            w, h = c.wrapOn(canv,aW,0xfffffff)
2750
05229265aff3 reportlab: fix special case <a> tag problem, add AnchorFlowable class
rgbecker
parents: 2695
diff changeset
   934
            if (w<_FUZZ or h<_FUZZ) and not getattr(c,'_ZEROSIZE',None): continue
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   935
            if yt!=y:
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   936
                s = c.getSpaceBefore()
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   937
                if not getattr(c,'_SPACETRANSFER',False):
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   938
                    h += max(s-pS,0)
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   939
            y -= h
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   940
            s = c.getSpaceAfter()
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   941
            if getattr(c,'_SPACETRANSFER',False):
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   942
                s = pS
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   943
            pS = s
4487
a895aa70fa64 more work on FrameBG versus BalancedColumns; version-->3.5.17
robin <robin@reportlab.com>
parents: 4486
diff changeset
   944
            fbg = getattr(frame,'_frameBGs',None)
a895aa70fa64 more work on FrameBG versus BalancedColumns; version-->3.5.17
robin <robin@reportlab.com>
parents: 4486
diff changeset
   945
            if fbg and fbg[-1].active:
4486
b5673e9d2876 fix frame background stroking for the container case. version --> 3.5.16
robin <robin@reportlab.com>
parents: 4485
diff changeset
   946
                bg = fbg[-1]
b5673e9d2876 fix frame background stroking for the container case. version --> 3.5.16
robin <robin@reportlab.com>
parents: 4485
diff changeset
   947
                fbgl = bg.left
b5673e9d2876 fix frame background stroking for the container case. version --> 3.5.16
robin <robin@reportlab.com>
parents: 4485
diff changeset
   948
                fbgr = bg.right
b5673e9d2876 fix frame background stroking for the container case. version --> 3.5.16
robin <robin@reportlab.com>
parents: 4485
diff changeset
   949
                bgm = bg.start
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   950
                fbw = scale*(frame._width-fbgl-fbgr)
4494
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   951
                fbx = x0+scale*(fbgl-frame._leftPadding)
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   952
                fbh = y + h + pS
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   953
                fby = max(y0,y-pS)
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   954
                fbh = max(0,fbh-fby)
4494
7850f3baf921 improvements to FrameBG handling _FBGBag etc; version --> 3.5.18
robin <robin@reportlab.com>
parents: 4487
diff changeset
   955
                bg.render(canv,frame,fbx,fby,fbw,fbh)
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   956
            c._frame = frame
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
   957
            c.drawOn(canv,x,y,_sW=aW-w)
3750
63d5d0c8665e flowables.py & frames.py: attempt to improve handling of various Zero size flowables
robin
parents: 3736
diff changeset
   958
            if c is not content[-1] and not getattr(c,'_SPACETRANSFER',None):
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   959
                y -= pS
4033
480bd0313eb0 flowables.py: ensure _frame is removed and add availableWidth to container drawon call
robin
parents: 3975
diff changeset
   960
            del c._frame
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   961
2873
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   962
    def copyContent(self,content=None):
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   963
        C = [].append
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   964
        for c in (content or self._content):
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   965
            C(cdeepcopy(c))
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   966
        self._content = C.__self__
0fcfd487c548 flowables.py: start on fix for copying problems in imageAndFlowables
rgbecker
parents: 2851
diff changeset
   967
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
   968
class PTOContainer(_Container,Flowable):
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   969
    '''PTOContainer(contentList,trailerList,headerList)
2762
48eadc6faff2 platypus: added in NotAtTopPageBreak and support
rgbecker
parents: 2750
diff changeset
   970
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   971
    A container for flowables decorated with trailer & header lists.
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   972
    If the split operation would be called then the trailer and header
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   973
    lists are injected before and after the split. This allows specialist
2762
48eadc6faff2 platypus: added in NotAtTopPageBreak and support
rgbecker
parents: 2750
diff changeset
   974
    "please turn over" and "continued from previous" like behaviours.'''
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   975
    def __init__(self,content,trailer=None,header=None):
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   976
        I = _PTOInfo(trailer,header)
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   977
        self._content = C = []
2449
47b15f941325 platypus: attempt to make KeepTogether/keepWithNext more robust
rgbecker
parents: 2408
diff changeset
   978
        for _ in _flowableSublist(content):
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   979
            if isinstance(_,PTOContainer):
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   980
                C.extend(_._content)
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   981
            else:
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   982
                C.append(_)
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   983
                if not hasattr(_,'_ptoinfo'): _._ptoinfo = I
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   984
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   985
    def wrap(self,availWidth,availHeight):
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   986
        self.width, self.height = _listWrapOn(self._content,availWidth,self.canv)
2384
6d44252e1042 platypus: added ptocontainer, moved tables test
rgbecker
parents: 2376
diff changeset
   987
        return self.width,self.height
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   988
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   989
    def split(self, availWidth, availHeight):
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   990
        from reportlab.platypus.doctemplate import Indenter
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   991
        if availHeight<0: return []
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   992
        canv = self.canv
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
   993
        C = self._content
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
   994
        x = i = H = pS = hx = 0
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   995
        n = len(C)
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   996
        I2W = {}
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
   997
        dLeft = dRight = 0
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
   998
        for x in xrange(n):
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
   999
            c = C[x]
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1000
            I = c._ptoinfo
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1001
            if I not in I2W.keys():
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1002
                T = I.trailer
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1003
                Hdr = I.header
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1004
                tW, tH = _listWrapOn(T, availWidth, self.canv)
2694
dd0ea6474ea0 fixes to crashing PTO trailer when empty, and numbering
andy
parents: 2662
diff changeset
  1005
                if len(T):  #trailer may have no content
dd0ea6474ea0 fixes to crashing PTO trailer when empty, and numbering
andy
parents: 2662
diff changeset
  1006
                    tSB = T[0].getSpaceBefore()
dd0ea6474ea0 fixes to crashing PTO trailer when empty, and numbering
andy
parents: 2662
diff changeset
  1007
                else:
dd0ea6474ea0 fixes to crashing PTO trailer when empty, and numbering
andy
parents: 2662
diff changeset
  1008
                    tSB = 0
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1009
                I2W[I] = T,tW,tH,tSB
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1010
            else:
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1011
                T,tW,tH,tSB = I2W[I]
2384
6d44252e1042 platypus: added ptocontainer, moved tables test
rgbecker
parents: 2376
diff changeset
  1012
            _, h = c.wrapOn(canv,availWidth,0xfffffff)
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1013
            if isinstance(c,Indenter):
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1014
                dw = c.left+c.right
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1015
                dLeft += c.left
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1016
                dRight += c.right
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1017
                availWidth -= dw
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1018
                pS = 0
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1019
                hx = 0
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1020
            else:
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1021
                if x:
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1022
                    hx = max(c.getSpaceBefore()-pS,0)
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1023
                    h += hx
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1024
                pS = c.getSpaceAfter()
2384
6d44252e1042 platypus: added ptocontainer, moved tables test
rgbecker
parents: 2376
diff changeset
  1025
            H += h+pS
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
  1026
            tHS = tH+max(tSB,pS)
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
  1027
            if H+tHS>=availHeight-_FUZZ: break
2384
6d44252e1042 platypus: added ptocontainer, moved tables test
rgbecker
parents: 2376
diff changeset
  1028
            i += 1
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1029
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1030
        #first retract last thing we tried
2384
6d44252e1042 platypus: added ptocontainer, moved tables test
rgbecker
parents: 2376
diff changeset
  1031
        H -= (h+pS)
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1032
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1033
        #attempt a sub split on the last one we have
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
  1034
        aH = (availHeight-H-tHS-hx)*0.99999
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1035
        if aH>=0.05*availHeight:
2387
75caa41a818f platypus/test: working pto (& inner pto)
rgbecker
parents: 2384
diff changeset
  1036
            SS = c.splitOn(canv,availWidth,aH)
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1037
        else:
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1038
            SS = []
2788
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1039
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1040
        if abs(dLeft)+abs(dRight)>1e-8:
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1041
            R1I = [Indenter(-dLeft,-dRight)]
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1042
            R2I = [Indenter(dLeft,dRight)]
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1043
        else:
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1044
            R1I = R2I = []
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1045
2788
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1046
        if not SS:
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1047
            j = i
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1048
            while i>1 and C[i-1].getKeepWithNext():
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1049
                i -= 1
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1050
                C[i].keepWithNext = 0
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1051
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1052
            if i==1 and C[0].getKeepWithNext():
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1053
                #robin's black sheep
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1054
                i = j
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1055
                C[0].keepWithNext = 0
e245da8fbe2b flowables: allow for keepWithNext in PTO
rgbecker
parents: 2773
diff changeset
  1056
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
  1057
        F = [UseUpSpace()]
2376
7e70411a7236 flowables.py: minor change to PTOContainer
rgbecker
parents: 2375
diff changeset
  1058
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
  1059
        if len(SS)>1:
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1060
            R1 = C[:i]+SS[:1]+R1I+T+F
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1061
            R2 = Hdr+R2I+SS[1:]+C[i+1:]
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1062
        elif not i:
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1063
            return []
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1064
        else:
3686
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1065
            R1 = C[:i]+R1I+T+F
0ef2cb9578d7 add support for Indenter in PTOs
robin
parents: 3663
diff changeset
  1066
            R2 = Hdr+R2I+C[i:]
2834
8bafca0cc650 flowables.py: use semi-deep copy for PTO split
rgbecker
parents: 2788
diff changeset
  1067
        T =  R1 + [PTOContainer(R2,[copy(x) for x in I.trailer],[copy(x) for x in I.header])]
2535
714a951e4f64 flowables.py: fixes to PTOContainer
rgbecker
parents: 2534
diff changeset
  1068
        return T
2375
1e175a4474d0 platypus: almost finished PTOContainer
rgbecker
parents: 2341
diff changeset
  1069
2528
39a609be559a renamed FrameFlowable to KeepInFrame
andy
parents: 2527
diff changeset
  1070
#utility functions used by KeepInFrame
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1071
def _hmodel(s0,s1,h0,h1):
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1072
    # calculate the parameters in the model
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1073
    # h = a/s**2 + b/s
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1074
    a11 = 1./s0**2
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1075
    a12 = 1./s0
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1076
    a21 = 1./s1**2
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1077
    a22 = 1./s1
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1078
    det = a11*a22-a12*a21
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1079
    b11 = a22/det
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1080
    b12 = -a12/det
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1081
    b21 = -a21/det
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1082
    b22 = a11/det
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1083
    a = b11*h0+b12*h1
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1084
    b = b21*h0+b22*h1
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1085
    return a,b
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1086
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3321
diff changeset
  1087
def _qsolve(h,ab):
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1088
    '''solve the model v = a/s**2 + b/s for an s which gives us v==h'''
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3321
diff changeset
  1089
    a,b = ab
2569
f7ac857ad20d flowables.py: attempt to fix up keepInFrame for one more case
rgbecker
parents: 2562
diff changeset
  1090
    if abs(a)<=_FUZZ:
f7ac857ad20d flowables.py: attempt to fix up keepInFrame for one more case
rgbecker
parents: 2562
diff changeset
  1091
        return b/h
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1092
    t = 0.5*b/a
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1093
    from math import sqrt
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1094
    f = -h/a
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1095
    r = t*t-f
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1096
    if r<0: return None
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1097
    r = sqrt(r)
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1098
    if t>=0:
2762
48eadc6faff2 platypus: added in NotAtTopPageBreak and support
rgbecker
parents: 2750
diff changeset
  1099
        s1 = -t - r
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1100
    else:
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1101
        s1 = -t + r
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1102
    s2 = f/s1
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1103
    return max(1./s1, 1./s2)
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1104
2528
39a609be559a renamed FrameFlowable to KeepInFrame
andy
parents: 2527
diff changeset
  1105
class KeepInFrame(_Container,Flowable):
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1106
    def __init__(self, maxWidth, maxHeight, content=[], mergeSpace=1, mode='shrink', name='',hAlign='LEFT',vAlign='BOTTOM', fakeWidth=None):
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1107
        '''mode describes the action to take when overflowing
2529
dced304f8584 flowables.py: keepInFrame now truncates etc properly, doctemplate.py: fix handle_frameEnd
rgbecker
parents: 2528
diff changeset
  1108
            error       raise an error in the normal way
dced304f8584 flowables.py: keepInFrame now truncates etc properly, doctemplate.py: fix handle_frameEnd
rgbecker
parents: 2528
diff changeset
  1109
            continue    ignore ie just draw it and report maxWidth, maxHeight
dced304f8584 flowables.py: keepInFrame now truncates etc properly, doctemplate.py: fix handle_frameEnd
rgbecker
parents: 2528
diff changeset
  1110
            shrink      shrinkToFit
dced304f8584 flowables.py: keepInFrame now truncates etc properly, doctemplate.py: fix handle_frameEnd
rgbecker
parents: 2528
diff changeset
  1111
            truncate    fit as much as possible
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1112
            set fakeWidth to False to make _listWrapOn do the 'right' thing
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1113
        '''
2531
40b6f4b41f7c platypus: changes to make identity more useful
rgbecker
parents: 2529
diff changeset
  1114
        self.name = name
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1115
        self.maxWidth = maxWidth
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1116
        self.maxHeight = maxHeight
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1117
        self.mode = mode
2529
dced304f8584 flowables.py: keepInFrame now truncates etc properly, doctemplate.py: fix handle_frameEnd
rgbecker
parents: 2528
diff changeset
  1118
        assert mode in ('error','overflow','shrink','truncate'), '%s invalid mode value %s' % (self.identity(),mode)
2528
39a609be559a renamed FrameFlowable to KeepInFrame
andy
parents: 2527
diff changeset
  1119
        assert maxHeight>=0,  '%s invalid maxHeight value %s' % (self.identity(),maxHeight)
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1120
        if mergeSpace is None: mergeSpace = overlapAttachedSpace
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1121
        self.mergespace = mergeSpace
3272
10f6899a18a5 reportlab: attempt to eliminate empty list argument issues bug contributed by Tim Roberts and Nate Silva
rgbecker
parents: 3184
diff changeset
  1122
        self._content = content or []
3184
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
  1123
        self.vAlign = vAlign
b410e045f2fc platypus: fix KeepInFrame justification
rgbecker
parents: 3182
diff changeset
  1124
        self.hAlign = hAlign
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1125
        self.fakeWidth = fakeWidth
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1126
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1127
    def _getAvailableWidth(self):
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1128
        return self.maxWidth - self._leftExtraIndent - self._rightExtraIndent
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1129
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1130
    def identity(self, maxLen=None):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
  1131
        return "<%s at %s%s%s> size=%sx%s" % (self.__class__.__name__, hex(id(self)), self._frameName(),
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
  1132
                getattr(self,'name','') and (' name="%s"'% getattr(self,'name','')) or '',
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
  1133
                getattr(self,'maxWidth','') and (' maxWidth=%s'%fp_str(getattr(self,'maxWidth',0))) or '',
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2569
diff changeset
  1134
                getattr(self,'maxHeight','')and (' maxHeight=%s' % fp_str(getattr(self,'maxHeight')))or '')
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1135
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1136
    def wrap(self,availWidth,availHeight):
3975
4a3599863c11 eliminate from . imports in favour of absolutes to allow running modules
robin
parents: 3781
diff changeset
  1137
        from reportlab.platypus.doctemplate import LayoutError
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1138
        mode = self.mode
2695
feb999d5dbd1 flowables.py: fix KeepInFrame behaviour to be more rational
rgbecker
parents: 2694
diff changeset
  1139
        maxWidth = float(min(self.maxWidth or availWidth,availWidth))
feb999d5dbd1 flowables.py: fix KeepInFrame behaviour to be more rational
rgbecker
parents: 2694
diff changeset
  1140
        maxHeight = float(min(self.maxHeight or availHeight,availHeight))
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1141
        fakeWidth = self.fakeWidth
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1142
        W, H = _listWrapOn(self._content,maxWidth,self.canv, fakeWidth=fakeWidth)
2695
feb999d5dbd1 flowables.py: fix KeepInFrame behaviour to be more rational
rgbecker
parents: 2694
diff changeset
  1143
        if (mode=='error' and (W>maxWidth+_FUZZ or H>maxHeight+_FUZZ)):
2534
809c000dbbb3 platypus: fixup KeepInFrame error handling
rgbecker
parents: 2533
diff changeset
  1144
            ident = 'content %sx%s too large for %s' % (W,H,self.identity(30))
809c000dbbb3 platypus: fixup KeepInFrame error handling
rgbecker
parents: 2533
diff changeset
  1145
            #leave to keep apart from the raise
809c000dbbb3 platypus: fixup KeepInFrame error handling
rgbecker
parents: 2533
diff changeset
  1146
            raise LayoutError(ident)
2695
feb999d5dbd1 flowables.py: fix KeepInFrame behaviour to be more rational
rgbecker
parents: 2694
diff changeset
  1147
        elif W<=maxWidth+_FUZZ and H<=maxHeight+_FUZZ:
2534
809c000dbbb3 platypus: fixup KeepInFrame error handling
rgbecker
parents: 2533
diff changeset
  1148
            self.width = W-_FUZZ      #we take what we get
809c000dbbb3 platypus: fixup KeepInFrame error handling
rgbecker
parents: 2533
diff changeset
  1149
            self.height = H-_FUZZ
2529
dced304f8584 flowables.py: keepInFrame now truncates etc properly, doctemplate.py: fix handle_frameEnd
rgbecker
parents: 2528
diff changeset
  1150
        elif mode in ('overflow','truncate'):   #we lie
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1151
            self.width = min(maxWidth,W)-_FUZZ
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1152
            self.height = min(maxHeight,H)-_FUZZ
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1153
        else:
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1154
            def func(x):
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1155
                x = float(x)
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1156
                W, H = _listWrapOn(self._content,x*maxWidth,self.canv, fakeWidth=fakeWidth)
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1157
                W /= x
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1158
                H /= x
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1159
                return W, H
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1160
            W0 = W
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1161
            H0 = H
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1162
            s0 = 1
2527
edff938c5e89 flowablse.py: minor fix and hack to FrameFlowable
rgbecker
parents: 2526
diff changeset
  1163
            if W>maxWidth+_FUZZ:
2569
f7ac857ad20d flowables.py: attempt to fix up keepInFrame for one more case
rgbecker
parents: 2562
diff changeset
  1164
                #squeeze out the excess width and or Height
4108
893cd2c16ec1 flowables.py: make width behaviour of _listWrapOn more controllable, add rl_settings.listWrapOnFakeWidth & bump version to 3.1.16
robin
parents: 4067
diff changeset
  1165
                s1 = W/maxWidth     #linear model
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1166
                W, H = func(s1)
2569
f7ac857ad20d flowables.py: attempt to fix up keepInFrame for one more case
rgbecker
parents: 2562
diff changeset
  1167
                if H<=maxHeight+_FUZZ:
f7ac857ad20d flowables.py: attempt to fix up keepInFrame for one more case
rgbecker
parents: 2562
diff changeset
  1168
                    self.width = W-_FUZZ
f7ac857ad20d flowables.py: attempt to fix up keepInFrame for one more case
rgbecker
parents: 2562
diff changeset
  1169
                    self.height = H-_FUZZ
2525
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1170
                    self._scale = s1
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: 2523
diff changeset
  1171
                    return W,H
634ec1f48514 platypus: initial FrameFlowable implementation
rgbecker
parents: