feat: avoid doing extra work when --disable-pdf-tags is passed

This commit is contained in:
Tobias Schmitz 2025-07-24 18:03:10 +02:00
parent 820ea27a41
commit 50a280b6c2
No known key found for this signature in database
3 changed files with 47 additions and 13 deletions

View File

@ -124,7 +124,7 @@ fn convert_pages(gc: &mut GlobalContext, document: &mut Document) -> SourceResul
surface.finish(); surface.finish();
tags::add_annotations(gc, &mut page, fc.link_annotations); tags::add_link_annotations(gc, &mut page, fc.link_annotations);
} }
} }

View File

@ -50,11 +50,14 @@ pub(crate) fn handle_link(
} }
}; };
let Some((link_id, link, link_nodes)) = gc.tags.stack.find_parent_link() else { let (link_id, tagging_ctx) = match gc.tags.stack.find_parent_link() {
unreachable!("expected a link parent") Some((link_id, link, nodes)) => (link_id, Some((link, nodes))),
None if gc.options.disable_tags => {
let link_id = gc.tags.next_link_id();
(link_id, None)
}
None => unreachable!("expected a link parent"),
}; };
let alt = link.alt.as_ref().map(EcoString::to_string);
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,
@ -65,14 +68,20 @@ pub(crate) fn handle_link(
Some(annotation) if should_use_quadpoints => annotation.quad_points.push(quad), Some(annotation) if should_use_quadpoints => annotation.quad_points.push(quad),
_ => { _ => {
let placeholder = gc.tags.placeholders.reserve(); let placeholder = gc.tags.placeholders.reserve();
link_nodes.push(TagNode::Placeholder(placeholder)); let (alt, span) = if let Some((link, nodes)) = tagging_ctx {
nodes.push(TagNode::Placeholder(placeholder));
let alt = link.alt.as_ref().map(EcoString::to_string);
(alt, link.span)
} else {
(None, Span::detached())
};
fc.push_link_annotation(LinkAnnotation { fc.push_link_annotation(LinkAnnotation {
id: link_id, id: link_id,
placeholder, placeholder,
quad_points: vec![quad], quad_points: vec![quad],
alt, alt,
target, target,
span: link.span, span,
}); });
} }
} }

View File

@ -43,6 +43,10 @@ pub(crate) fn handle_start(
surface: &mut Surface, surface: &mut Surface,
elem: &Content, elem: &Content,
) -> SourceResult<()> { ) -> SourceResult<()> {
if gc.options.disable_tags {
return Ok(());
}
if gc.tags.in_artifact.is_some() { if gc.tags.in_artifact.is_some() {
// Don't nest artifacts // Don't nest artifacts
return Ok(()); return Ok(());
@ -187,6 +191,10 @@ pub(crate) fn handle_start(
} }
pub(crate) fn handle_end(gc: &mut GlobalContext, surface: &mut Surface, loc: Location) { pub(crate) fn handle_end(gc: &mut GlobalContext, surface: &mut Surface, loc: Location) {
if gc.options.disable_tags {
return;
}
if let Some((l, _)) = gc.tags.in_artifact { if let Some((l, _)) = gc.tags.in_artifact {
if l == loc { if l == loc {
pop_artifact(gc, surface); pop_artifact(gc, surface);
@ -316,6 +324,10 @@ fn pop_artifact(gc: &mut GlobalContext, surface: &mut Surface) {
} }
pub(crate) fn page_start(gc: &mut GlobalContext, surface: &mut Surface) { pub(crate) fn page_start(gc: &mut GlobalContext, surface: &mut Surface) {
if gc.options.disable_tags {
return;
}
if let Some((_, kind)) = gc.tags.in_artifact { if let Some((_, kind)) = gc.tags.in_artifact {
let ty = artifact_type(kind); let ty = artifact_type(kind);
let id = surface.start_tagged(ContentTag::Artifact(ty)); let id = surface.start_tagged(ContentTag::Artifact(ty));
@ -324,13 +336,17 @@ pub(crate) fn page_start(gc: &mut GlobalContext, surface: &mut Surface) {
} }
pub(crate) fn page_end(gc: &mut GlobalContext, surface: &mut Surface) { pub(crate) fn page_end(gc: &mut GlobalContext, surface: &mut Surface) {
if gc.options.disable_tags {
return;
}
if gc.tags.in_artifact.is_some() { if gc.tags.in_artifact.is_some() {
surface.end_tagged(); surface.end_tagged();
} }
} }
/// Add all annotations that were found in the page frame. /// Add all annotations that were found in the page frame.
pub(crate) fn add_annotations( pub(crate) fn add_link_annotations(
gc: &mut GlobalContext, gc: &mut GlobalContext,
page: &mut Page, page: &mut Page,
annotations: Vec<LinkAnnotation>, annotations: Vec<LinkAnnotation>,
@ -343,10 +359,15 @@ pub(crate) fn add_annotations(
alt, alt,
) )
.with_location(Some(span.into_raw().get())); .with_location(Some(span.into_raw().get()));
if gc.options.disable_tags {
page.add_annotation(annot);
} else {
let annot_id = page.add_tagged_annotation(annot); let annot_id = page.add_tagged_annotation(annot);
gc.tags.placeholders.init(placeholder, Node::Leaf(annot_id)); gc.tags.placeholders.init(placeholder, Node::Leaf(annot_id));
} }
} }
}
pub(crate) fn update_bbox( pub(crate) fn update_bbox(
gc: &mut GlobalContext, gc: &mut GlobalContext,
@ -372,10 +393,10 @@ pub(crate) struct Tags {
pub(crate) footnotes: HashMap<Location, TagNode>, pub(crate) footnotes: HashMap<Location, TagNode>,
pub(crate) in_artifact: Option<(Location, ArtifactKind)>, pub(crate) in_artifact: Option<(Location, ArtifactKind)>,
/// Used to group multiple link annotations using quad points. /// Used to group multiple link annotations using quad points.
pub(crate) link_id: LinkId, link_id: LinkId,
/// Used to generate IDs referenced in table `Headers` attributes. /// Used to generate IDs referenced in table `Headers` attributes.
/// The IDs must be document wide unique. /// The IDs must be document wide unique.
pub(crate) table_id: TableId, table_id: TableId,
/// The output. /// The output.
pub(crate) tree: Vec<TagNode>, pub(crate) tree: Vec<TagNode>,
@ -444,7 +465,7 @@ impl Tags {
true true
} }
fn next_link_id(&mut self) -> LinkId { pub(crate) fn next_link_id(&mut self) -> LinkId {
self.link_id.0 += 1; self.link_id.0 += 1;
self.link_id self.link_id
} }
@ -770,6 +791,10 @@ fn start_content<'a, 'b>(
surface: &'b mut Surface<'a>, surface: &'b mut Surface<'a>,
content: ContentTag, content: ContentTag,
) -> TagHandle<'a, 'b> { ) -> TagHandle<'a, 'b> {
if gc.options.disable_tags {
return TagHandle { surface, started: false };
}
let content = if gc.tags.in_artifact.is_some() { let content = if gc.tags.in_artifact.is_some() {
return TagHandle { surface, started: false }; return TagHandle { surface, started: false };
} else if let Some(StackEntryKind::Table(_)) = gc.tags.stack.last().map(|e| &e.kind) { } else if let Some(StackEntryKind::Table(_)) = gc.tags.stack.last().map(|e| &e.kind) {