ref: 03431f292ab32bee57e01d9dc93670c55a4411e9
dir: /otf.c/
/* this file is generated. do not modify. */
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "otf.h"
typedef struct Range Range;
struct Otf {
Biobuf *f;
Range *r;
u8int *buf;
int bufsz;
int off;
/* extra fields to simplify parsing */
s16int indexToLocFormat;
u16int numberOfHMetrics;
u16int numGlyphs;
u16int platformID;
u16int encodingID;
u16int storageOffset;
u16int firstGlyphIndex;
u16int lastGlyphIndex;
u16int axisCount;
u16int instanceCount;
u16int instanceSize;
u16int designAxisSize;
u16int designAxisCount;
u16int axisValueCount;
};
#include "otfpriv.h"
int
read_SubHeader(Otf *o, SubHeader *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->firstCode = b[0]<<8 | b[1];
v->entryCode = b[2]<<8 | b[3];
v->idDelta = b[4]<<8 | b[5];
v->idRangeOffset = b[6]<<8 | b[7];
return 0;
err:
werrstr("%s: %r", "SubHeader");
return -1;
}
void
print_SubHeader(Biobuf *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);
USED(o);
}
int
read_MapGroup(Otf *o, MapGroup *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == nil)
goto err;
v->startCharCode = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->endCharCode = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
v->startGlyphID = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
return 0;
err:
werrstr("%s: %r", "MapGroup");
return -1;
}
void
print_MapGroup(Biobuf *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);
USED(o);
}
int
read_SubtableCmap0(Otf *o, SubtableCmap0 *v)
{
u8int *b;
if((b = otfreadn(o, 260)) == nil)
goto err;
v->length = b[0]<<8 | b[1];
v->language = b[2]<<8 | b[3];
for(int i = 0; i < 256; i++)
v->glyphIdArray[i] = b[4+i*1];
return 0;
err:
werrstr("%s: %r", "SubtableCmap0");
return -1;
}
void
print_SubtableCmap0(Biobuf *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);
for(int i = 0; i < 256; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
USED(o);
}
int
read_SubtableCmap2(Otf *o, SubtableCmap2 *v)
{
u8int *b;
if((b = otfreadn(o, 516)) == nil)
goto err;
v->length = b[0]<<8 | b[1];
v->language = b[2]<<8 | b[3];
for(int i = 0; i < 256; i++)
v->subHeaderKeys[i] = b[4+i*2]<<8 | b[5+i*2];
return 0;
err:
werrstr("%s: %r", "SubtableCmap2");
return -1;
}
void
print_SubtableCmap2(Biobuf *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);
for(int i = 0; i < 256; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "subHeaderKeys", i, v->subHeaderKeys[i]);
USED(o);
}
int
read_SubtableCmap4(Otf *o, SubtableCmap4 *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == nil)
goto err;
v->length = b[0]<<8 | b[1];
v->language = b[2]<<8 | b[3];
v->segCountX2 = b[4]<<8 | b[5];
v->searchRange = b[6]<<8 | b[7];
v->entrySelector = b[8]<<8 | b[9];
v->rangeShift = b[10]<<8 | b[11];
if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
goto err;
v->endCode = malloc((v->segCountX2/2)*sizeof(*v->endCode));
for(int i = 0; i < (v->segCountX2/2); i++)
v->endCode[i] = b[0+i*2]<<8 | b[1+i*2];
if((b = otfreadn(o, 2)) == nil)
goto err;
USED(b);
if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
goto err;
v->startCode = malloc((v->segCountX2/2)*sizeof(*v->startCode));
for(int i = 0; i < (v->segCountX2/2); i++)
v->startCode[i] = b[0+i*2]<<8 | b[1+i*2];
if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
goto err;
v->idDelta = malloc((v->segCountX2/2)*sizeof(*v->idDelta));
for(int i = 0; i < (v->segCountX2/2); i++)
v->idDelta[i] = b[0+i*2]<<8 | b[1+i*2];
if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
goto err;
v->idRangeOffset = malloc((v->segCountX2/2)*sizeof(*v->idRangeOffset));
for(int i = 0; i < (v->segCountX2/2); i++)
v->idRangeOffset[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "SubtableCmap4");
return -1;
}
void
print_SubtableCmap4(Biobuf *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);
for(int i = 0; i < (v->segCountX2/2); i++)
Bprint(f, "%*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]);
for(int i = 0; i < (v->segCountX2/2); i++)
Bprint(f, "%*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]);
USED(o);
}
int
read_SubtableCmap6(Otf *o, SubtableCmap6 *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->length = b[0]<<8 | b[1];
v->language = b[2]<<8 | b[3];
v->firstCode = b[4]<<8 | b[5];
v->entryCount = b[6]<<8 | b[7];
if((b = otfreadn(o, v->entryCount*2)) == nil)
goto err;
v->glyphIdArray = malloc(v->entryCount*sizeof(*v->glyphIdArray));
for(int i = 0; i < v->entryCount; i++)
v->glyphIdArray[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "SubtableCmap6");
return -1;
}
void
print_SubtableCmap6(Biobuf *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);
for(int i = 0; i < v->entryCount; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
USED(o);
}
int
read_SubtableCmap8(Otf *o, SubtableCmap8 *v)
{
u8int *b;
if((b = otfreadn(o, 8200)) == nil)
goto err;
v->length = b[0]<<8 | b[1];
v->language = b[2]<<8 | b[3];
for(int i = 0; i < 8192; i++)
v->is32[i] = b[4+i*1];
v->numGroups = b[8196]<<24 | b[8197]<<16 | b[8198]<<8 | b[8199];
if(otfarray(o, &v->groups, read_MapGroup, sizeof(MapGroup), v->numGroups) < 0){
werrstr("%s: %r", "groups");
goto err;
}
return 0;
err:
werrstr("%s: %r", "SubtableCmap8");
return -1;
}
void
print_SubtableCmap8(Biobuf *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);
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);
for(int i = 0; i < v->numGroups; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "groups", i);
print_MapGroup(f, indent+indentΔ, o, &v->groups[i]);
}
USED(o);
}
int
read_SubtableCmap10(Otf *o, SubtableCmap10 *v)
{
u8int *b;
if((b = otfreadn(o, 18)) == nil)
goto err;
v->reserved = b[0]<<8 | b[1];
v->length = b[2]<<24 | b[3]<<16 | b[4]<<8 | b[5];
v->language = b[6]<<24 | b[7]<<16 | b[8]<<8 | b[9];
v->startCharCode = b[10]<<24 | b[11]<<16 | b[12]<<8 | b[13];
v->numChars = b[14]<<24 | b[15]<<16 | b[16]<<8 | b[17];
return 0;
err:
werrstr("%s: %r", "SubtableCmap10");
return -1;
}
void
print_SubtableCmap10(Biobuf *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);
USED(o);
}
int
read_SubtableCmap12or13(Otf *o, SubtableCmap12or13 *v)
{
u8int *b;
if((b = otfreadn(o, 14)) == nil)
goto err;
v->reserved = b[0]<<8 | b[1];
v->length = b[2]<<24 | b[3]<<16 | b[4]<<8 | b[5];
v->language = b[6]<<24 | b[7]<<16 | b[8]<<8 | b[9];
v->numGroups = b[10]<<24 | b[11]<<16 | b[12]<<8 | b[13];
if(otfarray(o, &v->groups, read_MapGroup, sizeof(MapGroup), v->numGroups) < 0){
werrstr("%s: %r", "groups");
goto err;
}
return 0;
err:
werrstr("%s: %r", "SubtableCmap12or13");
return -1;
}
void
print_SubtableCmap12or13(Biobuf *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);
for(int i = 0; i < v->numGroups; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "groups", i);
print_MapGroup(f, indent+indentΔ, o, &v->groups[i]);
}
USED(o);
}
int
read_UnicodeRange(Otf *o, UnicodeRange *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->startUnicodeValue = b[0]<<16 | b[1]<<8 | b[2];
v->additionalCount = b[3];
return 0;
err:
werrstr("%s: %r", "UnicodeRange");
return -1;
}
void
print_UnicodeRange(Biobuf *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);
USED(o);
}
int
read_DefaultUVS(Otf *o, DefaultUVS *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->numUnicodeValueRanges = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(otfarray(o, &v->ranges, read_UnicodeRange, sizeof(UnicodeRange), v->numUnicodeValueRanges) < 0){
werrstr("%s: %r", "ranges");
goto err;
}
return 0;
err:
werrstr("%s: %r", "DefaultUVS");
return -1;
}
void
print_DefaultUVS(Biobuf *f, int indent, Otf *o, DefaultUVS *v)
{
Bprint(f, "%*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);
print_UnicodeRange(f, indent+indentΔ, o, &v->ranges[i]);
}
USED(o);
}
int
read_UVSMapping(Otf *o, UVSMapping *v)
{
u8int *b;
if((b = otfreadn(o, 5)) == nil)
goto err;
v->unicodeValue = b[0]<<16 | b[1]<<8 | b[2];
v->glyphID = b[3]<<8 | b[4];
return 0;
err:
werrstr("%s: %r", "UVSMapping");
return -1;
}
void
print_UVSMapping(Biobuf *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);
USED(o);
}
int
read_NonDefaultUVS(Otf *o, NonDefaultUVS *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->numUVSMappings = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(otfarray(o, &v->uvsMappings, read_UVSMapping, sizeof(UVSMapping), v->numUVSMappings) < 0){
werrstr("%s: %r", "uvsMappings");
goto err;
}
return 0;
err:
werrstr("%s: %r", "NonDefaultUVS");
return -1;
}
void
print_NonDefaultUVS(Biobuf *f, int indent, Otf *o, NonDefaultUVS *v)
{
Bprint(f, "%*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);
print_UVSMapping(f, indent+indentΔ, o, &v->uvsMappings[i]);
}
USED(o);
}
int
read_VariationSelector(Otf *o, VariationSelector *v)
{
u8int *b;
if((b = otfreadn(o, 11)) == nil)
goto err;
v->varSelector = b[0]<<16 | b[1]<<8 | b[2];
v->defaultUVSOffset = b[3]<<24 | b[4]<<16 | b[5]<<8 | b[6];
v->nonDefaultUVSOffset = b[7]<<24 | b[8]<<16 | b[9]<<8 | b[10];
if(v->defaultUVSOffset != 0){
if(otfpushrange(o, v->defaultUVSOffset, -1) < 0)
goto err;
v->defaultUVS = calloc(1, sizeof(*v->defaultUVS));
if(read_DefaultUVS(o, v->defaultUVS) < 0){
werrstr("%s: %r", "defaultUVS");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->nonDefaultUVSOffset != 0){
if(otfpushrange(o, v->nonDefaultUVSOffset, -1) < 0)
goto err;
v->nonDefaultUVS = calloc(1, sizeof(*v->nonDefaultUVS));
if(read_NonDefaultUVS(o, v->nonDefaultUVS) < 0){
werrstr("%s: %r", "nonDefaultUVS");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "VariationSelector");
return -1;
}
void
print_VariationSelector(Biobuf *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");
if(v->defaultUVS != nil)
print_DefaultUVS(f, indent+indentΔ, o, v->defaultUVS);
Bprint(f, "%*s%s:\n", indent, "", "nonDefaultUVS");
if(v->nonDefaultUVS != nil)
print_NonDefaultUVS(f, indent+indentΔ, o, v->nonDefaultUVS);
USED(o);
}
int
read_SubtableCmap14(Otf *o, SubtableCmap14 *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->length = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->numVarSelectorRecords = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
if(otfarray(o, &v->varSelector, read_VariationSelector, sizeof(VariationSelector), v->numVarSelectorRecords) < 0){
werrstr("%s: %r", "varSelector");
goto err;
}
return 0;
err:
werrstr("%s: %r", "SubtableCmap14");
return -1;
}
void
print_SubtableCmap14(Biobuf *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);
for(int i = 0; i < v->numVarSelectorRecords; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "varSelector", i);
print_VariationSelector(f, indent+indentΔ, o, &v->varSelector[i]);
}
USED(o);
}
int
read_SubtableCmap(Otf *o, SubtableCmap *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->format = b[0]<<8 | b[1];
if(v->format != 0 && v->format != 2 && v->format != 4 && v->format != 6 && v->format != 8 && v->format != 10 && v->format != 12 && v->format != 13 && v->format != 14){
werrstr("%s: invalid value: %d (0x%ux)", "format", v->format, v->format);
goto err;
}
if(v->format == 0){
if(read_SubtableCmap0(o, &v->sub0) < 0){
werrstr("%s: %r", "sub0");
goto err;
}
}
if(v->format == 2){
if(read_SubtableCmap2(o, &v->sub2) < 0){
werrstr("%s: %r", "sub2");
goto err;
}
}
if(v->format == 4){
if(read_SubtableCmap4(o, &v->sub4) < 0){
werrstr("%s: %r", "sub4");
goto err;
}
}
if(v->format == 6){
if(read_SubtableCmap6(o, &v->sub6) < 0){
werrstr("%s: %r", "sub6");
goto err;
}
}
if(v->format == 8){
if(read_SubtableCmap8(o, &v->sub8) < 0){
werrstr("%s: %r", "sub8");
goto err;
}
}
if(v->format == 10){
if(read_SubtableCmap10(o, &v->sub10) < 0){
werrstr("%s: %r", "sub10");
goto err;
}
}
if(v->format == 12 || v->format == 13){
if(read_SubtableCmap12or13(o, &v->sub12or13) < 0){
werrstr("%s: %r", "sub12or13");
goto err;
}
}
if(v->format == 14){
if(read_SubtableCmap14(o, &v->sub14) < 0){
werrstr("%s: %r", "sub14");
goto err;
}
}
return 0;
err:
werrstr("%s: %r", "SubtableCmap");
return -1;
}
void
print_SubtableCmap(Biobuf *f, int indent, Otf *o, SubtableCmap *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
if(v->format == 0){
Bprint(f, "%*s%s:\n", indent, "", "sub0");
print_SubtableCmap0(f, indent+indentΔ, o, &v->sub0);
}
if(v->format == 2){
Bprint(f, "%*s%s:\n", indent, "", "sub2");
print_SubtableCmap2(f, indent+indentΔ, o, &v->sub2);
}
if(v->format == 4){
Bprint(f, "%*s%s:\n", indent, "", "sub4");
print_SubtableCmap4(f, indent+indentΔ, o, &v->sub4);
}
if(v->format == 6){
Bprint(f, "%*s%s:\n", indent, "", "sub6");
print_SubtableCmap6(f, indent+indentΔ, o, &v->sub6);
}
if(v->format == 8){
Bprint(f, "%*s%s:\n", indent, "", "sub8");
print_SubtableCmap8(f, indent+indentΔ, o, &v->sub8);
}
if(v->format == 10){
Bprint(f, "%*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");
print_SubtableCmap12or13(f, indent+indentΔ, o, &v->sub12or13);
}
if(v->format == 14){
Bprint(f, "%*s%s:\n", indent, "", "sub14");
print_SubtableCmap14(f, indent+indentΔ, o, &v->sub14);
}
USED(o);
}
int
read_EncodingRecord(Otf *o, EncodingRecord *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->platformID = b[0]<<8 | b[1];
if(v->platformID > 4){
werrstr("%s: invalid value: %d (0x%ux)", "platformID", v->platformID, v->platformID);
goto err;
}
v->encodingID = b[2]<<8 | b[3];
v->subtableOffset = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
if(v->subtableOffset != 0){
if(otfpushrange(o, v->subtableOffset, -1) < 0)
goto err;
v->subtable = calloc(1, sizeof(*v->subtable));
if(read_SubtableCmap(o, v->subtable) < 0){
werrstr("%s: %r", "subtable");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "EncodingRecord");
return -1;
}
void
print_EncodingRecord(Biobuf *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");
if(v->subtable != nil)
print_SubtableCmap(f, indent+indentΔ, o, v->subtable);
USED(o);
}
int
read_TableCmap(Otf *o, TableCmap *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
u16int version = b[0]<<8 | b[1];
if(version != 0){
werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
goto err;
}
v->numTables = b[2]<<8 | b[3];
if(otfarray(o, &v->encodingRecords, read_EncodingRecord, sizeof(EncodingRecord), v->numTables) < 0){
werrstr("%s: %r", "encodingRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableCmap");
return -1;
}
void
print_TableCmap(Biobuf *f, int indent, Otf *o, TableCmap *v)
{
Bprint(f, "%*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);
print_EncodingRecord(f, indent+indentΔ, o, &v->encodingRecords[i]);
}
USED(o);
}
int
read_TableHead(Otf *o, TableHead *v)
{
u8int *b;
if((b = otfreadn(o, 54)) == 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;
}
u32int magicNumber = b[12]<<24 | b[13]<<16 | b[14]<<8 | b[15];
if(magicNumber != 0x5f0f3cf5){
werrstr("%s: invalid value: %d (0x%ux)", "magicNumber", magicNumber, magicNumber);
goto err;
}
v->flags = b[16]<<8 | b[17];
v->unitsPerEm = b[18]<<8 | b[19];
if(v->unitsPerEm < 16 || v->unitsPerEm > 16384){
werrstr("%s: invalid value: %d (0x%ux)", "unitsPerEm", v->unitsPerEm, v->unitsPerEm);
goto err;
}
v->created = ((s64int)b[20]<<56 | (s64int)b[21]<<48 | (s64int)b[22]<<40 | (s64int)b[23]<<32 | b[24]<<24 | b[25]<<16 | b[26]<<8 | b[27]) - 2082844800LL;
v->modified = ((s64int)b[28]<<56 | (s64int)b[29]<<48 | (s64int)b[30]<<40 | (s64int)b[31]<<32 | b[32]<<24 | b[33]<<16 | b[34]<<8 | b[35]) - 2082844800LL;
v->xMin = b[36]<<8 | b[37];
v->yMin = b[38]<<8 | b[39];
v->xMax = b[40]<<8 | b[41];
v->yMax = b[42]<<8 | b[43];
v->macStyle = b[44]<<8 | b[45];
v->lowestRecPPEM = b[46]<<8 | b[47];
s16int fontDirectionHint = b[48]<<8 | b[49];
if(fontDirectionHint < -2 || fontDirectionHint > 2){
werrstr("%s: invalid value: %d (0x%ux)", "fontDirectionHint", fontDirectionHint, fontDirectionHint);
goto err;
}
v->indexToLocFormat = b[50]<<8 | b[51];
o->indexToLocFormat = v->indexToLocFormat;
if(v->indexToLocFormat > 1){
werrstr("%s: invalid value: %d (0x%ux)", "indexToLocFormat", v->indexToLocFormat, v->indexToLocFormat);
goto err;
}
s16int glyphDataFormat = b[52]<<8 | b[53];
if(glyphDataFormat != 0){
werrstr("%s: invalid value: %d (0x%ux)", "glyphDataFormat", glyphDataFormat, glyphDataFormat);
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableHead");
return -1;
}
void
print_TableHead(Biobuf *f, int indent, Otf *o, TableHead *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "flags", v->flags);
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);
USED(o);
}
int
read_TableHhea(Otf *o, TableHhea *v)
{
u8int *b;
if((b = otfreadn(o, 36)) == nil)
goto err;
v->majorVersion = b[0]<<8 | b[1];
if(v->majorVersion != 1){
werrstr("%s: invalid value: %d (0x%ux)", "majorVersion", v->majorVersion, v->majorVersion);
goto err;
}
v->minorVersion = b[2]<<8 | b[3];
if(v->minorVersion != 0){
werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", v->minorVersion, v->minorVersion);
goto err;
}
v->ascender = b[4]<<8 | b[5];
v->descender = b[6]<<8 | b[7];
v->lineGap = b[8]<<8 | b[9];
v->advanceWidthMax = b[10]<<8 | b[11];
v->minLeftSideBearing = b[12]<<8 | b[13];
v->minRightSideBearing = b[14]<<8 | b[15];
v->xMaxExtent = b[16]<<8 | b[17];
v->caretSlopeRise = b[18]<<8 | b[19];
v->caretSlopeRun = b[20]<<8 | b[21];
v->caretOffset = b[22]<<8 | b[23];
v->metricDataFormat = b[32]<<8 | b[33];
if(v->metricDataFormat != 0){
werrstr("%s: invalid value: %d (0x%ux)", "metricDataFormat", v->metricDataFormat, v->metricDataFormat);
goto err;
}
v->numberOfHMetrics = b[34]<<8 | b[35];
o->numberOfHMetrics = v->numberOfHMetrics;
return 0;
err:
werrstr("%s: %r", "TableHhea");
return -1;
}
void
print_TableHhea(Biobuf *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);
USED(o);
}
int
read_LongHorMetric(Otf *o, LongHorMetric *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->advanceWidth = b[0]<<8 | b[1];
v->lsb = b[2]<<8 | b[3];
return 0;
err:
werrstr("%s: %r", "LongHorMetric");
return -1;
}
void
print_LongHorMetric(Biobuf *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);
USED(o);
}
int
read_TableMaxp(Otf *o, TableMaxp *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
u32int version = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(version != 20480 && version != 0x10000){
werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
goto err;
}
v->numGlyphs = b[4]<<8 | b[5];
o->numGlyphs = v->numGlyphs;
return 0;
err:
werrstr("%s: %r", "TableMaxp");
return -1;
}
void
print_TableMaxp(Biobuf *f, int indent, Otf *o, TableMaxp *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
USED(o);
}
int
read_TableHmtx(Otf *o, TableHmtx *v)
{
u8int *b;
if(otfarray(o, &v->hMetrics, read_LongHorMetric, sizeof(LongHorMetric), o->numberOfHMetrics) < 0){
werrstr("%s: %r", "hMetrics");
goto err;
}
if((b = otfreadn(o, (o->numGlyphs-o->numberOfHMetrics)*2)) == nil)
goto err;
v->leftSideBearings = malloc((o->numGlyphs-o->numberOfHMetrics)*sizeof(*v->leftSideBearings));
for(int i = 0; i < (o->numGlyphs-o->numberOfHMetrics); i++)
v->leftSideBearings[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "TableHmtx");
return -1;
}
void
print_TableHmtx(Biobuf *f, int indent, Otf *o, TableHmtx *v)
{
for(int i = 0; i < o->numberOfHMetrics; i++){
Bprint(f, "%*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]);
USED(o);
}
int
read_TablePost(Otf *o, TablePost *v)
{
u8int *b;
if((b = otfreadn(o, 16)) == nil)
goto err;
u32int version = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(version != 0x10000 && version != 0x20000 && version != 0x25000 && version != 0x30000){
werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
goto err;
}
v->italicAngle = (b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7])/65536.0f;
v->underlinePosition = b[8]<<8 | b[9];
v->underlineThickness = b[10]<<8 | b[11];
v->isFixedPitch = b[12]<<24 | b[13]<<16 | b[14]<<8 | b[15];
return 0;
err:
werrstr("%s: %r", "TablePost");
return -1;
}
void
print_TablePost(Biobuf *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);
USED(o);
}
int
read_NameRecord(Otf *o, NameRecord *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == nil)
goto err;
v->platformID = b[0]<<8 | b[1];
o->platformID = v->platformID;
v->encodingID = b[2]<<8 | b[3];
o->encodingID = v->encodingID;
v->languageID = b[4]<<8 | b[5];
v->nameID = b[6]<<8 | b[7];
v->stringLength = b[8]<<8 | b[9];
v->stringOffset = b[10]<<8 | b[11];
if((o->storageOffset+v->stringOffset) != 0){
if(otfpushrange(o, (o->storageOffset+v->stringOffset), -1) < 0)
goto err;
if((b = otfreadn(o, v->stringLength)) == nil)
goto err;
v->string = strtoutf8(o, b, v->stringLength);
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "NameRecord");
return -1;
}
void
print_NameRecord(Biobuf *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);
USED(o);
}
int
read_LangTagRecord(Otf *o, LangTagRecord *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->length = b[0]<<8 | b[1];
v->langTagOffset = b[2]<<8 | b[3];
if((o->storageOffset+v->langTagOffset) != 0){
if(otfpushrange(o, (o->storageOffset+v->langTagOffset), -1) < 0)
goto err;
if((b = otfreadn(o, v->length)) == nil)
goto err;
v->langTag = malloc(v->length/2+1);
utf16to8((u8int*)v->langTag, v->length/2+1, b, v->length);
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "LangTagRecord");
return -1;
}
void
print_LangTagRecord(Biobuf *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);
USED(o);
}
int
read_TableName(Otf *o, TableName *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == 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->count = b[2]<<8 | b[3];
v->storageOffset = b[4]<<8 | b[5];
o->storageOffset = v->storageOffset;
if(otfarray(o, &v->nameRecord, read_NameRecord, sizeof(NameRecord), v->count) < 0){
werrstr("%s: %r", "nameRecord");
goto err;
}
if(v->version >= 1){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->langTagCount = b[0]<<8 | b[1];
}
if(v->version >= 1){
if(otfarray(o, &v->langTagRecord, read_LangTagRecord, sizeof(LangTagRecord), v->langTagCount) < 0){
werrstr("%s: %r", "langTagRecord");
goto err;
}
}
return 0;
err:
werrstr("%s: %r", "TableName");
return -1;
}
void
print_TableName(Biobuf *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);
for(int i = 0; i < v->count; i++){
Bprint(f, "%*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);
if(v->version >= 1){
for(int i = 0; i < v->langTagCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "langTagRecord", i);
print_LangTagRecord(f, indent+indentΔ, o, &v->langTagRecord[i]);
}
}
USED(o);
}
int
read_BigGlyphMetrics(Otf *o, BigGlyphMetrics *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->height = b[0];
v->width = b[1];
v->horiBearingX = b[2];
v->horiBearingY = b[3];
v->horiAdvance = b[4];
v->vertBearingX = b[5];
v->vertBearingY = b[6];
v->vertAdvance = b[7];
return 0;
err:
werrstr("%s: %r", "BigGlyphMetrics");
return -1;
}
void
print_BigGlyphMetrics(Biobuf *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);
USED(o);
}
int
read_SmallGlyphMetrics(Otf *o, SmallGlyphMetrics *v)
{
u8int *b;
if((b = otfreadn(o, 5)) == nil)
goto err;
v->height = b[0];
v->width = b[1];
v->bearingX = b[2];
v->bearingY = b[3];
v->advance = b[4];
return 0;
err:
werrstr("%s: %r", "SmallGlyphMetrics");
return -1;
}
void
print_SmallGlyphMetrics(Biobuf *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);
USED(o);
}
int
read_SbitLineMetrics(Otf *o, SbitLineMetrics *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == nil)
goto err;
v->ascender = b[0];
v->descender = b[1];
v->widthMax = b[2];
v->caretSlopeNumerator = b[3];
v->caretSlopeDenumerator = b[4];
v->caretOffset = b[5];
v->minOriginSB = b[6];
v->minAdvanceSB = b[7];
v->maxBeforeBL = b[8];
v->minAfterBL = b[9];
return 0;
err:
werrstr("%s: %r", "SbitLineMetrics");
return -1;
}
void
print_SbitLineMetrics(Biobuf *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);
USED(o);
}
int
read_IndexSubtable1(Otf *o, IndexSubtable1 *v)
{
u8int *b;
if((b = otfreadn(o, ((o->lastGlyphIndex-o->firstGlyphIndex)+2)*4)) == nil)
goto err;
v->sbitOffsets = malloc(((o->lastGlyphIndex-o->firstGlyphIndex)+2)*sizeof(*v->sbitOffsets));
for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
v->sbitOffsets[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", "IndexSubtable1");
return -1;
}
void
print_IndexSubtable1(Biobuf *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]);
USED(o);
}
int
read_IndexSubtable2(Otf *o, IndexSubtable2 *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->imageSize = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(read_BigGlyphMetrics(o, &v->bigMetrics) < 0){
werrstr("%s: %r", "bigMetrics");
goto err;
}
return 0;
err:
werrstr("%s: %r", "IndexSubtable2");
return -1;
}
void
print_IndexSubtable2(Biobuf *f, int indent, Otf *o, IndexSubtable2 *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
Bprint(f, "%*s%s:\n", indent, "", "bigMetrics");
print_BigGlyphMetrics(f, indent+indentΔ, o, &v->bigMetrics);
USED(o);
}
int
read_IndexSubtable3(Otf *o, IndexSubtable3 *v)
{
u8int *b;
if((b = otfreadn(o, ((o->lastGlyphIndex-o->firstGlyphIndex)+2)*2)) == nil)
goto err;
v->sbitOffsets = malloc(((o->lastGlyphIndex-o->firstGlyphIndex)+2)*sizeof(*v->sbitOffsets));
for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
v->sbitOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "IndexSubtable3");
return -1;
}
void
print_IndexSubtable3(Biobuf *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]);
USED(o);
}
int
read_GlyphIdOffsetPair(Otf *o, GlyphIdOffsetPair *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->glyphID = b[0]<<8 | b[1];
v->sbitOffset = b[2]<<8 | b[3];
return 0;
err:
werrstr("%s: %r", "GlyphIdOffsetPair");
return -1;
}
void
print_GlyphIdOffsetPair(Biobuf *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);
USED(o);
}
int
read_IndexSubtable4(Otf *o, IndexSubtable4 *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->numGlyphs = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(otfarray(o, &v->glyphArray, read_GlyphIdOffsetPair, sizeof(GlyphIdOffsetPair), (v->numGlyphs+1)) < 0){
werrstr("%s: %r", "glyphArray");
goto err;
}
return 0;
err:
werrstr("%s: %r", "IndexSubtable4");
return -1;
}
void
print_IndexSubtable4(Biobuf *f, int indent, Otf *o, IndexSubtable4 *v)
{
Bprint(f, "%*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);
print_GlyphIdOffsetPair(f, indent+indentΔ, o, &v->glyphArray[i]);
}
USED(o);
}
int
read_IndexSubtable5(Otf *o, IndexSubtable5 *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->imageSize = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(read_BigGlyphMetrics(o, &v->bigMetrics) < 0){
werrstr("%s: %r", "bigMetrics");
goto err;
}
if((b = otfreadn(o, 4)) == nil)
goto err;
v->numGlyphs = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if((b = otfreadn(o, v->numGlyphs*2)) == nil)
goto err;
v->glyphIdArray = malloc(v->numGlyphs*sizeof(*v->glyphIdArray));
for(int i = 0; i < v->numGlyphs; i++)
v->glyphIdArray[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "IndexSubtable5");
return -1;
}
void
print_IndexSubtable5(Biobuf *f, int indent, Otf *o, IndexSubtable5 *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
Bprint(f, "%*s%s:\n", indent, "", "bigMetrics");
print_BigGlyphMetrics(f, indent+indentΔ, o, &v->bigMetrics);
Bprint(f, "%*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]);
USED(o);
}
int
read_IndexSubtable(Otf *o, IndexSubtable *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->indexFormat = b[0]<<8 | b[1];
if(v->indexFormat < 1 || v->indexFormat > 5){
werrstr("%s: invalid value: %d (0x%ux)", "indexFormat", v->indexFormat, v->indexFormat);
goto err;
}
v->imageFormat = b[2]<<8 | b[3];
v->imageDataOffset = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
if(v->indexFormat == 1){
if(read_IndexSubtable1(o, &v->sub1) < 0){
werrstr("%s: %r", "sub1");
goto err;
}
}
if(v->indexFormat == 2){
if(read_IndexSubtable2(o, &v->sub2) < 0){
werrstr("%s: %r", "sub2");
goto err;
}
}
if(v->indexFormat == 3){
if(read_IndexSubtable3(o, &v->sub3) < 0){
werrstr("%s: %r", "sub3");
goto err;
}
}
if(v->indexFormat == 4){
if(read_IndexSubtable4(o, &v->sub4) < 0){
werrstr("%s: %r", "sub4");
goto err;
}
}
if(v->indexFormat == 5){
if(read_IndexSubtable5(o, &v->sub5) < 0){
werrstr("%s: %r", "sub5");
goto err;
}
}
return 0;
err:
werrstr("%s: %r", "IndexSubtable");
return -1;
}
void
print_IndexSubtable(Biobuf *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);
if(v->indexFormat == 1){
Bprint(f, "%*s%s:\n", indent, "", "sub1");
print_IndexSubtable1(f, indent+indentΔ, o, &v->sub1);
}
if(v->indexFormat == 2){
Bprint(f, "%*s%s:\n", indent, "", "sub2");
print_IndexSubtable2(f, indent+indentΔ, o, &v->sub2);
}
if(v->indexFormat == 3){
Bprint(f, "%*s%s:\n", indent, "", "sub3");
print_IndexSubtable3(f, indent+indentΔ, o, &v->sub3);
}
if(v->indexFormat == 4){
Bprint(f, "%*s%s:\n", indent, "", "sub4");
print_IndexSubtable4(f, indent+indentΔ, o, &v->sub4);
}
if(v->indexFormat == 5){
Bprint(f, "%*s%s:\n", indent, "", "sub5");
print_IndexSubtable5(f, indent+indentΔ, o, &v->sub5);
}
USED(o);
}
int
read_IndexSubtableRecord(Otf *o, IndexSubtableRecord *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->firstGlyphIndex = b[0]<<8 | b[1];
o->firstGlyphIndex = v->firstGlyphIndex;
v->lastGlyphIndex = b[2]<<8 | b[3];
o->lastGlyphIndex = v->lastGlyphIndex;
v->indexSubtableOffset = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
if(v->indexSubtableOffset != 0){
if(otfpushrange(o, v->indexSubtableOffset, -1) < 0)
goto err;
v->indexSubtable = calloc(1, sizeof(*v->indexSubtable));
if(read_IndexSubtable(o, v->indexSubtable) < 0){
werrstr("%s: %r", "indexSubtable");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "IndexSubtableRecord");
return -1;
}
void
print_IndexSubtableRecord(Biobuf *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");
if(v->indexSubtable != nil)
print_IndexSubtable(f, indent+indentΔ, o, v->indexSubtable);
USED(o);
}
int
read_BitmapSize(Otf *o, BitmapSize *v)
{
u8int *b;
if((b = otfreadn(o, 16)) == nil)
goto err;
v->indexSubtableListOffset = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->indexSubtableListSize = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
v->numberOfIndexSubtables = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
if(read_SbitLineMetrics(o, &v->hori) < 0){
werrstr("%s: %r", "hori");
goto err;
}
if(read_SbitLineMetrics(o, &v->vert) < 0){
werrstr("%s: %r", "vert");
goto err;
}
if((b = otfreadn(o, 8)) == nil)
goto err;
v->startGlyphIndex = b[0]<<8 | b[1];
v->endGlyphIndex = b[2]<<8 | b[3];
v->ppemX = b[4];
v->ppemY = b[5];
v->bitDepth = b[6];
v->flags = b[7];
if(v->indexSubtableListOffset != 0){
if(otfpushrange(o, v->indexSubtableListOffset, -1) < 0)
goto err;
if(otfarray(o, &v->indexSubtableList, read_IndexSubtableRecord, sizeof(IndexSubtableRecord), v->numberOfIndexSubtables) < 0){
werrstr("%s: %r", "indexSubtableList");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "BitmapSize");
return -1;
}
void
print_BitmapSize(Biobuf *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");
print_SbitLineMetrics(f, indent+indentΔ, o, &v->hori);
Bprint(f, "%*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: %d\n", indent, "", "flags", v->flags);
for(int i = 0; i < v->numberOfIndexSubtables; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "indexSubtableList", i);
print_IndexSubtableRecord(f, indent+indentΔ, o, &v->indexSubtableList[i]);
}
USED(o);
}
int
read_TableEBDT(Otf *o, TableEBDT *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->majorVersion = b[0]<<8 | b[1];
if(v->majorVersion != 2){
werrstr("%s: invalid value: %d (0x%ux)", "majorVersion", v->majorVersion, v->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;
}
return 0;
err:
werrstr("%s: %r", "TableEBDT");
return -1;
}
void
print_TableEBDT(Biobuf *f, int indent, Otf *o, TableEBDT *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
USED(o);
}
int
read_TableEBLC(Otf *o, TableEBLC *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
u16int majorVersion = b[0]<<8 | b[1];
if(majorVersion != 2){
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->numSizes = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
if(otfarray(o, &v->bitmapSizes, read_BitmapSize, sizeof(BitmapSize), v->numSizes) < 0){
werrstr("%s: %r", "bitmapSizes");
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableEBLC");
return -1;
}
void
print_TableEBLC(Biobuf *f, int indent, Otf *o, TableEBLC *v)
{
Bprint(f, "%*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);
print_BitmapSize(f, indent+indentΔ, o, &v->bitmapSizes[i]);
}
USED(o);
}
int
read_AttachList(Otf *o, AttachList *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->coverageOffset = b[0]<<8 | b[1];
v->glyphCount = b[2]<<8 | b[3];
if((b = otfreadn(o, v->glyphCount*2)) == nil)
goto err;
v->attachPointOffsets = malloc(v->glyphCount*sizeof(*v->attachPointOffsets));
for(int i = 0; i < v->glyphCount; i++)
v->attachPointOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "AttachList");
return -1;
}
void
print_AttachList(Biobuf *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);
for(int i = 0; i < v->glyphCount; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "attachPointOffsets", i, v->attachPointOffsets[i]);
USED(o);
}
int
read_AttachPoint(Otf *o, AttachPoint *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->pointCount = b[0]<<8 | b[1];
if((b = otfreadn(o, v->pointCount*2)) == nil)
goto err;
v->pointIndices = malloc(v->pointCount*sizeof(*v->pointIndices));
for(int i = 0; i < v->pointCount; i++)
v->pointIndices[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "AttachPoint");
return -1;
}
void
print_AttachPoint(Biobuf *f, int indent, Otf *o, AttachPoint *v)
{
Bprint(f, "%*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]);
USED(o);
}
int
read_LigCaretList(Otf *o, LigCaretList *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->coverageOffset = b[0]<<8 | b[1];
v->ligGlyphCount = b[2]<<8 | b[3];
if((b = otfreadn(o, v->ligGlyphCount*2)) == nil)
goto err;
v->ligGlyphOffsets = malloc(v->ligGlyphCount*sizeof(*v->ligGlyphOffsets));
for(int i = 0; i < v->ligGlyphCount; i++)
v->ligGlyphOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "LigCaretList");
return -1;
}
void
print_LigCaretList(Biobuf *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);
for(int i = 0; i < v->ligGlyphCount; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "ligGlyphOffsets", i, v->ligGlyphOffsets[i]);
USED(o);
}
int
read_LigGlyph(Otf *o, LigGlyph *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->caretCount = b[0]<<8 | b[1];
if((b = otfreadn(o, v->caretCount*2)) == nil)
goto err;
v->caretValueOffsets = malloc(v->caretCount*sizeof(*v->caretValueOffsets));
for(int i = 0; i < v->caretCount; i++)
v->caretValueOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "LigGlyph");
return -1;
}
void
print_LigGlyph(Biobuf *f, int indent, Otf *o, LigGlyph *v)
{
Bprint(f, "%*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]);
USED(o);
}
int
read_CaretValue(Otf *o, CaretValue *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->format = b[0]<<8 | b[1];
if(v->format < 1 || v->format > 3){
werrstr("%s: invalid value: %d (0x%ux)", "format", v->format, v->format);
goto err;
}
if(v->format == 1 || v->format == 3){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->coordinate = b[0]<<8 | b[1];
}
if(v->format == 2){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->caretValuePointIndex = b[0]<<8 | b[1];
}
if(v->format == 3){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->deviceOffset = b[0]<<8 | b[1];
}
return 0;
err:
werrstr("%s: %r", "CaretValue");
return -1;
}
void
print_CaretValue(Biobuf *f, int indent, Otf *o, CaretValue *v)
{
Bprint(f, "%*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);
if(v->format == 2)
Bprint(f, "%*s%s: %ud\n", indent, "", "caretValuePointIndex", v->caretValuePointIndex);
if(v->format == 3)
Bprint(f, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
USED(o);
}
int
read_ValueRecord(Otf *o, ValueRecord *v)
{
u8int *b;
if((b = otfreadn(o, 16)) == nil)
goto err;
v->xPlacement = b[0]<<8 | b[1];
v->yPlacement = b[2]<<8 | b[3];
v->xAdvance = b[4]<<8 | b[5];
v->yAdvance = b[6]<<8 | b[7];
v->xPlaDeviceOffset = b[8]<<8 | b[9];
v->yPlaDeviceOffset = b[10]<<8 | b[11];
v->xAdvDeviceOffset = b[12]<<8 | b[13];
v->yAdvDeviceOffset = b[14]<<8 | b[15];
return 0;
err:
werrstr("%s: %r", "ValueRecord");
return -1;
}
void
print_ValueRecord(Biobuf *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);
USED(o);
}
int
read_SinglePos(Otf *o, SinglePos *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->format = b[0]<<8 | b[1];
if(v->format != 1 && v->format != 2){
werrstr("%s: invalid value: %d (0x%ux)", "format", v->format, v->format);
goto err;
}
v->coverageOffset = b[2]<<8 | b[3];
v->valueFormat = b[4]<<8 | b[5];
if(v->format == 1){
if(read_ValueRecord(o, &v->valueRecord) < 0){
werrstr("%s: %r", "valueRecord");
goto err;
}
}
if(v->format == 2){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->valueCount = b[0]<<8 | b[1];
}
if(v->format == 2){
if(otfarray(o, &v->valueRecords, read_ValueRecord, sizeof(ValueRecord), v->valueCount) < 0){
werrstr("%s: %r", "valueRecords");
goto err;
}
}
return 0;
err:
werrstr("%s: %r", "SinglePos");
return -1;
}
void
print_SinglePos(Biobuf *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);
if(v->format == 1){
Bprint(f, "%*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);
if(v->format == 2){
for(int i = 0; i < v->valueCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "valueRecords", i);
print_ValueRecord(f, indent+indentΔ, o, &v->valueRecords[i]);
}
}
USED(o);
}
int
read_TableGDEF(Otf *o, TableGDEF *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == 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 != 2 && v->minorVersion != 3){
werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", v->minorVersion, v->minorVersion);
goto err;
}
v->glyphClassDefOffset = b[4]<<8 | b[5];
v->attachListOffset = b[6]<<8 | b[7];
v->ligCaretListOffset = b[8]<<8 | b[9];
v->markAttachClassDefOffset = b[10]<<8 | b[11];
if(v->minorVersion >= 2){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->markGlyphSetsDefOffset = b[0]<<8 | b[1];
}
if(v->minorVersion >= 3){
if((b = otfreadn(o, 4)) == nil)
goto err;
v->itemVarStoreOffset = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
}
return 0;
err:
werrstr("%s: %r", "TableGDEF");
return -1;
}
void
print_TableGDEF(Biobuf *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);
if(v->minorVersion >= 2)
Bprint(f, "%*s%s: %ud\n", indent, "", "markGlyphSetsDefOffset", v->markGlyphSetsDefOffset);
if(v->minorVersion >= 3)
Bprint(f, "%*s%s: %ud\n", indent, "", "itemVarStoreOffset", v->itemVarStoreOffset);
USED(o);
}
int
read_LangSys(Otf *o, LangSys *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->requiredFeatureIndex = b[2]<<8 | b[3];
v->featureIndexCount = b[4]<<8 | b[5];
if((b = otfreadn(o, v->featureIndexCount*2)) == nil)
goto err;
v->featureIndices = malloc(v->featureIndexCount*sizeof(*v->featureIndices));
for(int i = 0; i < v->featureIndexCount; i++)
v->featureIndices[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "LangSys");
return -1;
}
void
print_LangSys(Biobuf *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);
for(int i = 0; i < v->featureIndexCount; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "featureIndices", i, v->featureIndices[i]);
USED(o);
}
int
read_LangSysRecord(Otf *o, LangSysRecord *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->langSysTag = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->langSysOffset = b[4]<<8 | b[5];
if(v->langSysOffset != 0){
if(otfpushrange(o, v->langSysOffset, -1) < 0)
goto err;
v->langSys = calloc(1, sizeof(*v->langSys));
if(read_LangSys(o, v->langSys) < 0){
werrstr("%s: %r", "langSys");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "LangSysRecord");
return -1;
}
void
print_LangSysRecord(Biobuf *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");
if(v->langSys != nil)
print_LangSys(f, indent+indentΔ, o, v->langSys);
USED(o);
}
int
read_Script(Otf *o, Script *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->defaultLangSysOffset = b[0]<<8 | b[1];
v->langSysCount = b[2]<<8 | b[3];
if(otfarray(o, &v->langSysRecords, read_LangSysRecord, sizeof(LangSysRecord), v->langSysCount) < 0){
werrstr("%s: %r", "langSysRecords");
goto err;
}
if(v->defaultLangSysOffset != 0){
if(otfpushrange(o, v->defaultLangSysOffset, -1) < 0)
goto err;
v->defaultLangSys = calloc(1, sizeof(*v->defaultLangSys));
if(read_LangSys(o, v->defaultLangSys) < 0){
werrstr("%s: %r", "defaultLangSys");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "Script");
return -1;
}
void
print_Script(Biobuf *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);
for(int i = 0; i < v->langSysCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "langSysRecords", i);
print_LangSysRecord(f, indent+indentΔ, o, &v->langSysRecords[i]);
}
Bprint(f, "%*s%s:\n", indent, "", "defaultLangSys");
if(v->defaultLangSys != nil)
print_LangSys(f, indent+indentΔ, o, v->defaultLangSys);
USED(o);
}
int
read_ScriptRecord(Otf *o, ScriptRecord *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->scriptTag = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->scriptOffset = b[4]<<8 | b[5];
if(v->scriptOffset != 0){
if(otfpushrange(o, v->scriptOffset, -1) < 0)
goto err;
v->script = calloc(1, sizeof(*v->script));
if(read_Script(o, v->script) < 0){
werrstr("%s: %r", "script");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "ScriptRecord");
return -1;
}
void
print_ScriptRecord(Biobuf *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");
if(v->script != nil)
print_Script(f, indent+indentΔ, o, v->script);
USED(o);
}
int
read_ScriptList(Otf *o, ScriptList *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->scriptCount = b[0]<<8 | b[1];
if(otfarray(o, &v->scriptRecords, read_ScriptRecord, sizeof(ScriptRecord), v->scriptCount) < 0){
werrstr("%s: %r", "scriptRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "ScriptList");
return -1;
}
void
print_ScriptList(Biobuf *f, int indent, Otf *o, ScriptList *v)
{
Bprint(f, "%*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);
print_ScriptRecord(f, indent+indentΔ, o, &v->scriptRecords[i]);
}
USED(o);
}
int
read_Feature(Otf *o, Feature *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->featureParamsOffset = b[0]<<8 | b[1];
v->lookupIndexCount = b[2]<<8 | b[3];
if((b = otfreadn(o, v->lookupIndexCount*2)) == nil)
goto err;
v->lookupListIndices = malloc(v->lookupIndexCount*sizeof(*v->lookupListIndices));
for(int i = 0; i < v->lookupIndexCount; i++)
v->lookupListIndices[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "Feature");
return -1;
}
void
print_Feature(Biobuf *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);
for(int i = 0; i < v->lookupIndexCount; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "lookupListIndices", i, v->lookupListIndices[i]);
USED(o);
}
int
read_FeatureRecord(Otf *o, FeatureRecord *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->featureTag = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->featureOffset = b[4]<<8 | b[5];
if(v->featureOffset != 0){
if(otfpushrange(o, v->featureOffset, -1) < 0)
goto err;
v->feature = calloc(1, sizeof(*v->feature));
if(read_Feature(o, v->feature) < 0){
werrstr("%s: %r", "feature");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "FeatureRecord");
return -1;
}
void
print_FeatureRecord(Biobuf *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");
if(v->feature != nil)
print_Feature(f, indent+indentΔ, o, v->feature);
USED(o);
}
int
read_FeatureList(Otf *o, FeatureList *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->featureCount = b[0]<<8 | b[1];
if(otfarray(o, &v->featureRecords, read_FeatureRecord, sizeof(FeatureRecord), v->featureCount) < 0){
werrstr("%s: %r", "featureRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "FeatureList");
return -1;
}
void
print_FeatureList(Biobuf *f, int indent, Otf *o, FeatureList *v)
{
Bprint(f, "%*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);
print_FeatureRecord(f, indent+indentΔ, o, &v->featureRecords[i]);
}
USED(o);
}
int
read_Lookup(Otf *o, Lookup *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->lookupType = b[0]<<8 | b[1];
v->lookupFlag = b[2]<<8 | b[3];
v->subTableCount = b[4]<<8 | b[5];
if((b = otfreadn(o, v->subTableCount*2)) == nil)
goto err;
v->subtableOffsets = malloc(v->subTableCount*sizeof(*v->subtableOffsets));
for(int i = 0; i < v->subTableCount; i++)
v->subtableOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
if((b = otfreadn(o, 2)) == nil)
goto err;
v->markFilteringSet = b[0]<<8 | b[1];
return 0;
err:
werrstr("%s: %r", "Lookup");
return -1;
}
void
print_Lookup(Biobuf *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);
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);
USED(o);
}
int
read_LookupList(Otf *o, LookupList *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->lookupCount = b[0]<<8 | b[1];
if((b = otfreadn(o, v->lookupCount*2)) == nil)
goto err;
v->lookupOffsets = malloc(v->lookupCount*sizeof(*v->lookupOffsets));
for(int i = 0; i < v->lookupCount; i++)
v->lookupOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "LookupList");
return -1;
}
void
print_LookupList(Biobuf *f, int indent, Otf *o, LookupList *v)
{
Bprint(f, "%*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]);
USED(o);
}
int
read_TableGPOS(Otf *o, TableGPOS *v)
{
u8int *b;
if((b = otfreadn(o, 10)) == 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 > 1){
werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", v->minorVersion, v->minorVersion);
goto err;
}
v->scriptListOffset = b[4]<<8 | b[5];
v->featureListOffset = b[6]<<8 | b[7];
v->lookupListOffset = b[8]<<8 | b[9];
if(v->minorVersion == 1){
if((b = otfreadn(o, 4)) == nil)
goto err;
v->featureVariationsOffset = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
}
if(v->scriptListOffset != 0){
if(otfpushrange(o, v->scriptListOffset, -1) < 0)
goto err;
v->scriptList = calloc(1, sizeof(*v->scriptList));
if(read_ScriptList(o, v->scriptList) < 0){
werrstr("%s: %r", "scriptList");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->featureListOffset != 0){
if(otfpushrange(o, v->featureListOffset, -1) < 0)
goto err;
v->featureList = calloc(1, sizeof(*v->featureList));
if(read_FeatureList(o, v->featureList) < 0){
werrstr("%s: %r", "featureList");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->lookupListOffset != 0){
if(otfpushrange(o, v->lookupListOffset, -1) < 0)
goto err;
v->lookupList = calloc(1, sizeof(*v->lookupList));
if(read_LookupList(o, v->lookupList) < 0){
werrstr("%s: %r", "lookupList");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableGPOS");
return -1;
}
void
print_TableGPOS(Biobuf *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);
if(v->minorVersion == 1)
Bprint(f, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
Bprint(f, "%*s%s:\n", indent, "", "scriptList");
if(v->scriptList != nil)
print_ScriptList(f, indent+indentΔ, o, v->scriptList);
Bprint(f, "%*s%s:\n", indent, "", "featureList");
if(v->featureList != nil)
print_FeatureList(f, indent+indentΔ, o, v->featureList);
Bprint(f, "%*s%s:\n", indent, "", "lookupList");
if(v->lookupList != nil)
print_LookupList(f, indent+indentΔ, o, v->lookupList);
USED(o);
}
int
read_TableGSUB(Otf *o, TableGSUB *v)
{
u8int *b;
if((b = otfreadn(o, 10)) == 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 > 1){
werrstr("%s: invalid value: %d (0x%ux)", "minorVersion", v->minorVersion, v->minorVersion);
goto err;
}
v->scriptListOffset = b[4]<<8 | b[5];
v->featureListOffset = b[6]<<8 | b[7];
v->lookupListOffset = b[8]<<8 | b[9];
if(v->minorVersion == 1){
if((b = otfreadn(o, 4)) == nil)
goto err;
v->featureVariationsOffset = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
}
if(v->scriptListOffset != 0){
if(otfpushrange(o, v->scriptListOffset, -1) < 0)
goto err;
v->scriptList = calloc(1, sizeof(*v->scriptList));
if(read_ScriptList(o, v->scriptList) < 0){
werrstr("%s: %r", "scriptList");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->featureListOffset != 0){
if(otfpushrange(o, v->featureListOffset, -1) < 0)
goto err;
v->featureList = calloc(1, sizeof(*v->featureList));
if(read_FeatureList(o, v->featureList) < 0){
werrstr("%s: %r", "featureList");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableGSUB");
return -1;
}
void
print_TableGSUB(Biobuf *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);
if(v->minorVersion == 1)
Bprint(f, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
Bprint(f, "%*s%s:\n", indent, "", "scriptList");
if(v->scriptList != nil)
print_ScriptList(f, indent+indentΔ, o, v->scriptList);
Bprint(f, "%*s%s:\n", indent, "", "featureList");
if(v->featureList != nil)
print_FeatureList(f, indent+indentΔ, o, v->featureList);
USED(o);
}
int
read_MathValueRecord(Otf *o, MathValueRecord *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->value = b[0]<<8 | b[1];
v->deviceOffset = b[2]<<8 | b[3];
return 0;
err:
werrstr("%s: %r", "MathValueRecord");
return -1;
}
void
print_MathValueRecord(Biobuf *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);
USED(o);
}
int
read_MathConstants(Otf *o, MathConstants *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->scriptPercentScaleDown = b[0]<<8 | b[1];
v->scriptScriptPercentScaleDown = b[2]<<8 | b[3];
v->delimitedSubFormulaMinHeight = b[4]<<8 | b[5];
v->displayOperatorMinHeight = b[6]<<8 | b[7];
if(read_MathValueRecord(o, &v->mathLeading) < 0){
werrstr("%s: %r", "mathLeading");
goto err;
}
if(read_MathValueRecord(o, &v->axisHeight) < 0){
werrstr("%s: %r", "axisHeight");
goto err;
}
if(read_MathValueRecord(o, &v->accentBaseHeight) < 0){
werrstr("%s: %r", "accentBaseHeight");
goto err;
}
if(read_MathValueRecord(o, &v->flattenedAccentBaseHeight) < 0){
werrstr("%s: %r", "flattenedAccentBaseHeight");
goto err;
}
if(read_MathValueRecord(o, &v->subscriptShiftDown) < 0){
werrstr("%s: %r", "subscriptShiftDown");
goto err;
}
if(read_MathValueRecord(o, &v->subscriptTopMax) < 0){
werrstr("%s: %r", "subscriptTopMax");
goto err;
}
if(read_MathValueRecord(o, &v->subscriptBaselineDropMin) < 0){
werrstr("%s: %r", "subscriptBaselineDropMin");
goto err;
}
if(read_MathValueRecord(o, &v->superscriptShiftUp) < 0){
werrstr("%s: %r", "superscriptShiftUp");
goto err;
}
if(read_MathValueRecord(o, &v->superscriptShiftUpCramped) < 0){
werrstr("%s: %r", "superscriptShiftUpCramped");
goto err;
}
if(read_MathValueRecord(o, &v->superscriptBottomMin) < 0){
werrstr("%s: %r", "superscriptBottomMin");
goto err;
}
if(read_MathValueRecord(o, &v->superscriptBaselineDropMax) < 0){
werrstr("%s: %r", "superscriptBaselineDropMax");
goto err;
}
if(read_MathValueRecord(o, &v->subSuperscriptGapMin) < 0){
werrstr("%s: %r", "subSuperscriptGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->superscriptBottomMaxWithSubscript) < 0){
werrstr("%s: %r", "superscriptBottomMaxWithSubscript");
goto err;
}
if(read_MathValueRecord(o, &v->spaceAfterScript) < 0){
werrstr("%s: %r", "spaceAfterScript");
goto err;
}
if(read_MathValueRecord(o, &v->upperLimitGapMin) < 0){
werrstr("%s: %r", "upperLimitGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->upperLimitBaselineRiseMin) < 0){
werrstr("%s: %r", "upperLimitBaselineRiseMin");
goto err;
}
if(read_MathValueRecord(o, &v->lowerLimitGapMin) < 0){
werrstr("%s: %r", "lowerLimitGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->lowerLimitBaselineDropMin) < 0){
werrstr("%s: %r", "lowerLimitBaselineDropMin");
goto err;
}
if(read_MathValueRecord(o, &v->stackTopShiftUp) < 0){
werrstr("%s: %r", "stackTopShiftUp");
goto err;
}
if(read_MathValueRecord(o, &v->stackTopDisplayStyleShiftUp) < 0){
werrstr("%s: %r", "stackTopDisplayStyleShiftUp");
goto err;
}
if(read_MathValueRecord(o, &v->stackBottomShiftDown) < 0){
werrstr("%s: %r", "stackBottomShiftDown");
goto err;
}
if(read_MathValueRecord(o, &v->stackBottomDisplayStyleShiftDown) < 0){
werrstr("%s: %r", "stackBottomDisplayStyleShiftDown");
goto err;
}
if(read_MathValueRecord(o, &v->stackGapMin) < 0){
werrstr("%s: %r", "stackGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->stackDisplayStyleGapMin) < 0){
werrstr("%s: %r", "stackDisplayStyleGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->stretchStackTopShiftUp) < 0){
werrstr("%s: %r", "stretchStackTopShiftUp");
goto err;
}
if(read_MathValueRecord(o, &v->stretchStackBottomShiftDown) < 0){
werrstr("%s: %r", "stretchStackBottomShiftDown");
goto err;
}
if(read_MathValueRecord(o, &v->stretchStackGapAboveMin) < 0){
werrstr("%s: %r", "stretchStackGapAboveMin");
goto err;
}
if(read_MathValueRecord(o, &v->stretchStackGapBelowMin) < 0){
werrstr("%s: %r", "stretchStackGapBelowMin");
goto err;
}
if(read_MathValueRecord(o, &v->fractionNumeratorShiftUp) < 0){
werrstr("%s: %r", "fractionNumeratorShiftUp");
goto err;
}
if(read_MathValueRecord(o, &v->fractionNumeratorDisplayStyleShiftUp) < 0){
werrstr("%s: %r", "fractionNumeratorDisplayStyleShiftUp");
goto err;
}
if(read_MathValueRecord(o, &v->fractionDenominatorShiftDown) < 0){
werrstr("%s: %r", "fractionDenominatorShiftDown");
goto err;
}
if(read_MathValueRecord(o, &v->fractionDenominatorDisplayStyleShiftDown) < 0){
werrstr("%s: %r", "fractionDenominatorDisplayStyleShiftDown");
goto err;
}
if(read_MathValueRecord(o, &v->fractionNumeratorGapMin) < 0){
werrstr("%s: %r", "fractionNumeratorGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->fractionNumDisplayStyleGapMin) < 0){
werrstr("%s: %r", "fractionNumDisplayStyleGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->fractionRuleThickness) < 0){
werrstr("%s: %r", "fractionRuleThickness");
goto err;
}
if(read_MathValueRecord(o, &v->fractionDenominatorGapMin) < 0){
werrstr("%s: %r", "fractionDenominatorGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->fractionDenomDisplayStyleGapMin) < 0){
werrstr("%s: %r", "fractionDenomDisplayStyleGapMin");
goto err;
}
if(read_MathValueRecord(o, &v->skewedFractionHorizontalGap) < 0){
werrstr("%s: %r", "skewedFractionHorizontalGap");
goto err;
}
if(read_MathValueRecord(o, &v->skewedFractionVerticalGap) < 0){
werrstr("%s: %r", "skewedFractionVerticalGap");
goto err;
}
if(read_MathValueRecord(o, &v->overbarVerticalGap) < 0){
werrstr("%s: %r", "overbarVerticalGap");
goto err;
}
if(read_MathValueRecord(o, &v->overbarRuleThickness) < 0){
werrstr("%s: %r", "overbarRuleThickness");
goto err;
}
if(read_MathValueRecord(o, &v->overbarExtraAscender) < 0){
werrstr("%s: %r", "overbarExtraAscender");
goto err;
}
if(read_MathValueRecord(o, &v->underbarVerticalGap) < 0){
werrstr("%s: %r", "underbarVerticalGap");
goto err;
}
if(read_MathValueRecord(o, &v->underbarRuleThickness) < 0){
werrstr("%s: %r", "underbarRuleThickness");
goto err;
}
if(read_MathValueRecord(o, &v->underbarExtraDescender) < 0){
werrstr("%s: %r", "underbarExtraDescender");
goto err;
}
if(read_MathValueRecord(o, &v->radicalVerticalGap) < 0){
werrstr("%s: %r", "radicalVerticalGap");
goto err;
}
if(read_MathValueRecord(o, &v->radicalDisplayStyleVerticalGap) < 0){
werrstr("%s: %r", "radicalDisplayStyleVerticalGap");
goto err;
}
if(read_MathValueRecord(o, &v->radicalRuleThickness) < 0){
werrstr("%s: %r", "radicalRuleThickness");
goto err;
}
if(read_MathValueRecord(o, &v->radicalExtraAscender) < 0){
werrstr("%s: %r", "radicalExtraAscender");
goto err;
}
if(read_MathValueRecord(o, &v->radicalKernBeforeDegree) < 0){
werrstr("%s: %r", "radicalKernBeforeDegree");
goto err;
}
if(read_MathValueRecord(o, &v->radicalKernAfterDegree) < 0){
werrstr("%s: %r", "radicalKernAfterDegree");
goto err;
}
if((b = otfreadn(o, 2)) == nil)
goto err;
v->radicalDegreeBottomRaisePercent = b[0]<<8 | b[1];
return 0;
err:
werrstr("%s: %r", "MathConstants");
return -1;
}
void
print_MathConstants(Biobuf *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");
print_MathValueRecord(f, indent+indentΔ, o, &v->mathLeading);
Bprint(f, "%*s%s:\n", indent, "", "axisHeight");
print_MathValueRecord(f, indent+indentΔ, o, &v->axisHeight);
Bprint(f, "%*s%s:\n", indent, "", "accentBaseHeight");
print_MathValueRecord(f, indent+indentΔ, o, &v->accentBaseHeight);
Bprint(f, "%*s%s:\n", indent, "", "flattenedAccentBaseHeight");
print_MathValueRecord(f, indent+indentΔ, o, &v->flattenedAccentBaseHeight);
Bprint(f, "%*s%s:\n", indent, "", "subscriptShiftDown");
print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptShiftDown);
Bprint(f, "%*s%s:\n", indent, "", "subscriptTopMax");
print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptTopMax);
Bprint(f, "%*s%s:\n", indent, "", "subscriptBaselineDropMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptBaselineDropMin);
Bprint(f, "%*s%s:\n", indent, "", "superscriptShiftUp");
print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptShiftUp);
Bprint(f, "%*s%s:\n", indent, "", "superscriptShiftUpCramped");
print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptShiftUpCramped);
Bprint(f, "%*s%s:\n", indent, "", "superscriptBottomMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBottomMin);
Bprint(f, "%*s%s:\n", indent, "", "superscriptBaselineDropMax");
print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBaselineDropMax);
Bprint(f, "%*s%s:\n", indent, "", "subSuperscriptGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->subSuperscriptGapMin);
Bprint(f, "%*s%s:\n", indent, "", "superscriptBottomMaxWithSubscript");
print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBottomMaxWithSubscript);
Bprint(f, "%*s%s:\n", indent, "", "spaceAfterScript");
print_MathValueRecord(f, indent+indentΔ, o, &v->spaceAfterScript);
Bprint(f, "%*s%s:\n", indent, "", "upperLimitGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->upperLimitGapMin);
Bprint(f, "%*s%s:\n", indent, "", "upperLimitBaselineRiseMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->upperLimitBaselineRiseMin);
Bprint(f, "%*s%s:\n", indent, "", "lowerLimitGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->lowerLimitGapMin);
Bprint(f, "%*s%s:\n", indent, "", "lowerLimitBaselineDropMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->lowerLimitBaselineDropMin);
Bprint(f, "%*s%s:\n", indent, "", "stackTopShiftUp");
print_MathValueRecord(f, indent+indentΔ, o, &v->stackTopShiftUp);
Bprint(f, "%*s%s:\n", indent, "", "stackTopDisplayStyleShiftUp");
print_MathValueRecord(f, indent+indentΔ, o, &v->stackTopDisplayStyleShiftUp);
Bprint(f, "%*s%s:\n", indent, "", "stackBottomShiftDown");
print_MathValueRecord(f, indent+indentΔ, o, &v->stackBottomShiftDown);
Bprint(f, "%*s%s:\n", indent, "", "stackBottomDisplayStyleShiftDown");
print_MathValueRecord(f, indent+indentΔ, o, &v->stackBottomDisplayStyleShiftDown);
Bprint(f, "%*s%s:\n", indent, "", "stackGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->stackGapMin);
Bprint(f, "%*s%s:\n", indent, "", "stackDisplayStyleGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->stackDisplayStyleGapMin);
Bprint(f, "%*s%s:\n", indent, "", "stretchStackTopShiftUp");
print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackTopShiftUp);
Bprint(f, "%*s%s:\n", indent, "", "stretchStackBottomShiftDown");
print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackBottomShiftDown);
Bprint(f, "%*s%s:\n", indent, "", "stretchStackGapAboveMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackGapAboveMin);
Bprint(f, "%*s%s:\n", indent, "", "stretchStackGapBelowMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackGapBelowMin);
Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorShiftUp");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorShiftUp);
Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorDisplayStyleShiftUp");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorDisplayStyleShiftUp);
Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorShiftDown");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorShiftDown);
Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorDisplayStyleShiftDown");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorDisplayStyleShiftDown);
Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorGapMin);
Bprint(f, "%*s%s:\n", indent, "", "fractionNumDisplayStyleGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumDisplayStyleGapMin);
Bprint(f, "%*s%s:\n", indent, "", "fractionRuleThickness");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionRuleThickness);
Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorGapMin);
Bprint(f, "%*s%s:\n", indent, "", "fractionDenomDisplayStyleGapMin");
print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenomDisplayStyleGapMin);
Bprint(f, "%*s%s:\n", indent, "", "skewedFractionHorizontalGap");
print_MathValueRecord(f, indent+indentΔ, o, &v->skewedFractionHorizontalGap);
Bprint(f, "%*s%s:\n", indent, "", "skewedFractionVerticalGap");
print_MathValueRecord(f, indent+indentΔ, o, &v->skewedFractionVerticalGap);
Bprint(f, "%*s%s:\n", indent, "", "overbarVerticalGap");
print_MathValueRecord(f, indent+indentΔ, o, &v->overbarVerticalGap);
Bprint(f, "%*s%s:\n", indent, "", "overbarRuleThickness");
print_MathValueRecord(f, indent+indentΔ, o, &v->overbarRuleThickness);
Bprint(f, "%*s%s:\n", indent, "", "overbarExtraAscender");
print_MathValueRecord(f, indent+indentΔ, o, &v->overbarExtraAscender);
Bprint(f, "%*s%s:\n", indent, "", "underbarVerticalGap");
print_MathValueRecord(f, indent+indentΔ, o, &v->underbarVerticalGap);
Bprint(f, "%*s%s:\n", indent, "", "underbarRuleThickness");
print_MathValueRecord(f, indent+indentΔ, o, &v->underbarRuleThickness);
Bprint(f, "%*s%s:\n", indent, "", "underbarExtraDescender");
print_MathValueRecord(f, indent+indentΔ, o, &v->underbarExtraDescender);
Bprint(f, "%*s%s:\n", indent, "", "radicalVerticalGap");
print_MathValueRecord(f, indent+indentΔ, o, &v->radicalVerticalGap);
Bprint(f, "%*s%s:\n", indent, "", "radicalDisplayStyleVerticalGap");
print_MathValueRecord(f, indent+indentΔ, o, &v->radicalDisplayStyleVerticalGap);
Bprint(f, "%*s%s:\n", indent, "", "radicalRuleThickness");
print_MathValueRecord(f, indent+indentΔ, o, &v->radicalRuleThickness);
Bprint(f, "%*s%s:\n", indent, "", "radicalExtraAscender");
print_MathValueRecord(f, indent+indentΔ, o, &v->radicalExtraAscender);
Bprint(f, "%*s%s:\n", indent, "", "radicalKernBeforeDegree");
print_MathValueRecord(f, indent+indentΔ, o, &v->radicalKernBeforeDegree);
Bprint(f, "%*s%s:\n", indent, "", "radicalKernAfterDegree");
print_MathValueRecord(f, indent+indentΔ, o, &v->radicalKernAfterDegree);
Bprint(f, "%*s%s: %d\n", indent, "", "radicalDegreeBottomRaisePercent", v->radicalDegreeBottomRaisePercent);
USED(o);
}
int
read_MathItalicsCorrectionInfo(Otf *o, MathItalicsCorrectionInfo *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->italicsCorrectionCoverageOffset = b[0]<<8 | b[1];
v->italicsCorrectionCount = b[2]<<8 | b[3];
if(otfarray(o, &v->italicsCorrection, read_MathValueRecord, sizeof(MathValueRecord), v->italicsCorrectionCount) < 0){
werrstr("%s: %r", "italicsCorrection");
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathItalicsCorrectionInfo");
return -1;
}
void
print_MathItalicsCorrectionInfo(Biobuf *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);
for(int i = 0; i < v->italicsCorrectionCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "italicsCorrection", i);
print_MathValueRecord(f, indent+indentΔ, o, &v->italicsCorrection[i]);
}
USED(o);
}
int
read_MathTopAccentAttachment(Otf *o, MathTopAccentAttachment *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->topAccentCoverageOffset = b[0]<<8 | b[1];
v->topAccentAttachmentCount = b[2]<<8 | b[3];
if(otfarray(o, &v->topAccentAttachment, read_MathValueRecord, sizeof(MathValueRecord), v->topAccentAttachmentCount) < 0){
werrstr("%s: %r", "topAccentAttachment");
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathTopAccentAttachment");
return -1;
}
void
print_MathTopAccentAttachment(Biobuf *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);
for(int i = 0; i < v->topAccentAttachmentCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "topAccentAttachment", i);
print_MathValueRecord(f, indent+indentΔ, o, &v->topAccentAttachment[i]);
}
USED(o);
}
int
read_MathKernInfoRecord(Otf *o, MathKernInfoRecord *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->topRightMathKernOffset = b[0]<<8 | b[1];
v->topLeftMathKernOffset = b[2]<<8 | b[3];
v->bottomRightMathKernOffset = b[4]<<8 | b[5];
v->bottomLeftMathKernOffset = b[6]<<8 | b[7];
return 0;
err:
werrstr("%s: %r", "MathKernInfoRecord");
return -1;
}
void
print_MathKernInfoRecord(Biobuf *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);
USED(o);
}
int
read_MathKernInfo(Otf *o, MathKernInfo *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->mathKernCoverageOffset = b[0]<<8 | b[1];
v->mathKernCount = b[2]<<8 | b[3];
if(otfarray(o, &v->mathKernInfoRecords, read_MathKernInfoRecord, sizeof(MathKernInfoRecord), v->mathKernCount) < 0){
werrstr("%s: %r", "mathKernInfoRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathKernInfo");
return -1;
}
void
print_MathKernInfo(Biobuf *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);
for(int i = 0; i < v->mathKernCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "mathKernInfoRecords", i);
print_MathKernInfoRecord(f, indent+indentΔ, o, &v->mathKernInfoRecords[i]);
}
USED(o);
}
int
read_MathKern(Otf *o, MathKern *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->heightCount = b[0]<<8 | b[1];
if(otfarray(o, &v->correctionHeight, read_MathValueRecord, sizeof(MathValueRecord), v->heightCount) < 0){
werrstr("%s: %r", "correctionHeight");
goto err;
}
if(otfarray(o, &v->kernValues, read_MathValueRecord, sizeof(MathValueRecord), v->heightCount) < 0){
werrstr("%s: %r", "kernValues");
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathKern");
return -1;
}
void
print_MathKern(Biobuf *f, int indent, Otf *o, MathKern *v)
{
Bprint(f, "%*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);
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);
print_MathValueRecord(f, indent+indentΔ, o, &v->kernValues[i]);
}
USED(o);
}
int
read_Coverage1(Otf *o, Coverage1 *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->glyphCount = b[0]<<8 | b[1];
if((b = otfreadn(o, v->glyphCount*2)) == nil)
goto err;
v->glyphArray = malloc(v->glyphCount*sizeof(*v->glyphArray));
for(int i = 0; i < v->glyphCount; i++)
v->glyphArray[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "Coverage1");
return -1;
}
void
print_Coverage1(Biobuf *f, int indent, Otf *o, Coverage1 *v)
{
Bprint(f, "%*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]);
USED(o);
}
int
read_RangeRecord(Otf *o, RangeRecord *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->startGlyphID = b[0]<<8 | b[1];
v->endGlyphID = b[2]<<8 | b[3];
v->startCoverageIndex = b[4]<<8 | b[5];
return 0;
err:
werrstr("%s: %r", "RangeRecord");
return -1;
}
void
print_RangeRecord(Biobuf *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);
USED(o);
}
int
read_Coverage2(Otf *o, Coverage2 *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->rangeCount = b[0]<<8 | b[1];
if(otfarray(o, &v->rangeRecords, read_RangeRecord, sizeof(RangeRecord), v->rangeCount) < 0){
werrstr("%s: %r", "rangeRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "Coverage2");
return -1;
}
void
print_Coverage2(Biobuf *f, int indent, Otf *o, Coverage2 *v)
{
Bprint(f, "%*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);
print_RangeRecord(f, indent+indentΔ, o, &v->rangeRecords[i]);
}
USED(o);
}
int
read_Coverage(Otf *o, Coverage *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->format = b[0]<<8 | b[1];
if(v->format != 1 && v->format != 2){
werrstr("%s: invalid value: %d (0x%ux)", "format", v->format, v->format);
goto err;
}
if(v->format == 1){
if(read_Coverage1(o, &v->cov1) < 0){
werrstr("%s: %r", "cov1");
goto err;
}
}
if(v->format == 2){
if(read_Coverage2(o, &v->cov2) < 0){
werrstr("%s: %r", "cov2");
goto err;
}
}
return 0;
err:
werrstr("%s: %r", "Coverage");
return -1;
}
void
print_Coverage(Biobuf *f, int indent, Otf *o, Coverage *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
if(v->format == 1){
Bprint(f, "%*s%s:\n", indent, "", "cov1");
print_Coverage1(f, indent+indentΔ, o, &v->cov1);
}
if(v->format == 2){
Bprint(f, "%*s%s:\n", indent, "", "cov2");
print_Coverage2(f, indent+indentΔ, o, &v->cov2);
}
USED(o);
}
int
read_MathVariants(Otf *o, MathVariants *v)
{
u8int *b;
if((b = otfreadn(o, 10)) == nil)
goto err;
v->minConnectorOverlap = b[0]<<8 | b[1];
v->vertGlyphCoverageOffset = b[2]<<8 | b[3];
v->horizGlyphCoverageOffset = b[4]<<8 | b[5];
v->vertGlyphCount = b[6]<<8 | b[7];
v->horizGlyphCount = b[8]<<8 | b[9];
if((b = otfreadn(o, v->vertGlyphCount*2)) == nil)
goto err;
v->vertGlyphConstructionOffsets = malloc(v->vertGlyphCount*sizeof(*v->vertGlyphConstructionOffsets));
for(int i = 0; i < v->vertGlyphCount; i++)
v->vertGlyphConstructionOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
if((b = otfreadn(o, v->horizGlyphCount*2)) == nil)
goto err;
v->horizGlyphConstructionOffsets = malloc(v->horizGlyphCount*sizeof(*v->horizGlyphConstructionOffsets));
for(int i = 0; i < v->horizGlyphCount; i++)
v->horizGlyphConstructionOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
if(v->vertGlyphCoverageOffset != 0){
if(otfpushrange(o, v->vertGlyphCoverageOffset, -1) < 0)
goto err;
v->vertGlyphCoverage = calloc(1, sizeof(*v->vertGlyphCoverage));
if(read_Coverage(o, v->vertGlyphCoverage) < 0){
werrstr("%s: %r", "vertGlyphCoverage");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->horizGlyphCoverageOffset != 0){
if(otfpushrange(o, v->horizGlyphCoverageOffset, -1) < 0)
goto err;
v->horizGlyphCoverage = calloc(1, sizeof(*v->horizGlyphCoverage));
if(read_Coverage(o, v->horizGlyphCoverage) < 0){
werrstr("%s: %r", "horizGlyphCoverage");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathVariants");
return -1;
}
void
print_MathVariants(Biobuf *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);
for(int i = 0; i < v->vertGlyphCount; i++)
Bprint(f, "%*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");
if(v->vertGlyphCoverage != nil)
print_Coverage(f, indent+indentΔ, o, v->vertGlyphCoverage);
Bprint(f, "%*s%s:\n", indent, "", "horizGlyphCoverage");
if(v->horizGlyphCoverage != nil)
print_Coverage(f, indent+indentΔ, o, v->horizGlyphCoverage);
USED(o);
}
int
read_MathGlyphInfo(Otf *o, MathGlyphInfo *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->mathItalicsCorrectionInfoOffset = b[0]<<8 | b[1];
v->mathTopAccentAttachmentOffset = b[2]<<8 | b[3];
v->extendedShapeCoverageOffset = b[4]<<8 | b[5];
v->mathKernInfoOffset = b[6]<<8 | b[7];
if(v->mathItalicsCorrectionInfoOffset != 0){
if(otfpushrange(o, v->mathItalicsCorrectionInfoOffset, -1) < 0)
goto err;
v->mathItalicsCorrectionInfo = calloc(1, sizeof(*v->mathItalicsCorrectionInfo));
if(read_MathItalicsCorrectionInfo(o, v->mathItalicsCorrectionInfo) < 0){
werrstr("%s: %r", "mathItalicsCorrectionInfo");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->mathTopAccentAttachmentOffset != 0){
if(otfpushrange(o, v->mathTopAccentAttachmentOffset, -1) < 0)
goto err;
v->mathTopAccentAttachment = calloc(1, sizeof(*v->mathTopAccentAttachment));
if(read_MathTopAccentAttachment(o, v->mathTopAccentAttachment) < 0){
werrstr("%s: %r", "mathTopAccentAttachment");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->mathKernInfoOffset != 0){
if(otfpushrange(o, v->mathKernInfoOffset, -1) < 0)
goto err;
v->mathKernInfo = calloc(1, sizeof(*v->mathKernInfo));
if(read_MathKernInfo(o, v->mathKernInfo) < 0){
werrstr("%s: %r", "mathKernInfo");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->extendedShapeCoverageOffset != 0){
if(otfpushrange(o, v->extendedShapeCoverageOffset, -1) < 0)
goto err;
v->extendedShapeCoverage = calloc(1, sizeof(*v->extendedShapeCoverage));
if(read_Coverage(o, v->extendedShapeCoverage) < 0){
werrstr("%s: %r", "extendedShapeCoverage");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathGlyphInfo");
return -1;
}
void
print_MathGlyphInfo(Biobuf *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");
if(v->mathItalicsCorrectionInfo != nil)
print_MathItalicsCorrectionInfo(f, indent+indentΔ, o, v->mathItalicsCorrectionInfo);
Bprint(f, "%*s%s:\n", indent, "", "mathTopAccentAttachment");
if(v->mathTopAccentAttachment != nil)
print_MathTopAccentAttachment(f, indent+indentΔ, o, v->mathTopAccentAttachment);
Bprint(f, "%*s%s:\n", indent, "", "mathKernInfo");
if(v->mathKernInfo != nil)
print_MathKernInfo(f, indent+indentΔ, o, v->mathKernInfo);
Bprint(f, "%*s%s:\n", indent, "", "extendedShapeCoverage");
if(v->extendedShapeCoverage != nil)
print_Coverage(f, indent+indentΔ, o, v->extendedShapeCoverage);
USED(o);
}
int
read_MathGlyphVariantRecord(Otf *o, MathGlyphVariantRecord *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->variantGlyph = b[0]<<8 | b[1];
v->advanceMeasurement = b[2]<<8 | b[3];
return 0;
err:
werrstr("%s: %r", "MathGlyphVariantRecord");
return -1;
}
void
print_MathGlyphVariantRecord(Biobuf *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);
USED(o);
}
int
read_GlyphPart(Otf *o, GlyphPart *v)
{
u8int *b;
if((b = otfreadn(o, 10)) == nil)
goto err;
v->glyphID = b[0]<<8 | b[1];
v->startConnectorLength = b[2]<<8 | b[3];
v->endConnectorLength = b[4]<<8 | b[5];
v->fullAdvance = b[6]<<8 | b[7];
v->partFlags = b[8]<<8 | b[9];
return 0;
err:
werrstr("%s: %r", "GlyphPart");
return -1;
}
void
print_GlyphPart(Biobuf *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);
USED(o);
}
int
read_GlyphAssembly(Otf *o, GlyphAssembly *v)
{
u8int *b;
if(read_MathValueRecord(o, &v->italicsCorrection) < 0){
werrstr("%s: %r", "italicsCorrection");
goto err;
}
if((b = otfreadn(o, 2)) == nil)
goto err;
v->partCount = b[0]<<8 | b[1];
if(otfarray(o, &v->partRecords, read_GlyphPart, sizeof(GlyphPart), v->partCount) < 0){
werrstr("%s: %r", "partRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "GlyphAssembly");
return -1;
}
void
print_GlyphAssembly(Biobuf *f, int indent, Otf *o, GlyphAssembly *v)
{
Bprint(f, "%*s%s:\n", indent, "", "italicsCorrection");
print_MathValueRecord(f, indent+indentΔ, o, &v->italicsCorrection);
Bprint(f, "%*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);
print_GlyphPart(f, indent+indentΔ, o, &v->partRecords[i]);
}
USED(o);
}
int
read_MathGlyphConstruction(Otf *o, MathGlyphConstruction *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->glyphAssemblyOffset = b[0]<<8 | b[1];
v->variantCount = b[2]<<8 | b[3];
if(otfarray(o, &v->mathGlyphVariantRecords, read_MathGlyphVariantRecord, sizeof(MathGlyphVariantRecord), v->variantCount) < 0){
werrstr("%s: %r", "mathGlyphVariantRecords");
goto err;
}
if(v->glyphAssemblyOffset != 0){
if(otfpushrange(o, v->glyphAssemblyOffset, -1) < 0)
goto err;
v->glyphAssembly = calloc(1, sizeof(*v->glyphAssembly));
if(read_GlyphAssembly(o, v->glyphAssembly) < 0){
werrstr("%s: %r", "glyphAssembly");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "MathGlyphConstruction");
return -1;
}
void
print_MathGlyphConstruction(Biobuf *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);
for(int i = 0; i < v->variantCount; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "mathGlyphVariantRecords", i);
print_MathGlyphVariantRecord(f, indent+indentΔ, o, &v->mathGlyphVariantRecords[i]);
}
Bprint(f, "%*s%s:\n", indent, "", "glyphAssembly");
if(v->glyphAssembly != nil)
print_GlyphAssembly(f, indent+indentΔ, o, v->glyphAssembly);
USED(o);
}
int
read_TableMATH(Otf *o, TableMATH *v)
{
u8int *b;
if((b = otfreadn(o, 10)) == 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->mathConstantsOffset = b[4]<<8 | b[5];
v->mathGlyphInfoOffset = b[6]<<8 | b[7];
v->mathVariantsOffset = b[8]<<8 | b[9];
if(v->mathConstantsOffset != 0){
if(otfpushrange(o, v->mathConstantsOffset, -1) < 0)
goto err;
v->mathConstants = calloc(1, sizeof(*v->mathConstants));
if(read_MathConstants(o, v->mathConstants) < 0){
werrstr("%s: %r", "mathConstants");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->mathGlyphInfoOffset != 0){
if(otfpushrange(o, v->mathGlyphInfoOffset, -1) < 0)
goto err;
v->mathGlyphInfo = calloc(1, sizeof(*v->mathGlyphInfo));
if(read_MathGlyphInfo(o, v->mathGlyphInfo) < 0){
werrstr("%s: %r", "mathGlyphInfo");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->mathVariantsOffset != 0){
if(otfpushrange(o, v->mathVariantsOffset, -1) < 0)
goto err;
v->mathVariants = calloc(1, sizeof(*v->mathVariants));
if(read_MathVariants(o, v->mathVariants) < 0){
werrstr("%s: %r", "mathVariants");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableMATH");
return -1;
}
void
print_TableMATH(Biobuf *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");
if(v->mathConstants != nil)
print_MathConstants(f, indent+indentΔ, o, v->mathConstants);
Bprint(f, "%*s%s:\n", indent, "", "mathGlyphInfo");
if(v->mathGlyphInfo != nil)
print_MathGlyphInfo(f, indent+indentΔ, o, v->mathGlyphInfo);
Bprint(f, "%*s%s:\n", indent, "", "mathVariants");
if(v->mathVariants != nil)
print_MathVariants(f, indent+indentΔ, o, v->mathVariants);
USED(o);
}
int
read_KernPair(Otf *o, KernPair *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
v->left = b[0]<<8 | b[1];
v->right = b[2]<<8 | b[3];
v->value = b[4]<<8 | b[5];
return 0;
err:
werrstr("%s: %r", "KernPair");
return -1;
}
void
print_KernPair(Biobuf *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);
USED(o);
}
int
read_KernSubtable0(Otf *o, KernSubtable0 *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->nPairs = b[0]<<8 | b[1];
v->searchRange = b[2]<<8 | b[3];
v->entrySelector = b[4]<<8 | b[5];
v->rangeShift = b[6]<<8 | b[7];
if(otfarray(o, &v->kernPairs, read_KernPair, sizeof(KernPair), v->nPairs) < 0){
werrstr("%s: %r", "kernPairs");
goto err;
}
return 0;
err:
werrstr("%s: %r", "KernSubtable0");
return -1;
}
void
print_KernSubtable0(Biobuf *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);
for(int i = 0; i < v->nPairs; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "kernPairs", i);
print_KernPair(f, indent+indentΔ, o, &v->kernPairs[i]);
}
USED(o);
}
int
read_KernClass(Otf *o, KernClass *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->firstGlyph = b[0]<<8 | b[1];
v->nGlyphs = b[2]<<8 | b[3];
if((b = otfreadn(o, v->nGlyphs*2)) == nil)
goto err;
v->values = malloc(v->nGlyphs*sizeof(*v->values));
for(int i = 0; i < v->nGlyphs; i++)
v->values[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "KernClass");
return -1;
}
void
print_KernClass(Biobuf *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);
for(int i = 0; i < v->nGlyphs; i++)
Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "values", i, v->values[i]);
USED(o);
}
int
read_KernSubtable2(Otf *o, KernSubtable2 *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->rowWidth = b[0]<<8 | b[1];
v->leftClassOffset = b[2]<<8 | b[3];
v->rightClassOffset = b[4]<<8 | b[5];
v->kerningArrayOffset = b[6]<<8 | b[7];
if(v->leftClassOffset != 0){
if(otfpushrange(o, v->leftClassOffset, -1) < 0)
goto err;
v->leftClass = calloc(1, sizeof(*v->leftClass));
if(read_KernClass(o, v->leftClass) < 0){
werrstr("%s: %r", "leftClass");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if(v->rightClassOffset != 0){
if(otfpushrange(o, v->rightClassOffset, -1) < 0)
goto err;
v->rightClass = calloc(1, sizeof(*v->rightClass));
if(read_KernClass(o, v->rightClass) < 0){
werrstr("%s: %r", "rightClass");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
if((b = otfreadn(o, (v->rowWidth/2)*2)) == nil)
goto err;
v->kerningArray = malloc((v->rowWidth/2)*sizeof(*v->kerningArray));
for(int i = 0; i < (v->rowWidth/2); i++)
v->kerningArray[i] = b[0+i*2]<<8 | b[1+i*2];
return 0;
err:
werrstr("%s: %r", "KernSubtable2");
return -1;
}
void
print_KernSubtable2(Biobuf *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");
if(v->leftClass != nil)
print_KernClass(f, indent+indentΔ, o, v->leftClass);
Bprint(f, "%*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]);
USED(o);
}
int
read_KernSubtable(Otf *o, KernSubtable *v)
{
u8int *b;
if((b = otfreadn(o, 6)) == nil)
goto err;
u16int version = b[0]<<8 | b[1];
if(version != 0){
werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
goto err;
}
v->length = b[2]<<8 | b[3];
if(v->length < 6){
werrstr("%s: invalid value: %d (0x%ux)", "length", v->length, v->length);
goto err;
}
v->coverage = b[4]<<8 | b[5];
return 0;
err:
werrstr("%s: %r", "KernSubtable");
return -1;
}
void
print_KernSubtable(Biobuf *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);
USED(o);
}
int
read_TableKern(Otf *o, TableKern *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
u16int version = b[0]<<8 | b[1];
if(version != 0){
werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
goto err;
}
v->nTables = b[2]<<8 | b[3];
if(otfarray(o, &v->subtables, read_KernSubtable, sizeof(KernSubtable), v->nTables) < 0){
werrstr("%s: %r", "subtables");
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableKern");
return -1;
}
void
print_TableKern(Biobuf *f, int indent, Otf *o, TableKern *v)
{
Bprint(f, "%*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);
print_KernSubtable(f, indent+indentΔ, o, &v->subtables[i]);
}
USED(o);
}
int
read_TableLoca(Otf *o, TableLoca *v)
{
u8int *b;
if(o->indexToLocFormat == 0){
if((b = otfreadn(o, (o->numGlyphs+1)*2)) == nil)
goto err;
v->shortOffsets = malloc((o->numGlyphs+1)*sizeof(*v->shortOffsets));
for(int i = 0; i < (o->numGlyphs+1); i++)
v->shortOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
}
if(o->indexToLocFormat == 1){
if((b = otfreadn(o, (o->numGlyphs+1)*4)) == nil)
goto err;
v->longOffsets = malloc((o->numGlyphs+1)*sizeof(*v->longOffsets));
for(int i = 0; i < (o->numGlyphs+1); i++)
v->longOffsets[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", "TableLoca");
return -1;
}
void
print_TableLoca(Biobuf *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]);
}
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]);
}
USED(o);
}
int
read_VariationAxisRecord(Otf *o, VariationAxisRecord *v)
{
u8int *b;
if((b = otfreadn(o, 20)) == nil)
goto err;
v->axisTag = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->minValue = (b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7])/65536.0f;
v->defaultValue = (b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11])/65536.0f;
v->maxValue = (b[12]<<24 | b[13]<<16 | b[14]<<8 | b[15])/65536.0f;
v->flags = b[16]<<8 | b[17];
v->axisNameID = b[18]<<8 | b[19];
return 0;
err:
werrstr("%s: %r", "VariationAxisRecord");
return -1;
}
void
print_VariationAxisRecord(Biobuf *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\n", indent, "", "flags", v->flags);
Bprint(f, "%*s%s: %ud\n", indent, "", "axisNameID", v->axisNameID);
USED(o);
}
int
read_UserTuple(Otf *o, UserTuple *v)
{
u8int *b;
if((b = otfreadn(o, o->axisCount*4)) == 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*4]<<24 | b[1+i*4]<<16 | b[2+i*4]<<8 | b[3+i*4])/65536.0f;
return 0;
err:
werrstr("%s: %r", "UserTuple");
return -1;
}
void
print_UserTuple(Biobuf *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]);
USED(o);
}
int
read_InstanceRecord(Otf *o, InstanceRecord *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->subfamilyNameID = b[0]<<8 | b[1];
v->flags = b[2]<<8 | b[3];
if(read_UserTuple(o, &v->coordinates) < 0){
werrstr("%s: %r", "coordinates");
goto err;
}
if((o->instanceSize==((o->axisCount*4)+6))){
if((b = otfreadn(o, 2)) == nil)
goto err;
v->postScriptNameID = b[0]<<8 | b[1];
}
return 0;
err:
werrstr("%s: %r", "InstanceRecord");
return -1;
}
void
print_InstanceRecord(Biobuf *f, int indent, Otf *o, InstanceRecord *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "subfamilyNameID", v->subfamilyNameID);
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)))
Bprint(f, "%*s%s: %ud\n", indent, "", "postScriptNameID", v->postScriptNameID);
USED(o);
}
int
read_AxisInstances(Otf *o, AxisInstances *v)
{
u8int *b;
if(otfarray(o, &v->axes, read_VariationAxisRecord, sizeof(VariationAxisRecord), o->axisCount) < 0){
werrstr("%s: %r", "axes");
goto err;
}
if(otfarray(o, &v->instaces, read_InstanceRecord, sizeof(InstanceRecord), o->instanceCount) < 0){
werrstr("%s: %r", "instaces");
goto err;
}
return 0;
err:
werrstr("%s: %r", "AxisInstances");
return -1;
}
void
print_AxisInstances(Biobuf *f, int indent, Otf *o, AxisInstances *v)
{
for(int i = 0; i < o->axisCount; i++){
Bprint(f, "%*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);
print_InstanceRecord(f, indent+indentΔ, o, &v->instaces[i]);
}
USED(o);
}
int
read_TableFvar(Otf *o, TableFvar *v)
{
u8int *b;
if((b = otfreadn(o, 16)) == 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->axesArrayOffset = b[4]<<8 | b[5];
v->axisCount = b[8]<<8 | b[9];
o->axisCount = v->axisCount;
u16int axisSize = b[10]<<8 | b[11];
if(axisSize != 20){
werrstr("%s: invalid value: %d (0x%ux)", "axisSize", axisSize, axisSize);
goto err;
}
v->instanceCount = b[12]<<8 | b[13];
o->instanceCount = v->instanceCount;
v->instanceSize = b[14]<<8 | b[15];
o->instanceSize = v->instanceSize;
if(v->axesArrayOffset != 0){
if(otfpushrange(o, v->axesArrayOffset, -1) < 0)
goto err;
v->axisInstances = calloc(1, sizeof(*v->axisInstances));
if(read_AxisInstances(o, v->axisInstances) < 0){
werrstr("%s: %r", "axisInstances");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableFvar");
return -1;
}
void
print_TableFvar(Biobuf *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");
if(v->axisInstances != nil)
print_AxisInstances(f, indent+indentΔ, o, v->axisInstances);
USED(o);
}
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;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->version = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(v->version == 1){
if((b = otfreadn(o, 24)) == nil)
goto err;
v->fontforge = ((s64int)b[0]<<56 | (s64int)b[1]<<48 | (s64int)b[2]<<40 | (s64int)b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7]) - 2082844800LL;
v->created = ((s64int)b[8]<<56 | (s64int)b[9]<<48 | (s64int)b[10]<<40 | (s64int)b[11]<<32 | b[12]<<24 | b[13]<<16 | b[14]<<8 | b[15]) - 2082844800LL;
v->modified = ((s64int)b[16]<<56 | (s64int)b[17]<<48 | (s64int)b[18]<<40 | (s64int)b[19]<<32 | b[20]<<24 | b[21]<<16 | b[22]<<8 | b[23]) - 2082844800LL;
}
return 0;
err:
werrstr("%s: %r", "TableFFTM");
return -1;
}
void
print_TableFFTM(Biobuf *f, int indent, Otf *o, TableFFTM *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
if(v->version == 1)
Bprint(f, "%*s%s: %T\n", indent, "", "fontforge", v->fontforge);
if(v->version == 1)
Bprint(f, "%*s%s: %T\n", indent, "", "created", v->created);
if(v->version == 1)
Bprint(f, "%*s%s: %T\n", indent, "", "modified", v->modified);
USED(o);
}
int
read_SignatureBlock1(Otf *o, SignatureBlock1 *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
v->signatureLength = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
if((b = otfreadn(o, v->signatureLength*1)) == nil)
goto err;
v->signature = malloc(v->signatureLength*sizeof(*v->signature));
for(int i = 0; i < v->signatureLength; i++)
v->signature[i] = b[0+i*1];
return 0;
err:
werrstr("%s: %r", "SignatureBlock1");
return -1;
}
void
print_SignatureBlock1(Biobuf *f, int indent, Otf *o, SignatureBlock1 *v)
{
Bprint(f, "%*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]);
USED(o);
}
int
read_SignatureRecord(Otf *o, SignatureRecord *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == nil)
goto err;
v->format = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->length = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
v->signatureBlockOffset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
if(v->format == 1){
if(v->signatureBlockOffset != 0){
if(otfpushrange(o, v->signatureBlockOffset, -1) < 0)
goto err;
v->signatureBlock1 = calloc(1, sizeof(*v->signatureBlock1));
if(read_SignatureBlock1(o, v->signatureBlock1) < 0){
werrstr("%s: %r", "signatureBlock1");
goto err;
}
if(otfpoprange(o) < 0)
goto err;
}
}
return 0;
err:
werrstr("%s: %r", "SignatureRecord");
return -1;
}
void
print_SignatureRecord(Biobuf *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);
if(v->format == 1){
Bprint(f, "%*s%s:\n", indent, "", "signatureBlock1");
if(v->signatureBlock1 != nil)
print_SignatureBlock1(f, indent+indentΔ, o, v->signatureBlock1);
}
USED(o);
}
int
read_TableDSIG(Otf *o, TableDSIG *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == nil)
goto err;
u32int version = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(version != 1){
werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
goto err;
}
v->numSignatures = b[4]<<8 | b[5];
v->flags = b[6]<<8 | b[7];
if(otfarray(o, &v->signatureRecords, read_SignatureRecord, sizeof(SignatureRecord), v->numSignatures) < 0){
werrstr("%s: %r", "signatureRecords");
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableDSIG");
return -1;
}
void
print_TableDSIG(Biobuf *f, int indent, Otf *o, TableDSIG *v)
{
Bprint(f, "%*s%s: %ud\n", indent, "", "numSignatures", v->numSignatures);
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]);
}
USED(o);
}
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_AxisValueMap(Otf *o, AxisValueMap *v)
{
u8int *b;
if((b = otfreadn(o, 4)) == nil)
goto err;
v->fromCoordinate = (b[0]<<8 | b[1]>>14)+(b[0]<<8 | b[1]&((1<<14)-1))/16384.0;
v->toCoordinate = (b[2]<<8 | b[3]>>14)+(b[2]<<8 | b[3]&((1<<14)-1))/16384.0;
return 0;
err:
werrstr("%s: %r", "AxisValueMap");
return -1;
}
void
print_AxisValueMap(Biobuf *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);
USED(o);
}
int
read_SegmentMaps(Otf *o, SegmentMaps *v)
{
u8int *b;
if((b = otfreadn(o, 2)) == nil)
goto err;
v->positionMapCount = b[0]<<8 | b[1];
if(otfarray(o, &v->axisValueMaps, read_AxisValueMap, sizeof(AxisValueMap), v->positionMapCount) < 0){
werrstr("%s: %r", "axisValueMaps");
goto err;
}
return 0;
err:
werrstr("%s: %r", "SegmentMaps");
return -1;
}
void
print_SegmentMaps(Biobuf *f, int indent, Otf *o, SegmentMaps *v)
{
Bprint(f, "%*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);
print_AxisValueMap(f, indent+indentΔ, o, &v->axisValueMaps[i]);
}
USED(o);
}
int
read_TableAvar(Otf *o, TableAvar *v)
{
u8int *b;
if((b = otfreadn(o, 8)) == 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[6]<<8 | b[7];
if(otfarray(o, &v->axisSegmentMaps, read_SegmentMaps, sizeof(SegmentMaps), v->axisCount) < 0){
werrstr("%s: %r", "axisSegmentMaps");
goto err;
}
return 0;
err:
werrstr("%s: %r", "TableAvar");
return -1;
}
void
print_TableAvar(Biobuf *f, int indent, Otf *o, TableAvar *v)
{
Bprint(f, "%*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);
print_SegmentMaps(f, indent+indentΔ, o, &v->axisSegmentMaps[i]);
}
USED(o);
}
int
read_TableOS∕2(Otf *o, TableOS∕2 *v)
{
u8int *b;
if((b = otfreadn(o, 78)) == nil)
goto err;
v->version = b[0]<<8 | b[1];
if(v->version > 5){
werrstr("%s: invalid value: %d (0x%ux)", "version", v->version, v->version);
goto err;
}
v->xAvgCharWidth = b[2]<<8 | b[3];
v->usWeightClass = b[4]<<8 | b[5];
v->usWidthClass = b[6]<<8 | b[7];
v->fsType = b[8]<<8 | b[9];
v->ySubscriptXSize = b[10]<<8 | b[11];
v->ySubscriptYSize = b[12]<<8 | b[13];
v->ySubscriptXOffset = b[14]<<8 | b[15];
v->ySubscriptYOffset = b[16]<<8 | b[17];
v->ySuperscriptXSize = b[18]<<8 | b[19];
v->ySuperscriptYSize = b[20]<<8 | b[21];
v->ySuperscriptXOffset = b[22]<<8 | b[23];
v->ySuperscriptYOffset = b[24]<<8 | b[25];
v->yStrikeoutSize = b[26]<<8 | b[27];
v->yStrikeoutPosition = b[28]<<8 | b[29];
v->sFamilyClass = b[30]<<8 | b[31];
for(int i = 0; i < 10; i++)
v->panose[i] = b[32+i*1];
v->ulUnicodeRange1 = b[42]<<24 | b[43]<<16 | b[44]<<8 | b[45];
v->ulUnicodeRange2 = b[46]<<24 | b[47]<<16 | b[48]<<8 | b[49];
v->ulUnicodeRange3 = b[50]<<24 | b[51]<<16 | b[52]<<8 | b[53];
v->ulUnicodeRange4 = b[54]<<24 | b[55]<<16 | b[56]<<8 | b[57];
v->achVendID = b[58]<<24 | b[59]<<16 | b[60]<<8 | b[61];
v->fsSelection = b[62]<<8 | b[63];
v->usFirstCharIndex = b[64]<<8 | b[65];
v->usLastCharIndex = b[66]<<8 | b[67];
v->sTypoAscender = b[68]<<8 | b[69];
v->sTypoDescender = b[70]<<8 | b[71];
v->sTypoLineGap = b[72]<<8 | b[73];
v->usWinAscent = b[74]<<8 | b[75];
v->usWinDescent = b[76]<<8 | b[77];
if(v->version >= 1){
if((b = otfreadn(o, 8)) == nil)
goto err;
v->ulCodePageRange1 = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->ulCodePageRange2 = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
}
if(v->version >= 2){
if((b = otfreadn(o, 10)) == nil)
goto err;
v->sxHeight = b[0]<<8 | b[1];
v->sCapHeight = b[2]<<8 | b[3];
v->usDefaultChar = b[4]<<8 | b[5];
v->usBreakChar = b[6]<<8 | b[7];
v->usMaxContext = b[8]<<8 | b[9];
}
if(v->version >= 5){
if((b = otfreadn(o, 4)) == nil)
goto err;
v->usLowerOpticalPointSize = b[0]<<8 | b[1];
v->usUpperOpticalPointSize = b[2]<<8 | b[3];
}
return 0;
err:
werrstr("%s: %r", "TableOS∕2");
return -1;
}
void
print_TableOS∕2(Biobuf *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);
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);
if(v->version >= 1)
Bprint(f, "%*s%s: %#ux\n", indent, "", "ulCodePageRange1", v->ulCodePageRange1);
if(v->version >= 1)
Bprint(f, "%*s%s: %#ux\n", indent, "", "ulCodePageRange2", v->ulCodePageRange2);
if(v->version >= 2)
Bprint(f, "%*s%s: %d\n", indent, "", "sxHeight", v->sxHeight);
if(v->version >= 2)
Bprint(f, "%*s%s: %d\n", indent, "", "sCapHeight", v->sCapHeight);
if(v->version >= 2)
Bprint(f, "%*s%s: %#ux\n", indent, "", "usDefaultChar", v->usDefaultChar);
if(v->version >= 2)
Bprint(f, "%*s%s: %#ux\n", indent, "", "usBreakChar", v->usBreakChar);
if(v->version >= 2)
Bprint(f, "%*s%s: %ud\n", indent, "", "usMaxContext", v->usMaxContext);
if(v->version >= 5)
Bprint(f, "%*s%s: %ud\n", indent, "", "usLowerOpticalPointSize", v->usLowerOpticalPointSize);
if(v->version >= 5)
Bprint(f, "%*s%s: %ud\n", indent, "", "usUpperOpticalPointSize", v->usUpperOpticalPointSize);
USED(o);
}
int
read_TableRecord(Otf *o, TableRecord *v)
{
u8int *b;
if((b = otfreadn(o, 16)) == nil)
goto err;
v->tableTag = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
v->offset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
v->length = b[12]<<24 | b[13]<<16 | b[14]<<8 | b[15];
return 0;
err:
werrstr("%s: %r", "TableRecord");
return -1;
}
void
print_TableRecord(Biobuf *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);
if(v->print != nil && v->parsed != nil)
v->print(f, indent+indentΔ, o, v->parsed);
USED(o);
}
int
read_TableDirectory(Otf *o, TableDirectory *v)
{
u8int *b;
if((b = otfreadn(o, 12)) == nil)
goto err;
v->sfntVersion = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
if(v->sfntVersion != 0x10000 && v->sfntVersion != 0x4f54544f){
werrstr("%s: invalid value: %d (0x%ux)", "sfntVersion", v->sfntVersion, v->sfntVersion);
goto err;
}
v->numTables = b[4]<<8 | b[5];
v->searchRange = b[6]<<8 | b[7];
v->entrySelector = b[8]<<8 | b[9];
v->rangeShift = b[10]<<8 | b[11];
if(otfarray(o, &v->tableRecords, read_TableRecord, sizeof(TableRecord), v->numTables) < 0){
werrstr("%s: %r", "tableRecords");
goto err;
}
int retry = 0;
do{
for(int i = 0; i < v->numTables; i++){
TableRecord *rec = &v->tableRecords[i];
if(rec->length == 0)
continue;
if(otfpushrange(o, rec->offset, rec->length) < 0)
goto err;
switch(rec->tableTag){
case (u32int)('c'<<24|'m'<<16|'a'<<8|'p'):
if(v->cmap != nil)
break;
v->cmap = calloc(1, sizeof(TableCmap));
if(read_TableCmap(o, v->cmap) < 0){
free(v->cmap);
goto err;
}
rec->parsed = v->cmap;
rec->print = (void*)print_TableCmap;
break;
case (u32int)('h'<<24|'e'<<16|'a'<<8|'d'):
if(v->head != nil)
break;
v->head = calloc(1, sizeof(TableHead));
if(read_TableHead(o, v->head) < 0){
free(v->head);
goto err;
}
rec->parsed = v->head;
rec->print = (void*)print_TableHead;
break;
case (u32int)('h'<<24|'h'<<16|'e'<<8|'a'):
if(v->hhea != nil)
break;
v->hhea = calloc(1, sizeof(TableHhea));
if(read_TableHhea(o, v->hhea) < 0){
free(v->hhea);
goto err;
}
rec->parsed = v->hhea;
rec->print = (void*)print_TableHhea;
break;
case (u32int)('m'<<24|'a'<<16|'x'<<8|'p'):
if(v->maxp != nil)
break;
v->maxp = calloc(1, sizeof(TableMaxp));
if(read_TableMaxp(o, v->maxp) < 0){
free(v->maxp);
goto err;
}
rec->parsed = v->maxp;
rec->print = (void*)print_TableMaxp;
break;
case (u32int)('h'<<24|'m'<<16|'t'<<8|'x'):
{
static int retried = 0;
if(v->hhea == nil || v->maxp == nil){
if(retried){
werrstr("%s: deps missing", "TableHmtx");
goto err;
}
retried = 1;
retry++;
break;
}
if(retried)
retry--;
}
if(v->hmtx != nil)
break;
v->hmtx = calloc(1, sizeof(TableHmtx));
if(read_TableHmtx(o, v->hmtx) < 0){
free(v->hmtx);
goto err;
}
rec->parsed = v->hmtx;
rec->print = (void*)print_TableHmtx;
break;
case (u32int)('p'<<24|'o'<<16|'s'<<8|'t'):
if(v->post != nil)
break;
v->post = calloc(1, sizeof(TablePost));
if(read_TablePost(o, v->post) < 0){
free(v->post);
goto err;
}
rec->parsed = v->post;
rec->print = (void*)print_TablePost;
break;
case (u32int)('n'<<24|'a'<<16|'m'<<8|'e'):
if(v->name != nil)
break;
v->name = calloc(1, sizeof(TableName));
if(read_TableName(o, v->name) < 0){
free(v->name);
goto err;
}
rec->parsed = v->name;
rec->print = (void*)print_TableName;
break;
case (u32int)('E'<<24|'B'<<16|'D'<<8|'T'):
if(v->ebdt != nil)
break;
v->ebdt = calloc(1, sizeof(TableEBDT));
if(read_TableEBDT(o, v->ebdt) < 0){
free(v->ebdt);
goto err;
}
rec->parsed = v->ebdt;
rec->print = (void*)print_TableEBDT;
break;
case (u32int)('E'<<24|'B'<<16|'L'<<8|'C'):
if(v->eblc != nil)
break;
v->eblc = calloc(1, sizeof(TableEBLC));
if(read_TableEBLC(o, v->eblc) < 0){
free(v->eblc);
goto err;
}
rec->parsed = v->eblc;
rec->print = (void*)print_TableEBLC;
break;
case (u32int)('G'<<24|'D'<<16|'E'<<8|'F'):
if(v->gdef != nil)
break;
v->gdef = calloc(1, sizeof(TableGDEF));
if(read_TableGDEF(o, v->gdef) < 0){
free(v->gdef);
goto err;
}
rec->parsed = v->gdef;
rec->print = (void*)print_TableGDEF;
break;
case (u32int)('G'<<24|'P'<<16|'O'<<8|'S'):
if(v->gpos != nil)
break;
v->gpos = calloc(1, sizeof(TableGPOS));
if(read_TableGPOS(o, v->gpos) < 0){
free(v->gpos);
goto err;
}
rec->parsed = v->gpos;
rec->print = (void*)print_TableGPOS;
break;
case (u32int)('G'<<24|'S'<<16|'U'<<8|'B'):
if(v->gsub != nil)
break;
v->gsub = calloc(1, sizeof(TableGSUB));
if(read_TableGSUB(o, v->gsub) < 0){
free(v->gsub);
goto err;
}
rec->parsed = v->gsub;
rec->print = (void*)print_TableGSUB;
break;
case (u32int)('M'<<24|'A'<<16|'T'<<8|'H'):
if(v->math != nil)
break;
v->math = calloc(1, sizeof(TableMATH));
if(read_TableMATH(o, v->math) < 0){
free(v->math);
goto err;
}
rec->parsed = v->math;
rec->print = (void*)print_TableMATH;
break;
case (u32int)('k'<<24|'e'<<16|'r'<<8|'n'):
if(v->kern != nil)
break;
v->kern = calloc(1, sizeof(TableKern));
if(read_TableKern(o, v->kern) < 0){
free(v->kern);
goto err;
}
rec->parsed = v->kern;
rec->print = (void*)print_TableKern;
break;
case (u32int)('l'<<24|'o'<<16|'c'<<8|'a'):
{
static int retried = 0;
if(v->head == nil){
if(retried){
werrstr("%s: deps missing", "TableLoca");
goto err;
}
retried = 1;
retry++;
break;
}
if(retried)
retry--;
}
if(v->loca != nil)
break;
v->loca = calloc(1, sizeof(TableLoca));
if(read_TableLoca(o, v->loca) < 0){
free(v->loca);
goto err;
}
rec->parsed = v->loca;
rec->print = (void*)print_TableLoca;
break;
case (u32int)('f'<<24|'v'<<16|'a'<<8|'r'):
if(v->fvar != nil)
break;
v->fvar = calloc(1, sizeof(TableFvar));
if(read_TableFvar(o, v->fvar) < 0){
free(v->fvar);
goto err;
}
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;
v->fftm = calloc(1, sizeof(TableFFTM));
if(read_TableFFTM(o, v->fftm) < 0){
free(v->fftm);
goto err;
}
rec->parsed = v->fftm;
rec->print = (void*)print_TableFFTM;
break;
case (u32int)('D'<<24|'S'<<16|'I'<<8|'G'):
if(v->dsig != nil)
break;
v->dsig = calloc(1, sizeof(TableDSIG));
if(read_TableDSIG(o, v->dsig) < 0){
free(v->dsig);
goto err;
}
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)('a'<<24|'v'<<16|'a'<<8|'r'):
if(v->avar != nil)
break;
v->avar = calloc(1, sizeof(TableAvar));
if(read_TableAvar(o, v->avar) < 0){
free(v->avar);
goto err;
}
rec->parsed = v->avar;
rec->print = (void*)print_TableAvar;
break;
case (u32int)('O'<<24|'S'<<16|'/'<<8|'2'):
if(v->os∕2 != nil)
break;
v->os∕2 = calloc(1, sizeof(TableOS∕2));
if(read_TableOS∕2(o, v->os∕2) < 0){
free(v->os∕2);
goto err;
}
rec->parsed = v->os∕2;
rec->print = (void*)print_TableOS∕2;
break;
default:
fprint(2, "no parser for \"%t\"\n", rec->tableTag);
break;
}
if(otfpoprange(o) < 0)
goto err;
}
}while(retry > 0);
return 0;
err:
werrstr("%s: %r", "TableDirectory");
return -1;
}
void
print_TableDirectory(Biobuf *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);
for(int i = 0; i < v->numTables; i++){
Bprint(f, "%*s%s[%d]:\n", indent, "", "tableRecords", i);
print_TableRecord(f, indent+indentΔ, o, &v->tableRecords[i]);
}
USED(o);
}