mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Auto merge of #11456 - emilio:stylo-linear-gradient, r=mbrubeck
stylo: Support linear-gradients as background-image This PR supports setting the background-image property to a linear-gradient in Geckolib. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes do not require tests because these are geckolib-only changes. r? @mbrubeck cc @heycam @bholley <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11456) <!-- Reviewable:end -->
This commit is contained in:
commit
e23962c404
11 changed files with 846 additions and 196 deletions
|
@ -309,8 +309,7 @@ ${helpers.predefined_type("text-indent",
|
||||||
// name per CSS-TEXT 6.2.
|
// name per CSS-TEXT 6.2.
|
||||||
${helpers.single_keyword("overflow-wrap",
|
${helpers.single_keyword("overflow-wrap",
|
||||||
"normal break-word",
|
"normal break-word",
|
||||||
gecko_ffi_name="mWordWrap",
|
gecko_constant_prefix="NS_STYLE_OVERFLOWWRAP")}
|
||||||
gecko_constant_prefix="NS_STYLE_WORDWRAP")}
|
|
||||||
|
|
||||||
// TODO(pcwalton): Support `word-break: keep-all` once we have better CJK support.
|
// TODO(pcwalton): Support `word-break: keep-all` once we have better CJK support.
|
||||||
${helpers.single_keyword("word-break",
|
${helpers.single_keyword("word-break",
|
||||||
|
|
|
@ -1179,6 +1179,7 @@ pub mod specified {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Angle {
|
impl Angle {
|
||||||
|
#[inline]
|
||||||
pub fn radians(self) -> f32 {
|
pub fn radians(self) -> f32 {
|
||||||
let Angle(radians) = self;
|
let Angle(radians) = self;
|
||||||
radians
|
radians
|
||||||
|
|
|
@ -24,9 +24,14 @@ use structs::nsStyleXUL;
|
||||||
use structs::nsStyleSVGReset;
|
use structs::nsStyleSVGReset;
|
||||||
use structs::nsStyleColumn;
|
use structs::nsStyleColumn;
|
||||||
use structs::nsStyleEffects;
|
use structs::nsStyleEffects;
|
||||||
|
use structs::nsStyleImage;
|
||||||
|
use structs::nsStyleGradient;
|
||||||
|
use structs::nsStyleCoord;
|
||||||
|
use structs::nsStyleGradientStop;
|
||||||
use structs::SheetParsingMode;
|
use structs::SheetParsingMode;
|
||||||
use structs::nsMainThreadPtrHandle;
|
use structs::nsMainThreadPtrHandle;
|
||||||
use structs::nsMainThreadPtrHolder;
|
use structs::nsMainThreadPtrHolder;
|
||||||
|
use structs::nscolor;
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
unsafe impl Send for nsStyleFont {}
|
unsafe impl Send for nsStyleFont {}
|
||||||
unsafe impl Sync for nsStyleFont {}
|
unsafe impl Sync for nsStyleFont {}
|
||||||
|
@ -100,6 +105,18 @@ impl HeapSizeOf for nsStyleColumn { fn heap_size_of_children(&self) -> usize { 0
|
||||||
unsafe impl Send for nsStyleEffects {}
|
unsafe impl Send for nsStyleEffects {}
|
||||||
unsafe impl Sync for nsStyleEffects {}
|
unsafe impl Sync for nsStyleEffects {}
|
||||||
impl HeapSizeOf for nsStyleEffects { fn heap_size_of_children(&self) -> usize { 0 } }
|
impl HeapSizeOf for nsStyleEffects { fn heap_size_of_children(&self) -> usize { 0 } }
|
||||||
|
unsafe impl Send for nsStyleImage {}
|
||||||
|
unsafe impl Sync for nsStyleImage {}
|
||||||
|
impl HeapSizeOf for nsStyleImage { fn heap_size_of_children(&self) -> usize { 0 } }
|
||||||
|
unsafe impl Send for nsStyleGradient {}
|
||||||
|
unsafe impl Sync for nsStyleGradient {}
|
||||||
|
impl HeapSizeOf for nsStyleGradient { fn heap_size_of_children(&self) -> usize { 0 } }
|
||||||
|
unsafe impl Send for nsStyleCoord {}
|
||||||
|
unsafe impl Sync for nsStyleCoord {}
|
||||||
|
impl HeapSizeOf for nsStyleCoord { fn heap_size_of_children(&self) -> usize { 0 } }
|
||||||
|
unsafe impl Send for nsStyleGradientStop {}
|
||||||
|
unsafe impl Sync for nsStyleGradientStop {}
|
||||||
|
impl HeapSizeOf for nsStyleGradientStop { fn heap_size_of_children(&self) -> usize { 0 } }
|
||||||
|
|
||||||
pub enum nsIAtom { }
|
pub enum nsIAtom { }
|
||||||
pub enum nsINode { }
|
pub enum nsINode { }
|
||||||
|
@ -171,6 +188,17 @@ extern "C" {
|
||||||
pub fn Gecko_SetListStyleType(style_struct: *mut nsStyleList, type_: u32);
|
pub fn Gecko_SetListStyleType(style_struct: *mut nsStyleList, type_: u32);
|
||||||
pub fn Gecko_CopyListStyleTypeFrom(dst: *mut nsStyleList,
|
pub fn Gecko_CopyListStyleTypeFrom(dst: *mut nsStyleList,
|
||||||
src: *const nsStyleList);
|
src: *const nsStyleList);
|
||||||
|
pub fn Gecko_SetNullImageValue(image: *mut nsStyleImage);
|
||||||
|
pub fn Gecko_SetGradientImageValue(image: *mut nsStyleImage,
|
||||||
|
gradient: *mut nsStyleGradient);
|
||||||
|
pub fn Gecko_CopyImageValueFrom(image: *mut nsStyleImage,
|
||||||
|
other: *const nsStyleImage);
|
||||||
|
pub fn Gecko_CreateGradient(shape: u8, size: u8, repeating: bool,
|
||||||
|
legacy_syntax: bool, stops: u32)
|
||||||
|
-> *mut nsStyleGradient;
|
||||||
|
pub fn Gecko_SetGradientStop(gradient: *mut nsStyleGradient, index: u32,
|
||||||
|
location: *const nsStyleCoord,
|
||||||
|
color: nscolor, is_interpolation_hint: bool);
|
||||||
pub fn Gecko_AddRefPrincipalArbitraryThread(aPtr:
|
pub fn Gecko_AddRefPrincipalArbitraryThread(aPtr:
|
||||||
*mut ThreadSafePrincipalHolder);
|
*mut ThreadSafePrincipalHolder);
|
||||||
pub fn Gecko_ReleasePrincipalArbitraryThread(aPtr:
|
pub fn Gecko_ReleasePrincipalArbitraryThread(aPtr:
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#![feature(const_fn)]
|
||||||
#![feature(concat_idents)]
|
#![feature(concat_idents)]
|
||||||
#![feature(type_macros)]
|
#![feature(type_macros)]
|
||||||
|
|
||||||
|
@ -10,5 +11,6 @@ extern crate heapsize;
|
||||||
#[allow(dead_code, non_camel_case_types)]
|
#[allow(dead_code, non_camel_case_types)]
|
||||||
pub mod bindings;
|
pub mod bindings;
|
||||||
pub mod ptr;
|
pub mod ptr;
|
||||||
|
pub mod sugar;
|
||||||
#[allow(dead_code, non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
#[allow(dead_code, non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
||||||
pub mod structs;
|
pub mod structs;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
5
ports/geckolib/gecko_bindings/sugar/mod.rs
Normal file
5
ports/geckolib/gecko_bindings/sugar/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* 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/. */
|
||||||
|
|
||||||
|
mod ns_t_array;
|
42
ports/geckolib/gecko_bindings/sugar/ns_t_array.rs
Normal file
42
ports/geckolib/gecko_bindings/sugar/ns_t_array.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* 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/. */
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::slice;
|
||||||
|
use structs::{nsTArray, nsTArrayHeader};
|
||||||
|
|
||||||
|
impl<T> Deref for nsTArray<T> {
|
||||||
|
type Target = [T];
|
||||||
|
|
||||||
|
fn deref<'a>(&'a self) -> &'a [T] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts(self.slice_begin(),
|
||||||
|
self.header().mLength as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DerefMut for nsTArray<T> {
|
||||||
|
fn deref_mut<'a>(&'a mut self) -> &'a mut [T] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts_mut(self.slice_begin(),
|
||||||
|
self.header().mLength as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> nsTArray<T> {
|
||||||
|
#[inline]
|
||||||
|
fn header<'a>(&'a self) -> &'a nsTArrayHeader {
|
||||||
|
debug_assert!(!self.mBuffer.is_null());
|
||||||
|
unsafe { mem::transmute(self.mBuffer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn slice_begin(&self) -> *mut T {
|
||||||
|
debug_assert!(!self.mBuffer.is_null());
|
||||||
|
(self.mBuffer as *const nsTArrayHeader).offset(1) as *mut _
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,8 @@ for STRUCT in nsStyleFont nsStyleColor nsStyleList nsStyleText \
|
||||||
nsStyleSVG nsStyleVariables nsStyleBackground nsStylePosition \
|
nsStyleSVG nsStyleVariables nsStyleBackground nsStylePosition \
|
||||||
nsStyleTextReset nsStyleDisplay nsStyleContent nsStyleUIReset \
|
nsStyleTextReset nsStyleDisplay nsStyleContent nsStyleUIReset \
|
||||||
nsStyleTable nsStyleMargin nsStylePadding nsStyleBorder \
|
nsStyleTable nsStyleMargin nsStylePadding nsStyleBorder \
|
||||||
nsStyleOutline nsStyleXUL nsStyleSVGReset nsStyleColumn nsStyleEffects
|
nsStyleOutline nsStyleXUL nsStyleSVGReset nsStyleColumn nsStyleEffects \
|
||||||
|
nsStyleImage nsStyleGradient nsStyleCoord nsStyleGradientStop
|
||||||
do
|
do
|
||||||
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $STRUCT "
|
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $STRUCT "
|
||||||
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use structs::$STRUCT;' "
|
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use structs::$STRUCT;' "
|
||||||
|
@ -50,7 +51,7 @@ do
|
||||||
done
|
done
|
||||||
|
|
||||||
# Other mapped types.
|
# Other mapped types.
|
||||||
for TYPE in SheetParsingMode nsMainThreadPtrHandle nsMainThreadPtrHolder
|
for TYPE in SheetParsingMode nsMainThreadPtrHandle nsMainThreadPtrHolder nscolor
|
||||||
do
|
do
|
||||||
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $TYPE "
|
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-blacklist-type $TYPE "
|
||||||
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use structs::$TYPE;' "
|
MAP_GECKO_TYPES=$MAP_GECKO_TYPES"-raw-line 'use structs::$TYPE;' "
|
||||||
|
|
|
@ -46,7 +46,6 @@ export RUST_BACKTRACE=1
|
||||||
"-I$1/../nsprpub/pr/include" \
|
"-I$1/../nsprpub/pr/include" \
|
||||||
$PLATFORM_DEPENDENT_DEFINES \
|
$PLATFORM_DEPENDENT_DEFINES \
|
||||||
-ignore-functions \
|
-ignore-functions \
|
||||||
-no-bitfield-methods \
|
|
||||||
-no-type-renaming \
|
-no-type-renaming \
|
||||||
-DMOZILLA_INTERNAL_API \
|
-DMOZILLA_INTERNAL_API \
|
||||||
-DMOZ_STYLO_BINDINGS=1 \
|
-DMOZ_STYLO_BINDINGS=1 \
|
||||||
|
@ -99,6 +98,7 @@ export RUST_BACKTRACE=1
|
||||||
-match "nsCSSScanner.h" \
|
-match "nsCSSScanner.h" \
|
||||||
-match "Types.h" \
|
-match "Types.h" \
|
||||||
-match "utility" \
|
-match "utility" \
|
||||||
|
-match "nsTArray" \
|
||||||
-match "pair" \
|
-match "pair" \
|
||||||
-match "SheetParsingMode.h" \
|
-match "SheetParsingMode.h" \
|
||||||
-match "StaticPtr.h" \
|
-match "StaticPtr.h" \
|
||||||
|
@ -106,6 +106,9 @@ export RUST_BACKTRACE=1
|
||||||
-blacklist-type "IsDestructibleFallbackImpl" \
|
-blacklist-type "IsDestructibleFallbackImpl" \
|
||||||
-blacklist-type "IsDestructibleFallback" \
|
-blacklist-type "IsDestructibleFallback" \
|
||||||
-blacklist-type "nsProxyReleaseEvent" \
|
-blacklist-type "nsProxyReleaseEvent" \
|
||||||
|
-blacklist-type "FallibleTArray" \
|
||||||
|
-blacklist-type "nsTArray_Impl" \
|
||||||
|
-blacklist-type "__is_tuple_like_impl" \
|
||||||
-opaque-type "nsIntMargin" \
|
-opaque-type "nsIntMargin" \
|
||||||
-opaque-type "nsIntPoint" \
|
-opaque-type "nsIntPoint" \
|
||||||
-opaque-type "nsIntRect" \
|
-opaque-type "nsIntRect" \
|
||||||
|
@ -130,7 +133,11 @@ if [ $? -ne 0 ]; then
|
||||||
else
|
else
|
||||||
echo -e "\e[34minfo:\e[0m bindgen exited successfully, running tests"
|
echo -e "\e[34minfo:\e[0m bindgen exited successfully, running tests"
|
||||||
TESTS_FILE=$(mktemp)
|
TESTS_FILE=$(mktemp)
|
||||||
rustc ../structs.rs --test -o $TESTS_FILE
|
TESTS_SRC=$(mktemp)
|
||||||
|
echo "#![feature(const_fn)]" > $TESTS_SRC
|
||||||
|
cat ../structs.rs >> $TESTS_SRC
|
||||||
|
rustc $TESTS_SRC --test -o $TESTS_FILE
|
||||||
$TESTS_FILE
|
$TESTS_FILE
|
||||||
rm $TESTS_FILE
|
rm $TESTS_FILE
|
||||||
|
rm $TESTS_SRC
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -18,11 +18,15 @@ use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
|
||||||
% endfor
|
% endfor
|
||||||
use gecko_bindings::bindings::{Gecko_CopyMozBindingFrom, Gecko_CopyListStyleTypeFrom};
|
use gecko_bindings::bindings::{Gecko_CopyMozBindingFrom, Gecko_CopyListStyleTypeFrom};
|
||||||
use gecko_bindings::bindings::{Gecko_SetMozBinding, Gecko_SetListStyleType};
|
use gecko_bindings::bindings::{Gecko_SetMozBinding, Gecko_SetListStyleType};
|
||||||
|
use gecko_bindings::bindings::{Gecko_SetNullImageValue, Gecko_SetGradientImageValue};
|
||||||
|
use gecko_bindings::bindings::{Gecko_CreateGradient};
|
||||||
|
use gecko_bindings::bindings::{Gecko_CopyImageValueFrom};
|
||||||
use gecko_bindings::structs;
|
use gecko_bindings::structs;
|
||||||
use glue::ArcHelpers;
|
use glue::ArcHelpers;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
use std::mem::{transmute, zeroed};
|
use std::mem::{transmute, uninitialized, zeroed};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::cmp;
|
||||||
use style::custom_properties::ComputedValuesMap;
|
use style::custom_properties::ComputedValuesMap;
|
||||||
use style::logical_geometry::WritingMode;
|
use style::logical_geometry::WritingMode;
|
||||||
use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
|
use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
|
||||||
|
@ -379,7 +383,7 @@ impl Debug for ${style_struct.gecko_struct_name} {
|
||||||
# These are currently being shuffled to a different style struct on the gecko side.
|
# These are currently being shuffled to a different style struct on the gecko side.
|
||||||
force_stub += ["backface-visibility", "transform-box", "transform-style"]
|
force_stub += ["backface-visibility", "transform-box", "transform-style"]
|
||||||
# These live in nsStyleImageLayers in gecko. Need to figure out what to do about that.
|
# These live in nsStyleImageLayers in gecko. Need to figure out what to do about that.
|
||||||
force_stub += ["background-repeat", "background-attachment", "background-clip", "background-origin"];
|
force_stub += ["background-attachment", "background-clip", "background-origin"];
|
||||||
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
|
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
|
||||||
force_stub += ["font-kerning", "font-stretch", "font-variant"]
|
force_stub += ["font-kerning", "font-stretch", "font-variant"]
|
||||||
# These have unusual representations in gecko.
|
# These have unusual representations in gecko.
|
||||||
|
@ -490,6 +494,7 @@ fn static_assert() {
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<% border_style_keyword = Keyword("border-style",
|
<% border_style_keyword = Keyword("border-style",
|
||||||
"none solid double dotted dashed hidden groove ridge inset outset") %>
|
"none solid double dotted dashed hidden groove ridge inset outset") %>
|
||||||
|
|
||||||
|
@ -706,10 +711,128 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Background" skip_longhands="background-color" skip_additionals="*">
|
<%self:impl_trait style_struct_name="Background"
|
||||||
|
skip_longhands="background-color background-repeat background-image"
|
||||||
|
skip_additionals="*">
|
||||||
|
|
||||||
<% impl_color("background_color", "mBackgroundColor") %>
|
<% impl_color("background_color", "mBackgroundColor") %>
|
||||||
|
|
||||||
|
fn copy_background_repeat_from(&mut self, other: &Self) {
|
||||||
|
self.gecko.mImage.mRepeatCount = other.gecko.mImage.mRepeatCount;
|
||||||
|
self.gecko.mImage.mLayers.mFirstElement.mRepeat =
|
||||||
|
other.gecko.mImage.mLayers.mFirstElement.mRepeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_background_repeat(&mut self, v: longhands::background_repeat::computed_value::T) {
|
||||||
|
use style::properties::longhands::background_repeat::computed_value::T as Computed;
|
||||||
|
use gecko_bindings::structs::{NS_STYLE_IMAGELAYER_REPEAT_REPEAT, NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT};
|
||||||
|
use gecko_bindings::structs::nsStyleImageLayers_Repeat;
|
||||||
|
let (repeat_x, repeat_y) = match v {
|
||||||
|
Computed::repeat_x => (NS_STYLE_IMAGELAYER_REPEAT_REPEAT,
|
||||||
|
NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT),
|
||||||
|
Computed::repeat_y => (NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT,
|
||||||
|
NS_STYLE_IMAGELAYER_REPEAT_REPEAT),
|
||||||
|
Computed::repeat => (NS_STYLE_IMAGELAYER_REPEAT_REPEAT,
|
||||||
|
NS_STYLE_IMAGELAYER_REPEAT_REPEAT),
|
||||||
|
Computed::no_repeat => (NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT,
|
||||||
|
NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.gecko.mImage.mRepeatCount = 1;
|
||||||
|
self.gecko.mImage.mLayers.mFirstElement.mRepeat = nsStyleImageLayers_Repeat {
|
||||||
|
mXRepeat: repeat_x as u8,
|
||||||
|
mYRepeat: repeat_y as u8,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_background_image_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
Gecko_CopyImageValueFrom(&mut self.gecko.mImage.mLayers.mFirstElement.mImage,
|
||||||
|
&other.gecko.mImage.mLayers.mFirstElement.mImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_background_image(&mut self, image: longhands::background_image::computed_value::T) {
|
||||||
|
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SHAPE_LINEAR, NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER};
|
||||||
|
use gecko_bindings::structs::nsStyleCoord;
|
||||||
|
use style::values::computed::Image;
|
||||||
|
use style::values::specified::AngleOrCorner;
|
||||||
|
use cssparser::Color as CSSColor;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Prevent leaking of the last element we did set
|
||||||
|
Gecko_SetNullImageValue(&mut self.gecko.mImage.mLayers.mFirstElement.mImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.gecko.mImage.mImageCount = cmp::max(1, self.gecko.mImage.mImageCount);
|
||||||
|
if let Some(image) = image.0 {
|
||||||
|
match image {
|
||||||
|
Image::LinearGradient(ref gradient) => {
|
||||||
|
let stop_count = gradient.stops.len();
|
||||||
|
if stop_count >= ::std::u32::MAX as usize {
|
||||||
|
warn!("stylo: Prevented overflow due to too many gradient stops");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let gecko_gradient = unsafe {
|
||||||
|
Gecko_CreateGradient(NS_STYLE_GRADIENT_SHAPE_LINEAR as u8,
|
||||||
|
NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as u8,
|
||||||
|
/* repeating = */ false,
|
||||||
|
/* legacy_syntax = */ false,
|
||||||
|
stop_count as u32)
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: figure out what gecko does in the `corner` case.
|
||||||
|
if let AngleOrCorner::Angle(angle) = gradient.angle_or_corner {
|
||||||
|
unsafe {
|
||||||
|
(*gecko_gradient).mAngle.set(angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut coord: nsStyleCoord = unsafe { uninitialized() };
|
||||||
|
for (index, stop) in gradient.stops.iter().enumerate() {
|
||||||
|
// NB: stops are guaranteed to be none in the gecko side by
|
||||||
|
// default.
|
||||||
|
coord.set(stop.position);
|
||||||
|
let color = 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),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut stop = unsafe {
|
||||||
|
&mut (*gecko_gradient).mStops[index]
|
||||||
|
};
|
||||||
|
|
||||||
|
stop.mColor = color;
|
||||||
|
stop.mIsInterpolationHint = false;
|
||||||
|
stop.mLocation.copy_from(&coord);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
Gecko_SetGradientImageValue(&mut self.gecko.mImage.mLayers.mFirstElement.mImage,
|
||||||
|
gecko_gradient);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Image::Url(_) => {
|
||||||
|
// let utf8_bytes = url.as_bytes();
|
||||||
|
// Gecko_SetUrlImageValue(&mut self.gecko.mImage.mLayers.mFirstElement,
|
||||||
|
// utf8_bytes.as_ptr() as *const _,
|
||||||
|
// utf8_bytes.len());
|
||||||
|
warn!("stylo: imgRequestProxies are not threadsafe in gecko, \
|
||||||
|
background-image: url() not yet implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="List" skip_longhands="list-style-type" skip_additionals="*">
|
<%self:impl_trait style_struct_name="List" skip_longhands="list-style-type" skip_additionals="*">
|
||||||
|
|
|
@ -6,6 +6,7 @@ use app_units::Au;
|
||||||
use cssparser::RGBA;
|
use cssparser::RGBA;
|
||||||
use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit};
|
use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
use style::values::computed::Angle;
|
||||||
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
||||||
|
|
||||||
pub trait StyleCoordHelpers {
|
pub trait StyleCoordHelpers {
|
||||||
|
@ -128,6 +129,26 @@ impl ToGeckoStyleCoord for LengthOrPercentageOrNone {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ToGeckoStyleCoord> ToGeckoStyleCoord for Option<T> {
|
||||||
|
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
|
||||||
|
if let Some(ref me) = *self {
|
||||||
|
me.to_gecko_style_coord(unit, union);
|
||||||
|
} else {
|
||||||
|
*unit = nsStyleUnit::eStyleUnit_None;
|
||||||
|
unsafe { *union.mInt.as_mut() = 0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToGeckoStyleCoord for Angle {
|
||||||
|
fn to_gecko_style_coord(&self,
|
||||||
|
unit: &mut nsStyleUnit,
|
||||||
|
union: &mut nsStyleUnion) {
|
||||||
|
*unit = nsStyleUnit::eStyleUnit_Radian;
|
||||||
|
unsafe { *union.mFloat.as_mut() = self.radians() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
||||||
(((rgba.alpha * 255.0).round() as u32) << 24) |
|
(((rgba.alpha * 255.0).round() as u32) << 24) |
|
||||||
(((rgba.blue * 255.0).round() as u32) << 16) |
|
(((rgba.blue * 255.0).round() as u32) << 16) |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue