<reponame>maartenbreddels/kaplot
# -*- coding: utf-8 -*-
import kaplot
import kaplot.objects
import kaplot.utils
import kaplot.text

class DeviceBase(object):
	def __init__(self):
		self.contextList = [kaplot.defaultContext.clone()]
		self.worldList = [((0, 0), (0.100, 0.100))]
		#self.worldList = [((0, 0), (3, 3))]
		#self.worldList = [((10, 10), (0, 0))]
		self.viewportList = [((0.2, 0.1), (0.7, 0.9))]
		#self.viewportList = [((0.0, 0.0), (1.0, 1.0))]

		self._glyphCache = {}
		self._glyphNr = 1
		self._clipping = True
		self._color = kaplot.utils.getColor("red")
		#self._fontsize = "10mm"
		self._fontname = "Verdana"
		#self._symbolsize = "5mm"
		
		#self.dpi = 72
		self._alpha = 1
		
	def preDraw(self, document):
		pass

	def postDraw(self, document):
		pass

	def preDrawPage(self, document, page):
		self.setClipRegion()
		self.dpi = document.dpi
		self.pushContext(self.contextList[0])
	
	def postDrawPage(self, document, page):
		#print len(self.contextList)
		#print len(self.worldList)
		#print len(self.viewportList)
		pass

	###########  CONTEXT  #######################		
	def setColor(self, color):
		self._color = kaplot.utils.decodeColor(kaplot.utils.getColor(color))
		self._setColor()
		
	def getColor(self):
		return self._color
		
	def _setColor(self):
		kaplot.info("color not implementen on device", printonce=True)
		
	def setAlpha(self, alpha):
		self._alpha = alpha
		self._setAlpha()
		
	def getAlpha(self):
		return self._alpha
		
	def _setAlpha(self):
		kaplot.info("alpha not implementen on device", printonce=True)
		
	def setLinewidth(self, linewidth):
		self._linewidth = linewidth
		self._setLinewidth()

	def getLinewidth(self):
		return self._linewidth
		
	def _setLinewidth(self):
		kaplot.info("linewidth not implementen on device", printonce=True)
		
	def setLinestyle(self, linestyle):
		self._linestyle = kaplot.utils.getLinestyle(linestyle)
		self._setLinestyle()

	def getLinestyle(self):
		return self._linestyle
		
	def _setLinestyle(self):
		kaplot.info("linestyle not implementen on device", printonce=True)
		
	def setPatternSize(self, patternsize):
		self._patternsize = patternsize
		self._setPatternSize()

	def getPatternSize(self):
		return self._fillstyle
		
	def _setPatternSize(self):
		kaplot.info("patternsize not implementen on device", printonce=True)
		
	def setSymbolSize(self, symbolsize):
		self._symbolsize = symbolsize
		self._setSymbolSize()

	def getSymbolSize(self):
		return self._symbolsize
		
	def _setSymbolSize(self):
		kaplot.info("symbolsize not implementen on device", printonce=True)
		
	def setFillstyle(self, fillstyle):
		self._fillstyle = fillstyle
		self._setFillstyle()

	def getFillstyle(self):
		return self._fillstyle
		
	def _setFillstyle(self):
		kaplot.info("fillstyle not implementen on device", printonce=True)
		
	def setFontname(self, fontname):
		self._fontname = fontname
		self._setFontname()

	def getFontname(self):
		return self._fontname
		
	def _setFontname(self):
		kaplot.info("fontname not implementen on device", printonce=True)
		
	def setFontsize(self, fontsize):
		self._fontsize = fontsize
		self._setFontsize()

	def getFontsize(self):
		return self._fontsize
		
	def _setFontsize(self):
		kaplot.info("fontsize not implementen on device", printonce=True)
		
	def setClipping(self, clipping):
		self._clipping = clipping
		self._setClipping(clipping)
		
	def getClipping(self):
		return self._clipping
		
	def _setClipping(self, clipping):
		kaplot.info("clipping not implementen on device", printonce=True)
		
	def restoreColor(self):
		self.setColor(self._findInContextStack("color"))
		
	def restoreAlpha(self):
		self.setAlpha(self._findInContextStack("alpha"))
		
	def restoreLinewidth(self):
		self.setLinewidth(self._findInContextStack("linewidth"))
		
	def restoreLinestyle(self):
		self.setLinestyle(self._findInContextStack("linestyle"))

	def restorePatternSize(self):
		self.setPatternSize(self._findInContextStack("patternsize"))
		
	def restoreSymbolSize(self):
		self.setSymbolSize(self._findInContextStack("symbolsize"))
		
	def restoreFillstyle(self):
		self.setFillstyle(self._findInContextStack("fillstyle"))
		
	def restoreFontname(self):
		self.setFontname(self._findInContextStack("fontname"))
		
	def restoreFontsize(self):
		self.setFontsize(self._findInContextStack("fontsize"))
		
	def _findInContextStack(self, name):
		for context in self.contextList[::-1]:
			if hasattr(context, name):
				return getattr(context, name)
		raise Exception, "attribute '%s' not found in context stack" % name

	def pushContext(self, context):
		context = kaplot.Context(context)
		self.contextList.append(context)
		if "color" in context:
			self.setColor(context.color)
		if "alpha" in context:
			self.setAlpha(context.alpha)
		if "linewidth" in context:
			self.setLinewidth(context.linewidth)
		if "linestyle" in context:
			self.setLinestyle(context.linestyle)
		if "patternsize" in context:
			self.setPatternSize(context.patternsize)
		if "symbolsize" in context:
			self.setSymbolSize(context.symbolsize)
		if "fillstyle" in context:
			self.setFillstyle(context.fillstyle)
		if "fontname" in context:
			self.setFontname(context.fontname)
		if "fontsize" in context:
			self.setFontsize(context.fontsize)
		
	def popContext(self):
		context = self.contextList.pop()
		if "color" in context:
			self.restoreColor()
		if "alpha" in context:
			self.restoreAlpha()
		if "linewidth" in context:
			self.restoreLinewidth()
		if "linestyle" in context:
			self.restoreLinestyle()
		if "patternsize" in context:
			self.restorePatternSize()
		if "symbolsize" in context:
			self.restoreSymbolSize()
		if "fillstyle" in context:
			self.restoreFillstyle()
		if "fontname" in context:
			self.restoreFontname()
		if "fontsize" in context:
			self.restoreFontsize()
		#if hasattr(context, "viewport"):
		#	self.popViewport()
			
	############## COORDINATES ########################
	def pushWorld(self, world):
		self.worldList.append(world)
		
	def popWorld(self):
		self.worldList.pop()
		
	def getWorld(self):
		#(x1, y1), (x2, y2) = self.worldList[-1]
		#return (float(x1), float(y1)), (float(x2), float(y2))
		return self.worldList[-1]
		
	def getWorldMatrix(self):
		p1, p2 = self.worldList[-1]
		#return kaplot.Matrix.scalebox(p1, p2) 
		(x1, y1), (x2, y2) = self.worldList[-1]
		width = x2 - x1
		height = y2 - y1
		sx = 1.0 / width
		sy = 1.0 / height
		tx = -x1 / float(width)
		ty = -y1 / float(height)
		mat = kaplot.Matrix(sx, sy, tx, ty)
		return mat
		
	def pushViewport(self, viewport):
		if viewport is None:
			raise Exception, "viewport can't be None"
		self.viewportList.append(viewport)
		
	def popViewport(self):
		self.viewportList.pop()
		
	def getViewport(self):
		return self.viewportList[-1]

	def getViewportMatrix(self):
		p1, p2 = self.viewportList[-1]
		return kaplot.Matrix.scalebox_inverse(p1, p2)
		(x1, y1), (x2, y2) = self.viewportList[-1]
		width = x2 - x1
		height = y2 - y1
		sx = width
		sy = height
		tx = x1
		ty = y1
		return kaplot.Matrix(sx, sy, tx, ty)
		
	def getDeviceMatrix(self):
		return kaplot.Matrix.scale(self.width-1, self.height-1)

	###### TEXT #######

	def drawText__(self, text, position, halign, valign, textangle):
		fontname = self._fontname
		#fontname = "verdana"
		font = kaplot.textmod.findFont(fontname, False, False)
		#fontsizepixels = self._convertUnits(self.fontsize, "px")
		#fontsize = int(fontsizepixels * 96)
		#x, y = self._getTotalMatrix() * position
		#font.set_char_size(0, int(fontsize))
		x, y = position
		#matrix = (	self.getDeviceMatrix() * \
		#			self.getViewportMatrix()\
		#		)
		#x, y = matrix * position
		fontsize = self._fontsize
		#print self._fontsize, self.dpi
		dpi = self.dpi
		#print fontsize, textangle
		try:
			textObject = kaplot.textmod.parseText(text, font, fontsize, fontname, dpi)
		except:
			kaplot.info("failed to parse text: %r" % text)
			raise
		#color = self._findInContextStack("color")
		#color = "red"
		#print "textangle =",textangle
		color = self._color
		textObject.draw(self.getCInterface(), x, y, textangle, valign, halign, color, self)
		points = textObject.getBBoxTransformed(x, y, textangle, valign, halign)
		#matrix = (	self.getDeviceMatrix() * \
		#			self.getViewportMatrix()\
		#		).inverse()
		#points = [matrix * k for k in points]
		#self.plotBbox(color="black", *points)


	def drawGlyph(self, char, textState, font, ftmatrix, drawCallable):
		key = (char, textState.fontSizePt, font)
		a, b, c, d, tx, ty = ftmatrix
		
		#print "drawGlyph", ftmatrix

		# it's assumed that cached glyphs have unrotated dx, dy's
		rotated = True

		if not key in self._glyphCache:
			# we first create a unrotated, untranslated glyph, so it's
			# easier to reuse
			glyphName = "gl%i" % self._glyphNr
			self._glyphNr += 1

			dx, dy, cached, = self.outputGlyph(glyphName, textState, font, ftmatrix, drawCallable)
			if cached:
				self._glyphCache[key] = (glyphName, dx, dy)
				rotated = False
		else:
			glyphName, dx, dy = self._glyphCache[key]
			rotated = False

		scale16 = 1.0/(1<<16)
		scale6 = 1.0/(1<<6)

		# draw this glyph
		self.currentChar = char
		self.drawCachedGlyph(glyphName, textState, font, ftmatrix)

		# these cached values were unrotated, so rotate it
		if not rotated:
			#print "matrix"
			matrix = kaplot.matrix.Matrix(a*scale16, d*scale16)
			matrix.xx = a*scale16
			matrix.xy = b*scale16
			matrix.yx = c*scale16
			matrix.yy = d*scale16
			#matrix.tx = tx*scale6
			#matrix.ty = tx*scale6
			#print a*scale16,b*scale16,c*scale16,d*scale16,tx*scale6,ty*scale6
			#print matrix
			#print dx, dy
			dx, dy = matrix * (dx, dy)
			#print dx, dy
		return int(dx), int(dy)

	def getTextBbox(self, text, x, y, halign, valign, textangle=0):
		fontname = self._fontname
		font = kaplot.textmod.findFont(fontname, False, False)
		#fontsizepixels = self._convertUnits(self.fontsize, "px")
		#fontsize = int(fontsizepixels * 96)
		#font.set_char_size(0, int(fontsize))
		#worldmatrix = self.getWorldMatrix()
		#print worldmatrix
		worldmatrix = self.getWorldMatrix()
		matrix = (	self.getDeviceMatrix() * \
					self.getViewportMatrix() *\
					worldmatrix
				)
		x, y = matrix * (x, y)
		#x, y = position
		try:
			textObject = kaplot.textmod.parseText(text, font, self._fontsize, fontname, self.dpi)
		except:
			kaplot.info("failed to parse text: %r" % text)
			raise
		#x, y = 0, 0
		points = textObject.getBBoxTransformed(x, y, textangle, valign, halign)
		matrix = (	self.getDeviceMatrix() * \
					self.getViewportMatrix() *\
					worldmatrix
				).inverse()
		vppoints = [matrix * k for k in points]
		#if self.debug:
		#self.plotBbox(*vppoints)
		#print points
		#import pdb
		#pdb.set_trace()
		return vppoints

	def drawLines(self, x1, y1, x2, y2, gridsnap=False):
		for x1_, y1_, x2_, y2_ in zip(x1, y1, x2, y2):
			self.drawLine(x1_, y1_, x2_, y2_, gridsnap=gridsnap)

	########### SYMBOL ################
	
	def drawSymbol(self, x, y, symbolName, xscales=None, yscales=None, angles=None, colors=None, colormap=None):
		if ":" in symbolName:
			_group, name = symbolName.split(":", 1)
			# TODO, entity -> unicode
			character = unicode(name)
			if len(character) != 1:
				raise ValueError, "a character symbol can only be of length 1"
			self._drawCharacterSymbol(x, y, character)
		else:
			if symbolName in kaplot.markers.symbols:
				self._drawSymbol(x, y, symbolName, xscales, yscales, angles, colors, colormap)
			else:
				raise ValueError, "unknown symbol: %r, choose between %r" % (symbolName, kaplot.markers.symbols.keys())

	def _drawSymbol(self, x, y, symbolName, xscales, yscales, angles):
		kaplot.info("plotting symbols not implemented")

	def getWindow(self):
		return None
		
	def isGuiDevice(self):
		return self.getWindow() is not None
		
	def checkWindow(self):
		pass
# -*- coding: utf-8 -*-
import kaplot
import kaplot.objects
import kaplot.utils
import kaplot.text

class DeviceBase(object):
	def __init__(self):
		self.contextList = [kaplot.defaultContext.clone()]
		self.worldList = [((0, 0), (0.100, 0.100))]
		#self.worldList = [((0, 0), (3, 3))]
		#self.worldList = [((10, 10), (0, 0))]
		self.viewportList = [((0.2, 0.1), (0.7, 0.9))]
		#self.viewportList = [((0.0, 0.0), (1.0, 1.0))]

		self._glyphCache = {}
		self._glyphNr = 1
		self._clipping = True
		self._color = kaplot.utils.getColor("red")
		#self._fontsize = "10mm"
		self._fontname = "Verdana"
		#self._symbolsize = "5mm"
		
		#self.dpi = 72
		self._alpha = 1
		
	def preDraw(self, document):
		pass

	def postDraw(self, document):
		pass

	def preDrawPage(self, document, page):
		self.setClipRegion()
		self.dpi = document.dpi
		self.pushContext(self.contextList[0])
	
	def postDrawPage(self, document, page):
		#print len(self.contextList)
		#print len(self.worldList)
		#print len(self.viewportList)
		pass

	###########  CONTEXT  #######################		
	def setColor(self, color):
		self._color = kaplot.utils.decodeColor(kaplot.utils.getColor(color))
		self._setColor()
		
	def getColor(self):
		return self._color
		
	def _setColor(self):
		kaplot.info("color not implementen on device", printonce=True)
		
	def setAlpha(self, alpha):
		self._alpha = alpha
		self._setAlpha()
		
	def getAlpha(self):
		return self._alpha
		
	def _setAlpha(self):
		kaplot.info("alpha not implementen on device", printonce=True)
		
	def setLinewidth(self, linewidth):
		self._linewidth = linewidth
		self._setLinewidth()

	def getLinewidth(self):
		return self._linewidth
		
	def _setLinewidth(self):
		kaplot.info("linewidth not implementen on device", printonce=True)
		
	def setLinestyle(self, linestyle):
		self._linestyle = kaplot.utils.getLinestyle(linestyle)
		self._setLinestyle()

	def getLinestyle(self):
		return self._linestyle
		
	def _setLinestyle(self):
		kaplot.info("linestyle not implementen on device", printonce=True)
		
	def setPatternSize(self, patternsize):
		self._patternsize = patternsize
		self._setPatternSize()

	def getPatternSize(self):
		return self._fillstyle
		
	def _setPatternSize(self):
		kaplot.info("patternsize not implementen on device", printonce=True)
		
	def setSymbolSize(self, symbolsize):
		self._symbolsize = symbolsize
		self._setSymbolSize()

	def getSymbolSize(self):
		return self._symbolsize
		
	def _setSymbolSize(self):
		kaplot.info("symbolsize not implementen on device", printonce=True)
		
	def setFillstyle(self, fillstyle):
		self._fillstyle = fillstyle
		self._setFillstyle()

	def getFillstyle(self):
		return self._fillstyle
		
	def _setFillstyle(self):
		kaplot.info("fillstyle not implementen on device", printonce=True)
		
	def setFontname(self, fontname):
		self._fontname = fontname
		self._setFontname()

	def getFontname(self):
		return self._fontname
		
	def _setFontname(self):
		kaplot.info("fontname not implementen on device", printonce=True)
		
	def setFontsize(self, fontsize):
		self._fontsize = fontsize
		self._setFontsize()

	def getFontsize(self):
		return self._fontsize
		
	def _setFontsize(self):
		kaplot.info("fontsize not implementen on device", printonce=True)
		
	def setClipping(self, clipping):
		self._clipping = clipping
		self._setClipping(clipping)
		
	def getClipping(self):
		return self._clipping
		
	def _setClipping(self, clipping):
		kaplot.info("clipping not implementen on device", printonce=True)
		
	def restoreColor(self):
		self.setColor(self._findInContextStack("color"))
		
	def restoreAlpha(self):
		self.setAlpha(self._findInContextStack("alpha"))
		
	def restoreLinewidth(self):
		self.setLinewidth(self._findInContextStack("linewidth"))
		
	def restoreLinestyle(self):
		self.setLinestyle(self._findInContextStack("linestyle"))

	def restorePatternSize(self):
		self.setPatternSize(self._findInContextStack("patternsize"))
		
	def restoreSymbolSize(self):
		self.setSymbolSize(self._findInContextStack("symbolsize"))
		
	def restoreFillstyle(self):
		self.setFillstyle(self._findInContextStack("fillstyle"))
		
	def restoreFontname(self):
		self.setFontname(self._findInContextStack("fontname"))
		
	def restoreFontsize(self):
		self.setFontsize(self._findInContextStack("fontsize"))
		
	def _findInContextStack(self, name):
		for context in self.contextList[::-1]:
			if hasattr(context, name):
				return getattr(context, name)
		raise Exception, "attribute '%s' not found in context stack" % name

	def pushContext(self, context):
		context = kaplot.Context(context)
		self.contextList.append(context)
		if "color" in context:
			self.setColor(context.color)
		if "alpha" in context:
			self.setAlpha(context.alpha)
		if "linewidth" in context:
			self.setLinewidth(context.linewidth)
		if "linestyle" in context:
			self.setLinestyle(context.linestyle)
		if "patternsize" in context:
			self.setPatternSize(context.patternsize)
		if "symbolsize" in context:
			self.setSymbolSize(context.symbolsize)
		if "fillstyle" in context:
			self.setFillstyle(context.fillstyle)
		if "fontname" in context:
			self.setFontname(context.fontname)
		if "fontsize" in context:
			self.setFontsize(context.fontsize)
		
	def popContext(self):
		context = self.contextList.pop()
		if "color" in context:
			self.restoreColor()
		if "alpha" in context:
			self.restoreAlpha()
		if "linewidth" in context:
			self.restoreLinewidth()
		if "linestyle" in context:
			self.restoreLinestyle()
		if "patternsize" in context:
			self.restorePatternSize()
		if "symbolsize" in context:
			self.restoreSymbolSize()
		if "fillstyle" in context:
			self.restoreFillstyle()
		if "fontname" in context:
			self.restoreFontname()
		if "fontsize" in context:
			self.restoreFontsize()
		#if hasattr(context, "viewport"):
		#	self.popViewport()
			
	############## COORDINATES ########################
	def pushWorld(self, world):
		self.worldList.append(world)
		
	def popWorld(self):
		self.worldList.pop()
		
	def getWorld(self):
		#(x1, y1), (x2, y2) = self.worldList[-1]
		#return (float(x1), float(y1)), (float(x2), float(y2))
		return self.worldList[-1]
		
	def getWorldMatrix(self):
		p1, p2 = self.worldList[-1]
		#return kaplot.Matrix.scalebox(p1, p2) 
		(x1, y1), (x2, y2) = self.worldList[-1]
		width = x2 - x1
		height = y2 - y1
		sx = 1.0 / width
		sy = 1.0 / height
		tx = -x1 / float(width)
		ty = -y1 / float(height)
		mat = kaplot.Matrix(sx, sy, tx, ty)
		return mat
		
	def pushViewport(self, viewport):
		if viewport is None:
			raise Exception, "viewport can't be None"
		self.viewportList.append(viewport)
		
	def popViewport(self):
		self.viewportList.pop()
		
	def getViewport(self):
		return self.viewportList[-1]

	def getViewportMatrix(self):
		p1, p2 = self.viewportList[-1]
		return kaplot.Matrix.scalebox_inverse(p1, p2)
		(x1, y1), (x2, y2) = self.viewportList[-1]
		width = x2 - x1
		height = y2 - y1
		sx = width
		sy = height
		tx = x1
		ty = y1
		return kaplot.Matrix(sx, sy, tx, ty)
		
	def getDeviceMatrix(self):
		return kaplot.Matrix.scale(self.width-1, self.height-1)

	###### TEXT #######

	def drawText__(self, text, position, halign, valign, textangle):
		fontname = self._fontname
		#fontname = "verdana"
		font = kaplot.textmod.findFont(fontname, False, False)
		#fontsizepixels = self._convertUnits(self.fontsize, "px")
		#fontsize = int(fontsizepixels * 96)
		#x, y = self._getTotalMatrix() * position
		#font.set_char_size(0, int(fontsize))
		x, y = position
		#matrix = (	self.getDeviceMatrix() * \
		#			self.getViewportMatrix()\
		#		)
		#x, y = matrix * position
		fontsize = self._fontsize
		#print self._fontsize, self.dpi
		dpi = self.dpi
		#print fontsize, textangle
		try:
			textObject = kaplot.textmod.parseText(text, font, fontsize, fontname, dpi)
		except:
			kaplot.info("failed to parse text: %r" % text)
			raise
		#color = self._findInContextStack("color")
		#color = "red"
		#print "textangle =",textangle
		color = self._color
		textObject.draw(self.getCInterface(), x, y, textangle, valign, halign, color, self)
		points = textObject.getBBoxTransformed(x, y, textangle, valign, halign)
		#matrix = (	self.getDeviceMatrix() * \
		#			self.getViewportMatrix()\
		#		).inverse()
		#points = [matrix * k for k in points]
		#self.plotBbox(color="black", *points)


	def drawGlyph(self, char, textState, font, ftmatrix, drawCallable):
		key = (char, textState.fontSizePt, font)
		a, b, c, d, tx, ty = ftmatrix
		
		#print "drawGlyph", ftmatrix

		# it's assumed that cached glyphs have unrotated dx, dy's
		rotated = True

		if not key in self._glyphCache:
			# we first create a unrotated, untranslated glyph, so it's
			# easier to reuse
			glyphName = "gl%i" % self._glyphNr
			self._glyphNr += 1

			dx, dy, cached, = self.outputGlyph(glyphName, textState, font, ftmatrix, drawCallable)
			if cached:
				self._glyphCache[key] = (glyphName, dx, dy)
				rotated = False
		else:
			glyphName, dx, dy = self._glyphCache[key]
			rotated = False

		scale16 = 1.0/(1<<16)
		scale6 = 1.0/(1<<6)

		# draw this glyph
		self.currentChar = char
		self.drawCachedGlyph(glyphName, textState, font, ftmatrix)

		# these cached values were unrotated, so rotate it
		if not rotated:
			#print "matrix"
			matrix = kaplot.matrix.Matrix(a*scale16, d*scale16)
			matrix.xx = a*scale16
			matrix.xy = b*scale16
			matrix.yx = c*scale16
			matrix.yy = d*scale16
			#matrix.tx = tx*scale6
			#matrix.ty = tx*scale6
			#print a*scale16,b*scale16,c*scale16,d*scale16,tx*scale6,ty*scale6
			#print matrix
			#print dx, dy
			dx, dy = matrix * (dx, dy)
			#print dx, dy
		return int(dx), int(dy)

	def getTextBbox(self, text, x, y, halign, valign, textangle=0):
		fontname = self._fontname
		font = kaplot.textmod.findFont(fontname, False, False)
		#fontsizepixels = self._convertUnits(self.fontsize, "px")
		#fontsize = int(fontsizepixels * 96)
		#font.set_char_size(0, int(fontsize))
		#worldmatrix = self.getWorldMatrix()
		#print worldmatrix
		worldmatrix = self.getWorldMatrix()
		matrix = (	self.getDeviceMatrix() * \
					self.getViewportMatrix() *\
					worldmatrix
				)
		x, y = matrix * (x, y)
		#x, y = position
		try:
			textObject = kaplot.textmod.parseText(text, font, self._fontsize, fontname, self.dpi)
		except:
			kaplot.info("failed to parse text: %r" % text)
			raise
		#x, y = 0, 0
		points = textObject.getBBoxTransformed(x, y, textangle, valign, halign)
		matrix = (	self.getDeviceMatrix() * \
					self.getViewportMatrix() *\
					worldmatrix
				).inverse()
		vppoints = [matrix * k for k in points]
		#if self.debug:
		#self.plotBbox(*vppoints)
		#print points
		#import pdb
		#pdb.set_trace()
		return vppoints

	def drawLines(self, x1, y1, x2, y2, gridsnap=False):
		for x1_, y1_, x2_, y2_ in zip(x1, y1, x2, y2):
			self.drawLine(x1_, y1_, x2_, y2_, gridsnap=gridsnap)

	########### SYMBOL ################
	
	def drawSymbol(self, x, y, symbolName, xscales=None, yscales=None, angles=None, colors=None, colormap=None):
		if ":" in symbolName:
			_group, name = symbolName.split(":", 1)
			# TODO, entity -> unicode
			character = unicode(name)
			if len(character) != 1:
				raise ValueError, "a character symbol can only be of length 1"
			self._drawCharacterSymbol(x, y, character)
		else:
			if symbolName in kaplot.markers.symbols:
				self._drawSymbol(x, y, symbolName, xscales, yscales, angles, colors, colormap)
			else:
				raise ValueError, "unknown symbol: %r, choose between %r" % (symbolName, kaplot.markers.symbols.keys())

	def _drawSymbol(self, x, y, symbolName, xscales, yscales, angles):
		kaplot.info("plotting symbols not implemented")

	def getWindow(self):
		return None
		
	def isGuiDevice(self):
		return self.getWindow() is not None
		
	def checkWindow(self):
		pass
# -*- coding: utf-8 -*- #self.worldList = [((0, 0), (3, 3))] #self.worldList = [((10, 10), (0, 0))] #self.viewportList = [((0.0, 0.0), (1.0, 1.0))] #self._fontsize = "10mm" #self._symbolsize = "5mm" #self.dpi = 72 #print len(self.contextList) #print len(self.worldList) #print len(self.viewportList) ###########  CONTEXT  ####################### #if hasattr(context, "viewport"): #	self.popViewport() ############## COORDINATES ######################## #(x1, y1), (x2, y2) = self.worldList[-1] #return (float(x1), float(y1)), (float(x2), float(y2)) #return kaplot.Matrix.scalebox(p1, p2) ###### TEXT ####### #fontname = "verdana" #fontsizepixels = self._convertUnits(self.fontsize, "px") #fontsize = int(fontsizepixels * 96) #x, y = self._getTotalMatrix() * position #font.set_char_size(0, int(fontsize)) #matrix = (	self.getDeviceMatrix() * \ #			self.getViewportMatrix()\ #		) #x, y = matrix * position #print self._fontsize, self.dpi #print fontsize, textangle #color = self._findInContextStack("color") #color = "red" #print "textangle =",textangle #matrix = (	self.getDeviceMatrix() * \ #			self.getViewportMatrix()\ #		).inverse() #points = [matrix * k for k in points] #self.plotBbox(color="black", *points) #print "drawGlyph", ftmatrix # it's assumed that cached glyphs have unrotated dx, dy's # we first create a unrotated, untranslated glyph, so it's # easier to reuse # draw this glyph # these cached values were unrotated, so rotate it #print "matrix" #matrix.tx = tx*scale6 #matrix.ty = tx*scale6 #print a*scale16,b*scale16,c*scale16,d*scale16,tx*scale6,ty*scale6 #print matrix #print dx, dy #print dx, dy #fontsizepixels = self._convertUnits(self.fontsize, "px") #fontsize = int(fontsizepixels * 96) #font.set_char_size(0, int(fontsize)) #worldmatrix = self.getWorldMatrix() #print worldmatrix #x, y = position #x, y = 0, 0 #if self.debug: #self.plotBbox(*vppoints) #print points #import pdb #pdb.set_trace() ########### SYMBOL ################ # TODO, entity -> unicode