From 8b6bfa5298d29b24ec47d5fb46bad21d13b83e07 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sun, 3 Nov 2024 14:22:39 +0000 Subject: [PATCH] Update editor to read Type 2 charstrings (in source form) Now the editor displays something useful again. --- editor | 56 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/editor b/editor index d45bb61..d2d1b38 100755 --- a/editor +++ b/editor @@ -2,10 +2,11 @@ # Interactive glyph editor for Bedstead. # -# This program was written by Simon Tatham in 2013. +# This program was written by Simon Tatham in 2013 and updated by Ben +# Harris in 2024. # -# Simon Tatham makes this program available under the CC0 Public -# Domain Dedication. +# Simon Tatham and Ben Harris make this program available under the +# CC0 Public Domain Dedication. '''Interactive glyph editor for Bedstead. @@ -91,19 +92,39 @@ class EditorGui: self.polygons = [] data = subprocess.check_output( - [self.bedstead] + list(map(str, self.bitmap))) - paths = [] - path = None - for line in data.splitlines(): - words = line.split() - if len(words) >= 3 and words[2] in [b"m",b"l"]: - x = int((float(words[0])-LEFT)*pixel*0.01 + 2*gutter + - XSIZE*pixel) - y = int((TOP - float(words[1]))*pixel*0.01 + gutter) - if words[2] == b"m": - path = [] - paths.append(path) - path.append([x,y]) + [self.bedstead] + list(map(str, self.bitmap)), + universal_newlines=True) + class CharstringInterpreter: + def __init__(self): + self.paths = [] + self.path = None + self.stack = [] + self.cursor = [0, 0] + def rmoveto(self): + self.path = [] + self.paths.append(self.path) + self.rlineto() + def rlineto(self): + while len(self.stack) >= 2: + self.cursor[0] += self.stack[0] + self.cursor[1] += self.stack[1] + self.stack = self.stack[2:] + self.path.append(self.cursor[:]) + def op(self, word): + try: + self.stack.append(float(word)) + except: + if word == "rmoveto": self.rmoveto() + elif word == "rlineto": self.rlineto() + elif word == "endchar": pass + else: + print("unknown charstring component " + repr(word)) + interp = CharstringInterpreter() + for word in data.split(): + interp.op(word) + paths = [[[int((float(x)-LEFT)*pixel*0.01 + 2*gutter + XSIZE*pixel), + int((TOP - float(y))*pixel*0.01 + gutter)] + for x, y in path] for path in interp.paths] # The output from 'bedstead' will be a set of disjoint paths, # in the Postscript style (going one way around the outside of @@ -150,8 +171,7 @@ class EditorGui: pathswithmetadata.sort(reverse=True) for _, colour, path in pathswithmetadata: - if len(path) > 1 and path[0] == path[-1]: - del path[-1] + if len(path) > 1: args = sum(path, []) # x,y,x,y,...,x.y pg = self.canvas.create_polygon(*args, fill=colour) self.polygons.append(pg) -- 2.30.2