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
--
⑨