diff --git a/crates/core/src/document/mupdf_sys.rs b/crates/core/src/document/mupdf_sys.rs index 79eef0c..2bcac49 100644 --- a/crates/core/src/document/mupdf_sys.rs +++ b/crates/core/src/document/mupdf_sys.rs @@ -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; @@ -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, diff --git a/crates/core/src/document/pdf.rs b/crates/core/src/document/pdf.rs index 90798c3..e7ce642 100644 --- a/crates/core/src/document/pdf.rs +++ b/crates/core/src/document/pdf.rs @@ -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 { + 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))