refactor(engine): move the bookmark list rows to bookmarks.rs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
alehel
2026-10-25 23:08:14 +01:00
co-authored by Claude Opus 5.5
parent 20974e7822
commit 4972a4e1eb
2 changed files with 64 additions and 60 deletions
+61
View File
@@ -0,0 +1,61 @@
//! The bookmark list.
/// A bookmark as the bookmark list shows it.
#[derive(Clone, Debug, PartialEq)]
pub struct BookmarkRow {
/// Child indices from the top level, 0-based, as the edit functions take them.
pub path: Vec<usize>,
pub title: String,
/// Shown expanded (a positive `/Count`).
pub open: bool,
/// The 0-based page it goes to.
pub page: Option<usize>,
/// Where on that page it goes ([`pdfcraft_render::DestView::Top`] when it doesn't say).
pub view: pdfcraft_render::DestView,
/// The title's colour (`/C`), `None` for the default black, and its style (`/F`).
pub color: Option<[f32; 3]>,
pub italic: bool,
pub bold: bool,
}
/// One page of the bookmark list, in outline order.
#[derive(Clone, Debug, PartialEq)]
pub struct BookmarkPage {
pub rows: Vec<BookmarkRow>,
/// Where the next page starts, or `None` at the end.
pub next: Option<usize>,
/// Set only when the document's structure could not be read for editing: its listing then
/// comes from the viewer's copy of the outline, which is shorter than the file's.
pub truncated: bool,
}
/// The rows of a viewer outline, in outline order, with their paths.
pub(crate) fn outline_rows(items: &[pdfcraft_render::OutlineItem]) -> Vec<BookmarkRow> {
let mut rows = Vec::new();
// One entry per open level: its items, and how many of them have been listed.
let mut levels: Vec<(&[pdfcraft_render::OutlineItem], usize)> = vec![(items, 0)];
while let Some(&(list, next)) = levels.last() {
let Some(item) = list.get(next) else {
levels.pop();
continue;
};
if let Some(top) = levels.last_mut() {
top.1 += 1;
}
let path: Vec<usize> = levels.iter().map(|(_, listed)| listed.saturating_sub(1)).collect();
rows.push(BookmarkRow {
path,
title: item.title.clone(),
open: item.open,
page: item.page,
view: item.view,
color: item.color,
italic: item.italic,
bold: item.bold,
});
if !item.children.is_empty() {
levels.push((&item.children, 0));
}
}
rows
}
+3 -60
View File
@@ -14,6 +14,7 @@
pub mod actions;
pub mod autotag;
mod bookmarks;
pub mod build_info;
pub mod camera;
pub mod camera_clean;
@@ -189,6 +190,8 @@ fn record_link_scan() {
});
}
use bookmarks::outline_rows;
pub use bookmarks::{BookmarkPage, BookmarkRow};
use comments::comment_list;
pub use comments::{SummarySort, comment_kind, comment_summary, comment_type_name};
pub use document::{Document, TextNotice, display_bytes_for, render_password_for};
@@ -273,66 +276,6 @@ fn apply_layer_state(layers: &mut [Layer], groups: &[Vec<(u32, u16)>], changes:
layers.iter().zip(before).any(|(l, was)| l.visible != was)
}
/// A bookmark as the bookmark list shows it.
#[derive(Clone, Debug, PartialEq)]
pub struct BookmarkRow {
/// Child indices from the top level, 0-based, as the edit functions take them.
pub path: Vec<usize>,
pub title: String,
/// Shown expanded (a positive `/Count`).
pub open: bool,
/// The 0-based page it goes to.
pub page: Option<usize>,
/// Where on that page it goes ([`pdfcraft_render::DestView::Top`] when it doesn't say).
pub view: pdfcraft_render::DestView,
/// The title's colour (`/C`), `None` for the default black, and its style (`/F`).
pub color: Option<[f32; 3]>,
pub italic: bool,
pub bold: bool,
}
/// One page of the bookmark list, in outline order.
#[derive(Clone, Debug, PartialEq)]
pub struct BookmarkPage {
pub rows: Vec<BookmarkRow>,
/// Where the next page starts, or `None` at the end.
pub next: Option<usize>,
/// Set only when the document's structure could not be read for editing: its listing then
/// comes from the viewer's copy of the outline, which is shorter than the file's.
pub truncated: bool,
}
/// The rows of a viewer outline, in outline order, with their paths.
fn outline_rows(items: &[pdfcraft_render::OutlineItem]) -> Vec<BookmarkRow> {
let mut rows = Vec::new();
// One entry per open level: its items, and how many of them have been listed.
let mut levels: Vec<(&[pdfcraft_render::OutlineItem], usize)> = vec![(items, 0)];
while let Some(&(list, next)) = levels.last() {
let Some(item) = list.get(next) else {
levels.pop();
continue;
};
if let Some(top) = levels.last_mut() {
top.1 += 1;
}
let path: Vec<usize> = levels.iter().map(|(_, listed)| listed.saturating_sub(1)).collect();
rows.push(BookmarkRow {
path,
title: item.title.clone(),
open: item.open,
page: item.page,
view: item.view,
color: item.color,
italic: item.italic,
bold: item.bold,
});
if !item.children.is_empty() {
levels.push((&item.children, 0));
}
}
rows
}
/// A document's working file captured for crash recovery.
#[derive(Clone, Debug)]
pub struct RecoverySnapshot {