style: Extend StyleComplexColor to support additive blending.

Refactored StyleComplexColor to support "complex" blending between
background (numeric) color and foreground color (currentColor).
Made explicit the distinction between numeric, currentColor and a
complex blend in Gecko and Stylo.

This is to support SMIL animation, for example, of the form:

     <animate from="rgb(10,20,30)" by="currentColor" ... />

Bug: 1465307
Reviewed-by: hiro,xidorn
MozReview-Commit-ID: IUAK8P07gtm
This commit is contained in:
Dan Glastonbury 2018-05-23 15:23:26 +10:00 committed by Emilio Cobos Álvarez
parent 3816143a1d
commit 255fe05d40
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
5 changed files with 248 additions and 204 deletions

View file

@ -5,28 +5,21 @@
//! Rust helpers to interact with Gecko's StyleComplexColor.
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
use gecko_bindings::structs::{nscolor, StyleComplexColor};
use gecko_bindings::structs::StyleComplexColor;
use gecko_bindings::structs::StyleComplexColor_Tag as Tag;
use values::{Auto, Either};
use values::computed::Color as ComputedColor;
use values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA};
use values::computed::ComplexColorRatios;
use values::computed::ui::ColorOrAuto;
impl From<nscolor> for StyleComplexColor {
fn from(other: nscolor) -> Self {
StyleComplexColor {
mColor: other,
mForegroundRatio: 0,
mIsAuto: false,
}
}
}
impl StyleComplexColor {
/// Create a `StyleComplexColor` value that represents `currentColor`.
pub fn current_color() -> Self {
StyleComplexColor {
mColor: 0,
mForegroundRatio: 255,
mIsAuto: false,
mBgRatio: 0.,
mFgRatio: 1.,
mTag: Tag::eForeground,
}
}
@ -34,28 +27,66 @@ impl StyleComplexColor {
pub fn auto() -> Self {
StyleComplexColor {
mColor: 0,
mForegroundRatio: 255,
mIsAuto: true,
mBgRatio: 0.,
mFgRatio: 1.,
mTag: Tag::eAuto,
}
}
}
impl From<ComputedRGBA> for StyleComplexColor {
fn from(other: ComputedRGBA) -> Self {
StyleComplexColor {
mColor: convert_rgba_to_nscolor(&other),
mBgRatio: 1.,
mFgRatio: 0.,
mTag: Tag::eNumeric,
}
}
}
impl From<ComputedColor> for StyleComplexColor {
fn from(other: ComputedColor) -> Self {
StyleComplexColor {
mColor: convert_rgba_to_nscolor(&other.color).into(),
mForegroundRatio: other.foreground_ratio,
mIsAuto: false,
match other {
ComputedColor::Numeric(color) => color.into(),
ComputedColor::Foreground => Self::current_color(),
ComputedColor::Complex(color, ratios) => {
debug_assert!(ratios != ComplexColorRatios::NUMERIC);
debug_assert!(ratios != ComplexColorRatios::FOREGROUND);
StyleComplexColor {
mColor: convert_rgba_to_nscolor(&color).into(),
mBgRatio: ratios.bg,
mFgRatio: ratios.fg,
mTag: Tag::eComplex,
}
}
}
}
}
impl From<StyleComplexColor> for ComputedColor {
fn from(other: StyleComplexColor) -> Self {
debug_assert!(!other.mIsAuto);
ComputedColor {
color: convert_nscolor_to_rgba(other.mColor),
foreground_ratio: other.mForegroundRatio,
match other.mTag {
Tag::eNumeric => {
debug_assert!(other.mBgRatio == 1. && other.mFgRatio == 0.);
ComputedColor::Numeric(convert_nscolor_to_rgba(other.mColor))
}
Tag::eForeground => {
debug_assert!(other.mBgRatio == 0. && other.mFgRatio == 1.);
ComputedColor::Foreground
}
Tag::eComplex => {
debug_assert!(other.mBgRatio != 1. || other.mFgRatio != 0.);
debug_assert!(other.mBgRatio != 0. || other.mFgRatio != 1.);
ComputedColor::Complex(
convert_nscolor_to_rgba(other.mColor),
ComplexColorRatios {
bg: other.mBgRatio,
fg: other.mFgRatio,
},
)
}
Tag::eAuto => unreachable!("Unsupport StyleComplexColor with tag eAuto"),
}
}
}
@ -71,7 +102,7 @@ impl From<ColorOrAuto> for StyleComplexColor {
impl From<StyleComplexColor> for ColorOrAuto {
fn from(other: StyleComplexColor) -> Self {
if !other.mIsAuto {
if other.mTag != Tag::eAuto {
Either::First(other.into())
} else {
Either::Second(Auto)