"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CffTopDictIndexWrite = exports.CffTopDictIo = exports.CffTopDictWrite = exports.CffTopDictRead = exports.CffTopDictDataCollector = exports.CffTopDictInterpreter = void 0;
const bin_util_1 = require("@ot-builder/bin-util");
const errors_1 = require("@ot-builder/errors");
const ot_glyphs_1 = require("@ot-builder/ot-glyphs");
const variance_1 = require("@ot-builder/variance");
const write_1 = require("../cff-index/write");
const draw_call_1 = require("../char-string/write/draw-call");
const operator_1 = require("../interp/operator");
const font_dict_1 = require("./font-dict");
const general_1 = require("./general");
class CffTopDictInterpreter extends font_dict_1.CffFontDictInterpreterBase {
    constructor(ctx) {
        super(ctx);
        this.td = new CffTopDictRead(this.fd);
    }
    doOperator(opCode, flags) {
        switch (opCode) {
            case operator_1.CffOperator.CharStrings:
                this.td.vCharStrings = this.ctx.vwCffTable.lift(variance_1.OtVar.Ops.originOf(this.st.pop()));
                break;
            case operator_1.CffOperator.FDArray:
                this.td.vFDArray = this.ctx.vwCffTable.lift(variance_1.OtVar.Ops.originOf(this.st.pop()));
                break;
            case operator_1.CffOperator.FDSelect:
                this.td.vFDSelect = this.ctx.vwCffTable.lift(variance_1.OtVar.Ops.originOf(this.st.pop()));
                break;
            case operator_1.CffOperator.VStore:
                this.td.vVarStore = this.ctx.vwCffTable.lift(variance_1.OtVar.Ops.originOf(this.st.pop()));
                break;
            case operator_1.CffOperator.Charset:
                this.td.vCharSet = this.ctx.vwCffTable.lift(variance_1.OtVar.Ops.originOf(this.st.pop()));
                break;
            case operator_1.CffOperator.Encoding:
                this.st.pop(); // Ignore
                break;
            case operator_1.CffOperator.ROS: {
                const cid = new ot_glyphs_1.Cff.CID();
                cid.supplement = variance_1.OtVar.Ops.originOf(this.st.pop());
                cid.ordering = this.popString();
                cid.registry = this.popString();
                this.td.cidROS = cid;
                break;
            }
            default:
                return super.doOperator(opCode, flags);
        }
    }
    getResult() {
        return this.td;
    }
}
exports.CffTopDictInterpreter = CffTopDictInterpreter;
class CffTopDictDataCollector extends general_1.CffDictDataCollector {
    constructor() {
        super(...arguments);
        this.fdDC = new font_dict_1.CffFontDictDataCollector();
    }
    *collectDrawCalls(td, ctx, rest) {
        if (td.cidROS) {
            if (!ctx.strings)
                throw errors_1.Errors.Cff.ShouldHaveStrings();
            yield new draw_call_1.CffDrawCallRaw([
                ctx.strings.push(td.cidROS.registry),
                ctx.strings.push(td.cidROS.ordering),
                td.cidROS.supplement
            ], operator_1.CffOperator.ROS);
        }
        yield* this.fdDC.collectDrawCalls(td.fd, ctx, rest);
        if (ctx.version <= 1) {
            const bBox = ctx.stat.fontBBox.getResult();
            yield new draw_call_1.CffDrawCallRaw([bBox.xMin, bBox.yMin, bBox.xMax, bBox.yMax], operator_1.CffOperator.FontBBox);
        }
        if (ctx.upm !== 1000) {
            yield new draw_call_1.CffDrawCallRaw([1 / ctx.upm, 0, 0, 1 / ctx.upm, 0, 0], operator_1.CffOperator.FontMatrix);
        }
    }
    processPointers(encoder, td, ctx, rest) {
        this.fdDC.processPointers(encoder, td.fd, ctx, rest);
        if (td.fgVarStore)
            encoder.absPointer(td.fgVarStore, operator_1.CffOperator.VStore);
        if (td.fgCharSet)
            encoder.absPointer(td.fgCharSet, operator_1.CffOperator.Charset);
        if (td.fgCharStrings)
            encoder.absPointer(td.fgCharStrings, operator_1.CffOperator.CharStrings);
        if (td.fgFDSelect)
            encoder.absPointer(td.fgFDSelect, operator_1.CffOperator.FDSelect);
        if (td.fgFDArray)
            encoder.absPointer(td.fgFDArray, operator_1.CffOperator.FDArray);
    }
}
exports.CffTopDictDataCollector = CffTopDictDataCollector;
class CffTopDictRead {
    constructor(fd) {
        this.fd = fd;
        this.cidROS = null;
        this.vCharStrings = null;
        this.vFDArray = null;
        this.vFDSelect = null;
        this.vVarStore = null;
        this.vCharSet = null;
        this.vEncoding = null;
    }
}
exports.CffTopDictRead = CffTopDictRead;
class CffTopDictWrite {
    constructor(fd) {
        this.fd = fd;
        this.fgCharStrings = null;
        this.fgFDArray = null;
        this.fgFDSelect = null;
        this.fgVarStore = null;
        this.fgCharSet = null;
        this.cidROS = null;
    }
}
exports.CffTopDictWrite = CffTopDictWrite;
exports.CffTopDictIo = {
    ...(0, general_1.CffDictReadT)((viewDict, ctx) => new CffTopDictInterpreter(ctx)),
    ...(0, general_1.CffDictWriteT)(new CffTopDictDataCollector())
};
const CffGeneralTopDictIndexWrite = new write_1.CffWriteIndex({
    write: (f, fd, ctx) => f.push(exports.CffTopDictIo, fd, ctx, undefined)
});
exports.CffTopDictIndexWrite = {
    ...(0, bin_util_1.Write)((frag, td, ctx) => {
        return frag.push(CffGeneralTopDictIndexWrite, [td], ctx);
    })
};
//# sourceMappingURL=top.js.map