shithub: fnt

Download patch

ref: 103c13316808ce1c0f3254bec5d1c7e44bd9a8e1
parent: d5219f723f7511b56d9811d19da617c4bb3b3fd0
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Jun 23 22:29:17 EDT 2024

a bit of glyf types

--- a/otf.c
+++ b/otf.c
@@ -15,6 +15,7 @@
 	/* extra fields to simplify parsing */
 	s16int indexToLocFormat;
 	u16int numberOfHMetrics;
+	s16int numberOfContours;
 	u16int numGlyphs;
 	u16int platformID;
 	u16int encodingID;
@@ -816,6 +817,115 @@
 	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);
+	USED(o);
+}
+
+int
+read_SimpleGlyph(Otf *o, SimpleGlyph *v)
+{
+	u8int *b;
+	if((b = otfreadn(o, o->numberOfContours*2)) == nil)
+		goto err;
+	v->endPtsOfContours = malloc(o->numberOfContours*sizeof(*v->endPtsOfContours));
+	for(int i = 0; i < o->numberOfContours; i++)
+		v->endPtsOfContours[i] = b[0+i*2]<<8 | b[1+i*2];
+	if((b = otfreadn(o, 2)) == nil)
+		goto err;
+	v->instructionLength = b[0]<<8 | b[1];
+	if((b = otfreadn(o, v->instructionLength*1)) == nil)
+		goto err;
+	v->instructions = malloc(v->instructionLength*sizeof(*v->instructions));
+	for(int i = 0; i < v->instructionLength; i++)
+		v->instructions[i] = b[0+i*1];
+	if((b = otfreadn(o, 1)) == nil)
+		goto err;
+	v->flags = b[0];
+	return 0;
+err:
+	werrstr("%s: %r", "SimpleGlyph");
+	return -1;
+}
+
+void
+print_SimpleGlyph(Biobuf *f, int indent, Otf *o, SimpleGlyph *v)
+{
+	for(int i = 0; i < o->numberOfContours; i++)
+		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "endPtsOfContours", i, v->endPtsOfContours[i]);
+	Bprint(f, "%*s%s: %ud\n", indent, "", "instructionLength", v->instructionLength);
+	for(int i = 0; i < v->instructionLength; i++)
+		Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "instructions", i, v->instructions[i]);
+	Bprint(f, "%*s%s: %#ux%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags, (v->flags&GLYPH_FL_ON_CURVE_POINT)?" GLYPH_FL_ON_CURVE_POINT":"", (v->flags&GLYPH_FL_X_SHORT_VECTOR)?" GLYPH_FL_X_SHORT_VECTOR":"", (v->flags&GLYPH_FL_Y_SHORT_VECTOR)?" GLYPH_FL_Y_SHORT_VECTOR":"", (v->flags&GLYPH_FL_REPEAT)?" GLYPH_FL_REPEAT":"", (v->flags&GLYPH_FL_X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR)?" GLYPH_FL_X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR":"", (v->flags&GLYPH_FL_Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR)?" GLYPH_FL_Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR":"", (v->flags&GLYPH_FL_OVERLAP_SIMPLE)?" GLYPH_FL_OVERLAP_SIMPLE":"");
+	USED(o);
+}
+
+int
+read_CompositeGlyph(Otf *o, CompositeGlyph *v)
+{
+	u8int *b;
+	if((b = otfreadn(o, 4)) == nil)
+		goto err;
+	v->flags = b[0]<<8 | b[1];
+	v->glyphIndex = b[2]<<8 | b[3];
+	return 0;
+err:
+	werrstr("%s: %r", "CompositeGlyph");
+	return -1;
+}
+
+void
+print_CompositeGlyph(Biobuf *f, int indent, Otf *o, CompositeGlyph *v)
+{
+	Bprint(f, "%*s%s: %#ux%s%s%s%s%s%s%s%s%s%s%s%s\n", indent, "", "flags", v->flags, (v->flags&CGLYPH_FL_WORD_ARGS)?" CGLYPH_FL_WORD_ARGS":"", (v->flags&CGLYPH_FL_SIGNED_XY)?" CGLYPH_FL_SIGNED_XY":"", (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":"", (v->flags&CGLYPH_FL_SCALE_XY)?" CGLYPH_FL_SCALE_XY":"", (v->flags&CGLYPH_FL_2X2_TRANSFORM)?" CGLYPH_FL_2X2_TRANSFORM":"", (v->flags&CGLYPH_FL_INSTRUCTIONS)?" CGLYPH_FL_INSTRUCTIONS":"", (v->flags&CGLYPH_FL_METRICS)?" CGLYPH_FL_METRICS":"", (v->flags&CGLYPH_FL_OVERLAP_COMPOUND)?" CGLYPH_FL_OVERLAP_COMPOUND":"", (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);
+	USED(o);
+}
+
+int
+read_GlyfHeader(Otf *o, GlyfHeader *v)
+{
+	u8int *b;
+	if((b = otfreadn(o, 10)) == nil)
+		goto err;
+	v->numberOfContours = b[0]<<8 | b[1];
+	o->numberOfContours = v->numberOfContours;
+	v->xMin = b[2]<<8 | b[3];
+	v->yMin = b[4]<<8 | b[5];
+	v->xMax = b[6]<<8 | b[7];
+	v->yMax = b[8]<<8 | b[9];
+	if(v->numberOfContours > 0){
+		if(read_SimpleGlyph(o, &v->simpleGlyph) < 0){
+			werrstr("%s: %r", "simpleGlyph");
+			goto err;
+		}
+	}
+	if(v->numberOfContours < 0){
+		if(read_CompositeGlyph(o, &v->compositeGlyph) < 0){
+			werrstr("%s: %r", "compositeGlyph");
+			goto err;
+		}
+	}
+	return 0;
+err:
+	werrstr("%s: %r", "GlyfHeader");
+	return -1;
+}
+
+void
+print_GlyfHeader(Biobuf *f, int indent, Otf *o, GlyfHeader *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);
+	if(v->numberOfContours > 0){
+		Bprint(f, "%*s%s:\n", indent, "", "simpleGlyph");
+		print_SimpleGlyph(f, indent+indentΔ, o, &v->simpleGlyph);
+	}
+	if(v->numberOfContours < 0){
+		Bprint(f, "%*s%s:\n", indent, "", "compositeGlyph");
+		print_CompositeGlyph(f, indent+indentΔ, o, &v->compositeGlyph);
+	}
 	USED(o);
 }
 
--- a/otf.h
+++ b/otf.h
@@ -21,6 +21,9 @@
 typedef struct TableCmap TableCmap;
 typedef struct TableHead TableHead;
 typedef struct TableHhea TableHhea;
+typedef struct SimpleGlyph SimpleGlyph;
+typedef struct CompositeGlyph CompositeGlyph;
+typedef struct GlyfHeader GlyfHeader;
 typedef struct LongHorMetric LongHorMetric;
 typedef struct TableMaxp TableMaxp;
 typedef struct TableHmtx TableHmtx;
@@ -360,6 +363,64 @@
 
 int read_TableHhea(Otf *o, TableHhea *v);
 void print_TableHhea(Biobuf *f, int indent, Otf *o, TableHhea *v);
+
+enum { // SimpleGlyph
+	// flags
+	GLYPH_FL_ON_CURVE_POINT = 1<<0,
+	GLYPH_FL_X_SHORT_VECTOR = 1<<1,
+	GLYPH_FL_Y_SHORT_VECTOR = 1<<2,
+	GLYPH_FL_REPEAT = 1<<3,
+	GLYPH_FL_X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR = 1<<4,
+	GLYPH_FL_Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR = 1<<5,
+	GLYPH_FL_OVERLAP_SIMPLE = 1<<6,
+};
+
+struct SimpleGlyph {
+	u16int *endPtsOfContours;
+	u16int instructionLength;
+	u8int *instructions;
+	u8int flags;
+};
+
+int read_SimpleGlyph(Otf *o, SimpleGlyph *v);
+void print_SimpleGlyph(Biobuf *f, int indent, Otf *o, SimpleGlyph *v);
+
+enum { // CompositeGlyph
+	// flags
+	CGLYPH_FL_WORD_ARGS = 1<<0,
+	CGLYPH_FL_SIGNED_XY = 1<<1,
+	CGLYPH_FL_ROUND_TO_GRID_XY = 1<<2,
+	CGLYPH_FL_SCALE = 1<<3,
+	CGLYPH_FL_MORE_COMPONENTS = 1<<5,
+	CGLYPH_FL_SCALE_XY = 1<<6,
+	CGLYPH_FL_2X2_TRANSFORM = 1<<7,
+	CGLYPH_FL_INSTRUCTIONS = 1<<8,
+	CGLYPH_FL_METRICS = 1<<9,
+	CGLYPH_FL_OVERLAP_COMPOUND = 1<<10,
+	CGLYPH_FL_SCALED_COMPONENT_OFFSET = 1<<11,
+	CGLYPH_FL_UNSCALED_COMPONENT_OFFSET = 1<<12,
+};
+
+struct CompositeGlyph {
+	u16int flags;
+	u16int glyphIndex;
+};
+
+int read_CompositeGlyph(Otf *o, CompositeGlyph *v);
+void print_CompositeGlyph(Biobuf *f, int indent, Otf *o, CompositeGlyph *v);
+
+struct GlyfHeader {
+	s16int numberOfContours;
+	s16int xMin;
+	s16int yMin;
+	s16int xMax;
+	s16int yMax;
+	SimpleGlyph simpleGlyph;
+	CompositeGlyph compositeGlyph;
+};
+
+int read_GlyfHeader(Otf *o, GlyfHeader *v);
+void print_GlyfHeader(Biobuf *f, int indent, Otf *o, GlyfHeader *v);
 
 struct LongHorMetric {
 	u16int advanceWidth;
--- a/otf.rkt
+++ b/otf.rkt
@@ -201,6 +201,54 @@
          {uint16 numberOfHMetrics ->o}
          #:tag "hhea")
 
+(define simpleGlyphFlags
+  #hash((0 . GLYPH_FL_ON_CURVE_POINT)
+        (1 . GLYPH_FL_X_SHORT_VECTOR)
+        (2 . GLYPH_FL_Y_SHORT_VECTOR)
+        (3 . GLYPH_FL_REPEAT)
+        (4 . GLYPH_FL_X_IS_SAME_OR_POSITIVE_X_SHORT_VECTOR)
+        (5 . GLYPH_FL_Y_IS_SAME_OR_POSITIVE_Y_SHORT_VECTOR)
+        (6 . GLYPH_FL_OVERLAP_SIMPLE)))
+
+(mkcmplx SimpleGlyph
+         {uint16 endPtsOfContours [o->numberOfContours]}
+         {uint16 instructionLength}
+         {uint8 instructions [instructionLength]}
+         {uint8 flags hex (bits simpleGlyphFlags)} ; FIXME this is a (packed) array
+         #;{uint8/uint16 xCoordinates [?]}
+         #;{uint8/uint16 yCoordinates [?]})
+
+(define compositeGlyphFlags
+  #hash((0 . CGLYPH_FL_WORD_ARGS)
+        (1 . CGLYPH_FL_SIGNED_XY)
+        (2 . CGLYPH_FL_ROUND_TO_GRID_XY)
+        (3 . CGLYPH_FL_SCALE)
+        (5 . CGLYPH_FL_MORE_COMPONENTS)
+        (6 . CGLYPH_FL_SCALE_XY)
+        (7 . CGLYPH_FL_2X2_TRANSFORM)
+        (8 . CGLYPH_FL_INSTRUCTIONS)
+        (9 . CGLYPH_FL_METRICS)
+        (10 . CGLYPH_FL_OVERLAP_COMPOUND)
+        (11 . CGLYPH_FL_SCALED_COMPONENT_OFFSET)
+        (12 . CGLYPH_FL_UNSCALED_COMPONENT_OFFSET)))
+
+(mkcmplx CompositeGlyph
+         {uint16 flags hex (bits compositeGlyphFlags)}
+         {uint16 glyphIndex}
+         #;{uint8/int8/uint16/int16 argument1} ; FIXME are you fucking kidding me
+         #;{uint8/int8/uint16/int16 argument2}
+         ; FIXME there is more shit here
+         )
+
+(mkcmplx GlyfHeader
+         {int16 numberOfContours ->o}
+         {int16 xMin}
+         {int16 yMin}
+         {int16 xMax}
+         {int16 yMax}
+         {SimpleGlyph simpleGlyph (> numberOfContours 0)}
+         {CompositeGlyph compositeGlyph (< numberOfContours 0)})
+
 (mkcmplx LongHorMetric {UFWORD advanceWidth} {FWORD lsb})
 
 (mkcmplx TableMaxp
--