* fix(draw-image): use density 72 for 1024x1024 PNG output * test(draw-image): assert real PNG dimensions via IHDR decode * chore(assets): regenerate cover.png at 1024x1024 * docs(handoff): add handoff and ADR for density fix * docs(handoff): set PR number --------- Co-authored-by: opencode-agent <agent@opencode.local>
3.4 KiB
3.4 KiB
| pr | title |
|---|---|
| 161 | fix(draw-image): use density 72 for 1024x1024 PNG output |
Что сделано
Фикс размера PNG draw-image (issue #159) — три изменения:
- density 96 → 72 —
.opencode/draw-image/render.mjs:36:sharp(Buffer.from(svg), { density: 72 }). При density:96 SVG 1024×1024 (поviewBox, 1in=72pt) рендерился как 1024 × 96/72 = 1365px. При density:72 → 1024 × 72/72 = 1024px ровно. - Реальные assertions размеров PNG — пустые проверки заменены на decode PNG IHDR chunk (width bytes 16-19, height bytes 20-23, big-endian uint32):
tests/e2e.test.tsassertPng1024— добавленыexpect(width).toBe(1024)+expect(height).toBe(1024).tests/render.integration.test.tsтест"renders valid PNG 1024x1024"— добавлены width/height assertions (были только magic bytes).tests/render.optional.integration.test.tsassertPng— добавлены width/height assertions.
- Регенерация assets/cover.png — удалены старые
assets/cover.png+cover.meta.json, перерендерены черезdraw-imagetool (template=cover, icon=opencode, subtitle). Проверено черезsharp().metadata(): 1024×1024 (было 1365×1365).
Тесты: npx vitest run в .opencode/draw-image/ → 55/55 passed (5 прогонов подряд стабильно). Все обновлённые assertions реально проверяют 1024×1024 через IHDR decode.
Почему
density: 96 — историческое значение, дававшее 33% оверсайз (1365 вместо 1024). PNG cover используется в README и slaid098.dev showcase — 1365px ломал layout и не соответствовал контракту meta.size: 1024 в cli.ts:78. Пустые assertions (только magic bytes, без width/height) маскировали баг — тесты «проходили» на 1365×1365, хотя в имени функции буквально assertPng1024. Density 72 — canonical значение для SVG-to-PNG при viewBox в pt (1pt = 1/72in), дающее pixel-perfect 1024×1024.
Pending
—
Watch out
- Существующий race condition на
.tmp-render.svg—cli.ts:64пишет shared temp SVG в__dirname. При параллельных CLI-вызовах (vitest concurrent) или leftover от ручных прогонов →render.mjsпадает сInput Buffer is empty. Это отдельный баг, заведён issue #160 (вне scope #159). На стабильных прогонах (clean tmp) не проявляется. Не чинить в этом PR. - Density-фикс меняет хэш всех PNG (
computeHashне зависит от density, ноgeneratedAtи пиксели differ) → все cached PNG будут перерендерены при следующем вызове CLI (meta.json hash не меняется, но если файл удалён — re-render).cover.meta.jsonперегенерирован. buf.readUInt32BE(16)/buf.readUInt32BE(20)— PNG IHDR fixed offset (8 signature + 4 length + 4 "IHDR" = 16 для width, 20 для height). Работает только для стандартных PNG (sharp всегда пишет IHDR первым chunk'ом).