Files
rdkit/Python/sping/tests/pidtest.py
Greg Landrum 75a79b6327 initial import
2006-05-06 22:20:08 +00:00

408 lines
14 KiB
Python
Executable File

"""piddletest.py
This module puts the various PIDDLE backends through their paces.
"""
from sping import pagesizes
from sping.pid import *
import string
import math
backends = ['PDF','PIL','TK',
'PS','SVG', 'WX' ] # 'piddleAI','piddleQD','piddleGL' ]
backends.sort()
#----------------------------------------------------------------------
# note, these tests do not flush() the canvas
#----------------------------------------------------------------------
def minimal(canvasClass):
"""Just a very basic test of line drawing and canvas size."""
canvas = canvasClass(pagesizes.A6, "test-minimal") # A6 is a quarter page
drawMinimal(canvas)
return canvas
def drawMinimal(canvas):
saver = StateSaver(canvas) # leave canvas state as you found it, restores state when leaves scope
size = canvas.size # (actual size *may* differ from requested size)
canvas.defaultLineColor = green
canvas.drawLine(1,1,size[0]-1,size[1]-1)
canvas.drawLine(1,size[1]-1,size[0]-1,1)
canvas.drawRect(1,1,size[0]-1,size[1]-1, edgeWidth=5)
return canvas
#----------------------------------------------------------------------
def basics(canvasClass):
"""A general test of most of the drawing primitives except images and strings."""
canvas = canvasClass((300,300), "test-basics")
return drawBasics(canvas)
def drawBasics(canvas):
saver = StateSaver(canvas) # leave canvas state as you found it, restores state when leaves scope
canvas.defaultLineColor = Color(0.7,0.7,1.0) # light blue
canvas.drawLines( map(lambda i:(i*10,0,i*10,300), range(30)) )
canvas.drawLines( map(lambda i:(0,i*10,300,i*10), range(30)) )
canvas.defaultLineColor = black
canvas.drawLine(10,200, 20,190, color=red)
canvas.drawEllipse( 130,30, 200,100, fillColor=yellow, edgeWidth=4 )
canvas.drawArc( 130,30, 200,100, 45,50, fillColor=blue, edgeColor=navy, edgeWidth=4 )
canvas.defaultLineWidth = 4
canvas.drawRoundRect( 30,30, 100,100, fillColor=blue, edgeColor=maroon )
canvas.drawCurve( 20,20, 100,50, 50,100, 160,160 )
#canvas.drawString("This is a test!", 30,130, Font(face="times",size=16,bold=1),
# color=green, angle=-45)
polypoints = [ (160,120), (130,190), (210,145), (110,145), (190,190) ]
canvas.drawPolygon(polypoints, fillColor=lime, edgeColor=red, edgeWidth=3, closed=1)
canvas.drawRect( 200,200,260,260, edgeColor=yellow, edgeWidth=5 )
canvas.drawLine( 200,260,260,260, color=green, width=5 )
canvas.drawLine( 260,200,260,260, color=red, width=5 )
return canvas
#----------------------------------------------------------------------
def advanced(canvasClass):
"""A test of figures and images."""
canvas = canvasClass((300,300), "test-advanced")
return drawAdvanced(canvas)
def drawAdvanced(canvas):
saver = StateSaver(canvas) # leave canvas state as you found it, restores state when leaves scope
figure = [
( figureCurve, 20,20, 100,50, 50,100, 160,160 ),
( figureLine, 200,200, 250,150 ),
( figureArc, 50,10, 250,150, 10,90 ) ]
canvas.drawFigure(figure, fillColor=yellow, edgeWidth=4)
try:
from PIL import Image
except:
canvas.drawString("PIL not available!", 20,200)
Image = None
if Image:
img = Image.open("python.gif")
canvas.drawImage( img, 120,50,120+32,50+64 );
canvas.drawImage( img, 0,210,300,210+32 );
return canvas
#----------------------------------------------------------------------
def bluefunc(x): return 1.0 / (1.0 + math.exp(-10*(x-0.6)))
def redfunc(x): return 1.0 / (1.0 + math.exp(10*(x-0.5)))
def greenfunc(x): return 1 - pow(redfunc(x+0.2),2) - bluefunc(x-0.3)
def spectrum(canvasClass):
canvas = canvasClass((300,300), "test-spectrum")
return drawSpectrum(canvas)
def drawSpectrum(canvas):
"""Generates a spectrum plot; illustrates colors and useful application."""
saver = StateSaver(canvas) # leave canvas state as you found it, restores state when leaves scope
def plot(f,canvas,offset=0):
for i in range(0,100):
x = float(i)/100
canvas.drawLine(i*3+offset,250, i*3+offset,250-100*f(x))
def genColors(n=100):
out = [None]*n;
for i in range(n):
x = float(i)/n
out[i] = Color(redfunc(x), greenfunc(x), bluefunc(x));
return out
colors = genColors(300)
# draw a black background for the spectrum
canvas.drawRect( 0,0,300,100, edgeColor=black, fillColor=black )
# draw the spectrum
for i in range(len(colors)):
canvas.drawLine(i,20,i,80, colors[i])
# plot the components of the spectrum
canvas.defaultLineColor = red
plot(redfunc, canvas)
canvas.defaultLineColor = blue
plot(bluefunc, canvas, 1)
canvas.defaultLineColor = green
plot(greenfunc, canvas, 2)
return canvas
#----------------------------------------------------------------------
def strings(canvasClass):
canvas = canvasClass( size=(400,400), name="test-strings" )
return drawStrings(canvas)
def drawStrings(canvas):
"""Checks font metrics, and also illustrates the standard fonts."""
saver = StateSaver(canvas) # leave canvas state as you found it, restores state when leaves scope
def Write(canvas, s, font, curs):
if font: canvas.defaultFont = font
text = s
while text and text[-1] == '\n': text = text[:-1]
canvas.drawString(text, x=curs[0], y=curs[1])
if s[-1] == '\n':
curs[0] = 10
curs[1] = curs[1] + canvas.fontHeight() + canvas.fontDescent()
else:
curs[0] = curs[0] + canvas.stringWidth(s)
def StandardFonts(canvas, Write):
canvas.defaultLineColor = black
curs = [10,70]
for size in (12, 18):
for fontname in ("times", "courier", "helvetica", "symbol",
"monospaced", "serif", "sansserif"):
curs[0] = 10
curs[1] = curs[1] + size*1.5
Write(canvas, "%s %d " % (fontname,size), Font(face=fontname, size=size), curs)
Write(canvas, "bold ", Font(face=fontname, size=size, bold=1), curs)
Write(canvas, "italic ", Font(face=fontname, size=size, italic=1), curs)
Write(canvas, "underline", Font(face=fontname, size=size, underline=1), curs)
CenterAndBox(canvas, "spam, spam, spam, baked beans, and spam!")
StandardFonts(canvas, Write)
return canvas
def CenterAndBox(canvas, s, cx=200, y=40):
"tests string positioning, stringWidth, fontAscent, and fontDescent"
canvas.drawLine(cx,y-30, cx,y+30, color=yellow)
w = canvas
w = canvas.stringWidth(s)
canvas.drawLine(cx-w/2, y, cx+w/2, y, color=red)
canvas.drawString(s, cx-w/2, y )
canvas.defaultLineColor = Color(0.7,0.7,1.0) # light blue
canvas.drawLine(cx-w/2, y-20, cx-w/2, y+20) # left
canvas.drawLine(cx+w/2, y-20, cx+w/2, y+20) # right
asc, desc = canvas.fontAscent(), canvas.fontDescent()
canvas.drawLine(cx-w/2-20, y-asc, cx+w/2+20, y-asc) # top
canvas.drawLine(cx-w/2-20, y+desc, cx+w/2+20, y+desc) # bottom
#----------------------------------------------------------------------
def rotstring(canvasClass):
canvas = canvasClass( (450,300), name='test-rotstring' )
return drawRotstring(canvas)
def drawRotstring(canvas):
"""Draws rotated strings."""
saver = StateSaver(canvas) # leave canvas state as you found it, restores state when leaves scope
canvas.defaultFont = Font(bold=1)
canvas.defaultLineColor = (blue + white)/2
canvas.drawLine(0,150, 300,150)
canvas.drawLine(150,0, 150,300)
s = " __albatros at "
w = canvas.stringWidth(s)
canvas.drawEllipse(150-w,150-w, 150+w, 150+w, fillColor=transparent)
colors = [red,orange,yellow,green,blue,purple]
cnum = 0
for ang in range(0, 359, 30):
canvas.defaultLineColor = colors[cnum]
s2 = s + str(ang)
canvas.drawString(s2, 150, 150, angle=ang)
cnum = (cnum+1) % len(colors)
canvas.drawString( "This is a\nrotated\nmulti-line string!!!", 350, 100, angle= -90, font=Font(underline=1) )
#canvas.drawString( "This is a\nrotated\nmulti-line string!!!", 400, 175, angle= -45, font=Font(underline=1) )
return canvas
#----------------------------------------------------------------------
#----------------------------------------------------------------------
def tkTest(testfunc):
# TK tests are called from here because need TK's event loop
try :
import sping.TK
import Tkinter
except:
print "A module needed for sping.TK is not available, select another backend"
return
root = Tkinter.Tk()
frame = Tkinter.Frame(root) # label='piddletestTK'
# try new Tk canvas
tkcanvas = sping.TK.TKCanvas(size=(400,400), name='sping-testTK', master = frame)
bframe = Tkinter.Frame(root)
minimalB=Tkinter.Button(bframe, text='minimal test',
command= lambda c=tkcanvas : (c.clear(),drawMinimal(c), c.flush())).pack(side=Tkinter.LEFT)
basicB = Tkinter.Button(bframe, text='basic test',
command= lambda c=tkcanvas: (c.clear(),drawBasics(c),c.flush()) ).pack(side=Tkinter.LEFT)
spectB =Tkinter.Button(bframe, text='spectrum test',
command= lambda c=tkcanvas: (c.clear(),drawSpectrum(c),c.flush()) ).pack(side=Tkinter.LEFT)
stringsB = Tkinter.Button(bframe, text='strings test',
command= lambda c=tkcanvas:(c.clear(),drawStrings(c),c.flush()) ).pack(side=Tkinter.LEFT)
rotstrB = Tkinter.Button(bframe, text='rotated strings test',
command= lambda c=tkcanvas:(c.clear(), drawRotstring(c),c.flush()) ).pack(side=Tkinter.LEFT)
advancedB = Tkinter.Button(bframe, text='advanced test',
command= lambda c=tkcanvas:(c.clear(), drawAdvanced(c),c.flush() ) ).pack(side=Tkinter.LEFT)
bframe.pack(side=Tkinter.TOP)
tkcanvas.pack()
frame.pack()
# try to draw before running mainloop
if testfunc== minimal:
drawMinimal(tkcanvas)
elif testfunc == basics:
drawBasics(tkcanvas)
elif testfunc == advanced :
drawAdvanced(tkcanvas)
elif testfunc == spectrum :
drawSpectrum(tkcanvas)
elif testfunc == strings :
drawStrings(tkcanvas)
elif testfunc == rotstring :
drawRotstring(tkcanvas)
else :
print "Illegal testfunc handed to tkTest"
raise ValueError,"Unsupported testfunc"
tkcanvas.flush()
root.mainloop()
#----------------------------------------------------------------------
def wxTest(testfunc):
try :
import sping.WX
from wxPython.wx import wxApp
except:
print "A module needed for sping.WX is not available, select another backend"
return
global wx_app
if not globals().has_key("wx_app"):
class CanvasApp(wxApp):
"The wxApp that runs canvas. Initializes windows, and handles redrawing"
def OnInit(self):
return 1
wx_app = CanvasApp(0)
# run the test, passing the canvas class and returning the canvas
canvas = testfunc(sping.WX.WXCanvas)
canvas.flush()
# Run the main loop
wx_app.MainLoop()
def runtest(backend, testfunc):
# special cases:
if backend=='TK':
tkTest(testfunc) # takes care of import, etc.
return
if backend=='WX':
wxTest(testfunc) # takes care of import, etc.
return
# import the relevant module
modname = 'sping.' + backend
print "importing ", modname
module = __import__('sping.'+backend, globals(), locals(), [backend])
# figure out the canvas class name (e.g., "PILCanvas") and get that
#canvasClass = getattr(module, backend[6:]+"Canvas")
#canvasClass = getattr(module, backend+"Canvas")
# from spam.ham import eggs
# __import('spam.ham', 'globals(), local
canvasClass = getattr(module, backend+"Canvas")
# run the test, passing the canvas class and returning the canvas
canvas = testfunc(canvasClass)
# do post-test cleanup
canvas.flush()
# handle save's here
if backend == 'PIL':
# I'm saving twice because sometimes jpeg doesn't work when png does
canvas.save(file=canvas.name+".jpg") # save as a jpeg file
canvas.save(format='png') # save as a png file
elif backend == 'piddleVCR':
filename = canvas.name + ".vcr"
canvas.save(filename)
print filename, "saved"
else: # if backend == 'PS' or backend== 'PDF':
canvas.save() # should be "pass'ed" by Canvas's that don't use save
def mainLoop():
global tests, backends
backend = None
test = None
while 1:
# print backends on left, tests on right, indicate chosen one of each
i = 0
while i < len(backends) or i < len(tests):
try: bstr = str(i+1) + '. ' + backends[i]
except: bstr = ''
try: tstr = chr(65+i) + '. ' + tests[i].__name__
except: tstr = ''
if i == backend: bflag = '==>'
else: bflag = ''
if i == test: tflag = '==>'
else: tflag = ''
print "%10s %-20s %10s %-20s" % (bflag, bstr, tflag, tstr)
i = i+1
print
inp = raw_input("Selection (0 to exit): ")
print
if inp == '0': return
if inp:
testinp = ''
if inp[-1] in string.letters: testinp = inp[-1]
elif inp[0] in string.letters: testinp = inp[0]
backinp = string.join(filter(lambda x:x in '0123456789',inp))
if backinp:
backend = int(backinp)-1
if backend < len(backends):
docstr = __import__('sping.'+backends[backend], globals(), locals(), backends[backend]).__doc__
#docstr = __import__('sping.'+backends[backend]).__doc__
if docstr: print docstr
else: print "<no doc string>"
else: backend = None
if testinp:
test = ord(string.upper(testinp[0])) - ord('A')
if test >= 0 and test < len(tests):
docstr = tests[test].__doc__
if docstr:
print docstr
else: test = None
print
# now, if we have a valid backend and test, run it
if backend != None and test != None:
runtest(backends[backend], tests[test])
tests = (minimal, basics, advanced, spectrum, strings, rotstring)
if __name__=='__main__':
mainLoop()