Source: overlays/screenshot/screenshot-sizing.mjs

/**
 * Shared helpers for screenshot output sizing from a base (full-res) region size.
 */

export function computeOutputSize(baseW, baseH, factor) {
    const f = Number(factor);
    const bw = Number(baseW);
    const bh = Number(baseH);
    if (!Number.isFinite(f) || f <= 0) return { outW: 1, outH: 1 };
    const outW = Math.max(1, Math.round(bw / f));
    const outH = Math.max(1, Math.round(bh / f));
    return { outW, outH };
}

/**
 * Build preset power-of-two downsample options plus an "Other..." sentinel.
 */
export function buildDownsampleOptions({
    baseW,
    baseH,
    maxDim = 23767,
    maxArea = 268435456,
    factors = [1, 2, 4, 8, 16, 32],
} = {}) {
    const bw = Number(baseW);
    const bh = Number(baseH);
    const opts = [];

    factors.forEach((f) => {
        const factor = Number(f);
        if (!Number.isFinite(factor) || factor <= 0) return;
        const { outW, outH } = computeOutputSize(bw, bh, factor);
        let disabledReason = null;
        if (outW < 1 || outH < 1) disabledReason = 'Too small';
        else if (outW > maxDim || outH > maxDim) disabledReason = 'Exceeds maximum dimension';
        else if (outW * outH > maxArea) disabledReason = 'Exceeds maximum area';
        const disabled = disabledReason != null;
        opts.push({
            kind: 'factor',
            factor,
            outW,
            outH,
            disabled,
            disabledReason,
            label: `${outW} × ${outH} (${formatFractionLabel(factor)})`,
        });
    });

    opts.push({ kind: 'other' });
    return opts;
}

function formatFractionLabel(factor) {
    const f = Number(factor);
    if (!Number.isFinite(f) || f <= 0) return '';
    if (f === 1) return '1/1';
    // Prefer clean integers (2,4,8...) as 1/N
    if (Number.isInteger(f)) return `1/${f}`;
    return `d=${f}`;
}