mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-07 22:44:25 +08:00
408 lines
14 KiB
Python
Executable File
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()
|