summaryrefslogtreecommitdiff
path: root/bin/reportlab/graphics/renderbase.py
diff options
context:
space:
mode:
authorStephane Wirtel <stephane@tinyerp.com>2008-11-14 16:06:02 +0100
committerStephane Wirtel <stephane@tinyerp.com>2008-11-14 16:06:02 +0100
commit3dae09ac14990a82aa9ef8afc2a0429b877ab123 (patch)
treefd4e64f6f37c8f23f54119197fad7ea69de418e2 /bin/reportlab/graphics/renderbase.py
parent882cd7027feca65405cfdf1337064aa676830d4b (diff)
Remove pydot, pychart and reportlab.
bzr revid: stephane@tinyerp.com-20081114150602-cpp1eeo3d0837fev
Diffstat (limited to 'bin/reportlab/graphics/renderbase.py')
-rw-r--r--bin/reportlab/graphics/renderbase.py351
1 files changed, 0 insertions, 351 deletions
diff --git a/bin/reportlab/graphics/renderbase.py b/bin/reportlab/graphics/renderbase.py
deleted file mode 100644
index 10282e15af4..00000000000
--- a/bin/reportlab/graphics/renderbase.py
+++ /dev/null
@@ -1,351 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2004
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/graphics/renderbase.py
-"""
-Superclass for renderers to factor out common functionality and default implementations.
-"""
-
-
-__version__=''' $Id $ '''
-
-from reportlab.graphics.shapes import *
-from reportlab.lib.validators import DerivedValue
-from reportlab import rl_config
-
-def inverse(A):
- "For A affine 2D represented as 6vec return 6vec version of A**(-1)"
- # I checked this RGB
- det = float(A[0]*A[3] - A[2]*A[1])
- R = [A[3]/det, -A[1]/det, -A[2]/det, A[0]/det]
- return tuple(R+[-R[0]*A[4]-R[2]*A[5],-R[1]*A[4]-R[3]*A[5]])
-
-def mmult(A, B):
- "A postmultiplied by B"
- # I checked this RGB
- # [a0 a2 a4] [b0 b2 b4]
- # [a1 a3 a5] * [b1 b3 b5]
- # [ 1 ] [ 1 ]
- #
- return (A[0]*B[0] + A[2]*B[1],
- A[1]*B[0] + A[3]*B[1],
- A[0]*B[2] + A[2]*B[3],
- A[1]*B[2] + A[3]*B[3],
- A[0]*B[4] + A[2]*B[5] + A[4],
- A[1]*B[4] + A[3]*B[5] + A[5])
-
-
-def getStateDelta(shape):
- """Used to compute when we need to change the graphics state.
- For example, if we have two adjacent red shapes we don't need
- to set the pen color to red in between. Returns the effect
- the given shape would have on the graphics state"""
- delta = {}
- for (prop, value) in shape.getProperties().items():
- if STATE_DEFAULTS.has_key(prop):
- delta[prop] = value
- return delta
-
-
-class StateTracker:
- """Keeps a stack of transforms and state
- properties. It can contain any properties you
- want, but the keys 'transform' and 'ctm' have
- special meanings. The getCTM()
- method returns the current transformation
- matrix at any point, without needing to
- invert matrixes when you pop."""
- def __init__(self, defaults=None):
- # one stack to keep track of what changes...
- self._deltas = []
-
- # and another to keep track of cumulative effects. Last one in
- # list is the current graphics state. We put one in to simplify
- # loops below.
- self._combined = []
- if defaults is None:
- defaults = STATE_DEFAULTS.copy()
- #ensure that if we have a transform, we have a CTM
- if defaults.has_key('transform'):
- defaults['ctm'] = defaults['transform']
- self._combined.append(defaults)
-
- def push(self,delta):
- """Take a new state dictionary of changes and push it onto
- the stack. After doing this, the combined state is accessible
- through getState()"""
-
- newstate = self._combined[-1].copy()
- for (key, value) in delta.items():
- if key == 'transform': #do cumulative matrix
- newstate['transform'] = delta['transform']
- newstate['ctm'] = mmult(self._combined[-1]['ctm'], delta['transform'])
- #print 'statetracker transform = (%0.2f, %0.2f, %0.2f, %0.2f, %0.2f, %0.2f)' % tuple(newstate['transform'])
- #print 'statetracker ctm = (%0.2f, %0.2f, %0.2f, %0.2f, %0.2f, %0.2f)' % tuple(newstate['ctm'])
-
- else: #just overwrite it
- newstate[key] = value
-
- self._combined.append(newstate)
- self._deltas.append(delta)
-
- def pop(self):
- """steps back one, and returns a state dictionary with the
- deltas to reverse out of wherever you are. Depending
- on your back end, you may not need the return value,
- since you can get the complete state afterwards with getState()"""
- del self._combined[-1]
- newState = self._combined[-1]
- lastDelta = self._deltas[-1]
- del self._deltas[-1]
- #need to diff this against the last one in the state
- reverseDelta = {}
- #print 'pop()...'
- for key, curValue in lastDelta.items():
- #print ' key=%s, value=%s' % (key, curValue)
- prevValue = newState[key]
- if prevValue <> curValue:
- #print ' state popping "%s"="%s"' % (key, curValue)
- if key == 'transform':
- reverseDelta[key] = inverse(lastDelta['transform'])
- else: #just return to previous state
- reverseDelta[key] = prevValue
- return reverseDelta
-
- def getState(self):
- "returns the complete graphics state at this point"
- return self._combined[-1]
-
- def getCTM(self):
- "returns the current transformation matrix at this point"""
- return self._combined[-1]['ctm']
-
- def __getitem__(self,key):
- "returns the complete graphics state value of key at this point"
- return self._combined[-1][key]
-
- def __setitem__(self,key,value):
- "sets the complete graphics state value of key to value"
- self._combined[-1][key] = value
-
-def testStateTracker():
- print 'Testing state tracker'
- defaults = {'fillColor':None, 'strokeColor':None,'fontName':None, 'transform':[1,0,0,1,0,0]}
- deltas = [
- {'fillColor':'red'},
- {'fillColor':'green', 'strokeColor':'blue','fontName':'Times-Roman'},
- {'transform':[0.5,0,0,0.5,0,0]},
- {'transform':[0.5,0,0,0.5,2,3]},
- {'strokeColor':'red'}
- ]
-
- st = StateTracker(defaults)
- print 'initial:', st.getState()
- print
- for delta in deltas:
- print 'pushing:', delta
- st.push(delta)
- print 'state: ',st.getState(),'\n'
-
- for delta in deltas:
- print 'popping:',st.pop()
- print 'state: ',st.getState(),'\n'
-
-
-def _expandUserNode(node,canvas):
- if isinstance(node, UserNode):
- try:
- if hasattr(node,'_canvas'):
- ocanvas = 1
- else:
- node._canvas = canvas
- ocanvas = None
- onode = node
- node = node.provideNode()
- finally:
- if not ocanvas: del onode._canvas
- return node
-
-def renderScaledDrawing(d):
- renderScale = d.renderScale
- if renderScale!=1.0:
- d = d.copy()
- d.width *= renderScale
- d.height *= renderScale
- d.scale(renderScale,renderScale)
- d.renderScale = 1.0
- return d
-
-class Renderer:
- """Virtual superclass for graphics renderers."""
-
- def __init__(self):
- self._tracker = StateTracker()
- self._nodeStack = [] #track nodes visited
-
- def undefined(self, operation):
- raise ValueError, "%s operation not defined at superclass class=%s" %(operation, self.__class__)
-
- def draw(self, drawing, canvas, x=0, y=0, showBoundary=rl_config._unset_):
- """This is the top level function, which draws the drawing at the given
- location. The recursive part is handled by drawNode."""
- #stash references for ease of communication
- if showBoundary is rl_config._unset_: showBoundary=rl_config.showBoundary
- self._canvas = canvas
- canvas.__dict__['_drawing'] = self._drawing = drawing
- drawing._parent = None
- try:
- #bounding box
- if showBoundary: canvas.rect(x, y, drawing.width, drawing.height)
- canvas.saveState()
- self.initState(x,y) #this is the push()
- self.drawNode(drawing)
- self.pop()
- canvas.restoreState()
- finally:
- #remove any circular references
- del self._canvas, self._drawing, canvas._drawing, drawing._parent
-
- def initState(self,x,y):
- deltas = STATE_DEFAULTS.copy()
- deltas['transform'] = [1,0,0,1,x,y]
- self._tracker.push(deltas)
- self.applyStateChanges(deltas, {})
-
- def pop(self):
- self._tracker.pop()
-
- def drawNode(self, node):
- """This is the recursive method called for each node
- in the tree"""
- # Undefined here, but with closer analysis probably can be handled in superclass
- self.undefined("drawNode")
-
- def getStateValue(self, key):
- """Return current state parameter for given key"""
- currentState = self._tracker._combined[-1]
- return currentState[key]
-
- def fillDerivedValues(self, node):
- """Examine a node for any values which are Derived,
- and replace them with their calculated values.
- Generally things may look at the drawing or their
- parent.
-
- """
- for (key, value) in node.__dict__.items():
- if isinstance(value, DerivedValue):
- #just replace with default for key?
- #print ' fillDerivedValues(%s)' % key
- newValue = value.getValue(self, key)
- #print ' got value of %s' % newValue
- node.__dict__[key] = newValue
-
- def drawNodeDispatcher(self, node):
- """dispatch on the node's (super) class: shared code"""
-
- canvas = getattr(self,'_canvas',None)
- # replace UserNode with its contents
-
- try:
- node = _expandUserNode(node,canvas)
- if hasattr(node,'_canvas'):
- ocanvas = 1
- else:
- node._canvas = canvas
- ocanvas = None
-
- self.fillDerivedValues(node)
- #draw the object, or recurse
- if isinstance(node, Line):
- self.drawLine(node)
- elif isinstance(node, Image):
- self.drawImage(node)
- elif isinstance(node, Rect):
- self.drawRect(node)
- elif isinstance(node, Circle):
- self.drawCircle(node)
- elif isinstance(node, Ellipse):
- self.drawEllipse(node)
- elif isinstance(node, PolyLine):
- self.drawPolyLine(node)
- elif isinstance(node, Polygon):
- self.drawPolygon(node)
- elif isinstance(node, Path):
- self.drawPath(node)
- elif isinstance(node, String):
- self.drawString(node)
- elif isinstance(node, Group):
- self.drawGroup(node)
- elif isinstance(node, Wedge):
- self.drawWedge(node)
- else:
- print 'DrawingError','Unexpected element %s in drawing!' % str(node)
- finally:
- if not ocanvas: del node._canvas
-
- _restores = {'stroke':'_stroke','stroke_width': '_lineWidth','stroke_linecap':'_lineCap',
- 'stroke_linejoin':'_lineJoin','fill':'_fill','font_family':'_font',
- 'font_size':'_fontSize'}
-
- def drawGroup(self, group):
- # just do the contents. Some renderers might need to override this
- # if they need a flipped transform
- canvas = getattr(self,'_canvas',None)
- for node in group.getContents():
- node = _expandUserNode(node,canvas)
-
- #here is where we do derived values - this seems to get everything. Touch wood.
- self.fillDerivedValues(node)
- try:
- if hasattr(node,'_canvas'):
- ocanvas = 1
- else:
- node._canvas = canvas
- ocanvas = None
- node._parent = group
- self.drawNode(node)
- finally:
- del node._parent
- if not ocanvas: del node._canvas
-
- def drawWedge(self, wedge):
- # by default ask the wedge to make a polygon of itself and draw that!
- #print "drawWedge"
- polygon = wedge.asPolygon()
- self.drawPolygon(polygon)
-
- def drawPath(self, path):
- polygons = path.asPolygons()
- for polygon in polygons:
- self.drawPolygon(polygon)
-
- def drawRect(self, rect):
- # could be implemented in terms of polygon
- self.undefined("drawRect")
-
- def drawLine(self, line):
- self.undefined("drawLine")
-
- def drawCircle(self, circle):
- self.undefined("drawCircle")
-
- def drawPolyLine(self, p):
- self.undefined("drawPolyLine")
-
- def drawEllipse(self, ellipse):
- self.undefined("drawEllipse")
-
- def drawPolygon(self, p):
- self.undefined("drawPolygon")
-
- def drawString(self, stringObj):
- self.undefined("drawString")
-
- def applyStateChanges(self, delta, newState):
- """This takes a set of states, and outputs the operators
- needed to set those properties"""
- self.undefined("applyStateChanges")
-
-if __name__=='__main__':
- print "this file has no script interpretation"
- print __doc__