1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! A `no-std` compatible library for fast color math, intended for use in programming
//! addressable LEDs.
//!
//! Currently this library is geared toward use in embedded systems, but does contain useful
//! APIs that are more generally useful.
//!
//! - **Fast `u8` and `u16` math** — Cichlid includes functions for scaling, dimming, and
//!    brightening single and double byte values. Basic trigonometric functions (sine, cosine)
//!    are implemented as well.
//!
//! - **HSV and RGB support** — Full control over each color is provided by the `HSV` and
//!   `ColorRGB` structures. Different means of converting from `HSV` to `ColorRGB` are also
//!   implemented.
//!
//! - **Axial (Two Point) Color Gradients** — Create smooth transitions between any two colors
//!   for any number of steps.
//!
//! - **Power Consumption Estimating** — Estimating power requirements can be done with
//!   structs implementing the `PowerEstimator` trait.
//!
//! This Library is still in its infancy, and as such there may be a lack of documentation and
//! vigorous testing.
//!
//! # Examples
//!
//! General Color operations:
//!
//! ```
//! use cichlid::ColorRGB;
//!
//! let red = ColorRGB::Red;
//! let blue = ColorRGB::Blue;
//! let mut purple = red + blue;
//! assert_eq!(purple, ColorRGB::new(255, 0, 255));
//!
//! purple.scale(128); // Scale by half
//! assert_eq!(purple, ColorRGB::new(128, 0, 128));
//!
//! purple *= 2;  // Multiple all components by two
//! assert_eq!(purple, red + blue);
//! ```
//!
//! Using `HSV` (Hue, Saturation, Value) and converting to `ColorRGB`:
//!
//! ```
//! use cichlid::{HSV, ColorRGB, prelude::*};
//!
//! let red_hsv = HSV::new(0, 255, 255);
//! let red_rgb = ColorRGB::from(red_hsv);
//! assert_eq!(red_rgb, ColorRGB::Red);
//! ```
//!
//! Creating a gradient is very easy, simply import the trait and call the method:
//!
//! ```
//! use cichlid::{HSV, ColorRGB, GradientDirection, prelude::*};
//! let mut colors = [ColorRGB::Black; 100];
//!
//! let start = HSV::new(0, 255, 255);
//! let end = HSV::new(100, 255, 180);
//! colors.gradient_fill(start, end, GradientDirection::Longest);
//! ```
//!
//! We can also create rainbows from both a step size, as well as a forming a complete rainbow.
//!
//! ```
//! use cichlid::{HSV, ColorRGB, GradientDirection, prelude::*};
//! let mut colors = [ColorRGB::Black; 256];
//!
//! let start_hue: u8 = 0;
//! let hue_delta: u16 = (1 << 8);
//!
//! colors.rainbow_fill(start_hue, hue_delta); // From step size
//! colors.rainbow_fill_single_cycle(start_hue); // Complete rainbow
//! ```
//!
//! # no-std
//!
//! To use in a `no-std` environment, simply add the following to your project's `cargo.toml`:
//!
//! ```ignore
//! [dependencies.cichlid]
//! version = "*"
//! features = ["no-std"]
//! ```
//!
//! # Low memory usage
//!
//! The `low-mem` feature creates a binary that is smaller due to relying less on in memory
//! tables, preferring direct computation instead. The only drawback of this is a slight
//! speed decrease.
//!
//! # Nightly features
//!
//! To use some unstable nightly features and optimizations, use the `nightly` feature flag.
//!
//! # Acknowledgements
//!
//! This library takes heavy inspiration and code-reuse from
//! [FastLED](https://github.com/FastLED/FastLED), an Arduino library for talking to addressable
//! LEDs.

// TODO: SERDE
#![cfg_attr(feature = "no-std", no_std)]
#![cfg_attr(feature = "nightly", feature(link_llvm_intrinsics))]
//#![feature(link_llvm_intrinsics)]

macro_rules! mk_rgb {
    ($r:expr, $g:expr, $b:expr) => {
        crate::rgb::ColorRGB::new($r, $g, $b)
    };
    ($f_rgb:expr) => {
        crate::rgb::ColorRGB::from($f_rgb)
    };
}

//macro_rules! HSV {
//    ($h:expr, $s:expr, $v:expr) => {crate::hsv::HSV::new($h, $s, $v)};
//    ($h:expr) => {crate::hsv::HSV::new($h, 255, 255)};
//}

pub mod color_codes;
mod color_util;
mod hsv;
pub mod math;
mod power_mgmt;
mod rgb;

pub use crate::color_util::GradientDirection;
pub use crate::hsv::HSV;

pub use crate::power_mgmt::{DefaultPowerEstimator, PowerEstimator};
pub use crate::rgb::ColorRGB;
pub use crate::color_util::gradient::{hsv_gradient,rgb_gradient};


pub mod prelude {
    //! Easy importing of integer and color auto traits.

    pub use crate::math::ScalingInt;
    pub use crate::math::Trig;

    pub use crate::color_util::ColorIterMut;
    pub use crate::color_util::ColorSliceMut;

    pub use crate::color_util::GradientFill;
    pub use crate::color_util::GradientFillToInclusive;

    pub use crate::color_util::GradientFillRGB;
    pub use crate::color_util::GradientFillRGBToInclusive;

    pub use crate::color_util::RainbowFill;
    pub use crate::color_util::RainbowFillSingleCycle;
}