author | rptlab |
Tue, 30 Apr 2013 14:28:14 +0100 | |
branch | py33 |
changeset 3723 | 99aa837b6703 |
parent 3721 | 0c93dd8ff567 |
child 3763 | d079e73fb7b0 |
permissions | -rw-r--r-- |
3617 | 1 |
#Copyright ReportLab Europe Ltd. 2000-2012 |
899 | 2 |
#see license.txt for license details |
3 |
#history www.reportlab.co.uk/rl-cgi/viewcvs.cgi/rlextra/graphics/Csrc/renderPM/renderP.py |
|
2332 | 4 |
__version__=''' $Id$ ''' |
3032 | 5 |
__doc__="""Render drawing objects in common bitmap formats |
6 |
||
7 |
Usage:: |
|
8 |
||
9 |
from reportlab.graphics import renderPM |
|
10 |
renderPM.drawToFile(drawing,filename,fmt='GIF',configPIL={....}) |
|
11 |
||
899 | 12 |
Other functions let you create a PM drawing as string or into a PM buffer. |
13 |
Execute the script to see some test drawings.""" |
|
14 |
||
15 |
from reportlab.graphics.shapes import * |
|
2544
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2405
diff
changeset
|
16 |
from reportlab.graphics.renderbase import StateTracker, getStateDelta, renderScaledDrawing |
2575 | 17 |
from reportlab.pdfbase.pdfmetrics import getFont, unicode2T1 |
899 | 18 |
from math import sin, cos, pi, ceil |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
19 |
from reportlab.lib.utils import getBytesIO, open_and_read |
1259
49bfe92e612e
Used showBoundary every wherei, moved to Drawings as Groups
rgbecker
parents:
1230
diff
changeset
|
20 |
from reportlab import rl_config |
899 | 21 |
|
22 |
class RenderPMError(Exception): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
23 |
pass |
899 | 24 |
|
25 |
import string, os, sys |
|
903 | 26 |
|
27 |
try: |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
28 |
import _renderPM |
3721 | 29 |
except ImportError as errMsg: |
30 |
raise ImportError("No module named _renderPM\n" + \ |
|
1683 | 31 |
(str(errMsg)!='No module named _renderPM' and "it may be the wrong version or badly installed!" or |
3721 | 32 |
"see https://www.reportlab.com/software/opensource/rl-addons/")) |
903 | 33 |
|
1895 | 34 |
def _getImage(): |
35 |
try: |
|
36 |
from PIL import Image |
|
37 |
except ImportError: |
|
38 |
import Image |
|
39 |
return Image |
|
40 |
||
899 | 41 |
def Color2Hex(c): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
42 |
#assert isinstance(colorobj, colors.Color) #these checks don't work well RGB |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
43 |
if c: return ((0xFF&int(255*c.red)) << 16) | ((0xFF&int(255*c.green)) << 8) | (0xFF&int(255*c.blue)) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
44 |
return c |
899 | 45 |
|
46 |
# the main entry point for users... |
|
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
47 |
def draw(drawing, canvas, x, y, showBoundary=rl_config._unset_): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
48 |
"""As it says""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
49 |
R = _PMRenderer() |
2553
a880f43d10bd
reprotlab/graphics: fix so renderScale is used properly
rgbecker
parents:
2544
diff
changeset
|
50 |
R.draw(renderScaledDrawing(drawing), canvas, x, y, showBoundary=showBoundary) |
1683 | 51 |
|
899 | 52 |
from reportlab.graphics.renderbase import Renderer |
53 |
class _PMRenderer(Renderer): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
54 |
"""This draws onto a pix map image. It needs to be a class |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
55 |
rather than a function, as some image-specific state tracking is |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
56 |
needed outside of the state info in the SVG model.""" |
899 | 57 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
58 |
def __init__(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
59 |
self._tracker = StateTracker() |
899 | 60 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
61 |
def pop(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
62 |
self._tracker.pop() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
63 |
self.applyState() |
899 | 64 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
65 |
def push(self,node): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
66 |
deltas = getStateDelta(node) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
67 |
self._tracker.push(deltas) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
68 |
self.applyState() |
899 | 69 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
70 |
def applyState(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
71 |
s = self._tracker.getState() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
72 |
self._canvas.ctm = s['ctm'] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
73 |
self._canvas.strokeWidth = s['strokeWidth'] |
3281
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
74 |
alpha = s['strokeOpacity'] |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
75 |
if alpha is not None: |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
76 |
self._canvas.strokeOpacity = alpha |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
77 |
self._canvas.setStrokeColor(s['strokeColor']) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
78 |
self._canvas.lineCap = s['strokeLineCap'] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
79 |
self._canvas.lineJoin = s['strokeLineJoin'] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
80 |
da = s['strokeDashArray'] |
3495
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
81 |
if not da: |
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
82 |
da = None |
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
83 |
else: |
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
84 |
if not isinstance(da,(list,tuple)): |
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
85 |
da = da, |
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
86 |
if len(da)!=2 or not isinstance(da[1],(list,tuple)): |
0b8d32884a1e
renderPM.py & renderPDF.py make dash phase more explicit
rgbecker
parents:
3370
diff
changeset
|
87 |
da = 0, da #assume phase of 0 |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
88 |
self._canvas.dashArray = da |
3281
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
89 |
alpha = s['fillOpacity'] |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
90 |
if alpha is not None: |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
91 |
self._canvas.fillOpacity = alpha |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
92 |
self._canvas.setFillColor(s['fillColor']) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
93 |
self._canvas.setFont(s['fontName'], s['fontSize']) |
899 | 94 |
|
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
95 |
def initState(self,x,y): |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
96 |
deltas = STATE_DEFAULTS.copy() |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
97 |
deltas['transform'] = self._canvas._baseCTM[0:4]+(x,y) |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
98 |
self._tracker.push(deltas) |
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
99 |
self.applyState() |
899 | 100 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
101 |
def drawNode(self, node): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
102 |
"""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
|
103 |
in the tree""" |
899 | 104 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
105 |
#apply state changes |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
106 |
self.push(node) |
899 | 107 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
108 |
#draw the object, or recurse |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
109 |
self.drawNodeDispatcher(node) |
899 | 110 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
111 |
# restore the state |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
112 |
self.pop() |
899 | 113 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
114 |
def drawRect(self, rect): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
115 |
c = self._canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
116 |
if rect.rx == rect.ry == 0: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
117 |
#plain old rectangle, draw clockwise (x-axis to y-axis) direction |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
118 |
c.rect(rect.x,rect.y, rect.width, rect.height) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
119 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
120 |
c.roundRect(rect.x,rect.y, rect.width, rect.height, rect.rx, rect.ry) |
899 | 121 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
122 |
def drawLine(self, line): |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
123 |
self._canvas.line(line.x1,line.y1,line.x2,line.y2) |
899 | 124 |
|
1680 | 125 |
def drawImage(self, image): |
3562
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
126 |
path = image.path |
3721 | 127 |
if isinstance(path,str): |
3562
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
128 |
if not (path and os.path.isfile(path)): return |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
129 |
im = _getImage().open(path).convert('RGB') |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
130 |
elif hasattr(path,'convert'): |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
131 |
im = path.convert('RGB') |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
132 |
else: |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
133 |
return |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
134 |
srcW, srcH = im.size |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
135 |
dstW, dstH = image.width, image.height |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
136 |
if dstW is None: dstW = srcW |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
137 |
if dstH is None: dstH = srcH |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
138 |
self._canvas._aapixbuf( |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
139 |
image.x, image.y, dstW, dstH, |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
140 |
im.tostring(), srcW, srcH, 3, |
ad5ccec5b07f
allow PIL Image in image.path for renderPDF & renderPM
rgbecker
parents:
3495
diff
changeset
|
141 |
) |
1680 | 142 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
143 |
def drawCircle(self, circle): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
144 |
c = self._canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
145 |
c.circle(circle.cx,circle.cy, circle.r) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
146 |
c.fillstrokepath() |
899 | 147 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
148 |
def drawPolyLine(self, polyline, _doClose=0): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
149 |
P = polyline.points |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
150 |
assert len(P) >= 2, 'Polyline must have 1 or more points' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
151 |
c = self._canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
152 |
c.pathBegin() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
153 |
c.moveTo(P[0], P[1]) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
154 |
for i in range(2, len(P), 2): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
155 |
c.lineTo(P[i], P[i+1]) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
156 |
if _doClose: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
157 |
c.pathClose() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
158 |
c.pathFill() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
159 |
c.pathStroke() |
899 | 160 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
161 |
def drawEllipse(self, ellipse): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
162 |
c=self._canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
163 |
c.ellipse(ellipse.cx, ellipse.cy, ellipse.rx,ellipse.ry) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
164 |
c.fillstrokepath() |
899 | 165 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
166 |
def drawPolygon(self, polygon): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
167 |
self.drawPolyLine(polygon,_doClose=1) |
899 | 168 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
169 |
def drawString(self, stringObj): |
2575 | 170 |
canv = self._canvas |
171 |
fill = canv.fillColor |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
172 |
if fill is not None: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
173 |
S = self._tracker.getState() |
2575 | 174 |
text_anchor = S['textAnchor'] |
175 |
fontName = S['fontName'] |
|
176 |
fontSize = S['fontSize'] |
|
177 |
text = stringObj.text |
|
178 |
x = stringObj.x |
|
179 |
y = stringObj.y |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
180 |
if not text_anchor in ['start','inherited']: |
2575 | 181 |
textLen = stringWidth(text, fontName,fontSize) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
182 |
if text_anchor=='end': |
3219
b28d6eef8227
reportlab: add support for String anchor 'numeric'
rgbecker
parents:
3180
diff
changeset
|
183 |
x -= textLen |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
184 |
elif text_anchor=='middle': |
3219
b28d6eef8227
reportlab: add support for String anchor 'numeric'
rgbecker
parents:
3180
diff
changeset
|
185 |
x -= textLen/2 |
b28d6eef8227
reportlab: add support for String anchor 'numeric'
rgbecker
parents:
3180
diff
changeset
|
186 |
elif text_anchor=='numeric': |
b28d6eef8227
reportlab: add support for String anchor 'numeric'
rgbecker
parents:
3180
diff
changeset
|
187 |
x -= numericXShift(text_anchor,text,textLen,fontName,fontSize,stringObj.encoding) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
188 |
else: |
3721 | 189 |
raise ValueError('bad value for textAnchor '+str(text_anchor)) |
2761 | 190 |
canv.drawString(x,y,text,_fontInfo=(fontName,fontSize)) |
899 | 191 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
192 |
def drawPath(self, path): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
193 |
c = self._canvas |
1697 | 194 |
if path is EmptyClipPath: |
195 |
del c._clipPaths[-1] |
|
196 |
if c._clipPaths: |
|
197 |
P = c._clipPaths[-1] |
|
198 |
icp = P.isClipPath |
|
199 |
P.isClipPath = 1 |
|
200 |
self.drawPath(P) |
|
201 |
P.isClipPath = icp |
|
202 |
else: |
|
203 |
c.clipPathClear() |
|
204 |
return |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
205 |
c.pathBegin() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
206 |
drawFuncs = (c.moveTo, c.lineTo, c.curveTo, c.pathClose) |
1697 | 207 |
from reportlab.graphics.shapes import _renderPath |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
208 |
isClosed = _renderPath(path, drawFuncs) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
209 |
if path.isClipPath: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
210 |
c.clipPathSet() |
1697 | 211 |
c._clipPaths.append(path) |
212 |
else: |
|
213 |
if isClosed: c.pathFill() |
|
214 |
c.pathStroke() |
|
1071 | 215 |
|
1327 | 216 |
def _setFont(gs,fontName,fontSize): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
217 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
218 |
gs.setFont(fontName,fontSize) |
3721 | 219 |
except _renderPM.Error as errMsg: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
220 |
if errMsg.args[0]!="Can't find font!": raise |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
221 |
#here's where we try to add a font to the canvas |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
222 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
223 |
f = getFont(fontName) |
2386
320b823de224
renderPM.py: backward compatibility fix for _renderPM version <=0.98
rgbecker
parents:
2360
diff
changeset
|
224 |
if _renderPM._version<='0.98': #added reader arg in 0.99 |
320b823de224
renderPM.py: backward compatibility fix for _renderPM version <=0.98
rgbecker
parents:
2360
diff
changeset
|
225 |
_renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector) |
320b823de224
renderPM.py: backward compatibility fix for _renderPM version <=0.98
rgbecker
parents:
2360
diff
changeset
|
226 |
else: |
320b823de224
renderPM.py: backward compatibility fix for _renderPM version <=0.98
rgbecker
parents:
2360
diff
changeset
|
227 |
_renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector,open_and_read) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
228 |
except: |
3721 | 229 |
s1, s2 = list(map(str,sys.exc_info()[:2])) |
230 |
raise RenderPMError("Can't setFont(%s) missing the T1 files?\nOriginally %s: %s" % (fontName,s1,s2)) |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
231 |
gs.setFont(fontName,fontSize) |
899 | 232 |
|
1899 | 233 |
def _convert2pilp(im): |
234 |
Image = _getImage() |
|
235 |
return im.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE) |
|
236 |
||
2811
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
237 |
def _convert2pilL(im): |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
238 |
return im.convert("L") |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
239 |
|
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
240 |
def _convert2pil1(im): |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
241 |
return im.convert("1") |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
242 |
|
2008
f643cd8fee79
Test PICT transparency & move to better markfilename
rgbecker
parents:
2000
diff
changeset
|
243 |
def _saveAsPICT(im,fn,fmt,transparent=None): |
1899 | 244 |
im = _convert2pilp(im) |
245 |
cols, rows = im.size |
|
2016 | 246 |
#s = _renderPM.pil2pict(cols,rows,im.tostring(),im.im.getpalette(),transparent is not None and Color2Hex(transparent) or -1) |
247 |
s = _renderPM.pil2pict(cols,rows,im.tostring(),im.im.getpalette()) |
|
1904 | 248 |
if not hasattr(fn,'write'): |
249 |
open(os.path.splitext(fn)[0]+'.'+string.lower(fmt),'wb').write(s) |
|
2008
f643cd8fee79
Test PICT transparency & move to better markfilename
rgbecker
parents:
2000
diff
changeset
|
250 |
if os.name=='mac': |
f643cd8fee79
Test PICT transparency & move to better markfilename
rgbecker
parents:
2000
diff
changeset
|
251 |
from reportlab.lib.utils import markfilename |
f643cd8fee79
Test PICT transparency & move to better markfilename
rgbecker
parents:
2000
diff
changeset
|
252 |
markfilename(fn,ext='PICT') |
1904 | 253 |
else: |
254 |
fn.write(s) |
|
1899 | 255 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
256 |
BEZIER_ARC_MAGIC = 0.5522847498 #constant for drawing circular arcs w/ Beziers |
899 | 257 |
class PMCanvas: |
1845 | 258 |
def __init__(self,w,h,dpi=72,bg=0xffffff,configPIL=None): |
259 |
'''configPIL dict is passed to image save method''' |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
260 |
scale = dpi/72.0 |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
261 |
w = int(w*scale+0.5) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
262 |
h = int(h*scale+0.5) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
263 |
self.__dict__['_gs'] = _renderPM.gstate(w,h,bg=bg) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
264 |
self.__dict__['_bg'] = bg |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
265 |
self.__dict__['_baseCTM'] = (scale,0,0,scale,0,0) |
1697 | 266 |
self.__dict__['_clipPaths'] = [] |
1845 | 267 |
self.__dict__['configPIL'] = configPIL |
1993 | 268 |
self.__dict__['_dpi'] = dpi |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
269 |
self.ctm = self._baseCTM |
899 | 270 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
271 |
def _drawTimeResize(self,w,h,bg=None): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
272 |
if bg is None: bg = self._bg |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
273 |
self._drawing.width, self._drawing.height = w, h |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
274 |
A = {'ctm':None, 'strokeWidth':None, 'strokeColor':None, 'lineCap':None, 'lineJoin':None, 'dashArray':None, 'fillColor':None} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
275 |
gs = self._gs |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
276 |
fN,fS = gs.fontName, gs.fontSize |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
277 |
for k in A.keys(): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
278 |
A[k] = getattr(gs,k) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
279 |
del gs, self._gs |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
280 |
gs = self.__dict__['_gs'] = _renderPM.gstate(w,h,bg=bg) |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
281 |
for k in A.keys(): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
282 |
setattr(self,k,A[k]) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
283 |
gs.setFont(fN,fS) |
1665 | 284 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
285 |
def toPIL(self): |
1895 | 286 |
im = _getImage().new('RGB', size=(self._gs.width, self._gs.height)) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
287 |
im.fromstring(self._gs.pixBuf) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
288 |
return im |
899 | 289 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
290 |
def saveToFile(self,fn,fmt=None): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
291 |
im = self.toPIL() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
292 |
if fmt is None: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
293 |
if type(fn) is not StringType: |
3721 | 294 |
raise ValueError("Invalid type '%s' for fn when fmt is None" % type(fn)) |
2401 | 295 |
fmt = os.path.splitext(fn)[1] |
296 |
if fmt.startswith('.'): fmt = fmt[1:] |
|
297 |
configPIL = self.configPIL or {} |
|
2818
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
298 |
configPIL.setdefault('preConvertCB',None) |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
299 |
preConvertCB=configPIL.pop('preConvertCB') |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
300 |
if preConvertCB: |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
301 |
im = preConvertCB(im) |
2401 | 302 |
fmt = string.upper(fmt) |
2818
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
303 |
if fmt in ('GIF',): |
2401 | 304 |
im = _convert2pilp(im) |
2811
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
305 |
elif fmt in ('TIFF','TIFFP','TIFFL','TIF','TIFF1'): |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
306 |
if fmt.endswith('P'): |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
307 |
im = _convert2pilp(im) |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
308 |
elif fmt.endswith('L'): |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
309 |
im = _convert2pilL(im) |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
310 |
elif fmt.endswith('1'): |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
311 |
im = _convert2pil1(im) |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
312 |
fmt='TIFF' |
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
313 |
elif fmt in ('PCT','PICT'): |
2401 | 314 |
return _saveAsPICT(im,fn,fmt,transparent=configPIL.get('transparent',None)) |
2811
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
315 |
elif fmt in ('PNG','BMP', 'PPM'): |
2401 | 316 |
if fmt=='PNG': |
317 |
try: |
|
318 |
from PIL import PngImagePlugin |
|
319 |
except ImportError: |
|
320 |
import PngImagePlugin |
|
321 |
elif fmt=='BMP': |
|
322 |
try: |
|
323 |
from PIL import BmpImagePlugin |
|
324 |
except ImportError: |
|
325 |
import BmpImagePlugin |
|
326 |
elif fmt in ('JPG','JPEG'): |
|
327 |
fmt = 'JPEG' |
|
2806 | 328 |
elif fmt in ('GIF',): |
329 |
pass |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
330 |
else: |
3721 | 331 |
raise RenderPMError("Unknown image kind %s" % fmt) |
2401 | 332 |
if fmt=='TIFF': |
333 |
tc = configPIL.get('transparent',None) |
|
334 |
if tc: |
|
335 |
from PIL import ImageChops, Image |
|
336 |
T = 768*[0] |
|
337 |
for o, c in zip((0,256,512), tc.bitmap_rgb()): |
|
338 |
T[o+c] = 255 |
|
339 |
#if type(fn) is type(''): ImageChops.invert(im.point(T).convert('L').point(255*[0]+[255])).save(fn+'_mask.gif','GIF') |
|
340 |
im = Image.merge('RGBA', im.split()+(ImageChops.invert(im.point(T).convert('L').point(255*[0]+[255])),)) |
|
341 |
#if type(fn) is type(''): im.save(fn+'_masked.gif','GIF') |
|
342 |
for a,d in ('resolution',self._dpi),('resolution unit','inch'): |
|
343 |
configPIL[a] = configPIL.get(a,d) |
|
2818
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
344 |
configPIL.setdefault('chops_invert',0) |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
345 |
if configPIL.pop('chops_invert'): |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
346 |
from PIL import ImageChops |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
347 |
im = ImageChops.invert(im) |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
348 |
configPIL.setdefault('preSaveCB',None) |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
349 |
preSaveCB=configPIL.pop('preSaveCB') |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
350 |
if preSaveCB: |
ccff6734b82b
renderPM.py: added preConvert/preSaveCB args and also invert option
rgbecker
parents:
2811
diff
changeset
|
351 |
im = preSaveCB(im) |
2811
3062d7ba9d04
reportlab/graphics: add tiffl, tiff1 formats & allow for kwds in asString
rgbecker
parents:
2806
diff
changeset
|
352 |
im.save(fn,fmt,**configPIL) |
2401 | 353 |
if not hasattr(fn,'write') and os.name=='mac': |
354 |
from reportlab.lib.utils import markfilename |
|
355 |
markfilename(fn,ext=fmt) |
|
899 | 356 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
357 |
def saveToString(self,fmt='GIF'): |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
358 |
s = getBytesIO() |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
359 |
self.saveToFile(s,fmt=fmt) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
360 |
return s.getvalue() |
939 | 361 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
362 |
def _saveToBMP(self,f): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
363 |
''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
364 |
Niki Spahiev, <niki@vintech.bg>, asserts that this is a respectable way to get BMP without PIL |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
365 |
f is a file like object to which the BMP is written |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
366 |
''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
367 |
import struct |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
368 |
gs = self._gs |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
369 |
pix, width, height = gs.pixBuf, gs.width, gs.height |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
370 |
f.write(struct.pack('=2sLLLLLLhh24x','BM',len(pix)+54,0,54,40,width,height,1,24)) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
371 |
rowb = width * 3 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
372 |
for o in range(len(pix),0,-rowb): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
373 |
f.write(pix[o-rowb:o]) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
374 |
f.write( '\0' * 14 ) |
1418 | 375 |
|
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
376 |
def setFont(self,fontName,fontSize,leading=None): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
377 |
_setFont(self._gs,fontName,fontSize) |
899 | 378 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
379 |
def __setattr__(self,name,value): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
380 |
setattr(self._gs,name,value) |
899 | 381 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
382 |
def __getattr__(self,name): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
383 |
return getattr(self._gs,name) |
899 | 384 |
|
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
385 |
def fillstrokepath(self,stroke=1,fill=1): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
386 |
if fill: self.pathFill() |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
387 |
if stroke: self.pathStroke() |
899 | 388 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
389 |
def _bezierArcSegmentCCW(self, cx,cy, rx,ry, theta0, theta1): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
390 |
"""compute the control points for a bezier arc with theta1-theta0 <= 90. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
391 |
Points are computed for an arc with angle theta increasing in the |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
392 |
counter-clockwise (CCW) direction. returns a tuple with starting point |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
393 |
and 3 control points of a cubic bezier curve for the curvto opertator""" |
899 | 394 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
395 |
# Requires theta1 - theta0 <= 90 for a good approximation |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
396 |
assert abs(theta1 - theta0) <= 90 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
397 |
cos0 = cos(pi*theta0/180.0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
398 |
sin0 = sin(pi*theta0/180.0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
399 |
x0 = cx + rx*cos0 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
400 |
y0 = cy + ry*sin0 |
899 | 401 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
402 |
cos1 = cos(pi*theta1/180.0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
403 |
sin1 = sin(pi*theta1/180.0) |
899 | 404 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
405 |
x3 = cx + rx*cos1 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
406 |
y3 = cy + ry*sin1 |
899 | 407 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
408 |
dx1 = -rx * sin0 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
409 |
dy1 = ry * cos0 |
899 | 410 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
411 |
#from pdfgeom |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
412 |
halfAng = pi*(theta1-theta0)/(2.0 * 180.0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
413 |
k = abs(4.0 / 3.0 * (1.0 - cos(halfAng) ) /(sin(halfAng)) ) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
414 |
x1 = x0 + dx1 * k |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
415 |
y1 = y0 + dy1 * k |
899 | 416 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
417 |
dx2 = -rx * sin1 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
418 |
dy2 = ry * cos1 |
899 | 419 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
420 |
x2 = x3 - dx2 * k |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
421 |
y2 = y3 - dy2 * k |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
422 |
return ((x0,y0), ((x1,y1), (x2,y2), (x3,y3)) ) |
899 | 423 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
424 |
def bezierArcCCW(self, cx,cy, rx,ry, theta0, theta1): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
425 |
"""return a set of control points for Bezier approximation to an arc |
3028
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
426 |
with angle increasing counter clockwise. No requirement on (theta1-theta0) <= 90 |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
427 |
However, it must be true that theta1-theta0 > 0.""" |
899 | 428 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
429 |
# I believe this is also clockwise |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
430 |
# pretty much just like Robert Kern's pdfgeom.BezierArc |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
431 |
angularExtent = theta1 - theta0 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
432 |
# break down the arc into fragments of <=90 degrees |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
433 |
if abs(angularExtent) <= 90.0: # we just need one fragment |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
434 |
angleList = [(theta0,theta1)] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
435 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
436 |
Nfrag = int( ceil( abs(angularExtent)/90.) ) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
437 |
fragAngle = float(angularExtent)/ Nfrag # this could be negative |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
438 |
angleList = [] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
439 |
for ii in range(Nfrag): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
440 |
a = theta0 + ii * fragAngle |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
441 |
b = a + fragAngle # hmm.. is I wonder if this is precise enought |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
442 |
angleList.append((a,b)) |
899 | 443 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
444 |
ctrlpts = [] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
445 |
for (a,b) in angleList: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
446 |
if not ctrlpts: # first time |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
447 |
[(x0,y0), pts] = self._bezierArcSegmentCCW(cx,cy, rx,ry, a,b) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
448 |
ctrlpts.append(pts) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
449 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
450 |
[(tmpx,tmpy), pts] = self._bezierArcSegmentCCW(cx,cy, rx,ry, a,b) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
451 |
ctrlpts.append(pts) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
452 |
return ((x0,y0), ctrlpts) |
899 | 453 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
454 |
def addEllipsoidalArc(self, cx,cy, rx, ry, ang1, ang2): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
455 |
"""adds an ellisesoidal arc segment to a path, with an ellipse centered |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
456 |
on cx,cy and with radii (major & minor axes) rx and ry. The arc is |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
457 |
drawn in the CCW direction. Requires: (ang2-ang1) > 0""" |
899 | 458 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
459 |
((x0,y0), ctrlpts) = self.bezierArcCCW(cx,cy, rx,ry,ang1,ang2) |
899 | 460 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
461 |
self.lineTo(x0,y0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
462 |
for ((x1,y1), (x2,y2),(x3,y3)) in ctrlpts: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
463 |
self.curveTo(x1,y1,x2,y2,x3,y3) |
899 | 464 |
|
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
465 |
def drawCentredString(self, x, y, text, text_anchor='middle'): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
466 |
if self.fillColor is not None: |
2405 | 467 |
textLen = stringWidth(text, self.fontName,self.fontSize) |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
468 |
if text_anchor=='end': |
2574 | 469 |
x -= textLen |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
470 |
elif text_anchor=='middle': |
2574 | 471 |
x -= textLen/2. |
3219
b28d6eef8227
reportlab: add support for String anchor 'numeric'
rgbecker
parents:
3180
diff
changeset
|
472 |
elif text_anchor=='numeric': |
b28d6eef8227
reportlab: add support for String anchor 'numeric'
rgbecker
parents:
3180
diff
changeset
|
473 |
x -= numericXShift(text_anchor,text,textLen,self.fontName,self.fontSize) |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
474 |
self.drawString(x,y,text) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
475 |
|
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
476 |
def drawRightString(self, text, x, y): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
477 |
self.drawCentredString(text,x,y,text_anchor='end') |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
478 |
|
2761 | 479 |
def drawString(self, x, y, text, _fontInfo=None): |
480 |
gs = self._gs |
|
481 |
if _fontInfo: |
|
482 |
fontName, fontSize = _fontInfo |
|
483 |
else: |
|
484 |
fontSize = gs.fontSize |
|
485 |
fontName = gs.fontName |
|
486 |
try: |
|
487 |
gfont=getFont(gs.fontName) |
|
488 |
except: |
|
489 |
gfont = None |
|
490 |
font = getFont(fontName) |
|
491 |
if font._dynamicFont: |
|
3721 | 492 |
if isinstance(text,str): text = text.encode('utf8') |
2761 | 493 |
gs.drawString(x,y,text) |
494 |
else: |
|
495 |
fc = font |
|
3721 | 496 |
if not isinstance(text,str): |
2761 | 497 |
try: |
498 |
text = text.decode('utf8') |
|
3721 | 499 |
except UnicodeDecodeError as e: |
2761 | 500 |
i,j = e.args[2:4] |
501 |
raise UnicodeDecodeError(*(e.args[:4]+('%s\n%s-->%s<--%s' % (e.args[4],text[i-10:i],text[i:j],text[j:j+10]),))) |
|
502 |
||
503 |
FT = unicode2T1(text,[font]+font.substitutionFonts) |
|
504 |
n = len(FT) |
|
505 |
nm1 = n-1 |
|
506 |
wscale = 0.001*fontSize |
|
3721 | 507 |
for i in range(n): |
2761 | 508 |
f, t = FT[i] |
509 |
if f!=fc: |
|
510 |
_setFont(gs,f.fontName,fontSize) |
|
511 |
fc = f |
|
512 |
gs.drawString(x,y,t) |
|
513 |
if i!=nm1: |
|
3721 | 514 |
x += wscale*sum(map(f.widths.__getitem__,list(map(ord,t)))) |
2761 | 515 |
if font!=fc: |
516 |
_setFont(gs,fontName,fontSize) |
|
517 |
||
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
518 |
def line(self,x1,y1,x2,y2): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
519 |
if self.strokeColor is not None: |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
520 |
self.pathBegin() |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
521 |
self.moveTo(x1,y1) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
522 |
self.lineTo(x2,y2) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
523 |
self.pathStroke() |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
524 |
|
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
525 |
def rect(self,x,y,width,height,stroke=1,fill=1): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
526 |
self.pathBegin() |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
527 |
self.moveTo(x, y) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
528 |
self.lineTo(x+width, y) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
529 |
self.lineTo(x+width, y + height) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
530 |
self.lineTo(x, y + height) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
531 |
self.pathClose() |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
532 |
self.fillstrokepath(stroke=stroke,fill=fill) |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
533 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
534 |
def roundRect(self, x, y, width, height, rx,ry): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
535 |
"""rect(self, x, y, width, height, rx,ry): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
536 |
Draw a rectangle if rx or rx and ry are specified the corners are |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
537 |
rounded with ellipsoidal arcs determined by rx and ry |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
538 |
(drawn in the counter-clockwise direction)""" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
539 |
if rx==0: rx = ry |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
540 |
if ry==0: ry = rx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
541 |
x2 = x + width |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
542 |
y2 = y + height |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
543 |
self.pathBegin() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
544 |
self.moveTo(x+rx,y) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
545 |
self.addEllipsoidalArc(x2-rx, y+ry, rx, ry, 270, 360 ) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
546 |
self.addEllipsoidalArc(x2-rx, y2-ry, rx, ry, 0, 90) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
547 |
self.addEllipsoidalArc(x+rx, y2-ry, rx, ry, 90, 180) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
548 |
self.addEllipsoidalArc(x+rx, y+ry, rx, ry, 180, 270) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
549 |
self.pathClose() |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
550 |
self.fillstrokepath() |
899 | 551 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
552 |
def circle(self, cx, cy, r): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
553 |
"add closed path circle with center cx,cy and axes r: counter-clockwise orientation" |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
554 |
self.ellipse(cx,cy,r,r) |
899 | 555 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
556 |
def ellipse(self, cx,cy,rx,ry): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
557 |
"""add closed path ellipse with center cx,cy and axes rx,ry: counter-clockwise orientation |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
558 |
(remember y-axis increases downward) """ |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
559 |
self.pathBegin() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
560 |
# first segment |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
561 |
x0 = cx + rx # (x0,y0) start pt |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
562 |
y0 = cy |
1683 | 563 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
564 |
x3 = cx # (x3,y3) end pt of arc |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
565 |
y3 = cy-ry |
899 | 566 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
567 |
x1 = cx+rx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
568 |
y1 = cy-ry*BEZIER_ARC_MAGIC |
899 | 569 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
570 |
x2 = x3 + rx*BEZIER_ARC_MAGIC |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
571 |
y2 = y3 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
572 |
self.moveTo(x0, y0) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
573 |
self.curveTo(x1,y1,x2,y2,x3,y3) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
574 |
# next segment |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
575 |
x0 = x3 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
576 |
y0 = y3 |
1683 | 577 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
578 |
x3 = cx-rx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
579 |
y3 = cy |
899 | 580 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
581 |
x1 = cx-rx*BEZIER_ARC_MAGIC |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
582 |
y1 = cy-ry |
899 | 583 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
584 |
x2 = x3 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
585 |
y2 = cy- ry*BEZIER_ARC_MAGIC |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
586 |
self.curveTo(x1,y1,x2,y2,x3,y3) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
587 |
# next segment |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
588 |
x0 = x3 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
589 |
y0 = y3 |
1683 | 590 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
591 |
x3 = cx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
592 |
y3 = cy+ry |
899 | 593 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
594 |
x1 = cx-rx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
595 |
y1 = cy+ry*BEZIER_ARC_MAGIC |
899 | 596 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
597 |
x2 = cx -rx*BEZIER_ARC_MAGIC |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
598 |
y2 = cy+ry |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
599 |
self.curveTo(x1,y1,x2,y2,x3,y3) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
600 |
#last segment |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
601 |
x0 = x3 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
602 |
y0 = y3 |
1683 | 603 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
604 |
x3 = cx+rx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
605 |
y3 = cy |
899 | 606 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
607 |
x1 = cx+rx*BEZIER_ARC_MAGIC |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
608 |
y1 = cy+ry |
899 | 609 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
610 |
x2 = cx+rx |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
611 |
y2 = cy+ry*BEZIER_ARC_MAGIC |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
612 |
self.curveTo(x1,y1,x2,y2,x3,y3) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
613 |
self.pathClose() |
899 | 614 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
615 |
def saveState(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
616 |
'''do nothing for compatibility''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
617 |
pass |
1259
49bfe92e612e
Used showBoundary every wherei, moved to Drawings as Groups
rgbecker
parents:
1230
diff
changeset
|
618 |
|
2401 | 619 |
def setFillColor(self,aColor): |
620 |
self.fillColor = Color2Hex(aColor) |
|
3281
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
621 |
alpha = getattr(aColor,'alpha',None) |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
622 |
if alpha is not None: |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
623 |
self.fillOpacity = alpha |
2401 | 624 |
|
625 |
def setStrokeColor(self,aColor): |
|
626 |
self.strokeColor = Color2Hex(aColor) |
|
3281
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
627 |
alpha = getattr(aColor,'alpha',None) |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
628 |
if alpha is not None: |
2a5d7d015044
renderPM.py: add support for opacity to python side of _renderPM extension
rgbecker
parents:
3255
diff
changeset
|
629 |
self.strokeOpacity = alpha |
2401 | 630 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
631 |
restoreState = saveState |
1259
49bfe92e612e
Used showBoundary every wherei, moved to Drawings as Groups
rgbecker
parents:
1230
diff
changeset
|
632 |
|
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
633 |
# compatibility routines |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
634 |
def setLineCap(self,cap): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
635 |
self.lineCap = cap |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
636 |
|
2761 | 637 |
def setLineJoin(self,join): |
638 |
self.lineJoin = join |
|
639 |
||
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
640 |
def setLineWidth(self,width): |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
641 |
self.strokeWidth = width |
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
642 |
|
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
643 |
def drawToPMCanvas(d, dpi=72, bg=0xffffff, configPIL=None, showBoundary=rl_config._unset_): |
2544
a6b9aa99b3c3
graphics: added Drawing.renderScale hack for renderer terminal drawing scales
rgbecker
parents:
2405
diff
changeset
|
644 |
d = renderScaledDrawing(d) |
2402
da8c6a14c84f
minor changes for pdf canvas compatibility and tests
rgbecker
parents:
2401
diff
changeset
|
645 |
c = PMCanvas(d.width, d.height, dpi=dpi, bg=bg, configPIL=configPIL) |
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
646 |
draw(d, c, 0, 0, showBoundary=showBoundary) |
1895 | 647 |
return c |
648 |
||
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
649 |
def drawToPIL(d, dpi=72, bg=0xffffff, configPIL=None, showBoundary=rl_config._unset_): |
1895 | 650 |
return drawToPMCanvas(d, dpi=dpi, bg=bg, configPIL=configPIL, showBoundary=showBoundary).toPIL() |
651 |
||
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
652 |
def drawToPILP(d, dpi=72, bg=0xffffff, configPIL=None, showBoundary=rl_config._unset_): |
1895 | 653 |
Image = _getImage() |
654 |
im = drawToPIL(d, dpi=dpi, bg=bg, configPIL=configPIL, showBoundary=showBoundary) |
|
655 |
return im.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE) |
|
1259
49bfe92e612e
Used showBoundary every wherei, moved to Drawings as Groups
rgbecker
parents:
1230
diff
changeset
|
656 |
|
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
657 |
def drawToFile(d,fn,fmt='GIF', dpi=72, bg=0xffffff, configPIL=None, showBoundary=rl_config._unset_): |
1845 | 658 |
'''create a pixmap and draw drawing, d to it then save as a file |
659 |
configPIL dict is passed to image save method''' |
|
1895 | 660 |
c = drawToPMCanvas(d, dpi=dpi, bg=bg, configPIL=configPIL, showBoundary=showBoundary) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
661 |
c.saveToFile(fn,fmt) |
899 | 662 |
|
2360
0fbaee224de1
rl_config add _unset_, graphics.renderxxx refactoring
rgbecker
parents:
2357
diff
changeset
|
663 |
def drawToString(d,fmt='GIF', dpi=72, bg=0xffffff, configPIL=None, showBoundary=rl_config._unset_): |
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
664 |
s = getBytesIO() |
1845 | 665 |
drawToFile(d,s,fmt=fmt, dpi=dpi, bg=bg, configPIL=configPIL) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
666 |
return s.getvalue() |
944 | 667 |
|
899 | 668 |
save = drawToFile |
669 |
||
3604
8ddab7f65f99
added failing test for finding custom fonts on Ubuntu
andy
parents:
3562
diff
changeset
|
670 |
def test(verbose=True): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
671 |
def ext(x): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
672 |
if x=='tiff': x='tif' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1665
diff
changeset
|
673 |
return x |
1924 | 674 |
#grab all drawings from the test module and write out. |
675 |
#make a page of links in HTML to assist viewing. |
|
676 |
import os |
|
2124 | 677 |
from reportlab.graphics import testshapes |
678 |
getAllTestDrawings = testshapes.getAllTestDrawings |
|
1924 | 679 |
drawings = [] |
680 |
if not os.path.isdir('pmout'): |
|
681 |
os.mkdir('pmout') |
|
682 |
htmlTop = """<html><head><title>renderPM output results</title></head> |
|
683 |
<body> |
|
684 |
<h1>renderPM results of output</h1> |
|
685 |
""" |
|
686 |
htmlBottom = """</body> |
|
687 |
</html> |
|
688 |
""" |
|
689 |
html = [htmlTop] |
|
3370
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
690 |
names = {} |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
691 |
argv = sys.argv[1:] |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
692 |
E = [a for a in argv if a.startswith('--ext=')] |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
693 |
if not E: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
694 |
E = ['gif','tiff', 'png', 'jpg', 'pct', 'py', 'svg'] |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
695 |
else: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
696 |
for a in E: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
697 |
argv.remove(a) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
698 |
E = (','.join([a[6:] for a in E])).split(',') |
2126 | 699 |
|
1924 | 700 |
#print in a loop, with their doc strings |
2184 | 701 |
for (drawing, docstring, name) in getAllTestDrawings(doTTF=hasattr(_renderPM,'ft_get_face')): |
3370
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
702 |
i = names[name] = names.setdefault(name,0)+1 |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
703 |
if i>1: name += '.%02d' % (i-1) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
704 |
if argv and name not in argv: continue |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
705 |
fnRoot = name |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
706 |
w = int(drawing.width) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
707 |
h = int(drawing.height) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
708 |
html.append('<hr><h2>Drawing %s</h2>\n<pre>%s</pre>' % (name, docstring)) |
899 | 709 |
|
3370
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
710 |
for k in E: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
711 |
if k in ['gif','png','jpg','pct']: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
712 |
html.append('<p>%s format</p>\n' % string.upper(k)) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
713 |
try: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
714 |
filename = '%s.%s' % (fnRoot, ext(k)) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
715 |
fullpath = os.path.join('pmout', filename) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
716 |
if os.path.isfile(fullpath): |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
717 |
os.remove(fullpath) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
718 |
if k=='pct': |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
719 |
from reportlab.lib.colors import white |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
720 |
drawToFile(drawing,fullpath,fmt=k,configPIL={'transparent':white}) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
721 |
elif k in ['py','svg']: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
722 |
drawing.save(formats=['py','svg'],outDir='pmout',fnRoot=fnRoot) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
723 |
else: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
724 |
drawToFile(drawing,fullpath,fmt=k) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
725 |
if k in ['gif','png','jpg']: |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
726 |
html.append('<img src="%s" border="1"><br>\n' % filename) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
727 |
elif k=='py': |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
728 |
html.append('<a href="%s">python source</a><br>\n' % filename) |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
729 |
elif k=='svg': |
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
730 |
html.append('<a href="%s">SVG</a><br>\n' % filename) |
3721 | 731 |
if verbose: print('wrote',fullpath) |
3370
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
732 |
except AttributeError: |
3721 | 733 |
print('Problem drawing %s file'%k) |
3370
0783797d9871
graphics.py: adjust renderPM test and fix renderSVG PolyLine
rgbecker
parents:
3365
diff
changeset
|
734 |
raise |
2206 | 735 |
if os.environ.get('RL_NOEPSPREVIEW','0')=='1': drawing.__dict__['preview'] = 0 |
2000 | 736 |
drawing.save(formats=['eps','pdf'],outDir='pmout',fnRoot=fnRoot) |
1924 | 737 |
html.append(htmlBottom) |
738 |
htmlFileName = os.path.join('pmout', 'index.html') |
|
739 |
open(htmlFileName, 'w').writelines(html) |
|
2052
96b3fec87ba0
Now uses markfilename from lib.utils for setting the filetype for the
johnprecedo
parents:
2016
diff
changeset
|
740 |
if sys.platform=='mac': |
96b3fec87ba0
Now uses markfilename from lib.utils for setting the filetype for the
johnprecedo
parents:
2016
diff
changeset
|
741 |
from reportlab.lib.utils import markfilename |
96b3fec87ba0
Now uses markfilename from lib.utils for setting the filetype for the
johnprecedo
parents:
2016
diff
changeset
|
742 |
markfilename(htmlFileName,ext='HTML') |
3721 | 743 |
if verbose: print('wrote %s' % htmlFileName) |
1924 | 744 |
|
745 |
if __name__=='__main__': |
|
1697 | 746 |
test() |