-
-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for transparency #162
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much!
Great PR description, implementation and tests!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, updated with a few changes:
- remove support for the
/ alpha
notation - updated the CLI help for
color
to include alpha transparency notation - omit trailing zeroes when printing decimal alpha values
I originally had a function like this to implement max precision:
fn max_precision(value: f64, max_precision: u32) -> String {
// (...snip...)
format!("{}", rounded)
}
but I ended up going with a struct MaxPrecision
that implements std::fmt::Display
to save the String
allocation. I'm still fairly new to Rust so let me know your thoughts on this 🙂.
#[test] | ||
fn alpha_roundtrip_hex_to_decimal() { | ||
// We use a max of 3 decimal places when displaying RGB floating point | ||
// alpha values. This test insures that is sufficient to "roundtrip" | ||
// from hex (0 < n < 255) to float (0 < n < 1) and back again, | ||
// e.g. hex `80` is float `0.502`, which parses to hex `80`, and so on. | ||
for alpha_int in 0..255 { | ||
let hex_string = format!("#000000{:02x}", alpha_int); | ||
let parsed_from_hex = hex_string.parse::<Color>().unwrap(); | ||
let rgba_string = parsed_from_hex.to_rgb_float_string(Format::Spaces); | ||
let parsed_from_rgba = rgba_string.parse::<Color>().unwrap(); | ||
assert_eq!(hex_string, parsed_from_rgba.to_rgb_hex_string(true)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I think this should provide proper coverage. This asserts that:
- for every hex alpha value, 0 < n < 255 (
00
-fe
) - parsing a color with this alpha, in hex notation
- outputting that color as
rgba()
, with alpha as decimal - parsing that color
- outputting that color using hex notation
- generates the same value as the original hex input string
For example, #00000080
parses to a color that stringifies to rgba(0, 0, 0, 0.502)
, that in turn parses to a color that stringifies to #00000080
. This actually caught a bug, where I was outputting alpha hex values using (f64 * 255.) as u8
, when I should have been using (f64 * 255.).round() as u8
.
I also threw in an impl FromStr for Color
that calls parser::parse_color
, that's not required, just thought it may be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
This PR adds support for parsing and displaying partially transparent colors. It adds a new function
Color::composite
which implements simple alpha compositing, and uses this to enhanceCanvas::draw_rect
to support painting partially transparent pixels over existing pixels. This is used to enable drawing color previews for transparent colors (see example below).Additionally, this PR enhances the parser to support parsing all common alpha formats, including:
RGBA
RRGGBBAA
rgba()
hsla()
The
lab
parser also supports specifying alpha. The alpha value may be provided as a double or percentage, and may be slash, comma, or space delimited; all of the following are valid:rgba(255 127 0 0.4)
rgba(255, 127, 0, 0.4)
rgba(255, 127, 0, 40%)
For backwards compatibility,
rgb()
andhsl()
also support alpha values. You can check theparse_alpha_syntax
test to see all supported formats.All
Color::to_*_string
methods now include the alpha value when it's not1.0
, and omit it when it is.Closes #131.
Open Questions
This PR doesn't update the simplified format used when displaying colors with
pastel format
(the alpha channel value will be displayed, but the color itself will be fully opaque). It also doesn't add support for rendering colored text with partial transparency.Example