"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetricVarianceIo = 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 var_store_1 = require("@ot-builder/var-store");
const variance_1 = require("@ot-builder/variance");
exports.MetricVarianceIo = {
    ...(0, bin_util_1.Read)((view, maxp, designSpace, isVertical) => {
        const mv = new ot_glyphs_1.MetricVariance.Table(isVertical);
        for (let gid = 0; gid < maxp.numGlyphs; gid++) {
            mv.measures[gid] = new ot_glyphs_1.MetricVariance.Measure();
        }
        const majorVersion = view.uint16();
        const minorVersion = view.uint16();
        errors_1.Assert.SubVersionSupported("HMTX/VMTX", majorVersion, minorVersion, [1, 0]);
        const pIVS = view.ptr32();
        const ivs = pIVS.next(var_store_1.ReadTimeIVS, designSpace);
        // Mapping list
        const vAdvance = view.ptr32Nullable();
        if (vAdvance) {
            vAdvance.next(var_store_1.DeltaSetIndexMap, {
                nMappingsNeeded: mv.measures.length,
                addMapping(gid, outer, inner) {
                    mv.measures[gid].advance = ivs.queryValue(outer, inner);
                }
            });
        }
        else {
            for (let gid = 0; gid < mv.measures.length; gid++) {
                mv.measures[gid].advance = ivs.queryValue(0, gid);
            }
        }
        // Skip, we don't need them.
        const vStartSB = view.ptr32Nullable();
        const vEndSB = view.ptr32Nullable();
        // Read VORG if necessary
        const vVorg = mv.isVertical ? view.ptr32Nullable() : null;
        if (vVorg) {
            vVorg.next(var_store_1.DeltaSetIndexMap, {
                nMappingsNeeded: mv.measures.length,
                addMapping(gid, outer, inner) {
                    mv.measures[gid].start = ivs.queryValue(outer, inner);
                }
            });
        }
        return mv;
    }),
    ...(0, bin_util_1.Write)((frag, mv, designSpace, pEmpty) => {
        // No axes present in font, reject
        if (!designSpace.length)
            throw errors_1.Errors.Variation.NoAxes();
        errors_1.Assert.NoGap("HVAR/VVAR measures", mv.measures);
        const ms = new variance_1.OtVar.MasterSet();
        const ivs = var_store_1.WriteTimeIVS.create(ms);
        const mFallback = new variance_1.OtVar.Master([
            {
                dim: designSpace.at(0),
                min: 0,
                peak: 1,
                max: 1
            }
        ]);
        let empty = true;
        const advanceMap = [];
        const originMap = [];
        for (let gid = 0; gid < mv.measures.length; gid++) {
            if (!variance_1.OtVar.Ops.isConstant(mv.measures[gid].advance))
                empty = false;
            advanceMap[gid] = ivs.valueToInnerOuterIDForce(mv.measures[gid].advance, mFallback);
        }
        if (mv.isVertical) {
            for (let gid = 0; gid < mv.measures.length; gid++) {
                if (!variance_1.OtVar.Ops.isConstant(mv.measures[gid].start))
                    empty = false;
                originMap[gid] = ivs.valueToInnerOuterIDForce(mv.measures[gid].start, mFallback);
            }
        }
        if (pEmpty)
            pEmpty.set(empty);
        frag.uint16(1).uint16(0); // Format
        frag.ptr32(bin_util_1.Frag.from(var_store_1.WriteTimeIVS, ivs, { designSpace })); // itemVariationStoreOffset
        frag.ptr32(bin_util_1.Frag.from(var_store_1.DeltaSetIndexMap, false, advanceMap)); // Advance mappings
        frag.ptr32(null); // LSB/RSB/TSB/BSB mappings are always set to empty
        frag.ptr32(null); // due to the limitation of OTVAR variation (no min/max functions)
        if (mv.isVertical)
            frag.ptr32(bin_util_1.Frag.from(var_store_1.DeltaSetIndexMap, false, originMap)); // VORG mappings
    })
};
//# sourceMappingURL=metric-variance.js.map