diff --git a/src/eval/array.rs b/src/eval/array.rs index 294d28711..5cd8df821 100644 --- a/src/eval/array.rs +++ b/src/eval/array.rs @@ -80,6 +80,11 @@ impl Array { self.0.iter() } + /// Extracts a slice of the whole array. + pub fn as_slice(&self) -> &[Value] { + self.0.as_slice() + } + /// Return a sorted version of this array. /// /// Returns an error if two values could not be compared. diff --git a/src/geom/angle.rs b/src/geom/angle.rs index 4e08a518a..b4d6f79ab 100644 --- a/src/geom/angle.rs +++ b/src/geom/angle.rs @@ -40,12 +40,12 @@ impl Angle { (self.0).0 } - /// Get the sine of this angle. + /// Get the sine of this angle in radians. pub fn sin(self) -> f64 { self.to_rad().sin() } - /// Get the cosine of this angle. + /// Get the cosine of this angle in radians. pub fn cos(self) -> f64 { self.to_rad().cos() } diff --git a/src/geom/point.rs b/src/geom/point.rs index 7ab0d3753..6d77507b4 100644 --- a/src/geom/point.rs +++ b/src/geom/point.rs @@ -49,12 +49,6 @@ impl Point { } } -impl From> for Point { - fn from(spec: Spec) -> Self { - Self::new(spec.x, spec.y) - } -} - impl Get for Point { type Component = Length; diff --git a/src/geom/transform.rs b/src/geom/transform.rs index eed51d460..5bc05d84e 100644 --- a/src/geom/transform.rs +++ b/src/geom/transform.rs @@ -36,9 +36,8 @@ impl Transform { /// A rotation transform. pub fn rotation(angle: Angle) -> Self { - let v = angle.to_rad(); - let cos = Relative::new(v.cos()); - let sin = Relative::new(v.sin()); + let cos = Relative::new(angle.cos()); + let sin = Relative::new(angle.sin()); Self { sx: cos, ky: sin, diff --git a/src/library/graphics/line.rs b/src/library/graphics/line.rs index 141abb08b..a650c76c2 100644 --- a/src/library/graphics/line.rs +++ b/src/library/graphics/line.rs @@ -2,18 +2,21 @@ use crate::library::prelude::*; /// Display a line without affecting the layout. #[derive(Debug, Hash)] -pub struct LineNode(Spec, Spec); +pub struct LineNode { + origin: Spec, + delta: Spec, +} #[node] impl LineNode { /// How the stroke the line. - pub const STROKE: Smart = Smart::Auto; + pub const STROKE: Paint = Color::BLACK.into(); /// The line's thickness. pub const THICKNESS: Length = Length::pt(1.0); fn construct(_: &mut Context, args: &mut Args) -> TypResult { let origin = args.named::>("origin")?.unwrap_or_default(); - let to = match args.named::>("to")? { + let delta = match args.named::>("to")? { Some(to) => to.zip(origin).map(|(to, from)| to - from), None => { let length = @@ -27,7 +30,7 @@ impl LineNode { } }; - Ok(Content::inline(Self(origin, to))) + Ok(Content::inline(Self { origin, delta })) } } @@ -38,23 +41,23 @@ impl Layout for LineNode { regions: &Regions, styles: StyleChain, ) -> TypResult>> { - let target = regions.expand.select(regions.first, Size::zero()); - let mut frame = Frame::new(target); - let thickness = styles.get(Self::THICKNESS); let stroke = Some(Stroke { - paint: styles.get(Self::STROKE).unwrap_or(Color::BLACK.into()), + paint: styles.get(Self::STROKE), thickness, }); let resolved_origin = - self.0.zip(regions.base).map(|(l, b)| Linear::resolve(l, b)); - let resolved_to = self.1.zip(regions.base).map(|(l, b)| Linear::resolve(l, b)); - - let geometry = Geometry::Line(resolved_to.into()); + self.origin.zip(regions.base).map(|(l, b)| Linear::resolve(l, b)); + let resolved_delta = + self.delta.zip(regions.base).map(|(l, b)| Linear::resolve(l, b)); + let geometry = Geometry::Line(resolved_delta.to_point()); let shape = Shape { geometry, fill: None, stroke }; - frame.prepend(resolved_origin.into(), Element::Shape(shape)); + + let target = regions.expand.select(regions.first, Size::zero()); + let mut frame = Frame::new(target); + frame.push(resolved_origin.to_point(), Element::Shape(shape)); Ok(vec![Arc::new(frame)]) } diff --git a/src/library/mod.rs b/src/library/mod.rs index 88f003c2d..505f1a1d1 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -174,11 +174,15 @@ castable! { castable! { Spec, - Expected: "two-dimensional length array", + Expected: "array of exactly two linears", Value::Array(array) => { - let e = "point array must contain exactly two entries"; - let a = array.get(0).map_err(|_| e)?.clone().cast::()?; - let b = array.get(1).map_err(|_| e)?.clone().cast::()?; - Spec::new(a, b) + match array.as_slice() { + [a, b] => { + let a = a.clone().cast::()?; + let b = b.clone().cast::()?; + Spec::new(a, b) + }, + _ => return Err("point array must contain exactly two entries".to_string()), + } }, } diff --git a/tests/ref/graphics/line.png b/tests/ref/graphics/line.png index 49f05f0d7..7858b5c9a 100644 Binary files a/tests/ref/graphics/line.png and b/tests/ref/graphics/line.png differ diff --git a/tests/typ/graphics/line.typ b/tests/typ/graphics/line.typ index d89c703a0..452e52f3c 100644 --- a/tests/typ/graphics/line.typ +++ b/tests/typ/graphics/line.typ @@ -14,6 +14,7 @@ #v(.5cm) --- +// Test the angle argument and positioning. #set page(fill: rgb("0B1026")) #set line(stroke: white) @@ -21,20 +22,22 @@ #let star(width, ..args) = box(width: width, height: width)[ #set text(spacing: 0%) #set line(..args) - - #line(length: +30%, origin: (09.0%, 02%)) - #line(length: +30%, origin: (38.7%, 02%), angle: -72deg) - #line(length: +30%, origin: (57.5%, 02%), angle: 252deg) - #line(length: +30%, origin: (57.3%, 02%)) - #line(length: -30%, origin: (88.0%, 02%), angle: -36deg) - #line(length: +30%, origin: (73.3%, 48%), angle: 252deg) - #line(length: -30%, origin: (73.5%, 48%), angle: 36deg) - #line(length: +30%, origin: (25.4%, 48%), angle: -36deg) - #line(length: +30%, origin: (25.6%, 48%), angle: -72deg) - #line(length: +32%, origin: (8.50%, 02%), angle: 34deg) + + #align(left)[ + #line(length: +30%, origin: (09.0%, 02%)) + #line(length: +30%, origin: (38.7%, 02%), angle: -72deg) + #line(length: +30%, origin: (57.5%, 02%), angle: 252deg) + #line(length: +30%, origin: (57.3%, 02%)) + #line(length: -30%, origin: (88.0%, 02%), angle: -36deg) + #line(length: +30%, origin: (73.3%, 48%), angle: 252deg) + #line(length: -30%, origin: (73.5%, 48%), angle: 36deg) + #line(length: +30%, origin: (25.4%, 48%), angle: -36deg) + #line(length: +30%, origin: (25.6%, 48%), angle: -72deg) + #line(length: +32%, origin: (8.50%, 02%), angle: 34deg) + ] ] -#grid(columns: (1fr, ) * 3, ..((star(20pt, thickness: .5pt), ) * 9)) +#align(center, grid(columns: (1fr, ) * 3, ..((star(20pt, thickness: .5pt), ) * 9))) --- // Test errors.