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