"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readFont = readFont;
const io_bin_encoding_1 = require("@ot-builder/io-bin-encoding");
const io_bin_ext_private_1 = require("@ot-builder/io-bin-ext-private");
const io_bin_glyph_store_1 = require("@ot-builder/io-bin-glyph-store");
const io_bin_layout_1 = require("@ot-builder/io-bin-layout");
const io_bin_metadata_1 = require("@ot-builder/io-bin-metadata");
const io_bin_name_1 = require("@ot-builder/io-bin-name");
const io_bin_vtt_private_1 = require("@ot-builder/io-bin-vtt-private");
const Ot = require("@ot-builder/ot");
const config_1 = require("./config");
function readFont(sfnt, gsf, partialConfig = {}) {
    const fullCfg = (0, config_1.createConfig)(partialConfig);
    const md = (0, io_bin_metadata_1.readOtMetadata)(sfnt, fullCfg);
    const names = (0, io_bin_name_1.readNames)(sfnt);
    let gOrd, glyphs, coGlyphs, cffGlyphNaming = null;
    if (sfnt.tables.has(Ot.Cff.Tag1) || sfnt.tables.has(Ot.Cff.Tag2)) {
        const r = (0, io_bin_glyph_store_1.readGlyphStore)(sfnt, fullCfg, md, gsf, io_bin_glyph_store_1.ReadCffGlyphs);
        gOrd = r.gOrd;
        glyphs = r.glyphs;
        coGlyphs = { cff: r.coGlyphs.cff };
        cffGlyphNaming = r.coGlyphs.cffGlyphNaming;
    }
    else {
        const r = (0, io_bin_glyph_store_1.readGlyphStore)(sfnt, fullCfg, md, gsf, io_bin_glyph_store_1.ReadTtfGlyphs);
        gOrd = r.gOrd;
        glyphs = r.glyphs;
        coGlyphs = r.coGlyphs;
    }
    const encoding = (0, io_bin_encoding_1.readEncoding)(sfnt, fullCfg, gOrd, md);
    const otl = (0, io_bin_layout_1.readOtl)(sfnt, fullCfg, gOrd, md);
    const otExtPrivate = (0, io_bin_ext_private_1.readExtPrivate)(sfnt, fullCfg, gOrd, md);
    const otVttPrivate = (0, io_bin_vtt_private_1.readVttPrivate)(sfnt, fullCfg, gOrd, md);
    // Glyph name
    nameGlyphs(md, gOrd, cffGlyphNaming, encoding, fullCfg);
    return {
        ...md,
        ...names,
        glyphs,
        ...coGlyphs,
        ...encoding,
        ...otl,
        ...otExtPrivate,
        ...otVttPrivate
    };
}
function nameGlyphs(md, gOrd, cffGlyphNaming, encoding, cfg) {
    const namingSource = {
        post: md.postGlyphNaming ? new PostGlyphNamingWrapper(md.postGlyphNaming, gOrd) : null,
        cff: cffGlyphNaming,
        encoding: new CmapNameIndexSource(encoding)
    };
    const namer = cfg.glyphNaming.namer || new Ot.StandardGlyphNamer();
    for (let gid = 0; gid < gOrd.length; gid++) {
        const glyph = gOrd.at(gid);
        glyph.name = namer.nameGlyph(namingSource, gid, glyph);
    }
}
class PostGlyphNamingWrapper {
    constructor(postNaming, gOrd) {
        this.postNaming = postNaming;
        this.gOrd = gOrd;
    }
    getName(glyph) {
        const gid = this.gOrd.tryReverse(glyph);
        if (gid == null)
            return undefined;
        else
            return this.postNaming.getName(gid);
    }
}
class CmapNameIndexSource {
    constructor(encoding) {
        this.reverse = new Map();
        this.reverseVar = new Map();
        if (encoding.cmap) {
            const encodingList = [...encoding.cmap.unicode.entries()].sort((a, b) => a[0] - b[0]);
            for (const [uni, g] of encodingList) {
                if (!this.reverse.has(g))
                    this.reverse.set(g, uni);
            }
            const varEncodingList = [...encoding.cmap.vs.entries()].sort((a, b) => a[0] - b[0] || a[1] - b[1]);
            for (const [uni, vs, g] of varEncodingList) {
                if (!this.reverse.has(g))
                    this.reverseVar.set(g, [uni, vs]);
            }
        }
    }
    getIndex(glyph) {
        return this.reverse.get(glyph);
    }
    getVariantIndex(glyph) {
        return this.reverseVar.get(glyph);
    }
}
//# sourceMappingURL=read.js.map