"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GposMarkToMarkReader = exports.GposMarkToLigatureReader = exports.GposMarkToBaseReader = void 0;
const errors_1 = require("@ot-builder/errors");
const ot_layout_1 = require("@ot-builder/ot-layout");
const coverage_1 = require("../shared/coverage");
const gpos_anchor_1 = require("../shared/gpos-anchor");
const MarkArray = {
    read(view, marks, clsStart, cov, ctx) {
        const markCount = view.uint16();
        errors_1.Assert.SizeMatch(`MarkArray::markCount`, markCount, cov.length);
        for (const gidMark of cov) {
            const markClass = view.uint16();
            const markAnchor = view.next(gpos_anchor_1.Ptr16GposAnchor, ctx.ivs);
            const markGlyph = ctx.gOrd.at(gidMark);
            let rec = marks.get(markGlyph);
            if (!rec) {
                rec = { markAnchors: [] };
                marks.set(markGlyph, rec);
            }
            rec.markAnchors[markClass + clsStart] = markAnchor;
        }
    }
};
const BaseArray = {
    read(view, bases, clsStart, clsCount, cov, ctx) {
        const baseCount = view.uint16();
        errors_1.Assert.SizeMatch(`BaseArray::baseCount`, baseCount, cov.length);
        for (const gid of cov) {
            const baseGlyph = ctx.gOrd.at(gid);
            for (let cls = 0; cls < clsCount; cls++) {
                const anchor = view.next(gpos_anchor_1.NullablePtr16GposAnchor, ctx.ivs);
                let rec = bases.get(baseGlyph);
                if (!rec) {
                    rec = { baseAnchors: [] };
                    bases.set(baseGlyph, rec);
                }
                rec.baseAnchors[cls + clsStart] = anchor;
            }
        }
    }
};
const LigatureAttach = {
    read(view, bases, clsStart, clsCount, baseGlyph, ctx) {
        const componentCount = view.uint16();
        for (let componentID = 0; componentID < componentCount; componentID++) {
            for (let cls = 0; cls < clsCount; cls++) {
                const anchor = view.next(gpos_anchor_1.NullablePtr16GposAnchor, ctx.ivs);
                let rec = bases.get(baseGlyph);
                if (!rec) {
                    rec = { baseAnchors: [] };
                    bases.set(baseGlyph, rec);
                }
                if (!rec.baseAnchors[componentID])
                    rec.baseAnchors[componentID] = [];
                rec.baseAnchors[componentID][cls + clsStart] = anchor;
            }
        }
    }
};
const LigatureArray = {
    read(view, bases, clsStart, clsCount, cov, ctx) {
        const baseCount = view.uint16();
        errors_1.Assert.SizeMatch(`BaseArray::baseCount`, baseCount, cov.length);
        for (const gid of cov) {
            const baseGlyph = ctx.gOrd.at(gid);
            view.ptr16().next(LigatureAttach, bases, clsStart, clsCount, baseGlyph, ctx);
        }
    }
};
class GposMarkReaderBase {
    getStartClass(marks) {
        let sk = 0;
        for (const [glyph, rec] of marks) {
            for (let cls = 0; cls < rec.markAnchors.length; cls++) {
                if (rec.markAnchors[cls] && cls + 1 > sk)
                    sk = cls + 1;
            }
        }
        return sk;
    }
    readMarkToBaseSubtable(view, marks, bases, ctx) {
        const format = view.uint16();
        errors_1.Assert.FormatSupported(`MarkBasePosFormat1`, format, 1);
        const startClass = this.getStartClass(marks);
        const covMarks = view.next(coverage_1.Ptr16GidCoverage);
        const covBases = view.next(coverage_1.Ptr16GidCoverage);
        const markClassCount = view.uint16();
        view.ptr16().next(MarkArray, marks, startClass, covMarks, ctx);
        view.ptr16().next(BaseArray, bases, startClass, markClassCount, covBases, ctx);
    }
    readMarkToLigatureSubtable(view, marks, bases, ctx) {
        const format = view.uint16();
        errors_1.Assert.FormatSupported(`MarkLigPosFormat1`, format, 1);
        const startClass = this.getStartClass(marks);
        const covMarks = view.next(coverage_1.Ptr16GidCoverage);
        const covBases = view.next(coverage_1.Ptr16GidCoverage);
        const markClassCount = view.uint16();
        view.ptr16().next(MarkArray, marks, startClass, covMarks, ctx);
        view.ptr16().next(LigatureArray, bases, startClass, markClassCount, covBases, ctx);
    }
}
class GposMarkToBaseReader extends GposMarkReaderBase {
    createLookup() {
        return new ot_layout_1.Gpos.MarkToBase();
    }
    parseSubtable(view, lookup, ctx) {
        this.readMarkToBaseSubtable(view, lookup.marks, lookup.bases, ctx);
    }
}
exports.GposMarkToBaseReader = GposMarkToBaseReader;
class GposMarkToLigatureReader extends GposMarkReaderBase {
    createLookup() {
        return new ot_layout_1.Gpos.MarkToLigature();
    }
    parseSubtable(view, lookup, ctx) {
        this.readMarkToLigatureSubtable(view, lookup.marks, lookup.bases, ctx);
    }
}
exports.GposMarkToLigatureReader = GposMarkToLigatureReader;
class GposMarkToMarkReader extends GposMarkReaderBase {
    createLookup() {
        return new ot_layout_1.Gpos.MarkToMark();
    }
    parseSubtable(view, lookup, ctx) {
        this.readMarkToBaseSubtable(view, lookup.marks, lookup.baseMarks, ctx);
    }
}
exports.GposMarkToMarkReader = GposMarkToMarkReader;
//# sourceMappingURL=gpos-mark-read.js.map