chiark / gitweb /
Update editor to read Type 2 charstrings (in source form)
authorBen Harris <bjh21@bjh21.me.uk>
Sun, 3 Nov 2024 14:22:39 +0000 (14:22 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Thu, 14 Nov 2024 22:27:18 +0000 (22:27 +0000)
Now the editor displays something useful again.

editor

diff --git a/editor b/editor
index d45bb61f0a0a896fe9f334138928b047fa15d903..d2d1b384b25f84d76d78dcde2ac17ba4260693f5 100755 (executable)
--- 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)