--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3748,18 +3748,18 @@ nsCSSBorderImageRenderer::CreateWebRende
wr::ToRepeatMode(mRepeatModeHorizontal),
wr::ToRepeatMode(mRepeatModeVertical));
break;
}
case eStyleImageType_Gradient:
{
RefPtr<nsStyleGradient> gradientData = mImageRenderer.GetGradientData();
nsCSSGradientRenderer renderer =
- nsCSSGradientRenderer::Create(aForFrame->PresContext(), gradientData,
- mImageSize);
+ nsCSSGradientRenderer::Create(aForFrame->PresContext(), aForFrame->Style(),
+ gradientData, mImageSize);
wr::ExtendMode extendMode;
nsTArray<wr::GradientStop> stops;
LayoutDevicePoint lineStart;
LayoutDevicePoint lineEnd;
LayoutDeviceSize gradientRadius;
renderer.BuildWebRenderParameters(1.0, extendMode, stops, lineStart, lineEnd, gradientRadius);
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -564,17 +564,18 @@ GetSpecifiedGradientPosition(const nsSty
}
default:
MOZ_ASSERT_UNREACHABLE("Unknown unit in gradient color stop position?");
return Nothing();
}
}
static nsTArray<ColorStop>
-ComputeColorStops(const nsStyleGradient& aGradient,
+ComputeColorStops(ComputedStyle* aComputedStyle,
+ const nsStyleGradient& aGradient,
int32_t aAppUnitsPerPixel,
gfxFloat aLineLength)
{
MOZ_ASSERT(aGradient.mStops.Length() >= 2,
"The parser should reject gradients with less than two stops");
nsTArray<ColorStop> stops(aGradient.mStops.Length());
@@ -602,31 +603,33 @@ ComputeColorStops(const nsStyleGradient&
} else {
// Other stops with no specified position get their position assigned
// later by interpolation, see below.
// Remember where the run of stops with no specified position starts,
// if it starts here.
if (firstUnsetPosition < 0) {
firstUnsetPosition = i;
}
+ auto stopColor = stop.mColor.CalcColor(aComputedStyle);
stops.AppendElement(ColorStop(0, stop.mIsInterpolationHint,
- Color::FromABGR(stop.mColor)));
+ Color::FromABGR(stopColor)));
continue;
}
if (i > 0) {
// Prevent decreasing stop positions by advancing this position
// to the previous stop position, if necessary
double previousPosition = firstUnsetPosition > 0
? stops[firstUnsetPosition - 1].mPosition
: stops[i - 1].mPosition;
position = std::max(position, previousPosition);
}
+ auto stopColor = stop.mColor.CalcColor(aComputedStyle);
stops.AppendElement(ColorStop(position, stop.mIsInterpolationHint,
- Color::FromABGR(stop.mColor)));
+ Color::FromABGR(stopColor)));
if (firstUnsetPosition > 0) {
// Interpolate positions for all stops that didn't have a specified position
double p = stops[firstUnsetPosition - 1].mPosition;
double d = (stops[i].mPosition - p)/(i - firstUnsetPosition + 1);
for (uint32_t j = firstUnsetPosition; j < i; ++j) {
p += d;
stops[j].mPosition = p;
}
@@ -634,18 +637,19 @@ ComputeColorStops(const nsStyleGradient&
}
}
return stops;
}
nsCSSGradientRenderer
nsCSSGradientRenderer::Create(nsPresContext* aPresContext,
- nsStyleGradient* aGradient,
- const nsSize& aIntrinsicSize)
+ ComputedStyle* aComputedStyle,
+ nsStyleGradient* aGradient,
+ const nsSize& aIntrinsicSize)
{
nscoord appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
gfxSize srcSize = gfxSize(gfxFloat(aIntrinsicSize.width)/appUnitsPerDevPixel,
gfxFloat(aIntrinsicSize.height)/appUnitsPerDevPixel);
// Compute "gradient line" start and end relative to the intrinsic size of
// the gradient.
gfxPoint lineStart, lineEnd;
@@ -661,17 +665,17 @@ nsCSSGradientRenderer::Create(nsPresCont
if (!lineStart.IsFinite() || !lineEnd.IsFinite()) {
lineStart = lineEnd = gfxPoint(0, 0);
}
gfxFloat lineLength = NS_hypot(lineEnd.x - lineStart.x,
lineEnd.y - lineStart.y);
// Build color stop array and compute stop positions
nsTArray<ColorStop> stops =
- ComputeColorStops(*aGradient, appUnitsPerDevPixel, lineLength);
+ ComputeColorStops(aComputedStyle, *aGradient, appUnitsPerDevPixel, lineLength);
ResolveMidpoints(stops);
nsCSSGradientRenderer renderer;
renderer.mPresContext = aPresContext;
renderer.mGradient = aGradient;
renderer.mStops = std::move(stops);
renderer.mLineStart = lineStart;
--- a/layout/painting/nsCSSRenderingGradients.h
+++ b/layout/painting/nsCSSRenderingGradients.h
@@ -36,16 +36,17 @@ struct ColorStop {
class nsCSSGradientRenderer final {
public:
/**
* Prepare a nsCSSGradientRenderer for a gradient for an element.
* aIntrinsicSize - the size of the source gradient.
*/
static nsCSSGradientRenderer Create(nsPresContext* aPresContext,
+ ComputedStyle* aComputedStyle,
nsStyleGradient* aGradient,
const nsSize& aIntrinsiceSize);
/**
* Draw the gradient to aContext
* aDest - where the first tile of gradient is
* aFill - the area to be filled with tiles of aDest
* aSrc - the area of the gradient that will fill aDest
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5438,18 +5438,18 @@ nsDisplayBorder::CreateBorderImageWebRen
wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeHorizontal),
wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeVertical));
break;
}
case eStyleImageType_Gradient:
{
RefPtr<nsStyleGradient> gradientData = mBorderImageRenderer->mImageRenderer.GetGradientData();
nsCSSGradientRenderer renderer =
- nsCSSGradientRenderer::Create(mFrame->PresContext(), gradientData,
- mBorderImageRenderer->mImageSize);
+ nsCSSGradientRenderer::Create(mFrame->PresContext(), mFrame->Style(),
+ gradientData, mBorderImageRenderer->mImageSize);
wr::ExtendMode extendMode;
nsTArray<wr::GradientStop> stops;
LayoutDevicePoint lineStart;
LayoutDevicePoint lineEnd;
LayoutDeviceSize gradientRadius;
renderer.BuildWebRenderParameters(1.0, extendMode, stops, lineStart, lineEnd, gradientRadius);
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -504,17 +504,18 @@ nsImageRenderer::Draw(nsPresContext*
aAnchor, aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags),
mExtendMode, aOpacity);
break;
}
case eStyleImageType_Gradient:
{
nsCSSGradientRenderer renderer =
- nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
+ nsCSSGradientRenderer::Create(aPresContext, mForFrame->Style(),
+ mGradientData, mSize);
renderer.Paint(*ctx, aDest, aFill, aRepeatSize, aSrc, aDirtyRect, aOpacity);
break;
}
case eStyleImageType_Element:
{
RefPtr<gfxDrawable> drawable = DrawableForElement(aDest, *ctx);
if (!drawable) {
@@ -581,17 +582,18 @@ nsImageRenderer::BuildWebRenderDisplayIt
mSize.width <= 0 || mSize.height <= 0) {
return ImgDrawResult::SUCCESS;
}
switch (mType) {
case eStyleImageType_Gradient:
{
nsCSSGradientRenderer renderer =
- nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
+ nsCSSGradientRenderer::Create(aPresContext, mForFrame->Style(),
+ mGradientData, mSize);
renderer.BuildWebRenderDisplayItems(aBuilder, aSc, aDest, aFill,
aRepeatSize, aSrc, !aItem->BackfaceIsHidden(), aOpacity);
break;
}
case eStyleImageType_Image:
{
uint32_t containerFlags = imgIContainer::FLAG_ASYNC_NOTIFY;
@@ -992,17 +994,18 @@ nsImageRenderer::DrawShapeImage(nsPresCo
dest, dest, Nothing(),
drawFlags,
nullptr, nullptr);
break;
}
case eStyleImageType_Gradient: {
nsCSSGradientRenderer renderer =
- nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
+ nsCSSGradientRenderer::Create(aPresContext, mForFrame->Style(),
+ mGradientData, mSize);
nsRect dest(nsPoint(0, 0), mSize);
renderer.Paint(aRenderingContext, dest, dest, mSize,
CSSIntRect::FromAppUnitsRounded(dest),
dest, 1.0);
break;
}
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1644,20 +1644,21 @@ Gecko_CreateGradient(uint8_t aShape,
result->mMozLegacySyntax = aMozLegacySyntax;
result->mAngle.SetNoneValue();
result->mBgPosX.SetNoneValue();
result->mBgPosY.SetNoneValue();
result->mRadiusX.SetNoneValue();
result->mRadiusY.SetNoneValue();
- nsStyleGradientStop dummyStop;
- dummyStop.mLocation.SetNoneValue();
- dummyStop.mColor = NS_RGB(0, 0, 0);
- dummyStop.mIsInterpolationHint = 0;
+ nsStyleGradientStop dummyStop = {
+ nsStyleCoord(eStyleUnit_None),
+ StyleComplexColor::FromColor(NS_RGB(0, 0, 0)),
+ 0
+ };
for (uint32_t i = 0; i < aStopCount; i++) {
result->mStops.AppendElement(dummyStop);
}
return result;
}
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2509,17 +2509,17 @@ nsComputedDOMStyle::GetCSSGradientString
// color stops
for (uint32_t i = 0; i < aGradient->mStops.Length(); ++i) {
if (needSep) {
aString.AppendLiteral(", ");
}
const auto& stop = aGradient->mStops[i];
if (!stop.mIsInterpolationHint) {
- SetToRGBAColor(tmpVal, stop.mColor);
+ SetValueFromComplexColor(tmpVal, stop.mColor);
tmpVal->GetCssText(tokenString);
aString.Append(tokenString);
}
if (stop.mLocation.GetUnit() != eStyleUnit_None) {
if (!stop.mIsInterpolationHint) {
aString.Append(' ');
}
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2008,17 +2008,19 @@ nsStyleGradient::nsStyleGradient()
, mMozLegacySyntax(false)
{
}
bool
nsStyleGradient::IsOpaque()
{
for (uint32_t i = 0; i < mStops.Length(); i++) {
- if (NS_GET_A(mStops[i].mColor) < 255) {
+ if (mStops[i].mColor.MaybeTransparent()) {
+ // We don't know the foreground color here, so if it's being used
+ // we must assume it might be transparent.
return false;
}
}
return true;
}
bool
nsStyleGradient::HasCalc()
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -156,17 +156,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
nscoord mScriptMinSize; // [inherited] length
float mScriptSizeMultiplier; // [inherited]
RefPtr<nsAtom> mLanguage; // [inherited]
};
struct nsStyleGradientStop
{
nsStyleCoord mLocation; // percent, coord, calc, none
- nscolor mColor;
+ mozilla::StyleComplexColor mColor;
bool mIsInterpolationHint;
// Use ==/!= on nsStyleGradient instead of on the gradient stop.
bool operator==(const nsStyleGradientStop&) const = delete;
bool operator!=(const nsStyleGradientStop&) const = delete;
};
class nsStyleGradient final
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -4,17 +4,17 @@
//! This module contains conversion helpers between Servo and Gecko types
//! Ideally, it would be in geckolib itself, but coherence
//! forces us to keep the traits and implementations here
#![allow(unsafe_code)]
use app_units::Au;
-use gecko::values::{convert_rgba_to_nscolor, GeckoStyleCoordConvertible};
+use gecko::values::GeckoStyleCoordConvertible;
use gecko_bindings::bindings;
use gecko_bindings::structs::{self, nsCSSUnit, nsStyleCoord_CalcValue};
use gecko_bindings::structs::{nsresult, SheetType, nsStyleImage};
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
use std::f32::consts::PI;
use stylesheets::{Origin, RulesMutateError};
use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto};
@@ -353,17 +353,17 @@ impl nsStyleImage {
// NB: stops are guaranteed to be none in the gecko side by
// default.
let gecko_stop = unsafe { &mut (*gecko_gradient).mStops[index] };
let mut coord = nsStyleCoord::null();
match *item {
GradientItem::ColorStop(ref stop) => {
- gecko_stop.mColor = convert_rgba_to_nscolor(&stop.color);
+ gecko_stop.mColor = stop.color.into();
gecko_stop.mIsInterpolationHint = false;
coord.set(stop.position);
},
GradientItem::InterpolationHint(hint) => {
gecko_stop.mIsInterpolationHint = true;
coord.set(Some(hint));
},
}
@@ -428,17 +428,16 @@ impl nsStyleImage {
unsafe fn get_image_url(&self) -> ComputedImageUrl {
let image_request = bindings::Gecko_GetImageRequest(self)
.as_ref().expect("Null image request?");
ComputedImageUrl::from_image_request(image_request)
}
unsafe fn get_gradient(self: &nsStyleImage) -> Box<Gradient> {
- use gecko::values::convert_nscolor_to_rgba;
use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER;
use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
use values::computed::{Length, LengthOrPercentage};
use values::computed::image::LineDirection;
use values::computed::position::Position;
use values::generics::image::{Circle, ColorStop, CompatMode, Ellipse};
@@ -596,17 +595,17 @@ impl nsStyleImage {
.map(|ref stop| {
if stop.mIsInterpolationHint {
GradientItem::InterpolationHint(
LengthOrPercentage::from_gecko_style_coord(&stop.mLocation)
.expect("mLocation could not convert to LengthOrPercentage"),
)
} else {
GradientItem::ColorStop(ColorStop {
- color: convert_nscolor_to_rgba(stop.mColor),
+ color: stop.mColor.into(),
position: LengthOrPercentage::from_gecko_style_coord(&stop.mLocation),
})
}
})
.collect();
let compat_mode = if gecko_gradient.mMozLegacySyntax {
CompatMode::Moz
--- a/servo/components/style/values/computed/image.rs
+++ b/servo/components/style/values/computed/image.rs
@@ -2,22 +2,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! CSS handling for the computed value of
//! [`image`][image]s
//!
//! [image]: https://drafts.csswg.org/css-images/#image-values
-use cssparser::RGBA;
use std::f32::consts::PI;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::{Either, None_};
-use values::computed::{Angle, Context};
+use values::computed::{Angle, Color, Context};
use values::computed::{Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue};
#[cfg(feature = "gecko")]
use values::computed::Percentage;
use values::computed::position::Position;
use values::computed::url::ComputedImageUrl;
use values::generics::image::{self as generic, CompatMode};
use values::specified::image::LineDirection as SpecifiedLineDirection;
use values::specified::position::{X, Y};
@@ -27,17 +26,17 @@ pub type ImageLayer = Either<None_, Imag
/// Computed values for an image according to CSS-IMAGES.
/// <https://drafts.csswg.org/css-images/#image-values>
pub type Image = generic::Image<Gradient, MozImageRect, ComputedImageUrl>;
/// Computed values for a CSS gradient.
/// <https://drafts.csswg.org/css-images/#gradients>
pub type Gradient =
- generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, RGBA, Angle>;
+ generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, Color, Angle>;
/// A computed gradient kind.
pub type GradientKind =
generic::GradientKind<LineDirection, Length, LengthOrPercentage, Position, Angle>;
/// A computed gradient line direction.
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub enum LineDirection {
@@ -53,20 +52,20 @@ pub enum LineDirection {
#[cfg(feature = "gecko")]
MozPosition(Option<Position>, Option<Angle>),
}
/// A computed radial gradient ending shape.
pub type EndingShape = generic::EndingShape<Length, LengthOrPercentage>;
/// A computed gradient item.
-pub type GradientItem = generic::GradientItem<RGBA, LengthOrPercentage>;
+pub type GradientItem = generic::GradientItem<Color, LengthOrPercentage>;
/// A computed color stop.
-pub type ColorStop = generic::ColorStop<RGBA, LengthOrPercentage>;
+pub type ColorStop = generic::ColorStop<Color, LengthOrPercentage>;
/// Computed values for `-moz-image-rect(...)`.
pub type MozImageRect = generic::MozImageRect<NumberOrPercentage, ComputedImageUrl>;
impl generic::LineDirection for LineDirection {
fn points_downwards(&self, compat_mode: CompatMode) -> bool {
match *self {
LineDirection::Angle(angle) => angle.radians() == PI,
--- a/servo/components/style/values/specified/image.rs
+++ b/servo/components/style/values/specified/image.rs
@@ -21,44 +21,38 @@ use style_traits::{CssType, CssWriter, K
use style_traits::{StyleParseErrorKind, SpecifiedValueInfo, ToCss};
use values::{Either, None_};
#[cfg(feature = "gecko")]
use values::computed::{Context, Position as ComputedPosition, ToComputedValue};
use values::generics::image::{self as generic, Circle, CompatMode, Ellipse, ShapeExtent};
use values::generics::image::PaintWorklet;
use values::generics::position::Position as GenericPosition;
use values::specified::{Angle, Color, Length, LengthOrPercentage};
-use values::specified::{Number, NumberOrPercentage, Percentage, RGBAColor};
+use values::specified::{Number, NumberOrPercentage, Percentage};
use values::specified::position::{LegacyPosition, Position, PositionComponent, Side, X, Y};
use values::specified::url::SpecifiedImageUrl;
/// A specified image layer.
pub type ImageLayer = Either<None_, Image>;
/// Specified values for an image according to CSS-IMAGES.
/// <https://drafts.csswg.org/css-images/#image-values>
pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>;
/// Specified values for a CSS gradient.
/// <https://drafts.csswg.org/css-images/#gradients>
#[cfg(not(feature = "gecko"))]
pub type Gradient =
- generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, RGBAColor, Angle>;
+ generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, Color, Angle>;
/// Specified values for a CSS gradient.
/// <https://drafts.csswg.org/css-images/#gradients>
#[cfg(feature = "gecko")]
-pub type Gradient = generic::Gradient<
- LineDirection,
- Length,
- LengthOrPercentage,
- GradientPosition,
- RGBAColor,
- Angle,
->;
+pub type Gradient =
+ generic::Gradient<LineDirection, Length, LengthOrPercentage, GradientPosition, Color, Angle>;
impl SpecifiedValueInfo for Gradient {
const SUPPORTED_TYPES: u8 = CssType::GRADIENT;
fn collect_completion_keywords(f: KeywordsCollectFn) {
// This list here should keep sync with that in Gradient::parse.
f(&[
"linear-gradient",
@@ -116,20 +110,20 @@ pub enum GradientPosition {
/// 1, 2-valued <position>.
Legacy(LegacyPosition),
}
/// A specified ending shape.
pub type EndingShape = generic::EndingShape<Length, LengthOrPercentage>;
/// A specified gradient item.
-pub type GradientItem = generic::GradientItem<RGBAColor, LengthOrPercentage>;
+pub type GradientItem = generic::GradientItem<Color, LengthOrPercentage>;
/// A computed color stop.
-pub type ColorStop = generic::ColorStop<RGBAColor, LengthOrPercentage>;
+pub type ColorStop = generic::ColorStop<Color, LengthOrPercentage>;
/// Specified values for `moz-image-rect`
/// -moz-image-rect(<uri>, top, right, bottom, left);
pub type MozImageRect = generic::MozImageRect<NumberOrPercentage, SpecifiedImageUrl>;
impl Parse for Image {
fn parse<'i, 't>(
context: &ParserContext,
@@ -952,17 +946,17 @@ impl GradientItem {
}
impl Parse for ColorStop {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Ok(ColorStop {
- color: RGBAColor::parse(context, input)?,
+ color: Color::parse(context, input)?,
position: input.try(|i| LengthOrPercentage::parse(context, i)).ok(),
})
}
}
impl Parse for PaintWorklet {
fn parse<'i, 't>(
_context: &ParserContext,