Skip to content

Commit

Permalink
Merge #301
Browse files Browse the repository at this point in the history
301: Remove the Gradient type and its module r=Ogeon a=Ogeon

As discussed in #218, the `Gradient` type has not gotten the attention it deserves and it's better to remove it in favor of other alternatives. This will also make the library more focused and easier to maintain. The predefined, named gradient constants are also removed.

## Closed Issues

* Closes #152, since the `Gradient` is now gone.
* Closes #156, since the `Gradient` is now gone.

## Breaking Change

Both `Gradient` and `gradient::named` are gone with no replacement, in favor of better alternatives in other crates.

Co-authored-by: Erik Hedvall <erikwhedvall@gmail.com>
  • Loading branch information
bors[bot] and Ogeon authored Jan 15, 2023
2 parents 2775fa6 + 98ae885 commit 1be0fb3
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 1,900 deletions.
Binary file removed gfx/readme_gradients_2.png
Binary file not shown.
4 changes: 2 additions & 2 deletions palette/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ categories = ["graphics", "multimedia::images", "no-std"]
build = "build/main.rs"

[features]
default = ["named_from_str", "named_gradients", "std", "approx"]
default = ["named_from_str", "std", "approx"]
named_from_str = ["named", "phf"]
named = []
named_gradients = ["std"]
random = ["rand"]
serializing = ["serde", "std"]
#ignore in feature test
Expand Down Expand Up @@ -76,6 +75,7 @@ lazy_static = "1"
serde = "1"
serde_derive = "1"
serde_json = "1"
enterpolation = "0.2.0"

[dev-dependencies.clap]
version = "2"
Expand Down
39 changes: 8 additions & 31 deletions palette/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ A color management and conversion library that focuses on maintaining correctnes
* Type system representations of color spaces, including RGB, HSL, HSV, HWB, L\*a\*b\*, L\*C\*h°, XYZ and xyY.
* Copy free conversion to and from color buffers allows simple integration with other crates and systems.
* Color operations implemented as traits, such as arithmetic, lighten/darken, hue shifting, mixing/interpolating, and SVG blend functions.
* Provides types for creating gradients.
* Color spaces can be customized, using type parameters, to support different levels of precision, linearity, white points, RGB standards, etc.
* Supports `#[no_std]`, with only gradients disabled.
* Optional `serde` and `rand` integration.
* Supports `#[no_std]`.
* Optional `serde`, `rand`, and `bytemuck` integration.

## Minimum Supported Rust Version (MSRV)

Expand Down Expand Up @@ -42,7 +41,6 @@ These features are enabled by default:

* `"named"` - Enables color constants, located in the `named` module.
* `"named_from_str"` - Enables `named::from_str`, which maps name strings to colors.
* `"named_gradients"`- Enables gradient constants, located in `gradient::named`. This requires the standard library.
* `"std"` - Enables use of the standard library.
* `"approx"` - Enables approximate comparison using [`approx`].

Expand All @@ -57,12 +55,7 @@ These features are disabled by default:

### Using palette in an embedded environment

Palette supports `#![no_std]` environments by disabling the `"std"` feature. However, there are some things that are unavailable without the standard library:

* Gradients are unavailable, because they depend heavily on Vectors.
* Serialization using `serde` is unavailable.

It uses [`libm`] to provide the floating-point operations that are typically in `std`.
Palette supports `#![no_std]` environments by disabling the `"std"` feature. It uses [`libm`] to provide the floating-point operations that are typically in `std`. However, serializing with `serde` is not available without the standard library.

## Examples

Expand Down Expand Up @@ -189,12 +182,13 @@ There's also the option to explicitly convert to and from premultiplied alpha, t

### Gradients

The `Gradient` type provides basic support for linear gradients in any color space that implements the `Mix` trait. As an example, the `Gradient::take` method returns an iterator over a number of points along the gradient:
Most color types are directly compatible with gradient and interpolation crates, such as [`enterpolation`]:

```rust
use palette::{Gradient, LinSrgb};
use enterpolation::{linear::ConstEquidistantLinear, Curve};
use palette::LinSrgb;

let gradient = Gradient::new(vec![
let gradient = ConstEquidistantLinear::<f32, _, 3>::equidistant_unchecked([
LinSrgb::new(0.00, 0.05, 0.20),
LinSrgb::new(0.70, 0.10, 0.20),
LinSrgb::new(0.95, 0.90, 0.30),
Expand All @@ -207,24 +201,6 @@ Here's the gradient as both its continuous form and as the 10 colors from `.take

![An illustration of the gradient with the continuous form above a row of discrete color swatches.](https://raw.githubusercontent.com/Ogeon/palette/05e60121f3ab39aba972c477f258c70d0495551d/gfx/readme_gradients_1.png)

There's also support for arbitrary spacing between the input points:

```rust
use palette::{Gradient, LinSrgb};

let gradient = Gradient::from([
(0.0, LinSrgb::new(0.00, 0.05, 0.20)), // A pair of position and color.
(0.2, LinSrgb::new(0.70, 0.10, 0.20)),
(1.0, LinSrgb::new(0.95, 0.90, 0.30)),
]);

let taken_colors: Vec<_> = gradient.take(10).collect();
```

Here's the gradient after the middle point has been moved more towards the beginning:

![An illustration of the gradient with the continuous form above a row of discrete color swatches.](https://raw.githubusercontent.com/Ogeon/palette/05e60121f3ab39aba972c477f258c70d0495551d/gfx/readme_gradients_2.png)

### Customizing Color Spaces

The built-in color spaces have been made customizable to account for as much variation as possible. The more common variants have been exposed as type aliases (like `Srgb`, `Srgba` and `LinSrgb` from above), but it's entirely possible to make custom compositions, including with entirely new parameters. For example, making up your own RGB standard:
Expand Down Expand Up @@ -356,3 +332,4 @@ at your option.
[`bytemuck`]: https://crates.io/crates/bytemuck
[`wide`]: https://crates.io/crates/wide
[`approx`]: https://crates.io/crates/approx
[`enterpolation`]: https://crates.io/crates/enterpolation
76 changes: 0 additions & 76 deletions palette/build/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ pub fn build() {
let dest_path = Path::new(&out_dir).join("named.rs");
let mut writer = File::create(dest_path).expect("couldn't create named.rs");
build_colors(&mut writer);
let dest_path = Path::new(&out_dir).join("named_gradients.rs");
let mut writer = File::create(dest_path).expect("couldn't create named_gradients.rs");
build_gradients(&mut writer);
}

#[cfg(feature = "named")]
Expand Down Expand Up @@ -58,75 +55,6 @@ pub fn build_colors(writer: &mut File) {
gen_from_str(writer, &entries)
}

#[cfg(feature = "named_gradients")]
pub fn build_gradients(writer: &mut File) {
use std::io::{BufRead, BufReader, Write};

let reader = BufReader::new(
File::open("build/svg_gradients_mpl.txt").expect("could not open svg_gradients_mpl.txt"),
);

let mut line_iter = reader.lines();
while let Some(Ok(line)) = line_iter.next() {
//empty lines are allowed
if line.is_empty() {
continue;
}
let mut parts = line.split_whitespace();
//every line should have the same info: name type number_of_colors [\n red green blue]^number_of_colors
let name = parts.next().expect("couldn't get the color name");
let color_type = parts.next().expect("couldn't get the type of the colors");
//we assume that color_type is a rgb type
let color_type = format!("crate::rgb::{}", color_type);
let number_of_colors: usize = parts
.next()
.expect("couldn't get the number of colors")
.parse()
.unwrap_or_else(|_| panic!("couldn't parse the number of colors for color {}", name));
writeln!(writer, "/// New matplotlib colormap by Nathaniel J. Smith, Stefan van der Walt, and (in the case of viridis) Eric Firing.").unwrap();
writeln!(writer, "///").unwrap();
writeln!(writer, "/// This gradient is perfectly perceptually-uniform, both in regular form and also when converted to black-and-white.").unwrap();
writeln!(
writer,
"/// The colormap is released under the CC0 license public domain dedication."
)
.unwrap();
write!(writer,
"pub const {0}: crate::gradient::Gradient<{1}, [(f32,{1});{2}]> = crate::gradient::Gradient([",
name.to_uppercase(), color_type, number_of_colors).unwrap();
for i in 0..number_of_colors {
let color = line_iter
.next()
.unwrap_or_else(|| panic!("less lines than stated colors in gradient {}", name))
.unwrap_or_else(|_| panic!("couldn't read the {}th line of color {}", i, name));
let mut rgb = color.split(',');
let red: f32 = rgb
.next()
.and_then(|r| r.trim().parse().ok())
.unwrap_or_else(|| panic!("couldn't get the {}th red-value for {}", i, name));
let green: f32 = rgb
.next()
.and_then(|r| r.trim().parse().ok())
.unwrap_or_else(|| panic!("couldn't get the {}th green-value for {}", i, name));
let blue: f32 = rgb
.next()
.and_then(|r| r.trim().parse().ok())
.unwrap_or_else(|| panic!("couldn't get the {}th blue-value for {}", i, name));
write!(
writer,
"({:.10},{}::new({}, {}, {})),",
(i as f32 / number_of_colors as f32),
color_type,
red,
green,
blue
)
.unwrap();
}
writeln!(writer, "], ::core::marker::PhantomData);").unwrap();
}
}

#[cfg(feature = "named_from_str")]
fn gen_from_str(writer: &mut File, entries: &[(String, String)]) {
use std::io::Write;
Expand All @@ -151,7 +79,3 @@ pub fn build_colors(_writer: &mut File) {}
#[allow(unused)]
#[cfg(not(feature = "named_from_str"))]
fn gen_from_str(_writer: &mut File, _entries: &[(String, String)]) {}

#[allow(unused)]
#[cfg(not(feature = "named_gradients"))]
pub fn build_gradients(_writer: &mut File) {}
Loading

0 comments on commit 1be0fb3

Please sign in to comment.