summaryrefslogtreecommitdiff
path: root/crates/typst-library/src/visualize/paint.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-10-27 19:04:55 +0100
committerGitHub <noreply@github.com>2024-10-27 18:04:55 +0000
commitbe7cfc85d08c545abfac08098b7b33b4bd71f37e (patch)
treef4137fa2aaa57babae1f7603a9b2ed7e688f43d8 /crates/typst-library/src/visualize/paint.rs
parentb8034a343831e8609aec2ec81eb7eeda57aa5d81 (diff)
Split out four new crates (#5302)
Diffstat (limited to 'crates/typst-library/src/visualize/paint.rs')
-rw-r--r--crates/typst-library/src/visualize/paint.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/crates/typst-library/src/visualize/paint.rs b/crates/typst-library/src/visualize/paint.rs
new file mode 100644
index 00000000..cd1006aa
--- /dev/null
+++ b/crates/typst-library/src/visualize/paint.rs
@@ -0,0 +1,102 @@
+use std::fmt::{self, Debug, Formatter};
+
+use ecow::EcoString;
+
+use crate::foundations::{cast, Repr, Smart};
+use crate::visualize::{Color, Gradient, Pattern, RelativeTo};
+
+/// How a fill or stroke should be painted.
+#[derive(Clone, Eq, PartialEq, Hash)]
+pub enum Paint {
+ /// A solid color.
+ Solid(Color),
+ /// A gradient.
+ Gradient(Gradient),
+ /// A pattern.
+ Pattern(Pattern),
+}
+
+impl Paint {
+ /// Unwraps a solid color used for text rendering.
+ pub fn unwrap_solid(&self) -> Color {
+ match self {
+ Self::Solid(color) => *color,
+ Self::Gradient(_) | Self::Pattern(_) => panic!("expected solid color"),
+ }
+ }
+
+ /// Gets the relative coordinate system for this paint.
+ pub fn relative(&self) -> Smart<RelativeTo> {
+ match self {
+ Self::Solid(_) => Smart::Auto,
+ Self::Gradient(gradient) => gradient.relative(),
+ Self::Pattern(pattern) => pattern.relative(),
+ }
+ }
+
+ /// Turns this paint into a paint for a text decoration.
+ ///
+ /// If this paint is a gradient, it will be converted to a gradient with
+ /// relative set to [`RelativeTo::Parent`].
+ pub fn as_decoration(&self) -> Self {
+ match self {
+ Self::Solid(color) => Self::Solid(*color),
+ Self::Gradient(gradient) => {
+ Self::Gradient(gradient.clone().with_relative(RelativeTo::Parent))
+ }
+ Self::Pattern(pattern) => {
+ Self::Pattern(pattern.clone().with_relative(RelativeTo::Parent))
+ }
+ }
+ }
+}
+
+impl Debug for Paint {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Solid(v) => v.fmt(f),
+ Self::Gradient(v) => v.fmt(f),
+ Self::Pattern(v) => v.fmt(f),
+ }
+ }
+}
+
+impl From<Pattern> for Paint {
+ fn from(pattern: Pattern) -> Self {
+ Self::Pattern(pattern)
+ }
+}
+
+impl Repr for Paint {
+ fn repr(&self) -> EcoString {
+ match self {
+ Self::Solid(color) => color.repr(),
+ Self::Gradient(gradient) => gradient.repr(),
+ Self::Pattern(pattern) => pattern.repr(),
+ }
+ }
+}
+
+impl<T: Into<Color>> From<T> for Paint {
+ fn from(t: T) -> Self {
+ Self::Solid(t.into())
+ }
+}
+
+impl From<Gradient> for Paint {
+ fn from(gradient: Gradient) -> Self {
+ Self::Gradient(gradient)
+ }
+}
+
+cast! {
+ Paint,
+ self => match self {
+ Self::Solid(color) => color.into_value(),
+ Self::Gradient(gradient) => gradient.into_value(),
+ Self::Pattern(pattern) => pattern.into_value(),
+ },
+ color: Color => Self::Solid(color),
+ gradient: Gradient => Self::Gradient(gradient),
+ pattern: Pattern => Self::Pattern(pattern),
+}