ultisuite-client/lib/drive/docs-ruler-units.ts
R3D347HR4Y 2a7c153748
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wrap page
2026-06-10 12:48:27 +02:00

59 lines
1.7 KiB
TypeScript

import { MM_TO_PX, type PageFormatId } from "@/lib/drive/page-formats"
import { DOCS_RULER_INCH_PX } from "@/lib/drive/docs-ruler-scale"
export type DocsRulerUnit = "cm" | "inch"
/** One centimetre in page coordinate space. */
export const DOCS_RULER_CM_PX = MM_TO_PX * 10
const INCH_FORMAT_IDS = new Set<PageFormatId>(["letter", "legal", "tabloid"])
const CM_FORMAT_IDS = new Set<PageFormatId>(["a4", "a5"])
export function resolveRulerUnit(formatId: PageFormatId): DocsRulerUnit {
if (INCH_FORMAT_IDS.has(formatId)) return "inch"
if (CM_FORMAT_IDS.has(formatId)) return "cm"
return "cm"
}
export type DocsRulerUnitConfig = {
unit: DocsRulerUnit
majorStepPx: number
minorDivisions: number
}
export function getRulerUnitConfig(formatId: PageFormatId): DocsRulerUnitConfig {
const unit = resolveRulerUnit(formatId)
if (unit === "inch") {
return {
unit,
majorStepPx: DOCS_RULER_INCH_PX,
minorDivisions: 8,
}
}
return {
unit,
majorStepPx: DOCS_RULER_CM_PX,
minorDivisions: 10,
}
}
export function formatRulerMajorLabel(value: number, unit: DocsRulerUnit): string {
if (value === 0) return "0"
const abs = Math.abs(value)
if (unit === "cm") {
return Number.isInteger(abs) ? String(value) : value.toFixed(1).replace(".", ",")
}
return Number.isInteger(abs) ? String(value) : String(Math.round(value * 10) / 10)
}
/** Margin distance from page edge, in the ruler unit for the page format. */
export function formatMarginDistanceLabel(
marginPx: number,
formatId: PageFormatId
): string {
const { unit, majorStepPx } = getRulerUnitConfig(formatId)
const value = marginPx / majorStepPx
const formatted = formatRulerMajorLabel(value, unit)
return unit === "inch" ? `${formatted}"` : `${formatted} cm`
}