mirror of
https://github.com/typst/typst
synced 2025-08-03 01:37:54 +08:00
refactor: clean up link annotation code
This commit is contained in:
parent
6d0c4c620d
commit
5ebe5490b5
@ -213,10 +213,7 @@ impl FrameContext {
|
||||
&mut self,
|
||||
link_id: tags::LinkId,
|
||||
) -> Option<&mut LinkAnnotation> {
|
||||
self.link_annotations
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find(|annot| annot.id == link_id)
|
||||
self.link_annotations.iter_mut().rfind(|a| a.id == link_id)
|
||||
}
|
||||
|
||||
pub(crate) fn push_link_annotation(&mut self, annotation: LinkAnnotation) {
|
||||
|
@ -9,11 +9,11 @@ use typst_library::model::Destination;
|
||||
use typst_syntax::Span;
|
||||
|
||||
use crate::convert::{FrameContext, GlobalContext};
|
||||
use crate::tags::{self, Placeholder, TagNode};
|
||||
use crate::tags::{LinkId, Placeholder, TagNode};
|
||||
use crate::util::{AbsExt, PointExt};
|
||||
|
||||
pub(crate) struct LinkAnnotation {
|
||||
pub(crate) id: tags::LinkId,
|
||||
pub(crate) id: LinkId,
|
||||
pub(crate) placeholder: Placeholder,
|
||||
pub(crate) alt: Option<String>,
|
||||
pub(crate) quad_points: Vec<kg::Quadrilateral>,
|
||||
@ -60,12 +60,19 @@ pub(crate) fn handle_link(
|
||||
};
|
||||
let quad = to_quadrilateral(fc, size);
|
||||
|
||||
// Unfortunately quadpoints still aren't well supported by most PDF readers,
|
||||
// even by acrobat. Which is understandable since they were only introduced
|
||||
// in PDF 1.6 (2005) /s
|
||||
let should_use_quadpoints = gc.options.standards.config.validator() == Validator::UA1;
|
||||
// Unfortunately quadpoints still aren't well supported by most PDF readers.
|
||||
// So only add multiple quadpoint entries to one annotation when targeting
|
||||
// PDF/UA. Otherwise generate multiple annotations, to avoid pdf readers
|
||||
// falling back to the bounding box rectangle, which can span parts unrelated
|
||||
// to the link. For example if there is a linebreak:
|
||||
// ```
|
||||
// Imagine this is a paragraph containing a link. It starts here https://github.com/
|
||||
// typst/typst and then ends on another line.
|
||||
// ```
|
||||
// The bounding box would span the entire paragraph, which is undesirable.
|
||||
let join_annotations = gc.options.standards.config.validator() == Validator::UA1;
|
||||
match fc.get_link_annotation(link_id) {
|
||||
Some(annotation) if should_use_quadpoints => annotation.quad_points.push(quad),
|
||||
Some(annotation) if join_annotations => annotation.quad_points.push(quad),
|
||||
_ => {
|
||||
let placeholder = gc.tags.placeholders.reserve();
|
||||
let (alt, span) = if let Some((link, nodes)) = tagging_ctx {
|
||||
|
@ -434,20 +434,21 @@ pub(crate) fn add_link_annotations(
|
||||
page: &mut Page,
|
||||
annotations: Vec<LinkAnnotation>,
|
||||
) {
|
||||
for annotation in annotations.into_iter() {
|
||||
let LinkAnnotation { id: _, placeholder, alt, quad_points, target, span } =
|
||||
annotation;
|
||||
let annot = krilla::annotation::Annotation::new_link(
|
||||
krilla::annotation::LinkAnnotation::new_with_quad_points(quad_points, target),
|
||||
alt,
|
||||
for a in annotations.into_iter() {
|
||||
let annotation = krilla::annotation::Annotation::new_link(
|
||||
krilla::annotation::LinkAnnotation::new_with_quad_points(
|
||||
a.quad_points,
|
||||
a.target,
|
||||
),
|
||||
a.alt,
|
||||
)
|
||||
.with_location(Some(span.into_raw().get()));
|
||||
.with_location(Some(a.span.into_raw()));
|
||||
|
||||
if gc.options.disable_tags {
|
||||
page.add_annotation(annot);
|
||||
page.add_annotation(annotation);
|
||||
} else {
|
||||
let annot_id = page.add_tagged_annotation(annot);
|
||||
gc.tags.placeholders.init(placeholder, Node::Leaf(annot_id));
|
||||
let annot_id = page.add_tagged_annotation(annotation);
|
||||
gc.tags.placeholders.init(a.placeholder, Node::Leaf(annot_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user