"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sparseShareGlyfData = sparseShareGlyfData;
const tslib_1 = require("tslib");
const Crypto = tslib_1.__importStar(require("node:crypto"));
const sparse_common_1 = require("./sparse-common");
const IndexToLocFormatOffset = 50;
function sparseShareGlyfData(fonts, sharing) {
    const tasks = getGlyfTasks(fonts);
    if (!tasks.length)
        return;
    const shared = [];
    for (const task of tasks) {
        (0, sparse_common_1.pushGlyphs)(shared, task.fontID, task.glyphData, sharing);
    }
    const db = (0, sparse_common_1.buildDataBlock)(shared);
    for (const task of tasks) {
        const locaBuf = taskToLocaBuf(task, sharing, db);
        task.glyf.data = db.dataBlock;
        task.glyf.length = db.dataBlock.byteLength;
        task.glyf.start = 0;
        task.loca.data = locaBuf;
        task.loca.length = locaBuf.byteLength;
        task.loca.start = 0;
        task.head.data.writeUInt16BE(1, IndexToLocFormatOffset);
    }
}
function taskToLocaBuf(entry, sharing, db) {
    const sh = sharing[entry.fontID];
    const entryOffsets = [];
    for (let gid = 0; gid < entry.glyphData.length; gid++) {
        entryOffsets[gid] = db.offsets[db.saGidMaps[sh[gid]].get(entry.glyphData[gid].hash)];
    }
    entryOffsets.push(db.dataBlock.byteLength);
    const locaBuf = (0, sparse_common_1.buildOffsetIndex)(entryOffsets, true);
    return locaBuf;
}
function getGlyfTasks(fonts) {
    const entries = [];
    for (let fid = 0; fid < fonts.length; fid++) {
        const font = fonts[fid];
        const head = font.tables.get("head");
        const loca = font.tables.get("loca");
        const glyf = font.tables.get("glyf");
        if (!head || !loca || !glyf)
            continue;
        const glyphData = parseGlyphData(head, loca, glyf);
        entries.push({ fontID: fid, head, loca, glyf, glyphData });
    }
    return entries;
}
function parseGlyphData(head, loca, glyf) {
    const indexToLocFormat = head.data.readUInt16BE(IndexToLocFormatOffset);
    const bytesPerRecord = indexToLocFormat === 0 ? 2 : 4;
    const offsetCount = loca.data.byteLength / bytesPerRecord;
    const offsets = [];
    for (let j = 0; j < offsetCount; j++) {
        if (indexToLocFormat === 0)
            offsets[j] = 2 * loca.data.readUInt16BE(bytesPerRecord * j);
        else
            offsets[j] = loca.data.readUInt32BE(bytesPerRecord * j);
    }
    const glyphData = [];
    for (let j = 0; j < offsets.length - 1; j++) {
        const buf = glyf.data.slice(offsets[j], offsets[j + 1]);
        if (buf.length % 4)
            throw new Error("Unreachable! Glyf data blocks should be aligned.");
        glyphData[j] = { hash: computeHashBuf(buf), buffer: buf };
    }
    return glyphData;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
function computeHashBuf(buffer) {
    return Crypto.createHash("sha256").update(buffer).digest("hex");
}
//# sourceMappingURL=sparse-glyf-data-processor.js.map