author | rptlab |
Tue, 30 Apr 2013 14:28:14 +0100 | |
branch | py33 |
changeset 3723 | 99aa837b6703 |
parent 3721 | 0c93dd8ff567 |
child 3731 | b233dd0577ff |
permissions | -rwxr-xr-x |
3617 | 1 |
#Copyright ReportLab Europe Ltd. 2000-2012 |
494 | 2 |
#see license.txt for license details |
2316
022b6622b686
Early 2.x has no UnicodeDecodeError and no ''.decode
robin
parents:
2315
diff
changeset
|
3 |
__version__=''' $Id$ ''' |
1683 | 4 |
__doc__=""" |
681 | 5 |
The Canvas object is the primary interface for creating PDF files. See |
3063 | 6 |
doc/reportlab-userguide.pdf for copious examples. |
0 | 7 |
""" |
3026 | 8 |
|
9 |
__all__ = ['Canvas'] |
|
928
47d97c066df2
canvas coordinate matrix tracking and related linkage support
aaron_watters
parents:
905
diff
changeset
|
10 |
ENABLE_TRACKING = 1 # turn this off to do profile testing w/o tracking |
562 | 11 |
|
0 | 12 |
import os |
13 |
import sys |
|
2461 | 14 |
import re |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
15 |
import hashlib |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
16 |
from string import digits |
0 | 17 |
import tempfile |
18 |
from math import sin, cos, tan, pi, ceil |
|
724 | 19 |
from reportlab import rl_config |
10 | 20 |
from reportlab.pdfbase import pdfutils |
21 |
from reportlab.pdfbase import pdfdoc |
|
22 |
from reportlab.pdfbase import pdfmetrics |
|
16 | 23 |
from reportlab.pdfgen import pdfgeom, pathobject, textobject |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
24 |
from reportlab.lib.colors import black, _chooseEnforceColorSpace, Color, CMYKColor, toColor |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
25 |
from reportlab.lib.utils import import_zlib, ImageReader, fp_str, isSeqType, isStrType, isUnicodeType, _digester |
3092 | 26 |
from reportlab.lib.boxstuff import aspectRatioFix |
2461 | 27 |
|
28 |
digitPat = re.compile('\d') #used in decimal alignment |
|
673 | 29 |
zlib = import_zlib() |
69 | 30 |
|
0 | 31 |
# Robert Kern |
32 |
# Constants for closing paths. |
|
33 |
# May be useful if one changes 'arc' and 'rect' to take a |
|
34 |
# default argument that tells how to close the path. |
|
35 |
# That way we can draw filled shapes. |
|
36 |
||
37 |
FILL_EVEN_ODD = 0 |
|
38 |
FILL_NON_ZERO = 1 |
|
39 |
#this is used by path-closing routines. |
|
40 |
#map stroke, fill, fillmode -> operator |
|
41 |
# fillmode: 1 = non-Zero (obviously), 0 = evenOdd |
|
42 |
PATH_OPS = {(0, 0, FILL_EVEN_ODD) : 'n', #no op |
|
43 |
(0, 0, FILL_NON_ZERO) : 'n', #no op |
|
44 |
(1, 0, FILL_EVEN_ODD) : 'S', #stroke only |
|
45 |
(1, 0, FILL_NON_ZERO) : 'S', #stroke only |
|
46 |
(0, 1, FILL_EVEN_ODD) : 'f*', #Fill only |
|
47 |
(0, 1, FILL_NON_ZERO) : 'f', #Fill only |
|
48 |
(1, 1, FILL_EVEN_ODD) : 'B*', #Stroke and Fill |
|
49 |
(1, 1, FILL_NON_ZERO) : 'B', #Stroke and Fill |
|
50 |
} |
|
51 |
||
1066 | 52 |
_escapePDF = pdfutils._escape |
53 |
_instanceEscapePDF = pdfutils._instanceEscapePDF |
|
989 | 54 |
|
2777
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
55 |
def _annFormat(D,color,thickness,dashArray,hradius=0,vradius=0): |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
56 |
from reportlab.pdfbase.pdfdoc import PDFArray, PDFDictionary |
3326 | 57 |
if color and 'C' not in D: |
2575 | 58 |
D["C"] = PDFArray([color.red, color.green, color.blue]) |
3326 | 59 |
if 'Border' not in D: |
2778 | 60 |
border = [hradius,vradius,thickness or 0] |
61 |
if dashArray: |
|
62 |
border.append(PDFArray(dashArray)) |
|
63 |
D["Border"] = PDFArray(border) |
|
2777
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
64 |
# BS = PDFDictionary() |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
65 |
# bss = 'S' |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
66 |
# if dashArray: |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
67 |
# BS['D'] = PDFArray(dashArray) |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
68 |
# bss = 'D' |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
69 |
# BS['W'] = thickness or 0 |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
70 |
# BS['S'] = bss |
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
71 |
# D['BS'] = BS |
2575 | 72 |
|
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
73 |
# helpers to guess color space for gradients |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
74 |
def _normalizeColor(aColor): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
75 |
if isinstance(aColor, CMYKColor): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
76 |
d = aColor.density |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
77 |
return "DeviceCMYK", tuple(c*d for c in aColor.cmyk()) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
78 |
elif isinstance(aColor, Color): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
79 |
return "DeviceRGB", aColor.rgb() |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
80 |
elif isinstance(aColor, (tuple, list)): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
81 |
l = len(aColor) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
82 |
if l == 3: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
83 |
return "DeviceRGB", aColor |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
84 |
elif l == 4: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
85 |
return "DeviceCMYK", aColor |
3721 | 86 |
elif isinstance(aColor, str): |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
87 |
return _normalizeColor(toColor(aColor)) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
88 |
raise ValueError("Unknown color %r" % aColor) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
89 |
|
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
90 |
def _normalizeColors(colors): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
91 |
space = None |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
92 |
outcolors = [] |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
93 |
for aColor in colors: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
94 |
nspace, outcolor = _normalizeColor(aColor) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
95 |
if space is not None and space != nspace: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
96 |
raise ValueError("Mismatch in color spaces: %s and %s" % (space, nspace)) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
97 |
space = nspace |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
98 |
outcolors.append(outcolor) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
99 |
return space, outcolors |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
100 |
|
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
101 |
def _buildColorFunction(colors, positions): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
102 |
from reportlab.pdfbase.pdfdoc import PDFExponentialFunction, PDFStitchingFunction |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
103 |
if positions is not None and len(positions) != len(colors): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
104 |
raise ValueError("need to have the same number of colors and positions") |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
105 |
# simplified functions for edge cases |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
106 |
if len(colors) == 1: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
107 |
# for completeness |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
108 |
return PDFExponentialFunction(N=1, C0=colors[0], C1=colors[0]) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
109 |
if len(colors) == 2: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
110 |
if positions is None or (positions[0] == 0 and positions[1] == 1): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
111 |
return PDFExponentialFunction(N=1, C0=colors[0], C1=colors[1]) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
112 |
# equally distribute if positions not specified |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
113 |
if positions is None: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
114 |
nc = len(colors) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
115 |
positions = [(1.0*x)/(nc-1) for x in range(nc)] |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
116 |
else: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
117 |
# sort positions and colors in increasing order |
3721 | 118 |
poscolors = list(zip(positions, colors)) |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
119 |
poscolors.sort(key=lambda x: x[0]) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
120 |
# add endpoint positions if not already present |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
121 |
if poscolors[0][0] != 0: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
122 |
poscolors.insert(0, (0.0, poscolors[0][1])) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
123 |
if poscolors[-1][0] != 1: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
124 |
poscolors.append((1.0, poscolors[-1][1])) |
3721 | 125 |
positions, colors = list(zip(*poscolors)) # unzip |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
126 |
# build stitching function |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
127 |
functions = [] |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
128 |
bounds = [pos for pos in positions[1:-1]] |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
129 |
encode = [] |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
130 |
lastcolor = colors[0] |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
131 |
for color in colors[1:]: |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
132 |
functions.append(PDFExponentialFunction(N=1, C0=lastcolor, C1=color)) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
133 |
lastcolor = color |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
134 |
encode.append(0.0) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
135 |
encode.append(1.0) |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
136 |
return PDFStitchingFunction(functions, bounds, encode, Domain="[0.0 1.0]") |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
137 |
|
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
138 |
class ExtGState: |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
139 |
defaults = dict( |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
140 |
CA=1, |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
141 |
ca=1, |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
142 |
OP=False, |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
143 |
op=False, |
3416 | 144 |
OPM=0, |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
145 |
) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
146 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
147 |
def __init__(self): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
148 |
self._d = {} |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
149 |
self._c = {} |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
150 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
151 |
def set(self,canv,a,v): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
152 |
d = self.defaults[a] |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
153 |
isbool = isinstance(d,bool) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
154 |
if isbool: v=bool(v) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
155 |
if v!=self._d.get(a,d) or (a=='op' and self.getValue('OP')!=d): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
156 |
self._d[a] = v |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
157 |
if isbool: v=str(v).lower() |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
158 |
t = a,v |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
159 |
if t in self._c: |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
160 |
name = self._c[t] |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
161 |
else: |
3422
f42ce6f3d1aa
canvas.py: try to make the Extended Graphics State names more unique :(
rptlab
parents:
3417
diff
changeset
|
162 |
name = 'gRLs'+str(len(self._c)) |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
163 |
self._c[t] = name |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
164 |
canv._code.append('/%s gs' % name) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
165 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
166 |
def getValue(self,a): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
167 |
return self._d.get(a,self.defaults[a]) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
168 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
169 |
def getState(self): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
170 |
S = {} |
3721 | 171 |
for t,name in self._c.items(): |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
172 |
S[name] = pdfdoc.PDFDictionary(dict((t,))) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
173 |
return S and pdfdoc.PDFDictionary(S) or None |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
174 |
|
3273
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
175 |
def pushCopy(self): |
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
176 |
'''the states must be shared across push/pop, but the values not''' |
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
177 |
x = self.__class__() |
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
178 |
x._d = self._d.copy() |
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
179 |
x._c = self._c |
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
180 |
return x |
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
181 |
|
3337 | 182 |
class Canvas(textobject._PDFColorSetter): |
262 | 183 |
"""This class is the programmer's interface to the PDF file format. Methods |
184 |
are (or will be) provided here to do just about everything PDF can do. |
|
1683 | 185 |
|
260 | 186 |
The underlying model to the canvas concept is that of a graphics state machine |
187 |
that at any given point in time has a current font, fill color (for figure |
|
188 |
interiors), stroke color (for figure borders), line width and geometric transform, among |
|
189 |
many other characteristics. |
|
1683 | 190 |
|
260 | 191 |
Canvas methods generally either draw something (like canvas.line) using the |
192 |
current state of the canvas or change some component of the canvas |
|
193 |
state (like canvas.setFont). The current state can be saved and restored |
|
194 |
using the saveState/restoreState methods. |
|
1683 | 195 |
|
260 | 196 |
Objects are "painted" in the order they are drawn so if, for example |
197 |
two rectangles overlap the last draw will appear "on top". PDF form |
|
198 |
objects (supported here) are used to draw complex drawings only once, |
|
199 |
for possible repeated use. |
|
1683 | 200 |
|
260 | 201 |
There are other features of canvas which are not visible when printed, |
202 |
such as outlines and bookmarks which are used for navigating a document |
|
203 |
in a viewer. |
|
1683 | 204 |
|
260 | 205 |
Here is a very silly example usage which generates a Hello World pdf document. |
1683 | 206 |
|
3350 | 207 |
Example:: |
208 |
||
209 |
from reportlab.pdfgen import canvas |
|
210 |
c = canvas.Canvas("hello.pdf") |
|
211 |
from reportlab.lib.units import inch |
|
212 |
# move the origin up and to the left |
|
213 |
c.translate(inch,inch) |
|
214 |
# define a large font |
|
215 |
c.setFont("Helvetica", 80) |
|
216 |
# choose some colors |
|
217 |
c.setStrokeColorRGB(0.2,0.5,0.3) |
|
218 |
c.setFillColorRGB(1,0,1) |
|
219 |
# draw a rectangle |
|
220 |
c.rect(inch,inch,6*inch,9*inch, fill=1) |
|
221 |
# make text go straight up |
|
222 |
c.rotate(90) |
|
223 |
# change color |
|
224 |
c.setFillColorRGB(0,0,0.77) |
|
225 |
# say hello (note after rotate the y coord needs to be negative!) |
|
226 |
c.drawString(3*inch, -3*inch, "Hello World") |
|
227 |
c.showPage() |
|
228 |
c.save() |
|
229 |
||
0 | 230 |
""" |
1683 | 231 |
|
100
b98a1487daad
Color methods in textobject and canvas now synchronised.
andy_robinson
parents:
77
diff
changeset
|
232 |
def __init__(self,filename, |
2020
982b43f6a27e
Fix up Canvas argument processing so defaults are dynamically taken
rgbecker
parents:
1976
diff
changeset
|
233 |
pagesize=None, |
100
b98a1487daad
Color methods in textobject and canvas now synchronised.
andy_robinson
parents:
77
diff
changeset
|
234 |
bottomup = 1, |
1005 | 235 |
pageCompression=None, |
2020
982b43f6a27e
Fix up Canvas argument processing so defaults are dynamically taken
rgbecker
parents:
1976
diff
changeset
|
236 |
invariant = None, |
3036
a1edc1b5d3ec
Add userPass and ownerPass parameters to Canvas constructor.
jonas
parents:
3034
diff
changeset
|
237 |
verbosity=0, |
3110 | 238 |
encrypt=None, |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
239 |
cropMarks=None, |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
240 |
pdfVersion=None, |
3443
64d1fba94908
reportlab: added preliminary support for enforcing color spaces
rgbecker
parents:
3425
diff
changeset
|
241 |
enforceColorSpace=None, |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
242 |
): |
260 | 243 |
"""Create a canvas of a given size. etc. |
2461 | 244 |
|
245 |
You may pass a file-like object to filename as an alternative to |
|
246 |
a string. |
|
3050 | 247 |
For more information about the encrypt parameter refer to the setEncrypt method. |
2461 | 248 |
|
260 | 249 |
Most of the attributes are private - we will use set/get methods |
3110 | 250 |
as the preferred interface. Default page size is A4. |
251 |
cropMarks may be True/False or an object with parameters borderWidth, markColor, markWidth |
|
252 |
and markLength |
|
3443
64d1fba94908
reportlab: added preliminary support for enforcing color spaces
rgbecker
parents:
3425
diff
changeset
|
253 |
|
3444
bea839deb0c1
reportlab: initial checkin for colorspace handling
rgbecker
parents:
3443
diff
changeset
|
254 |
if enforceColorSpace is in ('cmyk', 'rgb', 'sep','sep_black','sep_cmyk') then one of |
bea839deb0c1
reportlab: initial checkin for colorspace handling
rgbecker
parents:
3443
diff
changeset
|
255 |
the standard _PDFColorSetter callables will be used to enforce appropriate color settings. |
bea839deb0c1
reportlab: initial checkin for colorspace handling
rgbecker
parents:
3443
diff
changeset
|
256 |
If it is a callable then that will be used. |
3110 | 257 |
""" |
2021 | 258 |
if pagesize is None: pagesize = rl_config.defaultPageSize |
2020
982b43f6a27e
Fix up Canvas argument processing so defaults are dynamically taken
rgbecker
parents:
1976
diff
changeset
|
259 |
if invariant is None: invariant = rl_config.invariant |
0 | 260 |
self._filename = filename |
2575 | 261 |
|
262 |
self._doc = pdfdoc.PDFDocument(compression=pageCompression, |
|
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
263 |
invariant=invariant, filename=filename, |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
264 |
pdfVersion=pdfVersion or pdfdoc.PDF_VERSION_DEFAULT, |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
265 |
) |
1857 | 266 |
|
3444
bea839deb0c1
reportlab: initial checkin for colorspace handling
rgbecker
parents:
3443
diff
changeset
|
267 |
self._enforceColorSpace = _chooseEnforceColorSpace(enforceColorSpace) |
3443
64d1fba94908
reportlab: added preliminary support for enforcing color spaces
rgbecker
parents:
3425
diff
changeset
|
268 |
|
100
b98a1487daad
Color methods in textobject and canvas now synchronised.
andy_robinson
parents:
77
diff
changeset
|
269 |
#this only controls whether it prints 'saved ...' - 0 disables |
b98a1487daad
Color methods in textobject and canvas now synchronised.
andy_robinson
parents:
77
diff
changeset
|
270 |
self._verbosity = verbosity |
181
62d7a443cbc4
Added font encoding support and changed default encoding to WinAnsi
andy_robinson
parents:
179
diff
changeset
|
271 |
|
1502 | 272 |
#this is called each time a page is output if non-null |
273 |
self._onPage = None |
|
3110 | 274 |
self._cropMarks = cropMarks |
1683 | 275 |
|
0 | 276 |
self._pagesize = pagesize |
1887 | 277 |
self._pageRotation = 0 |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
278 |
#self._currentPageHasImages = 0 |
500 | 279 |
self._pageTransition = None |
1770
1c91caccd7e3
Added pageDuration feature for automatic slide transitions
andy_robinson
parents:
1689
diff
changeset
|
280 |
self._pageDuration = None |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
281 |
self._destinations = {} # dictionary of destinations for cross indexing. |
0 | 282 |
|
176 | 283 |
self.setPageCompression(pageCompression) |
0 | 284 |
self._pageNumber = 1 # keep a count |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
285 |
# when we create a form we need to save operations not in the form |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
286 |
self._codeStack = [] |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
287 |
self._restartAccumulators() # restart all accumulation state (generalized, arw) |
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
288 |
self._annotationCount = 0 |
77
a5d452cb7a5d
Removed some old comments; tweaks to experimental Outline methods.
andy_robinson
parents:
70
diff
changeset
|
289 |
|
a5d452cb7a5d
Removed some old comments; tweaks to experimental Outline methods.
andy_robinson
parents:
70
diff
changeset
|
290 |
self._outlines = [] # list for a name tree |
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
291 |
self._psCommandsBeforePage = [] #for postscript tray/font commands |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
292 |
self._psCommandsAfterPage = [] #for postscript tray/font commands |
1683 | 293 |
|
0 | 294 |
#PostScript has the origin at bottom left. It is easy to achieve a top- |
295 |
#down coord system by translating to the top of the page and setting y |
|
296 |
#scale to -1, but then text is inverted. So self.bottomup is used |
|
297 |
#to also set the text matrix accordingly. You can now choose your |
|
298 |
#drawing coordinates. |
|
299 |
self.bottomup = bottomup |
|
735
5dffc9c425d6
Made imageCaching a positive quantity and proeprty of the canvas
rgbecker
parents:
724
diff
changeset
|
300 |
self.imageCaching = rl_config.defaultImageCaching |
2765
1a4f58018bc8
canvas.py: fix long standing bug involving initial font setting
rgbecker
parents:
2718
diff
changeset
|
301 |
self.init_graphics_state() |
20 | 302 |
self._make_preamble() |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
303 |
self.state_stack = [] |
0 | 304 |
|
3048
3ff2383916b9
Renamed setencrypt to setEncrypt to follow naming convention.
jonas
parents:
3040
diff
changeset
|
305 |
self.setEncrypt(encrypt) |
3040 | 306 |
|
3048
3ff2383916b9
Renamed setencrypt to setEncrypt to follow naming convention.
jonas
parents:
3040
diff
changeset
|
307 |
def setEncrypt(self, encrypt): |
3050 | 308 |
''' |
309 |
Set the encryption used for the pdf generated by this canvas. |
|
310 |
If encrypt is a string object, it is used as the user password for the pdf. |
|
311 |
If encrypt is an instance of reportlab.lib.pdfencrypt.StandardEncryption, this object is |
|
312 |
used to encrypt the pdf. This allows more finegrained control over the encryption settings. |
|
313 |
''' |
|
3037
e014e27ec331
Canvas now accepts an encrypt parameter (user password or StandardEncryption object).
jonas
parents:
3036
diff
changeset
|
314 |
if encrypt: |
3036
a1edc1b5d3ec
Add userPass and ownerPass parameters to Canvas constructor.
jonas
parents:
3034
diff
changeset
|
315 |
from reportlab.lib import pdfencrypt |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
316 |
if isStrType(encrypt): #encrypt is the password itself |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
317 |
if isUnicodeType(encrypt): |
3081 | 318 |
encrypt = encrypt.encode('utf-8') |
319 |
encrypt = pdfencrypt.StandardEncryption(encrypt) #now it's the encrypt object |
|
3037
e014e27ec331
Canvas now accepts an encrypt parameter (user password or StandardEncryption object).
jonas
parents:
3036
diff
changeset
|
320 |
encrypt.setAllPermissions(1) |
e014e27ec331
Canvas now accepts an encrypt parameter (user password or StandardEncryption object).
jonas
parents:
3036
diff
changeset
|
321 |
elif not isinstance(encrypt, pdfencrypt.StandardEncryption): |
3050 | 322 |
raise TypeError('Expected string or instance of reportlab.lib.pdfencrypt.StandardEncryption as encrypt parameter but got %r' % encrypt) |
3036
a1edc1b5d3ec
Add userPass and ownerPass parameters to Canvas constructor.
jonas
parents:
3034
diff
changeset
|
323 |
self._doc.encrypt = encrypt |
3040 | 324 |
else: |
325 |
try: |
|
326 |
del self._doc.encrypt |
|
327 |
except AttributeError: |
|
328 |
pass |
|
3036
a1edc1b5d3ec
Add userPass and ownerPass parameters to Canvas constructor.
jonas
parents:
3034
diff
changeset
|
329 |
|
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
330 |
def init_graphics_state(self): |
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
331 |
#initial graphics state, never modify any of these in place |
0 | 332 |
self._x = 0 |
333 |
self._y = 0 |
|
2889 | 334 |
self._fontname = rl_config.canvas_basefontname |
0 | 335 |
self._fontsize = 12 |
2575 | 336 |
|
0 | 337 |
self._textMode = 0 #track if between BT/ET |
338 |
self._leading = 14.4 |
|
339 |
self._currentMatrix = (1., 0., 0., 1., 0., 0.) |
|
340 |
self._fillMode = 0 #even-odd |
|
1683 | 341 |
|
342 |
#text state |
|
0 | 343 |
self._charSpace = 0 |
344 |
self._wordSpace = 0 |
|
345 |
self._horizScale = 100 |
|
346 |
self._textRenderMode = 0 |
|
347 |
self._rise = 0 |
|
348 |
self._textLineMatrix = (1., 0., 0., 1., 0., 0.) |
|
349 |
self._textMatrix = (1., 0., 0., 1., 0., 0.) |
|
350 |
||
1683 | 351 |
# line drawing |
0 | 352 |
self._lineCap = 0 |
353 |
self._lineJoin = 0 |
|
354 |
self._lineDash = None #not done |
|
355 |
self._lineWidth = 0 |
|
356 |
self._mitreLimit = 0 |
|
357 |
||
3254
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
358 |
self._fillColorObj = self._strokeColorObj = rl_config.canvas_baseColor or (0,0,0) |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
359 |
self._extgstate = ExtGState() |
0 | 360 |
|
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
361 |
def push_state_stack(self): |
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
362 |
state = {} |
1476 | 363 |
d = self.__dict__ |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
364 |
for name in self.STATE_ATTRIBUTES: |
1476 | 365 |
state[name] = d[name] #getattr(self, name) |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
366 |
self.state_stack.append(state) |
3273
5a996758fbce
canvas.py: make the extgstate work across push/pop_state_stack pairs
rgbecker
parents:
3254
diff
changeset
|
367 |
self._extgstate = self._extgstate.pushCopy() |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
368 |
|
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
369 |
def pop_state_stack(self): |
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
370 |
state = self.state_stack[-1] |
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
371 |
del self.state_stack[-1] |
1476 | 372 |
d = self.__dict__ |
373 |
d.update(state) |
|
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
374 |
|
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
375 |
STATE_ATTRIBUTES = """_x _y _fontname _fontsize _textMode _leading _currentMatrix _fillMode |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
376 |
_fillMode _charSpace _wordSpace _horizScale _textRenderMode _rise _textLineMatrix |
3254
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
377 |
_textMatrix _lineCap _lineJoin _lineDash _lineWidth _mitreLimit _fillColorObj |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
378 |
_strokeColorObj _extgstate""".split() |
3721 | 379 |
STATE_RANGE = list(range(len(STATE_ATTRIBUTES))) |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
380 |
|
873 | 381 |
#self._addStandardFonts() |
1683 | 382 |
|
20 | 383 |
def _make_preamble(self): |
2890 | 384 |
P = [].append |
20 | 385 |
if self.bottomup: |
2890 | 386 |
P('1 0 0 1 0 0 cm') |
20 | 387 |
else: |
2890 | 388 |
P('1 0 0 -1 0 %s cm' % fp_str(self._pagesize[1])) |
3254
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
389 |
C = self._code |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
390 |
n = len(C) |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
391 |
if self._fillColorObj != (0,0,0): |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
392 |
self.setFillColor(self._fillColorObj) |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
393 |
if self._strokeColorObj != (0,0,0): |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
394 |
self.setStrokeColor(self._strokeColorObj) |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
395 |
P(' '.join(C[n:])) |
dd9042134279
canvas.py, textobject.py: merge _*ColorRGB/CMYK attributes into ColorObj
rgbecker
parents:
3226
diff
changeset
|
396 |
del C[n:] |
2890 | 397 |
font = pdfmetrics.getFont(self._fontname) |
398 |
if not font._dynamicFont: |
|
399 |
#set an initial font |
|
3336
95a1489dbfe4
canvas.py: add in some minor control on font setting
rgbecker
parents:
3326
diff
changeset
|
400 |
if font.face.builtIn or not getattr(self,'_drawTextAsPath',False): |
95a1489dbfe4
canvas.py: add in some minor control on font setting
rgbecker
parents:
3326
diff
changeset
|
401 |
P('BT %s 12 Tf 14.4 TL ET' % self._doc.getInternalFontName(self._fontname)) |
2890 | 402 |
self._preamble = ' '.join(P.__self__) |
20 | 403 |
|
1066 | 404 |
if not _instanceEscapePDF: |
405 |
def _escape(self, s): |
|
406 |
return _escapePDF(s) |
|
0 | 407 |
|
408 |
#info functions - non-standard |
|
409 |
def setAuthor(self, author): |
|
260 | 410 |
"""identify the author for invisible embedding inside the PDF document. |
411 |
the author annotation will appear in the the text of the file but will |
|
2595 | 412 |
not automatically be seen when the document is viewed, but is visible |
413 |
in document properties etc etc.""" |
|
0 | 414 |
self._doc.setAuthor(author) |
77
a5d452cb7a5d
Removed some old comments; tweaks to experimental Outline methods.
andy_robinson
parents:
70
diff
changeset
|
415 |
|
2595 | 416 |
def setDateFormatter(self, dateFormatter): |
417 |
"""accepts a func(yyyy,mm,dd,hh,m,s) used to create embedded formatted date""" |
|
418 |
self._doc.setDateFormatter(dateFormatter) |
|
419 |
||
420 |
def addOutlineEntry(self, title, key, level=0, closed=None): |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
421 |
"""Adds a new entry to the outline at given level. If LEVEL not specified, |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
422 |
entry goes at the top level. If level specified, it must be |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
423 |
no more than 1 greater than the outline level in the last call. |
1683 | 424 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
425 |
The key must be the (unique) name of a bookmark. |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
426 |
the title is the (non-unique) name to be displayed for the entry. |
1683 | 427 |
|
166 | 428 |
If closed is set then the entry should show no subsections by default |
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
429 |
when displayed. |
1683 | 430 |
|
3030 | 431 |
Example:: |
432 |
||
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
433 |
c.addOutlineEntry("first section", "section1") |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
434 |
c.addOutlineEntry("introduction", "s1s1", 1, closed=1) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
435 |
c.addOutlineEntry("body", "s1s2", 1) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
436 |
c.addOutlineEntry("detail1", "s1s2s1", 2) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
437 |
c.addOutlineEntry("detail2", "s1s2s2", 2) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
438 |
c.addOutlineEntry("conclusion", "s1s3", 1) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
439 |
c.addOutlineEntry("further reading", "s1s3s1", 2) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
440 |
c.addOutlineEntry("second section", "section1") |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
441 |
c.addOutlineEntry("introduction", "s2s1", 1) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
442 |
c.addOutlineEntry("body", "s2s2", 1, closed=1) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
443 |
c.addOutlineEntry("detail1", "s2s2s1", 2) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
444 |
c.addOutlineEntry("detail2", "s2s2s2", 2) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
445 |
c.addOutlineEntry("conclusion", "s2s3", 1) |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
446 |
c.addOutlineEntry("further reading", "s2s3s1", 2) |
1683 | 447 |
|
3030 | 448 |
generated outline looks like:: |
449 |
||
260 | 450 |
- first section |
451 |
|- introduction |
|
452 |
|- body |
|
453 |
| |- detail1 |
|
454 |
| |- detail2 |
|
455 |
|- conclusion |
|
456 |
| |- further reading |
|
457 |
- second section |
|
458 |
|- introduction |
|
459 |
|+ body |
|
460 |
|- conclusion |
|
461 |
| |- further reading |
|
1683 | 462 |
|
260 | 463 |
Note that the second "body" is closed. |
1683 | 464 |
|
260 | 465 |
Note that you can jump from level 5 to level 3 but not |
136 | 466 |
from 3 to 5: instead you need to provide all intervening |
467 |
levels going down (4 in this case). Note that titles can |
|
468 |
collide but keys cannot. |
|
469 |
""" |
|
77
a5d452cb7a5d
Removed some old comments; tweaks to experimental Outline methods.
andy_robinson
parents:
70
diff
changeset
|
470 |
#to be completed |
136 | 471 |
#self._outlines.append(title) |
2595 | 472 |
self._doc.outline.addOutlineEntry(key, level, title, closed=closed) |
1683 | 473 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
474 |
def setOutlineNames0(self, *nametree): # keep this for now (?) |
3030 | 475 |
"""nametree should can be a recursive tree like so:: |
476 |
||
477 |
c.setOutlineNames( |
|
478 |
"chapter1dest", |
|
479 |
("chapter2dest", |
|
480 |
["chapter2section1dest", |
|
481 |
"chapter2section2dest", |
|
482 |
"chapter2conclusiondest"] |
|
483 |
), # end of chapter2 description |
|
484 |
"chapter3dest", |
|
485 |
("chapter4dest", ["c4s1", "c4s2"]) |
|
486 |
) |
|
487 |
||
60 | 488 |
each of the string names inside must be bound to a bookmark |
489 |
before the document is generated. |
|
490 |
""" |
|
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
491 |
self._doc.outline.setNames(*((self,)+nametree)) |
1683 | 492 |
|
0 | 493 |
def setTitle(self, title): |
260 | 494 |
"""write a title into the PDF file that won't automatically display |
495 |
in the document itself.""" |
|
0 | 496 |
self._doc.setTitle(title) |
1683 | 497 |
|
0 | 498 |
def setSubject(self, subject): |
260 | 499 |
"""write a subject into the PDF file that won't automatically display |
500 |
in the document itself.""" |
|
0 | 501 |
self._doc.setSubject(subject) |
1683 | 502 |
|
3456 | 503 |
def setCreator(self, creator): |
504 |
"""write a creator into the PDF file that won't automatically display |
|
505 |
in the document itself. This should be used to name the original app |
|
506 |
which is passing data into ReportLab, if you wish to name it.""" |
|
507 |
self._doc.setCreator(creator) |
|
508 |
||
2666 | 509 |
def setKeywords(self, keywords): |
510 |
"""write a list of keywords into the PDF file which shows in document properties. |
|
511 |
Either submit a single string or a list/tuple""" |
|
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3142
diff
changeset
|
512 |
if isinstance(keywords,(list,tuple)): |
2666 | 513 |
keywords = ', '.join(keywords) |
514 |
self._doc.setKeywords(keywords) |
|
515 |
||
0 | 516 |
def pageHasData(self): |
517 |
"Info function - app can call it after showPage to see if it needs a save" |
|
518 |
return len(self._code) == 0 |
|
1683 | 519 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
520 |
def showOutline(self): |
479 | 521 |
"""Specify that Acrobat Reader should start with the outline tree visible. |
522 |
showFullScreen() and showOutline() conflict; the one called last |
|
523 |
wins.""" |
|
60 | 524 |
self._doc._catalog.showOutline() |
1683 | 525 |
|
479 | 526 |
def showFullScreen0(self): |
527 |
"""Specify that Acrobat Reader should start in full screen mode. |
|
528 |
showFullScreen() and showOutline() conflict; the one called last |
|
529 |
wins.""" |
|
530 |
self._doc._catalog.showFullScreen() |
|
531 |
||
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
532 |
def _setStrokeAlpha(self,v): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
533 |
""" |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
534 |
Define the transparency/opacity of strokes. 0 is fully |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
535 |
transparent, 1 is fully opaque. |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
536 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
537 |
Note that calling this function will cause a version 1.4 PDF |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
538 |
to be generated (rather than 1.3). |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
539 |
""" |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
540 |
self._doc.ensureMinPdfVersion('transparency') |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
541 |
self._extgstate.set(self,'CA',v) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
542 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
543 |
def _setFillAlpha(self,v): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
544 |
""" |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
545 |
Define the transparency/opacity of non-strokes. 0 is fully |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
546 |
transparent, 1 is fully opaque. |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
547 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
548 |
Note that calling this function will cause a version 1.4 PDF |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
549 |
to be generated (rather than 1.3). |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
550 |
""" |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
551 |
self._doc.ensureMinPdfVersion('transparency') |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
552 |
self._extgstate.set(self,'ca',v) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
553 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
554 |
def _setStrokeOverprint(self,v): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
555 |
self._extgstate.set(self,'OP',v) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
556 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
557 |
def _setFillOverprint(self,v): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
558 |
self._extgstate.set(self,'op',v) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
559 |
|
3417 | 560 |
def _setOverprintMask(self,v): |
561 |
self._extgstate.set(self,'OPM',v and 1 or 0) |
|
562 |
||
3142
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
563 |
def _getCmShift(self): |
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
564 |
cM = self._cropMarks |
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
565 |
if cM: |
3425 | 566 |
bleedW = max(0,getattr(cM,'bleedWidth',0)) |
567 |
bw = max(0,getattr(cM,'borderWidth',36)) |
|
568 |
if bleedW: |
|
569 |
bw -= bleedW |
|
3142
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
570 |
return bw |
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
571 |
|
0 | 572 |
def showPage(self): |
260 | 573 |
"""Close the current page and possibly start on a new page.""" |
873 | 574 |
# ensure a space at the end of the stream - Acrobat does |
575 |
# not mind, but Ghostscript dislikes 'Qendstream' even if |
|
576 |
# the length marker finishes after 'Q' |
|
3109 | 577 |
|
578 |
pageWidth = self._pagesize[0] |
|
579 |
pageHeight = self._pagesize[1] |
|
580 |
cM = self._cropMarks |
|
581 |
code = self._code |
|
582 |
if cM: |
|
3425 | 583 |
bw = max(0,getattr(cM,'borderWidth',36)) |
3110 | 584 |
if bw: |
3425 | 585 |
markLast = getattr(cM,'markLast',1) |
586 |
ml = min(bw,max(0,getattr(cM,'markLength',18))) |
|
3110 | 587 |
mw = getattr(cM,'markWidth',0.5) |
588 |
mc = getattr(cM,'markColor',black) |
|
3425 | 589 |
mg = 2*bw-ml |
3110 | 590 |
cx0 = len(code) |
591 |
if ml and mc: |
|
592 |
self.saveState() |
|
593 |
self.setStrokeColor(mc) |
|
594 |
self.setLineWidth(mw) |
|
595 |
self.lines([ |
|
3425 | 596 |
(bw,0,bw,ml), |
597 |
(pageWidth+bw,0,pageWidth+bw,ml), |
|
598 |
(bw,pageHeight+mg,bw,pageHeight+2*bw), |
|
599 |
(pageWidth+bw,pageHeight+mg,pageWidth+bw,pageHeight+2*bw), |
|
600 |
(0,bw,ml,bw), |
|
601 |
(pageWidth+mg,bw,pageWidth+2*bw,bw), |
|
602 |
(0,pageHeight+bw,ml,pageHeight+bw), |
|
603 |
(pageWidth+mg,pageHeight+bw,pageWidth+2*bw,pageHeight+bw), |
|
3110 | 604 |
]) |
605 |
self.restoreState() |
|
3425 | 606 |
if markLast: |
607 |
#if the marks are to be drawn after the content |
|
608 |
#save the code we just drew for later use |
|
609 |
L = code[cx0:] |
|
610 |
del code[cx0:] |
|
611 |
cx0 = len(code) |
|
612 |
||
613 |
bleedW = max(0,getattr(cM,'bleedWidth',0)) |
|
614 |
self.saveState() |
|
615 |
self.translate(bw-bleedW,bw-bleedW) |
|
616 |
if bleedW: |
|
617 |
#scale everything |
|
618 |
self.scale(1+(2.0*bleedW)/pageWidth,1+(2.0*bleedW)/pageHeight) |
|
619 |
||
620 |
#move our translation/expansion code to the beginning |
|
621 |
C = code[cx0:] |
|
622 |
del code[cx0:] |
|
3110 | 623 |
code[0:0] = C |
3109 | 624 |
self.restoreState() |
3425 | 625 |
if markLast: |
626 |
code.extend(L) |
|
627 |
pageWidth = 2*bw + pageWidth |
|
628 |
pageHeight = 2*bw + pageHeight |
|
3109 | 629 |
|
630 |
code.append(' ') |
|
0 | 631 |
page = pdfdoc.PDFPage() |
3109 | 632 |
page.pagewidth = pageWidth |
633 |
page.pageheight = pageHeight |
|
1887 | 634 |
page.Rotate = self._pageRotation |
0 | 635 |
page.hasImages = self._currentPageHasImages |
500 | 636 |
page.setPageTransition(self._pageTransition) |
0 | 637 |
page.setCompression(self._pageCompression) |
1770
1c91caccd7e3
Added pageDuration feature for automatic slide transitions
andy_robinson
parents:
1689
diff
changeset
|
638 |
if self._pageDuration is not None: |
1c91caccd7e3
Added pageDuration feature for automatic slide transitions
andy_robinson
parents:
1689
diff
changeset
|
639 |
page.Dur = self._pageDuration |
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
640 |
|
3109 | 641 |
strm = self._psCommandsBeforePage + [self._preamble] + code + self._psCommandsAfterPage |
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
642 |
page.setStream(strm) |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
643 |
self._setColorSpace(page) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
644 |
self._setExtGState(page) |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
645 |
self._setXObjects(page) |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
646 |
self._setShadingUsed(page) |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
647 |
self._setAnnotations(page) |
0 | 648 |
self._doc.addPage(page) |
1502 | 649 |
|
2197 | 650 |
if self._onPage: self._onPage(self._pageNumber) |
651 |
self._startPage() |
|
652 |
||
653 |
def _startPage(self): |
|
0 | 654 |
#now get ready for the next one |
3081 | 655 |
self._pageNumber += 1 |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
656 |
self._restartAccumulators() |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
657 |
self.init_graphics_state() |
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
658 |
self.state_stack = [] |
1502 | 659 |
|
660 |
def setPageCallBack(self, func): |
|
661 |
"""func(pageNum) will be called on each page end. |
|
1683 | 662 |
|
1502 | 663 |
This is mainly a hook for progress monitoring. |
664 |
Call setPageCallback(None) to clear a callback.""" |
|
665 |
self._onPage = func |
|
1683 | 666 |
|
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
667 |
def _setAnnotations(self,page): |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
668 |
page.Annots = self._annotationrefs |
1683 | 669 |
|
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
670 |
def _setColorSpace(self,obj): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
671 |
obj._colorsUsed = self._colorsUsed |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
672 |
|
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
673 |
def _setShadingUsed(self, page): |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
674 |
page._shadingUsed = self._shadingUsed |
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
675 |
|
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
676 |
def _setXObjects(self, thing): |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
677 |
"""for pages and forms, define the XObject dictionary for resources, if needed""" |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
678 |
forms = self._formsinuse |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
679 |
if forms: |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
680 |
xobjectsdict = self._doc.xobjDict(forms) |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
681 |
thing.XObjects = xobjectsdict |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
682 |
else: |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
683 |
thing.XObjects = None |
1683 | 684 |
|
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
685 |
def _bookmarkReference(self, name): |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
686 |
"""get a reference to a (possibly undefined, possibly unbound) bookmark""" |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
687 |
d = self._destinations |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
688 |
try: |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
689 |
return d[name] |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
690 |
except: |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
691 |
result = d[name] = pdfdoc.Destination(name) # newly defined, unbound |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
692 |
return result |
1683 | 693 |
|
1857 | 694 |
def bookmarkPage(self, key, |
2575 | 695 |
fit="Fit", |
1857 | 696 |
left=None, |
697 |
top=None, |
|
698 |
bottom=None, |
|
699 |
right=None, |
|
700 |
zoom=None |
|
701 |
): |
|
702 |
""" |
|
703 |
This creates a bookmark to the current page which can |
|
704 |
be referred to with the given key elsewhere. |
|
705 |
||
706 |
PDF offers very fine grained control over how Acrobat |
|
707 |
reader is zoomed when people link to this. The default |
|
708 |
is to keep the user's current zoom settings. the last |
|
709 |
arguments may or may not be needed depending on the |
|
710 |
choice of 'fitType'. |
|
1938 | 711 |
|
1857 | 712 |
Fit types and the other arguments they use are: |
3030 | 713 |
|
714 |
- XYZ left top zoom - fine grained control. null |
|
1857 | 715 |
or zero for any of the parameters means 'leave |
716 |
as is', so "0,0,0" will keep the reader's settings. |
|
717 |
NB. Adobe Reader appears to prefer "null" to 0's. |
|
1938 | 718 |
|
3030 | 719 |
- Fit - entire page fits in window |
1857 | 720 |
|
3030 | 721 |
- FitH top - top coord at top of window, width scaled |
722 |
to fit. |
|
1857 | 723 |
|
3030 | 724 |
- FitV left - left coord at left of window, height |
725 |
scaled to fit |
|
1938 | 726 |
|
3030 | 727 |
- FitR left bottom right top - scale window to fit |
728 |
the specified rectangle |
|
1857 | 729 |
|
730 |
(question: do we support /FitB, FitBH and /FitBV |
|
731 |
which are hangovers from version 1.1 / Acrobat 3.0?)""" |
|
437 | 732 |
dest = self._bookmarkReference(key) |
139
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
733 |
self._doc.inPage() # try to enable page-only features |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
734 |
pageref = self._doc.thisPageRef() |
1857 | 735 |
|
736 |
#None = "null" for PDF |
|
737 |
if left is None: |
|
738 |
left = "null" |
|
739 |
if top is None: |
|
740 |
top = "null" |
|
741 |
if bottom is None: |
|
742 |
bottom = "null" |
|
743 |
if right is None: |
|
744 |
right = "null" |
|
745 |
if zoom is None: |
|
746 |
zoom = "null" |
|
1938 | 747 |
|
2575 | 748 |
if fit == "XYZ": |
1857 | 749 |
dest.xyz(left,top,zoom) |
2575 | 750 |
elif fit == "Fit": |
1857 | 751 |
dest.fit() |
2575 | 752 |
elif fit == "FitH": |
1857 | 753 |
dest.fith(top) |
2575 | 754 |
elif fit == "FitV": |
1857 | 755 |
dest.fitv(left) |
2575 | 756 |
elif fit == "FitR": |
1857 | 757 |
dest.fitr(left,bottom,right,top) |
758 |
#Do we need these (version 1.1 / Acrobat 3 versions)? |
|
2575 | 759 |
elif fit == "FitB": |
1857 | 760 |
dest.fitb() |
2575 | 761 |
elif fit == "FitBH": |
1857 | 762 |
dest.fitbh(top) |
2575 | 763 |
elif fit == "FitBV": |
1857 | 764 |
dest.fitbv(left) |
765 |
else: |
|
2575 | 766 |
raise "Unknown Fit type %s" % (fit,) |
1857 | 767 |
|
768 |
dest.setPage(pageref) |
|
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
769 |
return dest |
1683 | 770 |
|
2575 | 771 |
def bookmarkHorizontalAbsolute(self, key, top, left=0, fit='XYZ', **kw): |
260 | 772 |
"""Bind a bookmark (destination) to the current page at a horizontal position. |
773 |
Note that the yhorizontal of the book mark is with respect to the default |
|
774 |
user space (where the origin is at the lower left corner of the page) |
|
775 |
and completely ignores any transform (translation, scale, skew, rotation, |
|
776 |
etcetera) in effect for the current graphics state. The programmer is |
|
777 |
responsible for making sure the bookmark matches an appropriate item on |
|
778 |
the page.""" |
|
1857 | 779 |
#This method should probably be deprecated since it is just a sub-set of bookmarkPage |
2575 | 780 |
return self.bookmarkPage(key, fit=fit, top=top, left=left, zoom=0) |
1938 | 781 |
|
2575 | 782 |
def bookmarkHorizontal(self, key, relativeX, relativeY, **kw): |
928
47d97c066df2
canvas coordinate matrix tracking and related linkage support
aaron_watters
parents:
905
diff
changeset
|
783 |
"""w.r.t. the current transformation, bookmark this horizontal.""" |
2575 | 784 |
(left, top) = self.absolutePosition(relativeX,relativeY) |
785 |
self.bookmarkHorizontalAbsolute(key, top, left=left, **kw) |
|
1683 | 786 |
|
139
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
787 |
#def _inPage0(self): disallowed! |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
788 |
# """declare a page, enable page features""" |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
789 |
# self._doc.inPage() |
1683 | 790 |
|
139
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
791 |
#def _inForm0(self): |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
792 |
# "deprecated in favore of beginForm...endForm" |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
793 |
# self._doc.inForm() |
1683 | 794 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
795 |
def doForm(self, name): |
1395 | 796 |
"""use a form XObj in current operation stream. |
797 |
||
798 |
The form should either have been defined previously using |
|
799 |
beginForm ... endForm, or may be defined later. If it is not |
|
800 |
defined at save time, an exception will be raised. The form |
|
801 |
will be drawn within the context of the current graphics |
|
802 |
state.""" |
|
1552 | 803 |
self._code.append("/%s Do" % self._doc.getXObjectName(name)) |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
804 |
self._formsinuse.append(name) |
1390 | 805 |
|
806 |
def hasForm(self, name): |
|
1395 | 807 |
"""Query whether form XObj really exists yet.""" |
1390 | 808 |
return self._doc.hasForm(name) |
1553 | 809 |
|
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
810 |
###################################################### |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
811 |
# |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
812 |
# Image routines |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
813 |
# |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
814 |
###################################################### |
3092 | 815 |
def drawInlineImage(self, image, x,y, width=None,height=None, |
816 |
preserveAspectRatio=False,anchor='c'): |
|
817 |
"""See drawImage, which should normally be used instead... |
|
818 |
||
819 |
drawInlineImage behaves like drawImage, but stores the image content |
|
820 |
within the graphics stream for the page. This means that the mask |
|
821 |
parameter for transparency is not available. It also means that there |
|
822 |
is no saving in file size or time if the same image is reused. |
|
823 |
||
824 |
In theory it allows images to be displayed slightly faster; however, |
|
825 |
we doubt if the difference is noticeable to any human user these days. |
|
826 |
Only use this if you have studied the PDF specification and know the |
|
827 |
implications. |
|
2652 | 828 |
""" |
3092 | 829 |
|
2575 | 830 |
self._currentPageHasImages = 1 |
3721 | 831 |
from .pdfimages import PDFImage |
2639
9ff3bbcf3282
reportlab: make anchor/preserveAspectRatio cooperate
rgbecker
parents:
2638
diff
changeset
|
832 |
img_obj = PDFImage(image, x,y, width, height) |
3092 | 833 |
img_obj.drawInlineImage(self, |
834 |
preserveAspectRatio=preserveAspectRatio, |
|
835 |
anchor=anchor) |
|
1553 | 836 |
return (img_obj.width, img_obj.height) |
837 |
||
3092 | 838 |
def drawImage(self, image, x, y, width=None, height=None, mask=None, |
839 |
preserveAspectRatio=False, anchor='c'): |
|
2045 | 840 |
"""Draws the image (ImageReader object or filename) as specified. |
1553 | 841 |
|
3092 | 842 |
"image" may be an image filename or an ImageReader object. |
843 |
||
844 |
x and y define the lower left corner of the image you wish to |
|
845 |
draw (or of its bounding box, if using preserveAspectRation below). |
|
846 |
||
847 |
If width and height are not given, the width and height of the |
|
848 |
image in pixels is used at a scale of 1 point to 1 pixel. |
|
849 |
||
850 |
If width and height are given, the image will be stretched to fill |
|
851 |
the given rectangle bounded by (x, y, x+width, y-height). |
|
852 |
||
853 |
If you supply negative widths and/or heights, it inverts them and adjusts |
|
854 |
x and y accordingly. |
|
855 |
||
856 |
The method returns the width and height of the underlying image, since |
|
857 |
this is often useful for layout algorithms and saves you work if you have |
|
858 |
not specified them yourself. |
|
1553 | 859 |
|
3092 | 860 |
The mask parameter supports transparent backgrounds. It takes 6 numbers |
861 |
and defines the range of RGB values which will be masked out or treated |
|
862 |
as transparent. For example with [0,2,40,42,136,139], it will mask out |
|
863 |
any pixels with a Red value from 0-2, Green from 40-42 and |
|
864 |
Blue from 136-139 (on a scale of 0-255). |
|
865 |
||
866 |
New post version 2.0: drawImage can center an image in a box you |
|
867 |
provide, while preserving its aspect ratio. For example, you might |
|
868 |
have a fixed square box in your design, and a collection of photos |
|
869 |
which might be landscape or portrait that you want to appear within |
|
870 |
the box. If preserveAspectRatio is true, your image will appear within |
|
871 |
the box specified. |
|
1552 | 872 |
|
3092 | 873 |
|
874 |
If preserveAspectRatio is True, the anchor property can be used to |
|
875 |
specify how images should fit into the given box. It should |
|
876 |
be set to one of the following values, taken from the points of |
|
877 |
the compass (plus 'c' for 'centre'): |
|
878 |
||
879 |
nw n ne |
|
880 |
w c e |
|
881 |
sw s se |
|
882 |
||
883 |
The default value is 'c' for 'centre'. Thus, if you want your |
|
884 |
bitmaps to always be centred and appear at the top of the given box, |
|
885 |
set anchor='n'. There are good examples of this in the output |
|
886 |
of test_pdfgen_general.py |
|
2652 | 887 |
|
1553 | 888 |
Unlike drawInlineImage, this creates 'external images' which |
889 |
are only stored once in the PDF file but can be drawn many times. |
|
890 |
If you give it the same filename twice, even at different locations |
|
3092 | 891 |
and sizes, it will reuse the first occurrence, resulting in a saving |
892 |
in file size and generation time. If you use ImageReader objects, |
|
893 |
it tests whether the image content has changed before deciding |
|
1553 | 894 |
whether to reuse it. |
1552 | 895 |
|
1553 | 896 |
In general you should use drawImage in preference to drawInlineImage |
3092 | 897 |
unless you have read the PDF Spec and understand the tradeoffs.""" |
898 |
||
2575 | 899 |
self._currentPageHasImages = 1 |
900 |
||
1553 | 901 |
# first, generate a unique name/signature for the image. If ANYTHING |
1683 | 902 |
# is different, even the mask, this should be different. |
2718 | 903 |
if isinstance(image,ImageReader): |
904 |
rawdata = image.getRGBData() |
|
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
905 |
smask = image._dataA |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
906 |
if mask=='auto' and smask: |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
907 |
mdata = smask.getRGBData() |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
908 |
else: |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
909 |
mdata = str(mask) |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
910 |
if isUnicodeType(mdata): |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
911 |
mdata = mdata.encode('utf8') |
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
912 |
name = _digester(rawdata+mdata) |
2718 | 913 |
else: |
1553 | 914 |
#filename, use it |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
915 |
s = '%s%s' % (image, mask) |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
916 |
if isUnicodeType(s): |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
917 |
s = s.encode('utf-8') |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
918 |
name = _digester(s) |
1553 | 919 |
|
920 |
# in the pdf document, this will be prefixed with something to |
|
921 |
# say it is an XObject. Does it exist yet? |
|
1552 | 922 |
regName = self._doc.getXObjectName(name) |
923 |
imgObj = self._doc.idToObject.get(regName, None) |
|
1553 | 924 |
if not imgObj: |
925 |
#first time seen, create and register the PDFImageXobject |
|
926 |
imgObj = pdfdoc.PDFImageXObject(name, image, mask=mask) |
|
927 |
imgObj.name = name |
|
928 |
self._setXObjects(imgObj) |
|
929 |
self._doc.Reference(imgObj, regName) |
|
930 |
self._doc.addForm(name, imgObj) |
|
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
931 |
smask = getattr(imgObj,'_smask',None) |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
932 |
if smask: #set up the softmask obtained above |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
933 |
mRegName = self._doc.getXObjectName(smask.name) |
2903
7bf831d085a3
canvas.py: attempt to fix possible redefines of the soft mask thingy
rgbecker
parents:
2902
diff
changeset
|
934 |
mImgObj = self._doc.idToObject.get(mRegName, None) |
7bf831d085a3
canvas.py: attempt to fix possible redefines of the soft mask thingy
rgbecker
parents:
2902
diff
changeset
|
935 |
if not mImgObj: |
7bf831d085a3
canvas.py: attempt to fix possible redefines of the soft mask thingy
rgbecker
parents:
2902
diff
changeset
|
936 |
self._setXObjects(smask) |
7bf831d085a3
canvas.py: attempt to fix possible redefines of the soft mask thingy
rgbecker
parents:
2902
diff
changeset
|
937 |
imgObj.smask = self._doc.Reference(smask,mRegName) |
7bf831d085a3
canvas.py: attempt to fix possible redefines of the soft mask thingy
rgbecker
parents:
2902
diff
changeset
|
938 |
else: |
2904 | 939 |
imgObj.smask = pdfdoc.PDFObjectReference(mRegName) |
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2890
diff
changeset
|
940 |
del imgObj._smask |
1553 | 941 |
|
1683 | 942 |
# ensure we have a size, as PDF will make it 1x1 pixel otherwise! |
2680 | 943 |
x,y,width,height,scaled = aspectRatioFix(preserveAspectRatio,anchor,x,y,width,height,imgObj.width,imgObj.height) |
1552 | 944 |
|
1553 | 945 |
# scale and draw |
1552 | 946 |
self.saveState() |
947 |
self.translate(x, y) |
|
948 |
self.scale(width, height) |
|
1553 | 949 |
self._code.append("/%s Do" % regName) |
1552 | 950 |
self.restoreState() |
1553 | 951 |
|
1683 | 952 |
# track what's been used on this page |
1552 | 953 |
self._formsinuse.append(name) |
1683 | 954 |
|
1553 | 955 |
return (imgObj.width, imgObj.height) |
1683 | 956 |
|
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
957 |
def _restartAccumulators(self): |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
958 |
if self._codeStack: |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
959 |
# restore the saved code |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
960 |
saved = self._codeStack[-1] |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
961 |
del self._codeStack[-1] |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
962 |
self._code, self._formsinuse, self._annotationrefs, self._formData,self._colorsUsed, self._shadingUsed = saved |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
963 |
else: |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
964 |
self._code = [] # ready for more... |
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
965 |
self._psCommandsAfterPage = [] |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
966 |
self._currentPageHasImages = 1 # for safety... |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
967 |
self._formsinuse = [] |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
968 |
self._annotationrefs = [] |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
969 |
self._formData = None |
3226
cd06c1172678
pdfgen,pdfbase: fix handling of CMYKColorSep spotNames with spaces etc
rgbecker
parents:
3198
diff
changeset
|
970 |
self._colorsUsed = {} |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
971 |
self._shadingUsed = {} |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
972 |
|
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
973 |
def _pushAccumulators(self): |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
974 |
"when you enter a form, save accumulator info not related to the form for page (if any)" |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
975 |
saved = (self._code, self._formsinuse, self._annotationrefs, self._formData, self._colorsUsed, self._shadingUsed) |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
976 |
self._codeStack.append(saved) |
0 | 977 |
self._code = [] # ready for more... |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
978 |
self._currentPageHasImages = 1 # for safety... |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
979 |
self._formsinuse = [] |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
980 |
self._annotationrefs = [] |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
981 |
self._formData = None |
3226
cd06c1172678
pdfgen,pdfbase: fix handling of CMYKColorSep spotNames with spaces etc
rgbecker
parents:
3198
diff
changeset
|
982 |
self._colorsUsed = {} |
3570
494980a689ff
reportlab: add in shading technology contributed by Peter Johnson <johnson.peter@gmail.com>
rgbecker
parents:
3456
diff
changeset
|
983 |
self._shadingUsed = {} |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
984 |
|
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
985 |
def _setExtGState(self, obj): |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
986 |
obj.ExtGState = self._extgstate.getState() |
1683 | 987 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
988 |
def beginForm(self, name, lowerx=0, lowery=0, upperx=None, uppery=None): |
260 | 989 |
"""declare the current graphics stream to be a named form. |
990 |
A graphics stream can either be a page or a form, not both. |
|
991 |
Some operations (like bookmarking) are permitted for pages |
|
992 |
but not forms. The form will not automatically be shown in the |
|
993 |
document but must be explicitly referenced using doForm in pages |
|
994 |
that require the form.""" |
|
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
995 |
self.push_state_stack() |
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
996 |
self.init_graphics_state() |
3034
777a8d5dd064
Check for _formData to know if we need to push the accumulators.
jonas
parents:
3030
diff
changeset
|
997 |
if self._code or self._formData: |
654
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
998 |
# save the code that is not in the formf |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
999 |
self._pushAccumulators() |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
1000 |
#self._codeStack.append(self._code) |
c84a6d44ea09
bugfix: code before of begin/end form should not appear in the form but in page
aaron_watters
parents:
562
diff
changeset
|
1001 |
#self._code = [] |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1002 |
self._formData = (name, lowerx, lowery, upperx, uppery) |
139
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
1003 |
self._doc.inForm() |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
1004 |
#self._inForm0() |
1683 | 1005 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1006 |
def endForm(self): |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1007 |
"""emit the current collection of graphics operations as a Form |
260 | 1008 |
as declared previously in beginForm.""" |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1009 |
(name, lowerx, lowery, upperx, uppery) = self._formData |
139
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
1010 |
#self.makeForm0(name, lowerx, lowery, upperx, uppery) |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
1011 |
# fall through! makeForm0 disallowed |
6369f06cf280
eliminated inForm/inPage apis in favor of only beginForm..endForm
aaron_watters
parents:
136
diff
changeset
|
1012 |
#def makeForm0(self, name, lowerx=0, lowery=0, upperx=None, uppery=None): |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1013 |
"""Like showpage, but make a form using accumulated operations instead""" |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1014 |
# deprecated in favor or beginForm(...)... endForm() |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1015 |
(w,h) = self._pagesize |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1016 |
if upperx is None: upperx=w |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1017 |
if uppery is None: uppery=h |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1018 |
form = pdfdoc.PDFFormXObject(lowerx=lowerx, lowery=lowery, upperx=upperx, uppery=uppery) |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1019 |
form.compression = self._pageCompression |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1020 |
form.setStreamList([self._preamble] + self._code) # ??? minus preamble (seems to be needed!) |
3198
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
1021 |
self._setColorSpace(form) |
683ca9eb6b18
reportlab: added in support for Overprint/Opacity & Separated colours (Opacity inspired by Simon King)
rgbecker
parents:
3180
diff
changeset
|
1022 |
self._setExtGState(form) |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1023 |
self._setXObjects(form) |
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1024 |
self._setAnnotations(form) |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1025 |
self._doc.addForm(name, form) |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1026 |
self._restartAccumulators() |
905
a6ec6532b578
fix for major font metrics state tracking bug
aaron_watters
parents:
875
diff
changeset
|
1027 |
self.pop_state_stack() |
1552 | 1028 |
|
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1029 |
def addPostScriptCommand(self, command, position=1): |
2199 | 1030 |
"""Embed literal Postscript in the document. |
1031 |
||
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1032 |
With position=0, it goes at very beginning of page stream; |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1033 |
with position=1, at current point; and |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1034 |
with position=2, at very end of page stream. What that does |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1035 |
to the resulting Postscript depends on Adobe's header :-) |
2403 | 1036 |
|
2199 | 1037 |
Use with extreme caution, but sometimes needed for printer tray commands. |
1038 |
Acrobat 4.0 will export Postscript to a printer or file containing |
|
1039 |
the given commands. Adobe Reader 6.0 no longer does as this feature is |
|
1040 |
deprecated. 5.0, I don't know about (please let us know!). This was |
|
1041 |
funded by Bob Marshall of Vector.co.uk and tested on a Lexmark 750. |
|
1042 |
See test_pdfbase_postscript.py for 2 test cases - one will work on |
|
1043 |
any Postscript device, the other uses a 'setpapertray' command which |
|
1044 |
will error in Distiller but work on printers supporting it. |
|
1045 |
""" |
|
1046 |
#check if we've done this one already... |
|
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1047 |
if isUnicodeType(command): |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1048 |
rawName = 'PS' + hashlib.md5(command.encode('utf-8')).hexdigest() |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1049 |
else: |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1050 |
rawName = 'PS' + hashlib.md5(command).hexdigest() |
2199 | 1051 |
regName = self._doc.getXObjectName(rawName) |
1052 |
psObj = self._doc.idToObject.get(regName, None) |
|
1053 |
if not psObj: |
|
1054 |
#first use of this chunk of Postscript, make an object |
|
1055 |
psObj = pdfdoc.PDFPostScriptXObject(command + '\r\n') |
|
1056 |
self._setXObjects(psObj) |
|
1057 |
self._doc.Reference(psObj, regName) |
|
1058 |
self._doc.addForm(rawName, psObj) |
|
2212
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1059 |
if position == 0: |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1060 |
self._psCommandsBeforePage.append("/%s Do" % regName) |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1061 |
elif position==1: |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1062 |
self._code.append("/%s Do" % regName) |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1063 |
else: |
9427c7cbccef
Added finegrained control of where postscript commands appear
andy_robinson
parents:
2200
diff
changeset
|
1064 |
self._psCommandsAfterPage.append("/%s Do" % regName) |
2403 | 1065 |
|
2199 | 1066 |
self._formsinuse.append(rawName) |
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2199
diff
changeset
|
1067 |
|
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1068 |
def _absRect(self,rect,relative=0): |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1069 |
if not rect: |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1070 |
w,h = self._pagesize |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1071 |
rect = (0,0,w,h) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1072 |
elif relative: |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1073 |
lx, ly, ux, uy = rect |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1074 |
xll,yll = self.absolutePosition(lx,ly) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1075 |
xur,yur = self.absolutePosition(ux, uy) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1076 |
xul,yul = self.absolutePosition(lx, uy) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1077 |
xlr,ylr = self.absolutePosition(ux, ly) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1078 |
xs = xll, xur, xul, xlr |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1079 |
ys = yll, yur, yul, ylr |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1080 |
xmin, ymin = min(xs), min(ys) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1081 |
xmax, ymax = max(xs), max(ys) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1082 |
rect = xmin, ymin, xmax, ymax |
3142
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
1083 |
bw = self._getCmShift() |
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
1084 |
if bw: |
426b4b7ee57c
Fix for position of hyperlinks when crop marks are added
damian
parents:
3110
diff
changeset
|
1085 |
rect = rect[0]+bw,rect[1]+bw,rect[2]+bw,rect[3]+bw |
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1086 |
return rect |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1087 |
|
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1088 |
def freeTextAnnotation(self, contents, DA, Rect=None, addtopage=1, name=None, relative=0, **kw): |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1089 |
"""DA is the default appearance string???""" |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1090 |
Rect = self._absRect(Rect,relative) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1091 |
self._addAnnotation(pdfdoc.FreeTextAnnotation(Rect, contents, DA, **kw), name, addtopage) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1092 |
|
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1093 |
def textAnnotation(self, contents, Rect=None, addtopage=1, name=None, relative=0, **kw): |
2438 | 1094 |
"""Experimental, but works. |
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1095 |
""" |
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1096 |
Rect = self._absRect(Rect,relative) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1097 |
self._addAnnotation(pdfdoc.TextAnnotation(Rect, contents, **kw), name, addtopage) |
2438 | 1098 |
textAnnotation0 = textAnnotation #deprecated |
1099 |
||
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1100 |
def inkAnnotation(self, contents, InkList=None, Rect=None, addtopage=1, name=None, relative=0, **kw): |
2438 | 1101 |
raise NotImplementedError |
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1102 |
"Experimental" |
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1103 |
Rect = self._absRect(Rect,relative) |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1104 |
if not InkList: |
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1105 |
InkList = ((100,100,100,h-100,w-100,h-100,w-100,100),) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1106 |
self._addAnnotation(pdfdoc.InkAnnotation(Rect, contents, InkList, **kw), name, addtopage) |
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1107 |
inkAnnotation0 = inkAnnotation #deprecated |
1683 | 1108 |
|
2575 | 1109 |
def linkAbsolute(self, contents, destinationname, Rect=None, addtopage=1, name=None, |
1110 |
thickness=0, color=None, dashArray=None, **kw): |
|
260 | 1111 |
"""rectangular link annotation positioned wrt the default user space. |
1112 |
The identified rectangle on the page becomes a "hot link" which |
|
1113 |
when clicked will send the viewer to the page and position identified |
|
1114 |
by the destination. |
|
1683 | 1115 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1116 |
Rect identifies (lowerx, lowery, upperx, uppery) for lower left |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1117 |
and upperright points of the rectangle. Translations and other transforms |
260 | 1118 |
are IGNORED (the rectangular position is given with respect |
1119 |
to the default user space. |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1120 |
destinationname should be the name of a bookmark (which may be defined later |
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1121 |
but must be defined before the document is generated). |
1683 | 1122 |
|
232
150d4caf48c7
removed 0's on stable linkage and outline operations.
aaron_watters
parents:
228
diff
changeset
|
1123 |
You may want to use the keyword argument Border='[0 0 0]' to |
260 | 1124 |
suppress the visible rectangle around the during viewing link.""" |
2575 | 1125 |
return self.linkRect(contents, destinationname, Rect, addtopage, name, relative=0, |
1126 |
thickness=thickness, color=color, dashArray=dashArray, **kw) |
|
1127 |
||
2777
db203a3e391c
canvas.py: make linkRect have relative=1 by default and minor mod to _annFormat
rgbecker
parents:
2766
diff
changeset
|
1128 |
def linkRect(self, contents, destinationname, Rect=None, addtopage=1, name=None, relative=1, |
2575 | 1129 |
thickness=0, color=None, dashArray=None, **kw): |
1130 |
"""rectangular link annotation w.r.t the current user transform. |
|
1131 |
if the transform is skewed/rotated the absolute rectangle will use the max/min x/y |
|
1132 |
""" |
|
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1133 |
destination = self._bookmarkReference(destinationname) # permitted to be undefined... must bind later... |
2575 | 1134 |
Rect = self._absRect(Rect,relative) |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1135 |
kw["Rect"] = Rect |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1136 |
kw["Contents"] = contents |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1137 |
kw["Destination"] = destination |
2575 | 1138 |
_annFormat(kw,color,thickness,dashArray) |
1139 |
return self._addAnnotation(pdfdoc.LinkAnnotation(**kw), name, addtopage) |
|
1431 | 1140 |
|
2564 | 1141 |
def linkURL(self, url, rect, relative=0, thickness=0, color=None, dashArray=None, kind="URI", **kw): |
1431 | 1142 |
"""Create a rectangular URL 'hotspot' in the given rectangle. |
1143 |
||
1144 |
if relative=1, this is in the current coord system, otherwise |
|
1439 | 1145 |
in absolute page space. |
1441 | 1146 |
The remaining options affect the border appearance; the border is |
1442 | 1147 |
drawn by Acrobat, not us. Set thickness to zero to hide it. |
1148 |
Any border drawn this way is NOT part of the page stream and |
|
1149 |
will not show when printed to a Postscript printer or distilled; |
|
1150 |
it is safest to draw your own.""" |
|
1439 | 1151 |
from reportlab.pdfbase.pdfdoc import PDFDictionary, PDFName, PDFArray, PDFString |
1152 |
#tried the documented BS element in the pdf spec but it |
|
1153 |
#does not work, and Acrobat itself does not appear to use it! |
|
1431 | 1154 |
|
2564 | 1155 |
ann = PDFDictionary(dict=kw) |
1431 | 1156 |
ann["Type"] = PDFName("Annot") |
1157 |
ann["Subtype"] = PDFName("Link") |
|
2571
dbbd2c8dfea3
reportlab: added FreeTextAnnotation and minor improvements to other annotations
rgbecker
parents:
2564
diff
changeset
|
1158 |
ann["Rect"] = PDFArray(self._absRect(rect,relative)) # the whole page for testing |
1441 | 1159 |
|
1683 | 1160 |
# the action is a separate dictionary |
1431 | 1161 |
A = PDFDictionary() |
1441 | 1162 |
A["Type"] = PDFName("Action") # not needed? |
2458 | 1163 |
uri = PDFString(url) |
1164 |
A['S'] = PDFName(kind) |
|
1165 |
if kind=="URI": |
|
1166 |
A["URI"] = uri |
|
1167 |
elif kind=='GoToR': |
|
1168 |
A["F"] = uri |
|
1169 |
A["D"] = "[ 0 /XYZ null null null ]" |
|
1170 |
else: |
|
1171 |
raise ValueError("Unknown linkURI kind '%s'" % kind) |
|
1172 |
||
1431 | 1173 |
ann["A"] = A |
2575 | 1174 |
_annFormat(ann,color,thickness,dashArray) |
1431 | 1175 |
self._addAnnotation(ann) |
1176 |
||
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1177 |
def _addAnnotation(self, annotation, name=None, addtopage=1): |
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1178 |
count = self._annotationCount = self._annotationCount+1 |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1179 |
if not name: name="NUMBER"+repr(count) |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1180 |
self._doc.addAnnotation(name, annotation) |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1181 |
if addtopage: |
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1182 |
self._annotatePage(name) |
1683 | 1183 |
|
54
9f1cadbf9728
added beginForm..endForm and fixed some naming convention issues.
aaron_watters
parents:
52
diff
changeset
|
1184 |
def _annotatePage(self, name): |
52
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1185 |
ref = self._doc.refAnnotation(name) |
3bbe0067a2dc
added support for destinations, forms, linkages
aaron_watters
parents:
48
diff
changeset
|
1186 |
self._annotationrefs.append(ref) |
0 | 1187 |
|
1188 |
def getPageNumber(self): |
|
260 | 1189 |
"get the page number for the current page being generated." |
0 | 1190 |
return self._pageNumber |
1683 | 1191 |
|
0 | 1192 |
def save(self): |
260 | 1193 |
"""Saves and close the PDF document in the file. |
1194 |
If there is current data a ShowPage is executed automatically. |
|
1195 |
After this operation the canvas must not be used further.""" |
|
1776 | 1196 |
if len(self._code): self.showPage() |
136 | 1197 |
self._doc.SaveToFile(self._filename, self) |
0 | 1198 |
|
1965
02ef6a007f0b
David Fraser's GetPDFData patch (to avoid unwanted StringIOs
rgbecker
parents:
1938
diff
changeset
|
1199 |
def getpdfdata(self): |
02ef6a007f0b
David Fraser's GetPDFData patch (to avoid unwanted StringIOs
rgbecker
parents:
1938
diff
changeset
|
1200 |
"""Returns the PDF data that would normally be written to a file. |
02ef6a007f0b
David Fraser's GetPDFData patch (to avoid unwanted StringIOs
rgbecker
parents:
1938
diff
changeset
|
1201 |
If there is current data a ShowPage is executed automatically. |
02ef6a007f0b
David Fraser's GetPDFData patch (to avoid unwanted StringIOs
rgbecker
parents:
1938
diff
changeset
|
1202 |
After this operation the canvas must not be used further.""" |
02ef6a007f0b
David Fraser's GetPDFData patch (to avoid unwanted StringIOs
rgbecker
parents:
1938
diff
changeset
|
1203 |
if len(self._code): self.showPage() |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1204 |
s = self._doc.GetPDFData(self) |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1205 |
if isUnicodeType(s): |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1206 |
s = s.encode('utf-8') |
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
1207 |
return s |
1965
02ef6a007f0b
David Fraser's GetPDFData patch (to avoid unwanted StringIOs
rgbecker
parents:
1938
diff
changeset
|
1208 |
|