fix: a header or footer takes the document's font, not the editor's

The zone was pinned to Liberation Serif 12pt, so a run whose font the
file leaves to the default — every page-number field in a fixture
fixture — rendered serif inside an Arial footer. Both formats base the
Header/Footer style on the default paragraph style, so the zone now
takes its text half.
This commit is contained in:
Steffen Becker committed 2026-08-11 20:58:29 +00:00
1 parent 95d174501d
commit 5969795d04
3 files changed
+10 -3

No files matched your search

+1 -1
View File
@@ -48,7 +48,7 @@ Both anchors differ: a wheel zoom holds the **point under the cursor** fixed (`p
One header and one footer (`HfDoc` = a single-paragraph TipTap doc per zone, persisted to `odf-editor-header`/`-footer`), repeated on every page. Double-clicking a page margin — or the Layout-panel "Edit header/footer" buttons — opens the zone for editing; clicking back into the body (`onFocus`) or Escape ends it. The edge→zone distance (header from top, footer from bottom) is user-configurable in cm via the Layout panel (`HfDistances`, persisted to `odf-editor-hf-distances`, default `HF_DISTANCE_CM` 1.27cm, clamped 0–10 and below the body margin).
- **Fields:** the bar beside the active zone inserts the `pageField.ts` atoms — page number, page count, chapter (the running head, level 1). Each is patched per page, so the same zone shows a different value on every page.
- **Rendering:** `HeaderFooterLayer.svelte` mounts inside the scaled `.paper` (like `.band-layer`), positioning per-page zone boxes in unscaled doc px. A zone's out-of-flow frame (`wrap` ≠ inline) is hidden in the box and painted per page by `.hf-bg-layer` at `z-index: -1` — hence `.paper`, not `.tiptap`, paints the page surface, so the image lands between the sheet and the body text. Inactive zones render as static HTML (`generateHTML` + `hfExtensions`); the active zone hosts the single live TipTap editor. `App.svelte`'s `activeEditor`/`activeTick` route the top toolbars to `hfEditor` while a zone is active, so all body formatting works on the header/footer with no toolbar changes.
- **Rendering:** the zone's own font is the document's **default paragraph style** (`styleCss` gives `.paper .hf-layer .hf-zone` its text half): both formats base the Header/Footer style on it, so a file whose body is Arial 10pt has an Arial footer, not the editor's serif. `HeaderFooterLayer.svelte` mounts inside the scaled `.paper` (like `.band-layer`), positioning per-page zone boxes in unscaled doc px. A zone's out-of-flow frame (`wrap` ≠ inline) is hidden in the box and painted per page by `.hf-bg-layer` at `z-index: -1` — hence `.paper`, not `.tiptap`, paints the page surface, so the image lands between the sheet and the body text. Inactive zones render as static HTML (`generateHTML` + `hfExtensions`); the active zone hosts the single live TipTap editor. `App.svelte`'s `activeEditor`/`activeTick` route the top toolbars to `hfEditor` while a zone is active, so all body formatting works on the header/footer with no toolbar changes.
## Debug tooling (dev only)
+3 -1
View File
@@ -526,7 +526,9 @@
min-height: 0;
width: 100%;
background: none !important;
font-size: 12pt;
/* The zone's own size, which follows the document's default style — not the 12pt
`.paper .tiptap` puts on the body. */
font-size: inherit;
line-height: 1.15;
outline: none;
/* Keep the editable root at its content height (min-height:0 would otherwise let
+6 -1
View File
@@ -291,7 +291,12 @@ export function styleCss(sheet: StyleSheet): string {
const text = textDeclarations(resolveStyle(sheet, style.name).text);
if (!text.length) continue;
const items = [`.paper .tiptap li:has(> ${attr})`];
if (style.name === DEFAULT_STYLE) items.push('.paper .tiptap li:has(> p:not([data-style]))');
if (style.name === DEFAULT_STYLE) {
items.push('.paper .tiptap li:has(> p:not([data-style]))');
// A header/footer zone is a paragraph of the file too, and both formats base its
// style on the default one — without this it renders in the editor's own font.
items.push('.paper .hf-layer .hf-zone');
}
rules.push(`${items.join(',\n')} {\n ${text.join(';\n ')};\n}`);
}
// Table styles last: their cell selectors must outrank the paragraph rules above.