forked from mirrors/gecko-dev
Bug 1281158 - Improve interaction of ThinVec in the style system. r=dshin
This is the logical continuation of bug 1121792. This improves on the existing support by totally removing all the manual nsTArray bindings, which have always been a bit clumsy. This is a prerequisite for bug 1281158 because I want to use ThinVec to avoid a few extra heap allocations in the computed values of the Content property. Differential Revision: https://phabricator.services.mozilla.com/D209689
This commit is contained in:
parent
5668d88093
commit
dc9b47aecf
21 changed files with 232 additions and 485 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -5542,6 +5542,7 @@ dependencies = [
|
|||
"selectors",
|
||||
"serde",
|
||||
"servo_arc",
|
||||
"thin-vec",
|
||||
"to_shmem",
|
||||
"to_shmem_derive",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -988,34 +988,6 @@ const AnonymousCounterStyle* Gecko_CounterStyle_GetAnonymous(
|
|||
return aPtr->AsAnonymous();
|
||||
}
|
||||
|
||||
void Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity,
|
||||
size_t aElemSize) {
|
||||
auto base =
|
||||
reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
|
||||
nsTArray_RelocateUsingMemutils>*>(aArray);
|
||||
|
||||
base->EnsureCapacity<nsTArrayInfallibleAllocator>(aCapacity, aElemSize);
|
||||
}
|
||||
|
||||
void Gecko_ClearPODTArray(void* aArray, size_t aElementSize,
|
||||
size_t aElementAlign) {
|
||||
auto base =
|
||||
reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
|
||||
nsTArray_RelocateUsingMemutils>*>(aArray);
|
||||
|
||||
base->template ShiftData<nsTArrayInfallibleAllocator>(
|
||||
0, base->Length(), 0, aElementSize, aElementAlign);
|
||||
}
|
||||
|
||||
void Gecko_ResizeTArrayForStrings(nsTArray<nsString>* aArray,
|
||||
uint32_t aLength) {
|
||||
aArray->SetLength(aLength);
|
||||
}
|
||||
|
||||
void Gecko_ResizeAtomArray(nsTArray<RefPtr<nsAtom>>* aArray, uint32_t aLength) {
|
||||
aArray->SetLength(aLength);
|
||||
}
|
||||
|
||||
void Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
|
||||
nsStyleImageLayers::LayerType aLayerType) {
|
||||
size_t oldLength = aLayers->mLayers.Length();
|
||||
|
|
@ -1135,16 +1107,6 @@ Keyframe* Gecko_GetOrCreateFinalKeyframe(
|
|||
KeyframeInsertPosition::LastForOffset);
|
||||
}
|
||||
|
||||
PropertyValuePair* Gecko_AppendPropertyValuePair(
|
||||
nsTArray<PropertyValuePair>* aProperties,
|
||||
const mozilla::AnimatedPropertyID* aProperty) {
|
||||
MOZ_ASSERT(aProperties);
|
||||
MOZ_ASSERT(
|
||||
aProperty->IsCustom() ||
|
||||
!nsCSSProps::PropHasFlags(aProperty->mID, CSSPropFlags::IsLogical));
|
||||
return aProperties->AppendElement(PropertyValuePair{*aProperty});
|
||||
}
|
||||
|
||||
void Gecko_GetComputedURLSpec(const StyleComputedUrl* aURL, nsCString* aOut) {
|
||||
MOZ_ASSERT(aURL);
|
||||
MOZ_ASSERT(aOut);
|
||||
|
|
|
|||
|
|
@ -375,20 +375,6 @@ const mozilla::ServoElementSnapshot* Gecko_GetElementSnapshot(
|
|||
// Have we seen this pointer before?
|
||||
bool Gecko_HaveSeenPtr(mozilla::SeenPtrs* table, const void* ptr);
|
||||
|
||||
// `array` must be an nsTArray
|
||||
// If changing this signature, please update the
|
||||
// friend function declaration in nsTArray.h
|
||||
void Gecko_EnsureTArrayCapacity(void* array, size_t capacity, size_t elem_size);
|
||||
|
||||
// Same here, `array` must be an nsTArray<T>, for some T.
|
||||
//
|
||||
// Important note: Only valid for POD types, since destructors won't be run
|
||||
// otherwise. This is ensured with rust traits for the relevant structs.
|
||||
void Gecko_ClearPODTArray(void* array, size_t elem_size, size_t elem_align);
|
||||
|
||||
void Gecko_ResizeTArrayForStrings(nsTArray<nsString>* array, uint32_t length);
|
||||
void Gecko_ResizeAtomArray(nsTArray<RefPtr<nsAtom>>* array, uint32_t length);
|
||||
|
||||
void Gecko_EnsureImageLayersLength(nsStyleImageLayers* layers, size_t len,
|
||||
nsStyleImageLayers::LayerType layer_type);
|
||||
|
||||
|
|
@ -438,13 +424,6 @@ mozilla::Keyframe* Gecko_GetOrCreateFinalKeyframe(
|
|||
const mozilla::StyleComputedTimingFunction* timingFunction,
|
||||
const mozilla::dom::CompositeOperationOrAuto composition);
|
||||
|
||||
// Appends and returns a new PropertyValuePair to |aProperties| initialized with
|
||||
// its mProperty member set to |aProperty| and all other members initialized to
|
||||
// their default values.
|
||||
mozilla::PropertyValuePair* Gecko_AppendPropertyValuePair(
|
||||
nsTArray<mozilla::PropertyValuePair>*,
|
||||
const mozilla::AnimatedPropertyID* aProperty);
|
||||
|
||||
void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len);
|
||||
|
||||
void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ hide-types = [
|
|||
"mozilla::StyleTimingFunction.*",
|
||||
# https://github.com/rust-lang/rust-bindgen/issues/1559
|
||||
"mozilla::StyleGeneric.*",
|
||||
"nsTArray_.*",
|
||||
".*ErrorResult.*",
|
||||
]
|
||||
bitfield-enums = [
|
||||
|
|
@ -290,7 +291,6 @@ allowlist-types = [
|
|||
"nsStyleUI",
|
||||
"nsStyleVisibility",
|
||||
"nsStyleXUL",
|
||||
"nsTArrayHeader",
|
||||
"mozilla::UniquePtr",
|
||||
"mozilla::DeclarationBlock",
|
||||
"mozilla::DefaultDelete",
|
||||
|
|
@ -632,6 +632,8 @@ mapped-generic-types = [
|
|||
{ generic = false, gecko = "nsAString", servo = "nsstring::nsAString" },
|
||||
{ generic = false, gecko = "nsCString", servo = "nsstring::nsCString" },
|
||||
{ generic = false, gecko = "nsString", servo = "nsstring::nsString" },
|
||||
{ generic = true, gecko = "nsTArray", servo = "thin_vec::ThinVec" },
|
||||
{ generic = true, gecko = "CopyableTArray", servo = "thin_vec::ThinVec" },
|
||||
]
|
||||
|
||||
allowlist-functions = ["Servo_.*", "Gecko_.*"]
|
||||
|
|
|
|||
|
|
@ -2054,35 +2054,4 @@ struct UniquePtr_Simple {
|
|||
STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr<int>,
|
||||
UniquePtr_Simple<int>);
|
||||
|
||||
/**
|
||||
* <div rustbindgen replaces="nsTArray"></div>
|
||||
*/
|
||||
template <typename T>
|
||||
class nsTArray_Simple {
|
||||
protected:
|
||||
T* mBuffer;
|
||||
|
||||
public:
|
||||
~nsTArray_Simple() {
|
||||
// The existence of a user-provided, and therefore non-trivial, destructor
|
||||
// here prevents bindgen from deriving the Clone trait via a simple memory
|
||||
// copy.
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* <div rustbindgen replaces="CopyableTArray"></div>
|
||||
*/
|
||||
template <typename T>
|
||||
class CopyableTArray_Simple : public nsTArray_Simple<T> {};
|
||||
|
||||
STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<nsStyleImageLayers::Layer>,
|
||||
nsTArray_Simple<nsStyleImageLayers::Layer>);
|
||||
STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleTransition>,
|
||||
nsTArray_Simple<mozilla::StyleTransition>);
|
||||
STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleAnimation>,
|
||||
nsTArray_Simple<mozilla::StyleAnimation>);
|
||||
STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray<mozilla::StyleViewTimeline>,
|
||||
nsTArray_Simple<mozilla::StyleViewTimeline>);
|
||||
|
||||
#endif /* nsStyleStruct_h___ */
|
||||
|
|
|
|||
|
|
@ -577,14 +577,14 @@ pub enum GeckoChildrenIterator<'a> {
|
|||
/// replaces it with the next sibling when requested.
|
||||
Current(Option<GeckoNode<'a>>),
|
||||
/// A Gecko-implemented iterator we need to drop appropriately.
|
||||
GeckoIterator(structs::StyleChildrenIterator),
|
||||
GeckoIterator(std::mem::ManuallyDrop<structs::StyleChildrenIterator>),
|
||||
}
|
||||
|
||||
impl<'a> Drop for GeckoChildrenIterator<'a> {
|
||||
fn drop(&mut self) {
|
||||
if let GeckoChildrenIterator::GeckoIterator(ref mut it) = *self {
|
||||
unsafe {
|
||||
bindings::Gecko_DestroyStyleChildrenIterator(it);
|
||||
bindings::Gecko_DestroyStyleChildrenIterator(&mut **it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -605,7 +605,7 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> {
|
|||
// however we can't express this easily with bindgen, and it would
|
||||
// introduce functions with two input lifetimes into bindgen,
|
||||
// which would be out of scope for elision.
|
||||
bindings::Gecko_GetNextStyleChild(&mut *(it as *mut _))
|
||||
bindings::Gecko_GetNextStyleChild(&mut **it)
|
||||
.as_ref()
|
||||
.map(GeckoNode)
|
||||
},
|
||||
|
|
@ -1015,9 +1015,9 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
self.may_have_anonymous_children()
|
||||
{
|
||||
unsafe {
|
||||
let mut iter: structs::StyleChildrenIterator = ::std::mem::zeroed();
|
||||
bindings::Gecko_ConstructStyleChildrenIterator(self.0, &mut iter);
|
||||
return LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter));
|
||||
let mut iter = std::mem::MaybeUninit::<structs::StyleChildrenIterator>::uninit();
|
||||
bindings::Gecko_ConstructStyleChildrenIterator(self.0, iter.as_mut_ptr());
|
||||
return LayoutIterator(GeckoChildrenIterator::GeckoIterator(std::mem::ManuallyDrop::new(iter.assume_init())));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
mod ns_com_ptr;
|
||||
mod ns_compatibility;
|
||||
mod ns_style_auto_array;
|
||||
mod ns_t_array;
|
||||
pub mod origin_flags;
|
||||
pub mod ownership;
|
||||
pub mod refptr;
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! Rust helpers for Gecko's nsTArray.
|
||||
|
||||
use crate::gecko_bindings::bindings;
|
||||
use crate::gecko_bindings::structs::{nsTArray, nsTArrayHeader, CopyableTArray};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::slice;
|
||||
|
||||
impl<T> Deref for nsTArray<T> {
|
||||
type Target = [T];
|
||||
|
||||
#[inline]
|
||||
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) }
|
||||
}
|
||||
|
||||
// unsafe, since header may be in shared static or something
|
||||
unsafe fn header_mut<'a>(&'a mut self) -> &'a mut nsTArrayHeader {
|
||||
debug_assert!(!self.mBuffer.is_null());
|
||||
|
||||
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 _
|
||||
}
|
||||
|
||||
/// Ensures the array has enough capacity at least to hold `cap` elements.
|
||||
///
|
||||
/// NOTE: This doesn't call the constructor on the values!
|
||||
pub fn ensure_capacity(&mut self, cap: usize) {
|
||||
if cap >= self.len() {
|
||||
unsafe {
|
||||
bindings::Gecko_EnsureTArrayCapacity(
|
||||
self as *mut nsTArray<T> as *mut _,
|
||||
cap,
|
||||
mem::size_of::<T>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears the array storage without calling the destructor on the values.
|
||||
#[inline]
|
||||
pub unsafe fn clear(&mut self) {
|
||||
if self.len() != 0 {
|
||||
bindings::Gecko_ClearPODTArray(
|
||||
self as *mut nsTArray<T> as *mut _,
|
||||
mem::size_of::<T>(),
|
||||
mem::align_of::<T>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears a POD array. This is safe since copy types are memcopyable.
|
||||
#[inline]
|
||||
pub fn clear_pod(&mut self)
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
unsafe { self.clear() }
|
||||
}
|
||||
|
||||
/// Resize and set the length of the array to `len`.
|
||||
///
|
||||
/// unsafe because this may leave the array with uninitialized elements.
|
||||
///
|
||||
/// This will not call constructors. If you need that, either manually add
|
||||
/// bindings or run the typed `EnsureCapacity` call on the gecko side.
|
||||
pub unsafe fn set_len(&mut self, len: u32) {
|
||||
// this can leak
|
||||
debug_assert!(len >= self.len() as u32);
|
||||
if self.len() == len as usize {
|
||||
return;
|
||||
}
|
||||
self.ensure_capacity(len as usize);
|
||||
self.header_mut().mLength = len;
|
||||
}
|
||||
|
||||
/// Resizes an array containing only POD elements
|
||||
///
|
||||
/// unsafe because this may leave the array with uninitialized elements.
|
||||
///
|
||||
/// This will not leak since it only works on POD types (and thus doesn't assert)
|
||||
pub unsafe fn set_len_pod(&mut self, len: u32)
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
if self.len() == len as usize {
|
||||
return;
|
||||
}
|
||||
self.ensure_capacity(len as usize);
|
||||
let header = self.header_mut();
|
||||
header.mLength = len;
|
||||
}
|
||||
|
||||
/// Collects the given iterator into this array.
|
||||
///
|
||||
/// Not unsafe because we won't leave uninitialized elements in the array.
|
||||
pub fn assign_from_iter_pod<I>(&mut self, iter: I)
|
||||
where
|
||||
T: Copy,
|
||||
I: ExactSizeIterator + Iterator<Item = T>,
|
||||
{
|
||||
debug_assert!(iter.len() <= 0xFFFFFFFF);
|
||||
unsafe {
|
||||
self.set_len_pod(iter.len() as u32);
|
||||
}
|
||||
self.iter_mut().zip(iter).for_each(|(r, v)| *r = v);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for CopyableTArray<T> {
|
||||
type Target = nsTArray<T>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self._base
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for CopyableTArray<T> {
|
||||
fn deref_mut(&mut self) -> &mut nsTArray<T> {
|
||||
&mut self._base
|
||||
}
|
||||
}
|
||||
|
|
@ -69,6 +69,8 @@ extern crate static_assertions;
|
|||
#[macro_use]
|
||||
extern crate style_derive;
|
||||
#[macro_use]
|
||||
extern crate thin_vec;
|
||||
#[macro_use]
|
||||
extern crate to_shmem_derive;
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
|||
|
|
@ -580,26 +580,18 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
</%def>
|
||||
|
||||
<%def name="impl_font_settings(ident, gecko_type, tag_type, value_type, gecko_value_type)">
|
||||
<%
|
||||
gecko_ffi_name = to_camel_case_lower(ident)
|
||||
%>
|
||||
<% gecko_ffi_name = to_camel_case_lower(ident) %>
|
||||
|
||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||
let iter = v.0.iter().map(|other| structs::${gecko_type} {
|
||||
mTag: other.tag.0,
|
||||
mValue: other.value as ${gecko_value_type},
|
||||
});
|
||||
self.mFont.${gecko_ffi_name}.assign_from_iter_pod(iter);
|
||||
self.mFont.${gecko_ffi_name}.clear();
|
||||
self.mFont.${gecko_ffi_name}.extend(iter);
|
||||
}
|
||||
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
let iter = other.mFont.${gecko_ffi_name}.iter().map(|s| *s);
|
||||
self.mFont.${gecko_ffi_name}.assign_from_iter_pod(iter);
|
||||
}
|
||||
|
||||
pub fn reset_${ident}(&mut self, other: &Self) {
|
||||
self.copy_${ident}_from(other)
|
||||
}
|
||||
<% impl_simple_copy(ident, "mFont." + gecko_ffi_name) %>
|
||||
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
use crate::values::generics::font::{FontSettings, FontTag, ${tag_type}};
|
||||
|
|
|
|||
|
|
@ -1104,14 +1104,12 @@ impl<'a> PropertyDeclarationId<'a> {
|
|||
}
|
||||
|
||||
/// Convert a `PropertyDeclarationId` into an `AnimatedPropertyID`
|
||||
/// Note that the rust AnimatedPropertyID doesn't implement Drop, so owned controls whether the
|
||||
/// custom name should be addrefed or not.
|
||||
///
|
||||
/// FIXME(emilio, bug 1870107): This is a bit error-prone. We should consider using cbindgen to
|
||||
/// generate the property id representation or so.
|
||||
/// FIXME(emilio, bug 1870107): We should consider using cbindgen to generate the property id
|
||||
/// representation or so.
|
||||
#[cfg(feature = "gecko")]
|
||||
#[inline]
|
||||
pub fn to_gecko_animated_property_id(&self, owned: bool) -> AnimatedPropertyID {
|
||||
pub fn to_gecko_animated_property_id(&self) -> AnimatedPropertyID {
|
||||
match self {
|
||||
Self::Longhand(id) => AnimatedPropertyID {
|
||||
mID: id.to_nscsspropertyid(),
|
||||
|
|
@ -1122,11 +1120,7 @@ impl<'a> PropertyDeclarationId<'a> {
|
|||
mID: nsCSSPropertyID::eCSSPropertyExtra_variable,
|
||||
mCustomName: RefPtr::null(),
|
||||
};
|
||||
property_id.mCustomName.mRawPtr = if owned {
|
||||
(*name).clone().into_addrefed()
|
||||
} else {
|
||||
name.as_ptr()
|
||||
};
|
||||
property_id.mCustomName.mRawPtr = (*name).clone().into_addrefed();
|
||||
property_id
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::error_reporting::ContextualParseError;
|
|||
#[cfg(feature = "gecko")]
|
||||
use crate::gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry;
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray};
|
||||
use crate::gecko_bindings::structs::{self, gfxFontFeatureValueSet};
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use crate::str::CssStringWriter;
|
||||
|
|
@ -24,6 +24,7 @@ use cssparser::{
|
|||
};
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
/// A @font-feature-values block declaration.
|
||||
/// It is `<ident>: <integer>+`.
|
||||
|
|
@ -54,8 +55,8 @@ impl<T: ToCss> ToCss for FFVDeclaration<T> {
|
|||
/// A trait for @font-feature-values rule to gecko values conversion.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub trait ToGeckoFontFeatureValues {
|
||||
/// Sets the equivalent of declaration to gecko `nsTArray<u32>` array.
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>);
|
||||
/// Sets the equivalent of declaration to gecko `ThinVec<u32>` array.
|
||||
fn to_gecko_font_feature_values(&self) -> ThinVec<u32>;
|
||||
}
|
||||
|
||||
/// A @font-feature-values block declaration value that keeps one value.
|
||||
|
|
@ -79,11 +80,8 @@ impl Parse for SingleValue {
|
|||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for SingleValue {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
unsafe {
|
||||
array.set_len_pod(1);
|
||||
}
|
||||
array[0] = self.0 as u32;
|
||||
fn to_gecko_font_feature_values(&self) -> ThinVec<u32> {
|
||||
thin_vec::thin_vec![self.0 as u32]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,16 +116,12 @@ impl Parse for PairValues {
|
|||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for PairValues {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
let len = if self.1.is_some() { 2 } else { 1 };
|
||||
|
||||
unsafe {
|
||||
array.set_len_pod(len);
|
||||
}
|
||||
array[0] = self.0 as u32;
|
||||
fn to_gecko_font_feature_values(&self) -> ThinVec<u32> {
|
||||
let mut result = thin_vec::thin_vec![self.0 as u32];
|
||||
if let Some(second) = self.1 {
|
||||
array[1] = second as u32;
|
||||
};
|
||||
result.push(second as u32);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,8 +159,8 @@ impl Parse for VectorValues {
|
|||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for VectorValues {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
array.assign_from_iter_pod(self.0.iter().map(|v| *v));
|
||||
fn to_gecko_font_feature_values(&self) -> ThinVec<u32> {
|
||||
self.0.iter().copied().collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +332,7 @@ macro_rules! font_feature_values_blocks {
|
|||
)
|
||||
};
|
||||
unsafe {
|
||||
val.value.to_gecko_font_feature_values(&mut *array);
|
||||
*array = val.value.to_gecko_font_feature_values();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,6 +273,23 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedValue for thin_vec::ThinVec<T>
|
||||
where
|
||||
T: ToAnimatedValue,
|
||||
{
|
||||
type AnimatedValue = thin_vec::ThinVec<<T as ToAnimatedValue>::AnimatedValue>;
|
||||
|
||||
#[inline]
|
||||
fn to_animated_value(self) -> Self::AnimatedValue {
|
||||
self.into_iter().map(T::to_animated_value).collect()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||
animated.into_iter().map(T::from_animated_value).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedValue for Box<T>
|
||||
where
|
||||
T: ToAnimatedValue,
|
||||
|
|
@ -452,6 +469,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedZero for thin_vec::ThinVec<T>
|
||||
where
|
||||
T: ToAnimatedZero,
|
||||
{
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
self.iter().map(|v| v.to_animated_zero()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToAnimatedZero for Box<[T]>
|
||||
where
|
||||
T: ToAnimatedZero,
|
||||
|
|
|
|||
|
|
@ -649,6 +649,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ToComputedValue for thin_vec::ThinVec<T>
|
||||
where
|
||||
T: ToComputedValue,
|
||||
{
|
||||
type ComputedValue = thin_vec::ThinVec<<T as ToComputedValue>::ComputedValue>;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
self.iter()
|
||||
.map(|item| item.to_computed_value(context))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
computed.iter().map(T::from_computed_value).collect()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(emilio): This is implementable more generically, but it's unlikely
|
||||
// what you want there, as it forces you to have an extra allocation.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -180,6 +180,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ToResolvedValue for thin_vec::ThinVec<T>
|
||||
where
|
||||
T: ToResolvedValue,
|
||||
{
|
||||
type ResolvedValue = thin_vec::ThinVec<<T as ToResolvedValue>::ResolvedValue>;
|
||||
|
||||
#[inline]
|
||||
fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
|
||||
self.into_iter()
|
||||
.map(|item| item.to_resolved_value(context))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
|
||||
resolved.into_iter().map(T::from_resolved_value).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToResolvedValue for Box<T>
|
||||
where
|
||||
T: ToResolvedValue,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ serde = "1.0"
|
|||
servo_arc = { path = "../servo_arc" }
|
||||
servo_atoms = { path = "../atoms", optional = true }
|
||||
servo_url = { path = "../url", optional = true }
|
||||
thin-vec = "0.2"
|
||||
to_shmem = { path = "../to_shmem" }
|
||||
to_shmem_derive = { path = "../to_shmem_derive" }
|
||||
webrender_api = { git = "https://github.com/servo/webrender", optional = true }
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ extern crate servo_arc;
|
|||
extern crate servo_atoms;
|
||||
#[cfg(feature = "servo")]
|
||||
extern crate servo_url;
|
||||
extern crate thin_vec;
|
||||
extern crate to_shmem;
|
||||
#[macro_use]
|
||||
extern crate to_shmem_derive;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use crate::owned_slice::OwnedSlice;
|
|||
use servo_arc::Arc;
|
||||
use std::ops::Range;
|
||||
use std::sync::Arc as StdArc;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
/// Type of value that a property supports. This is used by Gecko's
|
||||
/// devtools to make sense about value it parses, and types listed
|
||||
|
|
@ -119,6 +120,7 @@ macro_rules! impl_generic_specified_value_info {
|
|||
impl_generic_specified_value_info!(Option<T>);
|
||||
impl_generic_specified_value_info!(OwnedSlice<T>);
|
||||
impl_generic_specified_value_info!(Vec<T>);
|
||||
impl_generic_specified_value_info!(ThinVec<T>);
|
||||
impl_generic_specified_value_info!(Arc<T>);
|
||||
impl_generic_specified_value_info!(StdArc<T>);
|
||||
impl_generic_specified_value_info!(ArcSlice<T>);
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ renaming_overrides_prefixing = true
|
|||
"BeforeFlag" = "StyleEasingBeforeFlag"
|
||||
"FontPaletteValueSet" = "gfx::FontPaletteValueSet"
|
||||
"PaletteValues" = "gfx::FontPaletteValueSet::PaletteValues"
|
||||
"ThinVec" = "nsTArray"
|
||||
"ThinVec" = "CopyableTArray"
|
||||
"RawPthread" = "pthread_t"
|
||||
"RawHandle" = "void*"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ use super::error_reporter::ErrorReporter;
|
|||
use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader};
|
||||
use bincode::{deserialize, serialize};
|
||||
use cssparser::ToCss as ParserToCss;
|
||||
use cssparser::{BasicParseError, ParseError as CssParseError, Parser, ParserInput, ParserState, SourceLocation, UnicodeRange, Token};
|
||||
use cssparser::{
|
||||
BasicParseError, ParseError as CssParseError, Parser, ParserInput, ParserState, SourceLocation,
|
||||
Token, UnicodeRange,
|
||||
};
|
||||
use dom::{DocumentState, ElementState};
|
||||
use malloc_size_of::MallocSizeOfOps;
|
||||
use nsstring::{nsCString, nsString};
|
||||
|
|
@ -51,12 +54,8 @@ use style::gecko_bindings::bindings;
|
|||
use style::gecko_bindings::bindings::nsACString;
|
||||
use style::gecko_bindings::bindings::nsAString;
|
||||
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
|
||||
use style::gecko_bindings::bindings::Gecko_AppendPropertyValuePair;
|
||||
use style::gecko_bindings::bindings::Gecko_ConstructFontFeatureValueSet;
|
||||
use style::gecko_bindings::bindings::Gecko_ConstructFontPaletteValueSet;
|
||||
use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
|
||||
use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
|
||||
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
|
||||
use style::gecko_bindings::bindings::Gecko_HaveSeenPtr;
|
||||
use style::gecko_bindings::structs;
|
||||
use style::gecko_bindings::structs::gfx::FontPaletteValueSet;
|
||||
|
|
@ -69,7 +68,6 @@ use style::gecko_bindings::structs::nsCSSPropertyID;
|
|||
use style::gecko_bindings::structs::nsChangeHint;
|
||||
use style::gecko_bindings::structs::nsCompatibility;
|
||||
use style::gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator;
|
||||
use style::gecko_bindings::structs::nsTArray;
|
||||
use style::gecko_bindings::structs::nsresult;
|
||||
use style::gecko_bindings::structs::CallerType;
|
||||
use style::gecko_bindings::structs::CompositeOperation;
|
||||
|
|
@ -138,9 +136,8 @@ use style::stylesheets::{
|
|||
CssRules, CssRulesHelpers, DocumentRule, FontFaceRule, FontFeatureValuesRule,
|
||||
FontPaletteValuesRule, ImportRule, KeyframesRule, LayerBlockRule, LayerStatementRule,
|
||||
MarginRule, MediaRule, NamespaceRule, Origin, OriginSet, PagePseudoClassFlags, PageRule,
|
||||
PropertyRule, SanitizationData, SanitizationKind, StartingStyleRule, StyleRule,
|
||||
PropertyRule, SanitizationData, SanitizationKind, ScopeRule, StartingStyleRule, StyleRule,
|
||||
StylesheetContents, StylesheetLoader as StyleStylesheetLoader, SupportsRule, UrlExtraData,
|
||||
ScopeRule,
|
||||
};
|
||||
use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
|
||||
use style::thread_state;
|
||||
|
|
@ -163,7 +160,7 @@ use style::values::specified::source_size_list::SourceSizeList;
|
|||
use style::values::specified::{AbsoluteLength, NoCalcLength};
|
||||
use style::values::{specified, AtomIdent, CustomIdent, KeyframesName};
|
||||
use style_traits::{CssWriter, ParseError, ParsingMode, ToCss};
|
||||
use thin_vec::ThinVec;
|
||||
use thin_vec::ThinVec as nsTArray;
|
||||
use to_shmem::SharedMemoryBuilder;
|
||||
|
||||
trait ClosureHelper {
|
||||
|
|
@ -1264,9 +1261,9 @@ pub extern "C" fn Servo_ComputedValues_ShouldTransition(
|
|||
let Some(old_value) = AnimationValue::from_computed_values(prop, old) else {
|
||||
return Default::default();
|
||||
};
|
||||
if old_value == new_value
|
||||
|| (matches!(behavior, computed::TransitionBehavior::Normal)
|
||||
&& !old_value.interpolable_with(&new_value))
|
||||
if old_value == new_value ||
|
||||
(matches!(behavior, computed::TransitionBehavior::Normal) &&
|
||||
!old_value.interpolable_with(&new_value))
|
||||
{
|
||||
return Default::default();
|
||||
}
|
||||
|
|
@ -1415,7 +1412,6 @@ pub unsafe extern "C" fn Servo_Property_SupportsType(
|
|||
prop_id.supports_type(ty)
|
||||
}
|
||||
|
||||
// TODO(emilio): We could use ThinVec instead of nsTArray.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_Property_GetCSSValuesForProperty(
|
||||
prop_name: &nsACString,
|
||||
|
|
@ -1427,18 +1423,14 @@ pub unsafe extern "C" fn Servo_Property_GetCSSValuesForProperty(
|
|||
let mut values = BTreeSet::<&'static str>::new();
|
||||
prop_id.collect_property_completion_keywords(&mut |list| values.extend(list.iter()));
|
||||
|
||||
let mut extras = vec![];
|
||||
if values.contains("transparent") {
|
||||
// This is a special value devtools use to avoid inserting the
|
||||
// long list of color keywords. We need to prepend it to values.
|
||||
extras.push("COLOR");
|
||||
result.push("COLOR".into());
|
||||
}
|
||||
|
||||
let len = extras.len() + values.len();
|
||||
bindings::Gecko_ResizeTArrayForStrings(result, len as u32);
|
||||
|
||||
for (src, dest) in extras.iter().chain(values.iter()).zip(result.iter_mut()) {
|
||||
dest.write_str(src).unwrap();
|
||||
for value in values {
|
||||
result.push(value.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1692,7 +1684,7 @@ pub unsafe extern "C" fn Servo_ShutdownThreadPool() {
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_ThreadPool_GetThreadHandles(
|
||||
handles: &mut ThinVec<PlatformThreadHandle>,
|
||||
handles: &mut nsTArray<PlatformThreadHandle>,
|
||||
) {
|
||||
StyleThreadPool::get_thread_handles(handles);
|
||||
}
|
||||
|
|
@ -2157,7 +2149,7 @@ where
|
|||
#[no_mangle]
|
||||
pub extern "C" fn Servo_CssRules_ListTypes(rules: &LockedCssRules, result: &mut nsTArray<usize>) {
|
||||
read_locked_arc(rules, |rules: &CssRules| {
|
||||
result.assign_from_iter_pod(rules.0.iter().map(|rule| rule.rule_type() as usize));
|
||||
result.extend(rules.0.iter().map(|rule| rule.rule_type() as usize));
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -2537,7 +2529,7 @@ pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: &LockedStyleRule, result
|
|||
read_locked_arc(rule, |rule| rule.selectors.to_css(result).unwrap());
|
||||
}
|
||||
|
||||
fn desugared_selector_list(rules: &ThinVec<&LockedStyleRule>) -> SelectorList {
|
||||
fn desugared_selector_list(rules: &nsTArray<&LockedStyleRule>) -> SelectorList {
|
||||
let mut selectors: Option<SelectorList> = None;
|
||||
for rule in rules.iter().rev() {
|
||||
selectors = Some(read_locked_arc(rule, |rule| match selectors {
|
||||
|
|
@ -2549,13 +2541,15 @@ fn desugared_selector_list(rules: &ThinVec<&LockedStyleRule>) -> SelectorList {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleRule_GetSelectorList(rules: &ThinVec<&LockedStyleRule>) -> *mut SelectorList {
|
||||
pub extern "C" fn Servo_StyleRule_GetSelectorList(
|
||||
rules: &nsTArray<&LockedStyleRule>,
|
||||
) -> *mut SelectorList {
|
||||
Box::into_raw(Box::new(desugared_selector_list(rules)))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleRule_GetSelectorDataAtIndex(
|
||||
rules: &ThinVec<&LockedStyleRule>,
|
||||
rules: &nsTArray<&LockedStyleRule>,
|
||||
index: u32,
|
||||
text: Option<&mut nsACString>,
|
||||
specificity: Option<&mut u64>,
|
||||
|
|
@ -2579,7 +2573,7 @@ pub extern "C" fn Servo_StyleRule_GetSelectorCount(rule: &LockedStyleRule) -> u3
|
|||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
|
||||
rules: &ThinVec<&LockedStyleRule>,
|
||||
rules: &nsTArray<&LockedStyleRule>,
|
||||
element: &RawGeckoElement,
|
||||
index: u32,
|
||||
host: Option<&RawGeckoElement>,
|
||||
|
|
@ -3408,69 +3402,47 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetUnicodeRanges(
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_FontFaceRule_GetSources(
|
||||
rule: &LockedFontFaceRule,
|
||||
out: *mut nsTArray<FontFaceSourceListComponent>,
|
||||
out: &mut nsTArray<FontFaceSourceListComponent>,
|
||||
) {
|
||||
let out = &mut *out;
|
||||
read_locked_arc_worker(rule, |rule: &FontFaceRule| {
|
||||
let sources = match rule.sources {
|
||||
Some(ref s) => s,
|
||||
None => return,
|
||||
};
|
||||
let len = sources.0.iter().fold(0, |acc, src| {
|
||||
acc + match *src {
|
||||
|
||||
for source in sources.0.iter() {
|
||||
match *source {
|
||||
Source::Url(ref url) => {
|
||||
(if url.format_hint.is_some() { 2 } else { 1 }) +
|
||||
(if url.tech_flags.is_empty() { 0 } else { 1 })
|
||||
out.push(FontFaceSourceListComponent::Url(&url.url));
|
||||
if let Some(hint) = &url.format_hint {
|
||||
match hint {
|
||||
FontFaceSourceFormat::Keyword(kw) => {
|
||||
out.push(FontFaceSourceListComponent::FormatHintKeyword(*kw))
|
||||
},
|
||||
FontFaceSourceFormat::String(s) => {
|
||||
out.push(FontFaceSourceListComponent::FormatHintString {
|
||||
length: s.len(),
|
||||
utf8_bytes: s.as_ptr(),
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
if !url.tech_flags.is_empty() {
|
||||
out.push(FontFaceSourceListComponent::TechFlags(url.tech_flags));
|
||||
}
|
||||
},
|
||||
Source::Local(ref name) => {
|
||||
out.push(FontFaceSourceListComponent::Local(name.name.as_ptr()));
|
||||
},
|
||||
Source::Local(_) => 1,
|
||||
}
|
||||
});
|
||||
|
||||
out.set_len(len as u32);
|
||||
|
||||
let mut iter = out.iter_mut();
|
||||
|
||||
{
|
||||
let mut set_next = |component: FontFaceSourceListComponent| {
|
||||
*iter.next().expect("miscalculated length") = component;
|
||||
};
|
||||
|
||||
for source in sources.0.iter() {
|
||||
match *source {
|
||||
Source::Url(ref url) => {
|
||||
set_next(FontFaceSourceListComponent::Url(&url.url));
|
||||
if let Some(hint) = &url.format_hint {
|
||||
match hint {
|
||||
FontFaceSourceFormat::Keyword(kw) => {
|
||||
set_next(FontFaceSourceListComponent::FormatHintKeyword(*kw))
|
||||
},
|
||||
FontFaceSourceFormat::String(s) => {
|
||||
set_next(FontFaceSourceListComponent::FormatHintString {
|
||||
length: s.len(),
|
||||
utf8_bytes: s.as_ptr(),
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
if !url.tech_flags.is_empty() {
|
||||
set_next(FontFaceSourceListComponent::TechFlags(url.tech_flags));
|
||||
}
|
||||
},
|
||||
Source::Local(ref name) => {
|
||||
set_next(FontFaceSourceListComponent::Local(name.name.as_ptr()));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(iter.next().is_none(), "miscalculated");
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_FontFaceRule_GetVariationSettings(
|
||||
rule: &LockedFontFaceRule,
|
||||
variations: *mut nsTArray<structs::gfxFontVariation>,
|
||||
variations: &mut nsTArray<structs::gfxFontVariation>,
|
||||
) {
|
||||
read_locked_arc_worker(rule, |rule: &FontFaceRule| {
|
||||
let source_variations = match rule.variation_settings {
|
||||
|
|
@ -3478,20 +3450,22 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetVariationSettings(
|
|||
None => return,
|
||||
};
|
||||
|
||||
(*variations).set_len(source_variations.0.len() as u32);
|
||||
for (target, source) in (*variations).iter_mut().zip(source_variations.0.iter()) {
|
||||
*target = structs::gfxFontVariation {
|
||||
mTag: source.tag.0,
|
||||
mValue: source.value.get(),
|
||||
};
|
||||
}
|
||||
variations.extend(
|
||||
source_variations
|
||||
.0
|
||||
.iter()
|
||||
.map(|source| structs::gfxFontVariation {
|
||||
mTag: source.tag.0,
|
||||
mValue: source.value.get(),
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_FontFaceRule_GetFeatureSettings(
|
||||
rule: &LockedFontFaceRule,
|
||||
features: *mut nsTArray<structs::gfxFontFeature>,
|
||||
features: &mut nsTArray<structs::gfxFontFeature>,
|
||||
) {
|
||||
read_locked_arc_worker(rule, |rule: &FontFaceRule| {
|
||||
let source_features = match rule.feature_settings {
|
||||
|
|
@ -3499,13 +3473,15 @@ pub unsafe extern "C" fn Servo_FontFaceRule_GetFeatureSettings(
|
|||
None => return,
|
||||
};
|
||||
|
||||
(*features).set_len(source_features.0.len() as u32);
|
||||
for (target, source) in (*features).iter_mut().zip(source_features.0.iter()) {
|
||||
*target = structs::gfxFontFeature {
|
||||
mTag: source.tag.0,
|
||||
mValue: source.value.value() as u32,
|
||||
};
|
||||
}
|
||||
features.extend(
|
||||
source_features
|
||||
.0
|
||||
.iter()
|
||||
.map(|source| structs::gfxFontFeature {
|
||||
mTag: source.tag.0,
|
||||
mValue: source.value.value() as u32,
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -4368,7 +4344,7 @@ pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(
|
|||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ComputedValues_GetStyleRuleList(
|
||||
values: &ComputedValues,
|
||||
rules: &mut ThinVec<*const LockedStyleRule>,
|
||||
rules: &mut nsTArray<*const LockedStyleRule>,
|
||||
) {
|
||||
let rule_node = match values.rules {
|
||||
Some(ref r) => r,
|
||||
|
|
@ -6338,22 +6314,14 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(
|
|||
}
|
||||
seen.insert(property);
|
||||
|
||||
// This is safe since we immediately write to the uninitialized values.
|
||||
unsafe {
|
||||
animation_values.set_len((property_index + 1) as u32);
|
||||
ptr::write(
|
||||
&mut animation_values[property_index],
|
||||
structs::PropertyStyleAnimationValuePair {
|
||||
mProperty: property
|
||||
.to_gecko_animated_property_id(/* owned = */ true),
|
||||
mValue: structs::AnimationValue {
|
||||
mServo: value.map_or(structs::RefPtr::null(), |v| {
|
||||
structs::RefPtr::from_arc(Arc::new(v))
|
||||
}),
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
animation_values.push(structs::PropertyStyleAnimationValuePair {
|
||||
mProperty: property.to_gecko_animated_property_id(),
|
||||
mValue: structs::AnimationValue {
|
||||
mServo: value.map_or(structs::RefPtr::null(), |v| {
|
||||
structs::RefPtr::from_arc(Arc::new(v))
|
||||
}),
|
||||
},
|
||||
});
|
||||
property_index += 1;
|
||||
};
|
||||
|
||||
|
|
@ -6383,7 +6351,7 @@ pub extern "C" fn Servo_GetAnimationValues(
|
|||
element: &RawGeckoElement,
|
||||
style: &ComputedValues,
|
||||
raw_data: &PerDocumentStyleData,
|
||||
animation_values: &mut ThinVec<structs::RefPtr<AnimationValue>>,
|
||||
animation_values: &mut nsTArray<structs::RefPtr<AnimationValue>>,
|
||||
) {
|
||||
let data = raw_data.borrow();
|
||||
let element = GeckoElement(element);
|
||||
|
|
@ -6420,7 +6388,7 @@ pub extern "C" fn Servo_AnimationValue_GetPropertyId(
|
|||
value: &AnimationValue,
|
||||
property_id: &mut structs::AnimatedPropertyID,
|
||||
) {
|
||||
*property_id = value.id().to_gecko_animated_property_id(/* owned = */ true);
|
||||
*property_id = value.id().to_gecko_animated_property_id();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
@ -6507,6 +6475,15 @@ enum Offset {
|
|||
One,
|
||||
}
|
||||
|
||||
fn property_value_pair_for(id: &PropertyDeclarationId) -> structs::PropertyValuePair {
|
||||
structs::PropertyValuePair {
|
||||
mProperty: id.to_gecko_animated_property_id(),
|
||||
mServoDeclarationBlock: structs::RefPtr::null(),
|
||||
#[cfg(feature = "gecko_debug")]
|
||||
mSimulateComputeValuesFailure: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_in_missing_keyframe_values(
|
||||
all_properties: &PropertyDeclarationIdSet,
|
||||
timing_function: &ComputedTimingFunction,
|
||||
|
|
@ -6527,22 +6504,25 @@ fn fill_in_missing_keyframe_values(
|
|||
let composition = structs::CompositeOperationOrAuto::Auto;
|
||||
let keyframe = match offset {
|
||||
Offset::Zero => unsafe {
|
||||
Gecko_GetOrCreateInitialKeyframe(keyframes, timing_function, composition)
|
||||
&mut *bindings::Gecko_GetOrCreateInitialKeyframe(
|
||||
keyframes,
|
||||
timing_function,
|
||||
composition,
|
||||
)
|
||||
},
|
||||
Offset::One => unsafe {
|
||||
Gecko_GetOrCreateFinalKeyframe(keyframes, timing_function, composition)
|
||||
&mut *bindings::Gecko_GetOrCreateFinalKeyframe(
|
||||
keyframes,
|
||||
timing_function,
|
||||
composition,
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
// Append properties that have not been set at this offset.
|
||||
for property in all_properties.iter() {
|
||||
if !properties_at_offset.contains(property) {
|
||||
unsafe {
|
||||
Gecko_AppendPropertyValuePair(
|
||||
&mut *(*keyframe).mPropertyValues,
|
||||
&property.to_gecko_animated_property_id(/* owned = */ false),
|
||||
);
|
||||
}
|
||||
keyframe.mPropertyValues.push(property_value_pair_for(&property));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6608,7 +6588,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
|
|||
|
||||
// Look for an existing keyframe with the same offset, timing function, and compsition, or
|
||||
// else add a new keyframe at the beginning of the keyframe array.
|
||||
let keyframe = Gecko_GetOrCreateKeyframeAtStart(
|
||||
let keyframe = &mut *bindings::Gecko_GetOrCreateKeyframeAtStart(
|
||||
keyframes,
|
||||
step.start_percentage.0 as f32,
|
||||
&timing_function,
|
||||
|
|
@ -6629,11 +6609,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
|
|||
continue;
|
||||
}
|
||||
seen.insert(property);
|
||||
|
||||
Gecko_AppendPropertyValuePair(
|
||||
&mut *(*keyframe).mPropertyValues,
|
||||
&property.to_gecko_animated_property_id(/* owned = */ false),
|
||||
);
|
||||
keyframe.mPropertyValues.push(property_value_pair_for(&property));
|
||||
}
|
||||
if current_offset == 0.0 {
|
||||
has_complete_initial_keyframe = true;
|
||||
|
|
@ -6665,12 +6641,8 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
|
|||
continue;
|
||||
}
|
||||
|
||||
let pair = Gecko_AppendPropertyValuePair(
|
||||
&mut *(*keyframe).mPropertyValues,
|
||||
&id.to_gecko_animated_property_id(/* owned = */ false),
|
||||
);
|
||||
|
||||
(*pair).mServoDeclarationBlock.set_arc(Arc::new(
|
||||
let mut pair = property_value_pair_for(&id);
|
||||
pair.mServoDeclarationBlock.set_arc(Arc::new(
|
||||
global_style_data
|
||||
.shared_lock
|
||||
.wrap(PropertyDeclarationBlock::with_one(
|
||||
|
|
@ -6678,6 +6650,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
|
|||
Importance::Normal,
|
||||
)),
|
||||
));
|
||||
keyframe.mPropertyValues.push(pair);
|
||||
|
||||
if current_offset == 0.0 {
|
||||
properties_set_at_start.insert(id);
|
||||
|
|
@ -6720,7 +6693,7 @@ pub unsafe extern "C" fn Servo_StyleSet_GetKeyframesForName(
|
|||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_GetFontFaceRules(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
rules: &mut ThinVec<structs::nsFontFaceRuleContainer>,
|
||||
rules: &mut nsTArray<structs::nsFontFaceRuleContainer>,
|
||||
) {
|
||||
let data = raw_data.borrow();
|
||||
debug_assert_eq!(rules.len(), 0);
|
||||
|
|
@ -7594,7 +7567,6 @@ pub extern "C" fn Servo_StyleSet_HasNthOfCustomStateDependency(
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_HasNthOfStateDependency(
|
||||
raw_data: &PerDocumentStyleData,
|
||||
|
|
@ -8156,7 +8128,7 @@ pub unsafe extern "C" fn Servo_ColorTo(
|
|||
.unwrap();
|
||||
result_color.assign(&s);
|
||||
|
||||
result_components.assign_from_iter_pod(color.raw_components().iter().copied());
|
||||
result_components.extend(color.raw_components().iter().copied());
|
||||
|
||||
// For now we don't do gamut mapping, so always false.
|
||||
*result_adjusted = false;
|
||||
|
|
@ -9100,7 +9072,7 @@ impl PropDef {
|
|||
#[no_mangle]
|
||||
pub extern "C" fn Servo_GetRegisteredCustomProperties(
|
||||
per_doc_data: &PerDocumentStyleData,
|
||||
custom_properties: &mut ThinVec<PropDef>,
|
||||
custom_properties: &mut nsTArray<PropDef>,
|
||||
) {
|
||||
let stylist = &per_doc_data.borrow().stylist;
|
||||
|
||||
|
|
@ -9140,7 +9112,7 @@ pub struct SelectorWarningData {
|
|||
#[no_mangle]
|
||||
pub extern "C" fn Servo_GetSelectorWarnings(
|
||||
rule: &LockedStyleRule,
|
||||
warnings: &mut ThinVec<SelectorWarningData>,
|
||||
warnings: &mut nsTArray<SelectorWarningData>,
|
||||
) {
|
||||
read_locked_arc(rule, |r| {
|
||||
for (i, selector) in r.selectors.slice().iter().enumerate() {
|
||||
|
|
@ -9152,10 +9124,7 @@ pub extern "C" fn Servo_GetSelectorWarnings(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_GetRuleBodyText(
|
||||
initial_text: &nsACString,
|
||||
ret_val: &mut nsACString,
|
||||
) {
|
||||
pub extern "C" fn Servo_GetRuleBodyText(initial_text: &nsACString, ret_val: &mut nsACString) {
|
||||
let css_text = unsafe { initial_text.as_str_unchecked() };
|
||||
let mut input = ParserInput::new(&css_text);
|
||||
let mut input = Parser::new(&mut input);
|
||||
|
|
@ -9169,7 +9138,7 @@ pub extern "C" fn Servo_GetRuleBodyText(
|
|||
found_start = true;
|
||||
break;
|
||||
},
|
||||
_ => {}
|
||||
_ => {},
|
||||
}
|
||||
|
||||
if token.is_parse_error() {
|
||||
|
|
@ -9177,7 +9146,6 @@ pub extern "C" fn Servo_GetRuleBodyText(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if !found_start {
|
||||
ret_val.set_is_void(true);
|
||||
return;
|
||||
|
|
@ -9185,11 +9153,8 @@ pub extern "C" fn Servo_GetRuleBodyText(
|
|||
|
||||
let token_start = input.position();
|
||||
// Parse the nested block to move the parser to the end of the block
|
||||
let _ = input.parse_nested_block(
|
||||
|_i| -> Result<(), CssParseError<'_, BasicParseError>> {
|
||||
Ok(())
|
||||
}
|
||||
);
|
||||
let _ =
|
||||
input.parse_nested_block(|_i| -> Result<(), CssParseError<'_, BasicParseError>> { Ok(()) });
|
||||
|
||||
// We're not guaranteed to have a closing bracket, but when we do, we need to move
|
||||
// the end offset before it.
|
||||
|
|
@ -9239,11 +9204,8 @@ pub extern "C" fn Servo_ReplaceBlockRuleBodyTextInStylesheetText(
|
|||
let token_start = input.position();
|
||||
let rule_body_start = rule_start_index + token_start.byte_index();
|
||||
// Parse the nested block to move the parser to the end of the block
|
||||
let _ = input.parse_nested_block(
|
||||
|_i| -> Result<(), CssParseError<'_, BasicParseError>> {
|
||||
Ok(())
|
||||
}
|
||||
);
|
||||
let _ =
|
||||
input.parse_nested_block(|_i| -> Result<(), CssParseError<'_, BasicParseError>> { Ok(()) });
|
||||
let mut rule_body_end = rule_start_index + input.position().byte_index();
|
||||
|
||||
// We're not guaranteed to have a closing bracket, but when we do, we need to move
|
||||
|
|
@ -9259,11 +9221,7 @@ pub extern "C" fn Servo_ReplaceBlockRuleBodyTextInStylesheetText(
|
|||
}
|
||||
|
||||
/// Find css_text byte position corresponding to the passed line and column
|
||||
fn get_byte_index_from_line_and_column(
|
||||
css_text: &str,
|
||||
line: u32,
|
||||
column: u32,
|
||||
) -> Option<usize> {
|
||||
fn get_byte_index_from_line_and_column(css_text: &str, line: u32, column: u32) -> Option<usize> {
|
||||
// Find the byte index of the start of the passed line within css_text
|
||||
let mut line_byte_index = Some(0);
|
||||
if line != 1 {
|
||||
|
|
@ -9325,9 +9283,7 @@ pub struct CSSToken {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_CSSParser_create(
|
||||
text: &nsACString,
|
||||
) -> *mut ParserState {
|
||||
pub unsafe extern "C" fn Servo_CSSParser_create(text: &nsACString) -> *mut ParserState {
|
||||
let css_text = unsafe { text.as_str_unchecked() };
|
||||
let mut parser_input = ParserInput::new(&css_text);
|
||||
let input = Parser::new(&mut parser_input);
|
||||
|
|
@ -9335,23 +9291,17 @@ pub unsafe extern "C" fn Servo_CSSParser_create(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_CSSParser_destroy(
|
||||
state: *mut ParserState,
|
||||
) {
|
||||
pub unsafe extern "C" fn Servo_CSSParser_destroy(state: *mut ParserState) {
|
||||
drop(Box::from_raw(state));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_CSSParser_GetCurrentLine(
|
||||
state: &ParserState,
|
||||
) -> u32 {
|
||||
pub unsafe extern "C" fn Servo_CSSParser_GetCurrentLine(state: &ParserState) -> u32 {
|
||||
return state.source_location().line;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_CSSParser_GetCurrentColumn(
|
||||
state: &ParserState,
|
||||
) -> u32 {
|
||||
pub unsafe extern "C" fn Servo_CSSParser_GetCurrentColumn(state: &ParserState) -> u32 {
|
||||
return state.source_location().column;
|
||||
}
|
||||
|
||||
|
|
@ -9380,9 +9330,9 @@ pub unsafe extern "C" fn Servo_CSSParser_NextToken(
|
|||
Token::QuotedString(_) => "QuotedString",
|
||||
Token::UnquotedUrl(_) => "UnquotedUrl",
|
||||
Token::Delim(_) => "Delim",
|
||||
Token::Number{..} => "Number",
|
||||
Token::Percentage{..} => "Percentage",
|
||||
Token::Dimension{..} => "Dimension",
|
||||
Token::Number { .. } => "Number",
|
||||
Token::Percentage { .. } => "Percentage",
|
||||
Token::Dimension { .. } => "Dimension",
|
||||
Token::WhiteSpace(_) => "WhiteSpace",
|
||||
Token::Comment(_) => "Comment",
|
||||
Token::Colon => "Colon",
|
||||
|
|
@ -9454,27 +9404,19 @@ pub unsafe extern "C" fn Servo_CSSParser_NextToken(
|
|||
};
|
||||
|
||||
let token_unit = match *token {
|
||||
Token::Dimension{
|
||||
ref unit, ..
|
||||
} => {
|
||||
Token::Dimension { ref unit, .. } => {
|
||||
let mut unit_text = nsCString::new();
|
||||
unit_text.assign(unit.as_bytes());
|
||||
Some(unit_text)
|
||||
},
|
||||
_ => None
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let token_number = match *token {
|
||||
Token::Dimension {
|
||||
ref value, ..
|
||||
} => Some(value),
|
||||
Token::Number{
|
||||
ref value, ..
|
||||
} => Some(value),
|
||||
Token::Percentage{
|
||||
ref unit_value, ..
|
||||
} => Some(unit_value),
|
||||
_ => None
|
||||
Token::Dimension { ref value, .. } => Some(value),
|
||||
Token::Number { ref value, .. } => Some(value),
|
||||
Token::Percentage { ref unit_value, .. } => Some(unit_value),
|
||||
_ => None,
|
||||
};
|
||||
css_token.has_number = token_number.is_some();
|
||||
if css_token.has_number {
|
||||
|
|
@ -9507,12 +9449,10 @@ pub unsafe extern "C" fn Servo_CSSParser_NextToken(
|
|||
css_token.column = location_start.column;
|
||||
|
||||
if need_to_parse_nested_block {
|
||||
let _ = input.parse_nested_block(
|
||||
|i| -> Result<(), CssParseError<'_, BasicParseError>> {
|
||||
*state = i.state();
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
let _ = input.parse_nested_block(|i| -> Result<(), CssParseError<'_, BasicParseError>> {
|
||||
*state = i.state();
|
||||
Ok(())
|
||||
});
|
||||
} else {
|
||||
*state = input.state();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -369,13 +369,6 @@ struct nsTArray_SafeElementAtHelper<mozilla::OwningNonNull<E>, Derived>
|
|||
: public nsTArray_SafeElementAtSmartPtrHelper<mozilla::OwningNonNull<E>,
|
||||
Derived> {};
|
||||
|
||||
// Servo bindings.
|
||||
extern "C" void Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity,
|
||||
size_t aElementSize);
|
||||
extern "C" void Gecko_ClearPODTArray(void* aArray, size_t aElementSize,
|
||||
size_t aElementAlign);
|
||||
|
||||
//
|
||||
// This class serves as a base class for nsTArray. It shouldn't be used
|
||||
// directly. It holds common implementation code that does not depend on the
|
||||
// element type of the nsTArray.
|
||||
|
|
@ -393,11 +386,6 @@ class nsTArray_base {
|
|||
template <class E, class XAlloc>
|
||||
friend class nsTArray_Impl;
|
||||
|
||||
friend void Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity,
|
||||
size_t aElemSize);
|
||||
friend void Gecko_ClearPODTArray(void* aTArray, size_t aElementSize,
|
||||
size_t aElementAlign);
|
||||
|
||||
protected:
|
||||
typedef nsTArrayHeader Header;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue