diff options
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/mod.rs | 25 | ||||
| -rw-r--r-- | src/library/shape.rs | 2 | ||||
| -rw-r--r-- | src/library/table.rs | 2 | ||||
| -rw-r--r-- | src/library/text.rs | 2 | ||||
| -rw-r--r-- | src/library/utility.rs | 51 |
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> { |
