summaryrefslogtreecommitdiff
path: root/src/geom
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-03 11:44:53 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-03 13:35:39 +0100
commit37a7afddfaffd44cb9bc013c9506599267e08983 (patch)
tree20e7d62d3c5418baff01a21d0406b91bf3096214 /src/geom
parent56342bd972a13ffe21beaf2b87ab7eb1597704b4 (diff)
Split crates
Diffstat (limited to 'src/geom')
-rw-r--r--src/geom/align.rs37
-rw-r--r--src/geom/angle.rs2
-rw-r--r--src/geom/mod.rs2
-rw-r--r--src/geom/paint.rs18
-rw-r--r--src/geom/stroke.rs61
5 files changed, 101 insertions, 19 deletions
diff --git a/src/geom/align.rs b/src/geom/align.rs
index a7ee2763..25409e3a 100644
--- a/src/geom/align.rs
+++ b/src/geom/align.rs
@@ -78,3 +78,40 @@ impl Debug for Align {
})
}
}
+
+/// The generic alignment representation.
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+pub enum GenAlign {
+ /// Align at the start side of the text direction.
+ Start,
+ /// Align at the end side of the text direction.
+ End,
+ /// Align at a specific alignment.
+ Specific(Align),
+}
+
+impl GenAlign {
+ /// The axis this alignment belongs to.
+ pub const fn axis(self) -> Axis {
+ match self {
+ Self::Start | Self::End => Axis::X,
+ Self::Specific(align) => align.axis(),
+ }
+ }
+}
+
+impl From<Align> for GenAlign {
+ fn from(align: Align) -> Self {
+ Self::Specific(align)
+ }
+}
+
+impl Debug for GenAlign {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Start => f.pad("start"),
+ Self::End => f.pad("end"),
+ Self::Specific(align) => align.fmt(f),
+ }
+ }
+}
diff --git a/src/geom/angle.rs b/src/geom/angle.rs
index 33a864ca..8e80d72b 100644
--- a/src/geom/angle.rs
+++ b/src/geom/angle.rs
@@ -178,6 +178,6 @@ mod tests {
#[test]
fn test_angle_unit_conversion() {
assert!((Angle::rad(2.0 * PI).to_deg() - 360.0) < 1e-4);
- assert!((Angle::deg(45.0).to_rad() - 0.7854) < 1e-4);
+ assert!((Angle::deg(45.0).to_rad() - std::f64::consts::FRAC_PI_4) < 1e-4);
}
}
diff --git a/src/geom/mod.rs b/src/geom/mod.rs
index 6e2b8f9b..c1469b26 100644
--- a/src/geom/mod.rs
+++ b/src/geom/mod.rs
@@ -21,6 +21,7 @@ mod rounded;
mod scalar;
mod sides;
mod size;
+mod stroke;
mod transform;
pub use abs::*;
@@ -42,6 +43,7 @@ pub use rounded::*;
pub use scalar::*;
pub use sides::*;
pub use size::*;
+pub use stroke::*;
pub use transform::*;
use std::cmp::Ordering;
diff --git a/src/geom/paint.rs b/src/geom/paint.rs
index c5bbefa4..b07f09af 100644
--- a/src/geom/paint.rs
+++ b/src/geom/paint.rs
@@ -388,24 +388,6 @@ impl From<CmykColor> for Color {
}
}
-/// A stroke of a geometric shape.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub struct Stroke {
- /// The stroke's paint.
- pub paint: Paint,
- /// The stroke's thickness.
- pub thickness: Abs,
-}
-
-impl Default for Stroke {
- fn default() -> Self {
- Self {
- paint: Paint::Solid(Color::BLACK.into()),
- thickness: Abs::pt(1.0),
- }
- }
-}
-
/// Convert to the closest u8.
fn round_u8(value: f64) -> u8 {
value.round() as u8
diff --git a/src/geom/stroke.rs b/src/geom/stroke.rs
new file mode 100644
index 00000000..eae43c24
--- /dev/null
+++ b/src/geom/stroke.rs
@@ -0,0 +1,61 @@
+use super::*;
+use crate::model::Smart;
+
+/// A stroke of a geometric shape.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct Stroke {
+ /// The stroke's paint.
+ pub paint: Paint,
+ /// The stroke's thickness.
+ pub thickness: Abs,
+}
+
+impl Default for Stroke {
+ fn default() -> Self {
+ Self {
+ paint: Paint::Solid(Color::BLACK),
+ thickness: Abs::pt(1.0),
+ }
+ }
+}
+
+/// A partial stroke representation.
+///
+/// In this representation, both fields are optional so that you can pass either
+/// just a paint (`red`), just a thickness (`0.1em`) or both (`2pt + red`) where
+/// this is expected.
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct PartialStroke<T = Length> {
+ /// The stroke's paint.
+ pub paint: Smart<Paint>,
+ /// The stroke's thickness.
+ pub thickness: Smart<T>,
+}
+
+impl PartialStroke<Abs> {
+ /// Unpack the stroke, filling missing fields from the `default`.
+ pub fn unwrap_or(self, default: Stroke) -> Stroke {
+ Stroke {
+ paint: self.paint.unwrap_or(default.paint),
+ thickness: self.thickness.unwrap_or(default.thickness),
+ }
+ }
+
+ /// Unpack the stroke, filling missing fields with the default values.
+ pub fn unwrap_or_default(self) -> Stroke {
+ self.unwrap_or(Stroke::default())
+ }
+}
+
+impl<T: Debug> Debug for PartialStroke<T> {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match (self.paint, &self.thickness) {
+ (Smart::Custom(paint), Smart::Custom(thickness)) => {
+ write!(f, "{thickness:?} + {paint:?}")
+ }
+ (Smart::Custom(paint), Smart::Auto) => paint.fmt(f),
+ (Smart::Auto, Smart::Custom(thickness)) => thickness.fmt(f),
+ (Smart::Auto, Smart::Auto) => f.pad("<stroke>"),
+ }
+ }
+}