Skip to content
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

Support interpolation between currentcolor and numeric color #17219

Merged
merged 10 commits into from Jun 8, 2017

Some generated files are not rendered by default. Learn more.

@@ -14,7 +14,6 @@ app_units = "0.4.1"
atomic_refcell = "0.1"
bitflags = "0.7"
canvas_traits = {path = "../canvas_traits"}
cssparser = "0.13.7"
euclid = "0.13"
fnv = "1.0"
gfx = {path = "../gfx"}
@@ -422,17 +422,15 @@ pub trait FragmentDisplayListBuilding {
bounds: &Rect<Au>,
stops: &[GradientItem],
direction: &LineDirection,
repeating: bool,
style: &ServoComputedValues)
repeating: bool)
-> display_list::Gradient;

fn convert_radial_gradient(&self,
bounds: &Rect<Au>,
stops: &[GradientItem],
shape: &EndingShape,
center: &Position,
repeating: bool,
style: &ServoComputedValues)
repeating: bool)
-> display_list::RadialGradient;

/// Adds the display items necessary to paint the background linear gradient of this fragment
@@ -634,8 +632,7 @@ fn build_border_radius_for_inner_rect(outer_rect: &Rect<Au>,
}

fn convert_gradient_stops(gradient_items: &[GradientItem],
total_length: Au,
style: &ServoComputedValues) -> Vec<GradientStop> {
total_length: Au) -> Vec<GradientStop> {
// Determine the position of each stop per CSS-IMAGES § 3.4.

// Only keep the color stops, discard the color interpolation hints.
@@ -722,7 +719,7 @@ fn convert_gradient_stops(gradient_items: &[GradientItem],
};
stops.push(GradientStop {
offset: offset,
color: style.resolve_color(stop.color).to_gfx_color()
color: stop.color.to_gfx_color()
})
}
stops
@@ -1192,8 +1189,7 @@ impl FragmentDisplayListBuilding for Fragment {
bounds: &Rect<Au>,
stops: &[GradientItem],
direction: &LineDirection,
repeating: bool,
style: &ServoComputedValues)
repeating: bool)
-> display_list::Gradient {
let angle = match *direction {
LineDirection::Angle(angle) => angle.radians(),
@@ -1234,7 +1230,7 @@ impl FragmentDisplayListBuilding for Fragment {
let length = Au::from_f32_px(
(delta.x.to_f32_px() * 2.0).hypot(delta.y.to_f32_px() * 2.0));

let mut stops = convert_gradient_stops(stops, length, style);
let mut stops = convert_gradient_stops(stops, length);

// Only clamped gradients need to be fixed because in repeating gradients
// there is no "first" or "last" stop because they repeat infinitly in
@@ -1258,8 +1254,7 @@ impl FragmentDisplayListBuilding for Fragment {
stops: &[GradientItem],
shape: &EndingShape,
center: &Position,
repeating: bool,
style: &ServoComputedValues)
repeating: bool)
-> display_list::RadialGradient {
let center = Point2D::new(center.horizontal.to_used_value(bounds.size.width),
center.vertical.to_used_value(bounds.size.height));
@@ -1278,7 +1273,7 @@ impl FragmentDisplayListBuilding for Fragment {
},
};

let mut stops = convert_gradient_stops(stops, radius.width, style);
let mut stops = convert_gradient_stops(stops, radius.width);
// Repeating gradients have no last stops that can be ignored. So
// fixup is not necessary but may actually break the gradient.
if !repeating {
@@ -1322,8 +1317,7 @@ impl FragmentDisplayListBuilding for Fragment {
let gradient = self.convert_linear_gradient(&bounds,
&gradient.items[..],
angle_or_corner,
gradient.repeating,
style);
gradient.repeating);
DisplayItem::Gradient(box GradientDisplayItem {
base: base,
gradient: gradient,
@@ -1334,8 +1328,7 @@ impl FragmentDisplayListBuilding for Fragment {
&gradient.items[..],
shape,
center,
gradient.repeating,
style);
gradient.repeating);
DisplayItem::RadialGradient(box RadialGradientDisplayItem {
base: base,
gradient: gradient,
@@ -1459,8 +1452,7 @@ impl FragmentDisplayListBuilding for Fragment {
let grad = self.convert_linear_gradient(&bounds,
&gradient.items[..],
&angle_or_corner,
gradient.repeating,
style);
gradient.repeating);

state.add_display_item(DisplayItem::Border(box BorderDisplayItem {
base: base,
@@ -1478,8 +1470,7 @@ impl FragmentDisplayListBuilding for Fragment {
&gradient.items[..],
shape,
center,
gradient.repeating,
style);
gradient.repeating);
state.add_display_item(DisplayItem::Border(box BorderDisplayItem {
base: base,
border_widths: border.to_physical(style.writing_mode),
@@ -16,7 +16,6 @@ extern crate atomic_refcell;
extern crate bitflags;
extern crate canvas_traits;
extern crate core;
extern crate cssparser;
extern crate euclid;
extern crate fnv;
extern crate gfx;
@@ -9,7 +9,6 @@
use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use context::LayoutContext;
use cssparser::Color;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow};
@@ -22,6 +21,7 @@ use std::fmt;
use style::computed_values::{border_collapse, border_top_style, vertical_align};
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::ServoComputedValues;
use style::values::computed::Color;
use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance};

@@ -9,7 +9,6 @@
use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer};
use context::LayoutContext;
use cssparser::{Color, RGBA};
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
use euclid::Point2D;
use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
@@ -26,7 +25,7 @@ use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::ServoComputedValues;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::values::computed::LengthOrPercentageOrAuto;
use style::values::computed::{Color, LengthOrPercentageOrAuto};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow};

@@ -606,7 +605,7 @@ impl CollapsedBorder {
CollapsedBorder {
style: border_top_style::T::none,
width: Au(0),
color: Color::RGBA(RGBA::transparent()),
color: Color::transparent(),
provenance: CollapsedBorderProvenance::FromTable,
}
}
@@ -4,7 +4,6 @@

//! Element nodes.

use cssparser::Color;
use devtools_traits::AttrInfo;
use dom::activation::Activatable;
use dom::attr::{Attr, AttrHelpersForLayout};
@@ -112,7 +111,7 @@ use style::stylearc::Arc;
use style::stylist::ApplicableDeclarationBlock;
use style::thread_state;
use style::values::{CSSFloat, Either};
use style::values::specified::{self, CSSColor};
use style::values::specified;
use stylesheet_loader::StylesheetOwner;

// TODO: Update focus state when the top-level browsing context gains or loses system focus,
@@ -421,8 +420,8 @@ impl LayoutElementHelpers for LayoutJS<Element> {
if let Some(color) = bgcolor {
hints.push(from_declaration(
shared_lock,
PropertyDeclaration::BackgroundColor(
CSSColor { parsed: Color::RGBA(color), authored: None })));
PropertyDeclaration::BackgroundColor(color.into())
));
}

let background = if let Some(this) = self.downcast::<HTMLBodyElement>() {
@@ -456,10 +455,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
hints.push(from_declaration(
shared_lock,
PropertyDeclaration::Color(
longhands::color::SpecifiedValue(CSSColor {
parsed: Color::RGBA(color),
authored: None,
})
longhands::color::SpecifiedValue(color.into())
)
));
}
@@ -183,7 +183,6 @@ impl nsStyleImage {
}

fn set_gradient(&mut self, gradient: Gradient) {
use cssparser::Color as CSSColor;
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SHAPE_CIRCULAR, NS_STYLE_GRADIENT_SHAPE_ELLIPTICAL};
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SHAPE_LINEAR, NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER};
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE, NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE};
@@ -321,19 +320,7 @@ impl nsStyleImage {

match *item {
GradientItem::ColorStop(ref stop) => {
gecko_stop.mColor = match stop.color {
CSSColor::CurrentColor => {
// TODO(emilio): gecko just stores an nscolor,
// and it doesn't seem to support currentColor
// as value in a gradient.
//
// Double-check it and either remove
// currentColor for servo or see how gecko
// handles this.
0
},
CSSColor::RGBA(ref rgba) => convert_rgba_to_nscolor(rgba),
};
gecko_stop.mColor = convert_rgba_to_nscolor(&stop.color);
gecko_stop.mIsInterpolationHint = false;
coord.set(stop.position);
},
@@ -5,10 +5,9 @@
//! Rust helpers for Gecko's `nsCSSShadowItem`.

use app_units::Au;
use cssparser::Color;
use gecko::values::{convert_rgba_to_nscolor, convert_nscolor_to_rgba};
use gecko_bindings::structs::nsCSSShadowItem;
use values::computed::Shadow;
use values::computed::{Color, Shadow};

impl nsCSSShadowItem {
/// Set this item to the given shadow value.
@@ -18,14 +17,14 @@ impl nsCSSShadowItem {
self.mRadius = other.blur_radius.0;
self.mSpread = other.spread_radius.0;
self.mInset = other.inset;
self.mColor = match other.color {
Color::RGBA(rgba) => {
self.mHasColor = true;
convert_rgba_to_nscolor(&rgba)
},
if other.color.is_currentcolor() {
// TODO handle currentColor
// https://bugzilla.mozilla.org/show_bug.cgi?id=760345
Color::CurrentColor => 0,
self.mHasColor = false;
self.mColor = 0;
} else {
self.mHasColor = true;
self.mColor = convert_rgba_to_nscolor(&other.color.color);
}
}

@@ -37,7 +36,7 @@ impl nsCSSShadowItem {
blur_radius: Au(self.mRadius),
spread_radius: Au(self.mSpread),
inset: self.mInset,
color: Color::RGBA(convert_nscolor_to_rgba(self.mColor)),
color: Color::rgba(convert_nscolor_to_rgba(self.mColor)),
}
}
}
@@ -4,10 +4,10 @@

//! Rust helpers to interact with Gecko's StyleComplexColor.

use cssparser;
use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor};
use gecko_bindings::structs::{nscolor, StyleComplexColor};
use values;
use values::{Auto, Either};
use values::computed::Color as ComputedColor;

impl From<nscolor> for StyleComplexColor {
fn from(other: nscolor) -> Self {
@@ -39,40 +39,41 @@ impl StyleComplexColor {
}
}

impl From<cssparser::Color> for StyleComplexColor {
fn from(other: cssparser::Color) -> Self {
use cssparser::Color;

match other {
Color::RGBA(rgba) => convert_rgba_to_nscolor(&rgba).into(),
Color::CurrentColor => StyleComplexColor::current_color(),
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,
}
}
}

impl From<StyleComplexColor> for values::computed::ColorOrAuto {
fn from(color: StyleComplexColor) -> Self {
use values::{Auto, Either};

if color.mIsAuto {
return Either::Second(Auto);
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,
}
}
}

Either::First(color.into())
impl From<Either<ComputedColor, Auto>> for StyleComplexColor {
fn from(other: Either<ComputedColor, Auto>) -> Self {
match other {
Either::First(color) => color.into(),
Either::Second(_auto) => StyleComplexColor::auto(),
}
}
}

impl From<StyleComplexColor> for cssparser::Color {
impl From<StyleComplexColor> for Either<ComputedColor, Auto> {
fn from(other: StyleComplexColor) -> Self {
use cssparser::Color;

if other.mForegroundRatio == 0 {
Color::RGBA(convert_nscolor_to_rgba(other.mColor))
} else if other.mForegroundRatio == 255 {
Color::CurrentColor
if !other.mIsAuto {
Either::First(other.into())
} else {
// FIXME #13546 handle interpolation values
Color::CurrentColor
Either::Second(Auto)
}
}
}
@@ -148,7 +148,7 @@ class Longhand(object):
def __init__(self, style_struct, name, spec=None, animation_value_type=None, derived_from=None, keyword=None,
predefined_type=None, custom_cascade=False, experimental=False, internal=False,
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False,
allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
allowed_in_keyframe_block=True, cast_type='u8',
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False,
flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=False,
vector=False):
@@ -169,7 +169,6 @@ def __init__(self, style_struct, name, spec=None, animation_value_type=None, der
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
self.depend_on_viewport_size = depend_on_viewport_size
self.derived_from = (derived_from or "").split()
self.complex_color = complex_color
self.cast_type = cast_type
self.logical = arg_to_bool(logical)
self.alias = alias.split() if alias else []
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.