/* ============================================================================= * spreadsheet_autofit.ts (2단계 · 주인 sub_laptop_1) * 열 머리 경계를 두 번 눌러 폭 자동 맞춤 — 그 열 안 글자 수로 어림(엑셀 「글자 단위」). * 진짜 픽셀 값은 C(격자)가 쓰는 글꼴로 재야 더 정확 — `measure` 자리에 C 의 실제 재기 함수를 * 나중에 꽂을 수 있게 열어 둠(안 주면 아래 어림 규칙을 씀). * * 잇는 법(D · sub7 · C 격자 머리) — 열 머리 경계에서 두 번 누르면(dblclick) * `autofitColumn(ctx, col)` 을 부름. C 가 완성되면 `measure` 자리에 캔버스 `measureText` 를 넘겨 더 정밀하게. * * ── 이미 계약에 있어 새 파일이 필요 없는 것(붙일 자리만 확인) ────────────────────── * · 여러 범위(Ctrl+누르기) — `spreadsheet_view_types.ts` `Selection.범위` 가 이미 배열(D `spreadsheet_selection.ts` 가 씀). * · 눈금선 끄기 — `Command`(`종류:"눈금선"`) · `Sheet.보기?.눈금선` 이미 있음(A 가 처리). * · 확대 · 축소 — 값 자체를 저장하지 않는 화면 전용 CSS 배율(C 격자 뿌리에 transform) · 계약 밖. * ========================================================================== */ import type { Workbook } from "./spreadsheet_types"; import type { SpreadsheetContext } from "./spreadsheet_view_types"; export type TextMeasurer = (text: string) => number; const PADDING = 2; const MIN_WIDTH = 4; /** 글꼴을 모를 때 어림 — 한글 · 한자 · 전각은 1.9 배 폭 · 나머지는 1 배. */ const defaultMeasure: TextMeasurer = (text) => { let width = 0; for (const ch of text) width += ch.codePointAt(0)! >= 0x1100 ? 1.9 : 1; return width; }; const colFromKey = (key: string): number => { const m = /^([A-Z]+)\d+$/.exec(key); if (!m) return -1; let col = 0; for (const ch of m[1]) col = col * 26 + (ch.charCodeAt(0) - 64); return col - 1; }; /** 그 열에 든 칸 글자(식 칸은 식 글로 어림 — 계산값은 여기서 모름) 중 가장 넓은 것 + 여백. */ export function estimateColumnWidth( book: Workbook, sheetId: string, col: number, measure: TextMeasurer = defaultMeasure, ): number { const sheet = book.시트.find((s) => s.id === sheetId); if (!sheet) return MIN_WIDTH; let widest = 0; for (const [key, cell] of Object.entries(sheet.칸)) { if (colFromKey(key) !== col) continue; const text = cell.식 !== undefined ? cell.식 : cell.값 !== undefined ? String(cell.값) : ""; if (text) widest = Math.max(widest, measure(text)); } return Math.max(MIN_WIDTH, Math.ceil(widest + PADDING)); } /** 폭을 자동 맞춤 값으로 바꿈(열넓이 명령 하나). */ export function autofitColumn(ctx: SpreadsheetContext, col: number, measure?: TextMeasurer): void { const width = estimateColumnWidth(ctx.book, ctx.selection.시트, col, measure); ctx.dispatch({ 종류: "열폭", 시트: ctx.selection.시트, 열: [col], 폭: width }); }