ref: 542ec0666f609eb98baf5187bdf1d84b2b08e71c
parent: d44ae07e343d91452f7cd0bc8f78024f2ab3883a
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Jun 21 20:37:02 EDT 2024
more definitions
--- a/otf.c
+++ b/otf.c
@@ -21,6 +21,9 @@
u16int axisCount;
u16int instanceCount;
u16int instanceSize;
+ u16int designAxisSize;
+ u16int designAxisCount;
+ u16int axisValueCount;
};
struct Range {
@@ -3629,7 +3632,7 @@
print_KernSubtable(Biobuf *f, int indent, Otf *o, KernSubtable *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
- Bprint(f, "%*s%s: %ud\n", indent, "", "coverage", v->coverage);
+ Bprint(f, "%*s%s: %#ux\n", indent, "", "coverage", v->coverage);
USED(o);
}
@@ -3729,7 +3732,7 @@
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: %ud\n", indent, "", "flags", v->flags);
+ Bprint(f, "%*s%s: %#ux\n", indent, "", "flags", v->flags);
Bprint(f, "%*s%s: %ud\n", indent, "", "axisNameID", v->axisNameID);
USED(o);
}
@@ -3784,7 +3787,7 @@
print_InstanceRecord(Biobuf *f, int indent, Otf *o, InstanceRecord *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "subfamilyNameID", v->subfamilyNameID);
- Bprint(f, "%*s%s: %ud\n", indent, "", "flags", v->flags);
+ Bprint(f, "%*s%s: %#ux\n", indent, "", "flags", v->flags);
Bprint(f, "%*s%s:\n", indent, "", "coordinates");
print_UserTuple(f, indent+indentΔ, o, &v->coordinates);
if((o->instanceSize==((o->axisCount*4)+6)))
@@ -3883,6 +3886,285 @@
}
int
+read_RegionAxisCoordinates(Otf *o, RegionAxisCoordinates *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 6)) == nil)
+ goto err;
+ v->startCoord = (b[0]<<8 | b[1]>>14)+(b[0]<<8 | b[1]&((1<<14)-1))/16384.0;
+ v->peakCoord = (b[2]<<8 | b[3]>>14)+(b[2]<<8 | b[3]&((1<<14)-1))/16384.0;
+ v->endCoord = (b[4]<<8 | b[5]>>14)+(b[4]<<8 | b[5]&((1<<14)-1))/16384.0;
+ return 0;
+err:
+ werrstr("%s: %r", "RegionAxisCoordinates");
+ return -1;
+}
+
+void
+print_RegionAxisCoordinates(Biobuf *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);
+ USED(o);
+}
+
+int
+read_VariationRegion(Otf *o, VariationRegion *v)
+{
+ u8int *b;
+ if(otfarray(o, &v->regionAxes, read_RegionAxisCoordinates, sizeof(RegionAxisCoordinates), o->axisCount) < 0){
+ werrstr("%s: %r", "regionAxes");
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "VariationRegion");
+ return -1;
+}
+
+void
+print_VariationRegion(Biobuf *f, int indent, Otf *o, VariationRegion *v)
+{
+ for(int i = 0; i < o->axisCount; i++){
+ Bprint(f, "%*s%s[%d]:\n", indent, "", "regionAxes", i);
+ print_RegionAxisCoordinates(f, indent+indentΔ, o, &v->regionAxes[i]);
+ }
+ USED(o);
+}
+
+int
+read_VariationRegionList(Otf *o, VariationRegionList *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->axisCount = b[0]<<8 | b[1];
+ v->regionCount = b[2]<<8 | b[3];
+ if(otfarray(o, &v->variationRegion, read_VariationRegion, sizeof(VariationRegion), v->regionCount) < 0){
+ werrstr("%s: %r", "variationRegion");
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "VariationRegionList");
+ return -1;
+}
+
+void
+print_VariationRegionList(Biobuf *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);
+ for(int i = 0; i < v->regionCount; i++){
+ Bprint(f, "%*s%s[%d]:\n", indent, "", "variationRegion", i);
+ print_VariationRegion(f, indent+indentΔ, o, &v->variationRegion[i]);
+ }
+ USED(o);
+}
+
+int
+read_ItemVariationData(Otf *o, ItemVariationData *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 6)) == nil)
+ goto err;
+ v->itemCount = b[0]<<8 | b[1];
+ v->wordDeltaCount = b[2]<<8 | b[3];
+ v->regionIndexCount = b[4]<<8 | b[5];
+ if((b = otfreadn(o, v->regionIndexCount*2)) == nil)
+ goto err;
+ v->regionIndexes = malloc(v->regionIndexCount*sizeof(*v->regionIndexes));
+ for(int i = 0; i < v->regionIndexCount; i++)
+ v->regionIndexes[i] = b[0+i*2]<<8 | b[1+i*2];
+ return 0;
+err:
+ werrstr("%s: %r", "ItemVariationData");
+ return -1;
+}
+
+void
+print_ItemVariationData(Biobuf *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);
+ for(int i = 0; i < v->regionIndexCount; i++)
+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "regionIndexes", i, v->regionIndexes[i]);
+ USED(o);
+}
+
+int
+read_ItemVariationStore(Otf *o, ItemVariationStore *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 8)) == nil)
+ goto err;
+ u16int format = b[0]<<8 | b[1];
+ if(format != 1){
+ werrstr("%s: invalid value: %d (0x%ux)", "format", format, format);
+ goto err;
+ }
+ v->variationRegionListOffset = b[2]<<24 | b[3]<<16 | b[4]<<8 | b[5];
+ v->itemVariationDataCount = b[6]<<8 | b[7];
+ if((b = otfreadn(o, v->itemVariationDataCount*4)) == nil)
+ goto err;
+ v->itemVariationDataOffsets = malloc(v->itemVariationDataCount*sizeof(*v->itemVariationDataOffsets));
+ for(int i = 0; i < v->itemVariationDataCount; i++)
+ v->itemVariationDataOffsets[i] = b[0+i*4]<<24 | b[1+i*4]<<16 | b[2+i*4]<<8 | b[3+i*4];
+ return 0;
+err:
+ werrstr("%s: %r", "ItemVariationStore");
+ return -1;
+}
+
+void
+print_ItemVariationStore(Biobuf *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);
+ for(int i = 0; i < v->itemVariationDataCount; i++)
+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "itemVariationDataOffsets", i, v->itemVariationDataOffsets[i]);
+ USED(o);
+}
+
+int
+read_DeltaSetIndexMap(Otf *o, DeltaSetIndexMap *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 2)) == nil)
+ goto err;
+ v->format = b[0];
+ if(v->format != 0 && v->format != 1){
+ werrstr("%s: invalid value: %d (0x%ux)", "format", v->format, v->format);
+ goto err;
+ }
+ v->entryFormat = b[1];
+ if(v->format == 0){
+ if((b = otfreadn(o, 2)) == nil)
+ goto err;
+ v->mapCount0 = b[0]<<8 | b[1];
+ }
+ if(v->format == 1){
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->mapCount1 = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
+ }
+ if((b = otfreadn(o, 1)) == nil)
+ goto err;
+ v->mapData = b[0];
+ return 0;
+err:
+ werrstr("%s: %r", "DeltaSetIndexMap");
+ return -1;
+}
+
+void
+print_DeltaSetIndexMap(Biobuf *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);
+ if(v->format == 0)
+ Bprint(f, "%*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);
+ USED(o);
+}
+
+int
+read_TableHVAR(Otf *o, TableHVAR *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 20)) == nil)
+ goto err;
+ u16int majorVersion = b[0]<<8 | b[1];
+ if(majorVersion != 1){
+ werrstr("%s: invalid value: %d (0x%ux)", "majorVersion", majorVersion, majorVersion);
+ goto err;
+ }
+ u16int minorVersion = b[2]<<8 | b[3];
+ if(minorVersion != 0){
+ werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", minorVersion, minorVersion);
+ goto err;
+ }
+ v->itemVariationStoreOffset = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
+ v->advanceWidthMappingOffset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
+ v->lsbMappingOffset = b[12]<<24 | b[13]<<16 | b[14]<<8 | b[15];
+ v->rsbMappingOffset = b[16]<<24 | b[17]<<16 | b[18]<<8 | b[19];
+ if(v->itemVariationStoreOffset != 0){
+ if(otfpushrange(o, v->itemVariationStoreOffset, -1) < 0)
+ goto err;
+ v->itemVariationStore = calloc(1, sizeof(*v->itemVariationStore));
+ if(read_ItemVariationStore(o, v->itemVariationStore) < 0){
+ werrstr("%s: %r", "itemVariationStore");
+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ if(v->advanceWidthMappingOffset != 0){
+ if(otfpushrange(o, v->advanceWidthMappingOffset, -1) < 0)
+ goto err;
+ v->advanceWidthMapping = calloc(1, sizeof(*v->advanceWidthMapping));
+ if(read_DeltaSetIndexMap(o, v->advanceWidthMapping) < 0){
+ werrstr("%s: %r", "advanceWidthMapping");
+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ if(v->lsbMappingOffset != 0){
+ if(otfpushrange(o, v->lsbMappingOffset, -1) < 0)
+ goto err;
+ v->lsbMapping = calloc(1, sizeof(*v->lsbMapping));
+ if(read_DeltaSetIndexMap(o, v->lsbMapping) < 0){
+ werrstr("%s: %r", "lsbMapping");
+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ if(v->rsbMappingOffset != 0){
+ if(otfpushrange(o, v->rsbMappingOffset, -1) < 0)
+ goto err;
+ v->rsbMapping = calloc(1, sizeof(*v->rsbMapping));
+ if(read_DeltaSetIndexMap(o, v->rsbMapping) < 0){
+ werrstr("%s: %r", "rsbMapping");
+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "TableHVAR");
+ return -1;
+}
+
+void
+print_TableHVAR(Biobuf *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");
+ if(v->itemVariationStore != nil)
+ print_ItemVariationStore(f, indent+indentΔ, o, v->itemVariationStore);
+ Bprint(f, "%*s%s:\n", indent, "", "advanceWidthMapping");
+ if(v->advanceWidthMapping != nil)
+ print_DeltaSetIndexMap(f, indent+indentΔ, o, v->advanceWidthMapping);
+ Bprint(f, "%*s%s:\n", indent, "", "lsbMapping");
+ if(v->lsbMapping != nil)
+ print_DeltaSetIndexMap(f, indent+indentΔ, o, v->lsbMapping);
+ Bprint(f, "%*s%s:\n", indent, "", "rsbMapping");
+ if(v->rsbMapping != nil)
+ print_DeltaSetIndexMap(f, indent+indentΔ, o, v->rsbMapping);
+ USED(o);
+}
+
+int
read_TableFFTM(Otf *o, TableFFTM *v)
{
u8int *b;
@@ -4011,7 +4293,7 @@
print_TableDSIG(Biobuf *f, int indent, Otf *o, TableDSIG *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "numSignatures", v->numSignatures);
- Bprint(f, "%*s%s: %ud\n", indent, "", "flags", v->flags);
+ Bprint(f, "%*s%s: %#ux\n", indent, "", "flags", v->flags);
for(int i = 0; i < v->numSignatures; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "signatureRecords", i);
print_SignatureRecord(f, indent+indentΔ, o, &v->signatureRecords[i]);
@@ -4020,6 +4302,223 @@
}
int
+read_AxisRecord(Otf *o, AxisRecord *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 8)) == nil)
+ goto err;
+ v->axisTag = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
+ v->axisNameID = b[4]<<8 | b[5];
+ v->axisOrdering = b[6]<<8 | b[7];
+ if((b = otfreadn(o, (o->designAxisSize-8)*1)) == nil)
+ goto err;
+ USED(b);
+ return 0;
+err:
+ werrstr("%s: %r", "AxisRecord");
+ return -1;
+}
+
+void
+print_AxisRecord(Biobuf *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);
+ USED(o);
+}
+
+int
+read_DesignAxes(Otf *o, DesignAxes *v)
+{
+ u8int *b;
+ if(otfarray(o, &v->designAxes, read_AxisRecord, sizeof(AxisRecord), o->designAxisCount) < 0){
+ werrstr("%s: %r", "designAxes");
+ goto err;
+ }
+ if((b = otfreadn(o, o->axisValueCount*2)) == nil)
+ goto err;
+ v->axisValueOffsets = malloc(o->axisValueCount*sizeof(*v->axisValueOffsets));
+ for(int i = 0; i < o->axisValueCount; i++)
+ v->axisValueOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
+ return 0;
+err:
+ werrstr("%s: %r", "DesignAxes");
+ return -1;
+}
+
+void
+print_DesignAxes(Biobuf *f, int indent, Otf *o, DesignAxes *v)
+{
+ for(int i = 0; i < o->designAxisCount; i++){
+ Bprint(f, "%*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]);
+ USED(o);
+}
+
+int
+read_TableSTAT(Otf *o, TableSTAT *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 18)) == nil)
+ goto err;
+ u16int majorVersion = b[0]<<8 | b[1];
+ if(majorVersion != 1){
+ werrstr("%s: invalid value: %d (0x%ux)", "majorVersion", majorVersion, majorVersion);
+ goto err;
+ }
+ v->minorVersion = b[2]<<8 | b[3];
+ if(v->minorVersion != 0 && v->minorVersion != 1 && v->minorVersion != 2){
+ werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", v->minorVersion, v->minorVersion);
+ goto err;
+ }
+ v->designAxisSize = b[4]<<8 | b[5];
+ o->designAxisSize = v->designAxisSize;
+ v->designAxisCount = b[6]<<8 | b[7];
+ o->designAxisCount = v->designAxisCount;
+ v->designAxesOffset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
+ v->axisValueCount = b[12]<<8 | b[13];
+ o->axisValueCount = v->axisValueCount;
+ v->offsetToAxisValueOffsets = b[14]<<24 | b[15]<<16 | b[16]<<8 | b[17];
+ if(v->minorVersion > 0){
+ if((b = otfreadn(o, 2)) == nil)
+ goto err;
+ v->elidedFallbackNameID = b[0]<<8 | b[1];
+ }
+ if(v->designAxesOffset != 0){
+ if(otfpushrange(o, v->designAxesOffset, -1) < 0)
+ goto err;
+ v->designAxes = calloc(1, sizeof(*v->designAxes));
+ if(read_DesignAxes(o, v->designAxes) < 0){
+ werrstr("%s: %r", "designAxes");
+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "TableSTAT");
+ return -1;
+}
+
+void
+print_TableSTAT(Biobuf *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);
+ if(v->minorVersion > 0)
+ Bprint(f, "%*s%s: %ud\n", indent, "", "elidedFallbackNameID", v->elidedFallbackNameID);
+ Bprint(f, "%*s%s:\n", indent, "", "designAxes");
+ if(v->designAxes != nil)
+ print_DesignAxes(f, indent+indentΔ, o, v->designAxes);
+ USED(o);
+}
+
+int
+read_GaspRange(Otf *o, GaspRange *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->rangeMaxPPEM = b[0]<<8 | b[1];
+ v->rangeGaspBehavior = b[2]<<8 | b[3];
+ return 0;
+err:
+ werrstr("%s: %r", "GaspRange");
+ return -1;
+}
+
+void
+print_GaspRange(Biobuf *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);
+ USED(o);
+}
+
+int
+read_TableGasp(Otf *o, TableGasp *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->version = b[0]<<8 | b[1];
+ if(v->version != 0 && v->version != 1){
+ werrstr("%s: invalid value: %d (0x%ux)", "version", v->version, v->version);
+ goto err;
+ }
+ v->numRanges = b[2]<<8 | b[3];
+ if(otfarray(o, &v->gaspRanges, read_GaspRange, sizeof(GaspRange), v->numRanges) < 0){
+ werrstr("%s: %r", "gaspRanges");
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "TableGasp");
+ return -1;
+}
+
+void
+print_TableGasp(Biobuf *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);
+ for(int i = 0; i < v->numRanges; i++){
+ Bprint(f, "%*s%s[%d]:\n", indent, "", "gaspRanges", i);
+ print_GaspRange(f, indent+indentΔ, o, &v->gaspRanges[i]);
+ }
+ USED(o);
+}
+
+int
+read_TableGvar(Otf *o, TableGvar *v)
+{
+ u8int *b;
+ if((b = otfreadn(o, 20)) == nil)
+ goto err;
+ u16int majorVersion = b[0]<<8 | b[1];
+ if(majorVersion != 1){
+ werrstr("%s: invalid value: %d (0x%ux)", "majorVersion", majorVersion, majorVersion);
+ goto err;
+ }
+ u16int minorVersion = b[2]<<8 | b[3];
+ if(minorVersion != 0){
+ werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", minorVersion, minorVersion);
+ goto err;
+ }
+ v->axisCount = b[4]<<8 | b[5];
+ v->sharedTupleCount = b[6]<<8 | b[7];
+ v->sharedTuplesOffset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
+ v->glyphCount = b[12]<<8 | b[13];
+ v->flags = b[14]<<8 | b[15];
+ v->glyphVariationDataArrayOffset = b[16]<<24 | b[17]<<16 | b[18]<<8 | b[19];
+ return 0;
+err:
+ werrstr("%s: %r", "TableGvar");
+ return -1;
+}
+
+void
+print_TableGvar(Biobuf *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\n", indent, "", "flags", v->flags);
+ Bprint(f, "%*s%s: %ud\n", indent, "", "glyphVariationDataArrayOffset", v->glyphVariationDataArrayOffset);
+ USED(o);
+}
+
+int
read_TableOS∕2(Otf *o, TableOS∕2 *v)
{
u8int *b;
@@ -4400,6 +4899,31 @@
rec->parsed = v->fvar;
rec->print = (void*)print_TableFvar;
break;
+ case (u32int)('H'<<24|'V'<<16|'A'<<8|'R'):
+ {
+ static int retried = 0;
+ if(v->fvar == nil){
+ if(retried){
+ werrstr("%s: deps missing", "TableHVAR");
+ goto err;
+ }
+ retried = 1;
+ retry++;
+ break;
+ }
+ if(retried)
+ retry--;
+ }
+ if(v->hvar != nil)
+ break;
+ v->hvar = calloc(1, sizeof(TableHVAR));
+ if(read_TableHVAR(o, v->hvar) < 0){
+ free(v->hvar);
+ goto err;
+ }
+ rec->parsed = v->hvar;
+ rec->print = (void*)print_TableHVAR;
+ break;
case (u32int)('F'<<24|'F'<<16|'T'<<8|'M'):
if(v->fftm != nil)
break;
@@ -4421,6 +4945,39 @@
}
rec->parsed = v->dsig;
rec->print = (void*)print_TableDSIG;
+ break;
+ case (u32int)('S'<<24|'T'<<16|'A'<<8|'T'):
+ if(v->stat != nil)
+ break;
+ v->stat = calloc(1, sizeof(TableSTAT));
+ if(read_TableSTAT(o, v->stat) < 0){
+ free(v->stat);
+ goto err;
+ }
+ rec->parsed = v->stat;
+ rec->print = (void*)print_TableSTAT;
+ break;
+ case (u32int)('g'<<24|'a'<<16|'s'<<8|'p'):
+ if(v->gasp != nil)
+ break;
+ v->gasp = calloc(1, sizeof(TableGasp));
+ if(read_TableGasp(o, v->gasp) < 0){
+ free(v->gasp);
+ goto err;
+ }
+ rec->parsed = v->gasp;
+ rec->print = (void*)print_TableGasp;
+ break;
+ case (u32int)('g'<<24|'v'<<16|'a'<<8|'r'):
+ if(v->gvar != nil)
+ break;
+ v->gvar = calloc(1, sizeof(TableGvar));
+ if(read_TableGvar(o, v->gvar) < 0){
+ free(v->gvar);
+ goto err;
+ }
+ rec->parsed = v->gvar;
+ rec->print = (void*)print_TableGvar;
break;
case (u32int)('O'<<24|'S'<<16|'/'<<8|'2'):
if(v->os∕2 != nil)
--- a/otf.h
+++ b/otf.h
@@ -92,10 +92,23 @@
typedef struct InstanceRecord InstanceRecord;
typedef struct AxisInstances AxisInstances;
typedef struct TableFvar TableFvar;
+typedef struct RegionAxisCoordinates RegionAxisCoordinates;
+typedef struct VariationRegion VariationRegion;
+typedef struct VariationRegionList VariationRegionList;
+typedef struct ItemVariationData ItemVariationData;
+typedef struct ItemVariationStore ItemVariationStore;
+typedef struct DeltaSetIndexMap DeltaSetIndexMap;
+typedef struct TableHVAR TableHVAR;
typedef struct TableFFTM TableFFTM;
typedef struct SignatureBlock1 SignatureBlock1;
typedef struct SignatureRecord SignatureRecord;
typedef struct TableDSIG TableDSIG;
+typedef struct AxisRecord AxisRecord;
+typedef struct DesignAxes DesignAxes;
+typedef struct TableSTAT TableSTAT;
+typedef struct GaspRange GaspRange;
+typedef struct TableGasp TableGasp;
+typedef struct TableGvar TableGvar;
typedef struct TableOS∕2 TableOS∕2;
typedef struct TableRecord TableRecord;
typedef struct TableDirectory TableDirectory;
@@ -1102,6 +1115,78 @@
int read_TableFvar(Otf *o, TableFvar *v);
void print_TableFvar(Biobuf *f, int indent, Otf *o, TableFvar *v);
+struct RegionAxisCoordinates {
+ float startCoord;
+ float peakCoord;
+ float endCoord;
+};
+
+int read_RegionAxisCoordinates(Otf *o, RegionAxisCoordinates *v);
+void print_RegionAxisCoordinates(Biobuf *f, int indent, Otf *o, RegionAxisCoordinates *v);
+
+struct VariationRegion {
+ RegionAxisCoordinates *regionAxes;
+};
+
+int read_VariationRegion(Otf *o, VariationRegion *v);
+void print_VariationRegion(Biobuf *f, int indent, Otf *o, VariationRegion *v);
+
+struct VariationRegionList {
+ u16int axisCount;
+ u16int regionCount;
+ VariationRegion *variationRegion;
+};
+
+int read_VariationRegionList(Otf *o, VariationRegionList *v);
+void print_VariationRegionList(Biobuf *f, int indent, Otf *o, VariationRegionList *v);
+
+struct ItemVariationData {
+ u16int itemCount;
+ u16int wordDeltaCount;
+ u16int regionIndexCount;
+ u16int *regionIndexes;
+};
+
+int read_ItemVariationData(Otf *o, ItemVariationData *v);
+void print_ItemVariationData(Biobuf *f, int indent, Otf *o, ItemVariationData *v);
+
+struct ItemVariationStore {
+ // u16int format;
+ u32int variationRegionListOffset;
+ u16int itemVariationDataCount;
+ u32int *itemVariationDataOffsets;
+};
+
+int read_ItemVariationStore(Otf *o, ItemVariationStore *v);
+void print_ItemVariationStore(Biobuf *f, int indent, Otf *o, ItemVariationStore *v);
+
+struct DeltaSetIndexMap {
+ u8int format;
+ u8int entryFormat;
+ u16int mapCount0;
+ u32int mapCount1;
+ u8int mapData;
+};
+
+int read_DeltaSetIndexMap(Otf *o, DeltaSetIndexMap *v);
+void print_DeltaSetIndexMap(Biobuf *f, int indent, Otf *o, DeltaSetIndexMap *v);
+
+struct TableHVAR {
+ // u16int majorVersion;
+ // u16int minorVersion;
+ u32int itemVariationStoreOffset;
+ u32int advanceWidthMappingOffset;
+ u32int lsbMappingOffset;
+ u32int rsbMappingOffset;
+ ItemVariationStore *itemVariationStore;
+ DeltaSetIndexMap *advanceWidthMapping;
+ DeltaSetIndexMap *lsbMapping;
+ DeltaSetIndexMap *rsbMapping;
+};
+
+int read_TableHVAR(Otf *o, TableHVAR *v);
+void print_TableHVAR(Biobuf *f, int indent, Otf *o, TableHVAR *v);
+
struct TableFFTM {
u32int version;
s64int fontforge;
@@ -1142,6 +1227,70 @@
int read_TableDSIG(Otf *o, TableDSIG *v);
void print_TableDSIG(Biobuf *f, int indent, Otf *o, TableDSIG *v);
+struct AxisRecord {
+ u32int axisTag;
+ u16int axisNameID;
+ u16int axisOrdering;
+ // u8int *unused;
+};
+
+int read_AxisRecord(Otf *o, AxisRecord *v);
+void print_AxisRecord(Biobuf *f, int indent, Otf *o, AxisRecord *v);
+
+struct DesignAxes {
+ AxisRecord *designAxes;
+ u16int *axisValueOffsets;
+};
+
+int read_DesignAxes(Otf *o, DesignAxes *v);
+void print_DesignAxes(Biobuf *f, int indent, Otf *o, DesignAxes *v);
+
+struct TableSTAT {
+ // u16int majorVersion;
+ u16int minorVersion;
+ u16int designAxisSize;
+ u16int designAxisCount;
+ u32int designAxesOffset;
+ u16int axisValueCount;
+ u32int offsetToAxisValueOffsets;
+ u16int elidedFallbackNameID;
+ DesignAxes *designAxes;
+};
+
+int read_TableSTAT(Otf *o, TableSTAT *v);
+void print_TableSTAT(Biobuf *f, int indent, Otf *o, TableSTAT *v);
+
+struct GaspRange {
+ u16int rangeMaxPPEM;
+ u16int rangeGaspBehavior;
+};
+
+int read_GaspRange(Otf *o, GaspRange *v);
+void print_GaspRange(Biobuf *f, int indent, Otf *o, GaspRange *v);
+
+struct TableGasp {
+ u16int version;
+ u16int numRanges;
+ GaspRange *gaspRanges;
+};
+
+int read_TableGasp(Otf *o, TableGasp *v);
+void print_TableGasp(Biobuf *f, int indent, Otf *o, TableGasp *v);
+
+struct TableGvar {
+ // u16int majorVersion;
+ // u16int minorVersion;
+ u16int axisCount;
+ u16int sharedTupleCount;
+ u32int sharedTuplesOffset;
+ u16int glyphCount;
+ u16int flags;
+ u32int glyphVariationDataArrayOffset;
+};
+
+int read_TableGvar(Otf *o, TableGvar *v);
+void print_TableGvar(Biobuf *f, int indent, Otf *o, TableGvar *v);
+
struct TableOS∕2 {
u16int version;
s16int xAvgCharWidth;
@@ -1222,8 +1371,12 @@
TableKern *kern;
TableLoca *loca;
TableFvar *fvar;
+ TableHVAR *hvar;
TableFFTM *fftm;
TableDSIG *dsig;
+ TableSTAT *stat;
+ TableGasp *gasp;
+ TableGvar *gvar;
TableOS∕2 *os∕2;
};
--- a/otf.rkt
+++ b/otf.rkt
@@ -53,9 +53,12 @@
(mkcmplx SubtableCmap0 {uint16 length} {uint16 language} {uint8 glyphIdArray [256]})
; FIXME
-(mkcmplx SubtableCmap2 {uint16 length} {uint16 language} {uint16 subHeaderKeys [256]})
-#| {SubHeader subHeaders[?]}
- {uint16 glyphIdArray[?]}))|#
+(mkcmplx SubtableCmap2
+ {uint16 length}
+ {uint16 language}
+ {uint16 subHeaderKeys [256]}
+ #;{SubHeader subHeaders [?]}
+ #;{uint16 glyphIdArray [?]})
; FIXME
(mkcmplx SubtableCmap4
@@ -594,7 +597,7 @@
(mkcmplx KernSubtable
{uint16 version (== 0) unused}
{uint16 length (>= 6)} ; including this header
- {uint16 coverage}) ; FIXME the rest depends on the coverage bits (8-15 = 0 or 2)
+ {uint16 coverage hex}) ; FIXME the rest depends on the coverage bits (8-15 = 0 or 2)
(mkcmplx TableKern
{uint16 version (== 0) unused}
@@ -613,7 +616,7 @@
{Fixed minValue}
{Fixed defaultValue}
{Fixed maxValue}
- {uint16 flags}
+ {uint16 flags hex}
{uint16 axisNameID})
(mkcmplx UserTuple {Fixed coordinates [o->axisCount]})
@@ -620,7 +623,7 @@
(mkcmplx InstanceRecord
{uint16 subfamilyNameID}
- {uint16 flags}
+ {uint16 flags hex}
{UserTuple coordinates}
{uint16 postScriptNameID (== o->instanceSize (+ (* o->axisCount 4) 6))})
@@ -640,6 +643,56 @@
{AxisInstances axisInstances (at axesArrayOffset)}
#:tag "fvar")
+(mkcmplx RegionAxisCoordinates
+ {F2DOT14 startCoord}
+ {F2DOT14 peakCoord}
+ {F2DOT14 endCoord}) ; FIXME add an #:extra validation test here?
+
+(mkcmplx VariationRegion {RegionAxisCoordinates regionAxes [o->axisCount]})
+
+(mkcmplx VariationRegionList
+ {uint16 axisCount #;(== o->axisCount)} ; FIXME
+ {uint16 regionCount}
+ {VariationRegion variationRegion [regionCount]})
+
+(mkcmplx ItemVariationData
+ {uint16 itemCount}
+ {uint16 wordDeltaCount hex} ; FIXME &0x8000 LONG_WORDS, &0x7fff WORD_DELTA_COUNT_MASK
+ {uint16 regionIndexCount}
+ {uint16 regionIndexes [regionIndexCount]}
+ #;{DeltaSet deltaSets [itemCount]}) ; FIXME this one's awkward
+
+(mkcmplx ItemVariationStore
+ {uint16 format (== 1) unused}
+ {Offset32 variationRegionListOffset}
+ {uint16 itemVariationDataCount}
+ {Offset32 itemVariationDataOffsets [itemVariationDataCount]}
+ #;{ItemVariationData
+ itemVariationData
+ [itemVariationDataCount]
+ (at itemVariationDataOffsets)}) ; FIXME offsets array
+
+(mkcmplx DeltaSetIndexMap
+ {uint8 format (== 0 1)}
+ {uint8 entryFormat hex} ; FIXME flags/masks here
+ {uint16 mapCount0 (== format 0)}
+ {uint32 mapCount1 (== format 1)}
+ {uint8 mapData #;[?]}) ; FIXME here we go with even more awkward one
+
+(mkcmplx TableHVAR
+ {uint16 majorVersion (== 1) unused}
+ {uint16 minorVersion (== 0) unused}
+ {Offset32 itemVariationStoreOffset}
+ {Offset32 advanceWidthMappingOffset}
+ {Offset32 lsbMappingOffset}
+ {Offset32 rsbMappingOffset}
+ {ItemVariationStore itemVariationStore (at itemVariationStoreOffset)}
+ {DeltaSetIndexMap advanceWidthMapping (at advanceWidthMappingOffset)}
+ {DeltaSetIndexMap lsbMapping (at lsbMappingOffset)}
+ {DeltaSetIndexMap rsbMapping (at rsbMappingOffset)}
+ #:tag "HVAR"
+ #:after (list TableFvar)) ; as dep to test axisCount within matching the fvar's
+
(mkcmplx TableFFTM
{uint32 version}
{LONGDATETIME fontforge (== version 1)}
@@ -662,9 +715,51 @@
(mkcmplx TableDSIG
{uint32 version (== 1) unused}
{uint16 numSignatures}
- {uint16 flags}
+ {uint16 flags hex}
{SignatureRecord signatureRecords [numSignatures]}
#:tag "DSIG")
+
+(mkcmplx AxisRecord
+ {Tag axisTag}
+ {uint16 axisNameID}
+ {uint16 axisOrdering}
+ {uint8 unused [- o->designAxisSize 8] unused})
+
+(mkcmplx DesignAxes
+ {AxisRecord designAxes [o->designAxisCount]}
+ {Offset16 axisValueOffsets [o->axisValueCount]}) ; FIXME array of offsets
+
+(mkcmplx TableSTAT
+ {uint16 majorVersion (== 1) unused}
+ {uint16 minorVersion (== 0 1 2)} ; 0 is deprecated
+ {uint16 designAxisSize ->o}
+ {uint16 designAxisCount ->o}
+ {Offset32 designAxesOffset}
+ {uint16 axisValueCount ->o}
+ {Offset32 offsetToAxisValueOffsets}
+ {uint16 elidedFallbackNameID (> minorVersion 0)}
+ {DesignAxes designAxes (at designAxesOffset)}
+ #:tag "STAT")
+
+(mkcmplx GaspRange {uint16 rangeMaxPPEM} {uint16 rangeGaspBehavior hex})
+
+(mkcmplx TableGasp
+ {uint16 version (== 0 1)}
+ {uint16 numRanges}
+ {GaspRange gaspRanges [numRanges]}
+ #:tag "gasp")
+
+(mkcmplx TableGvar
+ {uint16 majorVersion (== 1) unused}
+ {uint16 minorVersion (== 0) unused}
+ {uint16 axisCount #;(== o->axisCount)} ; FIXME
+ {uint16 sharedTupleCount}
+ {Offset32 sharedTuplesOffset}
+ {uint16 glyphCount #;(== o->glyphCount)} ; FIXME
+ {uint16 flags hex}
+ {Offset32 glyphVariationDataArrayOffset}
+ #;{Offset16/Offset32 glyphVariationDataOffsets [+ glyphCount 1]} ; FIXME
+ #:tag "gvar")
(mkcmplx TableOS∕2
{uint16 version (<= 5)}