refactor: revert some changes to FrameItem::Link

This commit is contained in:
Tobias Schmitz 2025-06-25 15:08:08 +02:00
parent 2d6e3b6151
commit 4894a227d2
No known key found for this signature in database
7 changed files with 29 additions and 30 deletions

View File

@ -36,9 +36,9 @@ pub fn jump_from_click(
) -> Option<Jump> {
// Try to find a link first.
for (pos, item) in frame.items() {
if let FrameItem::Link(link, size) = item {
if let FrameItem::Link(dest, size) = item {
if is_in_rect(*pos, *size, click) {
return Some(match &link.dest {
return Some(match dest {
Destination::Url(url) => Jump::Url(url.clone()),
Destination::Position(pos) => Jump::Position(*pos),
Destination::Location(loc) => {

View File

@ -1,6 +1,6 @@
use typst_library::foundations::{LinkMarker, Packed, StyleChain};
use typst_library::foundations::StyleChain;
use typst_library::layout::{Abs, Fragment, Frame, FrameItem, HideElem, Point, Sides};
use typst_library::model::ParElem;
use typst_library::model::{Destination, LinkElem, ParElem};
/// Frame-level modifications resulting from styles that do not impose any
/// layout structure.
@ -20,7 +20,7 @@ use typst_library::model::ParElem;
#[derive(Debug, Clone)]
pub struct FrameModifiers {
/// A destination to link to.
link: Option<Packed<LinkMarker>>,
dest: Option<Destination>,
/// Whether the contents of the frame should be hidden.
hidden: bool,
}
@ -28,9 +28,8 @@ pub struct FrameModifiers {
impl FrameModifiers {
/// Retrieve all modifications that should be applied per-frame.
pub fn get_in(styles: StyleChain) -> Self {
// TODO: maybe verify that an alt text was provided here
Self {
link: LinkMarker::current_in(styles),
dest: LinkElem::current_in(styles),
hidden: HideElem::hidden_in(styles),
}
}
@ -95,7 +94,7 @@ fn modify_frame(
modifiers: &FrameModifiers,
link_box_outset: Option<Sides<Abs>>,
) {
if let Some(link) = &modifiers.link {
if let Some(dest) = &modifiers.dest {
let mut pos = Point::zero();
let mut size = frame.size();
if let Some(outset) = link_box_outset {
@ -103,7 +102,7 @@ fn modify_frame(
pos.x -= outset.left;
size += outset.sum_by_axis();
}
frame.push(pos, FrameItem::Link(link.clone(), size));
frame.push(pos, FrameItem::Link(dest.clone(), size));
}
if modifiers.hidden {
@ -130,8 +129,8 @@ where
let reset;
let outer = styles;
let mut styles = styles;
if modifiers.link.is_some() {
reset = LinkMarker::set_current(None).wrap();
if modifiers.dest.is_some() {
reset = LinkElem::set_current(None).wrap();
styles = outer.chain(&reset);
}

View File

@ -21,7 +21,7 @@ use crate::foundations::{
};
use crate::introspection::{Locatable, Location};
use crate::layout::{AlignElem, Alignment, Axes, Length, MoveElem, PadElem, Rel, Sides};
use crate::model::{Destination, EmphElem, StrongElem};
use crate::model::{Destination, EmphElem, LinkElem, StrongElem};
use crate::pdf::{ArtifactElem, ArtifactKind};
use crate::text::UnderlineElem;
@ -506,11 +506,10 @@ impl Content {
/// Link the content somewhere.
pub fn linked(self, dest: Destination, alt: Option<EcoString>) -> Self {
let span = self.span();
let link = Packed::new(LinkMarker::new(self, dest, alt));
link.clone()
LinkMarker::new(self, dest.clone(), alt)
.pack()
.spanned(span)
.styled(LinkMarker::set_current(Some(link)))
.styled(LinkElem::set_current(Some(dest)))
}
/// Set alignments for this content.
@ -1002,11 +1001,6 @@ pub struct LinkMarker {
pub dest: Destination,
#[required]
pub alt: Option<EcoString>,
/// A link style that should be applied to elements.
#[internal]
#[ghost]
pub current: Option<Packed<LinkMarker>>,
}
impl Show for Packed<LinkMarker> {

View File

@ -7,9 +7,10 @@ use std::sync::Arc;
use typst_syntax::Span;
use typst_utils::{LazyHash, Numeric};
use crate::foundations::{cast, dict, Dict, Label, LinkMarker, Packed, Value};
use crate::foundations::{cast, dict, Dict, Label, Value};
use crate::introspection::{Location, Tag};
use crate::layout::{Abs, Axes, FixedAlignment, Length, Point, Size, Transform};
use crate::model::Destination;
use crate::text::TextItem;
use crate::visualize::{Color, Curve, FixedStroke, Geometry, Image, Paint, Shape};
@ -472,7 +473,7 @@ pub enum FrameItem {
/// An image and its size.
Image(Image, Size, Span),
/// An internal or external link to a destination.
Link(Packed<LinkMarker>, Size),
Link(Destination, Size),
/// An introspectable element that produced something within this frame.
Tag(Tag),
}
@ -484,7 +485,7 @@ impl Debug for FrameItem {
Self::Text(text) => write!(f, "{text:?}"),
Self::Shape(shape, _) => write!(f, "{shape:?}"),
Self::Image(image, _, _) => write!(f, "{image:?}"),
Self::Link(link, _) => write!(f, "Link({:?}, {:?})", link.dest, link.alt),
Self::Link(dest, _) => write!(f, "Link({dest:?})"),
Self::Tag(tag) => write!(f, "{tag:?}"),
}
}

View File

@ -91,6 +91,11 @@ pub struct LinkElem {
_ => args.expect("body")?,
})]
pub body: Content,
/// A destination style that should be applied to elements.
#[internal]
#[ghost]
pub current: Option<Destination>,
}
impl LinkElem {

View File

@ -281,7 +281,7 @@ pub(crate) fn handle_frame(
FrameItem::Image(image, size, span) => {
handle_image(gc, fc, image, *size, surface, *span)?
}
FrameItem::Link(link, size) => handle_link(fc, gc, link, *size),
FrameItem::Link(dest, size) => handle_link(fc, gc, dest, *size),
FrameItem::Tag(Tag::Start(elem)) => tags::handle_start(gc, elem),
FrameItem::Tag(Tag::End(loc, _)) => tags::handle_end(gc, *loc),
}

View File

@ -5,7 +5,6 @@ use krilla::action::{Action, LinkAction};
use krilla::annotation::Target;
use krilla::destination::XyzDestination;
use krilla::geom as kg;
use typst_library::foundations::LinkMarker;
use typst_library::layout::{Abs, Point, Position, Size};
use typst_library::model::Destination;
@ -24,10 +23,10 @@ pub(crate) struct LinkAnnotation {
pub(crate) fn handle_link(
fc: &mut FrameContext,
gc: &mut GlobalContext,
link: &LinkMarker,
dest: &Destination,
size: Size,
) {
let target = match &link.dest {
let target = match dest {
Destination::Url(u) => {
Target::Action(Action::Link(LinkAction::new(u.to_string())))
}
@ -51,14 +50,15 @@ pub(crate) fn handle_link(
};
let entry = gc.tags.stack.last_mut().expect("a link parent");
let StackEntryKind::Link(link_id, _) = entry.kind else {
let StackEntryKind::Link(link_id, link) = &entry.kind else {
unreachable!("expected a link parent")
};
let alt = link.alt.as_ref().map(EcoString::to_string);
let rect = to_rect(fc, size);
let quadpoints = quadpoints(rect);
match fc.link_annotations.entry(link_id) {
match fc.link_annotations.entry(*link_id) {
Entry::Occupied(occupied) => {
// Update the bounding box and add the quadpoints of an existing link annotation.
let annotation = occupied.into_mut();
@ -73,7 +73,7 @@ pub(crate) fn handle_link(
placeholder,
rect,
quad_points: quadpoints.to_vec(),
alt: link.alt.as_ref().map(EcoString::to_string),
alt,
target,
});
}