ref: f711b4426695620ce7646d3036f69275be73e59f
parent: 19827008dbe2ae5253cb63df13c4d207ccecbf02
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Sep 2 19:25:31 EDT 2024
define COLR and CPAL
--- a/otf.rkt
+++ b/otf.rkt
@@ -1130,6 +1130,32 @@
{uint16 usUpperOpticalPointSize (>= version 5)}#:tag "OS/2")
+(mkcmplx BaseGlyph {uint16 glyphID} {uint16 firstLayerIndex} {uint16 numLayers})+
+(mkcmplx Layer {uint16 glyphID} {uint16 paletteIndex})+
+(mkcmplx TableCOLR
+ {uint16 version (== 0)} ; FIXME v1 has more stuff+ {uint16 numBaseGlyphRecords}+ {Offset32 baseGlyphRecordsOffset}+ {Offset32 layerRecordsOffset}+ {uint16 numLayerRecords}+ {BaseGlyph baseGlyphs [numBaseGlyphRecords] (at baseGlyphRecordsOffset)}+ {Layer layers [numLayerRecords] (at layerRecordsOffset)}+ #:tag "COLR")
+
+(mkcmplx ColorRecord {uint8 blue} {uint8 greed} {uint8 red} {uint8 alpha})+
+(mkcmplx TableCPAL
+ {uint16 version (== 0)} ; FIXME v1 has more stuff+ {uint16 numPaletteEntries}+ {uint16 numPalettes}+ {uint16 numColorRecords}+ {Offset32 colorRecordsArrayOffset}+ {uint16 colorRecordIndices [numPalettes]}+ {ColorRecord colorRecords [numColorRecords] (at colorRecordsArrayOffset)}+ #:tag "CPAL")
+
(mkcmplx TableRecord
{Tag tableTag} {uint32 checksum unused hex}--- a/plan9/otf.c
+++ b/plan9/otf.c
@@ -7376,6 +7376,191 @@
}
int
+read_BaseGlyph(Otf *o, BaseGlyph *v)
+{+ u8int *b = nil; USED(b);
+ if((b = otfreadn(o, 6)) == nil)
+ goto err;
+ v->glyphID = b[0]<<8 | b[1];
+ v->firstLayerIndex = b[2]<<8 | b[3];
+ v->numLayers = b[4]<<8 | b[5];
+ return 0;
+err:
+ werrstr("%s: %r", "BaseGlyph");+ return -1;
+}
+
+void
+print_BaseGlyph(Otfile *f, int indent, Otf *o, BaseGlyph *v)
+{+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "firstLayerIndex", v->firstLayerIndex);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "numLayers", v->numLayers);
+ USED(o);
+}
+
+int
+read_Layer(Otf *o, Layer *v)
+{+ u8int *b = nil; USED(b);
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->glyphID = b[0]<<8 | b[1];
+ v->paletteIndex = b[2]<<8 | b[3];
+ return 0;
+err:
+ werrstr("%s: %r", "Layer");+ return -1;
+}
+
+void
+print_Layer(Otfile *f, int indent, Otf *o, Layer *v)
+{+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "paletteIndex", v->paletteIndex);
+ USED(o);
+}
+
+int
+read_TableCOLR(Otf *o, TableCOLR *v)
+{+ u8int *b = nil; USED(b);
+ if((b = otfreadn(o, 14)) == nil)
+ goto err;
+ v->version = b[0]<<8 | b[1];
+ if(v->version != 0){+ werrstr("%s: invalid value: %d (%#ux)", "version", v->version, v->version);+ goto err;
+ }
+ v->numBaseGlyphRecords = b[2]<<8 | b[3];
+ v->baseGlyphRecordsOffset = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
+ v->layerRecordsOffset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
+ v->numLayerRecords = b[12]<<8 | b[13];
+ if(v->baseGlyphRecordsOffset != 0){+ if(otfpushrange(o, v->baseGlyphRecordsOffset, -1) < 0)
+ goto err;
+ if(otfarray(o, &v->baseGlyphs, read_BaseGlyph, sizeof(BaseGlyph), v->numBaseGlyphRecords) < 0){+ werrstr("%s: %r", "baseGlyphs");+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ if(v->layerRecordsOffset != 0){+ if(otfpushrange(o, v->layerRecordsOffset, -1) < 0)
+ goto err;
+ if(otfarray(o, &v->layers, read_Layer, sizeof(Layer), v->numLayerRecords) < 0){+ werrstr("%s: %r", "layers");+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "TableCOLR");+ return -1;
+}
+
+void
+print_TableCOLR(Otfile *f, int indent, Otf *o, TableCOLR *v)
+{+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "version", v->version);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "numBaseGlyphRecords", v->numBaseGlyphRecords);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "baseGlyphRecordsOffset", v->baseGlyphRecordsOffset);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "layerRecordsOffset", v->layerRecordsOffset);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "numLayerRecords", v->numLayerRecords);
+ for(int i = 0; i < v->numBaseGlyphRecords; i++){+ f->print(f->aux, "%*s%s[%d]:\n", indent, "", "baseGlyphs", i);
+ print_BaseGlyph(f, indent+indentΔ, o, &v->baseGlyphs[i]);
+ }
+ for(int i = 0; i < v->numLayerRecords; i++){+ f->print(f->aux, "%*s%s[%d]:\n", indent, "", "layers", i);
+ print_Layer(f, indent+indentΔ, o, &v->layers[i]);
+ }
+ USED(o);
+}
+
+int
+read_ColorRecord(Otf *o, ColorRecord *v)
+{+ u8int *b = nil; USED(b);
+ if((b = otfreadn(o, 4)) == nil)
+ goto err;
+ v->blue = b[0];
+ v->greed = b[1];
+ v->red = b[2];
+ v->alpha = b[3];
+ return 0;
+err:
+ werrstr("%s: %r", "ColorRecord");+ return -1;
+}
+
+void
+print_ColorRecord(Otfile *f, int indent, Otf *o, ColorRecord *v)
+{+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "blue", v->blue);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "greed", v->greed);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "red", v->red);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "alpha", v->alpha);
+ USED(o);
+}
+
+int
+read_TableCPAL(Otf *o, TableCPAL *v)
+{+ u8int *b = nil; USED(b);
+ if((b = otfreadn(o, 12)) == nil)
+ goto err;
+ v->version = b[0]<<8 | b[1];
+ if(v->version != 0){+ werrstr("%s: invalid value: %d (%#ux)", "version", v->version, v->version);+ goto err;
+ }
+ v->numPaletteEntries = b[2]<<8 | b[3];
+ v->numPalettes = b[4]<<8 | b[5];
+ v->numColorRecords = b[6]<<8 | b[7];
+ v->colorRecordsArrayOffset = b[8]<<24 | b[9]<<16 | b[10]<<8 | b[11];
+ if((b = otfreadn(o, v->numPalettes*2)) == nil)
+ goto err;
+ v->colorRecordIndices = malloc(v->numPalettes*sizeof(*v->colorRecordIndices));
+ for(int i = 0; i < v->numPalettes; i++)
+ v->colorRecordIndices[i] = b[0+i*2]<<8 | b[1+i*2];
+ if(v->colorRecordsArrayOffset != 0){+ if(otfpushrange(o, v->colorRecordsArrayOffset, -1) < 0)
+ goto err;
+ if(otfarray(o, &v->colorRecords, read_ColorRecord, sizeof(ColorRecord), v->numColorRecords) < 0){+ werrstr("%s: %r", "colorRecords");+ goto err;
+ }
+ if(otfpoprange(o) < 0)
+ goto err;
+ }
+ return 0;
+err:
+ werrstr("%s: %r", "TableCPAL");+ return -1;
+}
+
+void
+print_TableCPAL(Otfile *f, int indent, Otf *o, TableCPAL *v)
+{+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "version", v->version);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "numPaletteEntries", v->numPaletteEntries);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "numPalettes", v->numPalettes);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "numColorRecords", v->numColorRecords);
+ f->print(f->aux, "%*s%s: %ud\n", indent, "", "colorRecordsArrayOffset", v->colorRecordsArrayOffset);
+ for(int i = 0; i < v->numPalettes; i++)
+ f->print(f->aux, "%*s%s[%d]: %ud\n", indent, "", "colorRecordIndices", i, v->colorRecordIndices[i]);
+ for(int i = 0; i < v->numColorRecords; i++){+ f->print(f->aux, "%*s%s[%d]:\n", indent, "", "colorRecords", i);
+ print_ColorRecord(f, indent+indentΔ, o, &v->colorRecords[i]);
+ }
+ USED(o);
+}
+
+int
read_TableRecord(Otf *o, TableRecord *v)
{u8int *b = nil; USED(b);
@@ -7784,6 +7969,30 @@
}
rec->parsed = v->os∕2;
rec->print = (void*)print_TableOS∕2;
+ break;
+ case (u32int)('C'<<24|'O'<<16|'L'<<8|'R'):+ if(v->colr != nil)
+ break;
+ v->colr = calloc(1, sizeof(TableCOLR));
+ if(read_TableCOLR(o, v->colr) < 0){+ free(v->colr);
+ v->colr = nil;
+ goto err;
+ }
+ rec->parsed = v->colr;
+ rec->print = (void*)print_TableCOLR;
+ break;
+ case (u32int)('C'<<24|'P'<<16|'A'<<8|'L'):+ if(v->cpal != nil)
+ break;
+ v->cpal = calloc(1, sizeof(TableCPAL));
+ if(read_TableCPAL(o, v->cpal) < 0){+ free(v->cpal);
+ v->cpal = nil;
+ goto err;
+ }
+ rec->parsed = v->cpal;
+ rec->print = (void*)print_TableCPAL;
break;
default:
// FIXME fprint(2, "no parser for \"%t\"\n", rec->tableTag);
--- a/plan9/otf.h
+++ b/plan9/otf.h
@@ -311,6 +311,11 @@
typedef struct SegmentMaps SegmentMaps;
typedef struct TableAvar TableAvar;
typedef struct TableOS∕2 TableOS∕2;
+typedef struct BaseGlyph BaseGlyph;
+typedef struct Layer Layer;
+typedef struct TableCOLR TableCOLR;
+typedef struct ColorRecord ColorRecord;
+typedef struct TableCPAL TableCPAL;
typedef struct TableRecord TableRecord;
typedef struct TableDirectory TableDirectory;
@@ -1985,6 +1990,59 @@
int read_TableOS∕2(Otf *o, TableOS∕2 *v);
void print_TableOS∕2(Otfile *f, int indent, Otf *o, TableOS∕2 *v);
+struct BaseGlyph {+ u16int glyphID;
+ u16int firstLayerIndex;
+ u16int numLayers;
+};
+
+int read_BaseGlyph(Otf *o, BaseGlyph *v);
+void print_BaseGlyph(Otfile *f, int indent, Otf *o, BaseGlyph *v);
+
+struct Layer {+ u16int glyphID;
+ u16int paletteIndex;
+};
+
+int read_Layer(Otf *o, Layer *v);
+void print_Layer(Otfile *f, int indent, Otf *o, Layer *v);
+
+struct TableCOLR {+ u16int version;
+ u16int numBaseGlyphRecords;
+ u32int baseGlyphRecordsOffset;
+ u32int layerRecordsOffset;
+ u16int numLayerRecords;
+ BaseGlyph *baseGlyphs;
+ Layer *layers;
+};
+
+int read_TableCOLR(Otf *o, TableCOLR *v);
+void print_TableCOLR(Otfile *f, int indent, Otf *o, TableCOLR *v);
+
+struct ColorRecord {+ u8int blue;
+ u8int greed;
+ u8int red;
+ u8int alpha;
+};
+
+int read_ColorRecord(Otf *o, ColorRecord *v);
+void print_ColorRecord(Otfile *f, int indent, Otf *o, ColorRecord *v);
+
+struct TableCPAL {+ u16int version;
+ u16int numPaletteEntries;
+ u16int numPalettes;
+ u16int numColorRecords;
+ u32int colorRecordsArrayOffset;
+ u16int *colorRecordIndices;
+ ColorRecord *colorRecords;
+};
+
+int read_TableCPAL(Otf *o, TableCPAL *v);
+void print_TableCPAL(Otfile *f, int indent, Otf *o, TableCPAL *v);
+
struct TableRecord {u32int tableTag;
// u32int checksum;
@@ -2029,6 +2087,8 @@
TableGvar *gvar;
TableAvar *avar;
TableOS∕2 *os∕2;
+ TableCOLR *colr;
+ TableCPAL *cpal;
};
int read_TableDirectory(Otf *o, TableDirectory *v);
--
⑨