peniko/
style.rs

1// Copyright 2022 the Peniko Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4use kurbo::Stroke;
5
6/// Describes the rule that determines the interior portion of a shape.
7#[derive(Copy, Clone, PartialEq, Eq, Debug)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[repr(u8)]
10pub enum Fill {
11    /// Non-zero fill rule.
12    NonZero = 0,
13    /// Even-odd fill rule.
14    EvenOdd = 1,
15    // NOTICE: If a new value is added, be sure to modify `MAX_VALUE` in the bytemuck impl.
16}
17
18/// Describes draw style-- either a [fill](Fill) or [stroke](Stroke).
19///
20/// See also [`StyleRef`] which can be used to avoid allocations.
21#[derive(Clone, Debug)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23pub enum Style {
24    /// Filled draw operation.
25    Fill(Fill),
26    /// Stroked draw operation.
27    Stroke(Stroke),
28}
29
30impl From<Fill> for Style {
31    fn from(fill: Fill) -> Self {
32        Self::Fill(fill)
33    }
34}
35
36impl From<Stroke> for Style {
37    fn from(stroke: Stroke) -> Self {
38        Self::Stroke(stroke)
39    }
40}
41
42/// Reference to a [draw style](Style).
43///
44/// This is useful for methods that would like to accept draw styles by reference. Defining
45/// the type as `impl<Into<DrawRef>>` allows accepting types like `&Stroke` or `Fill`
46/// directly without cloning or allocating.
47#[expect(
48    variant_size_differences,
49    reason = "We don't expect this enum to be operated on in bulk."
50)]
51#[derive(Debug, Copy, Clone)]
52pub enum StyleRef<'a> {
53    /// Filled draw operation.
54    Fill(Fill),
55    /// Stroked draw operation.
56    Stroke(&'a Stroke),
57}
58
59impl StyleRef<'_> {
60    /// Converts the reference to an owned draw.
61    #[must_use]
62    pub fn to_owned(&self) -> Style {
63        match self {
64            Self::Fill(fill) => Style::Fill(*fill),
65            Self::Stroke(stroke) => Style::Stroke((*stroke).clone()),
66        }
67    }
68}
69
70impl From<Fill> for StyleRef<'_> {
71    fn from(fill: Fill) -> Self {
72        Self::Fill(fill)
73    }
74}
75
76impl<'a> From<&'a Stroke> for StyleRef<'a> {
77    fn from(stroke: &'a Stroke) -> Self {
78        Self::Stroke(stroke)
79    }
80}
81
82impl<'a> From<&'a Style> for StyleRef<'a> {
83    fn from(draw: &'a Style) -> Self {
84        match draw {
85            Style::Fill(fill) => Self::Fill(*fill),
86            Style::Stroke(stroke) => Self::Stroke(stroke),
87        }
88    }
89}