mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-28 12:16:53 -06:00
Merge PR #860
This commit is contained in:
@@ -591,8 +591,11 @@ fn compose_with_db(doc: &Document, story: &Story, frames: &[FrameSpec], opts: &C
|
||||
.and_then(|t| t.chars().next_back())
|
||||
.and_then(break_start);
|
||||
if let Some(t) = story.para_table(pi) {
|
||||
let start = after_break.unwrap_or(pp.start_paragraph);
|
||||
if cur.last_baseline.is_some() {
|
||||
cur.start(after_break.unwrap_or(pp.start_paragraph), &cols, frames, doc);
|
||||
cur.start(start, &cols, frames, doc);
|
||||
} else {
|
||||
cur.start_at_top(start, frames, doc);
|
||||
}
|
||||
let at_top = cur.last_baseline.is_none();
|
||||
let start_at = (cur.fi, cur.col);
|
||||
@@ -847,17 +850,22 @@ fn compose_with_db(doc: &Document, story: &Story, frames: &[FrameSpec], opts: &C
|
||||
StartParagraph::NextColumn => next_column(cur),
|
||||
other => cur.start(other, &cols, frames, doc),
|
||||
};
|
||||
// Paragraph start options.
|
||||
if let Some(start) = after_break
|
||||
&& cur.last_baseline.is_some()
|
||||
{
|
||||
begin_at(&mut cur, start);
|
||||
// Paragraph start options. At the top of a frame there is nothing to break away from, but
|
||||
// an odd or even page start still has to land on a page of that parity.
|
||||
if let Some(start) = after_break {
|
||||
if cur.last_baseline.is_some() {
|
||||
begin_at(&mut cur, start);
|
||||
} else {
|
||||
cur.start_at_top(start, frames, doc);
|
||||
}
|
||||
}
|
||||
if force_col[pi] {
|
||||
next_column(&mut cur);
|
||||
}
|
||||
if cur.last_baseline.is_some() {
|
||||
begin_at(&mut cur, pp.start_paragraph);
|
||||
} else {
|
||||
cur.start_at_top(pp.start_paragraph, frames, doc);
|
||||
}
|
||||
if spanning && cur.fi < frames.len() {
|
||||
// Close the band: the paragraph goes below the deepest of its columns, which are
|
||||
@@ -2070,6 +2078,20 @@ impl Cursor {
|
||||
StartParagraph::NextEvenPage => self.next_page(frames, doc, Some(false)),
|
||||
}
|
||||
}
|
||||
/// A start option for a paragraph at the top of a frame: there is nothing to break away from,
|
||||
/// but an odd or even page start still has to land on a page of that parity, so a paragraph
|
||||
/// at the top of an even page that asks for the next odd page moves on (and vice versa).
|
||||
fn start_at_top(&mut self, start: StartParagraph, frames: &[FrameSpec], doc: &Document) {
|
||||
let want_odd = match start {
|
||||
StartParagraph::NextOddPage => true,
|
||||
StartParagraph::NextEvenPage => false,
|
||||
_ => return,
|
||||
};
|
||||
let Some(page) = frames.get(self.fi).and_then(|f| f.page) else { return };
|
||||
if (doc.page_number(page) % 2 == 1) != want_odd {
|
||||
self.next_page(frames, doc, Some(want_odd));
|
||||
}
|
||||
}
|
||||
/// Move to the next frame on a later page, one with an odd page number (`odd` true) or an
|
||||
/// even one (false) when asked. Frames without a page (parent pages) qualify; with no frame
|
||||
/// left, the rest of the story is overset.
|
||||
|
||||
@@ -834,6 +834,29 @@ fn break_characters_end_their_paragraph_and_keep_page_parity() {
|
||||
assert_eq!(cs.overset_at, Some(text.find("four").unwrap()));
|
||||
}
|
||||
|
||||
/// A paragraph that starts at the top of a frame isn't pushed on by Next Page, but Next Odd Page
|
||||
/// (or Next Even Page) still moves it when that frame is on a page of the other parity.
|
||||
#[test]
|
||||
fn odd_and_even_page_starts_keep_parity_at_the_top_of_a_frame() {
|
||||
use designcraft_doc::StartParagraph;
|
||||
use designcraft_doc::story::PAGE_BREAK;
|
||||
let pages_of = |start: StartParagraph| {
|
||||
let mut d = Document::new(&NewDocument { pages: 4, facing_pages: false, primary_text_frame: true, ..Default::default() });
|
||||
let sid = d.settings.primary_story.unwrap();
|
||||
// "two" begins at the top of page 2, after the page break that ends "one".
|
||||
d.story_mut(sid).unwrap().insert(0, &format!("one{PAGE_BREAK}\ntwo\nthree"));
|
||||
d.story_mut(sid).unwrap().paras[1].para.start_paragraph = Some(start);
|
||||
let cs = compose_story(&d, sid, &ComposeOptions::default());
|
||||
// Frame i is on page i + 1.
|
||||
cs.frames.iter().enumerate().flat_map(|(fi, f)| f.lines.iter().map(move |l| (l.para, fi + 1))).collect::<Vec<_>>()
|
||||
};
|
||||
// Already at the top of an even page: Next Page and Next Even Page leave "two" where it is.
|
||||
assert_eq!(pages_of(StartParagraph::NextPage), vec![(0, 1), (1, 2), (2, 2)]);
|
||||
assert_eq!(pages_of(StartParagraph::NextEvenPage), vec![(0, 1), (1, 2), (2, 2)]);
|
||||
// Next Odd Page takes it to page 3, leaving page 2 empty.
|
||||
assert_eq!(pages_of(StartParagraph::NextOddPage), vec![(0, 1), (1, 3), (2, 3)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn line_before_a_break_character_is_a_last_line() {
|
||||
// As in InDesign: column, frame and page breaks end the paragraph's last line (set with the
|
||||
|
||||
Reference in New Issue
Block a user