summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-12-27 19:23:26 +0100
committerLaurenz <laurmaedje@gmail.com>2020-12-27 19:23:26 +0100
commit750d220bb080be077cd7ede6d18d485b1c3fb0c9 (patch)
tree741bcbf9e286de6433a0677d4bcf8b93d70fb806 /src
parentc44ebf876f6ab09fe1629d980efc5c4878a6a5a5 (diff)
Add color enum 🎨
Diffstat (limited to 'src')
-rw-r--r--src/color.rs49
-rw-r--r--src/eval/mod.rs3
-rw-r--r--src/eval/value.rs7
-rw-r--r--src/library/style.rs9
-rw-r--r--src/parse/mod.rs4
-rw-r--r--src/parse/tests.rs2
6 files changed, 37 insertions, 37 deletions
diff --git a/src/color.rs b/src/color.rs
index b7266e1b..b676be7c 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -3,6 +3,21 @@
use std::fmt::{self, Debug, Formatter};
use std::str::FromStr;
+/// A color in a dynamic format.
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum Color {
+ /// An 8-bit RGBA color.
+ Rgba(RgbaColor),
+}
+
+impl Debug for Color {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::Rgba(c) => c.fmt(f),
+ }
+ }
+}
+
/// An 8-bit RGBA color.
///
/// # Example
@@ -20,34 +35,23 @@ pub struct RgbaColor {
pub b: u8,
/// Alpha channel.
pub a: u8,
- /// Whether the color was provided as a fail-over by the parser because the
- /// user-defined value was invalid.
- ///
- /// If this is true, the color may be replaced with any color deemed
- /// appropriate at the use-site.
- pub healed: bool,
}
impl RgbaColor {
- /// Constructs a new, unhealed color.
+ /// Constructs a new RGBA color.
pub fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
- Self { r, g, b, a, healed: false }
- }
-
- /// Constructs a new color with a configurable healed status.
- pub fn with_healed(r: u8, g: u8, b: u8, a: u8, healed: bool) -> Self {
- Self { r, g, b, a, healed }
+ Self { r, g, b, a }
}
}
impl FromStr for RgbaColor {
- type Err = ParseColorError;
+ type Err = ParseRgbaError;
/// Constructs a new color from a hex string like `7a03c2`. Do not specify a
/// leading `#`.
fn from_str(hex_str: &str) -> Result<Self, Self::Err> {
if !hex_str.is_ascii() {
- return Err(ParseColorError);
+ return Err(ParseRgbaError);
}
let len = hex_str.len();
@@ -56,7 +60,7 @@ impl FromStr for RgbaColor {
let alpha = len == 4 || len == 8;
if !long && !short {
- return Err(ParseColorError);
+ return Err(ParseRgbaError);
}
let mut values: [u8; 4] = [255; 4];
@@ -66,7 +70,7 @@ impl FromStr for RgbaColor {
let pos = elem * item_len;
let item = &hex_str[pos .. (pos + item_len)];
- values[elem] = u8::from_str_radix(item, 16).map_err(|_| ParseColorError)?;
+ values[elem] = u8::from_str_radix(item, 16).map_err(|_| ParseRgbaError)?;
if short {
// Duplicate number for shorthand notation, i.e. `a` -> `aa`
@@ -92,20 +96,17 @@ impl Debug for RgbaColor {
write!(f, "{:02x}", self.a)?;
}
}
- if self.healed {
- f.write_str(" [healed]")?;
- }
Ok(())
}
}
-/// The error when parsing an [`RgbaColor`] fails.
+/// The error when parsing an [`RgbaColor`] from a string fails.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub struct ParseColorError;
+pub struct ParseRgbaError;
-impl std::error::Error for ParseColorError {}
+impl std::error::Error for ParseRgbaError {}
-impl fmt::Display for ParseColorError {
+impl fmt::Display for ParseRgbaError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.pad("invalid color")
}
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index c2b80b68..ed73b07c 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -20,6 +20,7 @@ use fontdock::FontStyle;
use crate::diag::Diag;
use crate::diag::{Deco, Feedback, Pass};
+use crate::color::Color;
use crate::env::SharedEnv;
use crate::geom::{BoxAlign, Dir, Flow, Gen, Length, Linear, Relative, Sides, Size};
use crate::layout::{
@@ -436,7 +437,7 @@ impl Eval for Lit {
Lit::Float(v) => Value::Float(v),
Lit::Length(v, unit) => Value::Length(Length::with_unit(v, unit)),
Lit::Percent(v) => Value::Relative(Relative::new(v / 100.0)),
- Lit::Color(v) => Value::Color(v),
+ Lit::Color(v) => Value::Color(Color::Rgba(v)),
Lit::Str(ref v) => Value::Str(v.clone()),
Lit::Dict(ref v) => Value::Dict(v.eval(ctx)),
Lit::Content(ref v) => Value::Content(v.clone()),
diff --git a/src/eval/value.rs b/src/eval/value.rs
index 8c98257e..a27e9aa9 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -7,7 +7,7 @@ use std::rc::Rc;
use fontdock::{FontStretch, FontStyle, FontWeight};
use super::{Args, Dict, Eval, EvalContext, SpannedEntry};
-use crate::color::RgbaColor;
+use crate::color::Color;
use crate::diag::Diag;
use crate::geom::{Dir, Length, Linear, Relative};
use crate::paper::Paper;
@@ -32,8 +32,8 @@ pub enum Value {
Relative(Relative),
/// A combination of an absolute length and a relative value: `20% + 5cm`.
Linear(Linear),
- /// A color value with alpha channel: `#f79143ff`.
- Color(RgbaColor),
+ /// A color value: `#f79143ff`.
+ Color(Color),
/// A string: `"string"`.
Str(String),
/// A dictionary value: `(false, 12cm, greeting="hi")`.
@@ -285,6 +285,7 @@ try_from_match!(Linear["linear"]:
Value::Length(v) => v.into(),
Value::Relative(v) => v.into(),
);
+try_from_match!(Color["color"]: Value::Color(v) => v);
try_from_match!(String["string"]: Value::Str(v) => v);
try_from_match!(SynTree["tree"]: Value::Content(v) => v);
try_from_match!(ValueDict["dictionary"]: Value::Dict(v) => v);
diff --git a/src/library/style.rs b/src/library/style.rs
index 43380249..8b8d9f26 100644
--- a/src/library/style.rs
+++ b/src/library/style.rs
@@ -2,9 +2,9 @@ use std::rc::Rc;
use fontdock::{FontStretch, FontStyle, FontWeight};
-use crate::color::RgbaColor;
use crate::eval::StringLike;
use crate::geom::Linear;
+use crate::color::{Color, RgbaColor};
use crate::prelude::*;
/// `font`: Configure the font.
@@ -152,22 +152,19 @@ pub fn rgb(mut args: Args, ctx: &mut EvalContext) -> Value {
let a = args.get::<_, Spanned<f64>>(ctx, 3);
args.done(ctx);
- let mut healed = r.is_none() || g.is_none() || b.is_none();
let mut clamp = |component: Option<Spanned<f64>>, default| {
component.map_or(default, |c| {
if c.v < 0.0 || c.v > 1.0 {
ctx.diag(error!(c.span, "should be between 0.0 and 1.0"));
- healed = true;
}
(c.v.max(0.0).min(1.0) * 255.0).round() as u8
})
};
- Value::Color(RgbaColor::with_healed(
+ Value::Color(Color::Rgba(RgbaColor::new(
clamp(r, 0),
clamp(g, 0),
clamp(b, 0),
clamp(a, 255),
- healed,
- ))
+ )))
}
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 261bbabb..04a9de58 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -487,9 +487,9 @@ fn ident(p: &mut Parser) -> Option<Ident> {
/// Parse a color.
fn color(p: &mut Parser, hex: &str, start: Pos) -> RgbaColor {
RgbaColor::from_str(hex).unwrap_or_else(|_| {
- // Heal color by assuming black.
+ // Replace color with black.
p.diag(error!(start .. p.pos(), "invalid color"));
- RgbaColor::with_healed(0, 0, 0, 255, true)
+ RgbaColor::new(0, 0, 0, 255)
})
}
diff --git a/src/parse/tests.rs b/src/parse/tests.rs
index 6d5eee38..1b6df74b 100644
--- a/src/parse/tests.rs
+++ b/src/parse/tests.rs
@@ -436,7 +436,7 @@ fn test_parse_values() {
e!("[val: [hi]]" => );
// Healed colors.
- v!("#12345" => Color(RgbaColor::with_healed(0, 0, 0, 0xff, true)));
+ v!("#12345" => Color(RgbaColor::new(0, 0, 0, 0xff)));
e!("[val: #12345]" => s(6, 12, "invalid color"));
e!("[val: #a5]" => s(6, 9, "invalid color"));
e!("[val: #14b2ah]" => s(6, 13, "invalid color"));