diff options
| author | pinky <> | 2007-01-07 23:07:40 +0000 |
|---|---|---|
| committer | pinky <> | 2007-01-07 23:07:40 +0000 |
| commit | e585ca2f943bae99eb9995faafc13a0437172e51 (patch) | |
| tree | cdad1e26c567b0d5be1abea1799615e50fb9d4a9 /bin/reportlab/graphics/renderbase.py | |
| parent | 05bb5d58295cd959c34f1fbcd5b605cd6dafaacc (diff) | |
Removed reportlab
bzr revid: pinky-6fa6b5bb1cfc5dd54307cd22a31f527d28d61e05
Diffstat (limited to 'bin/reportlab/graphics/renderbase.py')
| -rw-r--r-- | bin/reportlab/graphics/renderbase.py | 351 |
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__ |
