summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-31 16:31:21 +0200
committerLaurenz <laurmaedje@gmail.com>2023-03-31 16:33:33 +0200
commit5f97e0a77348d4fb1c89a9adf671647f1fa86dc3 (patch)
tree2800a61d06ac7cae8e57cb361804c530b1843bb8 /src
parent00f11ae56d6d20b92a8c6ad6f2245c3ad3e94d86 (diff)
Make `Paint` not implement `Copy`
Diffstat (limited to 'src')
-rw-r--r--src/export/pdf/page.rs20
-rw-r--r--src/export/render.rs12
-rw-r--r--src/geom/axes.rs6
-rw-r--r--src/geom/corners.rs36
-rw-r--r--src/geom/mod.rs13
-rw-r--r--src/geom/paint.rs2
-rw-r--r--src/geom/point.rs6
-rw-r--r--src/geom/rounded.rs6
-rw-r--r--src/geom/sides.rs24
-rw-r--r--src/geom/stroke.rs6
10 files changed, 74 insertions, 57 deletions
diff --git a/src/export/pdf/page.rs b/src/export/pdf/page.rs
index f3c81cb8..8f767e87 100644
--- a/src/export/pdf/page.rs
+++ b/src/export/pdf/page.rs
@@ -215,8 +215,8 @@ impl PageContext<'_, '_> {
}
}
- fn set_fill(&mut self, fill: Paint) {
- if self.state.fill != Some(fill) {
+ fn set_fill(&mut self, fill: &Paint) {
+ if self.state.fill.as_ref() != Some(fill) {
let f = |c| c as f32 / 255.0;
let Paint::Solid(color) = fill;
match color {
@@ -233,7 +233,7 @@ impl PageContext<'_, '_> {
self.content.set_fill_cmyk(f(c.c), f(c.m), f(c.y), f(c.k));
}
}
- self.state.fill = Some(fill);
+ self.state.fill = Some(fill.clone());
}
}
@@ -248,8 +248,8 @@ impl PageContext<'_, '_> {
self.state.fill_space = None;
}
- fn set_stroke(&mut self, stroke: Stroke) {
- if self.state.stroke != Some(stroke) {
+ fn set_stroke(&mut self, stroke: &Stroke) {
+ if self.state.stroke.as_ref() != Some(stroke) {
let f = |c| c as f32 / 255.0;
let Paint::Solid(color) = stroke.paint;
match color {
@@ -268,7 +268,7 @@ impl PageContext<'_, '_> {
}
self.content.set_line_width(stroke.thickness.to_f32());
- self.state.stroke = Some(stroke);
+ self.state.stroke = Some(stroke.clone());
}
}
@@ -335,7 +335,7 @@ fn write_text(ctx: &mut PageContext, x: f32, y: f32, text: &TextItem) {
.or_default()
.extend(text.glyphs.iter().map(|g| g.id));
- ctx.set_fill(text.fill);
+ ctx.set_fill(&text.fill);
ctx.set_font(&text.font, text.size);
ctx.content.begin_text();
@@ -386,11 +386,11 @@ fn write_shape(ctx: &mut PageContext, x: f32, y: f32, shape: &Shape) {
return;
}
- if let Some(fill) = shape.fill {
+ if let Some(fill) = &shape.fill {
ctx.set_fill(fill);
}
- if let Some(stroke) = shape.stroke {
+ if let Some(stroke) = &shape.stroke {
ctx.set_stroke(stroke);
}
@@ -413,7 +413,7 @@ fn write_shape(ctx: &mut PageContext, x: f32, y: f32, shape: &Shape) {
}
}
- match (shape.fill, shape.stroke) {
+ match (&shape.fill, &shape.stroke) {
(None, None) => unreachable!(),
(Some(_), None) => ctx.content.fill_nonzero(),
(None, Some(_)) => ctx.content.stroke(),
diff --git a/src/export/render.rs b/src/export/render.rs
index 11ab5447..dc87f447 100644
--- a/src/export/render.rs
+++ b/src/export/render.rs
@@ -223,7 +223,7 @@ fn render_outline_glyph(
builder.0.finish()?
};
- let paint = text.fill.into();
+ let paint = (&text.fill).into();
let rule = sk::FillRule::default();
// Flip vertically because font design coordinate
@@ -302,7 +302,7 @@ fn render_shape(
Geometry::Path(ref path) => convert_path(path)?,
};
- if let Some(fill) = shape.fill {
+ if let Some(fill) = &shape.fill {
let mut paint: sk::Paint = fill.into();
if matches!(shape.geometry, Geometry::Rect(_)) {
paint.anti_alias = false;
@@ -312,7 +312,7 @@ fn render_shape(
canvas.fill_path(&path, &paint, rule, ts, mask);
}
- if let Some(Stroke { paint, thickness }) = shape.stroke {
+ if let Some(Stroke { paint, thickness }) = &shape.stroke {
let paint = paint.into();
let stroke = sk::Stroke { width: thickness.to_f32(), ..Default::default() };
canvas.stroke_path(&path, &paint, &stroke, ts, mask);
@@ -428,10 +428,10 @@ impl From<Transform> for sk::Transform {
}
}
-impl From<Paint> for sk::Paint<'static> {
- fn from(paint: Paint) -> Self {
+impl From<&Paint> for sk::Paint<'static> {
+ fn from(paint: &Paint) -> Self {
let mut sk_paint = sk::Paint::default();
- let Paint::Solid(color) = paint;
+ let Paint::Solid(color) = *paint;
sk_paint.set_color(color.into());
sk_paint.anti_alias = true;
sk_paint
diff --git a/src/geom/axes.rs b/src/geom/axes.rs
index 92bd0388..8bc2456a 100644
--- a/src/geom/axes.rs
+++ b/src/geom/axes.rs
@@ -120,10 +120,10 @@ impl<T: Ord> Axes<T> {
impl<T> Get<Axis> for Axes<T> {
type Component = T;
- fn get(self, axis: Axis) -> T {
+ fn get_ref(&self, axis: Axis) -> &T {
match axis {
- Axis::X => self.x,
- Axis::Y => self.y,
+ Axis::X => &self.x,
+ Axis::Y => &self.y,
}
}
diff --git a/src/geom/corners.rs b/src/geom/corners.rs
index 844d3047..26d4082b 100644
--- a/src/geom/corners.rs
+++ b/src/geom/corners.rs
@@ -76,12 +76,12 @@ impl<T> Corners<T> {
impl<T> Get<Corner> for Corners<T> {
type Component = T;
- fn get(self, corner: Corner) -> T {
+ fn get_ref(&self, corner: Corner) -> &T {
match corner {
- Corner::TopLeft => self.top_left,
- Corner::TopRight => self.top_right,
- Corner::BottomRight => self.bottom_right,
- Corner::BottomLeft => self.bottom_left,
+ Corner::TopLeft => &self.top_left,
+ Corner::TopRight => &self.top_right,
+ Corner::BottomRight => &self.bottom_right,
+ Corner::BottomLeft => &self.bottom_left,
}
}
@@ -110,7 +110,7 @@ pub enum Corner {
impl<T> Cast for Corners<Option<T>>
where
- T: Cast + Copy,
+ T: Cast + Clone,
{
fn is(value: &Value) -> bool {
matches!(value, Value::Dict(_)) || T::is(value)
@@ -121,15 +121,23 @@ where
let mut take = |key| dict.take(key).ok().map(T::cast).transpose();
let rest = take("rest")?;
- let left = take("left")?.or(rest);
- let top = take("top")?.or(rest);
- let right = take("right")?.or(rest);
- let bottom = take("bottom")?.or(rest);
+ let left = take("left")?.or_else(|| rest.clone());
+ let top = take("top")?.or_else(|| rest.clone());
+ let right = take("right")?.or_else(|| rest.clone());
+ let bottom = take("bottom")?.or_else(|| rest.clone());
let corners = Corners {
- top_left: take("top-left")?.or(top).or(left),
- top_right: take("top-right")?.or(top).or(right),
- bottom_right: take("bottom-right")?.or(bottom).or(right),
- bottom_left: take("bottom-left")?.or(bottom).or(left),
+ top_left: take("top-left")?
+ .or_else(|| top.clone())
+ .or_else(|| left.clone()),
+ top_right: take("top-right")?
+ .or_else(|| top.clone())
+ .or_else(|| right.clone()),
+ bottom_right: take("bottom-right")?
+ .or_else(|| bottom.clone())
+ .or_else(|| right.clone()),
+ bottom_left: take("bottom-left")?
+ .or_else(|| bottom.clone())
+ .or_else(|| left.clone()),
};
dict.finish(&[
diff --git a/src/geom/mod.rs b/src/geom/mod.rs
index b7daaa1b..8896c24c 100644
--- a/src/geom/mod.rs
+++ b/src/geom/mod.rs
@@ -66,12 +66,21 @@ pub trait Get<Index> {
/// The structure's component type.
type Component;
- /// Return the component for the specified index.
- fn get(self, index: Index) -> Self::Component;
+ /// Borrow the component for the specified index.
+ fn get_ref(&self, index: Index) -> &Self::Component;
/// Borrow the component for the specified index mutably.
fn get_mut(&mut self, index: Index) -> &mut Self::Component;
+ /// Convenience method for getting a copy of a component.
+ fn get(self, index: Index) -> Self::Component
+ where
+ Self: Sized,
+ Self::Component: Copy,
+ {
+ *self.get_ref(index)
+ }
+
/// Convenience method for setting a component.
fn set(&mut self, index: Index, component: Self::Component) {
*self.get_mut(index) = component;
diff --git a/src/geom/paint.rs b/src/geom/paint.rs
index eacd6f95..e9bd3a2e 100644
--- a/src/geom/paint.rs
+++ b/src/geom/paint.rs
@@ -3,7 +3,7 @@ use std::str::FromStr;
use super::*;
/// How a fill or stroke should be painted.
-#[derive(Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Clone, Eq, PartialEq, Hash)]
pub enum Paint {
/// A solid color.
Solid(Color),
diff --git a/src/geom/point.rs b/src/geom/point.rs
index ce3a6ff2..b31ea296 100644
--- a/src/geom/point.rs
+++ b/src/geom/point.rs
@@ -72,10 +72,10 @@ impl Numeric for Point {
impl Get<Axis> for Point {
type Component = Abs;
- fn get(self, axis: Axis) -> Abs {
+ fn get_ref(&self, axis: Axis) -> &Abs {
match axis {
- Axis::X => self.x,
- Axis::Y => self.y,
+ Axis::X => &self.x,
+ Axis::Y => &self.y,
}
}
diff --git a/src/geom/rounded.rs b/src/geom/rounded.rs
index dbe21ac6..f445dfcb 100644
--- a/src/geom/rounded.rs
+++ b/src/geom/rounded.rs
@@ -14,7 +14,7 @@ pub fn rounded_rect(
res.push(Shape {
geometry: fill_geometry(size, radius),
fill,
- stroke: if stroke.is_uniform() { stroke.top } else { None },
+ stroke: if stroke.is_uniform() { stroke.top.clone() } else { None },
});
}
@@ -55,7 +55,7 @@ fn stroke_segments(
let max_radius = size.x.min(size.y) / 2.0;
for side in [Side::Top, Side::Right, Side::Bottom, Side::Left] {
- let continuous = stroke.get(side) == stroke.get(side.next_cw());
+ let continuous = stroke.get_ref(side) == stroke.get_ref(side.next_cw());
connection = connection.advance(continuous && side != Side::Left);
always_continuous &= continuous;
@@ -69,7 +69,7 @@ fn stroke_segments(
);
if !continuous {
- res.push((mem::take(&mut path), stroke.get(side)));
+ res.push((mem::take(&mut path), stroke.get_ref(side).clone()));
}
}
diff --git a/src/geom/sides.rs b/src/geom/sides.rs
index 247d9a98..25b1fab5 100644
--- a/src/geom/sides.rs
+++ b/src/geom/sides.rs
@@ -91,12 +91,12 @@ impl Sides<Rel<Abs>> {
impl<T> Get<Side> for Sides<T> {
type Component = T;
- fn get(self, side: Side) -> T {
+ fn get_ref(&self, side: Side) -> &T {
match side {
- Side::Left => self.left,
- Side::Top => self.top,
- Side::Right => self.right,
- Side::Bottom => self.bottom,
+ Side::Left => &self.left,
+ Side::Top => &self.top,
+ Side::Right => &self.right,
+ Side::Bottom => &self.bottom,
}
}
@@ -180,7 +180,7 @@ impl Side {
impl<T> Cast for Sides<Option<T>>
where
- T: Default + Cast + Copy,
+ T: Default + Cast + Clone,
{
fn is(value: &Value) -> bool {
matches!(value, Value::Dict(_)) || T::is(value)
@@ -191,13 +191,13 @@ where
let mut take = |key| dict.take(key).ok().map(T::cast).transpose();
let rest = take("rest")?;
- let x = take("x")?.or(rest);
- let y = take("y")?.or(rest);
+ let x = take("x")?.or_else(|| rest.clone());
+ let y = take("y")?.or_else(|| rest.clone());
let sides = Sides {
- left: take("left")?.or(x),
- top: take("top")?.or(y),
- right: take("right")?.or(x),
- bottom: take("bottom")?.or(y),
+ left: take("left")?.or_else(|| x.clone()),
+ top: take("top")?.or_else(|| y.clone()),
+ right: take("right")?.or_else(|| x.clone()),
+ bottom: take("bottom")?.or_else(|| y.clone()),
};
dict.finish(&["left", "top", "right", "bottom", "x", "y", "rest"])?;
diff --git a/src/geom/stroke.rs b/src/geom/stroke.rs
index 500a4c10..4dba06d9 100644
--- a/src/geom/stroke.rs
+++ b/src/geom/stroke.rs
@@ -1,7 +1,7 @@
use super::*;
/// A stroke of a geometric shape.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct Stroke {
/// The stroke's paint.
pub paint: Paint,
@@ -23,7 +23,7 @@ impl Default for Stroke {
/// 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)]
+#[derive(Default, Clone, Eq, PartialEq, Hash)]
pub struct PartialStroke<T = Length> {
/// The stroke's paint.
pub paint: Smart<Paint>,
@@ -48,7 +48,7 @@ impl PartialStroke<Abs> {
impl<T: Debug> Debug for PartialStroke<T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- match (self.paint, &self.thickness) {
+ match (&self.paint, &self.thickness) {
(Smart::Custom(paint), Smart::Custom(thickness)) => {
write!(f, "{thickness:?} + {paint:?}")
}