Skip to content

Commit

Permalink
Let MuPDF resolve the nonexplicit PDF links
Browse files Browse the repository at this point in the history
Fixes #369.
  • Loading branch information
baskerville committed Jul 3, 2024
1 parent aa7d2e7 commit 737a387
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
12 changes: 12 additions & 0 deletions crates/core/src/document/mupdf_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ extern {
pub fn fz_run_page(ctx: *mut FzContext, page: *mut FzPage, dev: *mut FzDevice, mat: FzMatrix, cookie: *mut FzCookie);
pub fn mp_load_links(ctx: *mut FzContext, page: *mut FzPage) -> *mut FzLink;
pub fn fz_drop_link(ctx: *mut FzContext, link: *mut FzLink);
pub fn fz_resolve_link_dest(ctx: *mut FzContext, doc: *mut FzDocument, uri: *const libc::c_char) -> FzLinkDest;
pub fn mp_new_stext_page_from_page(ctx: *mut FzContext, page: *mut FzPage, options: *const FzTextOptions) -> *mut FzTextPage;
pub fn fz_drop_stext_page(ctx: *mut FzContext, tp: *mut FzTextPage);
pub fn fz_new_bbox_device(ctx: *mut FzContext, rect: *mut FzRect) -> *mut FzDevice;
Expand Down Expand Up @@ -144,6 +145,17 @@ pub struct FzTextOptions {
pub scale: libc::c_float,
}

#[repr(C)]
pub struct FzLinkDest {
pub loc: FzLocation,
pub kind: libc::c_int,
pub x: libc::c_float,
pub y: libc::c_float,
pub w: libc::c_float,
pub h: libc::c_float,
pub zoom: libc::c_float,
}

#[repr(C)]
pub struct FzPixmap {
storable: FzStorable,
Expand Down
40 changes: 40 additions & 0 deletions crates/core/src/document/pdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,46 @@ impl Document for PdfDocument {
unsafe { mp_count_pages(self.ctx.0, self.doc) as usize }
}

fn resolve_location(&mut self, loc: Location) -> Option<usize> {
if self.pages_count() == 0 {
return None;
}

match loc {
Location::Exact(index) => {
if index >= self.pages_count() {
None
} else {
Some(index)
}
},
Location::Previous(index) => {
if index > 0 {
Some(index - 1)
} else {
None
}
},
Location::Next(index) => {
if index < self.pages_count() - 1 {
Some(index + 1)
} else {
None
}
},
Location::LocalUri(_index, uri) => {
let c_uri = CString::new(uri).unwrap();
let dest = unsafe { fz_resolve_link_dest(self.ctx.0, self.doc, c_uri.as_ptr()) };
if dest.loc.page.is_positive() {
Some(dest.loc.page as usize)
} else {
None
}
},
_ => None,
}
}

fn pixmap(&mut self, loc: Location, scale: f32) -> Option<(Pixmap, usize)> {
let index = self.resolve_location(loc)?;
self.page(index).and_then(|page| page.pixmap(scale)).map(|pixmap| (pixmap, index))
Expand Down

0 comments on commit 737a387

Please sign in to comment.