mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-02 16:30:05 -06:00
Layout: a roman page number in the footer stays roman when the body shows the page count (#2966)
A paragraph with a PAGE field is cached by the page number, the totals, the section and the bookmarks, but not by the number format the field shows the page number in. Paginating lays the footer out to know where the body ends, before the section's number format is set in the field context, so as decimal. When the body shows NUMPAGES or SECTIONPAGES, the pass that has the right totals made that layout's key equal to the page's own footer's, and the cached decimal one was drawn: page 2 of a section numbered in lower-case roman showed "2", not "ii". The number format is now part of the key. Co-authored-by: dfgodvan <180286157+dfgodvan@users.noreply.github.com>
This commit is contained in:
@@ -63,8 +63,8 @@ impl FieldCtx {
|
||||
self.page_from.iter().rev().find(|(from, _)| *from <= off).map_or(self.page, |(_, page)| *page)
|
||||
}
|
||||
/// A key for caches: the parts of the context a page-dependent paragraph depends on.
|
||||
pub fn page_key(&self) -> (u32, u32, u32, u32, u64) {
|
||||
(self.page, self.pages, self.section_pages, self.section, self.bookmarks_key)
|
||||
pub fn page_key(&self) -> (u32, u32, u32, u32, u64, NumFormat) {
|
||||
(self.page, self.pages, self.section_pages, self.section, self.bookmarks_key, self.page_format)
|
||||
}
|
||||
/// A key for caches of paragraph `p` with STYLEREF fields (0 when they show their stored
|
||||
/// result): a hash of the results its STYLEREF fields have on this page, so an edit to body
|
||||
|
||||
@@ -503,7 +503,7 @@ struct Key {
|
||||
rev: u64,
|
||||
width: u32,
|
||||
label: Option<String>,
|
||||
page: Option<(u32, u32, u32, u32, u64)>,
|
||||
page: Option<(u32, u32, u32, u32, u64, wordcraft_doc::section::NumFormat)>,
|
||||
/// The pages a split paragraph's fields are on after its first (`FieldCtx::page_from`).
|
||||
page_from: u64,
|
||||
table: u64,
|
||||
|
||||
@@ -530,3 +530,41 @@ fn footer_border_limits_body() {
|
||||
assert!(page.body.bottom() <= top + 0.01, "body {}, footer stroke {top}", page.body.bottom());
|
||||
}
|
||||
}
|
||||
|
||||
/// A section numbering its pages in lower-case roman shows them so in its footer when the body
|
||||
/// shows the page count (`NUMPAGES`): the footer laid out while paginating, before the section's
|
||||
/// number format is known, isn't taken for the page's own footer.
|
||||
#[test]
|
||||
fn a_roman_page_number_in_the_footer_stays_roman_with_the_page_count_in_the_body() {
|
||||
let field = |instr: &str| InlineObject::Field {
|
||||
instr: instr.into(),
|
||||
result: String::new(),
|
||||
locked: false,
|
||||
dirty: false,
|
||||
code: false,
|
||||
form: String::new(),
|
||||
};
|
||||
let mut d = Document::new();
|
||||
let mut fp = Paragraph::new();
|
||||
fp.insert_object(0, field("PAGE"), &Default::default()).unwrap();
|
||||
let id = d.add_part(PartKind::Footer, vec![para_block(fp)]);
|
||||
d.last_section.footers.default = Some(id);
|
||||
let mut np = Paragraph::with_text(" pages", Default::default());
|
||||
np.insert_object(0, field("NUMPAGES"), &Default::default()).unwrap();
|
||||
d.body = vec![para_block(np)];
|
||||
d.body.extend(paras(&"word ".repeat(40), 40));
|
||||
let mut end = Paragraph::with_text("end", Default::default());
|
||||
end.section = Some(Box::new(d.last_section.clone()));
|
||||
d.body.push(para_block(end));
|
||||
d.body.extend(paras(&"word ".repeat(40), 120));
|
||||
d.last_section.page_num_start = Some(1);
|
||||
d.last_section.page_num_format = wordcraft_doc::section::NumFormat::LowerRoman;
|
||||
let l = lay(&d);
|
||||
let roman: Vec<_> = l.pages.iter().filter(|p| p.section == 1).collect();
|
||||
assert!(roman.len() > 5);
|
||||
for p in roman {
|
||||
let glyphs: usize = p.footer.iter().map(|it| if let Placed::Lines { para, .. } = it { para.glyphs.len() } else { 0 }).sum();
|
||||
let want = wordcraft_doc::section::NumFormat::LowerRoman.format(p.number);
|
||||
assert_eq!(glyphs, want.chars().count(), "page {}: the footer should show {want}", p.number);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user