Files
houseplan-card/docs/PDF-EXPORT.md
T
Claude 4bc3e9baa6 docs(hygiene): ARCHITECTURE.md — карта, а не хроника (#680)
Волна 3 эпика #674. ARCHITECTURE.md 2330 → 653 строки: система координат
прототипа 1489×1053, разделы Hidden Isometric Stage 2/4 (текущее — ISOMETRIC.md,
история — ADR 122/570), хроники «Additions v1.28–v1.41» и «Audit follow-ups»
сняты; подсистемы — короткое описание со ссылкой на канонический документ.
Устаревшее исправлено по коду: дерево Layout (store.py, frontend_registration,
весь список модулей), хранилища (config, layout, virtual_lights, trails),
ленивые локали de и fr, таблица WS API (31 + 3 команды, #256-проекция,
space/delete, files/cleanup без keep, контент через /api/houseplan/content),
DevItem без несуществующих полей, отказ help/feedback по support_api.

Всё ещё верное и не записанное в другом месте перенесено в канонические
документы: DEVICE-PRESENTATION (заметки реализации, Action authority, черновик
диалога), RADAR (карта реализации), VACUUM (владение кодом), CANVAS (icon_size,
--hp-cell-visual-scale, барьер записи координат), FILTERING (#44, каталог),
DECOR-EDITOR §7 (инварианты бэкенда ассетов), WALL-THICKNESS (§1 идентичность
и нулевые стены, §2 кэши, §4 hover/туннели/острова, §6 удаление комнаты,
§9 failed-core, §11 завершение цепочки и комната по грани), ISOMETRIC
(isoPlaneMatrix, iso-overlays, створки, служебные атрибуты), LIGHT (Glow над
заливкой #55, формула и screen-смешение), CONFIG-COMPATIBILITY (манифест схемы
#33, Masonry-слоты #561, квадратный холст v1.48, устаревшие URL контента,
layout/set #356), SCOPE (таблица владельцев при сборке файлов), WARM-REMOUNT
§5 (холодная загрузка и визуальная непрерывность), UX-MODES (порядок
стартового пространства), PDF-EXPORT (граница реализации), FURNITURE (adopt,
BOOT_MAX_MS). Раздел TESTING «Backend quality gates (#42)» и строка
DEVELOPMENT о bundle-freshness — из того же разбора, в предыдущем коммите.

Issue: #680
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
2026-09-27 22:33:04 +03:00

102 lines
5.2 KiB
Markdown

# PDF export
House Plan can save the current space as a one-page A4 architectural PDF.
For administrators, the printer button appears in the card header between
**General settings** and **Help & feedback**. The export is always a flat plan,
even when the card currently uses the isometric view.
![PDF export options](images/10-pdf-export.png)
The PDF always contains the physical architecture: walls, partitions, columns,
zero-thickness walls and door, window, gate and passage openings. Device
markers, Home Assistant states, Glow, sunlight, vacuum trails, room colours and
Zigbee topology are intentionally excluded.
The dialog can additionally include:
- room dimensions and clean floor areas;
- room names;
- furniture and other Background-editor decor;
- the current space backdrop, when one is configured.
The selected options are remembered in this browser. The export reads the
current plan but never changes it.
The dialog is designed to remain usable down to a 320 CSS px-wide View area.
It does not require horizontal scrolling; on narrow screens its actions stack
vertically while retaining touch-sized controls.
## Sheet and measurement rules
The output is a single A4 sheet. House Plan builds the complete print scene
first — architecture, enabled dimensions, names, decor and backdrop — and then
chooses portrait or landscape and the smallest standard scale that fits all of
it. The complete scene is centred on the usable sheet,
so optional content is not pushed into a fixed reserve or left outside the
centred area. The footer shows the scale, a 1 m or 5 ft scale bar, a vector
compass when north is configured, the date and the House Plan version. There
is no architectural symbol legend.
For unusually large plans, House Plan continues the scale series in steps of
50 until the complete scene fits. If the architecture itself cannot fit on one
A4 sheet at any scale, export stops with an error instead of producing a
clipped file.
Physical walls, partitions and columns use a `#7f7f7f` base with a consistent
45-degree hatch. Openings remain clean cut-outs through both the base and the
hatch. Zero-thickness walls keep the existing dashed print convention and are
not hatched.
Areas use the same clean-floor geometry as the room information card. Internal
dimensions follow the inner wall faces; external dimensions follow the outer
physical outline. Only horizontal and vertical measurements are printed;
genuinely diagonal edges are omitted rather than projected into misleading
dimensions. Within one room contour or one connected outer ring, equivalent
opposite measurements are shown once on the side with more free space. Equal
lengths in different rooms, disconnected rings or unrelated walls are never
deduplicated globally. Labels are centred on their measured wall and arranged
in consistent lanes clear of the wall body. Units follow Home Assistant. Very
short internal edges use a tick instead of unreadable text. A value that has no
room beside its own wall is not printed at all: it is never pushed through a
wall, a room name or an area, and it is not moved to a separate list beside the
plan: a separate list would cost the drawing a whole step of the scale series
and turn the sheet sideways.
For a rectangular step in an exterior facade, the chain retains enough
horizontal and vertical values to reconstruct the outline: both neighbouring
facade sections, the step height and one copy of its depth. An extension line
may leave the physical corner to which it belongs, including a short
collinear/solid prefix, but it is rejected if it touches architecture again
after reaching free space. This narrow source-corner rule prevents both lost
step dimensions and dimension lines drawn through another wall.
## Images, fonts and limits
Backdrop and decor images are embedded locally in the browser. They are not
sent to a conversion service. Embedded image data is limited to 25 MB; an
unavailable image or exceeded limit stops the export and leaves the dialog open
so the options can be changed.
Text uses an embedded subset of Roboto Regular covering the four House Plan
interface languages. The bundled font is distributed under the Apache License
2.0; its license is stored in `assets/fonts/LICENSE`.
The resulting file is named
`houseplan-<space-name>-<YYYY-MM-DD>.pdf`. Browser and Home Assistant mobile-app
download handling determines its final Downloads location.
## Implementation boundary
PDF export is a lazy read-only runtime (`src/pdf/`, `lazyPdfFiles`); View
carries only the administrator trigger and the shared exact-build loader. It
reads the already normalised current space through the same physical-geometry
resolvers as View, produces one deterministic A4 document and never writes
config or layout. Dimension input is normalised before collinear compaction and
keeps only canonical horizontal/vertical edges; text bounds use the writer's
real font metrics and transform; lanes test exact box/segment intersections
against wall rings, never sampled points; parallel facade steps stay in
independent collinear groups. Only exterior extension lines use the
source-aware collision state machine; dimension lines, shelves, labels and
internal dimensions stay on the strict path. Physical walls are even-odd clipped
paths with a page-anchored hatch.