shithub: fnt

Download patch

ref: 48e1da1dd908852cb62e931b46c92f8d3e987ab4
parent: 9cdddf09964fe994938467a19cc8aea34380a0c6
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Jun 20 22:15:55 EDT 2024

DSIG

--- a/otf.c
+++ b/otf.c
@@ -3735,6 +3735,110 @@
 }
 
 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: %ud\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_TableOS∕2(Otf *o, TableOS∕2 *v)
 {
 	u8int *b;
@@ -4114,6 +4218,17 @@
 				}
 				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)('O'<<24|'S'<<16|'/'<<8|'2'):
 				if(v->os∕2 != nil)
--- a/otf.h
+++ b/otf.h
@@ -88,6 +88,9 @@
 typedef struct TableKern TableKern;
 typedef struct TableLoca TableLoca;
 typedef struct TableFFTM TableFFTM;
+typedef struct SignatureBlock1 SignatureBlock1;
+typedef struct SignatureRecord SignatureRecord;
+typedef struct TableDSIG TableDSIG;
 typedef struct TableOS∕2 TableOS∕2;
 typedef struct TableRecord TableRecord;
 typedef struct TableDirectory TableDirectory;
@@ -1052,6 +1055,36 @@
 int read_TableFFTM(Otf *o, TableFFTM *v);
 void print_TableFFTM(Biobuf *f, int indent, Otf *o, TableFFTM *v);
 
+struct SignatureBlock1 {
+	// u16int reserved1;
+	// u16int reserved2;
+	u32int signatureLength;
+	u8int *signature;
+};
+
+int read_SignatureBlock1(Otf *o, SignatureBlock1 *v);
+void print_SignatureBlock1(Biobuf *f, int indent, Otf *o, SignatureBlock1 *v);
+
+struct SignatureRecord {
+	u32int format;
+	u32int length;
+	u32int signatureBlockOffset;
+	SignatureBlock1 *signatureBlock1;
+};
+
+int read_SignatureRecord(Otf *o, SignatureRecord *v);
+void print_SignatureRecord(Biobuf *f, int indent, Otf *o, SignatureRecord *v);
+
+struct TableDSIG {
+	// u32int version;
+	u16int numSignatures;
+	u16int flags;
+	SignatureRecord *signatureRecords;
+};
+
+int read_TableDSIG(Otf *o, TableDSIG *v);
+void print_TableDSIG(Biobuf *f, int indent, Otf *o, TableDSIG *v);
+
 struct TableOS∕2 {
 	u16int version;
 	s16int xAvgCharWidth;
@@ -1132,6 +1165,7 @@
 	TableKern *kern;
 	TableLoca *loca;
 	TableFFTM *fftm;
+	TableDSIG *dsig;
 	TableOS∕2 *os∕2;
 };
 
--- a/otf.rkt
+++ b/otf.rkt
@@ -611,6 +611,25 @@
          {LONGDATETIME modified (== version 1)}
          #:tag "FFTM")
 
+(mkcmplx SignatureBlock1
+         {uint16 reserved1 unused}
+         {uint16 reserved2 unused}
+         {uint32 signatureLength}
+         {uint8 signature [signatureLength]})
+
+(mkcmplx SignatureRecord
+         {uint32 format}
+         {uint32 length}
+         {Offset32 signatureBlockOffset}
+         {SignatureBlock1 signatureBlock1 (at signatureBlockOffset) (== format 1)})
+
+(mkcmplx TableDSIG
+         {uint32 version (== 1) unused}
+         {uint16 numSignatures}
+         {uint16 flags}
+         {SignatureRecord signatureRecords [numSignatures]}
+         #:tag "DSIG")
+
 (mkcmplx TableOS∕2
          {uint16 version (<= 5)}
          {FWORD xAvgCharWidth}