summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/export/pdf.rs10
-rw-r--r--src/frame.rs28
-rw-r--r--src/library/text/link.rs21
-rw-r--r--src/model/locate.rs27
4 files changed, 41 insertions, 45 deletions
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index 5e8896f7..c050bfc5 100644
--- a/src/export/pdf.rs
+++ b/src/export/pdf.rs
@@ -333,14 +333,14 @@ impl<'a> PdfExporter<'a> {
.action_type(ActionType::Uri)
.uri(Str(uri.as_str().as_bytes()));
}
- Destination::Internal(page, point) => {
- let page = page - 1;
- let height = page_heights[page];
+ Destination::Internal(loc) => {
+ let index = loc.page - 1;
+ let height = page_heights[index];
link.action()
.action_type(ActionType::GoTo)
.destination_direct()
- .page(page_refs[page])
- .xyz(point.x.to_f32(), height - point.y.to_f32(), None);
+ .page(page_refs[index])
+ .xyz(loc.pos.x.to_f32(), height - loc.pos.y.to_f32(), None);
}
}
}
diff --git a/src/frame.rs b/src/frame.rs
index 289de6da..2ece5147 100644
--- a/src/frame.rs
+++ b/src/frame.rs
@@ -3,6 +3,7 @@
use std::fmt::{self, Debug, Formatter, Write};
use std::sync::Arc;
+use crate::eval::{Dict, Value};
use crate::font::FaceId;
use crate::geom::{
Align, Em, Length, Numeric, Paint, Point, Shape, Size, Spec, Transform,
@@ -313,21 +314,30 @@ pub struct Glyph {
}
/// A link destination.
-#[derive(Clone, Eq, PartialEq, Hash)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum Destination {
/// A link to a point on a page.
- Internal(usize, Point),
+ Internal(Location),
/// A link to a URL.
Url(EcoString),
}
-impl Debug for Destination {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- match self {
- Self::Internal(page, point) => {
- write!(f, "Internal(Page {}, {:?})", page, point)
- }
- Self::Url(url) => write!(f, "Url({})", url),
+/// A physical location in a document.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct Location {
+ /// The page, starting at 1.
+ pub page: usize,
+ /// The exact coordinates on the page (from the top left, as usual).
+ pub pos: Point,
+}
+
+impl Location {
+ /// Encode into a user-facing dictionary.
+ pub fn encode(&self) -> Dict {
+ dict! {
+ "page" => Value::Int(self.page as i64),
+ "x" => Value::Length(self.pos.x.into()),
+ "y" => Value::Length(self.pos.y.into()),
}
}
}
diff --git a/src/library/text/link.rs b/src/library/text/link.rs
index 2ce7a469..12cbaf59 100644
--- a/src/library/text/link.rs
+++ b/src/library/text/link.rs
@@ -1,6 +1,5 @@
use super::TextNode;
use crate::library::prelude::*;
-use crate::util::EcoString;
/// Link text and other elements to an URL.
#[derive(Debug, Hash)]
@@ -24,7 +23,7 @@ impl LinkNode {
let dest = args.expect::<Destination>("destination")?;
let body = match dest {
Destination::Url(_) => args.eat()?,
- Destination::Internal(_, _) => Some(args.expect("body")?),
+ Destination::Internal(_) => Some(args.expect("body")?),
};
Self { dest, body }
}))
@@ -36,10 +35,10 @@ castable! {
Expected: "string or dictionary with `page`, `x`, and `y` keys",
Value::Str(string) => Self::Url(string),
Value::Dict(dict) => {
- let page: i64 = dict.get(&EcoString::from_str("page"))?.clone().cast()?;
- let x: RawLength = dict.get(&EcoString::from_str("x"))?.clone().cast()?;
- let y: RawLength = dict.get(&EcoString::from_str("y"))?.clone().cast()?;
- Self::Internal(page as usize, Point::new(x.length, y.length))
+ let page: i64 = dict.get(&"page".into())?.clone().cast()?;
+ let x: RawLength = dict.get(&"x".into())?.clone().cast()?;
+ let y: RawLength = dict.get(&"y".into())?.clone().cast()?;
+ Self::Internal(Location { page: page as usize, pos: Point::new(x.length, y.length) })
},
}
@@ -56,11 +55,7 @@ impl Show for LinkNode {
dict! {
"url" => match &self.dest {
Destination::Url(url) => Value::Str(url.clone()),
- Destination::Internal(page, point) => Value::Dict(dict!{
- "page" => Value::Int(*page as i64),
- "x" => Value::Length(point.x.into()),
- "y" => Value::Length(point.y.into()),
- }),
+ Destination::Internal(loc) => Value::Dict(loc.encode()),
},
"body" => match &self.body {
Some(body) => Value::Content(body.clone()),
@@ -79,7 +74,7 @@ impl Show for LinkNode {
let shorter = text.len() < url.len();
Content::Text(if shorter { text.into() } else { url.clone() })
}
- Destination::Internal(_, _) => panic!("missing body"),
+ Destination::Internal(_) => Content::Empty,
}))
}
@@ -99,7 +94,7 @@ impl Show for LinkNode {
if match styles.get(Self::UNDERLINE) {
Smart::Auto => match &self.dest {
Destination::Url(_) => true,
- Destination::Internal(_, _) => false,
+ Destination::Internal(_) => false,
},
Smart::Custom(underline) => underline,
} {
diff --git a/src/model/locate.rs b/src/model/locate.rs
index 05204d2e..c61facc5 100644
--- a/src/model/locate.rs
+++ b/src/model/locate.rs
@@ -4,7 +4,7 @@ use std::sync::Arc;
use super::Content;
use crate::diag::TypResult;
use crate::eval::{Args, Array, Dict, Func, Value};
-use crate::frame::{Element, Frame};
+use crate::frame::{Element, Frame, Location};
use crate::geom::{Point, Transform};
use crate::syntax::Spanned;
use crate::util::EcoString;
@@ -296,7 +296,7 @@ fn locate_in_frame(
}
/// A document pin.
-#[derive(Debug, Default, Clone, PartialEq, Hash)]
+#[derive(Debug, Clone, PartialEq, Hash)]
pub struct Pin {
/// The physical location of the pin in the document.
loc: Location,
@@ -330,22 +330,13 @@ impl Pin {
}
}
-/// A physical location in a document.
-#[derive(Debug, Default, Copy, Clone, PartialEq, Hash)]
-struct Location {
- /// The page, starting at 1.
- page: usize,
- /// The exact coordinates on the page (from the top left, as usual).
- pos: Point,
-}
-
-impl Location {
- /// Encode into a user-facing dictionary.
- fn encode(&self) -> Dict {
- dict! {
- "page" => Value::Int(self.page as i64),
- "x" => Value::Length(self.pos.x.into()),
- "y" => Value::Length(self.pos.y.into()),
+impl Default for Pin {
+ fn default() -> Self {
+ Self {
+ loc: Location { page: 0, pos: Point::zero() },
+ flow: 0,
+ group: None,
+ value: None,
}
}
}