shithub: fnt

Download patch

ref: ed8ed23fc5671e443072e00603cf03805db8fd18
parent: a65e44617ba1d08e011f3cee56470a0a7351ea47
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Jul 6 17:01:19 EDT 2024

initial implementation of wavelet rasterizer

Also make the code build and run on Linux.

--- a/gen.rkt
+++ b/gen.rkt
@@ -1,6 +1,12 @@
 #!/usr/bin/env racket
 #lang racket
 
+(define plan9? (make-parameter #f))
+
+(command-line
+  #:once-each
+  [("--plan9") "Generate for Plan 9" (plan9? #t)])
+
 (require (for-syntax racket/format))
 (require (for-syntax syntax/parse))
 (require (for-syntax racket/contract))
@@ -57,7 +63,7 @@
                  (gen-c code b index) ; generates code for the C source file
                  (c-type code)) ; type name to be used in C
 
-(define-struct type (name bits c verb parse)
+(define-struct type (name bits c verb fmtarg parse)
   #:transparent
   #:methods gen:code
   [(define (gen-h t)
@@ -243,6 +249,7 @@
   (define fixed-array (and basic-array (number? cnt)))
   (define array-index (if cnt "[i]" ""))
   (define verb (if (type? t) (or (field-verb f) (type-verb t)) ""))
+  (define fmtarg (if (type? t) (type-fmtarg t) identity))
   (define bits (field-bits f))
   (define bits-verbs (or (and bits (string-join (make-list (hash-count bits) "%s") "")) ""))
   (define bits-args
@@ -256,17 +263,16 @@
         ""))
   (define print-index
     (if basic-array
-        (~a "Bprint(f, \"%*s%s[%d]: "
+        (~a "f->print(f->aux, \"%*s%s[%d]: "
             verb
             bits-verbs
             "\\n\", indent, \"\", \""
             (field-name f)
-            "\", i, v->"
-            (field-name f)
-            array-index
+            "\", i, "
+            (fmtarg (~a "v->" (field-name f) array-index))
             bits-args
             ");")
-        (~a "Bprint(f, \"%*s%s[%d]:\\n\", indent, \"\", \"" (field-name f) "\", i);")))
+        (~a "f->print(f->aux, \"%*s%s[%d]:\\n\", indent, \"\", \"" (field-name f) "\", i);")))
   (define array-loop
     (if cnt
         (λ (lst)
@@ -278,17 +284,16 @@
     (flatten
      (list
       (if (type? t)
-          (~a "Bprint(f, \"%*s%s: "
+          (~a "f->print(f->aux, \"%*s%s: "
               verb
               bits-verbs
               "\\n\", indent, \"\", \""
               (field-name f)
-              "\", v->"
-              (field-name f)
-              array-index
+              "\", "
+              (fmtarg (~a "v->" (field-name f) array-index))
               bits-args
               ");")
-          (list (if cnt empty (~a "Bprint(f, \"%*s%s:\\n\", indent, \"\", \"" (field-name f) "\");"))
+          (list (if cnt empty (~a "f->print(f->aux, \"%*s%s:\\n\", indent, \"\", \"" (field-name f) "\");"))
                 (if is-ptr (~a "if(v->" (field-name f) " != nil)") empty)
                 (~a (if is-ptr "	" "")
                     "print_"
@@ -332,7 +337,7 @@
                             (~a "int read_" (cmplx-name c) "(Otf *o, " (cmplx-name c) " *v);")
                             (~a "void print_"
                                 (cmplx-name c)
-                                "(Biobuf *f, int indent, Otf *o, "
+                                "(Otfile *f, int indent, Otf *o, "
                                 (cmplx-name c)
                                 " *v);")))))
    (define (gen-c c b index)
@@ -406,7 +411,7 @@
              (~a "}"))
        (list (~a "")
              (~a "void")
-             (~a "print_" (cmplx-name c) "(Biobuf *f, int indent, Otf *o, " (cmplx-name c) " *v)")
+             (~a "print_" (cmplx-name c) "(Otfile *f, int indent, Otf *o, " (cmplx-name c) " *v)")
              (~a "{")
              (indent (map field-print-c (cmplx-fields c)))
              (indent (filter-extra (cmplx-extra c) 'print))
@@ -428,15 +433,20 @@
 
 (define-for-syntax typenames '())
 
+(define (c-friendly-name t #:downcase [downcase #f])
+  (define (f t)
+    (string-replace (string-trim ((if downcase string-downcase identity) t)) "/" (if (plan9?) "∕" "")))
+  (if (symbol? t) (string->symbol (f (symbol->string t))) (f t)))
+
 (define-syntax (mktype stx)
   (syntax-parse stx
-    [(_ typ:id bits c:id verb:string) #'(mktype typ bits c verb (autoparse bits `c))]
-    [(_ typ:id bits c:id verb:string parse:expr)
+    [(_ typ:id bits c:id verb:expr) #'(mktype typ bits c verb (autoparse bits `c))]
+    [(_ typ:id bits c:id verb:expr parse:expr)
      #:declare bits (expr/c #'size-in-bits/c #:name "size in bits")
      (begin
        (set! typenames (cons (syntax-e #`typ) typenames))
        #'(begin
-           (define typ (make-type `typ bits.c `c verb parse))
+           (define typ (make-type `typ bits.c `c (if (pair? verb) (car verb) verb) (if (pair? verb) (cdr verb) identity) parse))
            (set! types (append types (list typ)))))]))
 
 (define-syntax (mkcmplx stx)
@@ -452,7 +462,7 @@
        #'(begin
            (define tag- (~? (~@ tag.c) #f))
            (define typ
-             (make-cmplx `typ
+             (make-cmplx (c-friendly-name `typ)
                          (mkfields [~@ fields] ...)
                          tag-
                          (~? (~@ extra) empty)
@@ -494,7 +504,7 @@
     [(_ _ _ ({~literal at} e:expr)) #''(at e)]
     [(_ type _ {~literal hex})
      #:fail-when (not (type-number? (syntax-e #'type))) "not a number type"
-     #''(verb "%#ux")]
+     #'(if (plan9?) '(verb "%#ux") '(verb "%#x"))]
     [(_ type _ (p:compop vs:number ...+))
      #:fail-when (not (type-comparable? (syntax-e #'type))) "type can't be used in a comparison"
      #''(test p vs ...)]
--- /dev/null
+++ b/meson.build
@@ -1,0 +1,36 @@
+project(
+	'fnt',
+	'c',
+	version: '0.1',
+	default_options: [
+		'c_std=c2x',
+		'warning_level=3',
+		'buildtype=debugoptimized',
+	],
+)
+
+add_project_arguments(
+	'-Werror=strict-aliasing',
+	'-Wno-pedantic',
+	'-Wno-parentheses',
+	'-Wno-incompatible-pointer-types',
+	'-Wno-sign-compare',
+	'-Wno-unknown-pragmas',
+	'-D_DEFAULT_SOURCE',
+	language: 'c',
+)
+
+src = [
+	'otf.c',
+	'rast.c',
+	'unix.c',
+	'test_unix.c',
+]
+
+executable(
+	'fntest',
+	sources: [src],
+	include_directories: include_directories(
+		'unix',
+	),
+)
--- a/mkfile
+++ b/mkfile
@@ -1,11 +1,14 @@
 </$objtype/mkfile
 
 BIN=/$objtype/bin
-TARG=test
+TARG=test_plan9
+CFLAGS=$CFLAGS -Iplan9
 
 OFILES=\
   otf.$O\
-  test.$O\
+  rast.$O\
+  plan9.$O\
+  test_plan9.$O\
 
 HFILES=\
   otf.h\
--- a/otf.c
+++ b/otf.c
@@ -1,7 +1,5 @@
 /* this file is generated. do not modify. */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
+#include "otfsys.h"
 #include "otf.h"
 
 int indentΔ = 2;
@@ -9,7 +7,7 @@
 typedef struct Range Range;
 
 struct Otf {
-	Biobuf *f;
+	Otfile *f;
 	Range *r;
 	u8int *buf;
 	int bufsz;
@@ -118,20 +116,15 @@
 }
 
 Otf *
-otfopen(char *path)
+otfopen(Otfile *f)
 {
 	Otf *o;
-	Biobuf *f;
 
-	if((f = Bopen(path, OREAD)) == nil)
-		return nil;
 	if((o = calloc(1, sizeof(*o))) == nil){
 		werrstr("no memory");
-		Bterm(f);
 	}else{
 		o->f = f;
 		if(read_TableDirectory(o, &o->td) != 0){
-			Bterm(f);
 			free(o);
 			o = nil;
 		}
@@ -140,7 +133,7 @@
 }
 
 void
-otfprint(Otf *o, Biobuf *out, int indent)
+otfprint(Otf *o, Otfile *out, int indent)
 {
 	print_TableDirectory(out, indent, o, &o->td);
 }
@@ -180,7 +173,7 @@
 	r->start = off;
 	r->len = len;
 	r->prevoff = o->off;
-	if((x = Bseek(o->f, off, 0)) != off){
+	if((x = o->f->seek(o->f->aux, off, 0)) != off){
 		werrstr("seek offset: need %d, got %d", off, x);
 		goto err;
 	}
@@ -203,7 +196,7 @@
 		werrstr("pop without push");
 		goto err;
 	}
-	if((x = Bseek(o->f, r->prevoff, 0)) != r->prevoff){
+	if((x = o->f->seek(o->f->aux, r->prevoff, 0)) != r->prevoff){
 		werrstr("seek offset: need %d, got %d", r->prevoff, x);
 		goto err;
 	}
@@ -242,7 +235,7 @@
 		o->buf = b;
 		o->bufsz = n;
 	}
-	if((x = Bread(o->f, o->buf, n)) != n){
+	if((x = o->f->read(o->f->aux, o->buf, n)) != n){
 		werrstr("need %d, got %d; off %d", n, x, o->off);
 		goto err;
 	}
@@ -357,9 +350,10 @@
 }
 
 void
-print_ComponentGlyph(Biobuf *f, int indent, Otf *o, ComponentGlyph *v)
+print_ComponentGlyph(Otfile *f, int indent, Otf *o, ComponentGlyph *v)
 {
-	Bprint(f, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags,
+	void *a = f->aux;
+	f->print(a, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags,
 		(v->flags&CGLYPH_FL_ROUND_TO_GRID_XY)?" CGLYPH_FL_ROUND_TO_GRID_XY":"",
 		(v->flags&CGLYPH_FL_SCALE)?" CGLYPH_FL_SCALE":"",
 		(v->flags&CGLYPH_FL_MORE_COMPONENTS)?" CGLYPH_FL_MORE_COMPONENTS":"",
@@ -371,32 +365,32 @@
 		(v->flags&CGLYPH_FL_SCALED_COMPONENT_OFFSET)?" CGLYPH_FL_SCALED_COMPONENT_OFFSET":"",
 		(v->flags&CGLYPH_FL_UNSCALED_COMPONENT_OFFSET)?" CGLYPH_FL_UNSCALED_COMPONENT_OFFSET":""
 	);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphIndex", v->glyphIndex);
+	f->print(a, "%*s%s: %ud\n", indent, "", "glyphIndex", v->glyphIndex);
 	if(v->arg1 != 0 || v->arg2 != 0){
-		Bprint(f, "%*s%s: %d\n", indent, "", "arg1", v->arg1);
-		Bprint(f, "%*s%s: %d\n", indent, "", "arg2", v->arg2);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "arg1", v->arg1);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "arg2", v->arg2);
 	}
 	if(v->flags & CGLYPH_FL_SCALE){
-		Bprint(f, "%*s%s: %g\n", indent, "", "scale", v->scale);
+		f->print(a, "%*s%s: %g\n", indent, "", "scale", v->scale);
 	}else if(v->flags & CGLYPH_FL_SCALE_XY){
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
 	}else if(v->flags & CGLYPH_FL_2X2_TRANSFORM){
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scale01", v->scale01);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scale10", v->scale10);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
+		f->print(a, "%*s%s: %g\n", indent, "", "scale01", v->scale01);
+		f->print(a, "%*s%s: %g\n", indent, "", "scale10", v->scale10);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
 	}
 	if(v->numInstr > 0 && v->instr != nil){
-		Bprint(f, "%*s%s: %ud\n", indent, "", "numInstr", v->numInstr);
-		Bprint(f, "%*s%s:", indent, "", "instr");
+		f->print(a, "%*s%s: %ud\n", indent, "", "numInstr", v->numInstr);
+		f->print(a, "%*s%s:", indent, "", "instr");
 		for(int i = 0; i < v->numInstr; i++)
-			Bprint(f, " %02ux", v->instr[i]);
-		Bprint(f, "\n");
+			f->print(a, " %02ux", v->instr[i]);
+		f->print(a, "\n");
 	}
 	if(v->next != nil){
-		Bprint(f, "%*s%s:\n", indent, "", "next");
-		print_ComponentGlyph(f, indent+indentΔ, o, v->next);
+		f->print(a, "%*s%s:\n", indent, "", "next");
+		print_ComponentGlyph(a, indent+indentΔ, o, v->next);
 	}
 }
 
@@ -523,64 +517,32 @@
 }
 
 void
-print_SimpleGlyph(Biobuf *f, int indent, Otf *o, SimpleGlyph *v)
+print_SimpleGlyph(Otfile *f, int indent, Otf *o, SimpleGlyph *v)
 {
+	void *a = f->aux;
 	USED(o);
 	if(v->numEndPtsOfContours > 0){
-		Bprint(f, "%*s%s:", indent, "", "endPtsOfContours");
+		f->print(a, "%*s%s:", indent, "", "endPtsOfContours");
 		for(int i = 0; i < v->numEndPtsOfContours; i++)
-			Bprint(f, " %ud", v->endPtsOfContours[i]);
-		Bprint(f, "\n");
+			f->print(a, " %ud", v->endPtsOfContours[i]);
+		f->print(a, "\n");
 	}
 	if(v->instructionLength > 0){
-		Bprint(f, "%*s%s: %ud\n", indent, "", "instructionLength", v->instructionLength);
-		Bprint(f, "%*s%s:", indent, "", "instructions");
+		f->print(a, "%*s%s: %ud\n", indent, "", "instructionLength", v->instructionLength);
+		f->print(a, "%*s%s:", indent, "", "instructions");
 		for(int i = 0; i < v->instructionLength; i++)
-			Bprint(f, " %02ux", v->instructions[i]);
-		Bprint(f, "\n");
+			f->print(a, " %02ux", v->instructions[i]);
+		f->print(a, "\n");
 	}
 	if(v->numPoints > 0){
-		Bprint(f, "%*s%s: %d\n", indent, "", "numPoints", v->numPoints);
-		Bprint(f, "%*s%s:", indent, "", "points");
+		f->print(a, "%*s%s: %d\n", indent, "", "numPoints", v->numPoints);
+		f->print(a, "%*s%s:", indent, "", "points");
 		for(int i = 0; i < v->numPoints; i++)
-			Bprint(f, " (%d,%d,%d)", v->points[i].x, v->points[i].y, v->points[i].onCurve);
-		Bprint(f, "\n");
+			f->print(a, " (%d,%d,%s)", v->points[i].x, v->points[i].y, v->points[i].onCurve?"on":"off");
+		f->print(a, "\n");
 	}
 }
 
-static int
-Tfmt(Fmt *f)
-{
-	Tm t;
-	s64int v = va_arg(f->args, s64int);
-	return fmtprint(f, "%τ", tmfmt(tmtime(&t, v, nil), nil));
-}
-
-static int
-Vfmt(Fmt *f)
-{
-	u32int v = va_arg(f->args, u32int);
-	return fmtprint(f, "%d.%d", v>>16, v&0xffff);
-}
-
-static int
-tfmt(Fmt *f)
-{
-	u32int v = va_arg(f->args, u32int);
-	if(v == 0)
-		return fmtprint(f, "<nil>");
-	return fmtprint(f, "%c%c%c%c", v>>24, v>>16, v>>8, v>>0);
-}
-
-void
-otfinit(void)
-{
-	tmfmtinstall();
-	fmtinstall('V', Vfmt);
-	fmtinstall('T', Tfmt);
-	fmtinstall('t', tfmt);
-}
-
 Glyf *
 otfglyf(Otf *o, int index)
 {
@@ -664,12 +626,12 @@
 }
 
 void
-print_SubHeader(Biobuf *f, int indent, Otf *o, SubHeader *v)
+print_SubHeader(Otfile *f, int indent, Otf *o, SubHeader *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "firstCode", v->firstCode);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "entryCode", v->entryCode);
-	Bprint(f, "%*s%s: %d\n", indent, "", "idDelta", v->idDelta);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "idRangeOffset", v->idRangeOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "firstCode", v->firstCode);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "entryCode", v->entryCode);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "idDelta", v->idDelta);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "idRangeOffset", v->idRangeOffset);
 	USED(o);
 }
 
@@ -689,11 +651,11 @@
 }
 
 void
-print_MapGroup(Biobuf *f, int indent, Otf *o, MapGroup *v)
+print_MapGroup(Otfile *f, int indent, Otf *o, MapGroup *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startCharCode", v->startCharCode);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "endCharCode", v->endCharCode);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startGlyphID", v->startGlyphID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startCharCode", v->startCharCode);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "endCharCode", v->endCharCode);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startGlyphID", v->startGlyphID);
 	USED(o);
 }
 
@@ -714,12 +676,12 @@
 }
 
 void
-print_SubtableCmap0(Biobuf *f, int indent, Otf *o, SubtableCmap0 *v)
+print_SubtableCmap0(Otfile *f, int indent, Otf *o, SubtableCmap0 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
 	for(int i = 0; i < 256; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
 	USED(o);
 }
 
@@ -740,12 +702,12 @@
 }
 
 void
-print_SubtableCmap2(Biobuf *f, int indent, Otf *o, SubtableCmap2 *v)
+print_SubtableCmap2(Otfile *f, int indent, Otf *o, SubtableCmap2 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
 	for(int i = 0; i < 256; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "subHeaderKeys", i, v->subHeaderKeys[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "subHeaderKeys", i, v->subHeaderKeys[i]);
 	USED(o);
 }
 
@@ -791,22 +753,22 @@
 }
 
 void
-print_SubtableCmap4(Biobuf *f, int indent, Otf *o, SubtableCmap4 *v)
+print_SubtableCmap4(Otfile *f, int indent, Otf *o, SubtableCmap4 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "segCountX2", v->segCountX2);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "segCountX2", v->segCountX2);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
 	for(int i = 0; i < (v->segCountX2/2); i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "endCode", i, v->endCode[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "endCode", i, v->endCode[i]);
 	for(int i = 0; i < (v->segCountX2/2); i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "startCode", i, v->startCode[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "startCode", i, v->startCode[i]);
 	for(int i = 0; i < (v->segCountX2/2); i++)
-		Bprint(f, "%*s%s[%d]: %d\n", indent, "", "idDelta", i, v->idDelta[i]);
+		f->print(f->aux, "%*s%s[%d]: %d\n", indent, "", "idDelta", i, v->idDelta[i]);
 	for(int i = 0; i < (v->segCountX2/2); i++)
-		Bprint(f, "%*s%s[%d]: %d\n", indent, "", "idRangeOffset", i, v->idRangeOffset[i]);
+		f->print(f->aux, "%*s%s[%d]: %d\n", indent, "", "idRangeOffset", i, v->idRangeOffset[i]);
 	USED(o);
 }
 
@@ -832,14 +794,14 @@
 }
 
 void
-print_SubtableCmap6(Biobuf *f, int indent, Otf *o, SubtableCmap6 *v)
+print_SubtableCmap6(Otfile *f, int indent, Otf *o, SubtableCmap6 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "firstCode", v->firstCode);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "entryCount", v->entryCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "firstCode", v->firstCode);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "entryCount", v->entryCount);
 	for(int i = 0; i < v->entryCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
 	USED(o);
 }
 
@@ -865,15 +827,15 @@
 }
 
 void
-print_SubtableCmap8(Biobuf *f, int indent, Otf *o, SubtableCmap8 *v)
+print_SubtableCmap8(Otfile *f, int indent, Otf *o, SubtableCmap8 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
 	for(int i = 0; i < 8192; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "is32", i, v->is32[i]);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numGroups", v->numGroups);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "is32", i, v->is32[i]);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numGroups", v->numGroups);
 	for(int i = 0; i < v->numGroups; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "groups", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "groups", i);
 		print_MapGroup(f, indent+indentΔ, o, &v->groups[i]);
 	}
 	USED(o);
@@ -897,13 +859,13 @@
 }
 
 void
-print_SubtableCmap10(Biobuf *f, int indent, Otf *o, SubtableCmap10 *v)
+print_SubtableCmap10(Otfile *f, int indent, Otf *o, SubtableCmap10 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "reserved", v->reserved);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startCharCode", v->startCharCode);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numChars", v->numChars);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "reserved", v->reserved);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startCharCode", v->startCharCode);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numChars", v->numChars);
 	USED(o);
 }
 
@@ -928,14 +890,14 @@
 }
 
 void
-print_SubtableCmap12or13(Biobuf *f, int indent, Otf *o, SubtableCmap12or13 *v)
+print_SubtableCmap12or13(Otfile *f, int indent, Otf *o, SubtableCmap12or13 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "reserved", v->reserved);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numGroups", v->numGroups);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "reserved", v->reserved);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "language", v->language);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numGroups", v->numGroups);
 	for(int i = 0; i < v->numGroups; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "groups", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "groups", i);
 		print_MapGroup(f, indent+indentΔ, o, &v->groups[i]);
 	}
 	USED(o);
@@ -956,10 +918,10 @@
 }
 
 void
-print_UnicodeRange(Biobuf *f, int indent, Otf *o, UnicodeRange *v)
+print_UnicodeRange(Otfile *f, int indent, Otf *o, UnicodeRange *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startUnicodeValue", v->startUnicodeValue);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "additionalCount", v->additionalCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startUnicodeValue", v->startUnicodeValue);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "additionalCount", v->additionalCount);
 	USED(o);
 }
 
@@ -981,11 +943,11 @@
 }
 
 void
-print_DefaultUVS(Biobuf *f, int indent, Otf *o, DefaultUVS *v)
+print_DefaultUVS(Otfile *f, int indent, Otf *o, DefaultUVS *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numUnicodeValueRanges", v->numUnicodeValueRanges);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numUnicodeValueRanges", v->numUnicodeValueRanges);
 	for(int i = 0; i < v->numUnicodeValueRanges; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "ranges", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "ranges", i);
 		print_UnicodeRange(f, indent+indentΔ, o, &v->ranges[i]);
 	}
 	USED(o);
@@ -1006,10 +968,10 @@
 }
 
 void
-print_UVSMapping(Biobuf *f, int indent, Otf *o, UVSMapping *v)
+print_UVSMapping(Otfile *f, int indent, Otf *o, UVSMapping *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "unicodeValue", v->unicodeValue);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "unicodeValue", v->unicodeValue);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
 	USED(o);
 }
 
@@ -1031,11 +993,11 @@
 }
 
 void
-print_NonDefaultUVS(Biobuf *f, int indent, Otf *o, NonDefaultUVS *v)
+print_NonDefaultUVS(Otfile *f, int indent, Otf *o, NonDefaultUVS *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numUVSMappings", v->numUVSMappings);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numUVSMappings", v->numUVSMappings);
 	for(int i = 0; i < v->numUVSMappings; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "uvsMappings", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "uvsMappings", i);
 		print_UVSMapping(f, indent+indentΔ, o, &v->uvsMappings[i]);
 	}
 	USED(o);
@@ -1079,15 +1041,15 @@
 }
 
 void
-print_VariationSelector(Biobuf *f, int indent, Otf *o, VariationSelector *v)
+print_VariationSelector(Otfile *f, int indent, Otf *o, VariationSelector *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "varSelector", v->varSelector);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "defaultUVSOffset", v->defaultUVSOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "nonDefaultUVSOffset", v->nonDefaultUVSOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "defaultUVS");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "varSelector", v->varSelector);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "defaultUVSOffset", v->defaultUVSOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "nonDefaultUVSOffset", v->nonDefaultUVSOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "defaultUVS");
 	if(v->defaultUVS != nil)
 		print_DefaultUVS(f, indent+indentΔ, o, v->defaultUVS);
-	Bprint(f, "%*s%s:\n", indent, "", "nonDefaultUVS");
+	f->print(f->aux, "%*s%s:\n", indent, "", "nonDefaultUVS");
 	if(v->nonDefaultUVS != nil)
 		print_NonDefaultUVS(f, indent+indentΔ, o, v->nonDefaultUVS);
 	USED(o);
@@ -1112,12 +1074,12 @@
 }
 
 void
-print_SubtableCmap14(Biobuf *f, int indent, Otf *o, SubtableCmap14 *v)
+print_SubtableCmap14(Otfile *f, int indent, Otf *o, SubtableCmap14 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numVarSelectorRecords", v->numVarSelectorRecords);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numVarSelectorRecords", v->numVarSelectorRecords);
 	for(int i = 0; i < v->numVarSelectorRecords; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "varSelector", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "varSelector", i);
 		print_VariationSelector(f, indent+indentΔ, o, &v->varSelector[i]);
 	}
 	USED(o);
@@ -1189,39 +1151,39 @@
 }
 
 void
-print_SubtableCmap(Biobuf *f, int indent, Otf *o, SubtableCmap *v)
+print_SubtableCmap(Otfile *f, int indent, Otf *o, SubtableCmap *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "format", v->format);
 	if(v->format == 0){
-		Bprint(f, "%*s%s:\n", indent, "", "sub0");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub0");
 		print_SubtableCmap0(f, indent+indentΔ, o, &v->sub0);
 	}
 	if(v->format == 2){
-		Bprint(f, "%*s%s:\n", indent, "", "sub2");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub2");
 		print_SubtableCmap2(f, indent+indentΔ, o, &v->sub2);
 	}
 	if(v->format == 4){
-		Bprint(f, "%*s%s:\n", indent, "", "sub4");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub4");
 		print_SubtableCmap4(f, indent+indentΔ, o, &v->sub4);
 	}
 	if(v->format == 6){
-		Bprint(f, "%*s%s:\n", indent, "", "sub6");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub6");
 		print_SubtableCmap6(f, indent+indentΔ, o, &v->sub6);
 	}
 	if(v->format == 8){
-		Bprint(f, "%*s%s:\n", indent, "", "sub8");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub8");
 		print_SubtableCmap8(f, indent+indentΔ, o, &v->sub8);
 	}
 	if(v->format == 10){
-		Bprint(f, "%*s%s:\n", indent, "", "sub10");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub10");
 		print_SubtableCmap10(f, indent+indentΔ, o, &v->sub10);
 	}
 	if(v->format == 12 || v->format == 13){
-		Bprint(f, "%*s%s:\n", indent, "", "sub12or13");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub12or13");
 		print_SubtableCmap12or13(f, indent+indentΔ, o, &v->sub12or13);
 	}
 	if(v->format == 14){
-		Bprint(f, "%*s%s:\n", indent, "", "sub14");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub14");
 		print_SubtableCmap14(f, indent+indentΔ, o, &v->sub14);
 	}
 	USED(o);
@@ -1258,12 +1220,12 @@
 }
 
 void
-print_EncodingRecord(Biobuf *f, int indent, Otf *o, EncodingRecord *v)
+print_EncodingRecord(Otfile *f, int indent, Otf *o, EncodingRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "platformID", v->platformID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "encodingID", v->encodingID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "subtableOffset", v->subtableOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "subtable");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "platformID", v->platformID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "encodingID", v->encodingID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "subtableOffset", v->subtableOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "subtable");
 	if(v->subtable != nil)
 		print_SubtableCmap(f, indent+indentΔ, o, v->subtable);
 	USED(o);
@@ -1292,11 +1254,11 @@
 }
 
 void
-print_TableCmap(Biobuf *f, int indent, Otf *o, TableCmap *v)
+print_TableCmap(Otfile *f, int indent, Otf *o, TableCmap *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numTables", v->numTables);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numTables", v->numTables);
 	for(int i = 0; i < v->numTables; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "encodingRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "encodingRecords", i);
 		print_EncodingRecord(f, indent+indentΔ, o, &v->encodingRecords[i]);
 	}
 	USED(o);
@@ -1360,19 +1322,19 @@
 }
 
 void
-print_TableHead(Biobuf *f, int indent, Otf *o, TableHead *v)
+print_TableHead(Otfile *f, int indent, Otf *o, TableHead *v)
 {
-	Bprint(f, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags, (v->flags&HEAD_FL_BASELINE_Y_0)?" HEAD_FL_BASELINE_Y_0":"", (v->flags&HEAD_FL_LEFT_SIDEBEARING_X_0)?" HEAD_FL_LEFT_SIDEBEARING_X_0":"", (v->flags&HEAD_FL_INSTR_DEP_POINT_SZ)?" HEAD_FL_INSTR_DEP_POINT_SZ":"", (v->flags&HEAD_FL_FORCE_PPEM_INT)?" HEAD_FL_FORCE_PPEM_INT":"", (v->flags&HEAD_FL_INSTR_ALT_ADVANCE_WIDTH)?" HEAD_FL_INSTR_ALT_ADVANCE_WIDTH":"", (v->flags&HEAD_FL_LOSSLESS)?" HEAD_FL_LOSSLESS":"", (v->flags&HEAD_FL_CONVERTED)?" HEAD_FL_CONVERTED":"", (v->flags&HEAD_FL_CLEARTYPE)?" HEAD_FL_CLEARTYPE":"", (v->flags&HEAD_FL_LAST_RESORT)?" HEAD_FL_LAST_RESORT":"");
-	Bprint(f, "%*s%s: %ud\n", indent, "", "unitsPerEm", v->unitsPerEm);
-	Bprint(f, "%*s%s: %T\n", indent, "", "created", v->created);
-	Bprint(f, "%*s%s: %T\n", indent, "", "modified", v->modified);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xMin", v->xMin);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yMin", v->yMin);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xMax", v->xMax);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yMax", v->yMax);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "macStyle", v->macStyle);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lowestRecPPEM", v->lowestRecPPEM);
-	Bprint(f, "%*s%s: %d\n", indent, "", "indexToLocFormat", v->indexToLocFormat);
+	f->print(f->aux, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags, (v->flags&HEAD_FL_BASELINE_Y_0)?" HEAD_FL_BASELINE_Y_0":"", (v->flags&HEAD_FL_LEFT_SIDEBEARING_X_0)?" HEAD_FL_LEFT_SIDEBEARING_X_0":"", (v->flags&HEAD_FL_INSTR_DEP_POINT_SZ)?" HEAD_FL_INSTR_DEP_POINT_SZ":"", (v->flags&HEAD_FL_FORCE_PPEM_INT)?" HEAD_FL_FORCE_PPEM_INT":"", (v->flags&HEAD_FL_INSTR_ALT_ADVANCE_WIDTH)?" HEAD_FL_INSTR_ALT_ADVANCE_WIDTH":"", (v->flags&HEAD_FL_LOSSLESS)?" HEAD_FL_LOSSLESS":"", (v->flags&HEAD_FL_CONVERTED)?" HEAD_FL_CONVERTED":"", (v->flags&HEAD_FL_CLEARTYPE)?" HEAD_FL_CLEARTYPE":"", (v->flags&HEAD_FL_LAST_RESORT)?" HEAD_FL_LAST_RESORT":"");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "unitsPerEm", v->unitsPerEm);
+	f->print(f->aux, "%*s%s: %τ\n", indent, "", "created", fmttime(v->created));
+	f->print(f->aux, "%*s%s: %τ\n", indent, "", "modified", fmttime(v->modified));
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xMin", v->xMin);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yMin", v->yMin);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xMax", v->xMax);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yMax", v->yMax);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "macStyle", v->macStyle);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lowestRecPPEM", v->lowestRecPPEM);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "indexToLocFormat", v->indexToLocFormat);
 	USED(o);
 }
 
@@ -1416,22 +1378,22 @@
 }
 
 void
-print_TableHhea(Biobuf *f, int indent, Otf *o, TableHhea *v)
+print_TableHhea(Otfile *f, int indent, Otf *o, TableHhea *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ascender", v->ascender);
-	Bprint(f, "%*s%s: %d\n", indent, "", "descender", v->descender);
-	Bprint(f, "%*s%s: %d\n", indent, "", "lineGap", v->lineGap);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "advanceWidthMax", v->advanceWidthMax);
-	Bprint(f, "%*s%s: %d\n", indent, "", "minLeftSideBearing", v->minLeftSideBearing);
-	Bprint(f, "%*s%s: %d\n", indent, "", "minRightSideBearing", v->minRightSideBearing);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xMaxExtent", v->xMaxExtent);
-	Bprint(f, "%*s%s: %d\n", indent, "", "caretSlopeRise", v->caretSlopeRise);
-	Bprint(f, "%*s%s: %d\n", indent, "", "caretSlopeRun", v->caretSlopeRun);
-	Bprint(f, "%*s%s: %d\n", indent, "", "caretOffset", v->caretOffset);
-	Bprint(f, "%*s%s: %d\n", indent, "", "metricDataFormat", v->metricDataFormat);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numberOfHMetrics", v->numberOfHMetrics);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ascender", v->ascender);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "descender", v->descender);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "lineGap", v->lineGap);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "advanceWidthMax", v->advanceWidthMax);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "minLeftSideBearing", v->minLeftSideBearing);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "minRightSideBearing", v->minRightSideBearing);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xMaxExtent", v->xMaxExtent);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "caretSlopeRise", v->caretSlopeRise);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "caretSlopeRun", v->caretSlopeRun);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "caretOffset", v->caretOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "metricDataFormat", v->metricDataFormat);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numberOfHMetrics", v->numberOfHMetrics);
 	USED(o);
 }
 
@@ -1458,18 +1420,18 @@
 }
 
 void
-print_Glyf(Biobuf *f, int indent, Otf *o, Glyf *v)
+print_Glyf(Otfile *f, int indent, Otf *o, Glyf *v)
 {
-	Bprint(f, "%*s%s: %d\n", indent, "", "numberOfContours", v->numberOfContours);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xMin", v->xMin);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yMin", v->yMin);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xMax", v->xMax);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yMax", v->yMax);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "numberOfContours", v->numberOfContours);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xMin", v->xMin);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yMin", v->yMin);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xMax", v->xMax);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yMax", v->yMax);
 	if(v->component != nil){
-		Bprint(f, "%*s%s:\n", indent, "", "component");
+		f->print(f->aux, "%*s%s:\n", indent, "", "component");
 		print_ComponentGlyph(f, indent+indentΔ, o, v->component);
 	}else if(v->simple != nil){
-		Bprint(f, "%*s%s:\n", indent, "", "simple");
+		f->print(f->aux, "%*s%s:\n", indent, "", "simple");
 		print_SimpleGlyph(f, indent+indentΔ, o, v->simple);
 	}
 	USED(o);
@@ -1490,10 +1452,10 @@
 }
 
 void
-print_LongHorMetric(Biobuf *f, int indent, Otf *o, LongHorMetric *v)
+print_LongHorMetric(Otfile *f, int indent, Otf *o, LongHorMetric *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "advanceWidth", v->advanceWidth);
-	Bprint(f, "%*s%s: %d\n", indent, "", "lsb", v->lsb);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "advanceWidth", v->advanceWidth);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "lsb", v->lsb);
 	USED(o);
 }
 
@@ -1517,9 +1479,9 @@
 }
 
 void
-print_TableMaxp(Biobuf *f, int indent, Otf *o, TableMaxp *v)
+print_TableMaxp(Otfile *f, int indent, Otf *o, TableMaxp *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
 	USED(o);
 }
 
@@ -1543,14 +1505,14 @@
 }
 
 void
-print_TableHmtx(Biobuf *f, int indent, Otf *o, TableHmtx *v)
+print_TableHmtx(Otfile *f, int indent, Otf *o, TableHmtx *v)
 {
 	for(int i = 0; i < o->numberOfHMetrics; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "hMetrics", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "hMetrics", i);
 		print_LongHorMetric(f, indent+indentΔ, o, &v->hMetrics[i]);
 	}
 	for(int i = 0; i < (o->numGlyphs-o->numberOfHMetrics); i++)
-		Bprint(f, "%*s%s[%d]: %d\n", indent, "", "leftSideBearings", i, v->leftSideBearings[i]);
+		f->print(f->aux, "%*s%s[%d]: %d\n", indent, "", "leftSideBearings", i, v->leftSideBearings[i]);
 	USED(o);
 }
 
@@ -1576,12 +1538,12 @@
 }
 
 void
-print_TablePost(Biobuf *f, int indent, Otf *o, TablePost *v)
+print_TablePost(Otfile *f, int indent, Otf *o, TablePost *v)
 {
-	Bprint(f, "%*s%s: %g\n", indent, "", "italicAngle", v->italicAngle);
-	Bprint(f, "%*s%s: %d\n", indent, "", "underlinePosition", v->underlinePosition);
-	Bprint(f, "%*s%s: %d\n", indent, "", "underlineThickness", v->underlineThickness);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "isFixedPitch", v->isFixedPitch);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "italicAngle", v->italicAngle);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "underlinePosition", v->underlinePosition);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "underlineThickness", v->underlineThickness);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "isFixedPitch", v->isFixedPitch);
 	USED(o);
 }
 
@@ -1615,15 +1577,15 @@
 }
 
 void
-print_NameRecord(Biobuf *f, int indent, Otf *o, NameRecord *v)
+print_NameRecord(Otfile *f, int indent, Otf *o, NameRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "platformID", v->platformID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "encodingID", v->encodingID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "languageID", v->languageID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "nameID", v->nameID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "stringLength", v->stringLength);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "stringOffset", v->stringOffset);
-	Bprint(f, "%*s%s: %s\n", indent, "", "string", v->string);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "platformID", v->platformID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "encodingID", v->encodingID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "languageID", v->languageID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "nameID", v->nameID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "stringLength", v->stringLength);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "stringOffset", v->stringOffset);
+	f->print(f->aux, "%*s%s: %s\n", indent, "", "string", v->string);
 	USED(o);
 }
 
@@ -1652,11 +1614,11 @@
 }
 
 void
-print_LangTagRecord(Biobuf *f, int indent, Otf *o, LangTagRecord *v)
+print_LangTagRecord(Otfile *f, int indent, Otf *o, LangTagRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "langTagOffset", v->langTagOffset);
-	Bprint(f, "%*s%s: %s\n", indent, "", "langTag", v->langTag);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "langTagOffset", v->langTagOffset);
+	f->print(f->aux, "%*s%s: %s\n", indent, "", "langTag", v->langTag);
 	USED(o);
 }
 
@@ -1696,20 +1658,20 @@
 }
 
 void
-print_TableName(Biobuf *f, int indent, Otf *o, TableName *v)
+print_TableName(Otfile *f, int indent, Otf *o, TableName *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "count", v->count);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "storageOffset", v->storageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "version", v->version);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "count", v->count);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "storageOffset", v->storageOffset);
 	for(int i = 0; i < v->count; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "nameRecord", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "nameRecord", i);
 		print_NameRecord(f, indent+indentΔ, o, &v->nameRecord[i]);
 	}
 	if(v->version >= 1)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "langTagCount", v->langTagCount);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "langTagCount", v->langTagCount);
 	if(v->version >= 1){
 		for(int i = 0; i < v->langTagCount; i++){
-			Bprint(f, "%*s%s[%d]:\n", indent, "", "langTagRecord", i);
+			f->print(f->aux, "%*s%s[%d]:\n", indent, "", "langTagRecord", i);
 			print_LangTagRecord(f, indent+indentΔ, o, &v->langTagRecord[i]);
 		}
 	}
@@ -1737,16 +1699,16 @@
 }
 
 void
-print_BigGlyphMetrics(Biobuf *f, int indent, Otf *o, BigGlyphMetrics *v)
+print_BigGlyphMetrics(Otfile *f, int indent, Otf *o, BigGlyphMetrics *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "height", v->height);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "width", v->width);
-	Bprint(f, "%*s%s: %d\n", indent, "", "horiBearingX", v->horiBearingX);
-	Bprint(f, "%*s%s: %d\n", indent, "", "horiBearingY", v->horiBearingY);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "horiAdvance", v->horiAdvance);
-	Bprint(f, "%*s%s: %d\n", indent, "", "vertBearingX", v->vertBearingX);
-	Bprint(f, "%*s%s: %d\n", indent, "", "vertBearingY", v->vertBearingY);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "vertAdvance", v->vertAdvance);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "height", v->height);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "width", v->width);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "horiBearingX", v->horiBearingX);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "horiBearingY", v->horiBearingY);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "horiAdvance", v->horiAdvance);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "vertBearingX", v->vertBearingX);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "vertBearingY", v->vertBearingY);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "vertAdvance", v->vertAdvance);
 	USED(o);
 }
 
@@ -1768,13 +1730,13 @@
 }
 
 void
-print_SmallGlyphMetrics(Biobuf *f, int indent, Otf *o, SmallGlyphMetrics *v)
+print_SmallGlyphMetrics(Otfile *f, int indent, Otf *o, SmallGlyphMetrics *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "height", v->height);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "width", v->width);
-	Bprint(f, "%*s%s: %d\n", indent, "", "bearingX", v->bearingX);
-	Bprint(f, "%*s%s: %d\n", indent, "", "bearingY", v->bearingY);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "advance", v->advance);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "height", v->height);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "width", v->width);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "bearingX", v->bearingX);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "bearingY", v->bearingY);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "advance", v->advance);
 	USED(o);
 }
 
@@ -1801,18 +1763,18 @@
 }
 
 void
-print_SbitLineMetrics(Biobuf *f, int indent, Otf *o, SbitLineMetrics *v)
+print_SbitLineMetrics(Otfile *f, int indent, Otf *o, SbitLineMetrics *v)
 {
-	Bprint(f, "%*s%s: %d\n", indent, "", "ascender", v->ascender);
-	Bprint(f, "%*s%s: %d\n", indent, "", "descender", v->descender);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "widthMax", v->widthMax);
-	Bprint(f, "%*s%s: %d\n", indent, "", "caretSlopeNumerator", v->caretSlopeNumerator);
-	Bprint(f, "%*s%s: %d\n", indent, "", "caretSlopeDenumerator", v->caretSlopeDenumerator);
-	Bprint(f, "%*s%s: %d\n", indent, "", "caretOffset", v->caretOffset);
-	Bprint(f, "%*s%s: %d\n", indent, "", "minOriginSB", v->minOriginSB);
-	Bprint(f, "%*s%s: %d\n", indent, "", "minAdvanceSB", v->minAdvanceSB);
-	Bprint(f, "%*s%s: %d\n", indent, "", "maxBeforeBL", v->maxBeforeBL);
-	Bprint(f, "%*s%s: %d\n", indent, "", "minAfterBL", v->minAfterBL);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ascender", v->ascender);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "descender", v->descender);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "widthMax", v->widthMax);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "caretSlopeNumerator", v->caretSlopeNumerator);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "caretSlopeDenumerator", v->caretSlopeDenumerator);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "caretOffset", v->caretOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "minOriginSB", v->minOriginSB);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "minAdvanceSB", v->minAdvanceSB);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "maxBeforeBL", v->maxBeforeBL);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "minAfterBL", v->minAfterBL);
 	USED(o);
 }
 
@@ -1832,10 +1794,10 @@
 }
 
 void
-print_IndexSubtable1(Biobuf *f, int indent, Otf *o, IndexSubtable1 *v)
+print_IndexSubtable1(Otfile *f, int indent, Otf *o, IndexSubtable1 *v)
 {
 	for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "sbitOffsets", i, v->sbitOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "sbitOffsets", i, v->sbitOffsets[i]);
 	USED(o);
 }
 
@@ -1857,10 +1819,10 @@
 }
 
 void
-print_IndexSubtable2(Biobuf *f, int indent, Otf *o, IndexSubtable2 *v)
+print_IndexSubtable2(Otfile *f, int indent, Otf *o, IndexSubtable2 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
-	Bprint(f, "%*s%s:\n", indent, "", "bigMetrics");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
+	f->print(f->aux, "%*s%s:\n", indent, "", "bigMetrics");
 	print_BigGlyphMetrics(f, indent+indentΔ, o, &v->bigMetrics);
 	USED(o);
 }
@@ -1881,10 +1843,10 @@
 }
 
 void
-print_IndexSubtable3(Biobuf *f, int indent, Otf *o, IndexSubtable3 *v)
+print_IndexSubtable3(Otfile *f, int indent, Otf *o, IndexSubtable3 *v)
 {
 	for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "sbitOffsets", i, v->sbitOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "sbitOffsets", i, v->sbitOffsets[i]);
 	USED(o);
 }
 
@@ -1903,10 +1865,10 @@
 }
 
 void
-print_GlyphIdOffsetPair(Biobuf *f, int indent, Otf *o, GlyphIdOffsetPair *v)
+print_GlyphIdOffsetPair(Otfile *f, int indent, Otf *o, GlyphIdOffsetPair *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "sbitOffset", v->sbitOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "sbitOffset", v->sbitOffset);
 	USED(o);
 }
 
@@ -1928,11 +1890,11 @@
 }
 
 void
-print_IndexSubtable4(Biobuf *f, int indent, Otf *o, IndexSubtable4 *v)
+print_IndexSubtable4(Otfile *f, int indent, Otf *o, IndexSubtable4 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
 	for(int i = 0; i < (v->numGlyphs+1); i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "glyphArray", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "glyphArray", i);
 		print_GlyphIdOffsetPair(f, indent+indentΔ, o, &v->glyphArray[i]);
 	}
 	USED(o);
@@ -1964,14 +1926,14 @@
 }
 
 void
-print_IndexSubtable5(Biobuf *f, int indent, Otf *o, IndexSubtable5 *v)
+print_IndexSubtable5(Otfile *f, int indent, Otf *o, IndexSubtable5 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
-	Bprint(f, "%*s%s:\n", indent, "", "bigMetrics");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
+	f->print(f->aux, "%*s%s:\n", indent, "", "bigMetrics");
 	print_BigGlyphMetrics(f, indent+indentΔ, o, &v->bigMetrics);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
 	for(int i = 0; i < v->numGlyphs; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
 	USED(o);
 }
 
@@ -2025,29 +1987,29 @@
 }
 
 void
-print_IndexSubtable(Biobuf *f, int indent, Otf *o, IndexSubtable *v)
+print_IndexSubtable(Otfile *f, int indent, Otf *o, IndexSubtable *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "indexFormat", v->indexFormat);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "imageFormat", v->imageFormat);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "imageDataOffset", v->imageDataOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "indexFormat", v->indexFormat);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "imageFormat", v->imageFormat);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "imageDataOffset", v->imageDataOffset);
 	if(v->indexFormat == 1){
-		Bprint(f, "%*s%s:\n", indent, "", "sub1");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub1");
 		print_IndexSubtable1(f, indent+indentΔ, o, &v->sub1);
 	}
 	if(v->indexFormat == 2){
-		Bprint(f, "%*s%s:\n", indent, "", "sub2");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub2");
 		print_IndexSubtable2(f, indent+indentΔ, o, &v->sub2);
 	}
 	if(v->indexFormat == 3){
-		Bprint(f, "%*s%s:\n", indent, "", "sub3");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub3");
 		print_IndexSubtable3(f, indent+indentΔ, o, &v->sub3);
 	}
 	if(v->indexFormat == 4){
-		Bprint(f, "%*s%s:\n", indent, "", "sub4");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub4");
 		print_IndexSubtable4(f, indent+indentΔ, o, &v->sub4);
 	}
 	if(v->indexFormat == 5){
-		Bprint(f, "%*s%s:\n", indent, "", "sub5");
+		f->print(f->aux, "%*s%s:\n", indent, "", "sub5");
 		print_IndexSubtable5(f, indent+indentΔ, o, &v->sub5);
 	}
 	USED(o);
@@ -2082,12 +2044,12 @@
 }
 
 void
-print_IndexSubtableRecord(Biobuf *f, int indent, Otf *o, IndexSubtableRecord *v)
+print_IndexSubtableRecord(Otfile *f, int indent, Otf *o, IndexSubtableRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "firstGlyphIndex", v->firstGlyphIndex);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lastGlyphIndex", v->lastGlyphIndex);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "indexSubtableOffset", v->indexSubtableOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "indexSubtable");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "firstGlyphIndex", v->firstGlyphIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lastGlyphIndex", v->lastGlyphIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "indexSubtableOffset", v->indexSubtableOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "indexSubtable");
 	if(v->indexSubtable != nil)
 		print_IndexSubtable(f, indent+indentΔ, o, v->indexSubtable);
 	USED(o);
@@ -2135,23 +2097,23 @@
 }
 
 void
-print_BitmapSize(Biobuf *f, int indent, Otf *o, BitmapSize *v)
+print_BitmapSize(Otfile *f, int indent, Otf *o, BitmapSize *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "indexSubtableListOffset", v->indexSubtableListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "indexSubtableListSize", v->indexSubtableListSize);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numberOfIndexSubtables", v->numberOfIndexSubtables);
-	Bprint(f, "%*s%s:\n", indent, "", "hori");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "indexSubtableListOffset", v->indexSubtableListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "indexSubtableListSize", v->indexSubtableListSize);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numberOfIndexSubtables", v->numberOfIndexSubtables);
+	f->print(f->aux, "%*s%s:\n", indent, "", "hori");
 	print_SbitLineMetrics(f, indent+indentΔ, o, &v->hori);
-	Bprint(f, "%*s%s:\n", indent, "", "vert");
+	f->print(f->aux, "%*s%s:\n", indent, "", "vert");
 	print_SbitLineMetrics(f, indent+indentΔ, o, &v->vert);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startGlyphIndex", v->startGlyphIndex);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "endGlyphIndex", v->endGlyphIndex);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "ppemX", v->ppemX);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "ppemY", v->ppemY);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "bitDepth", v->bitDepth);
-	Bprint(f, "%*s%s: %#ux%s%s\n", indent, "", "flags", v->flags, (v->flags&BITMAPSIZE_FL_HORIZONTAL_METRICS)?" BITMAPSIZE_FL_HORIZONTAL_METRICS":"", (v->flags&BITMAPSIZE_FL_VERTICAL_METRICS)?" BITMAPSIZE_FL_VERTICAL_METRICS":"");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startGlyphIndex", v->startGlyphIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "endGlyphIndex", v->endGlyphIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "ppemX", v->ppemX);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "ppemY", v->ppemY);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "bitDepth", v->bitDepth);
+	f->print(f->aux, "%*s%s: %#ux%s%s\n", indent, "", "flags", v->flags, (v->flags&BITMAPSIZE_FL_HORIZONTAL_METRICS)?" BITMAPSIZE_FL_HORIZONTAL_METRICS":"", (v->flags&BITMAPSIZE_FL_VERTICAL_METRICS)?" BITMAPSIZE_FL_VERTICAL_METRICS":"");
 	for(int i = 0; i < v->numberOfIndexSubtables; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "indexSubtableList", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "indexSubtableList", i);
 		print_IndexSubtableRecord(f, indent+indentΔ, o, &v->indexSubtableList[i]);
 	}
 	USED(o);
@@ -2180,9 +2142,9 @@
 }
 
 void
-print_TableEBDT(Biobuf *f, int indent, Otf *o, TableEBDT *v)
+print_TableEBDT(Otfile *f, int indent, Otf *o, TableEBDT *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
 	USED(o);
 }
 
@@ -2214,11 +2176,11 @@
 }
 
 void
-print_TableEBLC(Biobuf *f, int indent, Otf *o, TableEBLC *v)
+print_TableEBLC(Otfile *f, int indent, Otf *o, TableEBLC *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numSizes", v->numSizes);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numSizes", v->numSizes);
 	for(int i = 0; i < v->numSizes; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "bitmapSizes", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "bitmapSizes", i);
 		print_BitmapSize(f, indent+indentΔ, o, &v->bitmapSizes[i]);
 	}
 	USED(o);
@@ -2244,12 +2206,12 @@
 }
 
 void
-print_AttachList(Biobuf *f, int indent, Otf *o, AttachList *v)
+print_AttachList(Otfile *f, int indent, Otf *o, AttachList *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
 	for(int i = 0; i < v->glyphCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "attachPointOffsets", i, v->attachPointOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "attachPointOffsets", i, v->attachPointOffsets[i]);
 	USED(o);
 }
 
@@ -2272,11 +2234,11 @@
 }
 
 void
-print_AttachPoint(Biobuf *f, int indent, Otf *o, AttachPoint *v)
+print_AttachPoint(Otfile *f, int indent, Otf *o, AttachPoint *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "pointCount", v->pointCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "pointCount", v->pointCount);
 	for(int i = 0; i < v->pointCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "pointIndices", i, v->pointIndices[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "pointIndices", i, v->pointIndices[i]);
 	USED(o);
 }
 
@@ -2300,12 +2262,12 @@
 }
 
 void
-print_LigCaretList(Biobuf *f, int indent, Otf *o, LigCaretList *v)
+print_LigCaretList(Otfile *f, int indent, Otf *o, LigCaretList *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "ligGlyphCount", v->ligGlyphCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "ligGlyphCount", v->ligGlyphCount);
 	for(int i = 0; i < v->ligGlyphCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "ligGlyphOffsets", i, v->ligGlyphOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "ligGlyphOffsets", i, v->ligGlyphOffsets[i]);
 	USED(o);
 }
 
@@ -2328,11 +2290,11 @@
 }
 
 void
-print_LigGlyph(Biobuf *f, int indent, Otf *o, LigGlyph *v)
+print_LigGlyph(Otfile *f, int indent, Otf *o, LigGlyph *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "caretCount", v->caretCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "caretCount", v->caretCount);
 	for(int i = 0; i < v->caretCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "caretValueOffsets", i, v->caretValueOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "caretValueOffsets", i, v->caretValueOffsets[i]);
 	USED(o);
 }
 
@@ -2369,15 +2331,15 @@
 }
 
 void
-print_CaretValue(Biobuf *f, int indent, Otf *o, CaretValue *v)
+print_CaretValue(Otfile *f, int indent, Otf *o, CaretValue *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "format", v->format);
 	if(v->format == 1 || v->format == 3)
-		Bprint(f, "%*s%s: %d\n", indent, "", "coordinate", v->coordinate);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "coordinate", v->coordinate);
 	if(v->format == 2)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "caretValuePointIndex", v->caretValuePointIndex);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "caretValuePointIndex", v->caretValuePointIndex);
 	if(v->format == 3)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
 	USED(o);
 }
 
@@ -2402,16 +2364,16 @@
 }
 
 void
-print_ValueRecord(Biobuf *f, int indent, Otf *o, ValueRecord *v)
+print_ValueRecord(Otfile *f, int indent, Otf *o, ValueRecord *v)
 {
-	Bprint(f, "%*s%s: %d\n", indent, "", "xPlacement", v->xPlacement);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yPlacement", v->yPlacement);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xAdvance", v->xAdvance);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yAdvance", v->yAdvance);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "xPlaDeviceOffset", v->xPlaDeviceOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "yPlaDeviceOffset", v->yPlaDeviceOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "xAdvDeviceOffset", v->xAdvDeviceOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "yAdvDeviceOffset", v->yAdvDeviceOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xPlacement", v->xPlacement);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yPlacement", v->yPlacement);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xAdvance", v->xAdvance);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yAdvance", v->yAdvance);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "xPlaDeviceOffset", v->xPlaDeviceOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "yPlaDeviceOffset", v->yPlaDeviceOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "xAdvDeviceOffset", v->xAdvDeviceOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "yAdvDeviceOffset", v->yAdvDeviceOffset);
 	USED(o);
 }
 
@@ -2452,20 +2414,20 @@
 }
 
 void
-print_SinglePos(Biobuf *f, int indent, Otf *o, SinglePos *v)
+print_SinglePos(Otfile *f, int indent, Otf *o, SinglePos *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "valueFormat", v->valueFormat);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "format", v->format);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "valueFormat", v->valueFormat);
 	if(v->format == 1){
-		Bprint(f, "%*s%s:\n", indent, "", "valueRecord");
+		f->print(f->aux, "%*s%s:\n", indent, "", "valueRecord");
 		print_ValueRecord(f, indent+indentΔ, o, &v->valueRecord);
 	}
 	if(v->format == 2)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "valueCount", v->valueCount);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "valueCount", v->valueCount);
 	if(v->format == 2){
 		for(int i = 0; i < v->valueCount; i++){
-			Bprint(f, "%*s%s[%d]:\n", indent, "", "valueRecords", i);
+			f->print(f->aux, "%*s%s[%d]:\n", indent, "", "valueRecords", i);
 			print_ValueRecord(f, indent+indentΔ, o, &v->valueRecords[i]);
 		}
 	}
@@ -2509,17 +2471,17 @@
 }
 
 void
-print_TableGDEF(Biobuf *f, int indent, Otf *o, TableGDEF *v)
+print_TableGDEF(Otfile *f, int indent, Otf *o, TableGDEF *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphClassDefOffset", v->glyphClassDefOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "attachListOffset", v->attachListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "ligCaretListOffset", v->ligCaretListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "markAttachClassDefOffset", v->markAttachClassDefOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphClassDefOffset", v->glyphClassDefOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "attachListOffset", v->attachListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "ligCaretListOffset", v->ligCaretListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "markAttachClassDefOffset", v->markAttachClassDefOffset);
 	if(v->minorVersion >= 2)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "markGlyphSetsDefOffset", v->markGlyphSetsDefOffset);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "markGlyphSetsDefOffset", v->markGlyphSetsDefOffset);
 	if(v->minorVersion >= 3)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "itemVarStoreOffset", v->itemVarStoreOffset);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "itemVarStoreOffset", v->itemVarStoreOffset);
 	USED(o);
 }
 
@@ -2543,12 +2505,12 @@
 }
 
 void
-print_LangSys(Biobuf *f, int indent, Otf *o, LangSys *v)
+print_LangSys(Otfile *f, int indent, Otf *o, LangSys *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "requiredFeatureIndex", v->requiredFeatureIndex);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "featureIndexCount", v->featureIndexCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "requiredFeatureIndex", v->requiredFeatureIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureIndexCount", v->featureIndexCount);
 	for(int i = 0; i < v->featureIndexCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "featureIndices", i, v->featureIndices[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "featureIndices", i, v->featureIndices[i]);
 	USED(o);
 }
 
@@ -2578,11 +2540,11 @@
 }
 
 void
-print_LangSysRecord(Biobuf *f, int indent, Otf *o, LangSysRecord *v)
+print_LangSysRecord(Otfile *f, int indent, Otf *o, LangSysRecord *v)
 {
-	Bprint(f, "%*s%s: %t\n", indent, "", "langSysTag", v->langSysTag);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "langSysOffset", v->langSysOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "langSys");
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "langSysTag", v->langSysTag>>24, v->langSysTag>>16, v->langSysTag>>8, v->langSysTag>>0);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "langSysOffset", v->langSysOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "langSys");
 	if(v->langSys != nil)
 		print_LangSys(f, indent+indentΔ, o, v->langSys);
 	USED(o);
@@ -2618,15 +2580,15 @@
 }
 
 void
-print_Script(Biobuf *f, int indent, Otf *o, Script *v)
+print_Script(Otfile *f, int indent, Otf *o, Script *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "defaultLangSysOffset", v->defaultLangSysOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "langSysCount", v->langSysCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "defaultLangSysOffset", v->defaultLangSysOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "langSysCount", v->langSysCount);
 	for(int i = 0; i < v->langSysCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "langSysRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "langSysRecords", i);
 		print_LangSysRecord(f, indent+indentΔ, o, &v->langSysRecords[i]);
 	}
-	Bprint(f, "%*s%s:\n", indent, "", "defaultLangSys");
+	f->print(f->aux, "%*s%s:\n", indent, "", "defaultLangSys");
 	if(v->defaultLangSys != nil)
 		print_LangSys(f, indent+indentΔ, o, v->defaultLangSys);
 	USED(o);
@@ -2658,11 +2620,11 @@
 }
 
 void
-print_ScriptRecord(Biobuf *f, int indent, Otf *o, ScriptRecord *v)
+print_ScriptRecord(Otfile *f, int indent, Otf *o, ScriptRecord *v)
 {
-	Bprint(f, "%*s%s: %t\n", indent, "", "scriptTag", v->scriptTag);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "scriptOffset", v->scriptOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "script");
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "scriptTag", v->scriptTag>>24, v->scriptTag>>16, v->scriptTag>>8, v->scriptTag>>0);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "scriptOffset", v->scriptOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "script");
 	if(v->script != nil)
 		print_Script(f, indent+indentΔ, o, v->script);
 	USED(o);
@@ -2686,11 +2648,11 @@
 }
 
 void
-print_ScriptList(Biobuf *f, int indent, Otf *o, ScriptList *v)
+print_ScriptList(Otfile *f, int indent, Otf *o, ScriptList *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "scriptCount", v->scriptCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "scriptCount", v->scriptCount);
 	for(int i = 0; i < v->scriptCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "scriptRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "scriptRecords", i);
 		print_ScriptRecord(f, indent+indentΔ, o, &v->scriptRecords[i]);
 	}
 	USED(o);
@@ -2716,12 +2678,12 @@
 }
 
 void
-print_Feature(Biobuf *f, int indent, Otf *o, Feature *v)
+print_Feature(Otfile *f, int indent, Otf *o, Feature *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "featureParamsOffset", v->featureParamsOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lookupIndexCount", v->lookupIndexCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureParamsOffset", v->featureParamsOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lookupIndexCount", v->lookupIndexCount);
 	for(int i = 0; i < v->lookupIndexCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "lookupListIndices", i, v->lookupListIndices[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "lookupListIndices", i, v->lookupListIndices[i]);
 	USED(o);
 }
 
@@ -2751,11 +2713,11 @@
 }
 
 void
-print_FeatureRecord(Biobuf *f, int indent, Otf *o, FeatureRecord *v)
+print_FeatureRecord(Otfile *f, int indent, Otf *o, FeatureRecord *v)
 {
-	Bprint(f, "%*s%s: %t\n", indent, "", "featureTag", v->featureTag);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "featureOffset", v->featureOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "feature");
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "featureTag", v->featureTag>>24, v->featureTag>>16, v->featureTag>>8, v->featureTag>>0);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureOffset", v->featureOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "feature");
 	if(v->feature != nil)
 		print_Feature(f, indent+indentΔ, o, v->feature);
 	USED(o);
@@ -2779,11 +2741,11 @@
 }
 
 void
-print_FeatureList(Biobuf *f, int indent, Otf *o, FeatureList *v)
+print_FeatureList(Otfile *f, int indent, Otf *o, FeatureList *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "featureCount", v->featureCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureCount", v->featureCount);
 	for(int i = 0; i < v->featureCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "featureRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "featureRecords", i);
 		print_FeatureRecord(f, indent+indentΔ, o, &v->featureRecords[i]);
 	}
 	USED(o);
@@ -2813,14 +2775,14 @@
 }
 
 void
-print_Lookup(Biobuf *f, int indent, Otf *o, Lookup *v)
+print_Lookup(Otfile *f, int indent, Otf *o, Lookup *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lookupType", v->lookupType);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lookupFlag", v->lookupFlag);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "subTableCount", v->subTableCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lookupType", v->lookupType);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lookupFlag", v->lookupFlag);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "subTableCount", v->subTableCount);
 	for(int i = 0; i < v->subTableCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "subtableOffsets", i, v->subtableOffsets[i]);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "markFilteringSet", v->markFilteringSet);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "subtableOffsets", i, v->subtableOffsets[i]);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "markFilteringSet", v->markFilteringSet);
 	USED(o);
 }
 
@@ -2843,11 +2805,11 @@
 }
 
 void
-print_LookupList(Biobuf *f, int indent, Otf *o, LookupList *v)
+print_LookupList(Otfile *f, int indent, Otf *o, LookupList *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lookupCount", v->lookupCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lookupCount", v->lookupCount);
 	for(int i = 0; i < v->lookupCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "lookupOffsets", i, v->lookupOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "lookupOffsets", i, v->lookupOffsets[i]);
 	USED(o);
 }
 
@@ -2915,21 +2877,21 @@
 }
 
 void
-print_TableGPOS(Biobuf *f, int indent, Otf *o, TableGPOS *v)
+print_TableGPOS(Otfile *f, int indent, Otf *o, TableGPOS *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "scriptListOffset", v->scriptListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "featureListOffset", v->featureListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lookupListOffset", v->lookupListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "scriptListOffset", v->scriptListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureListOffset", v->featureListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lookupListOffset", v->lookupListOffset);
 	if(v->minorVersion == 1)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "scriptList");
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "scriptList");
 	if(v->scriptList != nil)
 		print_ScriptList(f, indent+indentΔ, o, v->scriptList);
-	Bprint(f, "%*s%s:\n", indent, "", "featureList");
+	f->print(f->aux, "%*s%s:\n", indent, "", "featureList");
 	if(v->featureList != nil)
 		print_FeatureList(f, indent+indentΔ, o, v->featureList);
-	Bprint(f, "%*s%s:\n", indent, "", "lookupList");
+	f->print(f->aux, "%*s%s:\n", indent, "", "lookupList");
 	if(v->lookupList != nil)
 		print_LookupList(f, indent+indentΔ, o, v->lookupList);
 	USED(o);
@@ -2988,18 +2950,18 @@
 }
 
 void
-print_TableGSUB(Biobuf *f, int indent, Otf *o, TableGSUB *v)
+print_TableGSUB(Otfile *f, int indent, Otf *o, TableGSUB *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "scriptListOffset", v->scriptListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "featureListOffset", v->featureListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lookupListOffset", v->lookupListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "scriptListOffset", v->scriptListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureListOffset", v->featureListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lookupListOffset", v->lookupListOffset);
 	if(v->minorVersion == 1)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "scriptList");
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "scriptList");
 	if(v->scriptList != nil)
 		print_ScriptList(f, indent+indentΔ, o, v->scriptList);
-	Bprint(f, "%*s%s:\n", indent, "", "featureList");
+	f->print(f->aux, "%*s%s:\n", indent, "", "featureList");
 	if(v->featureList != nil)
 		print_FeatureList(f, indent+indentΔ, o, v->featureList);
 	USED(o);
@@ -3020,10 +2982,10 @@
 }
 
 void
-print_MathValueRecord(Biobuf *f, int indent, Otf *o, MathValueRecord *v)
+print_MathValueRecord(Otfile *f, int indent, Otf *o, MathValueRecord *v)
 {
-	Bprint(f, "%*s%s: %d\n", indent, "", "value", v->value);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "value", v->value);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
 	USED(o);
 }
 
@@ -3251,115 +3213,115 @@
 }
 
 void
-print_MathConstants(Biobuf *f, int indent, Otf *o, MathConstants *v)
+print_MathConstants(Otfile *f, int indent, Otf *o, MathConstants *v)
 {
-	Bprint(f, "%*s%s: %d\n", indent, "", "scriptPercentScaleDown", v->scriptPercentScaleDown);
-	Bprint(f, "%*s%s: %d\n", indent, "", "scriptScriptPercentScaleDown", v->scriptScriptPercentScaleDown);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "delimitedSubFormulaMinHeight", v->delimitedSubFormulaMinHeight);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "displayOperatorMinHeight", v->displayOperatorMinHeight);
-	Bprint(f, "%*s%s:\n", indent, "", "mathLeading");
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "scriptPercentScaleDown", v->scriptPercentScaleDown);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "scriptScriptPercentScaleDown", v->scriptScriptPercentScaleDown);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "delimitedSubFormulaMinHeight", v->delimitedSubFormulaMinHeight);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "displayOperatorMinHeight", v->displayOperatorMinHeight);
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathLeading");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->mathLeading);
-	Bprint(f, "%*s%s:\n", indent, "", "axisHeight");
+	f->print(f->aux, "%*s%s:\n", indent, "", "axisHeight");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->axisHeight);
-	Bprint(f, "%*s%s:\n", indent, "", "accentBaseHeight");
+	f->print(f->aux, "%*s%s:\n", indent, "", "accentBaseHeight");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->accentBaseHeight);
-	Bprint(f, "%*s%s:\n", indent, "", "flattenedAccentBaseHeight");
+	f->print(f->aux, "%*s%s:\n", indent, "", "flattenedAccentBaseHeight");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->flattenedAccentBaseHeight);
-	Bprint(f, "%*s%s:\n", indent, "", "subscriptShiftDown");
+	f->print(f->aux, "%*s%s:\n", indent, "", "subscriptShiftDown");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptShiftDown);
-	Bprint(f, "%*s%s:\n", indent, "", "subscriptTopMax");
+	f->print(f->aux, "%*s%s:\n", indent, "", "subscriptTopMax");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptTopMax);
-	Bprint(f, "%*s%s:\n", indent, "", "subscriptBaselineDropMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "subscriptBaselineDropMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptBaselineDropMin);
-	Bprint(f, "%*s%s:\n", indent, "", "superscriptShiftUp");
+	f->print(f->aux, "%*s%s:\n", indent, "", "superscriptShiftUp");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptShiftUp);
-	Bprint(f, "%*s%s:\n", indent, "", "superscriptShiftUpCramped");
+	f->print(f->aux, "%*s%s:\n", indent, "", "superscriptShiftUpCramped");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptShiftUpCramped);
-	Bprint(f, "%*s%s:\n", indent, "", "superscriptBottomMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "superscriptBottomMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBottomMin);
-	Bprint(f, "%*s%s:\n", indent, "", "superscriptBaselineDropMax");
+	f->print(f->aux, "%*s%s:\n", indent, "", "superscriptBaselineDropMax");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBaselineDropMax);
-	Bprint(f, "%*s%s:\n", indent, "", "subSuperscriptGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "subSuperscriptGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->subSuperscriptGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "superscriptBottomMaxWithSubscript");
+	f->print(f->aux, "%*s%s:\n", indent, "", "superscriptBottomMaxWithSubscript");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBottomMaxWithSubscript);
-	Bprint(f, "%*s%s:\n", indent, "", "spaceAfterScript");
+	f->print(f->aux, "%*s%s:\n", indent, "", "spaceAfterScript");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->spaceAfterScript);
-	Bprint(f, "%*s%s:\n", indent, "", "upperLimitGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "upperLimitGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->upperLimitGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "upperLimitBaselineRiseMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "upperLimitBaselineRiseMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->upperLimitBaselineRiseMin);
-	Bprint(f, "%*s%s:\n", indent, "", "lowerLimitGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "lowerLimitGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->lowerLimitGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "lowerLimitBaselineDropMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "lowerLimitBaselineDropMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->lowerLimitBaselineDropMin);
-	Bprint(f, "%*s%s:\n", indent, "", "stackTopShiftUp");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stackTopShiftUp");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stackTopShiftUp);
-	Bprint(f, "%*s%s:\n", indent, "", "stackTopDisplayStyleShiftUp");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stackTopDisplayStyleShiftUp");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stackTopDisplayStyleShiftUp);
-	Bprint(f, "%*s%s:\n", indent, "", "stackBottomShiftDown");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stackBottomShiftDown");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stackBottomShiftDown);
-	Bprint(f, "%*s%s:\n", indent, "", "stackBottomDisplayStyleShiftDown");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stackBottomDisplayStyleShiftDown");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stackBottomDisplayStyleShiftDown);
-	Bprint(f, "%*s%s:\n", indent, "", "stackGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stackGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stackGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "stackDisplayStyleGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stackDisplayStyleGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stackDisplayStyleGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "stretchStackTopShiftUp");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stretchStackTopShiftUp");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackTopShiftUp);
-	Bprint(f, "%*s%s:\n", indent, "", "stretchStackBottomShiftDown");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stretchStackBottomShiftDown");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackBottomShiftDown);
-	Bprint(f, "%*s%s:\n", indent, "", "stretchStackGapAboveMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stretchStackGapAboveMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackGapAboveMin);
-	Bprint(f, "%*s%s:\n", indent, "", "stretchStackGapBelowMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "stretchStackGapBelowMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackGapBelowMin);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorShiftUp");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionNumeratorShiftUp");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorShiftUp);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorDisplayStyleShiftUp");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionNumeratorDisplayStyleShiftUp");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorDisplayStyleShiftUp);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorShiftDown");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionDenominatorShiftDown");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorShiftDown);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorDisplayStyleShiftDown");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionDenominatorDisplayStyleShiftDown");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorDisplayStyleShiftDown);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionNumeratorGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionNumDisplayStyleGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionNumDisplayStyleGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumDisplayStyleGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionRuleThickness");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionRuleThickness");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionRuleThickness);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionDenominatorGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "fractionDenomDisplayStyleGapMin");
+	f->print(f->aux, "%*s%s:\n", indent, "", "fractionDenomDisplayStyleGapMin");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenomDisplayStyleGapMin);
-	Bprint(f, "%*s%s:\n", indent, "", "skewedFractionHorizontalGap");
+	f->print(f->aux, "%*s%s:\n", indent, "", "skewedFractionHorizontalGap");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->skewedFractionHorizontalGap);
-	Bprint(f, "%*s%s:\n", indent, "", "skewedFractionVerticalGap");
+	f->print(f->aux, "%*s%s:\n", indent, "", "skewedFractionVerticalGap");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->skewedFractionVerticalGap);
-	Bprint(f, "%*s%s:\n", indent, "", "overbarVerticalGap");
+	f->print(f->aux, "%*s%s:\n", indent, "", "overbarVerticalGap");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->overbarVerticalGap);
-	Bprint(f, "%*s%s:\n", indent, "", "overbarRuleThickness");
+	f->print(f->aux, "%*s%s:\n", indent, "", "overbarRuleThickness");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->overbarRuleThickness);
-	Bprint(f, "%*s%s:\n", indent, "", "overbarExtraAscender");
+	f->print(f->aux, "%*s%s:\n", indent, "", "overbarExtraAscender");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->overbarExtraAscender);
-	Bprint(f, "%*s%s:\n", indent, "", "underbarVerticalGap");
+	f->print(f->aux, "%*s%s:\n", indent, "", "underbarVerticalGap");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->underbarVerticalGap);
-	Bprint(f, "%*s%s:\n", indent, "", "underbarRuleThickness");
+	f->print(f->aux, "%*s%s:\n", indent, "", "underbarRuleThickness");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->underbarRuleThickness);
-	Bprint(f, "%*s%s:\n", indent, "", "underbarExtraDescender");
+	f->print(f->aux, "%*s%s:\n", indent, "", "underbarExtraDescender");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->underbarExtraDescender);
-	Bprint(f, "%*s%s:\n", indent, "", "radicalVerticalGap");
+	f->print(f->aux, "%*s%s:\n", indent, "", "radicalVerticalGap");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->radicalVerticalGap);
-	Bprint(f, "%*s%s:\n", indent, "", "radicalDisplayStyleVerticalGap");
+	f->print(f->aux, "%*s%s:\n", indent, "", "radicalDisplayStyleVerticalGap");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->radicalDisplayStyleVerticalGap);
-	Bprint(f, "%*s%s:\n", indent, "", "radicalRuleThickness");
+	f->print(f->aux, "%*s%s:\n", indent, "", "radicalRuleThickness");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->radicalRuleThickness);
-	Bprint(f, "%*s%s:\n", indent, "", "radicalExtraAscender");
+	f->print(f->aux, "%*s%s:\n", indent, "", "radicalExtraAscender");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->radicalExtraAscender);
-	Bprint(f, "%*s%s:\n", indent, "", "radicalKernBeforeDegree");
+	f->print(f->aux, "%*s%s:\n", indent, "", "radicalKernBeforeDegree");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->radicalKernBeforeDegree);
-	Bprint(f, "%*s%s:\n", indent, "", "radicalKernAfterDegree");
+	f->print(f->aux, "%*s%s:\n", indent, "", "radicalKernAfterDegree");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->radicalKernAfterDegree);
-	Bprint(f, "%*s%s: %d\n", indent, "", "radicalDegreeBottomRaisePercent", v->radicalDegreeBottomRaisePercent);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "radicalDegreeBottomRaisePercent", v->radicalDegreeBottomRaisePercent);
 	USED(o);
 }
 
@@ -3382,12 +3344,12 @@
 }
 
 void
-print_MathItalicsCorrectionInfo(Biobuf *f, int indent, Otf *o, MathItalicsCorrectionInfo *v)
+print_MathItalicsCorrectionInfo(Otfile *f, int indent, Otf *o, MathItalicsCorrectionInfo *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "italicsCorrectionCoverageOffset", v->italicsCorrectionCoverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "italicsCorrectionCount", v->italicsCorrectionCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "italicsCorrectionCoverageOffset", v->italicsCorrectionCoverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "italicsCorrectionCount", v->italicsCorrectionCount);
 	for(int i = 0; i < v->italicsCorrectionCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "italicsCorrection", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "italicsCorrection", i);
 		print_MathValueRecord(f, indent+indentΔ, o, &v->italicsCorrection[i]);
 	}
 	USED(o);
@@ -3412,12 +3374,12 @@
 }
 
 void
-print_MathTopAccentAttachment(Biobuf *f, int indent, Otf *o, MathTopAccentAttachment *v)
+print_MathTopAccentAttachment(Otfile *f, int indent, Otf *o, MathTopAccentAttachment *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "topAccentCoverageOffset", v->topAccentCoverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "topAccentAttachmentCount", v->topAccentAttachmentCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "topAccentCoverageOffset", v->topAccentCoverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "topAccentAttachmentCount", v->topAccentAttachmentCount);
 	for(int i = 0; i < v->topAccentAttachmentCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "topAccentAttachment", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "topAccentAttachment", i);
 		print_MathValueRecord(f, indent+indentΔ, o, &v->topAccentAttachment[i]);
 	}
 	USED(o);
@@ -3440,12 +3402,12 @@
 }
 
 void
-print_MathKernInfoRecord(Biobuf *f, int indent, Otf *o, MathKernInfoRecord *v)
+print_MathKernInfoRecord(Otfile *f, int indent, Otf *o, MathKernInfoRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "topRightMathKernOffset", v->topRightMathKernOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "topLeftMathKernOffset", v->topLeftMathKernOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "bottomRightMathKernOffset", v->bottomRightMathKernOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "bottomLeftMathKernOffset", v->bottomLeftMathKernOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "topRightMathKernOffset", v->topRightMathKernOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "topLeftMathKernOffset", v->topLeftMathKernOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "bottomRightMathKernOffset", v->bottomRightMathKernOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "bottomLeftMathKernOffset", v->bottomLeftMathKernOffset);
 	USED(o);
 }
 
@@ -3468,12 +3430,12 @@
 }
 
 void
-print_MathKernInfo(Biobuf *f, int indent, Otf *o, MathKernInfo *v)
+print_MathKernInfo(Otfile *f, int indent, Otf *o, MathKernInfo *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathKernCoverageOffset", v->mathKernCoverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathKernCount", v->mathKernCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathKernCoverageOffset", v->mathKernCoverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathKernCount", v->mathKernCount);
 	for(int i = 0; i < v->mathKernCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "mathKernInfoRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "mathKernInfoRecords", i);
 		print_MathKernInfoRecord(f, indent+indentΔ, o, &v->mathKernInfoRecords[i]);
 	}
 	USED(o);
@@ -3501,15 +3463,15 @@
 }
 
 void
-print_MathKern(Biobuf *f, int indent, Otf *o, MathKern *v)
+print_MathKern(Otfile *f, int indent, Otf *o, MathKern *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "heightCount", v->heightCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "heightCount", v->heightCount);
 	for(int i = 0; i < v->heightCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "correctionHeight", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "correctionHeight", i);
 		print_MathValueRecord(f, indent+indentΔ, o, &v->correctionHeight[i]);
 	}
 	for(int i = 0; i < v->heightCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "kernValues", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "kernValues", i);
 		print_MathValueRecord(f, indent+indentΔ, o, &v->kernValues[i]);
 	}
 	USED(o);
@@ -3534,11 +3496,11 @@
 }
 
 void
-print_Coverage1(Biobuf *f, int indent, Otf *o, Coverage1 *v)
+print_Coverage1(Otfile *f, int indent, Otf *o, Coverage1 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
 	for(int i = 0; i < v->glyphCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphArray", i, v->glyphArray[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "glyphArray", i, v->glyphArray[i]);
 	USED(o);
 }
 
@@ -3558,11 +3520,11 @@
 }
 
 void
-print_RangeRecord(Biobuf *f, int indent, Otf *o, RangeRecord *v)
+print_RangeRecord(Otfile *f, int indent, Otf *o, RangeRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startGlyphID", v->startGlyphID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "endGlyphID", v->endGlyphID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startCoverageIndex", v->startCoverageIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startGlyphID", v->startGlyphID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "endGlyphID", v->endGlyphID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startCoverageIndex", v->startCoverageIndex);
 	USED(o);
 }
 
@@ -3584,11 +3546,11 @@
 }
 
 void
-print_Coverage2(Biobuf *f, int indent, Otf *o, Coverage2 *v)
+print_Coverage2(Otfile *f, int indent, Otf *o, Coverage2 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rangeCount", v->rangeCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rangeCount", v->rangeCount);
 	for(int i = 0; i < v->rangeCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "rangeRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "rangeRecords", i);
 		print_RangeRecord(f, indent+indentΔ, o, &v->rangeRecords[i]);
 	}
 	USED(o);
@@ -3624,15 +3586,15 @@
 }
 
 void
-print_Coverage(Biobuf *f, int indent, Otf *o, Coverage *v)
+print_Coverage(Otfile *f, int indent, Otf *o, Coverage *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "format", v->format);
 	if(v->format == 1){
-		Bprint(f, "%*s%s:\n", indent, "", "cov1");
+		f->print(f->aux, "%*s%s:\n", indent, "", "cov1");
 		print_Coverage1(f, indent+indentΔ, o, &v->cov1);
 	}
 	if(v->format == 2){
-		Bprint(f, "%*s%s:\n", indent, "", "cov2");
+		f->print(f->aux, "%*s%s:\n", indent, "", "cov2");
 		print_Coverage2(f, indent+indentΔ, o, &v->cov2);
 	}
 	USED(o);
@@ -3688,21 +3650,21 @@
 }
 
 void
-print_MathVariants(Biobuf *f, int indent, Otf *o, MathVariants *v)
+print_MathVariants(Otfile *f, int indent, Otf *o, MathVariants *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "minConnectorOverlap", v->minConnectorOverlap);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "vertGlyphCoverageOffset", v->vertGlyphCoverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "horizGlyphCoverageOffset", v->horizGlyphCoverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "vertGlyphCount", v->vertGlyphCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "horizGlyphCount", v->horizGlyphCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "minConnectorOverlap", v->minConnectorOverlap);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "vertGlyphCoverageOffset", v->vertGlyphCoverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "horizGlyphCoverageOffset", v->horizGlyphCoverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "vertGlyphCount", v->vertGlyphCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "horizGlyphCount", v->horizGlyphCount);
 	for(int i = 0; i < v->vertGlyphCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "vertGlyphConstructionOffsets", i, v->vertGlyphConstructionOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "vertGlyphConstructionOffsets", i, v->vertGlyphConstructionOffsets[i]);
 	for(int i = 0; i < v->horizGlyphCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "horizGlyphConstructionOffsets", i, v->horizGlyphConstructionOffsets[i]);
-	Bprint(f, "%*s%s:\n", indent, "", "vertGlyphCoverage");
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "horizGlyphConstructionOffsets", i, v->horizGlyphConstructionOffsets[i]);
+	f->print(f->aux, "%*s%s:\n", indent, "", "vertGlyphCoverage");
 	if(v->vertGlyphCoverage != nil)
 		print_Coverage(f, indent+indentΔ, o, v->vertGlyphCoverage);
-	Bprint(f, "%*s%s:\n", indent, "", "horizGlyphCoverage");
+	f->print(f->aux, "%*s%s:\n", indent, "", "horizGlyphCoverage");
 	if(v->horizGlyphCoverage != nil)
 		print_Coverage(f, indent+indentΔ, o, v->horizGlyphCoverage);
 	USED(o);
@@ -3769,22 +3731,22 @@
 }
 
 void
-print_MathGlyphInfo(Biobuf *f, int indent, Otf *o, MathGlyphInfo *v)
+print_MathGlyphInfo(Otfile *f, int indent, Otf *o, MathGlyphInfo *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathItalicsCorrectionInfoOffset", v->mathItalicsCorrectionInfoOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathTopAccentAttachmentOffset", v->mathTopAccentAttachmentOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "extendedShapeCoverageOffset", v->extendedShapeCoverageOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathKernInfoOffset", v->mathKernInfoOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "mathItalicsCorrectionInfo");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathItalicsCorrectionInfoOffset", v->mathItalicsCorrectionInfoOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathTopAccentAttachmentOffset", v->mathTopAccentAttachmentOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "extendedShapeCoverageOffset", v->extendedShapeCoverageOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathKernInfoOffset", v->mathKernInfoOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathItalicsCorrectionInfo");
 	if(v->mathItalicsCorrectionInfo != nil)
 		print_MathItalicsCorrectionInfo(f, indent+indentΔ, o, v->mathItalicsCorrectionInfo);
-	Bprint(f, "%*s%s:\n", indent, "", "mathTopAccentAttachment");
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathTopAccentAttachment");
 	if(v->mathTopAccentAttachment != nil)
 		print_MathTopAccentAttachment(f, indent+indentΔ, o, v->mathTopAccentAttachment);
-	Bprint(f, "%*s%s:\n", indent, "", "mathKernInfo");
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathKernInfo");
 	if(v->mathKernInfo != nil)
 		print_MathKernInfo(f, indent+indentΔ, o, v->mathKernInfo);
-	Bprint(f, "%*s%s:\n", indent, "", "extendedShapeCoverage");
+	f->print(f->aux, "%*s%s:\n", indent, "", "extendedShapeCoverage");
 	if(v->extendedShapeCoverage != nil)
 		print_Coverage(f, indent+indentΔ, o, v->extendedShapeCoverage);
 	USED(o);
@@ -3805,10 +3767,10 @@
 }
 
 void
-print_MathGlyphVariantRecord(Biobuf *f, int indent, Otf *o, MathGlyphVariantRecord *v)
+print_MathGlyphVariantRecord(Otfile *f, int indent, Otf *o, MathGlyphVariantRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "variantGlyph", v->variantGlyph);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "advanceMeasurement", v->advanceMeasurement);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "variantGlyph", v->variantGlyph);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "advanceMeasurement", v->advanceMeasurement);
 	USED(o);
 }
 
@@ -3830,13 +3792,13 @@
 }
 
 void
-print_GlyphPart(Biobuf *f, int indent, Otf *o, GlyphPart *v)
+print_GlyphPart(Otfile *f, int indent, Otf *o, GlyphPart *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "startConnectorLength", v->startConnectorLength);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "endConnectorLength", v->endConnectorLength);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "fullAdvance", v->fullAdvance);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "partFlags", v->partFlags);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "startConnectorLength", v->startConnectorLength);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "endConnectorLength", v->endConnectorLength);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "fullAdvance", v->fullAdvance);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "partFlags", v->partFlags);
 	USED(o);
 }
 
@@ -3862,13 +3824,13 @@
 }
 
 void
-print_GlyphAssembly(Biobuf *f, int indent, Otf *o, GlyphAssembly *v)
+print_GlyphAssembly(Otfile *f, int indent, Otf *o, GlyphAssembly *v)
 {
-	Bprint(f, "%*s%s:\n", indent, "", "italicsCorrection");
+	f->print(f->aux, "%*s%s:\n", indent, "", "italicsCorrection");
 	print_MathValueRecord(f, indent+indentΔ, o, &v->italicsCorrection);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "partCount", v->partCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "partCount", v->partCount);
 	for(int i = 0; i < v->partCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "partRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "partRecords", i);
 		print_GlyphPart(f, indent+indentΔ, o, &v->partRecords[i]);
 	}
 	USED(o);
@@ -3904,15 +3866,15 @@
 }
 
 void
-print_MathGlyphConstruction(Biobuf *f, int indent, Otf *o, MathGlyphConstruction *v)
+print_MathGlyphConstruction(Otfile *f, int indent, Otf *o, MathGlyphConstruction *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphAssemblyOffset", v->glyphAssemblyOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "variantCount", v->variantCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphAssemblyOffset", v->glyphAssemblyOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "variantCount", v->variantCount);
 	for(int i = 0; i < v->variantCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "mathGlyphVariantRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "mathGlyphVariantRecords", i);
 		print_MathGlyphVariantRecord(f, indent+indentΔ, o, &v->mathGlyphVariantRecords[i]);
 	}
-	Bprint(f, "%*s%s:\n", indent, "", "glyphAssembly");
+	f->print(f->aux, "%*s%s:\n", indent, "", "glyphAssembly");
 	if(v->glyphAssembly != nil)
 		print_GlyphAssembly(f, indent+indentΔ, o, v->glyphAssembly);
 	USED(o);
@@ -3977,18 +3939,18 @@
 }
 
 void
-print_TableMATH(Biobuf *f, int indent, Otf *o, TableMATH *v)
+print_TableMATH(Otfile *f, int indent, Otf *o, TableMATH *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathConstantsOffset", v->mathConstantsOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathGlyphInfoOffset", v->mathGlyphInfoOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mathVariantsOffset", v->mathVariantsOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "mathConstants");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathConstantsOffset", v->mathConstantsOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathGlyphInfoOffset", v->mathGlyphInfoOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mathVariantsOffset", v->mathVariantsOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathConstants");
 	if(v->mathConstants != nil)
 		print_MathConstants(f, indent+indentΔ, o, v->mathConstants);
-	Bprint(f, "%*s%s:\n", indent, "", "mathGlyphInfo");
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathGlyphInfo");
 	if(v->mathGlyphInfo != nil)
 		print_MathGlyphInfo(f, indent+indentΔ, o, v->mathGlyphInfo);
-	Bprint(f, "%*s%s:\n", indent, "", "mathVariants");
+	f->print(f->aux, "%*s%s:\n", indent, "", "mathVariants");
 	if(v->mathVariants != nil)
 		print_MathVariants(f, indent+indentΔ, o, v->mathVariants);
 	USED(o);
@@ -4010,11 +3972,11 @@
 }
 
 void
-print_KernPair(Biobuf *f, int indent, Otf *o, KernPair *v)
+print_KernPair(Otfile *f, int indent, Otf *o, KernPair *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "left", v->left);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "right", v->right);
-	Bprint(f, "%*s%s: %d\n", indent, "", "value", v->value);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "left", v->left);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "right", v->right);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "value", v->value);
 	USED(o);
 }
 
@@ -4039,14 +4001,14 @@
 }
 
 void
-print_KernSubtable0(Biobuf *f, int indent, Otf *o, KernSubtable0 *v)
+print_KernSubtable0(Otfile *f, int indent, Otf *o, KernSubtable0 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "nPairs", v->nPairs);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "nPairs", v->nPairs);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
 	for(int i = 0; i < v->nPairs; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "kernPairs", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "kernPairs", i);
 		print_KernPair(f, indent+indentΔ, o, &v->kernPairs[i]);
 	}
 	USED(o);
@@ -4072,12 +4034,12 @@
 }
 
 void
-print_KernClass(Biobuf *f, int indent, Otf *o, KernClass *v)
+print_KernClass(Otfile *f, int indent, Otf *o, KernClass *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "firstGlyph", v->firstGlyph);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "nGlyphs", v->nGlyphs);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "firstGlyph", v->firstGlyph);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "nGlyphs", v->nGlyphs);
 	for(int i = 0; i < v->nGlyphs; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "values", i, v->values[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "values", i, v->values[i]);
 	USED(o);
 }
 
@@ -4125,20 +4087,20 @@
 }
 
 void
-print_KernSubtable2(Biobuf *f, int indent, Otf *o, KernSubtable2 *v)
+print_KernSubtable2(Otfile *f, int indent, Otf *o, KernSubtable2 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rowWidth", v->rowWidth);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "leftClassOffset", v->leftClassOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rightClassOffset", v->rightClassOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "kerningArrayOffset", v->kerningArrayOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "leftClass");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rowWidth", v->rowWidth);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "leftClassOffset", v->leftClassOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rightClassOffset", v->rightClassOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "kerningArrayOffset", v->kerningArrayOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "leftClass");
 	if(v->leftClass != nil)
 		print_KernClass(f, indent+indentΔ, o, v->leftClass);
-	Bprint(f, "%*s%s:\n", indent, "", "rightClass");
+	f->print(f->aux, "%*s%s:\n", indent, "", "rightClass");
 	if(v->rightClass != nil)
 		print_KernClass(f, indent+indentΔ, o, v->rightClass);
 	for(int i = 0; i < (v->rowWidth/2); i++)
-		Bprint(f, "%*s%s[%d]: %d\n", indent, "", "kerningArray", i, v->kerningArray[i]);
+		f->print(f->aux, "%*s%s[%d]: %d\n", indent, "", "kerningArray", i, v->kerningArray[i]);
 	USED(o);
 }
 
@@ -4166,10 +4128,10 @@
 }
 
 void
-print_KernSubtable(Biobuf *f, int indent, Otf *o, KernSubtable *v)
+print_KernSubtable(Otfile *f, int indent, Otf *o, KernSubtable *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "coverage", v->coverage);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "coverage", v->coverage);
 	USED(o);
 }
 
@@ -4196,11 +4158,11 @@
 }
 
 void
-print_TableKern(Biobuf *f, int indent, Otf *o, TableKern *v)
+print_TableKern(Otfile *f, int indent, Otf *o, TableKern *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "nTables", v->nTables);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "nTables", v->nTables);
 	for(int i = 0; i < v->nTables; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "subtables", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "subtables", i);
 		print_KernSubtable(f, indent+indentΔ, o, &v->subtables[i]);
 	}
 	USED(o);
@@ -4231,15 +4193,15 @@
 }
 
 void
-print_TableLoca(Biobuf *f, int indent, Otf *o, TableLoca *v)
+print_TableLoca(Otfile *f, int indent, Otf *o, TableLoca *v)
 {
 	if(o->indexToLocFormat == 0){
 		for(int i = 0; i < (o->numGlyphs+1); i++)
-			Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "shortOffsets", i, v->shortOffsets[i]);
+			f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "shortOffsets", i, v->shortOffsets[i]);
 	}
 	if(o->indexToLocFormat == 1){
 		for(int i = 0; i < (o->numGlyphs+1); i++)
-			Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "longOffsets", i, v->longOffsets[i]);
+			f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "longOffsets", i, v->longOffsets[i]);
 	}
 	USED(o);
 }
@@ -4263,14 +4225,14 @@
 }
 
 void
-print_VariationAxisRecord(Biobuf *f, int indent, Otf *o, VariationAxisRecord *v)
+print_VariationAxisRecord(Otfile *f, int indent, Otf *o, VariationAxisRecord *v)
 {
-	Bprint(f, "%*s%s: %t\n", indent, "", "axisTag", v->axisTag);
-	Bprint(f, "%*s%s: %g\n", indent, "", "minValue", v->minValue);
-	Bprint(f, "%*s%s: %g\n", indent, "", "defaultValue", v->defaultValue);
-	Bprint(f, "%*s%s: %g\n", indent, "", "maxValue", v->maxValue);
-	Bprint(f, "%*s%s: %#ux%s\n", indent, "", "flags", v->flags, (v->flags&VARIATIONAXISRECORD_FL_HIDDEN_AXIS)?" VARIATIONAXISRECORD_FL_HIDDEN_AXIS":"");
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisNameID", v->axisNameID);
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "axisTag", v->axisTag>>24, v->axisTag>>16, v->axisTag>>8, v->axisTag>>0);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "minValue", v->minValue);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "defaultValue", v->defaultValue);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "maxValue", v->maxValue);
+	f->print(f->aux, "%*s%s: %#ux%s\n", indent, "", "flags", v->flags, (v->flags&VARIATIONAXISRECORD_FL_HIDDEN_AXIS)?" VARIATIONAXISRECORD_FL_HIDDEN_AXIS":"");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisNameID", v->axisNameID);
 	USED(o);
 }
 
@@ -4290,10 +4252,10 @@
 }
 
 void
-print_UserTuple(Biobuf *f, int indent, Otf *o, UserTuple *v)
+print_UserTuple(Otfile *f, int indent, Otf *o, UserTuple *v)
 {
 	for(int i = 0; i < o->axisCount; i++)
-		Bprint(f, "%*s%s[%d]: %g\n", indent, "", "coordinates", i, v->coordinates[i]);
+		f->print(f->aux, "%*s%s[%d]: %g\n", indent, "", "coordinates", i, v->coordinates[i]);
 	USED(o);
 }
 
@@ -4320,13 +4282,13 @@
 }
 
 void
-print_InstanceRecord(Biobuf *f, int indent, Otf *o, InstanceRecord *v)
+print_InstanceRecord(Otfile *f, int indent, Otf *o, InstanceRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "subfamilyNameID", v->subfamilyNameID);
-	Bprint(f, "%*s%s:\n", indent, "", "coordinates");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "subfamilyNameID", v->subfamilyNameID);
+	f->print(f->aux, "%*s%s:\n", indent, "", "coordinates");
 	print_UserTuple(f, indent+indentΔ, o, &v->coordinates);
 	if((o->instanceSize==((o->axisCount*4)+6)))
-		Bprint(f, "%*s%s: %ud\n", indent, "", "postScriptNameID", v->postScriptNameID);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "postScriptNameID", v->postScriptNameID);
 	USED(o);
 }
 
@@ -4349,14 +4311,14 @@
 }
 
 void
-print_AxisInstances(Biobuf *f, int indent, Otf *o, AxisInstances *v)
+print_AxisInstances(Otfile *f, int indent, Otf *o, AxisInstances *v)
 {
 	for(int i = 0; i < o->axisCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "axes", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "axes", i);
 		print_VariationAxisRecord(f, indent+indentΔ, o, &v->axes[i]);
 	}
 	for(int i = 0; i < o->instanceCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "instaces", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "instaces", i);
 		print_InstanceRecord(f, indent+indentΔ, o, &v->instaces[i]);
 	}
 	USED(o);
@@ -4408,13 +4370,13 @@
 }
 
 void
-print_TableFvar(Biobuf *f, int indent, Otf *o, TableFvar *v)
+print_TableFvar(Otfile *f, int indent, Otf *o, TableFvar *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axesArrayOffset", v->axesArrayOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "instanceCount", v->instanceCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "instanceSize", v->instanceSize);
-	Bprint(f, "%*s%s:\n", indent, "", "axisInstances");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axesArrayOffset", v->axesArrayOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "instanceCount", v->instanceCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "instanceSize", v->instanceSize);
+	f->print(f->aux, "%*s%s:\n", indent, "", "axisInstances");
 	if(v->axisInstances != nil)
 		print_AxisInstances(f, indent+indentΔ, o, v->axisInstances);
 	USED(o);
@@ -4436,11 +4398,11 @@
 }
 
 void
-print_RegionAxisCoordinates(Biobuf *f, int indent, Otf *o, RegionAxisCoordinates *v)
+print_RegionAxisCoordinates(Otfile *f, int indent, Otf *o, RegionAxisCoordinates *v)
 {
-	Bprint(f, "%*s%s: %g\n", indent, "", "startCoord", v->startCoord);
-	Bprint(f, "%*s%s: %g\n", indent, "", "peakCoord", v->peakCoord);
-	Bprint(f, "%*s%s: %g\n", indent, "", "endCoord", v->endCoord);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "startCoord", v->startCoord);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "peakCoord", v->peakCoord);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "endCoord", v->endCoord);
 	USED(o);
 }
 
@@ -4459,10 +4421,10 @@
 }
 
 void
-print_VariationRegion(Biobuf *f, int indent, Otf *o, VariationRegion *v)
+print_VariationRegion(Otfile *f, int indent, Otf *o, VariationRegion *v)
 {
 	for(int i = 0; i < o->axisCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "regionAxes", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "regionAxes", i);
 		print_RegionAxisCoordinates(f, indent+indentΔ, o, &v->regionAxes[i]);
 	}
 	USED(o);
@@ -4487,12 +4449,12 @@
 }
 
 void
-print_VariationRegionList(Biobuf *f, int indent, Otf *o, VariationRegionList *v)
+print_VariationRegionList(Otfile *f, int indent, Otf *o, VariationRegionList *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "regionCount", v->regionCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "regionCount", v->regionCount);
 	for(int i = 0; i < v->regionCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "variationRegion", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "variationRegion", i);
 		print_VariationRegion(f, indent+indentΔ, o, &v->variationRegion[i]);
 	}
 	USED(o);
@@ -4519,13 +4481,13 @@
 }
 
 void
-print_ItemVariationData(Biobuf *f, int indent, Otf *o, ItemVariationData *v)
+print_ItemVariationData(Otfile *f, int indent, Otf *o, ItemVariationData *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "itemCount", v->itemCount);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "wordDeltaCount", v->wordDeltaCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "regionIndexCount", v->regionIndexCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "itemCount", v->itemCount);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "wordDeltaCount", v->wordDeltaCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "regionIndexCount", v->regionIndexCount);
 	for(int i = 0; i < v->regionIndexCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "regionIndexes", i, v->regionIndexes[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "regionIndexes", i, v->regionIndexes[i]);
 	USED(o);
 }
 
@@ -4554,12 +4516,12 @@
 }
 
 void
-print_ItemVariationStore(Biobuf *f, int indent, Otf *o, ItemVariationStore *v)
+print_ItemVariationStore(Otfile *f, int indent, Otf *o, ItemVariationStore *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "variationRegionListOffset", v->variationRegionListOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "itemVariationDataCount", v->itemVariationDataCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "variationRegionListOffset", v->variationRegionListOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "itemVariationDataCount", v->itemVariationDataCount);
 	for(int i = 0; i < v->itemVariationDataCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "itemVariationDataOffsets", i, v->itemVariationDataOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "itemVariationDataOffsets", i, v->itemVariationDataOffsets[i]);
 	USED(o);
 }
 
@@ -4595,15 +4557,15 @@
 }
 
 void
-print_DeltaSetIndexMap(Biobuf *f, int indent, Otf *o, DeltaSetIndexMap *v)
+print_DeltaSetIndexMap(Otfile *f, int indent, Otf *o, DeltaSetIndexMap *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "entryFormat", v->entryFormat);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "format", v->format);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "entryFormat", v->entryFormat);
 	if(v->format == 0)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "mapCount0", v->mapCount0);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "mapCount0", v->mapCount0);
 	if(v->format == 1)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "mapCount1", v->mapCount1);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "mapData", v->mapData);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "mapCount1", v->mapCount1);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "mapData", v->mapData);
 	USED(o);
 }
 
@@ -4678,22 +4640,22 @@
 }
 
 void
-print_TableHVAR(Biobuf *f, int indent, Otf *o, TableHVAR *v)
+print_TableHVAR(Otfile *f, int indent, Otf *o, TableHVAR *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "itemVariationStoreOffset", v->itemVariationStoreOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "advanceWidthMappingOffset", v->advanceWidthMappingOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "lsbMappingOffset", v->lsbMappingOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rsbMappingOffset", v->rsbMappingOffset);
-	Bprint(f, "%*s%s:\n", indent, "", "itemVariationStore");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "itemVariationStoreOffset", v->itemVariationStoreOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "advanceWidthMappingOffset", v->advanceWidthMappingOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "lsbMappingOffset", v->lsbMappingOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rsbMappingOffset", v->rsbMappingOffset);
+	f->print(f->aux, "%*s%s:\n", indent, "", "itemVariationStore");
 	if(v->itemVariationStore != nil)
 		print_ItemVariationStore(f, indent+indentΔ, o, v->itemVariationStore);
-	Bprint(f, "%*s%s:\n", indent, "", "advanceWidthMapping");
+	f->print(f->aux, "%*s%s:\n", indent, "", "advanceWidthMapping");
 	if(v->advanceWidthMapping != nil)
 		print_DeltaSetIndexMap(f, indent+indentΔ, o, v->advanceWidthMapping);
-	Bprint(f, "%*s%s:\n", indent, "", "lsbMapping");
+	f->print(f->aux, "%*s%s:\n", indent, "", "lsbMapping");
 	if(v->lsbMapping != nil)
 		print_DeltaSetIndexMap(f, indent+indentΔ, o, v->lsbMapping);
-	Bprint(f, "%*s%s:\n", indent, "", "rsbMapping");
+	f->print(f->aux, "%*s%s:\n", indent, "", "rsbMapping");
 	if(v->rsbMapping != nil)
 		print_DeltaSetIndexMap(f, indent+indentΔ, o, v->rsbMapping);
 	USED(o);
@@ -4720,15 +4682,15 @@
 }
 
 void
-print_TableFFTM(Biobuf *f, int indent, Otf *o, TableFFTM *v)
+print_TableFFTM(Otfile *f, int indent, Otf *o, TableFFTM *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "version", v->version);
 	if(v->version == 1)
-		Bprint(f, "%*s%s: %T\n", indent, "", "fontforge", v->fontforge);
+		f->print(f->aux, "%*s%s: %τ\n", indent, "", "fontforge", fmttime(v->fontforge));
 	if(v->version == 1)
-		Bprint(f, "%*s%s: %T\n", indent, "", "created", v->created);
+		f->print(f->aux, "%*s%s: %τ\n", indent, "", "created", fmttime(v->created));
 	if(v->version == 1)
-		Bprint(f, "%*s%s: %T\n", indent, "", "modified", v->modified);
+		f->print(f->aux, "%*s%s: %τ\n", indent, "", "modified", fmttime(v->modified));
 	USED(o);
 }
 
@@ -4751,11 +4713,11 @@
 }
 
 void
-print_SignatureBlock1(Biobuf *f, int indent, Otf *o, SignatureBlock1 *v)
+print_SignatureBlock1(Otfile *f, int indent, Otf *o, SignatureBlock1 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "signatureLength", v->signatureLength);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "signatureLength", v->signatureLength);
 	for(int i = 0; i < v->signatureLength; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "signature", i, v->signature[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "signature", i, v->signature[i]);
 	USED(o);
 }
 
@@ -4788,13 +4750,13 @@
 }
 
 void
-print_SignatureRecord(Biobuf *f, int indent, Otf *o, SignatureRecord *v)
+print_SignatureRecord(Otfile *f, int indent, Otf *o, SignatureRecord *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "signatureBlockOffset", v->signatureBlockOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "format", v->format);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "signatureBlockOffset", v->signatureBlockOffset);
 	if(v->format == 1){
-		Bprint(f, "%*s%s:\n", indent, "", "signatureBlock1");
+		f->print(f->aux, "%*s%s:\n", indent, "", "signatureBlock1");
 		if(v->signatureBlock1 != nil)
 			print_SignatureBlock1(f, indent+indentΔ, o, v->signatureBlock1);
 	}
@@ -4825,12 +4787,12 @@
 }
 
 void
-print_TableDSIG(Biobuf *f, int indent, Otf *o, TableDSIG *v)
+print_TableDSIG(Otfile *f, int indent, Otf *o, TableDSIG *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numSignatures", v->numSignatures);
-	Bprint(f, "%*s%s: %#ux%s\n", indent, "", "flags", v->flags, (v->flags&DSIG_CANNOT_BE_RESIGNED)?" DSIG_CANNOT_BE_RESIGNED":"");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numSignatures", v->numSignatures);
+	f->print(f->aux, "%*s%s: %#ux%s\n", indent, "", "flags", v->flags, (v->flags&DSIG_CANNOT_BE_RESIGNED)?" DSIG_CANNOT_BE_RESIGNED":"");
 	for(int i = 0; i < v->numSignatures; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "signatureRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "signatureRecords", i);
 		print_SignatureRecord(f, indent+indentΔ, o, &v->signatureRecords[i]);
 	}
 	USED(o);
@@ -4855,11 +4817,11 @@
 }
 
 void
-print_AxisRecord(Biobuf *f, int indent, Otf *o, AxisRecord *v)
+print_AxisRecord(Otfile *f, int indent, Otf *o, AxisRecord *v)
 {
-	Bprint(f, "%*s%s: %t\n", indent, "", "axisTag", v->axisTag);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisNameID", v->axisNameID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisOrdering", v->axisOrdering);
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "axisTag", v->axisTag>>24, v->axisTag>>16, v->axisTag>>8, v->axisTag>>0);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisNameID", v->axisNameID);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisOrdering", v->axisOrdering);
 	USED(o);
 }
 
@@ -4883,14 +4845,14 @@
 }
 
 void
-print_DesignAxes(Biobuf *f, int indent, Otf *o, DesignAxes *v)
+print_DesignAxes(Otfile *f, int indent, Otf *o, DesignAxes *v)
 {
 	for(int i = 0; i < o->designAxisCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "designAxes", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "designAxes", i);
 		print_AxisRecord(f, indent+indentΔ, o, &v->designAxes[i]);
 	}
 	for(int i = 0; i < o->axisValueCount; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "axisValueOffsets", i, v->axisValueOffsets[i]);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "axisValueOffsets", i, v->axisValueOffsets[i]);
 	USED(o);
 }
 
@@ -4941,17 +4903,17 @@
 }
 
 void
-print_TableSTAT(Biobuf *f, int indent, Otf *o, TableSTAT *v)
+print_TableSTAT(Otfile *f, int indent, Otf *o, TableSTAT *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "designAxisSize", v->designAxisSize);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "designAxisCount", v->designAxisCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "designAxesOffset", v->designAxesOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisValueCount", v->axisValueCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "offsetToAxisValueOffsets", v->offsetToAxisValueOffsets);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "designAxisSize", v->designAxisSize);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "designAxisCount", v->designAxisCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "designAxesOffset", v->designAxesOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisValueCount", v->axisValueCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "offsetToAxisValueOffsets", v->offsetToAxisValueOffsets);
 	if(v->minorVersion > 0)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "elidedFallbackNameID", v->elidedFallbackNameID);
-	Bprint(f, "%*s%s:\n", indent, "", "designAxes");
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "elidedFallbackNameID", v->elidedFallbackNameID);
+	f->print(f->aux, "%*s%s:\n", indent, "", "designAxes");
 	if(v->designAxes != nil)
 		print_DesignAxes(f, indent+indentΔ, o, v->designAxes);
 	USED(o);
@@ -4972,10 +4934,10 @@
 }
 
 void
-print_GaspRange(Biobuf *f, int indent, Otf *o, GaspRange *v)
+print_GaspRange(Otfile *f, int indent, Otf *o, GaspRange *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rangeMaxPPEM", v->rangeMaxPPEM);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "rangeGaspBehavior", v->rangeGaspBehavior);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rangeMaxPPEM", v->rangeMaxPPEM);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "rangeGaspBehavior", v->rangeGaspBehavior);
 	USED(o);
 }
 
@@ -5002,12 +4964,12 @@
 }
 
 void
-print_TableGasp(Biobuf *f, int indent, Otf *o, TableGasp *v)
+print_TableGasp(Otfile *f, int indent, Otf *o, TableGasp *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numRanges", v->numRanges);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "version", v->version);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numRanges", v->numRanges);
 	for(int i = 0; i < v->numRanges; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "gaspRanges", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "gaspRanges", i);
 		print_GaspRange(f, indent+indentΔ, o, &v->gaspRanges[i]);
 	}
 	USED(o);
@@ -5029,10 +4991,10 @@
 }
 
 void
-print_Tuple(Biobuf *f, int indent, Otf *o, Tuple *v)
+print_Tuple(Otfile *f, int indent, Otf *o, Tuple *v)
 {
 	for(int i = 0; i < o->axisCount; i++)
-		Bprint(f, "%*s%s[%d]: %g\n", indent, "", "coordinates", i, v->coordinates[i]);
+		f->print(f->aux, "%*s%s[%d]: %g\n", indent, "", "coordinates", i, v->coordinates[i]);
 	USED(o);
 }
 
@@ -5063,15 +5025,15 @@
 }
 
 void
-print_TupleVariationHeader(Biobuf *f, int indent, Otf *o, TupleVariationHeader *v)
+print_TupleVariationHeader(Otfile *f, int indent, Otf *o, TupleVariationHeader *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "variationDataSize", v->variationDataSize);
-	Bprint(f, "%*s%s: %ud%s%s%s\n", indent, "", "tupleIndex", v->tupleIndex, (v->tupleIndex&TUPLEINDEX_FL_PRIVATE_POINT_NUMBERS)?" TUPLEINDEX_FL_PRIVATE_POINT_NUMBERS":"", (v->tupleIndex&TUPLEINDEX_FL_INTERMEDIATE_REGION)?" TUPLEINDEX_FL_INTERMEDIATE_REGION":"", (v->tupleIndex&TUPLEINDEX_FL_EMBEDDED_PEAK_TUPLE)?" TUPLEINDEX_FL_EMBEDDED_PEAK_TUPLE":"");
-	Bprint(f, "%*s%s:\n", indent, "", "peakTuple");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "variationDataSize", v->variationDataSize);
+	f->print(f->aux, "%*s%s: %ud%s%s%s\n", indent, "", "tupleIndex", v->tupleIndex, (v->tupleIndex&TUPLEINDEX_FL_PRIVATE_POINT_NUMBERS)?" TUPLEINDEX_FL_PRIVATE_POINT_NUMBERS":"", (v->tupleIndex&TUPLEINDEX_FL_INTERMEDIATE_REGION)?" TUPLEINDEX_FL_INTERMEDIATE_REGION":"", (v->tupleIndex&TUPLEINDEX_FL_EMBEDDED_PEAK_TUPLE)?" TUPLEINDEX_FL_EMBEDDED_PEAK_TUPLE":"");
+	f->print(f->aux, "%*s%s:\n", indent, "", "peakTuple");
 	print_Tuple(f, indent+indentΔ, o, &v->peakTuple);
-	Bprint(f, "%*s%s:\n", indent, "", "intermediateStartTuple");
+	f->print(f->aux, "%*s%s:\n", indent, "", "intermediateStartTuple");
 	print_Tuple(f, indent+indentΔ, o, &v->intermediateStartTuple);
-	Bprint(f, "%*s%s:\n", indent, "", "intermediateEndTuple");
+	f->print(f->aux, "%*s%s:\n", indent, "", "intermediateEndTuple");
 	print_Tuple(f, indent+indentΔ, o, &v->intermediateEndTuple);
 	USED(o);
 }
@@ -5095,12 +5057,12 @@
 }
 
 void
-print_GlyphVariationData(Biobuf *f, int indent, Otf *o, GlyphVariationData *v)
+print_GlyphVariationData(Otfile *f, int indent, Otf *o, GlyphVariationData *v)
 {
-	Bprint(f, "%*s%s: %ud%s\n", indent, "", "tupleVariationCount", v->tupleVariationCount, (v->tupleVariationCount&COUNT_FL_SHARED_POINT_NUMBERS)?" COUNT_FL_SHARED_POINT_NUMBERS":"");
-	Bprint(f, "%*s%s: %ud\n", indent, "", "dataOffset", v->dataOffset);
+	f->print(f->aux, "%*s%s: %ud%s\n", indent, "", "tupleVariationCount", v->tupleVariationCount, (v->tupleVariationCount&COUNT_FL_SHARED_POINT_NUMBERS)?" COUNT_FL_SHARED_POINT_NUMBERS":"");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "dataOffset", v->dataOffset);
 	for(int i = 0; i < (v->tupleVariationCount&4095); i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "tupleVariationHeaders", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "tupleVariationHeaders", i);
 		print_TupleVariationHeader(f, indent+indentΔ, o, &v->tupleVariationHeaders[i]);
 	}
 	USED(o);
@@ -5159,24 +5121,24 @@
 }
 
 void
-print_TableGvar(Biobuf *f, int indent, Otf *o, TableGvar *v)
+print_TableGvar(Otfile *f, int indent, Otf *o, TableGvar *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "sharedTupleCount", v->sharedTupleCount);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "sharedTuplesOffset", v->sharedTuplesOffset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
-	Bprint(f, "%*s%s: %#ux%s\n", indent, "", "flags", v->flags, (v->flags&GVAR_FL_LONG_OFFSETS)?" GVAR_FL_LONG_OFFSETS":"");
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphVariationDataArrayOffset", v->glyphVariationDataArrayOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "sharedTupleCount", v->sharedTupleCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "sharedTuplesOffset", v->sharedTuplesOffset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
+	f->print(f->aux, "%*s%s: %#ux%s\n", indent, "", "flags", v->flags, (v->flags&GVAR_FL_LONG_OFFSETS)?" GVAR_FL_LONG_OFFSETS":"");
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphVariationDataArrayOffset", v->glyphVariationDataArrayOffset);
 	if((v->flags&GVAR_FL_LONG_OFFSETS) == 0){
 		for(int i = 0; i < (v->glyphCount+1); i++)
-			Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphVariationDataOffsetsShort", i, v->glyphVariationDataOffsetsShort[i]);
+			f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "glyphVariationDataOffsetsShort", i, v->glyphVariationDataOffsetsShort[i]);
 	}
 	if((v->flags&GVAR_FL_LONG_OFFSETS) != 0){
 		for(int i = 0; i < (v->glyphCount+1); i++)
-			Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphVariationDataOffsetsLong", i, v->glyphVariationDataOffsetsLong[i]);
+			f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "glyphVariationDataOffsetsLong", i, v->glyphVariationDataOffsetsLong[i]);
 	}
 	for(int i = 0; i < v->sharedTupleCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "sharedTuples", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "sharedTuples", i);
 		print_Tuple(f, indent+indentΔ, o, &v->sharedTuples[i]);
 	}
 	USED(o);
@@ -5197,10 +5159,10 @@
 }
 
 void
-print_AxisValueMap(Biobuf *f, int indent, Otf *o, AxisValueMap *v)
+print_AxisValueMap(Otfile *f, int indent, Otf *o, AxisValueMap *v)
 {
-	Bprint(f, "%*s%s: %g\n", indent, "", "fromCoordinate", v->fromCoordinate);
-	Bprint(f, "%*s%s: %g\n", indent, "", "toCoordinate", v->toCoordinate);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "fromCoordinate", v->fromCoordinate);
+	f->print(f->aux, "%*s%s: %g\n", indent, "", "toCoordinate", v->toCoordinate);
 	USED(o);
 }
 
@@ -5222,11 +5184,11 @@
 }
 
 void
-print_SegmentMaps(Biobuf *f, int indent, Otf *o, SegmentMaps *v)
+print_SegmentMaps(Otfile *f, int indent, Otf *o, SegmentMaps *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "positionMapCount", v->positionMapCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "positionMapCount", v->positionMapCount);
 	for(int i = 0; i < v->positionMapCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "axisValueMaps", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "axisValueMaps", i);
 		print_AxisValueMap(f, indent+indentΔ, o, &v->axisValueMaps[i]);
 	}
 	USED(o);
@@ -5260,11 +5222,11 @@
 }
 
 void
-print_TableAvar(Biobuf *f, int indent, Otf *o, TableAvar *v)
+print_TableAvar(Otfile *f, int indent, Otf *o, TableAvar *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "axisCount", v->axisCount);
 	for(int i = 0; i < v->axisCount; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "axisSegmentMaps", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "axisSegmentMaps", i);
 		print_SegmentMaps(f, indent+indentΔ, o, &v->axisSegmentMaps[i]);
 	}
 	USED(o);
@@ -5339,57 +5301,57 @@
 }
 
 void
-print_TableOS∕2(Biobuf *f, int indent, Otf *o, TableOS∕2 *v)
+print_TableOS∕2(Otfile *f, int indent, Otf *o, TableOS∕2 *v)
 {
-	Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
-	Bprint(f, "%*s%s: %d\n", indent, "", "xAvgCharWidth", v->xAvgCharWidth);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "usWeightClass", v->usWeightClass);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "usWidthClass", v->usWidthClass);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "fsType", v->fsType);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySubscriptXSize", v->ySubscriptXSize);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySubscriptYSize", v->ySubscriptYSize);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySubscriptXOffset", v->ySubscriptXOffset);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySubscriptYOffset", v->ySubscriptYOffset);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySuperscriptXSize", v->ySuperscriptXSize);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySuperscriptYSize", v->ySuperscriptYSize);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySuperscriptXOffset", v->ySuperscriptXOffset);
-	Bprint(f, "%*s%s: %d\n", indent, "", "ySuperscriptYOffset", v->ySuperscriptYOffset);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yStrikeoutSize", v->yStrikeoutSize);
-	Bprint(f, "%*s%s: %d\n", indent, "", "yStrikeoutPosition", v->yStrikeoutPosition);
-	Bprint(f, "%*s%s: %d\n", indent, "", "sFamilyClass", v->sFamilyClass);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "version", v->version);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "xAvgCharWidth", v->xAvgCharWidth);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "usWeightClass", v->usWeightClass);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "usWidthClass", v->usWidthClass);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "fsType", v->fsType);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySubscriptXSize", v->ySubscriptXSize);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySubscriptYSize", v->ySubscriptYSize);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySubscriptXOffset", v->ySubscriptXOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySubscriptYOffset", v->ySubscriptYOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySuperscriptXSize", v->ySuperscriptXSize);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySuperscriptYSize", v->ySuperscriptYSize);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySuperscriptXOffset", v->ySuperscriptXOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "ySuperscriptYOffset", v->ySuperscriptYOffset);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yStrikeoutSize", v->yStrikeoutSize);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "yStrikeoutPosition", v->yStrikeoutPosition);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "sFamilyClass", v->sFamilyClass);
 	for(int i = 0; i < 10; i++)
-		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "panose", i, v->panose[i]);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange1", v->ulUnicodeRange1);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange2", v->ulUnicodeRange2);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange3", v->ulUnicodeRange3);
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange4", v->ulUnicodeRange4);
-	Bprint(f, "%*s%s: %t\n", indent, "", "achVendID", v->achVendID);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "fsSelection", v->fsSelection);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "usFirstCharIndex", v->usFirstCharIndex);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "usLastCharIndex", v->usLastCharIndex);
-	Bprint(f, "%*s%s: %d\n", indent, "", "sTypoAscender", v->sTypoAscender);
-	Bprint(f, "%*s%s: %d\n", indent, "", "sTypoDescender", v->sTypoDescender);
-	Bprint(f, "%*s%s: %d\n", indent, "", "sTypoLineGap", v->sTypoLineGap);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "usWinAscent", v->usWinAscent);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "usWinDescent", v->usWinDescent);
+		f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "panose", i, v->panose[i]);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange1", v->ulUnicodeRange1);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange2", v->ulUnicodeRange2);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange3", v->ulUnicodeRange3);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "ulUnicodeRange4", v->ulUnicodeRange4);
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "achVendID", v->achVendID>>24, v->achVendID>>16, v->achVendID>>8, v->achVendID>>0);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "fsSelection", v->fsSelection);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "usFirstCharIndex", v->usFirstCharIndex);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "usLastCharIndex", v->usLastCharIndex);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "sTypoAscender", v->sTypoAscender);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "sTypoDescender", v->sTypoDescender);
+	f->print(f->aux, "%*s%s: %d\n", indent, "", "sTypoLineGap", v->sTypoLineGap);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "usWinAscent", v->usWinAscent);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "usWinDescent", v->usWinDescent);
 	if(v->version >= 1)
-		Bprint(f, "%*s%s: %#ux\n", indent, "", "ulCodePageRange1", v->ulCodePageRange1);
+		f->print(f->aux, "%*s%s: %#ux\n", indent, "", "ulCodePageRange1", v->ulCodePageRange1);
 	if(v->version >= 1)
-		Bprint(f, "%*s%s: %#ux\n", indent, "", "ulCodePageRange2", v->ulCodePageRange2);
+		f->print(f->aux, "%*s%s: %#ux\n", indent, "", "ulCodePageRange2", v->ulCodePageRange2);
 	if(v->version >= 2)
-		Bprint(f, "%*s%s: %d\n", indent, "", "sxHeight", v->sxHeight);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "sxHeight", v->sxHeight);
 	if(v->version >= 2)
-		Bprint(f, "%*s%s: %d\n", indent, "", "sCapHeight", v->sCapHeight);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "sCapHeight", v->sCapHeight);
 	if(v->version >= 2)
-		Bprint(f, "%*s%s: %#ux\n", indent, "", "usDefaultChar", v->usDefaultChar);
+		f->print(f->aux, "%*s%s: %#ux\n", indent, "", "usDefaultChar", v->usDefaultChar);
 	if(v->version >= 2)
-		Bprint(f, "%*s%s: %#ux\n", indent, "", "usBreakChar", v->usBreakChar);
+		f->print(f->aux, "%*s%s: %#ux\n", indent, "", "usBreakChar", v->usBreakChar);
 	if(v->version >= 2)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "usMaxContext", v->usMaxContext);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "usMaxContext", v->usMaxContext);
 	if(v->version >= 5)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "usLowerOpticalPointSize", v->usLowerOpticalPointSize);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "usLowerOpticalPointSize", v->usLowerOpticalPointSize);
 	if(v->version >= 5)
-		Bprint(f, "%*s%s: %ud\n", indent, "", "usUpperOpticalPointSize", v->usUpperOpticalPointSize);
+		f->print(f->aux, "%*s%s: %ud\n", indent, "", "usUpperOpticalPointSize", v->usUpperOpticalPointSize);
 	USED(o);
 }
 
@@ -5409,11 +5371,11 @@
 }
 
 void
-print_TableRecord(Biobuf *f, int indent, Otf *o, TableRecord *v)
+print_TableRecord(Otfile *f, int indent, Otf *o, TableRecord *v)
 {
-	Bprint(f, "%*s%s: %t\n", indent, "", "tableTag", v->tableTag);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "offset", v->offset);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
+	f->print(f->aux, "%*s%s: %c%c%c%c\n", indent, "", "tableTag", v->tableTag>>24, v->tableTag>>16, v->tableTag>>8, v->tableTag>>0);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "offset", v->offset);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "length", v->length);
 	if(v->print != nil && v->parsed != nil)
 		v->print(f, indent+indentΔ, o, v->parsed);
 	USED(o);
@@ -5768,7 +5730,7 @@
 				rec->print = (void*)print_TableOS∕2;
 				break;
 			default:
-				fprint(2, "no parser for \"%t\"\n", rec->tableTag);
+				// FIXME fprint(2, "no parser for \"%t\"\n", rec->tableTag);
 				break;
 			}
 			if(otfpoprange(o) < 0)
@@ -5782,15 +5744,15 @@
 }
 
 void
-print_TableDirectory(Biobuf *f, int indent, Otf *o, TableDirectory *v)
+print_TableDirectory(Otfile *f, int indent, Otf *o, TableDirectory *v)
 {
-	Bprint(f, "%*s%s: %#ux\n", indent, "", "sfntVersion", v->sfntVersion);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "numTables", v->numTables);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
+	f->print(f->aux, "%*s%s: %#ux\n", indent, "", "sfntVersion", v->sfntVersion);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "numTables", v->numTables);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
+	f->print(f->aux, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
 	for(int i = 0; i < v->numTables; i++){
-		Bprint(f, "%*s%s[%d]:\n", indent, "", "tableRecords", i);
+		f->print(f->aux, "%*s%s[%d]:\n", indent, "", "tableRecords", i);
 		print_TableRecord(f, indent+indentΔ, o, &v->tableRecords[i]);
 	}
 	USED(o);
--- a/otf.c.in
+++ b/otf.c.in
@@ -1,7 +1,5 @@
 /* this file is generated. do not modify. */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
+#include "otfsys.h"
 #include "otf.h"
 
 int indentΔ = 2;
@@ -9,7 +7,7 @@
 typedef struct Range Range;
 
 struct Otf {
-	Biobuf *f;
+	Otfile *f;
 	Range *r;
 	u8int *buf;
 	int bufsz;
@@ -104,20 +102,15 @@
 }
 
 Otf *
-otfopen(char *path)
+otfopen(Otfile *f)
 {
 	Otf *o;
-	Biobuf *f;
 
-	if((f = Bopen(path, OREAD)) == nil)
-		return nil;
 	if((o = calloc(1, sizeof(*o))) == nil){
 		werrstr("no memory");
-		Bterm(f);
 	}else{
 		o->f = f;
 		if(read_TableDirectory(o, &o->td) != 0){
-			Bterm(f);
 			free(o);
 			o = nil;
 		}
@@ -126,7 +119,7 @@
 }
 
 void
-otfprint(Otf *o, Biobuf *out, int indent)
+otfprint(Otf *o, Otfile *out, int indent)
 {
 	print_TableDirectory(out, indent, o, &o->td);
 }
@@ -166,7 +159,7 @@
 	r->start = off;
 	r->len = len;
 	r->prevoff = o->off;
-	if((x = Bseek(o->f, off, 0)) != off){
+	if((x = o->f->seek(o->f->aux, off, 0)) != off){
 		werrstr("seek offset: need %d, got %d", off, x);
 		goto err;
 	}
@@ -189,7 +182,7 @@
 		werrstr("pop without push");
 		goto err;
 	}
-	if((x = Bseek(o->f, r->prevoff, 0)) != r->prevoff){
+	if((x = o->f->seek(o->f->aux, r->prevoff, 0)) != r->prevoff){
 		werrstr("seek offset: need %d, got %d", r->prevoff, x);
 		goto err;
 	}
@@ -228,7 +221,7 @@
 		o->buf = b;
 		o->bufsz = n;
 	}
-	if((x = Bread(o->f, o->buf, n)) != n){
+	if((x = o->f->read(o->f->aux, o->buf, n)) != n){
 		werrstr("need %d, got %d; off %d", n, x, o->off);
 		goto err;
 	}
@@ -343,9 +336,10 @@
 }
 
 void
-print_ComponentGlyph(Biobuf *f, int indent, Otf *o, ComponentGlyph *v)
+print_ComponentGlyph(Otfile *f, int indent, Otf *o, ComponentGlyph *v)
 {
-	Bprint(f, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags,
+	void *a = f->aux;
+	f->print(a, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags,
 		(v->flags&CGLYPH_FL_ROUND_TO_GRID_XY)?" CGLYPH_FL_ROUND_TO_GRID_XY":"",
 		(v->flags&CGLYPH_FL_SCALE)?" CGLYPH_FL_SCALE":"",
 		(v->flags&CGLYPH_FL_MORE_COMPONENTS)?" CGLYPH_FL_MORE_COMPONENTS":"",
@@ -357,32 +351,32 @@
 		(v->flags&CGLYPH_FL_SCALED_COMPONENT_OFFSET)?" CGLYPH_FL_SCALED_COMPONENT_OFFSET":"",
 		(v->flags&CGLYPH_FL_UNSCALED_COMPONENT_OFFSET)?" CGLYPH_FL_UNSCALED_COMPONENT_OFFSET":""
 	);
-	Bprint(f, "%*s%s: %ud\n", indent, "", "glyphIndex", v->glyphIndex);
+	f->print(a, "%*s%s: %ud\n", indent, "", "glyphIndex", v->glyphIndex);
 	if(v->arg1 != 0 || v->arg2 != 0){
-		Bprint(f, "%*s%s: %d\n", indent, "", "arg1", v->arg1);
-		Bprint(f, "%*s%s: %d\n", indent, "", "arg2", v->arg2);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "arg1", v->arg1);
+		f->print(f->aux, "%*s%s: %d\n", indent, "", "arg2", v->arg2);
 	}
 	if(v->flags & CGLYPH_FL_SCALE){
-		Bprint(f, "%*s%s: %g\n", indent, "", "scale", v->scale);
+		f->print(a, "%*s%s: %g\n", indent, "", "scale", v->scale);
 	}else if(v->flags & CGLYPH_FL_SCALE_XY){
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
 	}else if(v->flags & CGLYPH_FL_2X2_TRANSFORM){
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scale01", v->scale01);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scale10", v->scale10);
-		Bprint(f, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleX", v->scaleX);
+		f->print(a, "%*s%s: %g\n", indent, "", "scale01", v->scale01);
+		f->print(a, "%*s%s: %g\n", indent, "", "scale10", v->scale10);
+		f->print(a, "%*s%s: %g\n", indent, "", "scaleY", v->scaleY);
 	}
 	if(v->numInstr > 0 && v->instr != nil){
-		Bprint(f, "%*s%s: %ud\n", indent, "", "numInstr", v->numInstr);
-		Bprint(f, "%*s%s:", indent, "", "instr");
+		f->print(a, "%*s%s: %ud\n", indent, "", "numInstr", v->numInstr);
+		f->print(a, "%*s%s:", indent, "", "instr");
 		for(int i = 0; i < v->numInstr; i++)
-			Bprint(f, " %02ux", v->instr[i]);
-		Bprint(f, "\n");
+			f->print(a, " %02ux", v->instr[i]);
+		f->print(a, "\n");
 	}
 	if(v->next != nil){
-		Bprint(f, "%*s%s:\n", indent, "", "next");
-		print_ComponentGlyph(f, indent+indentΔ, o, v->next);
+		f->print(a, "%*s%s:\n", indent, "", "next");
+		print_ComponentGlyph(a, indent+indentΔ, o, v->next);
 	}
 }
 
@@ -509,62 +503,30 @@
 }
 
 void
-print_SimpleGlyph(Biobuf *f, int indent, Otf *o, SimpleGlyph *v)
+print_SimpleGlyph(Otfile *f, int indent, Otf *o, SimpleGlyph *v)
 {
+	void *a = f->aux;
 	USED(o);
 	if(v->numEndPtsOfContours > 0){
-		Bprint(f, "%*s%s:", indent, "", "endPtsOfContours");
+		f->print(a, "%*s%s:", indent, "", "endPtsOfContours");
 		for(int i = 0; i < v->numEndPtsOfContours; i++)
-			Bprint(f, " %ud", v->endPtsOfContours[i]);
-		Bprint(f, "\n");
+			f->print(a, " %ud", v->endPtsOfContours[i]);
+		f->print(a, "\n");
 	}
 	if(v->instructionLength > 0){
-		Bprint(f, "%*s%s: %ud\n", indent, "", "instructionLength", v->instructionLength);
-		Bprint(f, "%*s%s:", indent, "", "instructions");
+		f->print(a, "%*s%s: %ud\n", indent, "", "instructionLength", v->instructionLength);
+		f->print(a, "%*s%s:", indent, "", "instructions");
 		for(int i = 0; i < v->instructionLength; i++)
-			Bprint(f, " %02ux", v->instructions[i]);
-		Bprint(f, "\n");
+			f->print(a, " %02ux", v->instructions[i]);
+		f->print(a, "\n");
 	}
 	if(v->numPoints > 0){
-		Bprint(f, "%*s%s: %d\n", indent, "", "numPoints", v->numPoints);
-		Bprint(f, "%*s%s:", indent, "", "points");
+		f->print(a, "%*s%s: %d\n", indent, "", "numPoints", v->numPoints);
+		f->print(a, "%*s%s:", indent, "", "points");
 		for(int i = 0; i < v->numPoints; i++)
-			Bprint(f, " (%d,%d,%d)", v->points[i].x, v->points[i].y, v->points[i].onCurve);
-		Bprint(f, "\n");
+			f->print(a, " (%d,%d,%s)", v->points[i].x, v->points[i].y, v->points[i].onCurve?"on":"off");
+		f->print(a, "\n");
 	}
-}
-
-static int
-Tfmt(Fmt *f)
-{
-	Tm t;
-	s64int v = va_arg(f->args, s64int);
-	return fmtprint(f, "%τ", tmfmt(tmtime(&t, v, nil), nil));
-}
-
-static int
-Vfmt(Fmt *f)
-{
-	u32int v = va_arg(f->args, u32int);
-	return fmtprint(f, "%d.%d", v>>16, v&0xffff);
-}
-
-static int
-tfmt(Fmt *f)
-{
-	u32int v = va_arg(f->args, u32int);
-	if(v == 0)
-		return fmtprint(f, "<nil>");
-	return fmtprint(f, "%c%c%c%c", v>>24, v>>16, v>>8, v>>0);
-}
-
-void
-otfinit(void)
-{
-	tmfmtinstall();
-	fmtinstall('V', Vfmt);
-	fmtinstall('T', Tfmt);
-	fmtinstall('t', tfmt);
 }
 
 Glyf *
--- a/otf.h
+++ b/otf.h
@@ -1,7 +1,28 @@
 /* this file is generated. do not modify. */
 typedef struct Otf Otf;
+#ifdef __unix__
+#include <stdint.h>
+typedef int8_t s8int;
+typedef int16_t s16int;
+typedef int32_t s32int;
+typedef int64_t s64int;
+typedef uint8_t u8int;
+typedef uint16_t u16int;
+typedef uint32_t u32int;
+typedef uint64_t u64int;
+#else
 #pragma incomplete Otf
+#endif
 
+typedef struct Otfile Otfile;
+
+struct Otfile {
+	void *aux;
+	int (*seek)(void *aux, int off, int whence);
+	int (*read)(void *aux, void *dst, int sz);
+	int (*print)(void *aux, const char *fmt, ...);
+};
+
 typedef struct ComponentGlyph ComponentGlyph;
 
 enum {
@@ -50,13 +71,8 @@
 
 extern int indentΔ;
 
-#pragma varargck type "T" s64int
-#pragma varargck type "t" u32int
-#pragma varargck type "V" u32int
-
-void otfinit(void);
-Otf *otfopen(char *path);
-void otfprint(Otf *o, Biobuf *out, int indent);
+Otf *otfopen(Otfile *in);
+void otfprint(Otf *o, Otfile *out, int indent);
 void otfclose(Otf *o);
 
 /* FIXME these will go, this is for debugging and designing the drawing logic */
@@ -63,6 +79,7 @@
 typedef struct Glyf Glyf;
 Glyf *otfglyf(Otf *o, int index);
 int otfglyfnum(Otf *o);
+u8int *otfdrawglyf(Glyf *g, int h, int *wo);
 
 typedef struct SubHeader SubHeader;
 typedef struct MapGroup MapGroup;
@@ -191,7 +208,7 @@
 };
 
 int read_SubHeader(Otf *o, SubHeader *v);
-void print_SubHeader(Biobuf *f, int indent, Otf *o, SubHeader *v);
+void print_SubHeader(Otfile *f, int indent, Otf *o, SubHeader *v);
 
 struct MapGroup {
 	u32int startCharCode;
@@ -200,7 +217,7 @@
 };
 
 int read_MapGroup(Otf *o, MapGroup *v);
-void print_MapGroup(Biobuf *f, int indent, Otf *o, MapGroup *v);
+void print_MapGroup(Otfile *f, int indent, Otf *o, MapGroup *v);
 
 struct SubtableCmap0 {
 	u16int length;
@@ -209,7 +226,7 @@
 };
 
 int read_SubtableCmap0(Otf *o, SubtableCmap0 *v);
-void print_SubtableCmap0(Biobuf *f, int indent, Otf *o, SubtableCmap0 *v);
+void print_SubtableCmap0(Otfile *f, int indent, Otf *o, SubtableCmap0 *v);
 
 struct SubtableCmap2 {
 	u16int length;
@@ -218,7 +235,7 @@
 };
 
 int read_SubtableCmap2(Otf *o, SubtableCmap2 *v);
-void print_SubtableCmap2(Biobuf *f, int indent, Otf *o, SubtableCmap2 *v);
+void print_SubtableCmap2(Otfile *f, int indent, Otf *o, SubtableCmap2 *v);
 
 struct SubtableCmap4 {
 	u16int length;
@@ -235,7 +252,7 @@
 };
 
 int read_SubtableCmap4(Otf *o, SubtableCmap4 *v);
-void print_SubtableCmap4(Biobuf *f, int indent, Otf *o, SubtableCmap4 *v);
+void print_SubtableCmap4(Otfile *f, int indent, Otf *o, SubtableCmap4 *v);
 
 struct SubtableCmap6 {
 	u16int length;
@@ -246,7 +263,7 @@
 };
 
 int read_SubtableCmap6(Otf *o, SubtableCmap6 *v);
-void print_SubtableCmap6(Biobuf *f, int indent, Otf *o, SubtableCmap6 *v);
+void print_SubtableCmap6(Otfile *f, int indent, Otf *o, SubtableCmap6 *v);
 
 struct SubtableCmap8 {
 	u16int length;
@@ -257,7 +274,7 @@
 };
 
 int read_SubtableCmap8(Otf *o, SubtableCmap8 *v);
-void print_SubtableCmap8(Biobuf *f, int indent, Otf *o, SubtableCmap8 *v);
+void print_SubtableCmap8(Otfile *f, int indent, Otf *o, SubtableCmap8 *v);
 
 struct SubtableCmap10 {
 	u16int reserved;
@@ -268,7 +285,7 @@
 };
 
 int read_SubtableCmap10(Otf *o, SubtableCmap10 *v);
-void print_SubtableCmap10(Biobuf *f, int indent, Otf *o, SubtableCmap10 *v);
+void print_SubtableCmap10(Otfile *f, int indent, Otf *o, SubtableCmap10 *v);
 
 struct SubtableCmap12or13 {
 	u16int reserved;
@@ -279,7 +296,7 @@
 };
 
 int read_SubtableCmap12or13(Otf *o, SubtableCmap12or13 *v);
-void print_SubtableCmap12or13(Biobuf *f, int indent, Otf *o, SubtableCmap12or13 *v);
+void print_SubtableCmap12or13(Otfile *f, int indent, Otf *o, SubtableCmap12or13 *v);
 
 struct UnicodeRange {
 	u32int startUnicodeValue;
@@ -287,7 +304,7 @@
 };
 
 int read_UnicodeRange(Otf *o, UnicodeRange *v);
-void print_UnicodeRange(Biobuf *f, int indent, Otf *o, UnicodeRange *v);
+void print_UnicodeRange(Otfile *f, int indent, Otf *o, UnicodeRange *v);
 
 struct DefaultUVS {
 	u32int numUnicodeValueRanges;
@@ -295,7 +312,7 @@
 };
 
 int read_DefaultUVS(Otf *o, DefaultUVS *v);
-void print_DefaultUVS(Biobuf *f, int indent, Otf *o, DefaultUVS *v);
+void print_DefaultUVS(Otfile *f, int indent, Otf *o, DefaultUVS *v);
 
 struct UVSMapping {
 	u32int unicodeValue;
@@ -303,7 +320,7 @@
 };
 
 int read_UVSMapping(Otf *o, UVSMapping *v);
-void print_UVSMapping(Biobuf *f, int indent, Otf *o, UVSMapping *v);
+void print_UVSMapping(Otfile *f, int indent, Otf *o, UVSMapping *v);
 
 struct NonDefaultUVS {
 	u32int numUVSMappings;
@@ -311,7 +328,7 @@
 };
 
 int read_NonDefaultUVS(Otf *o, NonDefaultUVS *v);
-void print_NonDefaultUVS(Biobuf *f, int indent, Otf *o, NonDefaultUVS *v);
+void print_NonDefaultUVS(Otfile *f, int indent, Otf *o, NonDefaultUVS *v);
 
 struct VariationSelector {
 	u32int varSelector;
@@ -322,7 +339,7 @@
 };
 
 int read_VariationSelector(Otf *o, VariationSelector *v);
-void print_VariationSelector(Biobuf *f, int indent, Otf *o, VariationSelector *v);
+void print_VariationSelector(Otfile *f, int indent, Otf *o, VariationSelector *v);
 
 struct SubtableCmap14 {
 	u32int length;
@@ -331,7 +348,7 @@
 };
 
 int read_SubtableCmap14(Otf *o, SubtableCmap14 *v);
-void print_SubtableCmap14(Biobuf *f, int indent, Otf *o, SubtableCmap14 *v);
+void print_SubtableCmap14(Otfile *f, int indent, Otf *o, SubtableCmap14 *v);
 
 struct SubtableCmap {
 	u16int format;
@@ -346,7 +363,7 @@
 };
 
 int read_SubtableCmap(Otf *o, SubtableCmap *v);
-void print_SubtableCmap(Biobuf *f, int indent, Otf *o, SubtableCmap *v);
+void print_SubtableCmap(Otfile *f, int indent, Otf *o, SubtableCmap *v);
 
 struct EncodingRecord {
 	u16int platformID;
@@ -356,7 +373,7 @@
 };
 
 int read_EncodingRecord(Otf *o, EncodingRecord *v);
-void print_EncodingRecord(Biobuf *f, int indent, Otf *o, EncodingRecord *v);
+void print_EncodingRecord(Otfile *f, int indent, Otf *o, EncodingRecord *v);
 
 struct TableCmap {
 	// u16int version;
@@ -365,7 +382,7 @@
 };
 
 int read_TableCmap(Otf *o, TableCmap *v);
-void print_TableCmap(Biobuf *f, int indent, Otf *o, TableCmap *v);
+void print_TableCmap(Otfile *f, int indent, Otf *o, TableCmap *v);
 
 enum { // TableHead
 	// flags
@@ -402,7 +419,7 @@
 };
 
 int read_TableHead(Otf *o, TableHead *v);
-void print_TableHead(Biobuf *f, int indent, Otf *o, TableHead *v);
+void print_TableHead(Otfile *f, int indent, Otf *o, TableHead *v);
 
 struct TableHhea {
 	u16int majorVersion;
@@ -423,7 +440,7 @@
 };
 
 int read_TableHhea(Otf *o, TableHhea *v);
-void print_TableHhea(Biobuf *f, int indent, Otf *o, TableHhea *v);
+void print_TableHhea(Otfile *f, int indent, Otf *o, TableHhea *v);
 
 struct Glyf {
 	s16int numberOfContours;
@@ -436,7 +453,7 @@
 };
 
 int read_Glyf(Otf *o, Glyf *v);
-void print_Glyf(Biobuf *f, int indent, Otf *o, Glyf *v);
+void print_Glyf(Otfile *f, int indent, Otf *o, Glyf *v);
 
 struct LongHorMetric {
 	u16int advanceWidth;
@@ -444,7 +461,7 @@
 };
 
 int read_LongHorMetric(Otf *o, LongHorMetric *v);
-void print_LongHorMetric(Biobuf *f, int indent, Otf *o, LongHorMetric *v);
+void print_LongHorMetric(Otfile *f, int indent, Otf *o, LongHorMetric *v);
 
 struct TableMaxp {
 	// u32int version;
@@ -452,7 +469,7 @@
 };
 
 int read_TableMaxp(Otf *o, TableMaxp *v);
-void print_TableMaxp(Biobuf *f, int indent, Otf *o, TableMaxp *v);
+void print_TableMaxp(Otfile *f, int indent, Otf *o, TableMaxp *v);
 
 struct TableHmtx {
 	LongHorMetric *hMetrics;
@@ -460,7 +477,7 @@
 };
 
 int read_TableHmtx(Otf *o, TableHmtx *v);
-void print_TableHmtx(Biobuf *f, int indent, Otf *o, TableHmtx *v);
+void print_TableHmtx(Otfile *f, int indent, Otf *o, TableHmtx *v);
 
 struct TablePost {
 	// u32int version;
@@ -471,7 +488,7 @@
 };
 
 int read_TablePost(Otf *o, TablePost *v);
-void print_TablePost(Biobuf *f, int indent, Otf *o, TablePost *v);
+void print_TablePost(Otfile *f, int indent, Otf *o, TablePost *v);
 
 struct NameRecord {
 	u16int platformID;
@@ -484,7 +501,7 @@
 };
 
 int read_NameRecord(Otf *o, NameRecord *v);
-void print_NameRecord(Biobuf *f, int indent, Otf *o, NameRecord *v);
+void print_NameRecord(Otfile *f, int indent, Otf *o, NameRecord *v);
 
 struct LangTagRecord {
 	u16int length;
@@ -493,7 +510,7 @@
 };
 
 int read_LangTagRecord(Otf *o, LangTagRecord *v);
-void print_LangTagRecord(Biobuf *f, int indent, Otf *o, LangTagRecord *v);
+void print_LangTagRecord(Otfile *f, int indent, Otf *o, LangTagRecord *v);
 
 struct TableName {
 	u16int version;
@@ -505,7 +522,7 @@
 };
 
 int read_TableName(Otf *o, TableName *v);
-void print_TableName(Biobuf *f, int indent, Otf *o, TableName *v);
+void print_TableName(Otfile *f, int indent, Otf *o, TableName *v);
 
 struct BigGlyphMetrics {
 	u8int height;
@@ -519,7 +536,7 @@
 };
 
 int read_BigGlyphMetrics(Otf *o, BigGlyphMetrics *v);
-void print_BigGlyphMetrics(Biobuf *f, int indent, Otf *o, BigGlyphMetrics *v);
+void print_BigGlyphMetrics(Otfile *f, int indent, Otf *o, BigGlyphMetrics *v);
 
 struct SmallGlyphMetrics {
 	u8int height;
@@ -530,7 +547,7 @@
 };
 
 int read_SmallGlyphMetrics(Otf *o, SmallGlyphMetrics *v);
-void print_SmallGlyphMetrics(Biobuf *f, int indent, Otf *o, SmallGlyphMetrics *v);
+void print_SmallGlyphMetrics(Otfile *f, int indent, Otf *o, SmallGlyphMetrics *v);
 
 struct SbitLineMetrics {
 	s8int ascender;
@@ -547,7 +564,7 @@
 };
 
 int read_SbitLineMetrics(Otf *o, SbitLineMetrics *v);
-void print_SbitLineMetrics(Biobuf *f, int indent, Otf *o, SbitLineMetrics *v);
+void print_SbitLineMetrics(Otfile *f, int indent, Otf *o, SbitLineMetrics *v);
 
 struct IndexSubtable1 {
 	u32int *sbitOffsets;
@@ -554,7 +571,7 @@
 };
 
 int read_IndexSubtable1(Otf *o, IndexSubtable1 *v);
-void print_IndexSubtable1(Biobuf *f, int indent, Otf *o, IndexSubtable1 *v);
+void print_IndexSubtable1(Otfile *f, int indent, Otf *o, IndexSubtable1 *v);
 
 struct IndexSubtable2 {
 	u32int imageSize;
@@ -562,7 +579,7 @@
 };
 
 int read_IndexSubtable2(Otf *o, IndexSubtable2 *v);
-void print_IndexSubtable2(Biobuf *f, int indent, Otf *o, IndexSubtable2 *v);
+void print_IndexSubtable2(Otfile *f, int indent, Otf *o, IndexSubtable2 *v);
 
 struct IndexSubtable3 {
 	u16int *sbitOffsets;
@@ -569,7 +586,7 @@
 };
 
 int read_IndexSubtable3(Otf *o, IndexSubtable3 *v);
-void print_IndexSubtable3(Biobuf *f, int indent, Otf *o, IndexSubtable3 *v);
+void print_IndexSubtable3(Otfile *f, int indent, Otf *o, IndexSubtable3 *v);
 
 struct GlyphIdOffsetPair {
 	u16int glyphID;
@@ -577,7 +594,7 @@
 };
 
 int read_GlyphIdOffsetPair(Otf *o, GlyphIdOffsetPair *v);
-void print_GlyphIdOffsetPair(Biobuf *f, int indent, Otf *o, GlyphIdOffsetPair *v);
+void print_GlyphIdOffsetPair(Otfile *f, int indent, Otf *o, GlyphIdOffsetPair *v);
 
 struct IndexSubtable4 {
 	u32int numGlyphs;
@@ -585,7 +602,7 @@
 };
 
 int read_IndexSubtable4(Otf *o, IndexSubtable4 *v);
-void print_IndexSubtable4(Biobuf *f, int indent, Otf *o, IndexSubtable4 *v);
+void print_IndexSubtable4(Otfile *f, int indent, Otf *o, IndexSubtable4 *v);
 
 struct IndexSubtable5 {
 	u32int imageSize;
@@ -595,7 +612,7 @@
 };
 
 int read_IndexSubtable5(Otf *o, IndexSubtable5 *v);
-void print_IndexSubtable5(Biobuf *f, int indent, Otf *o, IndexSubtable5 *v);
+void print_IndexSubtable5(Otfile *f, int indent, Otf *o, IndexSubtable5 *v);
 
 struct IndexSubtable {
 	u16int indexFormat;
@@ -609,7 +626,7 @@
 };
 
 int read_IndexSubtable(Otf *o, IndexSubtable *v);
-void print_IndexSubtable(Biobuf *f, int indent, Otf *o, IndexSubtable *v);
+void print_IndexSubtable(Otfile *f, int indent, Otf *o, IndexSubtable *v);
 
 struct IndexSubtableRecord {
 	u16int firstGlyphIndex;
@@ -619,7 +636,7 @@
 };
 
 int read_IndexSubtableRecord(Otf *o, IndexSubtableRecord *v);
-void print_IndexSubtableRecord(Biobuf *f, int indent, Otf *o, IndexSubtableRecord *v);
+void print_IndexSubtableRecord(Otfile *f, int indent, Otf *o, IndexSubtableRecord *v);
 
 enum { // BitmapSize
 	// flags
@@ -644,7 +661,7 @@
 };
 
 int read_BitmapSize(Otf *o, BitmapSize *v);
-void print_BitmapSize(Biobuf *f, int indent, Otf *o, BitmapSize *v);
+void print_BitmapSize(Otfile *f, int indent, Otf *o, BitmapSize *v);
 
 struct TableEBDT {
 	u16int majorVersion;
@@ -652,7 +669,7 @@
 };
 
 int read_TableEBDT(Otf *o, TableEBDT *v);
-void print_TableEBDT(Biobuf *f, int indent, Otf *o, TableEBDT *v);
+void print_TableEBDT(Otfile *f, int indent, Otf *o, TableEBDT *v);
 
 struct TableEBLC {
 	// u16int majorVersion;
@@ -662,7 +679,7 @@
 };
 
 int read_TableEBLC(Otf *o, TableEBLC *v);
-void print_TableEBLC(Biobuf *f, int indent, Otf *o, TableEBLC *v);
+void print_TableEBLC(Otfile *f, int indent, Otf *o, TableEBLC *v);
 
 struct AttachList {
 	u16int coverageOffset;
@@ -671,7 +688,7 @@
 };
 
 int read_AttachList(Otf *o, AttachList *v);
-void print_AttachList(Biobuf *f, int indent, Otf *o, AttachList *v);
+void print_AttachList(Otfile *f, int indent, Otf *o, AttachList *v);
 
 struct AttachPoint {
 	u16int pointCount;
@@ -679,7 +696,7 @@
 };
 
 int read_AttachPoint(Otf *o, AttachPoint *v);
-void print_AttachPoint(Biobuf *f, int indent, Otf *o, AttachPoint *v);
+void print_AttachPoint(Otfile *f, int indent, Otf *o, AttachPoint *v);
 
 struct LigCaretList {
 	u16int coverageOffset;
@@ -688,7 +705,7 @@
 };
 
 int read_LigCaretList(Otf *o, LigCaretList *v);
-void print_LigCaretList(Biobuf *f, int indent, Otf *o, LigCaretList *v);
+void print_LigCaretList(Otfile *f, int indent, Otf *o, LigCaretList *v);
 
 struct LigGlyph {
 	u16int caretCount;
@@ -696,7 +713,7 @@
 };
 
 int read_LigGlyph(Otf *o, LigGlyph *v);
-void print_LigGlyph(Biobuf *f, int indent, Otf *o, LigGlyph *v);
+void print_LigGlyph(Otfile *f, int indent, Otf *o, LigGlyph *v);
 
 struct CaretValue {
 	u16int format;
@@ -706,7 +723,7 @@
 };
 
 int read_CaretValue(Otf *o, CaretValue *v);
-void print_CaretValue(Biobuf *f, int indent, Otf *o, CaretValue *v);
+void print_CaretValue(Otfile *f, int indent, Otf *o, CaretValue *v);
 
 struct ValueRecord {
 	s16int xPlacement;
@@ -720,7 +737,7 @@
 };
 
 int read_ValueRecord(Otf *o, ValueRecord *v);
-void print_ValueRecord(Biobuf *f, int indent, Otf *o, ValueRecord *v);
+void print_ValueRecord(Otfile *f, int indent, Otf *o, ValueRecord *v);
 
 struct SinglePos {
 	u16int format;
@@ -732,7 +749,7 @@
 };
 
 int read_SinglePos(Otf *o, SinglePos *v);
-void print_SinglePos(Biobuf *f, int indent, Otf *o, SinglePos *v);
+void print_SinglePos(Otfile *f, int indent, Otf *o, SinglePos *v);
 
 struct TableGDEF {
 	// u16int majorVersion;
@@ -746,7 +763,7 @@
 };
 
 int read_TableGDEF(Otf *o, TableGDEF *v);
-void print_TableGDEF(Biobuf *f, int indent, Otf *o, TableGDEF *v);
+void print_TableGDEF(Otfile *f, int indent, Otf *o, TableGDEF *v);
 
 struct LangSys {
 	// u16int lookupOrderOffset;
@@ -756,7 +773,7 @@
 };
 
 int read_LangSys(Otf *o, LangSys *v);
-void print_LangSys(Biobuf *f, int indent, Otf *o, LangSys *v);
+void print_LangSys(Otfile *f, int indent, Otf *o, LangSys *v);
 
 struct LangSysRecord {
 	u32int langSysTag;
@@ -765,7 +782,7 @@
 };
 
 int read_LangSysRecord(Otf *o, LangSysRecord *v);
-void print_LangSysRecord(Biobuf *f, int indent, Otf *o, LangSysRecord *v);
+void print_LangSysRecord(Otfile *f, int indent, Otf *o, LangSysRecord *v);
 
 struct Script {
 	u16int defaultLangSysOffset;
@@ -775,7 +792,7 @@
 };
 
 int read_Script(Otf *o, Script *v);
-void print_Script(Biobuf *f, int indent, Otf *o, Script *v);
+void print_Script(Otfile *f, int indent, Otf *o, Script *v);
 
 struct ScriptRecord {
 	u32int scriptTag;
@@ -784,7 +801,7 @@
 };
 
 int read_ScriptRecord(Otf *o, ScriptRecord *v);
-void print_ScriptRecord(Biobuf *f, int indent, Otf *o, ScriptRecord *v);
+void print_ScriptRecord(Otfile *f, int indent, Otf *o, ScriptRecord *v);
 
 struct ScriptList {
 	u16int scriptCount;
@@ -792,7 +809,7 @@
 };
 
 int read_ScriptList(Otf *o, ScriptList *v);
-void print_ScriptList(Biobuf *f, int indent, Otf *o, ScriptList *v);
+void print_ScriptList(Otfile *f, int indent, Otf *o, ScriptList *v);
 
 struct Feature {
 	u16int featureParamsOffset;
@@ -801,7 +818,7 @@
 };
 
 int read_Feature(Otf *o, Feature *v);
-void print_Feature(Biobuf *f, int indent, Otf *o, Feature *v);
+void print_Feature(Otfile *f, int indent, Otf *o, Feature *v);
 
 struct FeatureRecord {
 	u32int featureTag;
@@ -810,7 +827,7 @@
 };
 
 int read_FeatureRecord(Otf *o, FeatureRecord *v);
-void print_FeatureRecord(Biobuf *f, int indent, Otf *o, FeatureRecord *v);
+void print_FeatureRecord(Otfile *f, int indent, Otf *o, FeatureRecord *v);
 
 struct FeatureList {
 	u16int featureCount;
@@ -818,7 +835,7 @@
 };
 
 int read_FeatureList(Otf *o, FeatureList *v);
-void print_FeatureList(Biobuf *f, int indent, Otf *o, FeatureList *v);
+void print_FeatureList(Otfile *f, int indent, Otf *o, FeatureList *v);
 
 struct Lookup {
 	u16int lookupType;
@@ -829,7 +846,7 @@
 };
 
 int read_Lookup(Otf *o, Lookup *v);
-void print_Lookup(Biobuf *f, int indent, Otf *o, Lookup *v);
+void print_Lookup(Otfile *f, int indent, Otf *o, Lookup *v);
 
 struct LookupList {
 	u16int lookupCount;
@@ -837,7 +854,7 @@
 };
 
 int read_LookupList(Otf *o, LookupList *v);
-void print_LookupList(Biobuf *f, int indent, Otf *o, LookupList *v);
+void print_LookupList(Otfile *f, int indent, Otf *o, LookupList *v);
 
 struct TableGPOS {
 	// u16int majorVersion;
@@ -852,7 +869,7 @@
 };
 
 int read_TableGPOS(Otf *o, TableGPOS *v);
-void print_TableGPOS(Biobuf *f, int indent, Otf *o, TableGPOS *v);
+void print_TableGPOS(Otfile *f, int indent, Otf *o, TableGPOS *v);
 
 struct TableGSUB {
 	// u16int majorVersion;
@@ -866,7 +883,7 @@
 };
 
 int read_TableGSUB(Otf *o, TableGSUB *v);
-void print_TableGSUB(Biobuf *f, int indent, Otf *o, TableGSUB *v);
+void print_TableGSUB(Otfile *f, int indent, Otf *o, TableGSUB *v);
 
 struct MathValueRecord {
 	s16int value;
@@ -874,7 +891,7 @@
 };
 
 int read_MathValueRecord(Otf *o, MathValueRecord *v);
-void print_MathValueRecord(Biobuf *f, int indent, Otf *o, MathValueRecord *v);
+void print_MathValueRecord(Otfile *f, int indent, Otf *o, MathValueRecord *v);
 
 struct MathConstants {
 	s16int scriptPercentScaleDown;
@@ -936,7 +953,7 @@
 };
 
 int read_MathConstants(Otf *o, MathConstants *v);
-void print_MathConstants(Biobuf *f, int indent, Otf *o, MathConstants *v);
+void print_MathConstants(Otfile *f, int indent, Otf *o, MathConstants *v);
 
 struct MathItalicsCorrectionInfo {
 	u16int italicsCorrectionCoverageOffset;
@@ -945,7 +962,7 @@
 };
 
 int read_MathItalicsCorrectionInfo(Otf *o, MathItalicsCorrectionInfo *v);
-void print_MathItalicsCorrectionInfo(Biobuf *f, int indent, Otf *o, MathItalicsCorrectionInfo *v);
+void print_MathItalicsCorrectionInfo(Otfile *f, int indent, Otf *o, MathItalicsCorrectionInfo *v);
 
 struct MathTopAccentAttachment {
 	u16int topAccentCoverageOffset;
@@ -954,7 +971,7 @@
 };
 
 int read_MathTopAccentAttachment(Otf *o, MathTopAccentAttachment *v);
-void print_MathTopAccentAttachment(Biobuf *f, int indent, Otf *o, MathTopAccentAttachment *v);
+void print_MathTopAccentAttachment(Otfile *f, int indent, Otf *o, MathTopAccentAttachment *v);
 
 struct MathKernInfoRecord {
 	u16int topRightMathKernOffset;
@@ -964,7 +981,7 @@
 };
 
 int read_MathKernInfoRecord(Otf *o, MathKernInfoRecord *v);
-void print_MathKernInfoRecord(Biobuf *f, int indent, Otf *o, MathKernInfoRecord *v);
+void print_MathKernInfoRecord(Otfile *f, int indent, Otf *o, MathKernInfoRecord *v);
 
 struct MathKernInfo {
 	u16int mathKernCoverageOffset;
@@ -973,7 +990,7 @@
 };
 
 int read_MathKernInfo(Otf *o, MathKernInfo *v);
-void print_MathKernInfo(Biobuf *f, int indent, Otf *o, MathKernInfo *v);
+void print_MathKernInfo(Otfile *f, int indent, Otf *o, MathKernInfo *v);
 
 struct MathKern {
 	u16int heightCount;
@@ -982,7 +999,7 @@
 };
 
 int read_MathKern(Otf *o, MathKern *v);
-void print_MathKern(Biobuf *f, int indent, Otf *o, MathKern *v);
+void print_MathKern(Otfile *f, int indent, Otf *o, MathKern *v);
 
 struct Coverage1 {
 	u16int glyphCount;
@@ -990,7 +1007,7 @@
 };
 
 int read_Coverage1(Otf *o, Coverage1 *v);
-void print_Coverage1(Biobuf *f, int indent, Otf *o, Coverage1 *v);
+void print_Coverage1(Otfile *f, int indent, Otf *o, Coverage1 *v);
 
 struct RangeRecord {
 	u16int startGlyphID;
@@ -999,7 +1016,7 @@
 };
 
 int read_RangeRecord(Otf *o, RangeRecord *v);
-void print_RangeRecord(Biobuf *f, int indent, Otf *o, RangeRecord *v);
+void print_RangeRecord(Otfile *f, int indent, Otf *o, RangeRecord *v);
 
 struct Coverage2 {
 	u16int rangeCount;
@@ -1007,7 +1024,7 @@
 };
 
 int read_Coverage2(Otf *o, Coverage2 *v);
-void print_Coverage2(Biobuf *f, int indent, Otf *o, Coverage2 *v);
+void print_Coverage2(Otfile *f, int indent, Otf *o, Coverage2 *v);
 
 struct Coverage {
 	u16int format;
@@ -1016,7 +1033,7 @@
 };
 
 int read_Coverage(Otf *o, Coverage *v);
-void print_Coverage(Biobuf *f, int indent, Otf *o, Coverage *v);
+void print_Coverage(Otfile *f, int indent, Otf *o, Coverage *v);
 
 struct MathVariants {
 	u16int minConnectorOverlap;
@@ -1031,7 +1048,7 @@
 };
 
 int read_MathVariants(Otf *o, MathVariants *v);
-void print_MathVariants(Biobuf *f, int indent, Otf *o, MathVariants *v);
+void print_MathVariants(Otfile *f, int indent, Otf *o, MathVariants *v);
 
 struct MathGlyphInfo {
 	u16int mathItalicsCorrectionInfoOffset;
@@ -1045,7 +1062,7 @@
 };
 
 int read_MathGlyphInfo(Otf *o, MathGlyphInfo *v);
-void print_MathGlyphInfo(Biobuf *f, int indent, Otf *o, MathGlyphInfo *v);
+void print_MathGlyphInfo(Otfile *f, int indent, Otf *o, MathGlyphInfo *v);
 
 struct MathGlyphVariantRecord {
 	u16int variantGlyph;
@@ -1053,7 +1070,7 @@
 };
 
 int read_MathGlyphVariantRecord(Otf *o, MathGlyphVariantRecord *v);
-void print_MathGlyphVariantRecord(Biobuf *f, int indent, Otf *o, MathGlyphVariantRecord *v);
+void print_MathGlyphVariantRecord(Otfile *f, int indent, Otf *o, MathGlyphVariantRecord *v);
 
 struct GlyphPart {
 	u16int glyphID;
@@ -1064,7 +1081,7 @@
 };
 
 int read_GlyphPart(Otf *o, GlyphPart *v);
-void print_GlyphPart(Biobuf *f, int indent, Otf *o, GlyphPart *v);
+void print_GlyphPart(Otfile *f, int indent, Otf *o, GlyphPart *v);
 
 struct GlyphAssembly {
 	MathValueRecord italicsCorrection;
@@ -1073,7 +1090,7 @@
 };
 
 int read_GlyphAssembly(Otf *o, GlyphAssembly *v);
-void print_GlyphAssembly(Biobuf *f, int indent, Otf *o, GlyphAssembly *v);
+void print_GlyphAssembly(Otfile *f, int indent, Otf *o, GlyphAssembly *v);
 
 struct MathGlyphConstruction {
 	u16int glyphAssemblyOffset;
@@ -1083,7 +1100,7 @@
 };
 
 int read_MathGlyphConstruction(Otf *o, MathGlyphConstruction *v);
-void print_MathGlyphConstruction(Biobuf *f, int indent, Otf *o, MathGlyphConstruction *v);
+void print_MathGlyphConstruction(Otfile *f, int indent, Otf *o, MathGlyphConstruction *v);
 
 struct TableMATH {
 	// u16int majorVersion;
@@ -1097,7 +1114,7 @@
 };
 
 int read_TableMATH(Otf *o, TableMATH *v);
-void print_TableMATH(Biobuf *f, int indent, Otf *o, TableMATH *v);
+void print_TableMATH(Otfile *f, int indent, Otf *o, TableMATH *v);
 
 struct KernPair {
 	u16int left;
@@ -1106,7 +1123,7 @@
 };
 
 int read_KernPair(Otf *o, KernPair *v);
-void print_KernPair(Biobuf *f, int indent, Otf *o, KernPair *v);
+void print_KernPair(Otfile *f, int indent, Otf *o, KernPair *v);
 
 struct KernSubtable0 {
 	u16int nPairs;
@@ -1117,7 +1134,7 @@
 };
 
 int read_KernSubtable0(Otf *o, KernSubtable0 *v);
-void print_KernSubtable0(Biobuf *f, int indent, Otf *o, KernSubtable0 *v);
+void print_KernSubtable0(Otfile *f, int indent, Otf *o, KernSubtable0 *v);
 
 struct KernClass {
 	u16int firstGlyph;
@@ -1126,7 +1143,7 @@
 };
 
 int read_KernClass(Otf *o, KernClass *v);
-void print_KernClass(Biobuf *f, int indent, Otf *o, KernClass *v);
+void print_KernClass(Otfile *f, int indent, Otf *o, KernClass *v);
 
 struct KernSubtable2 {
 	u16int rowWidth;
@@ -1139,7 +1156,7 @@
 };
 
 int read_KernSubtable2(Otf *o, KernSubtable2 *v);
-void print_KernSubtable2(Biobuf *f, int indent, Otf *o, KernSubtable2 *v);
+void print_KernSubtable2(Otfile *f, int indent, Otf *o, KernSubtable2 *v);
 
 struct KernSubtable {
 	// u16int version;
@@ -1148,7 +1165,7 @@
 };
 
 int read_KernSubtable(Otf *o, KernSubtable *v);
-void print_KernSubtable(Biobuf *f, int indent, Otf *o, KernSubtable *v);
+void print_KernSubtable(Otfile *f, int indent, Otf *o, KernSubtable *v);
 
 struct TableKern {
 	// u16int version;
@@ -1157,7 +1174,7 @@
 };
 
 int read_TableKern(Otf *o, TableKern *v);
-void print_TableKern(Biobuf *f, int indent, Otf *o, TableKern *v);
+void print_TableKern(Otfile *f, int indent, Otf *o, TableKern *v);
 
 struct TableLoca {
 	u16int *shortOffsets;
@@ -1165,7 +1182,7 @@
 };
 
 int read_TableLoca(Otf *o, TableLoca *v);
-void print_TableLoca(Biobuf *f, int indent, Otf *o, TableLoca *v);
+void print_TableLoca(Otfile *f, int indent, Otf *o, TableLoca *v);
 
 enum { // VariationAxisRecord
 	// flags
@@ -1182,7 +1199,7 @@
 };
 
 int read_VariationAxisRecord(Otf *o, VariationAxisRecord *v);
-void print_VariationAxisRecord(Biobuf *f, int indent, Otf *o, VariationAxisRecord *v);
+void print_VariationAxisRecord(Otfile *f, int indent, Otf *o, VariationAxisRecord *v);
 
 struct UserTuple {
 	float *coordinates;
@@ -1189,7 +1206,7 @@
 };
 
 int read_UserTuple(Otf *o, UserTuple *v);
-void print_UserTuple(Biobuf *f, int indent, Otf *o, UserTuple *v);
+void print_UserTuple(Otfile *f, int indent, Otf *o, UserTuple *v);
 
 struct InstanceRecord {
 	u16int subfamilyNameID;
@@ -1199,7 +1216,7 @@
 };
 
 int read_InstanceRecord(Otf *o, InstanceRecord *v);
-void print_InstanceRecord(Biobuf *f, int indent, Otf *o, InstanceRecord *v);
+void print_InstanceRecord(Otfile *f, int indent, Otf *o, InstanceRecord *v);
 
 struct AxisInstances {
 	VariationAxisRecord *axes;
@@ -1207,7 +1224,7 @@
 };
 
 int read_AxisInstances(Otf *o, AxisInstances *v);
-void print_AxisInstances(Biobuf *f, int indent, Otf *o, AxisInstances *v);
+void print_AxisInstances(Otfile *f, int indent, Otf *o, AxisInstances *v);
 
 struct TableFvar {
 	// u16int majorVersion;
@@ -1222,7 +1239,7 @@
 };
 
 int read_TableFvar(Otf *o, TableFvar *v);
-void print_TableFvar(Biobuf *f, int indent, Otf *o, TableFvar *v);
+void print_TableFvar(Otfile *f, int indent, Otf *o, TableFvar *v);
 
 struct RegionAxisCoordinates {
 	float startCoord;
@@ -1231,7 +1248,7 @@
 };
 
 int read_RegionAxisCoordinates(Otf *o, RegionAxisCoordinates *v);
-void print_RegionAxisCoordinates(Biobuf *f, int indent, Otf *o, RegionAxisCoordinates *v);
+void print_RegionAxisCoordinates(Otfile *f, int indent, Otf *o, RegionAxisCoordinates *v);
 
 struct VariationRegion {
 	RegionAxisCoordinates *regionAxes;
@@ -1238,7 +1255,7 @@
 };
 
 int read_VariationRegion(Otf *o, VariationRegion *v);
-void print_VariationRegion(Biobuf *f, int indent, Otf *o, VariationRegion *v);
+void print_VariationRegion(Otfile *f, int indent, Otf *o, VariationRegion *v);
 
 struct VariationRegionList {
 	u16int axisCount;
@@ -1247,7 +1264,7 @@
 };
 
 int read_VariationRegionList(Otf *o, VariationRegionList *v);
-void print_VariationRegionList(Biobuf *f, int indent, Otf *o, VariationRegionList *v);
+void print_VariationRegionList(Otfile *f, int indent, Otf *o, VariationRegionList *v);
 
 struct ItemVariationData {
 	u16int itemCount;
@@ -1257,7 +1274,7 @@
 };
 
 int read_ItemVariationData(Otf *o, ItemVariationData *v);
-void print_ItemVariationData(Biobuf *f, int indent, Otf *o, ItemVariationData *v);
+void print_ItemVariationData(Otfile *f, int indent, Otf *o, ItemVariationData *v);
 
 struct ItemVariationStore {
 	// u16int format;
@@ -1267,7 +1284,7 @@
 };
 
 int read_ItemVariationStore(Otf *o, ItemVariationStore *v);
-void print_ItemVariationStore(Biobuf *f, int indent, Otf *o, ItemVariationStore *v);
+void print_ItemVariationStore(Otfile *f, int indent, Otf *o, ItemVariationStore *v);
 
 struct DeltaSetIndexMap {
 	u8int format;
@@ -1278,7 +1295,7 @@
 };
 
 int read_DeltaSetIndexMap(Otf *o, DeltaSetIndexMap *v);
-void print_DeltaSetIndexMap(Biobuf *f, int indent, Otf *o, DeltaSetIndexMap *v);
+void print_DeltaSetIndexMap(Otfile *f, int indent, Otf *o, DeltaSetIndexMap *v);
 
 struct TableHVAR {
 	// u16int majorVersion;
@@ -1294,7 +1311,7 @@
 };
 
 int read_TableHVAR(Otf *o, TableHVAR *v);
-void print_TableHVAR(Biobuf *f, int indent, Otf *o, TableHVAR *v);
+void print_TableHVAR(Otfile *f, int indent, Otf *o, TableHVAR *v);
 
 struct TableFFTM {
 	u32int version;
@@ -1304,7 +1321,7 @@
 };
 
 int read_TableFFTM(Otf *o, TableFFTM *v);
-void print_TableFFTM(Biobuf *f, int indent, Otf *o, TableFFTM *v);
+void print_TableFFTM(Otfile *f, int indent, Otf *o, TableFFTM *v);
 
 struct SignatureBlock1 {
 	// u16int reserved1;
@@ -1314,7 +1331,7 @@
 };
 
 int read_SignatureBlock1(Otf *o, SignatureBlock1 *v);
-void print_SignatureBlock1(Biobuf *f, int indent, Otf *o, SignatureBlock1 *v);
+void print_SignatureBlock1(Otfile *f, int indent, Otf *o, SignatureBlock1 *v);
 
 struct SignatureRecord {
 	u32int format;
@@ -1324,7 +1341,7 @@
 };
 
 int read_SignatureRecord(Otf *o, SignatureRecord *v);
-void print_SignatureRecord(Biobuf *f, int indent, Otf *o, SignatureRecord *v);
+void print_SignatureRecord(Otfile *f, int indent, Otf *o, SignatureRecord *v);
 
 enum { // TableDSIG
 	// flags
@@ -1339,7 +1356,7 @@
 };
 
 int read_TableDSIG(Otf *o, TableDSIG *v);
-void print_TableDSIG(Biobuf *f, int indent, Otf *o, TableDSIG *v);
+void print_TableDSIG(Otfile *f, int indent, Otf *o, TableDSIG *v);
 
 struct AxisRecord {
 	u32int axisTag;
@@ -1349,7 +1366,7 @@
 };
 
 int read_AxisRecord(Otf *o, AxisRecord *v);
-void print_AxisRecord(Biobuf *f, int indent, Otf *o, AxisRecord *v);
+void print_AxisRecord(Otfile *f, int indent, Otf *o, AxisRecord *v);
 
 struct DesignAxes {
 	AxisRecord *designAxes;
@@ -1357,7 +1374,7 @@
 };
 
 int read_DesignAxes(Otf *o, DesignAxes *v);
-void print_DesignAxes(Biobuf *f, int indent, Otf *o, DesignAxes *v);
+void print_DesignAxes(Otfile *f, int indent, Otf *o, DesignAxes *v);
 
 struct TableSTAT {
 	// u16int majorVersion;
@@ -1372,7 +1389,7 @@
 };
 
 int read_TableSTAT(Otf *o, TableSTAT *v);
-void print_TableSTAT(Biobuf *f, int indent, Otf *o, TableSTAT *v);
+void print_TableSTAT(Otfile *f, int indent, Otf *o, TableSTAT *v);
 
 struct GaspRange {
 	u16int rangeMaxPPEM;
@@ -1380,7 +1397,7 @@
 };
 
 int read_GaspRange(Otf *o, GaspRange *v);
-void print_GaspRange(Biobuf *f, int indent, Otf *o, GaspRange *v);
+void print_GaspRange(Otfile *f, int indent, Otf *o, GaspRange *v);
 
 struct TableGasp {
 	u16int version;
@@ -1389,7 +1406,7 @@
 };
 
 int read_TableGasp(Otf *o, TableGasp *v);
-void print_TableGasp(Biobuf *f, int indent, Otf *o, TableGasp *v);
+void print_TableGasp(Otfile *f, int indent, Otf *o, TableGasp *v);
 
 struct Tuple {
 	float *coordinates;
@@ -1396,7 +1413,7 @@
 };
 
 int read_Tuple(Otf *o, Tuple *v);
-void print_Tuple(Biobuf *f, int indent, Otf *o, Tuple *v);
+void print_Tuple(Otfile *f, int indent, Otf *o, Tuple *v);
 
 enum { // TupleVariationHeader
 	// tupleIndex
@@ -1414,7 +1431,7 @@
 };
 
 int read_TupleVariationHeader(Otf *o, TupleVariationHeader *v);
-void print_TupleVariationHeader(Biobuf *f, int indent, Otf *o, TupleVariationHeader *v);
+void print_TupleVariationHeader(Otfile *f, int indent, Otf *o, TupleVariationHeader *v);
 
 enum { // GlyphVariationData
 	// tupleVariationCount
@@ -1428,7 +1445,7 @@
 };
 
 int read_GlyphVariationData(Otf *o, GlyphVariationData *v);
-void print_GlyphVariationData(Biobuf *f, int indent, Otf *o, GlyphVariationData *v);
+void print_GlyphVariationData(Otfile *f, int indent, Otf *o, GlyphVariationData *v);
 
 enum { // TableGvar
 	// flags
@@ -1450,7 +1467,7 @@
 };
 
 int read_TableGvar(Otf *o, TableGvar *v);
-void print_TableGvar(Biobuf *f, int indent, Otf *o, TableGvar *v);
+void print_TableGvar(Otfile *f, int indent, Otf *o, TableGvar *v);
 
 struct AxisValueMap {
 	float fromCoordinate;
@@ -1458,7 +1475,7 @@
 };
 
 int read_AxisValueMap(Otf *o, AxisValueMap *v);
-void print_AxisValueMap(Biobuf *f, int indent, Otf *o, AxisValueMap *v);
+void print_AxisValueMap(Otfile *f, int indent, Otf *o, AxisValueMap *v);
 
 struct SegmentMaps {
 	u16int positionMapCount;
@@ -1466,7 +1483,7 @@
 };
 
 int read_SegmentMaps(Otf *o, SegmentMaps *v);
-void print_SegmentMaps(Biobuf *f, int indent, Otf *o, SegmentMaps *v);
+void print_SegmentMaps(Otfile *f, int indent, Otf *o, SegmentMaps *v);
 
 struct TableAvar {
 	// u16int majorVersion;
@@ -1477,7 +1494,7 @@
 };
 
 int read_TableAvar(Otf *o, TableAvar *v);
-void print_TableAvar(Biobuf *f, int indent, Otf *o, TableAvar *v);
+void print_TableAvar(Otfile *f, int indent, Otf *o, TableAvar *v);
 
 struct TableOS∕2 {
 	u16int version;
@@ -1522,7 +1539,7 @@
 };
 
 int read_TableOS∕2(Otf *o, TableOS∕2 *v);
-void print_TableOS∕2(Biobuf *f, int indent, Otf *o, TableOS∕2 *v);
+void print_TableOS∕2(Otfile *f, int indent, Otf *o, TableOS∕2 *v);
 
 struct TableRecord {
 	u32int tableTag;
@@ -1530,11 +1547,11 @@
 	u32int offset;
 	u32int length;
 	void *parsed;
-	void (*print)(Biobuf *f, int indent, Otf *o, void *parsed);
+	void (*print)(Otfile *f, int indent, Otf *o, void *parsed);
 };
 
 int read_TableRecord(Otf *o, TableRecord *v);
-void print_TableRecord(Biobuf *f, int indent, Otf *o, TableRecord *v);
+void print_TableRecord(Otfile *f, int indent, Otf *o, TableRecord *v);
 
 struct TableDirectory {
 	u32int sfntVersion;
@@ -1570,4 +1587,4 @@
 };
 
 int read_TableDirectory(Otf *o, TableDirectory *v);
-void print_TableDirectory(Biobuf *f, int indent, Otf *o, TableDirectory *v);
+void print_TableDirectory(Otfile *f, int indent, Otf *o, TableDirectory *v);
--- a/otf.h.in
+++ b/otf.h.in
@@ -1,7 +1,28 @@
 /* this file is generated. do not modify. */
 typedef struct Otf Otf;
+#ifdef __unix__
+#include <stdint.h>
+typedef int8_t s8int;
+typedef int16_t s16int;
+typedef int32_t s32int;
+typedef int64_t s64int;
+typedef uint8_t u8int;
+typedef uint16_t u16int;
+typedef uint32_t u32int;
+typedef uint64_t u64int;
+#else
 #pragma incomplete Otf
+#endif
 
+typedef struct Otfile Otfile;
+
+struct Otfile {
+	void *aux;
+	int (*seek)(void *aux, int off, int whence);
+	int (*read)(void *aux, void *dst, int sz);
+	int (*print)(void *aux, const char *fmt, ...);
+};
+
 typedef struct ComponentGlyph ComponentGlyph;
 
 enum {
@@ -50,13 +71,8 @@
 
 extern int indentΔ;
 
-#pragma varargck type "T" s64int
-#pragma varargck type "t" u32int
-#pragma varargck type "V" u32int
-
-void otfinit(void);
-Otf *otfopen(char *path);
-void otfprint(Otf *o, Biobuf *out, int indent);
+Otf *otfopen(Otfile *in);
+void otfprint(Otf *o, Otfile *out, int indent);
 void otfclose(Otf *o);
 
 /* FIXME these will go, this is for debugging and designing the drawing logic */
@@ -63,3 +79,4 @@
 typedef struct Glyf Glyf;
 Glyf *otfglyf(Otf *o, int index);
 int otfglyfnum(Otf *o);
+u8int *otfdrawglyf(Glyf *g, int h, int *wo);
--- a/otf.rkt
+++ b/otf.rkt
@@ -13,27 +13,29 @@
   (member type
           '(uint8 int8 uint16 int16 uint24 uint32 int32 Version16Dot16 Offset16 Offset24 Offset32)))
 
+(define ufmt (if (plan9?) "%ud" "%u"))
+
 (mktype String 8 char "%s")
 (mktype String-UTF16 8 char "%s")
-(mktype uint8 8 u8int "%ud")
+(mktype uint8 8 u8int ufmt)
 (mktype int8 8 s8int "%d")
-(mktype uint16 16 u16int "%ud")
+(mktype uint16 16 u16int ufmt)
 (mktype int16 16 s16int "%d")
-(mktype uint24 24 u32int "%ud")
-(mktype uint32 32 u32int "%ud")
+(mktype uint24 24 u32int ufmt)
+(mktype uint32 32 u32int ufmt)
 (mktype int32 32 s32int "%d")
 (mktype FWORD 16 s16int "%d")
-(mktype UFWORD 16 u16int "%ud")
+(mktype UFWORD 16 u16int ufmt)
 (mktype LONGDATETIME
         64
         s64int
-        "%T"
+        (cons (if (plan9?) "%τ" "%s") (λ (v) (~a "fmttime(" v ")")))
         (λ (b index [offset #f]) (~a "(" ((autoparse 64 's64int) b index offset) ") - 2082844800LL")))
-(mktype Tag 32 u32int "%t")
-(mktype Offset16 16 u16int "%ud")
-(mktype Offset24 24 u32int "%ud")
-(mktype Offset32 32 u32int "%ud")
-(mktype Version16Dot16 32 u32int "%V")
+(mktype Tag 32 u32int (cons "%c%c%c%c" (λ (v) (~a v ">>24, " v ">>16, " v ">>8, " v ">>0"))))
+(mktype Offset16 16 u16int ufmt)
+(mktype Offset24 24 u32int ufmt)
+(mktype Offset32 32 u32int ufmt)
+(mktype Version16Dot16 32 u32int (cons "%d.%d" (λ (v) (~a v ">>16, " v "&0xffff"))))
 (mktype Fixed
         32
         float
@@ -217,10 +219,10 @@
                    (~a "	goto err;")))
        (cons 'print
              (list (~a "if(v->component != nil){")
-                   (~a "	Bprint(f, \"%*s%s:\\n\", indent, \"\", \"component\");")
+                   (~a "	f->print(f->aux, \"%*s%s:\\n\", indent, \"\", \"component\");")
                    (~a "	print_ComponentGlyph(f, indent+indentΔ, o, v->component);")
                    (~a "}else if(v->simple != nil){")
-                   (~a "	Bprint(f, \"%*s%s:\\n\", indent, \"\", \"simple\");")
+                   (~a "	f->print(f->aux, \"%*s%s:\\n\", indent, \"\", \"simple\");")
                    (~a "	print_SimpleGlyph(f, indent+indentΔ, o, v->simple);")
                    (~a "}")))))
 
@@ -847,7 +849,7 @@
          {SegmentMaps axisSegmentMaps [axisCount]}
          #:tag "avar")
 
-(mkcmplx TableOS∕2
+(mkcmplx TableOS/2
          {uint16 version (<= 5)}
          {FWORD xAvgCharWidth}
          {uint16 usWeightClass}
@@ -897,17 +899,14 @@
          #:extra
          (list (cons 'field
                      (list (~a "void *parsed;")
-                           (~a "void (*print)(Biobuf *f, int indent, Otf *o, void *parsed);")))
+                           (~a "void (*print)(Otfile *f, int indent, Otf *o, void *parsed);")))
                (cons 'print
                      (list (~a "if(v->print != nil && v->parsed != nil)")
                            (~a "	v->print(f, indent+indentΔ, o, v->parsed);")))))
 
-(define (c-friendly-name t)
-  (string-replace (string-trim (string-downcase t)) "/" "∕"))
-
 (define (tagged-tables-fields tagged)
   (define (ptr c)
-    (c-friendly-name (cmplx-tag c)))
+    (c-friendly-name (cmplx-tag c) #:downcase #t))
   (define (case-statement c)
     (define tag (cmplx-tag c))
     (define (ft t i)
@@ -955,7 +954,7 @@
                     (~a "		switch(rec->tableTag){")
                     (indent (indent (map case-statement tagged)))
                     (~a "		default:")
-                    (~a "			fprint(2, \"no parser for \\\"%t\\\"\\n\", rec->tableTag);")
+                    (~a "			// FIXME fprint(2, \"no parser for \\\"%t\\\"\\n\", rec->tableTag);")
                     (~a "			break;")
                     (~a "		}")
                     (~a "		if(otfpoprange(o) < 0)")
--- /dev/null
+++ b/plan9.c
@@ -1,0 +1,8 @@
+#include "otfsys.h"
+
+Tmfmt
+fmttime(vlong v)
+{
+	Tm t;
+	return tmfmt(tmtime(&t, v, nil), nil);
+}
--- /dev/null
+++ b/plan9/otfsys.h
@@ -1,0 +1,5 @@
+#pragma once
+#include <u.h>
+#include <libc.h>
+
+Tmfmt fmttime(vlong v);
--- /dev/null
+++ b/rast.c
@@ -1,0 +1,527 @@
+/*
+ * Recommended reading:
+ *
+ * Wavelet Rasterization
+ *                 (2011) J. Manson, S.Schaefer
+ *
+ * A Simple and Fast Line-Clipping Method as a Scratch Extension for Computer Graphics Education
+ *                 (2019) Dimitrios Matthes, Vasileios Drakopoulos
+ *
+ * Clipping of Bézier Curves
+ *                 (1985) Fuhua Cheng, Chi-Cheng Lin
+ *
+ * On the numerical condition of polynomials in Bernstein form
+ *                 (1987) R. T. Farouki, V. T. Rajan
+ *
+ * Numerical Condition of Polynomials in Different Forms
+ *                 (2001) Hong Zhang
+ *
+ * Computer Aided Geometric Design
+ *                 (2017) Thomas W. Sederberg
+ */
+#include "otfsys.h"
+#include "otf.h"
+
+typedef struct SegQ SegQ;
+typedef struct SegC SegC;
+typedef struct Spt Spt;
+typedef double Sval;
+
+struct Spt {
+	Sval x;
+	Sval y;
+};
+
+struct SegQ {
+	union {
+		struct {
+			union {
+				Spt p0;
+				Sval v0[2];
+			};
+			union {
+				Spt p1;
+				Sval v1[2];
+			};
+			union {
+				Spt p2;
+				Sval v2[2];
+			};
+		};
+		Sval v[3*2];
+	};
+};
+
+/* the divisions when calculating coefficients are reduced,
+ * thus pixel value range is [0.0-QBZR_PIX_SCALE] instead of [0.0-1.0]
+ */
+#define QBZR_PIX_SCALE 4.0
+
+#define ε 1.0e-10
+
+static int
+closest²(int v)
+{
+	v--;
+	v |= v>>1;
+	v |= v>>2;
+	v |= v>>4;
+	v |= v>>8;
+	v |= v>>16;
+	return v + 1;
+}
+
+static int
+qslv(Sval *qs, Sval a, Sval b, Sval c)
+{
+	Sval p, q, d;
+	int n;
+
+#define ₀(x) (x > -ε && x < ε)
+	if(₀(a)){
+		if(₀(b))
+			return 0;
+		qs[0] = -c/b;
+		return qs[0] > 0 && qs[0] < 1;
+	}
+
+	p = b/(2.0*a);
+	q = c/a;
+	d = p*p - q;
+
+	if(₀(d)){
+		qs[0] = -p;
+		return qs[0] > 0 && qs[0] < 1;
+	}
+#undef ₀
+
+	if(d < 0.0)
+		return 0;
+
+	d = sqrt(d);
+	n = 0;
+	if((q = -d-p) > 0 && q < 1)
+		qs[n++] = q;
+	if((q = d-p) > 0 && q < 1)
+		qs[n++] = q;
+    return n;
+}
+
+static int
+Svalcmp(void *a_, void *b_)
+{
+	Sval a = *(Sval*)a_, b = *(Sval*)b_;
+	return (a > b) - (a < b);
+}
+
+static int
+qKL(SegQ *s₀, int jj, Sval px, Sval py, Sval *K, Sval *L)
+{
+	Sval qs[1+4*2+1];
+	Sval a, b, c, w, v;
+	SegQ s, z;
+	int i, j, n, r;
+
+	/* transform */
+	for(i = 0; i < nelem(s.v); i += 2){
+		s.v[i+0] = s₀->v[i+0]*jj - px;
+		s.v[i+1] = s₀->v[i+1]*jj - py;
+	}
+
+	/* FIXME would it make things faster to do proper convex hull test here? */
+	if(s.p0.x < 0 && s.p1.x < 0 && s.p2.x < 0 ||
+	   s.p0.x > 1 && s.p1.x > 1 && s.p2.x > 1 ||
+	   s.p0.y < 0 && s.p1.y < 0 && s.p2.y < 0 ||
+	   s.p0.y > 1 && s.p1.y > 1 && s.p2.y > 1)
+		return 0;
+
+#define e(t,a) (s.p0.a*(1-t)*(1-t) + 2*s.p1.a*(1-t)*t + s.p2.a*t*t)
+#define within(v) ((w = e(v, x)) >= -ε && w <= 1+ε && (w = e(v, y)) >= -ε && w <= 1+ε)
+
+	/* clip to quadtree cell */
+	n = 0;
+	if(s.p0.x >= 0 && s.p0.x <= 1 && s.p0.y >= 0 && s.p0.y <= 1)
+		qs[n++] = 0;
+	for(i = 0; i < 2; i++){
+		c = s.v0[i];
+		a = c - 2*s.v1[i] + s.v2[i];
+		b = 2*(s.v1[i] - c);
+		n += qslv(qs+n, a, b, c);
+		n += qslv(qs+n, a, b, c-1);
+	}
+	qsort(qs, n, sizeof(Sval), Svalcmp);
+	if(s.p2.x >= 0 && s.p2.x <= 1 && s.p2.y >= 0 && s.p2.y <= 1)
+		qs[n++] = 1;
+	j = 0;
+	for(i = 0; i < n; i++){
+		v = qs[i];
+		if(within(v))
+			qs[j++] = v;
+	}
+#undef within
+
+	/* remove duplicates */
+	n = 1;
+	for(i = 1; i < j; i++){
+		v = qs[i];
+		if(v != qs[i-1])
+			qs[n++] = v;
+	}
+
+	/* calculate K & L on subsections */
+	r = 0;
+	for(i = 0; i < n-1; i++){
+		a = qs[i];
+		b = qs[i+1];
+
+		z.p0.y = e(a, y);
+		z.p2.y = e(b, y);
+		if(fabs(z.p0.y-1) < ε && fabs(z.p2.y-1) < ε)
+			continue;
+		z.p0.x = e(a, x);
+		z.p2.x = e(b, x);
+		if(fabs(z.p0.x-1) < ε && fabs(z.p2.x-1) < ε)
+			continue;
+#undef e
+
+		c = 1 - a;
+		v = (b - a)/c;
+		z.p1.x = (1-v)*z.p0.x + v*(c*s.p1.x + a*s.p2.x);
+		z.p1.y = (1-v)*z.p0.y + v*(c*s.p1.y + a*s.p2.y);
+
+		K[0] += z.p2.y - z.p0.y;
+		K[1] += z.p0.x - z.p2.x;
+		L[0] += 3*z.p2.x*z.p2.y
+		      + 2*z.p2.y*z.p1.x
+		      - 2*z.p2.x*z.p1.y
+		      +   z.p2.y*z.p0.x
+		      + 2*z.p1.y*z.p0.x
+		      -   z.p0.y*(  z.p2.x + 2*z.p1.x + 3*z.p0.x);
+		L[1] += 2*z.p1.y*z.p0.x
+		      +   z.p2.y*(2*z.p1.x +   z.p0.x)
+		      - 2*z.p1.x*z.p0.y
+		      + 3*z.p0.x*z.p0.y
+		      -   z.p2.x*(3*z.p2.y + 2*z.p1.y +   z.p0.y);
+		r = 1;
+	}
+	if(r){
+		L[0] /= 6.0;
+		L[1] /= 6.0;
+	}
+	return r;
+}
+
+static int
+lKL(SegQ *s₀, int jj, Sval px, Sval py, Sval *K, Sval *L)
+{
+	Sval x₁, x₂, y₁, y₂, α₁, α₂, β₁, β₂;
+
+	/* transform */
+	α₁ = x₁ = s₀->p0.x*jj - px;
+	β₁ = y₁ = s₀->p0.y*jj - py;
+	α₂ = x₂ = s₀->p1.x*jj - px;
+	β₂ = y₂ = s₀->p1.y*jj - py;
+
+	if(α₁ < 0){
+		if(α₂ < 0) return 0;
+		α₁ = 0;
+		β₁ = (y₂-y₁)/(x₂-x₁)*(0-x₁)+y₁;
+	}else if(α₁ > 1){
+		if(α₂ > 1) return 0;
+		α₁ = 1;
+		β₁ = (y₂-y₁)/(x₂-x₁)*(1-x₁)+y₁;
+	}
+	if(α₂ < 0){
+		α₂ = 0;
+		β₂ = (y₂-y₁)/(x₂-x₁)*(0-x₁)+y₁;
+	}else if(α₂ > 1){
+		α₂ = 1;
+		β₂ = (y₂-y₁)/(x₂-x₁)*(1-x₁)+y₁;
+	}
+	if(β₁ < 0){
+		if(β₂ < 0) return 0;
+		β₁ = 0;
+		α₁ = (x₂-x₁)/(y₂-y₁)*(0-y₁)+x₁;
+	}else if(β₁ > 1){
+		if(β₂ > 1) return 0;
+		β₁ = 1;
+		α₁ = (x₂-x₁)/(y₂-y₁)*(1-y₁)+x₁;
+	}
+	if(β₂ < 0){
+		β₂ = 0;
+		α₂ = (x₂-x₁)/(y₂-y₁)*(0-y₁)+x₁;
+	}else if(β₂ > 1){
+		β₂ = 1;
+		α₂ = (x₂-x₁)/(y₂-y₁)*(1-y₁)+x₁;
+	}
+
+	K[0] += β₂ - β₁;
+	K[1] += α₁ - α₂;
+	L[0] += (β₂ - β₁)*(α₁ + α₂)/2;
+	L[1] += (α₁ - α₂)*(β₁ + β₂)/2;
+	return 1;
+}
+
+static u64int
+qCxy(SegQ *s, int ns, int jj, int px, int py, Sval *c, u64int *m, u64int tm)
+{
+	int (*f)(SegQ*, int, Sval, Sval, Sval*, Sval*);
+	u64int tx₀, tx₁, z, all;
+	Sval K[4][2], L[4][2];
+	int i;
+
+	jj *= 2;
+	px *= 2;
+	py *= 2;
+	if(jj > 8){
+		tx₀ = 0;
+		tx₁ = 0;
+	}else{
+		tx₀ = 1ULL<<(px*jj + py);
+		tx₁ = 1ULL<<((px+1)*jj + py);
+	}
+	all = 0;
+	for(i = 0; i < ns; i++, s++){
+		if((m[i] & tm) == 0)
+			continue;
+
+		K[0][0] = K[0][1] = 0;
+		K[1][0] = K[1][1] = 0;
+		K[2][0] = K[2][1] = 0;
+		K[3][0] = K[3][1] = 0;
+		L[0][0] = L[0][1] = 0;
+		L[1][0] = L[1][1] = 0;
+		L[2][0] = L[2][1] = 0;
+		L[3][0] = L[3][1] = 0;
+
+		if(s->p1.x == s->p2.x && s->p1.y == s->p2.y)
+			f = lKL;
+		else
+			f = qKL;
+
+		if(tx₀ == 0){
+			f(s, jj, px+0, py+0, K[0], L[0]);
+			f(s, jj, px+0, py+1, K[1], L[1]);
+			f(s, jj, px+1, py+0, K[2], L[2]);
+			f(s, jj, px+1, py+1, K[3], L[3]);
+		}else{
+			z = 0;
+			if(f(s, jj, px+0, py+0, K[0], L[0]))
+				z |= tx₀;
+			if(f(s, jj, px+0, py+1, K[1], L[1]))
+				z |= tx₀<<1;
+			if(f(s, jj, px+1, py+0, K[2], L[2]))
+				z |= tx₁;
+			if(f(s, jj, px+1, py+1, K[3], L[3]))
+				z |= tx₁<<1;
+			m[ns+i] |= z;
+			all |= z;
+		}
+
+		c[0] += L[0][1] + L[2][1] + K[1][1] - L[1][1] + K[3][1] - L[3][1];
+		c[1] += L[0][0] + L[1][0] + K[2][0] - L[2][0] + K[3][0] - L[3][0];
+		c[2] += L[0][0] - L[1][0] + K[2][0] - L[2][0] - K[3][0] + L[3][0];
+	}
+	return all;
+}
+
+static int
+qbzr(SegQ *seg, int ns, int dw, int dh, Sval *p)
+{
+	int ₂ju, ₂j, w, h, i, j, ju, px, py;
+	Sval r₂ju, s₀, s, *c, *c₀x, *c₀y, *cs, zx, zy;
+	u64int *ma, *mb, all, nall;
+
+	₂ju = closest²(dh);
+	if(₂ju < (j = closest²(dw)))
+		₂ju = j;
+	r₂ju = 1.0 / ₂ju;
+	for(ju = 1; (1<<ju) < ₂ju; ju++);
+
+	/* scale */
+	for(i = 0; i < ns; i++){
+		for(j = 0; j < nelem(seg->v); j++)
+			seg[i].v[j] *= r₂ju;
+	}
+
+	/* calculate area */
+	s₀ = 0;
+	for(i = 0; i < ns; i++){
+#define det(a,b) (a.x*b.y - a.y*b.x)
+#define cQ(s) (det(s.p0, s.p1) + det(s.p1, s.p2) + det(s.p0, s.p2)/2)/3
+		s₀ -= cQ(seg[i]);
+#undef det
+#undef cQ
+	}
+	s₀ *= QBZR_PIX_SCALE;
+
+	/* working space:
+	 * quick is-segment-in-the-cell tests (two 64-bit nums per segment)
+	 * wavelet coefficients (count by geometric series, 3 per "pixel" of every zoom level)
+	 */
+	j = 2*ns*sizeof(*ma) + (1-(4<<2*(ju-1)))/(1-4)*3*sizeof(*c);
+	/* current zoom level bitmasks for quick tests */
+	if((ma = calloc(1, j)) == nil){
+		werrstr("no memory");
+		return -1;
+	}
+	/* next zoom level bitmasks */
+	mb = ma + ns;
+	/* first (1x1) zoom level - all segments are there */
+	for(i = 0; i < ns; i++)
+		ma[i] = 1;
+
+	/* coefficients */
+	c = cs = (Sval*)(ma + 2*ns);
+
+	/* bitmasks used per-segment are united (bitwise OR) to skip entire empty cells */
+	all = 1;
+	nall = 0;
+	/* first few loops build the test bitmasks: 1x1 -> 4x4 -> 8x8 */
+	for(j = 0, ₂j = 1; j < ju && j <= 3; j++, ₂j <<= 1){
+		for(px = 0; px < ₂j; px++){
+			for(py = 0; py < ₂j; py++, c += 3){
+				u64int tm = 1ULL<<(px*₂j + py);
+				if(all & tm)
+					nall |= qCxy(seg, ns, ₂j, px, py, c, ma, tm);
+			}
+		}
+		if(j != 3){
+			for(i = 0; i < ns; i++){
+				ma[i] = mb[i];
+				mb[i] = 0;
+			}
+			all = nall;
+			nall = 0;
+		}
+	}
+
+	/* no more bitmasks, just calculate coefficients */
+	for(; j < ju; j++, ₂j <<= 1){
+		for(px = 0; px < ₂j; px++){
+			/* bitmasks are expanded only up to 8x8 (64 bits)
+			 * so use that for more coarse testing
+			 */
+			u64int tm₀ = 1ULL<<((px>>(j-3))*8);
+			for(py = 0; py < ₂j; py++, c += 3){
+				u64int tm = tm₀ << (py>>(j-3));
+				if(all & tm)
+					qCxy(seg, ns, ₂j, px, py, c, ma, tm);
+			}
+		}
+	}
+
+	/* reverse Y axis (opentype coord vs plan 9) */
+	for(h = dh-1; h >= 0; h--){
+		for(w = 0; w < dw; w++){
+			c = cs;
+			s = s₀;
+			for(₂j = 1; ₂j < ₂ju; ₂j *= 2){
+				zx = r₂ju * ₂j * w;
+				c₀x = c;
+				px = (int)zx;
+				zx -= px;
+				c += px*3*₂j;
+				for(; zx >= 0; px++, zx--, c = c₀y + 3*₂j){
+					c₀y = c;
+					zy = r₂ju * ₂j * h;
+					py = (int)zy;
+					zy -= py;
+					c += 3*py;
+					for(; zy >= 0; py++, zy--, c += 3){
+						switch((zy < 0.5)<<1 | (zx < 0.5)){
+						case 0:  s += +c[0] + c[1] - c[2]; break;
+						case 1:  s += +c[0] - c[1] + c[2]; break;
+						case 2:  s += -c[0] + c[1] + c[2]; break;
+						default: s += -c[0] - c[1] - c[2]; break;
+						}
+					}
+				}
+				c = c₀x + 3*₂j*₂j;
+			}
+			*p++ = s;
+		}
+	}
+	free(ma);
+	return 0;
+}
+
+u8int *
+otfdrawglyf(Glyf *g, int h, int *wo)
+{
+	SegQ *s₀, *s;
+	Sval *fp;
+	Point *p₀, *p, *prev;
+	Spt *pts₀, *pts, *e;
+	int w, i, r, k, npts, npx, ns;
+	double scale;
+
+	scale = (double)h / (g->yMax - g->yMin);
+	w = *wo = (g->xMax - g->xMin) * scale;
+
+	npx = w * h;
+	fp = calloc(1, npx*sizeof(*fp));
+	ns = 0;
+	s₀ = nil;
+
+	for(k = 0; k < g->numberOfContours; k++){
+		npts = g->simple->endPtsOfContours[k]+1;
+		if(k > 0)
+			npts -= g->simple->endPtsOfContours[k-1]+1;
+
+		pts₀ = e = malloc((npts+2)*3*sizeof(*e));
+		p₀ = p = g->simple->points + (k > 0 ? g->simple->endPtsOfContours[k-1]+1 : 0);
+		prev = p₀+npts-1;
+		if(!p->onCurve){
+			/* fun stuff */
+			if(prev->onCurve)
+				*e = (Spt){prev->x, prev->y};
+			else
+				*e = (Spt){(Sval)(p->x + prev->x)/2, (Sval)(p->y + prev->y)/2};
+			e++;
+		}
+		for(prev = nil; p < p₀+npts; prev = p, p++, e++){
+			if(prev != nil && p->onCurve == prev->onCurve){
+				/* more fun stuff */
+				if(p->onCurve) /* straight line */
+					*e = (Spt){p->x, p->y};
+				else /* a point in the middle */
+					*e = (Spt){(Sval)(p->x + prev->x)/2, (Sval)(p->y + prev->y)/2};
+				e++;
+			}
+			*e = (Spt){p->x, p->y};
+		}
+		if(e[-1].x != pts₀->x || e[-1].y != pts₀->y){
+			if(p[-1].onCurve) /* close with a straight line */
+				*e++ = *pts₀;
+			*e++ = *pts₀;
+		}
+
+		s₀ = realloc(s₀, (ns + (e-pts₀)/2)*sizeof(*s₀));
+		s = s₀ + ns;
+		pts = e;
+		for(e = pts₀; e <= pts-3; e += 2, s++, ns++){
+			s->v0[0] = (e[0].x - g->xMin) * scale;
+			s->v0[1] = (e[0].y - g->yMin) * scale;
+			s->v1[0] = (e[1].x - g->xMin) * scale;
+			s->v1[1] = (e[1].y - g->yMin) * scale;
+			s->v2[0] = (e[2].x - g->xMin) * scale;
+			s->v2[1] = (e[2].y - g->yMin) * scale;
+		}
+		free(pts₀);
+	}
+
+	r = qbzr(s₀, ns, w, h, fp);
+	free(s₀);
+
+	if(r != 0)
+		return nil;
+
+	u8int *b = malloc(npx);
+	for(i = 0; i < npx; i++){
+		b[i] = fp[i] <= 0 ? 0 : (fp[i] >= QBZR_PIX_SCALE ? 255 : fp[i]/QBZR_PIX_SCALE*255);
+		b[i] = 255 - b[i];
+	}
+	free(fp);
+	return b;
+}
--- a/test.c
+++ /dev/null
@@ -1,37 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include "otf.h"
-
-void
-main(int argc, char **argv)
-{
-	Biobuf *out;
-	Otf *o;
-	int i;
-
-	otfinit();
-	out = Bfdopen(1, OWRITE);
-	for(i = 1; i < argc; i++){
-		Bprint(out, "%s\n", argv[i]);
-		if((o = otfopen(argv[i])) == nil){
-			fprint(2, "%r\n");
-		}else{
-			int n = otfglyfnum(o);
-			for(int i = 0; i < n; i++){
-				Glyf *g = otfglyf(o, i);
-				if(g == nil)
-					fprint(2, "%d: %r\n", i);
-				else{
-					Bprint(out, "\n%d:\n", i);
-					print_Glyf(out, indentΔ, o, g);
-				}
-			}
-			//otfprint(o, out, indentΔ);
-		}
-		otfclose(o);
-	}
-	Bterm(out);
-
-	exits(nil);
-}
--- /dev/null
+++ b/test_plan9.c
@@ -1,0 +1,115 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "otf.h"
+
+static int
+otfseek(void *aux, int off, int whence)
+{
+	return Bseek(aux, off, whence);
+}
+
+static int
+otfread(void *aux, void *dst, int sz)
+{
+	return Bread(aux, dst, sz);
+}
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-g GLYPH_ID] [-G] [-i N] [-s PX] font.otf ...\n", argv0);
+	fprint(2, " -g: specifies a single glyph id\n");
+	fprint(2, " -G: print out glyph ids, only ones that can be drawn atm (no compound yet)\n");
+	fprint(2, " -s: draw (of size PX) and write the image to stdout\n");
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	int i, gi, G, h;
+	Otfile in, out;
+	Otf *o;
+
+	gi = -1;
+	G = 0;
+	h = 0;
+	ARGBEGIN{
+	case 'g':
+		gi = strtol(EARGF(usage()), nil, 0);
+		break;
+	case 'G':
+		G++;
+		break;
+	case 's':
+		h = strtol(EARGF(usage()), nil, 0);
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	in.seek = otfseek;
+	in.read = otfread;
+	out.print = (void*)Bprint;
+
+	out.aux = Bfdopen(1, OWRITE);
+	for(i = 0; i < argc; i++){
+		if(h <= 0)
+			Bprint(out.aux, "%s\n", argv[i]);
+		if((in.aux = Bopen(argv[i], OREAD)) == nil || (o = otfopen(&in)) == nil){
+			fprint(2, "%r\n");
+			continue;
+		}
+		if(G){
+			int i, n = otfglyfnum(o);
+			for(i = 0; i < n; i++){
+				Glyf *g = otfglyf(o, i);
+				if(g != nil && g->simple != nil && g->numberOfContours > 0){
+					if(h > 0){
+						int w;
+						u8int *b = otfdrawglyf(g, h, &w);
+						if(b == nil)
+							sysfatal("%r");
+						free(b);
+					}else{
+						fprint(2, "%d ", i);
+					}
+				}
+				free(g);
+			}
+			if(h <= 0)
+				fprint(2, "\n");
+		}else if(gi < 0){
+			otfprint(o, &out, indentΔ);
+		}else{
+			int n = otfglyfnum(o);
+			if(gi >= n)
+				sysfatal("glyph %d out of range, max %d\n", gi, n-1);
+			Glyf *g = otfglyf(o, gi);
+			if(g == nil){
+				fprint(2, "%d: %r\n", gi);
+			}else if(h > 0){
+				if(g->component != nil)
+					fprint(2, "%d: component\n", gi);
+				else{
+					int w;
+					u8int *b = otfdrawglyf(g, h, &w);
+					if(b == nil)
+						sysfatal("%r");
+					fprint(1, "%11s %11d %11d %11d %11d ", "k8", 0, 0, w, h);
+					write(1, b, w*h);
+					free(b);
+				}
+			}else{
+				Bprint(out.aux, "\n%d:\n", gi);
+				print_Glyf(&out, indentΔ, o, g);
+			}
+		}
+		otfclose(o);
+		Bterm(in.aux);
+	}
+	Bterm(out.aux);
+
+	exits(nil);
+}
--- /dev/null
+++ b/test_unix.c
@@ -1,0 +1,144 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "otf.h"
+
+static char *argv0;
+
+#define	ARGBEGIN	for((argv0? 0: (argv0=*argv)),argv++,argc--;\
+			    argv[0] && argv[0][0]=='-' && argv[0][1];\
+			    argc--, argv++) {\
+				char *_args, *_argt;\
+				int _argc;\
+				_args = &argv[0][1];\
+				if(_args[0]=='-' && _args[1]==0){\
+					argc--; argv++; break;\
+				}\
+				_argc = 0;\
+				while((_argc = *_args++) != 0)\
+				switch(_argc)
+#define	ARGEND		(void)_argt; (void)_argc; (void)_args;}(void)argv; (void)argc;
+#define	ARGF()		(_argt=_args, _args="",\
+				(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
+#define	ARGC()		_argc
+
+#define	EARGF(x)		(_argt=_args, _args="",\
+				(*_argt? _argt: argv[1]? (argc--, *++argv): (x, (char*)0)))
+
+static int
+otfseek(void *aux, int off, int whence)
+{
+	if(fseek(aux, off, whence) < 0)
+		return -1;
+	return ftell(aux);
+}
+
+static int
+otfread(void *aux, void *dst, int sz)
+{
+	return fread(dst, 1, sz, aux);
+}
+
+static void
+usage(void)
+{
+	fprintf(stderr, "usage: %s [-g GLYPH_ID] [-G] [-i N] [-s PX] font.otf ...\n", argv0);
+	fprintf(stderr, " -g: specifies a single glyph id\n");
+	fprintf(stderr, " -G: print out glyph ids, only ones that can be drawn atm (no compound yet)\n");
+	fprintf(stderr, " -s: draw (of size PX) and write the image to stdout\n");
+	exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+	int i, gi, G, h;
+	Otfile in, out;
+	Otf *o;
+
+	gi = -1;
+	G = 0;
+	h = 0;
+	ARGBEGIN{
+	case 'g':
+		gi = strtol(EARGF(usage()), NULL, 0);
+		break;
+	case 'G':
+		G++;
+		break;
+	case 's':
+		h = strtol(EARGF(usage()), NULL, 0);
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	in.seek = otfseek;
+	in.read = otfread;
+	out.print = (void*)fprintf;
+
+	out.aux = fdopen(1, "wb");
+	for(i = 0; i < argc; i++){
+		if(h <= 0)
+			fprintf(out.aux, "%s\n", argv[i]);
+		if((in.aux = fopen(argv[i], "rb")) == NULL || (o = otfopen(&in)) == NULL){
+			fprintf(stderr, "%s: failed\n", argv[i]);
+			continue;
+		}
+		if(G){
+			int i, n = otfglyfnum(o);
+			for(i = 0; i < n; i++){
+				Glyf *g = otfglyf(o, i);
+				if(g != NULL && g->simple != NULL && g->numberOfContours > 0){
+					if(h > 0){
+						int w;
+						u8int *b = otfdrawglyf(g, h, &w);
+						if(b == NULL){
+							fprintf(stderr, "failed\n");
+							exit(1);
+						}
+						free(b);
+					}else{
+						fprintf(out.aux, "%d ", i);
+					}
+				}
+				free(g);
+			}
+			if(h <= 0)
+				fprintf(out.aux, "\n");
+		}else if(gi < 0){
+			otfprint(o, &out, indentΔ);
+		}else{
+			int n = otfglyfnum(o);
+			if(gi >= n){
+				fprintf(stderr, "glyph %d out of range, max %d\n", gi, n-1);
+				exit(1);
+			}
+			Glyf *g = otfglyf(o, gi);
+			if(g == NULL){
+				fprintf(stderr, "%d: failed\n", gi);
+			}else if(h > 0){
+				if(g->component != NULL)
+					fprintf(stderr, "%d: component\n", gi);
+				else{
+					int w;
+					u8int *b = otfdrawglyf(g, h, &w);
+					if(b == NULL){
+						fprintf(stderr, "failed\n");
+						exit(1);
+					}
+					fprintf(out.aux, "%11s %11d %11d %11d %11d ", "k8", 0, 0, w, h);
+					fwrite(b, 1, w*h, out.aux);
+					free(b);
+				}
+			}else{
+				fprintf(out.aux, "\n%d:\n", gi);
+				print_Glyf(&out, indentΔ, o, g);
+			}
+		}
+		otfclose(o);
+		fclose(in.aux);
+	}
+	fclose(out.aux);
+
+	return 0;
+}
--- /dev/null
+++ b/unix.c
@@ -1,0 +1,33 @@
+#include "otfsys.h"
+#include <stdarg.h>
+#include <time.h>
+
+char *
+fmttime(long long v)
+{
+	static char buf[32];
+	time_t t = v;
+	struct tm *tm;
+	tm = gmtime(&t);
+	strftime(buf, sizeof(buf), "%c", tm);
+	return buf;
+}
+
+#define ERRMAX 512
+
+static char errstr[ERRMAX];
+
+void
+werrstr(char *fmt, ...)
+{
+	va_list a;
+	char buf[ERRMAX];
+	int n;
+
+	va_start(a, fmt);
+	n = vsnprintf(buf, sizeof(buf), fmt, a);
+	va_end(a);
+	if(n >= 2 && buf[n-2] == '%' && buf[n-1] == 'r')
+		snprintf(buf+n-2, sizeof(buf)-n+2, "%s", errstr);
+	strcpy(errstr, buf);
+}
--- /dev/null
+++ b/unix/otfsys.h
@@ -1,0 +1,12 @@
+#pragma once
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define nil NULL
+#define USED(x) (void)(x)
+#define nelem(a) (int)(sizeof(a)/sizeof((a)[0]))
+
+char *fmttime(long long v);
+void werrstr(char *fmt, ...);