mirror of
https://github.com/typst/typst
synced 2025-07-27 14:27:56 +08:00
feat: mark all shapes as artifacts
This commit is contained in:
parent
e3c0855a2b
commit
a495724813
@ -1,6 +1,7 @@
|
|||||||
use krilla::geom::{Path, PathBuilder, Rect};
|
use krilla::geom::{Path, PathBuilder, Rect};
|
||||||
use krilla::surface::Surface;
|
use krilla::surface::Surface;
|
||||||
use typst_library::diag::SourceResult;
|
use typst_library::diag::SourceResult;
|
||||||
|
use typst_library::pdf::ArtifactKind;
|
||||||
use typst_library::visualize::{Geometry, Shape};
|
use typst_library::visualize::{Geometry, Shape};
|
||||||
use typst_syntax::Span;
|
use typst_syntax::Span;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ pub(crate) fn handle_shape(
|
|||||||
gc: &mut GlobalContext,
|
gc: &mut GlobalContext,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
let mut handle = tags::start_marked(gc, surface);
|
let mut handle = tags::start_artifact(gc, surface, ArtifactKind::Other);
|
||||||
let surface = handle.surface();
|
let surface = handle.surface();
|
||||||
|
|
||||||
surface.set_location(span.into_raw().get());
|
surface.set_location(span.into_raw().get());
|
||||||
|
@ -45,10 +45,10 @@ pub(crate) fn handle_start(
|
|||||||
|
|
||||||
if let Some(artifact) = elem.to_packed::<ArtifactElem>() {
|
if let Some(artifact) = elem.to_packed::<ArtifactElem>() {
|
||||||
let kind = artifact.kind.get(StyleChain::default());
|
let kind = artifact.kind.get(StyleChain::default());
|
||||||
start_artifact(gc, surface, loc, kind);
|
push_artifact(gc, surface, loc, kind);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Some(_) = elem.to_packed::<RepeatElem>() {
|
} else if let Some(_) = elem.to_packed::<RepeatElem>() {
|
||||||
start_artifact(gc, surface, loc, ArtifactKind::Other);
|
push_artifact(gc, surface, loc, ArtifactKind::Other);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ pub(crate) fn handle_start(
|
|||||||
// first page. Maybe it should be the cell on the last page, but that
|
// first page. Maybe it should be the cell on the last page, but that
|
||||||
// would require more changes in the layouting code, or a pre-pass
|
// would require more changes in the layouting code, or a pre-pass
|
||||||
// on the frames to figure out if there are other footers following.
|
// on the frames to figure out if there are other footers following.
|
||||||
start_artifact(gc, surface, loc, ArtifactKind::Other);
|
push_artifact(gc, surface, loc, ArtifactKind::Other);
|
||||||
} else {
|
} else {
|
||||||
push_stack(gc, loc, StackEntryKind::TableCell(cell.clone()))?;
|
push_stack(gc, loc, StackEntryKind::TableCell(cell.clone()))?;
|
||||||
}
|
}
|
||||||
@ -125,29 +125,10 @@ pub(crate) fn handle_start(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_stack(
|
|
||||||
gc: &mut GlobalContext,
|
|
||||||
loc: Location,
|
|
||||||
kind: StackEntryKind,
|
|
||||||
) -> SourceResult<()> {
|
|
||||||
if !gc.tags.context_supports(&kind) {
|
|
||||||
if gc.options.standards.config.validator() == Validator::UA1 {
|
|
||||||
// TODO: error
|
|
||||||
} else {
|
|
||||||
// TODO: warning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gc.tags.stack.push(StackEntry { loc, kind, nodes: Vec::new() });
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
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 let Some((l, _)) = gc.tags.in_artifact {
|
if let Some((l, _)) = gc.tags.in_artifact {
|
||||||
if l == loc {
|
if l == loc {
|
||||||
surface.end_tagged();
|
pop_artifact(gc, surface);
|
||||||
gc.tags.in_artifact = None;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -205,6 +186,41 @@ pub(crate) fn handle_end(gc: &mut GlobalContext, surface: &mut Surface, loc: Loc
|
|||||||
gc.tags.push(node);
|
gc.tags.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_stack(
|
||||||
|
gc: &mut GlobalContext,
|
||||||
|
loc: Location,
|
||||||
|
kind: StackEntryKind,
|
||||||
|
) -> SourceResult<()> {
|
||||||
|
if !gc.tags.context_supports(&kind) {
|
||||||
|
if gc.options.standards.config.validator() == Validator::UA1 {
|
||||||
|
// TODO: error
|
||||||
|
} else {
|
||||||
|
// TODO: warning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gc.tags.stack.push(StackEntry { loc, kind, nodes: Vec::new() });
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_artifact(
|
||||||
|
gc: &mut GlobalContext,
|
||||||
|
surface: &mut Surface,
|
||||||
|
loc: Location,
|
||||||
|
kind: ArtifactKind,
|
||||||
|
) {
|
||||||
|
let ty = artifact_type(kind);
|
||||||
|
let id = surface.start_tagged(ContentTag::Artifact(ty));
|
||||||
|
gc.tags.push(TagNode::Leaf(id));
|
||||||
|
gc.tags.in_artifact = Some((loc, kind));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop_artifact(gc: &mut GlobalContext, surface: &mut Surface) {
|
||||||
|
surface.end_tagged();
|
||||||
|
gc.tags.in_artifact = None;
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn page_start(gc: &mut GlobalContext, surface: &mut Surface) {
|
pub(crate) fn page_start(gc: &mut GlobalContext, surface: &mut Surface) {
|
||||||
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);
|
||||||
@ -452,6 +468,17 @@ pub(crate) fn start_span<'a, 'b>(
|
|||||||
start_content(gc, surface, ContentTag::Span(span))
|
start_content(gc, surface, ContentTag::Span(span))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a [`TagHandle`] that automatically calls [`Surface::end_tagged`]
|
||||||
|
/// when dropped.
|
||||||
|
pub(crate) fn start_artifact<'a, 'b>(
|
||||||
|
gc: &mut GlobalContext,
|
||||||
|
surface: &'b mut Surface<'a>,
|
||||||
|
kind: ArtifactKind,
|
||||||
|
) -> TagHandle<'a, 'b> {
|
||||||
|
let ty = artifact_type(kind);
|
||||||
|
start_content(gc, surface, ContentTag::Artifact(ty))
|
||||||
|
}
|
||||||
|
|
||||||
fn start_content<'a, 'b>(
|
fn start_content<'a, 'b>(
|
||||||
gc: &mut GlobalContext,
|
gc: &mut GlobalContext,
|
||||||
surface: &'b mut Surface<'a>,
|
surface: &'b mut Surface<'a>,
|
||||||
@ -471,18 +498,6 @@ fn start_content<'a, 'b>(
|
|||||||
TagHandle { surface, started: true }
|
TagHandle { surface, started: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_artifact(
|
|
||||||
gc: &mut GlobalContext,
|
|
||||||
surface: &mut Surface,
|
|
||||||
loc: Location,
|
|
||||||
kind: ArtifactKind,
|
|
||||||
) {
|
|
||||||
let ty = artifact_type(kind);
|
|
||||||
let id = surface.start_tagged(ContentTag::Artifact(ty));
|
|
||||||
gc.tags.push(TagNode::Leaf(id));
|
|
||||||
gc.tags.in_artifact = Some((loc, kind));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn artifact_type(kind: ArtifactKind) -> ArtifactType {
|
fn artifact_type(kind: ArtifactKind) -> ArtifactType {
|
||||||
match kind {
|
match kind {
|
||||||
ArtifactKind::Header => ArtifactType::Header,
|
ArtifactKind::Header => ArtifactType::Header,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user