author | robin <robin@reportlab.com> |
Tue, 07 Mar 2017 10:00:34 +0000 | |
changeset 4330 | 617ffa6bbdc8 |
parent 4303 | 1dbe6269e831 |
child 4370 | 823a8c33ce43 |
permissions | -rw-r--r-- |
4330 | 1 |
#Copyright ReportLab Europe Ltd. 2000-2017 |
817 | 2 |
#see license.txt for license details |
2332 | 3 |
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/renderbase.py |
568 | 4 |
|
4252 | 5 |
__version__='3.3.0' |
3032 | 6 |
__doc__='''Superclass for renderers to factor out common functionality and default implementations.''' |
568 | 7 |
|
8 |
from reportlab.graphics.shapes import * |
|
2547 | 9 |
from reportlab.lib.validators import DerivedValue |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
10 |
from reportlab import rl_config |
568 | 11 |
|
12 |
def inverse(A): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
13 |
"For A affine 2D represented as 6vec return 6vec version of A**(-1)" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
14 |
# I checked this RGB |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
15 |
det = float(A[0]*A[3] - A[2]*A[1]) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
16 |
R = [A[3]/det, -A[1]/det, -A[2]/det, A[0]/det] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
17 |
return tuple(R+[-R[0]*A[4]-R[2]*A[5],-R[1]*A[4]-R[3]*A[5]]) |
568 | 18 |
|
19 |
def mmult(A, B): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
20 |
"A postmultiplied by B" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
21 |
# I checked this RGB |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
22 |
# [a0 a2 a4] [b0 b2 b4] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
23 |
# [a1 a3 a5] * [b1 b3 b5] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
24 |
# [ 1 ] [ 1 ] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
25 |
# |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
26 |
return (A[0]*B[0] + A[2]*B[1], |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
27 |
A[1]*B[0] + A[3]*B[1], |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
28 |
A[0]*B[2] + A[2]*B[3], |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
29 |
A[1]*B[2] + A[3]*B[3], |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
30 |
A[0]*B[4] + A[2]*B[5] + A[4], |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
31 |
A[1]*B[4] + A[3]*B[5] + A[5]) |
568 | 32 |
|
33 |
def getStateDelta(shape): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
34 |
"""Used to compute when we need to change the graphics state. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
35 |
For example, if we have two adjacent red shapes we don't need |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
36 |
to set the pen color to red in between. Returns the effect |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
37 |
the given shape would have on the graphics state""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
38 |
delta = {} |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
39 |
for prop, value in shape.getProperties().items(): |
3326 | 40 |
if prop in STATE_DEFAULTS: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
41 |
delta[prop] = value |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
42 |
return delta |
568 | 43 |
|
44 |
class StateTracker: |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
45 |
"""Keeps a stack of transforms and state |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
46 |
properties. It can contain any properties you |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
47 |
want, but the keys 'transform' and 'ctm' have |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
48 |
special meanings. The getCTM() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
49 |
method returns the current transformation |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
50 |
matrix at any point, without needing to |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
51 |
invert matrixes when you pop.""" |
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
52 |
def __init__(self, defaults=None, defaultObj=None): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
53 |
# one stack to keep track of what changes... |
2547 | 54 |
self._deltas = [] |
568 | 55 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
56 |
# and another to keep track of cumulative effects. Last one in |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
57 |
# list is the current graphics state. We put one in to simplify |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
58 |
# loops below. |
2547 | 59 |
self._combined = [] |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
60 |
if defaults is None: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
61 |
defaults = STATE_DEFAULTS.copy() |
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
62 |
if defaultObj: |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
63 |
for k in STATE_DEFAULTS.keys(): |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
64 |
a = 'initial'+k[:1].upper()+k[1:] |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
65 |
if hasattr(defaultObj,a): |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
66 |
defaults[k] = getattr(defaultObj,a) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
67 |
#ensure that if we have a transform, we have a CTM |
3326 | 68 |
if 'transform' in defaults: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
69 |
defaults['ctm'] = defaults['transform'] |
2547 | 70 |
self._combined.append(defaults) |
568 | 71 |
|
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
72 |
def _applyDefaultObj(self,d): |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
73 |
return d |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
74 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
75 |
def push(self,delta): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
76 |
"""Take a new state dictionary of changes and push it onto |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
77 |
the stack. After doing this, the combined state is accessible |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
78 |
through getState()""" |
1665 | 79 |
|
2547 | 80 |
newstate = self._combined[-1].copy() |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
81 |
for key, value in delta.items(): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
82 |
if key == 'transform': #do cumulative matrix |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
83 |
newstate['transform'] = delta['transform'] |
2547 | 84 |
newstate['ctm'] = mmult(self._combined[-1]['ctm'], delta['transform']) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
85 |
#print 'statetracker transform = (%0.2f, %0.2f, %0.2f, %0.2f, %0.2f, %0.2f)' % tuple(newstate['transform']) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
86 |
#print 'statetracker ctm = (%0.2f, %0.2f, %0.2f, %0.2f, %0.2f, %0.2f)' % tuple(newstate['ctm']) |
568 | 87 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
88 |
else: #just overwrite it |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
89 |
newstate[key] = value |
568 | 90 |
|
2547 | 91 |
self._combined.append(newstate) |
92 |
self._deltas.append(delta) |
|
568 | 93 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
94 |
def pop(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
95 |
"""steps back one, and returns a state dictionary with the |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
96 |
deltas to reverse out of wherever you are. Depending |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
97 |
on your back end, you may not need the return value, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
98 |
since you can get the complete state afterwards with getState()""" |
2547 | 99 |
del self._combined[-1] |
100 |
newState = self._combined[-1] |
|
101 |
lastDelta = self._deltas[-1] |
|
102 |
del self._deltas[-1] |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
103 |
#need to diff this against the last one in the state |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
104 |
reverseDelta = {} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
105 |
#print 'pop()...' |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
106 |
for key, curValue in lastDelta.items(): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
107 |
#print ' key=%s, value=%s' % (key, curValue) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
108 |
prevValue = newState[key] |
3326 | 109 |
if prevValue != curValue: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
110 |
#print ' state popping "%s"="%s"' % (key, curValue) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
111 |
if key == 'transform': |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
112 |
reverseDelta[key] = inverse(lastDelta['transform']) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
113 |
else: #just return to previous state |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
114 |
reverseDelta[key] = prevValue |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
115 |
return reverseDelta |
568 | 116 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
117 |
def getState(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
118 |
"returns the complete graphics state at this point" |
2547 | 119 |
return self._combined[-1] |
568 | 120 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
121 |
def getCTM(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
122 |
"returns the current transformation matrix at this point""" |
2547 | 123 |
return self._combined[-1]['ctm'] |
568 | 124 |
|
2401 | 125 |
def __getitem__(self,key): |
126 |
"returns the complete graphics state value of key at this point" |
|
2547 | 127 |
return self._combined[-1][key] |
2401 | 128 |
|
129 |
def __setitem__(self,key,value): |
|
130 |
"sets the complete graphics state value of key to value" |
|
2547 | 131 |
self._combined[-1][key] = value |
568 | 132 |
|
133 |
def testStateTracker(): |
|
3721 | 134 |
print('Testing state tracker') |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
135 |
defaults = {'fillColor':None, 'strokeColor':None,'fontName':None, 'transform':[1,0,0,1,0,0]} |
3368
afa025c34493
reportlab: new base font mechanism more fully applied
rgbecker
parents:
3326
diff
changeset
|
136 |
from reportlab.graphics.shapes import _baseGFontName |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
137 |
deltas = [ |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
138 |
{'fillColor':'red'}, |
3368
afa025c34493
reportlab: new base font mechanism more fully applied
rgbecker
parents:
3326
diff
changeset
|
139 |
{'fillColor':'green', 'strokeColor':'blue','fontName':_baseGFontName}, |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
140 |
{'transform':[0.5,0,0,0.5,0,0]}, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
141 |
{'transform':[0.5,0,0,0.5,2,3]}, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
142 |
{'strokeColor':'red'} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
143 |
] |
1665 | 144 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
145 |
st = StateTracker(defaults) |
3721 | 146 |
print('initial:', st.getState()) |
147 |
print() |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
148 |
for delta in deltas: |
3721 | 149 |
print('pushing:', delta) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
150 |
st.push(delta) |
3721 | 151 |
print('state: ',st.getState(),'\n') |
568 | 152 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
153 |
for delta in deltas: |
3721 | 154 |
print('popping:',st.pop()) |
155 |
print('state: ',st.getState(),'\n') |
|
1665 | 156 |
|
157 |
def _expandUserNode(node,canvas): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
158 |
if isinstance(node, UserNode): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
159 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
160 |
if hasattr(node,'_canvas'): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
161 |
ocanvas = 1 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
162 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
163 |
node._canvas = canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
164 |
ocanvas = None |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
165 |
onode = node |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
166 |
node = node.provideNode() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
167 |
finally: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
168 |
if not ocanvas: del onode._canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
169 |
return node |
568 | 170 |
|
2544
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
171 |
def renderScaledDrawing(d): |
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
172 |
renderScale = d.renderScale |
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
173 |
if renderScale!=1.0: |
2827
ec03c767079c
renderbase.py: attempt to fix problems with copy in renderScaledDrawing
rgbecker
parents:
2570
diff
changeset
|
174 |
o = d |
ec03c767079c
renderbase.py: attempt to fix problems with copy in renderScaledDrawing
rgbecker
parents:
2570
diff
changeset
|
175 |
d = d.__class__(o.width*renderScale,o.height*renderScale) |
ec03c767079c
renderbase.py: attempt to fix problems with copy in renderScaledDrawing
rgbecker
parents:
2570
diff
changeset
|
176 |
d.__dict__ = o.__dict__.copy() |
2544
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
177 |
d.scale(renderScale,renderScale) |
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
178 |
d.renderScale = 1.0 |
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
179 |
return d |
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2401
diff
changeset
|
180 |
|
568 | 181 |
class Renderer: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
182 |
"""Virtual superclass for graphics renderers.""" |
1665 | 183 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
184 |
def undefined(self, operation): |
3721 | 185 |
raise ValueError("%s operation not defined at superclass class=%s" %(operation, self.__class__)) |
568 | 186 |
|
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
187 |
def draw(self, drawing, canvas, x=0, y=0, showBoundary=rl_config._unset_): |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
188 |
"""This is the top level function, which draws the drawing at the given |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
189 |
location. The recursive part is handled by drawNode.""" |
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
190 |
self._tracker = StateTracker(defaultObj=drawing) |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
191 |
#stash references for ease of communication |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
192 |
if showBoundary is rl_config._unset_: showBoundary=rl_config.showBoundary |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
193 |
self._canvas = canvas |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
194 |
canvas.__dict__['_drawing'] = self._drawing = drawing |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
195 |
drawing._parent = None |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
196 |
try: |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
197 |
#bounding box |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
198 |
if showBoundary: canvas.rect(x, y, drawing.width, drawing.height) |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
199 |
canvas.saveState() |
2547 | 200 |
self.initState(x,y) #this is the push() |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
201 |
self.drawNode(drawing) |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
202 |
self.pop() |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
203 |
canvas.restoreState() |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
204 |
finally: |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
205 |
#remove any circular references |
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
206 |
del self._canvas, self._drawing, canvas._drawing, drawing._parent, self._tracker |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
207 |
|
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
208 |
def initState(self,x,y): |
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
209 |
deltas = self._tracker._combined[-1] |
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
210 |
deltas['transform'] = tuple(list(deltas['transform'])[:4])+(x,y) |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
211 |
self._tracker.push(deltas) |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
212 |
self.applyStateChanges(deltas, {}) |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
213 |
|
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
214 |
def pop(self): |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
215 |
self._tracker.pop() |
568 | 216 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
217 |
def drawNode(self, node): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
218 |
"""This is the recursive method called for each node |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
219 |
in the tree""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
220 |
# Undefined here, but with closer analysis probably can be handled in superclass |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
221 |
self.undefined("drawNode") |
1665 | 222 |
|
2547 | 223 |
def getStateValue(self, key): |
224 |
"""Return current state parameter for given key""" |
|
225 |
currentState = self._tracker._combined[-1] |
|
226 |
return currentState[key] |
|
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
227 |
|
2547 | 228 |
def fillDerivedValues(self, node): |
229 |
"""Examine a node for any values which are Derived, |
|
230 |
and replace them with their calculated values. |
|
231 |
Generally things may look at the drawing or their |
|
232 |
parent. |
|
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
233 |
|
2547 | 234 |
""" |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
235 |
for key, value in node.__dict__.items(): |
2547 | 236 |
if isinstance(value, DerivedValue): |
237 |
#just replace with default for key? |
|
238 |
#print ' fillDerivedValues(%s)' % key |
|
239 |
newValue = value.getValue(self, key) |
|
240 |
#print ' got value of %s' % newValue |
|
241 |
node.__dict__[key] = newValue |
|
242 |
||
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
243 |
def drawNodeDispatcher(self, node): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
244 |
"""dispatch on the node's (super) class: shared code""" |
2570
7b93b3b42e51
reportlab/graphics cosmetics and adding drawImage to renderPS
rgbecker
parents:
2547
diff
changeset
|
245 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
246 |
canvas = getattr(self,'_canvas',None) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
247 |
# replace UserNode with its contents |
2570
7b93b3b42e51
reportlab/graphics cosmetics and adding drawImage to renderPS
rgbecker
parents:
2547
diff
changeset
|
248 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
249 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
250 |
node = _expandUserNode(node,canvas) |
3233 | 251 |
if not node: return |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
252 |
if hasattr(node,'_canvas'): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
253 |
ocanvas = 1 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
254 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
255 |
node._canvas = canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
256 |
ocanvas = None |
568 | 257 |
|
2547 | 258 |
self.fillDerivedValues(node) |
3385 | 259 |
dtcb = getattr(node,'_drawTimeCallback',None) |
260 |
if dtcb: |
|
261 |
dtcb(node,canvas=canvas,renderer=self) |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
262 |
#draw the object, or recurse |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
263 |
if isinstance(node, Line): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
264 |
self.drawLine(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
265 |
elif isinstance(node, Image): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
266 |
self.drawImage(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
267 |
elif isinstance(node, Rect): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
268 |
self.drawRect(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
269 |
elif isinstance(node, Circle): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
270 |
self.drawCircle(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
271 |
elif isinstance(node, Ellipse): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
272 |
self.drawEllipse(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
273 |
elif isinstance(node, PolyLine): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
274 |
self.drawPolyLine(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
275 |
elif isinstance(node, Polygon): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
276 |
self.drawPolygon(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
277 |
elif isinstance(node, Path): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
278 |
self.drawPath(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
279 |
elif isinstance(node, String): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
280 |
self.drawString(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
281 |
elif isinstance(node, Group): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
282 |
self.drawGroup(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
283 |
elif isinstance(node, Wedge): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
284 |
self.drawWedge(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
285 |
else: |
3721 | 286 |
print('DrawingError','Unexpected element %s in drawing!' % str(node)) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
287 |
finally: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
288 |
if not ocanvas: del node._canvas |
1665 | 289 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
290 |
_restores = {'stroke':'_stroke','stroke_width': '_lineWidth','stroke_linecap':'_lineCap', |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
291 |
'stroke_linejoin':'_lineJoin','fill':'_fill','font_family':'_font', |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
292 |
'font_size':'_fontSize'} |
585
e0144950b3e2
Fixes to CTM to support bitmap renderer; extra string rotation
andy_robinson
parents:
580
diff
changeset
|
293 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
294 |
def drawGroup(self, group): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
295 |
# just do the contents. Some renderers might need to override this |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
296 |
# if they need a flipped transform |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
297 |
canvas = getattr(self,'_canvas',None) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
298 |
for node in group.getContents(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
299 |
node = _expandUserNode(node,canvas) |
3233 | 300 |
if not node: continue |
2547 | 301 |
|
4274
ec03159b74bb
changes to Render class; allow drawings to specify initialFontName/Size version-->3.3.9
robin
parents:
4252
diff
changeset
|
302 |
#here is where we do derived values - this seems to get everything. Touch wood. |
2547 | 303 |
self.fillDerivedValues(node) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
304 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
305 |
if hasattr(node,'_canvas'): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
306 |
ocanvas = 1 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
307 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
308 |
node._canvas = canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
309 |
ocanvas = None |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
310 |
node._parent = group |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
311 |
self.drawNode(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
312 |
finally: |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2332
diff
changeset
|
313 |
del node._parent |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
314 |
if not ocanvas: del node._canvas |
585
e0144950b3e2
Fixes to CTM to support bitmap renderer; extra string rotation
andy_robinson
parents:
580
diff
changeset
|
315 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
316 |
def drawWedge(self, wedge): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
317 |
# by default ask the wedge to make a polygon of itself and draw that! |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
318 |
#print "drawWedge" |
4132
28379377462b
fix doughnut chart special case and how it is drawn; bump to 3.1.31
robin
parents:
3723
diff
changeset
|
319 |
P = wedge.asPolygon() |
28379377462b
fix doughnut chart special case and how it is drawn; bump to 3.1.31
robin
parents:
3723
diff
changeset
|
320 |
if isinstance(P,Path): |
28379377462b
fix doughnut chart special case and how it is drawn; bump to 3.1.31
robin
parents:
3723
diff
changeset
|
321 |
self.drawPath(P) |
28379377462b
fix doughnut chart special case and how it is drawn; bump to 3.1.31
robin
parents:
3723
diff
changeset
|
322 |
else: |
28379377462b
fix doughnut chart special case and how it is drawn; bump to 3.1.31
robin
parents:
3723
diff
changeset
|
323 |
self.drawPolygon(P) |
1665 | 324 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
325 |
def drawPath(self, path): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
326 |
polygons = path.asPolygons() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
327 |
for polygon in polygons: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
328 |
self.drawPolygon(polygon) |
568 | 329 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
330 |
def drawRect(self, rect): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
331 |
# could be implemented in terms of polygon |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
332 |
self.undefined("drawRect") |
568 | 333 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
334 |
def drawLine(self, line): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
335 |
self.undefined("drawLine") |
568 | 336 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
337 |
def drawCircle(self, circle): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
338 |
self.undefined("drawCircle") |
1665 | 339 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
340 |
def drawPolyLine(self, p): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
341 |
self.undefined("drawPolyLine") |
568 | 342 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
343 |
def drawEllipse(self, ellipse): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
344 |
self.undefined("drawEllipse") |
568 | 345 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
346 |
def drawPolygon(self, p): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
347 |
self.undefined("drawPolygon") |
568 | 348 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
349 |
def drawString(self, stringObj): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
350 |
self.undefined("drawString") |
568 | 351 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
352 |
def applyStateChanges(self, delta, newState): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
353 |
"""This takes a set of states, and outputs the operators |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
354 |
needed to set those properties""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
355 |
self.undefined("applyStateChanges") |
568 | 356 |
|
4303
1dbe6269e831
improved support for images in renderPM/renderSVG bug report from Claude Paroz; version --> 3.3.26
robin
parents:
4274
diff
changeset
|
357 |
def drawImage(self,*args,**kwds): |
1dbe6269e831
improved support for images in renderPM/renderSVG bug report from Claude Paroz; version --> 3.3.26
robin
parents:
4274
diff
changeset
|
358 |
raise NotImplementedError('drawImage') |
1dbe6269e831
improved support for images in renderPM/renderSVG bug report from Claude Paroz; version --> 3.3.26
robin
parents:
4274
diff
changeset
|
359 |
|
568 | 360 |
if __name__=='__main__': |
3721 | 361 |
print("this file has no script interpretation") |
362 |
print(__doc__) |