mirror of
https://github.com/typst/typst
synced 2025-08-03 09:47: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,
|
&mut self,
|
||||||
link_id: tags::LinkId,
|
link_id: tags::LinkId,
|
||||||
) -> Option<&mut LinkAnnotation> {
|
) -> Option<&mut LinkAnnotation> {
|
||||||
self.link_annotations
|
self.link_annotations.iter_mut().rfind(|a| a.id == link_id)
|
||||||
.iter_mut()
|
|
||||||
.rev()
|
|
||||||
.find(|annot| annot.id == link_id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_link_annotation(&mut self, annotation: LinkAnnotation) {
|
pub(crate) fn push_link_annotation(&mut self, annotation: LinkAnnotation) {
|
||||||
|
@ -9,11 +9,11 @@ use typst_library::model::Destination;
|
|||||||
use typst_syntax::Span;
|
use typst_syntax::Span;
|
||||||
|
|
||||||
use crate::convert::{FrameContext, GlobalContext};
|
use crate::convert::{FrameContext, GlobalContext};
|
||||||
use crate::tags::{self, Placeholder, TagNode};
|
use crate::tags::{LinkId, Placeholder, TagNode};
|
||||||
use crate::util::{AbsExt, PointExt};
|
use crate::util::{AbsExt, PointExt};
|
||||||
|
|
||||||
pub(crate) struct LinkAnnotation {
|
pub(crate) struct LinkAnnotation {
|
||||||
pub(crate) id: tags::LinkId,
|
pub(crate) id: LinkId,
|
||||||
pub(crate) placeholder: Placeholder,
|
pub(crate) placeholder: Placeholder,
|
||||||
pub(crate) alt: Option<String>,
|
pub(crate) alt: Option<String>,
|
||||||
pub(crate) quad_points: Vec<kg::Quadrilateral>,
|
pub(crate) quad_points: Vec<kg::Quadrilateral>,
|
||||||
@ -60,12 +60,19 @@ pub(crate) fn handle_link(
|
|||||||
};
|
};
|
||||||
let quad = to_quadrilateral(fc, size);
|
let quad = to_quadrilateral(fc, size);
|
||||||
|
|
||||||
// Unfortunately quadpoints still aren't well supported by most PDF readers,
|
// Unfortunately quadpoints still aren't well supported by most PDF readers.
|
||||||
// even by acrobat. Which is understandable since they were only introduced
|
// So only add multiple quadpoint entries to one annotation when targeting
|
||||||
// in PDF 1.6 (2005) /s
|
// PDF/UA. Otherwise generate multiple annotations, to avoid pdf readers
|
||||||
let should_use_quadpoints = gc.options.standards.config.validator() == Validator::UA1;
|
// 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) {
|
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 placeholder = gc.tags.placeholders.reserve();
|
||||||
let (alt, span) = if let Some((link, nodes)) = tagging_ctx {
|
let (alt, span) = if let Some((link, nodes)) = tagging_ctx {
|
||||||
|
@ -434,20 +434,21 @@ pub(crate) fn add_link_annotations(
|
|||||||
page: &mut Page,
|
page: &mut Page,
|
||||||
annotations: Vec<LinkAnnotation>,
|
annotations: Vec<LinkAnnotation>,
|
||||||
) {
|
) {
|
||||||
for annotation in annotations.into_iter() {
|
for a in annotations.into_iter() {
|
||||||
let LinkAnnotation { id: _, placeholder, alt, quad_points, target, span } =
|
let annotation = krilla::annotation::Annotation::new_link(
|
||||||
annotation;
|
krilla::annotation::LinkAnnotation::new_with_quad_points(
|
||||||
let annot = krilla::annotation::Annotation::new_link(
|
a.quad_points,
|
||||||
krilla::annotation::LinkAnnotation::new_with_quad_points(quad_points, target),
|
a.target,
|
||||||
alt,
|
),
|
||||||
|
a.alt,
|
||||||
)
|
)
|
||||||
.with_location(Some(span.into_raw().get()));
|
.with_location(Some(a.span.into_raw()));
|
||||||
|
|
||||||
if gc.options.disable_tags {
|
if gc.options.disable_tags {
|
||||||
page.add_annotation(annot);
|
page.add_annotation(annotation);
|
||||||
} else {
|
} else {
|
||||||
let annot_id = page.add_tagged_annotation(annot);
|
let annot_id = page.add_tagged_annotation(annotation);
|
||||||
gc.tags.placeholders.init(placeholder, Node::Leaf(annot_id));
|
gc.tags.placeholders.init(a.placeholder, Node::Leaf(annot_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user