X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=spec%2Fedit_spec.py;h=670e1bf19403fd173c5c89b97c9158f5845222ed;hb=9188f342f67f399dbb7857dd1970ab44a8c24138;hp=2ede7542ea72e3951c69ffb2e06e51af07fab948;hpb=95903addc2703a928de38e99b4274a5d3da44aa2;p=swftools.git diff --git a/spec/edit_spec.py b/spec/edit_spec.py old mode 100644 new mode 100755 index 2ede754..670e1bf --- a/spec/edit_spec.py +++ b/spec/edit_spec.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python import wx import wx.lib.scrolledpanel as scrolled import os @@ -16,6 +17,8 @@ class Check: return "pixel at (%d,%d)" % (self.x,self.y) def right(self): return "" + def verifies(self, model): + return True class PixelColorCheck(Check): def __init__(self, x,y, color): @@ -23,6 +26,10 @@ class PixelColorCheck(Check): self.color = color def right(self): return "is of color 0x%06x" % self.color + def verifies(self, model): + p = model.getPixel(self.x,self.y) + val = p[0]<<16 | p[1]<<8 | p[2] + return val == self.color class TwoPixelCheck(Check): def __init__(self, x,y, x2,y2): @@ -53,14 +60,89 @@ class AreaPlain(AreaCheck): class AreaNotPlain(AreaCheck): pass +class AreaText(AreaCheck): + def __init__(self, x,y, x2, y2, text=""): + AreaCheck.__init__(self,x,y,x2,y2) + self.text = text + +checktypes = [PixelColorCheck,PixelBrighterThan,PixelDarkerThan,PixelEqualTo,AreaPlain,AreaNotPlain,AreaText] + +global TESTMODE + +def convert_to_ppm(pdf): + print pdf + f = os.popen("pdfinfo "+pdf, "rb") + info = f.read() + f.close() + width,heigth = re.compile(r"Page size:\s*([0-9]+) x ([0-9]+) pts").findall(info)[0] + dpi = int(72.0 * 612 / int(width)) + if TESTMODE: + os.system("pdf2swf -s zoom="+str(dpi)+" -p1 "+pdf+" -o test.swf") + os.system("swfrender --legacy test.swf -o test.png") + os.unlink("test.swf") + return "test.png" + else: + os.system("pdftoppm -r "+str(dpi)+" -f 1 -l 1 "+pdf+" test") + return "test-000001.ppm" + + class Model: - def __init__(self, filename, checks): - self.filename = filename + def __init__(self, specfile, docfile, checks): + self.specfile = specfile + self.docfile = docfile + self.imgfilename = convert_to_ppm(self.docfile) + self.bitmap = wx.Bitmap(self.imgfilename) + self.image = wx.ImageFromBitmap(self.bitmap) + self.width = self.bitmap.GetWidth() + self.height = self.bitmap.GetHeight() self.checks = checks + self.xy2check = {} + self.appendListeners = [] + self.drawModeListeners = [] + self.drawmode = PixelColorCheck + + def close(self): + try: os.unlink(self.imgfilename) + except: pass + + def getPixel(self,x,y): + return (self.image.GetRed(x,y), self.image.GetGreen(x,y), self.image.GetBlue(x,y)) + + def setdrawmode(self, mode): + self.drawmode = mode + for f in self.drawModeListeners: + f() + + def find(self, x, y): + return self.xy2check.get((x,y),None) + + def delete(self, check): + i = self.checks.index(check) + del self.checks[i] + del self.xy2check[(check.x,check.y)] + for f in self.appendListeners: + f(check) + + def append(self, check): + self.checks += [check] + self.xy2check[(check.x,check.y)] = check + for f in self.appendListeners: + f(check) @staticmethod def load(filename): - path = os.path.splitext(filename)[0]+".rb" + # convenience, allow to do "edit_spec.py file.pdf" + p,ext = os.path.splitext(filename) + if ext!=".rb": + path = p+".rb" + if not os.path.isfile(path): + path = p+".spec.rb" + if not os.path.isfile(path): + print "No file %s found, creating new..." % path + return Model(path, filename, []) + else: + path = filename + fi = open(path, "rb") r_file = re.compile(r"^convert_file \"([^\"]*)\"") r_pixelcolor = re.compile(r"^pixel_at\(([0-9]+),([0-9]+)\).should_be_of_color (0x[0-9a-fA-F]+)") @@ -69,6 +151,7 @@ class Model: r_pixelequalto = re.compile(r"^pixel_at\(([0-9]+),([0-9]+)\).should_be_the_same_as pixel_at\(([0-9]+),([0-9]+)\)") r_areaplain = re.compile(r"^area_at\(([0-9]+),([0-9]+),([0-9]+),([0-9]+)\).should_be_plain_colored") r_areanotplain = re.compile(r"^area_at\(([0-9]+),([0-9]+),([0-9]+),([0-9]+)\).should_not_be_plain_colored") + r_areatext = re.compile(r"^area_at\(([0-9]+),([0-9]+),([0-9]+),([0-9]+)\).should_contain_text '(.*)'") r_width = re.compile(r"^width.should be ([0-9]+)") r_height = re.compile(r"^height.should be ([0-9]+)") r_describe = re.compile(r"^describe \"pdf conversion\"") @@ -85,19 +168,22 @@ class Model: if filename: raise Exception("can't load multi-file specs (in line %d)" % (nr+1)) filename = m.group(1); + model = Model(path, filename, []) continue m = r_pixelcolor.match(line) - if m: checks += [PixelColorCheck(int(m.group(1)),int(m.group(2)),int(m.group(3),16))];continue + if m: model.append(PixelColorCheck(int(m.group(1)),int(m.group(2)),int(m.group(3),16)));continue m = r_pixelbrighter.match(line) - if m: checks += [PixelBrighterThan(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4)))];continue + if m: model.append(PixelBrighterThan(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4))));continue m = r_pixeldarker.match(line) - if m: checks += [PixelDarkerThan(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4)))];continue + if m: model.append(PixelDarkerThan(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4))));continue m = r_pixelequalto.match(line) - if m: checks += [PixelEqualTo(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4)))];continue + if m: model.append(PixelEqualTo(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4))));continue m = r_areaplain.match(line) - if m: checks += [AreaPlain(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4)))];continue + if m: model.append(AreaPlain(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4))));continue m = r_areanotplain.match(line) - if m: checks += [AreaNotPlain(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4)))];continue + if m: model.append(AreaNotPlain(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4))));continue + m = r_areatext.match(line) + if m: model.append(AreaText(int(m.group(1)),int(m.group(2)),int(m.group(3)),int(m.group(4)),m.group(5)));continue if r_width.match(line) or r_height.match(line): continue # compatibility if r_describe.match(line) or r_end.match(line) or r_header.match(line): @@ -106,13 +192,13 @@ class Model: raise Exception("invalid file format: can't load this file (in line %d)" % (nr+1)) fi.close() - return Model(filename, checks) + return model def save(self): - path = os.path.splitext(self.filename)[0]+".rb" + path = self.specfile fi = open(path, "wb") fi.write("require File.dirname(__FILE__) + '/spec_helper'\n\ndescribe \"pdf conversion\" do\n") - fi.write(" convert_file \"%s\" do\n" % self.filename) + fi.write(" convert_file \"%s\" do\n" % self.docfile) for check in self.checks: c = check.__class__ if c == PixelColorCheck: @@ -127,101 +213,45 @@ class Model: fi.write(" area_at(%d,%d,%d,%d).should_be_plain_colored\n" % (check.x,check.y,check.x2,check.y2)) elif c == AreaNotPlain: fi.write(" area_at(%d,%d,%d,%d).should_not_be_plain_colored\n" % (check.x,check.y,check.x2,check.y2)) + elif c == AreaText: + fi.write(" area_at(%d,%d,%d,%d).should_contain_text '%s'\n" % (check.x,check.y,check.x2,check.y2,check.text)) fi.write(" end\n") fi.write("end\n") fi.close() - -class ImageFrame(wx.Frame): - def __init__(self, application, model): - wx.Frame.__init__(self, None, -1, style = wx.DEFAULT_FRAME_STYLE, pos=(50,50)) - self.application = application +class ZoomWindow(wx.Window): + def __init__(self, parent, model): + wx.Window.__init__(self, parent, pos=(0,0), size=(15*32,15*32)) self.model = model self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) - self.bitmap = wx.Bitmap(model.filename) - self.width = self.bitmap.GetWidth() - self.height = self.bitmap.GetHeight() - self.bitmap_x = 500 - self.bitmap_y = 32 - self.SetSize((self.width+self.bitmap_x+32, max(self.height+self.bitmap_y, 15*32))) - self.image = wx.ImageFromBitmap(self.bitmap) self.x = 0 self.y = 0 - self.createToolbar() - def createToolbar(self): - tsize = (16,16) - self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT) - self.toolbar.AddSimpleTool(wx.ID_OPEN, - wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize), - "Open") - self.toolbar.AddSimpleTool(wx.ID_SAVE, - wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize), - "Save selected pages") - self.toolbar.AddSimpleTool(wx.ID_PREFERENCES, - wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR, tsize), - "Options") - #self.toolbar.AddSeparator() - self.toolbar.Realize() - - def OnMouseClick(self, event): - x = min(max(event.X - self.bitmap_x, 0), self.width-1) - y = min(max(event.Y - self.bitmap_y, 0), self.height-1) - if y not in self.model.pixels: - self.model.pixels[y] = {} - if y in self.model.pixels and x in self.model.pixels[y]: - del self.model.pixels[y][x] - else: - color = self.image.GetRed(x,y)<<16 | self.image.GetGreen(x,y)<<8 | self.image.GetBlue(x,y) - self.model.pixels[y][x] = color + def setpos(self,x,y): + self.x = x + self.y = y self.Refresh() - - def OnMouse(self, event): - if event.LeftIsDown(): - return self.OnMouseClick(event) - lastx = self.x - lasty = self.y - self.x = min(max(event.X - self.bitmap_x, 0), self.width-1) - self.y = min(max(event.Y - self.bitmap_y, 0), self.height-1) - if lastx!=self.x or lasty!=self.y: - self.Refresh() - + def OnPaint(self, event): dc = wx.PaintDC(self) self.Draw(dc) - + def Draw(self,dc=None): if not dc: dc = wx.ClientDC(self) - dc.SetBackground(wx.Brush((0,0,0))) - dc.DrawBitmap(self.bitmap, self.bitmap_x, self.bitmap_y, False) - - for yy,row in self.model.pixels.items(): - for xx in row.keys(): - x = xx+self.bitmap_x - y = yy+self.bitmap_y - l = 0 - for r in range(10): - r = (r+1)*3.141526/5 - dc.DrawLine(x+10*math.sin(l), y+10*math.cos(l), x+10*math.sin(r), y+10*math.cos(r)) - l = r - dc.DrawLine(x,y,x+1,y) - color = (0,255,0) for yy in range(15): y = self.y+yy-8 - marked = self.model.pixels.get(y, {}) for xx in range(15): x = self.x+xx-8 - if 0<=x