Skip to content

Commit

Permalink
Make Rgb<f32> use [0:1] as range
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Jun 29, 2024
1 parent f3ce44c commit 0e1771d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
16 changes: 12 additions & 4 deletions cursive-core/src/style/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ impl From<u8> for BaseColor {

/// RGB color.
///
/// If `T = u8` this is a 24-bit color.
/// If `T = u8` this is the usual 24-bit true color.
///
/// If `T = f32` this uses floats between 0 and 1.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Rgb<T = u8> {
/// Red component.
Expand Down Expand Up @@ -161,8 +163,12 @@ impl<T> Rgb<T> {

impl Rgb<f32> {
/// Casts each component to u8.
///
/// Goes from `[0:1]` to `[0:255]` range.
pub fn as_u8(self) -> Rgb<u8> {
self.map(|x| x as u8)
// Going from [0:1.0] to [0:255]
// We add 0.5 to make sure the float is above the integer we want.
self.map(|x| (0.5 + (x.clamp(0.0, 1.0) * 255.0).round()) as u8)
}

/// Convert to a Color.
Expand All @@ -173,6 +179,8 @@ impl Rgb<f32> {

impl Rgb<(f32, f32)> {
/// Interpolate each component individually.
///
/// This is a simple linear interpolation per channel.
pub fn interpolate(self, x: f32) -> Rgb<f32> {
self.map(|(a, b)| a * (1f32 - x) + b * x)
}
Expand All @@ -181,7 +189,7 @@ impl Rgb<(f32, f32)> {
impl Rgb<(u8, u8)> {
/// Cast each component to a tuple of f32.
pub fn as_f32(self) -> Rgb<(f32, f32)> {
self.map(|(x, y)| (x as f32, y as f32))
self.map(|(x, y)| (x as f32 / 255.0, y as f32 / 255.0))
}
}

Expand All @@ -203,7 +211,7 @@ impl Rgb<u8> {

/// Cast each component to f32.
pub fn as_f32(self) -> Rgb<f32> {
self.map(|x| x as f32)
self.map(|x| x as f32 / 255.0)
}

/// Returns a pure red RGB color.
Expand Down
34 changes: 27 additions & 7 deletions cursive-core/src/style/gradient/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
//! Gradients
//!
//! This module defines a few types to help work with gradients:
//!
//! * [`Linear`] is a 1-dimensional (linear) piecewise gradient: given a float value between 0 and
//! 1, it returns the interpolated [`crate::style::Rgb`] color at that point.
//! * A few 2D gradients assign float values between 0 and 1 to each cell of a grid, and internally
//! use a `Linear` gradient to convert that to a color.
//! * [`Angled`] applies its linear gradient on the 2D grid at an angle.
//! * [`Radial`] applies its linear gradient according to the distance from a center.
//! * [`Bilinear`] uses bilinear interpolation between the 4 corners to compute the color for
//! each cell.
//!
//! Note that this module works with `Rgb<f32>`, where each color has a f32 value between 0 and 1.
//! Various conversions to/from `Rgb<u8>` and [`crate::style::Color`] are available.
use crate::{style::Rgb, Vec2, XY};

/// A linear gradient interpolating between 0 and 1.
/// A 2D color distribution.
///
/// Types implementing this trait can assign a color to each point of a grid.
pub trait Interpolator {
/// Get the color for the given position, given the total size of the area to cover.
///
/// The resulting value uses floats between 0 and 1.
fn interpolate(&self, pos: Vec2, size: Vec2) -> Rgb<f32>;
}

/// A linear gradient interpolating color for floats between 0 and 1.
pub struct Linear {
/// Color for the start of the gradient.
pub start: Rgb<f32>,
Expand Down Expand Up @@ -53,6 +77,8 @@ impl Linear {
}

/// Interpolate the color for the given position.
///
/// The resulting value uses floats between 0 and 1.
pub fn interpolate(&self, x: f32) -> Rgb<f32> {
// Find the segment
if x <= 0f32 {
Expand Down Expand Up @@ -151,12 +177,6 @@ pub struct Angled {
pub gradient: Linear,
}

/// Something that can interpolate.
pub trait Interpolator {
/// Get the color for the given position, given the total size.
fn interpolate(&self, pos: Vec2, size: Vec2) -> Rgb<f32>;
}

impl Interpolator for Angled {
fn interpolate(&self, mut pos: Vec2, mut size: Vec2) -> Rgb<f32> {
use std::f32::consts::{FRAC_PI_2, PI, TAU};
Expand Down

0 comments on commit 0e1771d

Please sign in to comment.