summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2022-02-08 21:12:09 +0100
committerMartin Haug <mhaug@live.de>2022-02-08 21:12:09 +0100
commitfe70db1f4ce078f7b41c163a1c0ead31fd04850a (patch)
tree0f85390a89a05dc763cbc2eb6c611c48877c08cd /src/library
parent62cf2a19d7207118f115c05c8f7c453d6db77a0a (diff)
New color stuff
- CMYK function - More default colors - Interpret RGB values as sRGB
Diffstat (limited to 'src/library')
-rw-r--r--src/library/mod.rs25
-rw-r--r--src/library/shape.rs2
-rw-r--r--src/library/table.rs2
-rw-r--r--src/library/text.rs2
-rw-r--r--src/library/utility.rs51
5 files changed, 62 insertions, 20 deletions
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 55017645..33b327e9 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -142,6 +142,7 @@ pub fn new() -> Scope {
std.def_func("mod", modulo);
std.def_func("range", range);
std.def_func("rgb", rgb);
+ std.def_func("cmyk", cmyk);
std.def_func("lower", lower);
std.def_func("upper", upper);
std.def_func("roman", roman);
@@ -150,12 +151,24 @@ pub fn new() -> Scope {
std.def_func("sorted", sorted);
// Predefined colors.
- // TODO: More colors.
- std.def_const("white", RgbaColor::WHITE);
- std.def_const("black", RgbaColor::BLACK);
- std.def_const("eastern", RgbaColor::new(0x23, 0x9D, 0xAD, 0xFF));
- std.def_const("conifer", RgbaColor::new(0x9f, 0xEB, 0x52, 0xFF));
- std.def_const("forest", RgbaColor::new(0x43, 0xA1, 0x27, 0xFF));
+ std.def_const("black", Color::BLACK);
+ std.def_const("gray", Color::GRAY);
+ std.def_const("silver", Color::SILVER);
+ std.def_const("white", Color::WHITE);
+ std.def_const("navy", Color::NAVY);
+ std.def_const("blue", Color::BLUE);
+ std.def_const("aqua", Color::AQUA);
+ std.def_const("teal", Color::TEAL);
+ std.def_const("eastern", Color::EASTERN);
+ std.def_const("purple", Color::PURPLE);
+ std.def_const("fuchsia", Color::FUCHSIA);
+ std.def_const("maroon", Color::MAROON);
+ std.def_const("red", Color::RED);
+ std.def_const("orange", Color::ORANGE);
+ std.def_const("yellow", Color::YELLOW);
+ std.def_const("olive", Color::OLIVE);
+ std.def_const("green", Color::GREEN);
+ std.def_const("lime", Color::LIME);
// Other constants.
std.def_const("ltr", Dir::LTR);
diff --git a/src/library/shape.rs b/src/library/shape.rs
index 5d31d570..0dd75c08 100644
--- a/src/library/shape.rs
+++ b/src/library/shape.rs
@@ -125,7 +125,7 @@ impl<S: ShapeKind> Layout for ShapeNode<S> {
let thickness = styles.get(Self::THICKNESS);
let stroke = styles
.get(Self::STROKE)
- .unwrap_or(fill.is_none().then(|| RgbaColor::BLACK.into()))
+ .unwrap_or(fill.is_none().then(|| Color::BLACK.into()))
.map(|paint| Stroke { paint, thickness });
if fill.is_some() || stroke.is_some() {
diff --git a/src/library/table.rs b/src/library/table.rs
index d7aa61db..b0f0fbf5 100644
--- a/src/library/table.rs
+++ b/src/library/table.rs
@@ -21,7 +21,7 @@ impl TableNode {
/// The secondary cell fill color.
pub const SECONDARY: Option<Paint> = None;
/// How the stroke the cells.
- pub const STROKE: Option<Paint> = Some(RgbaColor::BLACK.into());
+ pub const STROKE: Option<Paint> = Some(Color::BLACK.into());
/// The stroke's thickness.
pub const THICKNESS: Length = Length::pt(1.0);
/// How much to pad the cells's content.
diff --git a/src/library/text.rs b/src/library/text.rs
index 00c20a9e..019f8c35 100644
--- a/src/library/text.rs
+++ b/src/library/text.rs
@@ -51,7 +51,7 @@ impl TextNode {
/// Whether a monospace font should be preferred.
pub const MONOSPACE: bool = false;
/// The glyph fill color.
- pub const FILL: Paint = RgbaColor::BLACK.into();
+ pub const FILL: Paint = Color::BLACK.into();
/// Decorative lines.
#[fold(|a, b| a.into_iter().chain(b).collect())]
pub const LINES: Vec<Decoration> = vec![];
diff --git a/src/library/utility.rs b/src/library/utility.rs
index 0f533be4..5b9831c5 100644
--- a/src/library/utility.rs
+++ b/src/library/utility.rs
@@ -94,21 +94,50 @@ pub fn rgb(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Err(_) => bail!(string.span, "invalid hex string"),
}
} else {
- let r = args.expect("red component")?;
- let g = args.expect("green component")?;
- let b = args.expect("blue component")?;
- let a = args.eat()?.unwrap_or(Spanned::new(1.0, Span::detached()));
- let f = |Spanned { v, span }: Spanned<f64>| {
- if (0.0 ..= 1.0).contains(&v) {
- Ok((v * 255.0).round() as u8)
+ struct Component(u8);
+
+ castable! {
+ Component,
+ Expected: "integer or relative",
+ Value::Int(v) => match v {
+ 0 ..= 255 => Self(v as u8),
+ _ => Err("must be between 0 and 255")?,
+ },
+ Value::Relative(v) => if (0.0 ..= 1.0).contains(&v.get()) {
+ Self((v.get() * 255.0).round() as u8)
} else {
- bail!(span, "value must be between 0.0 and 1.0");
- }
- };
- RgbaColor::new(f(r)?, f(g)?, f(b)?, f(a)?)
+ Err("must be between 0% and 100%")?
+ },
+ }
+
+ let Component(r) = args.expect("red component")?;
+ let Component(g) = args.expect("green component")?;
+ let Component(b) = args.expect("blue component")?;
+ let Component(a) = args.eat()?.unwrap_or(Component(255));
+ RgbaColor::new(r, g, b, a)
},
))
}
+/// Create an CMYK color.
+pub fn cmyk(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
+ struct Component(u8);
+
+ castable! {
+ Component,
+ Expected: "relative",
+ Value::Relative(v) => if (0.0 ..= 1.0).contains(&v.get()) {
+ Self((v.get() * 255.0).round() as u8)
+ } else {
+ Err("must be between 0% and 100%")?
+ },
+ }
+
+ let Component(c) = args.expect("cyan component")?;
+ let Component(m) = args.expect("magenta component")?;
+ let Component(y) = args.expect("yellow component")?;
+ let Component(k) = args.expect("key component")?;
+ Ok(Value::Color(CmykColor::new(c, m, y, k).into()))
+}
/// The absolute value of a numeric value.
pub fn abs(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {