chiark / gitweb /
Bits I had lying around for generating a Mode 7 style outline font.
authorBen Harris <bjh21@cam.ac.uk>
Wed, 30 Sep 2009 09:59:10 +0000 (10:59 +0100)
committerBen Harris <bjh21@cam.ac.uk>
Wed, 30 Sep 2009 09:59:10 +0000 (10:59 +0100)
ttxt.c [new file with mode: 0644]
ttxt.pl [new file with mode: 0644]

diff --git a/ttxt.c b/ttxt.c
new file mode 100644 (file)
index 0000000..eeb83dc
--- /dev/null
+++ b/ttxt.c
@@ -0,0 +1,288 @@
+#include <stdio.h>
+
+#define XSIZE 6
+#define YSIZE 10
+
+struct corner {
+       int tl, tr, bl, br;
+};
+
+inline int
+getpix(char data[YSIZE], int x, int y) {
+
+       if (x < 0 || x >= XSIZE || y < 0 || y >= YSIZE)
+               return 0;
+       else
+               return (data[y] >> (XSIZE - x - 1)) & 1;
+}
+
+void doprologue(void);
+void dochar(char data[YSIZE]);
+
+char data[][YSIZE] = {
+       000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
+       004, 004, 004, 004, 004, 000, 004, 000, 000, 000,
+       012, 012, 012, 000, 000, 000, 000, 000, 000, 000,
+       012, 012, 037, 012, 037, 012, 012, 000, 000, 000,
+       016, 025, 024, 016, 005, 025, 016, 000, 000, 000,
+       030, 031, 002, 004, 010, 023, 003, 000, 000, 000,
+       010, 024, 024, 010, 025, 022, 015, 000, 000, 000,
+       004, 004, 004, 000, 000, 000, 000, 000, 000, 000,
+       002, 004, 010, 010, 010, 004, 002, 000, 000, 000,
+       010, 004, 002, 002, 002, 004, 010, 000, 000, 000,
+       004, 025, 016, 004, 016, 025, 004, 000, 000, 000,
+       000, 004, 004, 037, 004, 004, 000, 000, 000, 000,
+       000, 000, 000, 000, 000, 004, 004, 010, 000, 000,
+       000, 000, 000, 016, 000, 000, 000, 000, 000, 000,
+       000, 000, 000, 000, 000, 000, 004, 000, 000, 000,
+       000, 001, 002, 004, 010, 020, 000, 000, 000, 000,
+       004, 012, 021, 021, 021, 012, 004, 000, 000, 000, /* 0 */
+       004, 014, 004, 004, 004, 004, 016, 000, 000, 000, /* 1 */
+       016, 021, 001, 006, 010, 020, 037, 000, 000, 000, /* 2 */
+       037, 001, 002, 006, 001, 021, 016, 000, 000, 000,
+       002, 006, 012, 022, 037, 002, 002, 000, 000, 000,
+       037, 020, 036, 001, 001, 021, 016, 000, 000, 000,
+       006, 010, 020, 036, 021, 021, 016, 000, 000, 000,
+       037, 001, 002, 004, 010, 010, 010, 000, 000, 000,
+       016, 021, 021, 016, 021, 021, 016, 000, 000, 000,
+       016, 021, 021, 017, 001, 002, 014, 000, 000, 000,
+       000, 000, 004, 000, 000, 000, 004, 000, 000, 000,
+       000, 000, 004, 000, 000, 004, 004, 010, 000, 000,
+       002, 004, 010, 020, 010, 004, 002, 000, 000, 000,
+       000, 000, 037, 000, 037, 000, 000, 000, 000, 000,
+       010, 004, 002, 001, 002, 004, 010, 000, 000, 000,
+       016, 021, 002, 004, 004, 000, 004, 000, 000, 000,
+       016, 021, 027, 025, 027, 020, 016, 000, 000, 000,
+       004, 012, 021, 021, 037, 021, 021, 000, 000, 000,
+       036, 021, 021, 036, 021, 021, 036, 000, 000, 000,
+       016, 021, 020, 020, 020, 021, 016, 000, 000, 000,
+       036, 021, 021, 021, 021, 021, 036, 000, 000, 000,
+       037, 020, 020, 036, 020, 020, 037, 000, 000, 000,
+       037, 020, 020, 036, 020, 020, 020, 000, 000, 000,
+       016, 021, 020, 020, 023, 021, 016, 000, 000, 000,
+       021, 021, 021, 037, 021, 021, 021, 000, 000, 000,
+       016, 004, 004, 004, 004, 004, 016, 000, 000, 000,
+       001, 001, 001, 001, 001, 021, 016, 000, 000, 000,
+       021, 022, 024, 030, 024, 022, 021, 000, 000, 000,
+       020, 020, 020, 020, 020, 020, 037, 000, 000, 000,
+       021, 033, 025, 021, 021, 021, 021, 000, 000, 000,
+       021, 021, 031, 025, 023, 021, 021, 000, 000, 000,
+       016, 021, 021, 021, 021, 021, 016, 000, 000, 000,
+       036, 021, 021, 036, 020, 020, 020, 000, 000, 000,
+       016, 021, 021, 021, 025, 022, 015, 000, 000, 000,
+       036, 021, 021, 036, 024, 022, 021, 000, 000, 000,
+       016, 021, 020, 016, 001, 021, 016, 000, 000, 000,
+       037, 004, 004, 004, 004, 004, 004, 000, 000, 000, /* T */
+       021, 021, 021, 021, 021, 021, 016, 000, 000, 000,
+       021, 021, 021, 012, 012, 004, 004, 000, 000, 000,
+       021, 021, 021, 025, 025, 025, 012, 000, 000, 000,
+       021, 021, 012, 004, 012, 021, 021, 000, 000, 000,
+       021, 021, 012, 004, 004, 004, 004, 000, 000, 000,
+       037, 001, 002, 004, 010, 020, 037, 000, 000, 000, /* Z */
+       016, 010, 010, 010, 010, 010, 016, 000, 000, 000, /* bracketleft */
+       000, 020, 010, 004, 002, 001, 000, 000, 000, 000, /* backslash */
+       016, 002, 002, 002, 002, 002, 016, 000, 000, 000, /* bracketright */
+       004, 012, 021, 000, 000, 000, 000, 000, 000, 000, /* asciicircum */
+       000, 000, 000, 000, 000, 000, 000, 037, 000, 000, /* underscore */
+       010, 004, 002, 000, 000, 000, 000, 000, 000, 000, /* asciigrave */
+       000, 000, 016, 001, 017, 021, 017, 000, 000, 000,
+       020, 020, 036, 021, 021, 021, 036, 000, 000, 000,
+       000, 000, 017, 020, 020, 020, 017, 000, 000, 000,
+       001, 001, 017, 021, 021, 021, 017, 000, 000, 000,
+       000, 000, 016, 021, 037, 020, 016, 000, 000, 000, /* e */
+       002, 004, 004, 016, 004, 004, 004, 000, 000, 000,
+       000, 000, 017, 021, 021, 021, 017, 001, 016, 000,
+       020, 020, 036, 021, 021, 021, 021, 000, 000, 000,
+       004, 000, 014, 004, 004, 004, 016, 000, 000, 000,
+       004, 000, 004, 004, 004, 004, 004, 004, 010, 000,
+       010, 010, 011, 012, 014, 012, 011, 000, 000, 000,
+       014, 004, 004, 004, 004, 004, 016, 000, 000, 000,
+       000, 000, 032, 025, 025, 025, 025, 000, 000, 000,
+       000, 000, 036, 021, 021, 021, 021, 000, 000, 000,
+       000, 000, 016, 021, 021, 021, 016, 000, 000, 000,
+       000, 000, 036, 021, 021, 021, 036, 020, 020, 000,
+       000, 000, 017, 021, 021, 021, 017, 001, 001, 000,
+       000, 000, 013, 014, 010, 010, 010, 000, 000, 000,
+       000, 000, 017, 020, 016, 001, 036, 000, 000, 000,
+       004, 004, 016, 004, 004, 004, 002, 000, 000, 000,
+       000, 000, 021, 021, 021, 021, 017, 000, 000, 000,
+       000, 000, 021, 021, 012, 012, 004, 000, 000, 000,
+       000, 000, 021, 021, 025, 025, 012, 000, 000, 000,
+       000, 000, 021, 012, 004, 012, 021, 000, 000, 000,
+       000, 000, 021, 021, 021, 021, 017, 001, 016, 000,
+       000, 000, 037, 002, 004, 010, 037, 000, 000, 000,
+       003, 004, 004, 030, 004, 004, 003, 000, 000, 000, /* braceleft */
+       004, 004, 004, 004, 004, 004, 004, 000, 000, 000, /* bar */
+       030, 004, 004, 003, 004, 004, 030, 000, 000, 000, /* braceright */
+       010, 025, 002, 000, 000, 000, 000, 000, 000, 000, /* asciitilde */
+       037, 037, 037, 037, 037, 037, 037, 000, 000, 000,
+
+       000, 004, 010, 037, 010, 004, 000, 000, 000, 000, /* leftarrow */
+       020, 020, 020, 020, 026, 001, 002, 004, 007, 000, /* onehalf */
+       000, 004, 002, 037, 002, 004, 000, 000, 000, 000, /* rightarrow */
+       000, 004, 016, 025, 004, 004, 000, 000, 000, 000, /* uparrow */
+       000, 000, 000, 037, 000, 000, 000, 000, 000, 000, /* endash */
+       006, 011, 010, 010, 034, 010, 010, 037, 000, 000, /* sterling */
+       010, 010, 010, 010, 011, 003, 005, 007, 001, 000, /* onequarter */
+       012, 012, 012, 012, 012, 012, 012, 000, 000, 000, /* doublebar */
+       030, 004, 030, 004, 031, 003, 005, 007, 001, 000, /* threequarters */
+       000, 004, 000, 037, 000, 004, 000, 000, 000, 000, /* divide */
+};
+
+int
+main(int argc, char **argv)
+{
+       int i;
+
+       doprologue();
+       for (i = 0; i < 105; i++) {
+               printf("gsave %d %d translate\n",
+                      i % 16 * XSIZE, (6 - i / 16) * YSIZE);
+               dochar(&data[i][0]);
+               printf("grestore\n");
+       }
+       printf("showpage\n");
+}
+
+void
+doprologue(void)
+{
+
+       printf("%s",
+"%!
+
+/blackpixel {
+    newpath
+    % Octagonal centre bit -- always black.
+    0 0.25 moveto
+    0 0.75 lineto
+    0.25 1 lineto
+    0.75 1 lineto
+    1 0.75 lineto
+    1 0.25 lineto
+    0.75 0 lineto
+    0.25 0 lineto
+    closepath fill
+
+    % fill in appropriate corners
+    gsave
+    { %forall
+       { %if
+           0 0 moveto
+           0 0.25 lineto
+           0.25 0 lineto
+           closepath fill
+       } if
+       1 0 translate 90 rotate
+    } forall
+    grestore
+} bind def
+
+/whitepixel {
+    gsave
+    { %forall
+       { %if
+           0 0 moveto
+           0 0.75 lineto
+           0.75 0 lineto
+           closepath fill
+       } if
+       1 0 translate 90 rotate
+    } forall
+    grestore
+} bind def
+
+4 4 scale
+1 1 translate
+");
+}
+
+void
+dochar(char data[YSIZE])
+{
+       struct corner corner[XSIZE][YSIZE] = { };
+       int x, y;
+
+       for (x = 0; x < XSIZE; x++) {
+               for (y = 0; y < YSIZE; y++) {
+                       printf("gsave %d %d translate\n", x, YSIZE - y - 1);
+                       if (getpix(data, x, y)) {
+                               /* Assume filled in */
+                               corner[x][y].tl = 1;
+                               corner[x][y].tr = 1;
+                               corner[x][y].bl = 1;
+                               corner[x][y].br = 1;
+                               /* Check for diagonals */
+                               if ((getpix(data, x-1, y) == 0 &&
+                                    getpix(data, x, y-1) == 0 &&
+                                    getpix(data, x-1, y-1) == 1) ||
+                                   (getpix(data, x+1, y) == 0 &&
+                                    getpix(data, x, y+1) == 0 &&
+                                    getpix(data, x+1, y+1) == 1)) {
+                                       corner[x][y].tr = 0;
+                                       corner[x][y].bl = 0;
+                               }
+                               if ((getpix(data, x+1, y) == 0 &&
+                                    getpix(data, x, y-1) == 0 &&
+                                    getpix(data, x+1, y-1) == 1) ||
+                                   (getpix(data, x-1, y) == 0 &&
+                                    getpix(data, x, y+1) == 0 &&
+                                    getpix(data, x-1, y+1) == 1)) {
+                                       corner[x][y].tl = 0;
+                                       corner[x][y].br = 0;
+                               }
+                               /* Avoid odd gaps */
+                               if (getpix(data, x-1, y) == 1 ||
+                                   getpix(data, x-1, y-1) == 1 ||
+                                   getpix(data, x, y-1) == 1)
+                                       corner[x][y].tl = 1;
+                               if (getpix(data, x+1, y) == 1 ||
+                                   getpix(data, x+1, y-1) == 1 ||
+                                   getpix(data, x, y-1) == 1)
+                                       corner[x][y].tr = 1;
+                               if (getpix(data, x-1, y) == 1 ||
+                                   getpix(data, x-1, y+1) == 1 ||
+                                   getpix(data, x, y+1) == 1)
+                                       corner[x][y].bl = 1;
+                               if (getpix(data, x+1, y) == 1 ||
+                                   getpix(data, x+1, y+1) == 1 ||
+                                   getpix(data, x, y+1) == 1)
+                                       corner[x][y].br = 1;
+                               printf("[ %s %s %s %s ] blackpixel\n",
+                                      corner[x][y].bl ? "true" : "false",
+                                      corner[x][y].br ? "true" : "false",
+                                      corner[x][y].tr ? "true" : "false",
+                                      corner[x][y].tl ? "true" : "false");
+                       } else {
+                               /* Assume clear */
+                               corner[x][y].tl = 0;
+                               corner[x][y].tr = 0;
+                               corner[x][y].bl = 0;
+                               corner[x][y].br = 0;
+                               /* white pixel -- just diagonals */
+                               if (getpix(data, x-1, y) == 1 &&
+                                   getpix(data, x, y-1) == 1 &&
+                                   getpix(data, x-1, y-1) == 0)
+                                       corner[x][y].tl = 1;
+                               if (getpix(data, x+1, y) == 1 &&
+                                   getpix(data, x, y-1) == 1 &&
+                                   getpix(data, x+1, y-1) == 0)
+                                       corner[x][y].tr = 1;
+                               if (getpix(data, x-1, y) == 1 &&
+                                   getpix(data, x, y+1) == 1 &&
+                                   getpix(data, x-1, y+1) == 0)
+                                       corner[x][y].bl = 1;
+                               if (getpix(data, x+1, y) == 1 &&
+                                   getpix(data, x, y+1) == 1 &&
+                                   getpix(data, x+1, y+1) == 0)
+                                       corner[x][y].br = 1;
+                               printf("[ %s %s %s %s ] whitepixel\n",
+                                      corner[x][y].bl ? "true" : "false",
+                                      corner[x][y].br ? "true" : "false",
+                                      corner[x][y].tr ? "true" : "false",
+                                      corner[x][y].tl ? "true" : "false");
+                       }
+                       printf("grestore\n");
+               }
+       }
+}
diff --git a/ttxt.pl b/ttxt.pl
new file mode 100644 (file)
index 0000000..60df406
--- /dev/null
+++ b/ttxt.pl
@@ -0,0 +1,40 @@
+#! /usr/bin/perl
+
+$ylimit = 6; $xlimit = 8;
+
+@pixel = (
+         [ 0, 0, 0, 1, 0, 0 ],
+         [ 0, 0, 1, 0, 1, 0 ],
+         [ 0, 1, 0, 0, 0, 1 ],
+         [ 0, 1, 0, 0, 0, 1 ],
+         [ 0, 1, 0, 0, 0, 1 ],
+         [ 0, 0, 1, 0, 1, 0 ],
+         [ 0, 0, 0, 1, 0, 0 ],
+         [ 0, 0, 0, 0, 0, 0 ],
+         );
+
+@augment = ( [], [], [], [], [], [], [] );
+
+for ($x = 0; $x < $xlimit - 1; $x++) {
+    for ($y = 0; $y < $ylimit - 1; $y++) {
+       if ($pixel[$x][$y] == $pixel[$x+1][$y+1] &&
+           $pixel[$x][$y] != $pixel[$x+1][$y] &&
+           $pixel[$x][$y+1] == $pixel[$x+1][$y]) {
+           $augment[$x][$y] = 1;
+       }
+    }
+}
+
+for ($x = 0; $x < $xlimit; $x++) {
+    for ($y = 0; $y < $ylimit; $y++) {
+       print "gsave $x $y translate\n";
+       print "[ ";
+       print $augment[$x-1][$y-1] ? "true " : "false ";
+       print $augment[$x][$y-1] ? "true " : "false ";
+       print $augment[$x][$y] ? "true " : "false ";
+       print $augment[$x-1][$y] ? "true " : "false ";
+       print "] ";
+       print $pixel[$x][$y] ? "blackpixel\n" : "whitepixel\n";
+       print "grestore\n";
+    }
+}