ref: d5219f723f7511b56d9811d19da617c4bb3b3fd0
parent: b8442cf99bf3c724441a5abca9f6497eb6407add
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Jun 23 21:50:56 EDT 2024
a bit more of gvar
--- a/gen.rkt
+++ b/gen.rkt
@@ -476,7 +476,7 @@
(define-syntax-class arithop
#:description "arithmetical operator"
(pattern op:id
- #:when (member (syntax-e #'op) '(+ - / *))))
+ #:when (member (syntax-e #'op) '(+ - / * &))))
(define-syntax-class oref
#:description "extra context field reference"
--- a/otf.c
+++ b/otf.c
@@ -4358,6 +4358,99 @@
}
int
+read_Tuple(Otf *o, Tuple *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, o->axisCount*2)) == nil)
+ goto err;
+ v->coordinates = malloc(o->axisCount*sizeof(*v->coordinates));
+ for(int i = 0; i < o->axisCount; i++)
+ v->coordinates[i] = (b[0+i*2]<<8 | b[1+i*2]>>14)+(b[0+i*2]<<8 | b[1+i*2]&((1<<14)-1))/16384.0;
+ return 0;
+err:
+ werrstr("%s: %r", "Tuple");
+ return -1;
+}
+
+void
+print_Tuple(Biobuf *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]);
+ USED(o);
+}
+
+int
+read_TupleVariationHeader(Otf *o, TupleVariationHeader *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->variationDataSize = b[0]<<8 | b[1];
+ v->tupleIndex = b[2]<<8 | b[3];
+ if(read_Tuple(o, &v->peakTuple) < 0){
+ werrstr("%s: %r", "peakTuple");
+ goto err;
+ }
+ if(read_Tuple(o, &v->intermediateStartTuple) < 0){
+ werrstr("%s: %r", "intermediateStartTuple");
+ goto err;
+ }
+ if(read_Tuple(o, &v->intermediateEndTuple) < 0){
+ werrstr("%s: %r", "intermediateEndTuple");
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "TupleVariationHeader");
+ return -1;
+}
+
+void
+print_TupleVariationHeader(Biobuf *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");
+ print_Tuple(f, indent+indentΔ, o, &v->peakTuple);
+ Bprint(f, "%*s%s:\n", indent, "", "intermediateStartTuple");
+ print_Tuple(f, indent+indentΔ, o, &v->intermediateStartTuple);
+ Bprint(f, "%*s%s:\n", indent, "", "intermediateEndTuple");
+ print_Tuple(f, indent+indentΔ, o, &v->intermediateEndTuple);
+ USED(o);
+}
+
+int
+read_GlyphVariationData(Otf *o, GlyphVariationData *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->tupleVariationCount = b[0]<<8 | b[1];
+ v->dataOffset = b[2]<<8 | b[3];
+ if(otfarray(o, &v->tupleVariationHeaders, read_TupleVariationHeader, sizeof(TupleVariationHeader), (v->tupleVariationCount&4095)) < 0){
+ werrstr("%s: %r", "tupleVariationHeaders");
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "GlyphVariationData");
+ return -1;
+}
+
+void
+print_GlyphVariationData(Biobuf *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);
+ for(int i = 0; i < (v->tupleVariationCount&4095); i++){
+ Bprint(f, "%*s%s[%d]:\n", indent, "", "tupleVariationHeaders", i);
+ print_TupleVariationHeader(f, indent+indentΔ, o, &v->tupleVariationHeaders[i]);
+ }
+ USED(o);
+}
+
+int
read_TableGvar(Otf *o, TableGvar *v)
{
u8int *b;
@@ -4393,6 +4486,16 @@
for(int i = 0; i < (v->glyphCount+1); i++)
v->glyphVariationDataOffsetsLong[i] = b[0+i*4]<<24 | b[1+i*4]<<16 | b[2+i*4]<<8 | b[3+i*4];
}
+ if(v->sharedTuplesOffset != 0){
+ if(otfpushrange(o, v->sharedTuplesOffset, -1) < 0)
+ goto err;
+ if(otfarray(o, &v->sharedTuples, read_Tuple, sizeof(Tuple), v->sharedTupleCount) < 0){
+ werrstr("%s: %r", "sharedTuples");
+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
return 0;
err:
werrstr("%s: %r", "TableGvar");
@@ -4416,6 +4519,10 @@
for(int i = 0; i < (v->glyphCount+1); i++)
Bprint(f, "%*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);
+ print_Tuple(f, indent+indentΔ, o, &v->sharedTuples[i]);
+ }
USED(o);
}
@@ -4958,6 +5065,20 @@
rec->print = (void*)print_TableGasp;
break;
case (u32int)('g'<<24|'v'<<16|'a'<<8|'r'):
+ {
+ static int retried = 0;
+ if(v->fvar == nil){
+ if(retried){
+ werrstr("%s: deps missing", "TableGvar");
+ goto err;
+ }
+ retried = 1;
+ retry++;
+ break;
+ }
+ if(retried)
+ retry--;
+ }
if(v->gvar != nil)
break;
v->gvar = calloc(1, sizeof(TableGvar));
--- a/otf.h
+++ b/otf.h
@@ -108,6 +108,9 @@
typedef struct TableSTAT TableSTAT;
typedef struct GaspRange GaspRange;
typedef struct TableGasp TableGasp;
+typedef struct Tuple Tuple;
+typedef struct TupleVariationHeader TupleVariationHeader;
+typedef struct GlyphVariationData GlyphVariationData;
typedef struct TableGvar TableGvar;
typedef struct AxisValueMap AxisValueMap;
typedef struct SegmentMaps SegmentMaps;
@@ -1311,6 +1314,45 @@
int read_TableGasp(Otf *o, TableGasp *v);
void print_TableGasp(Biobuf *f, int indent, Otf *o, TableGasp *v);
+struct Tuple {
+ float *coordinates;
+};
+
+int read_Tuple(Otf *o, Tuple *v);
+void print_Tuple(Biobuf *f, int indent, Otf *o, Tuple *v);
+
+enum { // TupleVariationHeader
+ // tupleIndex
+ TUPLEINDEX_FL_PRIVATE_POINT_NUMBERS = 1<<13,
+ TUPLEINDEX_FL_INTERMEDIATE_REGION = 1<<14,
+ TUPLEINDEX_FL_EMBEDDED_PEAK_TUPLE = 1<<15,
+};
+
+struct TupleVariationHeader {
+ u16int variationDataSize;
+ u16int tupleIndex;
+ Tuple peakTuple;
+ Tuple intermediateStartTuple;
+ Tuple intermediateEndTuple;
+};
+
+int read_TupleVariationHeader(Otf *o, TupleVariationHeader *v);
+void print_TupleVariationHeader(Biobuf *f, int indent, Otf *o, TupleVariationHeader *v);
+
+enum { // GlyphVariationData
+ // tupleVariationCount
+ COUNT_FL_SHARED_POINT_NUMBERS = 1<<15,
+};
+
+struct GlyphVariationData {
+ u16int tupleVariationCount;
+ u16int dataOffset;
+ TupleVariationHeader *tupleVariationHeaders;
+};
+
+int read_GlyphVariationData(Otf *o, GlyphVariationData *v);
+void print_GlyphVariationData(Biobuf *f, int indent, Otf *o, GlyphVariationData *v);
+
enum { // TableGvar
// flags
GVAR_FL_LONG_OFFSETS = 1<<0,
@@ -1327,6 +1369,7 @@
u32int glyphVariationDataArrayOffset;
u16int *glyphVariationDataOffsetsShort;
u32int *glyphVariationDataOffsetsLong;
+ Tuple *sharedTuples;
};
int read_TableGvar(Otf *o, TableGvar *v);
--- a/otf.rkt
+++ b/otf.rkt
@@ -773,6 +773,27 @@
{GaspRange gaspRanges [numRanges]}
#:tag "gasp")
+(mkcmplx Tuple {F2DOT14 coordinates [o->axisCount]})
+
+(define tupleIndexFlags
+ #hash((13 . TUPLEINDEX_FL_PRIVATE_POINT_NUMBERS)
+ (14 . TUPLEINDEX_FL_INTERMEDIATE_REGION)
+ (15 . TUPLEINDEX_FL_EMBEDDED_PEAK_TUPLE)))
+
+(mkcmplx TupleVariationHeader
+ {uint16 variationDataSize}
+ {uint16 tupleIndex (bits tupleIndexFlags)} ; FIXME 0xfff is TUPLE_INDEX_MASK
+ {Tuple peakTuple}
+ {Tuple intermediateStartTuple}
+ {Tuple intermediateEndTuple})
+
+(define glyphVariationDataCountFlags #hash((15 . COUNT_FL_SHARED_POINT_NUMBERS)))
+
+(mkcmplx GlyphVariationData
+ {uint16 tupleVariationCount (bits glyphVariationDataCountFlags)}
+ {Offset16 dataOffset}
+ {TupleVariationHeader tupleVariationHeaders [& tupleVariationCount #xfff]})
+
(define gvarFlags #hash((0 . GVAR_FL_LONG_OFFSETS)))
(mkcmplx
@@ -787,7 +808,9 @@
{Offset32 glyphVariationDataArrayOffset}
{Offset16 glyphVariationDataOffsetsShort [+ glyphCount 1] (== (& flags GVAR_FL_LONG_OFFSETS) 0)}
{Offset32 glyphVariationDataOffsetsLong [+ glyphCount 1] (!= (& flags GVAR_FL_LONG_OFFSETS) 0)}
- #:tag "gvar")
+ {Tuple sharedTuples [sharedTupleCount] (at sharedTuplesOffset)}
+ #:tag "gvar"
+ #:after (list TableFvar))
(mkcmplx AxisValueMap {F2DOT14 fromCoordinate} {F2DOT14 toCoordinate})