style: Use Servo for the representation of grid template areas.

Right now we do a lot of useless string copying. In order to avoid transcoding
to utf-16 during layout, make sure to use nsCString at a few related places.

I may revisit this since we're storing other line names as atoms in some places.
So it may be better to just use atoms everywhere.

But that'd be a different patch either way.

Differential Revision: https://phabricator.services.mozilla.com/D35117
This commit is contained in:
Emilio Cobos Álvarez 2019-06-18 22:29:58 +00:00
parent e8271ee926
commit 6cb588d2b5
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
4 changed files with 68 additions and 130 deletions

View file

@ -1083,8 +1083,8 @@ fn static_assert() {
align-content justify-content align-self
justify-self align-items justify-items
grid-auto-rows grid-auto-columns
grid-auto-flow grid-template-areas
grid-template-rows grid-template-columns">
grid-auto-flow grid-template-rows
grid-template-columns">
% for side in SIDES:
<% impl_split_style_coord(side.ident, "mOffset", side.index) %>
% endfor
@ -1136,13 +1136,19 @@ fn static_assert() {
pub fn set_${value.name}(&mut self, v: longhands::${value.name}::computed_value::T) {
use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
let ident = v.ident.as_ref().map_or(&[] as &[_], |ident| ident.0.as_slice());
self.gecko.${value.gecko}.mLineName.assign(ident);
self.gecko.${value.gecko}.mHasSpan = v.is_span;
let line = &mut self.gecko.${value.gecko};
let line_name = &mut line.mLineName;
match v.ident.as_ref() {
Some(i) => i.0.with_str(|s| line_name.assign(s)),
None => line_name.assign(""),
};
line.mHasSpan = v.is_span;
if let Some(integer) = v.line_num {
// clamping the integer between a range
self.gecko.${value.gecko}.mInteger = cmp::max(nsStyleGridLine_kMinLine,
cmp::min(integer, nsStyleGridLine_kMaxLine));
line.mInteger = cmp::max(
nsStyleGridLine_kMinLine,
cmp::min(integer, nsStyleGridLine_kMaxLine),
);
}
}
@ -1205,20 +1211,20 @@ fn static_assert() {
pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
use crate::gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine};
use nsstring::nsString;
use nsstring::nsCString;
use std::usize;
use crate::values::CustomIdent;
use crate::values::generics::grid::TrackListType::Auto;
use crate::values::generics::grid::{GridTemplateComponent, RepeatCount};
#[inline]
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<nsString>) {
fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<nsCString>) {
unsafe {
bindings::Gecko_ResizeTArrayForStrings(gecko_names, servo_names.len() as u32);
bindings::Gecko_ResizeTArrayForCStrings(gecko_names, servo_names.len() as u32);
}
for (servo_name, gecko_name) in servo_names.iter().zip(gecko_names.iter_mut()) {
gecko_name.assign(servo_name.0.as_slice());
servo_name.0.with_str(|s| gecko_name.assign(s))
}
}
@ -1256,9 +1262,9 @@ fn static_assert() {
auto_track_size = Some(auto_repeat.track_sizes.get(0).unwrap().clone());
} else {
unsafe {
bindings::Gecko_ResizeTArrayForStrings(
bindings::Gecko_ResizeTArrayForCStrings(
&mut value.mRepeatAutoLineNameListBefore, 0);
bindings::Gecko_ResizeTArrayForStrings(
bindings::Gecko_ResizeTArrayForCStrings(
&mut value.mRepeatAutoLineNameListAfter, 0);
}
}
@ -1332,7 +1338,7 @@ fn static_assert() {
pub fn clone_grid_template_${kind}(&self) -> longhands::grid_template_${kind}::computed_value::T {
<% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
use crate::gecko_bindings::structs::nsTArray;
use nsstring::nsString;
use nsstring::nsCString;
use crate::values::CustomIdent;
use crate::values::generics::grid::{GridTemplateComponent, LineNameList, RepeatCount};
use crate::values::generics::grid::{TrackList, TrackListType, TrackListValue, TrackRepeat, TrackSize};
@ -1343,15 +1349,15 @@ fn static_assert() {
};
#[inline]
fn to_boxed_customident_slice(gecko_names: &nsTArray<nsString>) -> Box<[CustomIdent]> {
fn to_boxed_customident_slice(gecko_names: &nsTArray<nsCString>) -> Box<[CustomIdent]> {
let idents: Vec<CustomIdent> = gecko_names.iter().map(|gecko_name| {
CustomIdent(Atom::from(gecko_name.to_string()))
CustomIdent(Atom::from(unsafe { gecko_name.as_str_unchecked() }))
}).collect();
idents.into_boxed_slice()
}
#[inline]
fn to_line_names_vec(gecko_line_names: &nsTArray<nsTArray<nsString>>)
fn to_line_names_vec(gecko_line_names: &nsTArray<nsTArray<nsCString>>)
-> Vec<Box<[CustomIdent]>> {
gecko_line_names.iter().map(|gecko_names| {
to_boxed_customident_slice(gecko_names)
@ -1415,88 +1421,6 @@ fn static_assert() {
% endfor
${impl_simple_type_with_conversion("grid_auto_flow")}
pub fn set_grid_template_areas(&mut self, v: values::computed::position::GridTemplateAreas) {
use crate::gecko_bindings::bindings::Gecko_NewGridTemplateAreasValue;
use crate::gecko_bindings::sugar::refptr::UniqueRefPtr;
let v = match v {
Either::First(areas) => areas,
Either::Second(_) => {
unsafe { self.gecko.mGridTemplateAreas.clear() }
return;
},
};
let mut refptr = unsafe {
UniqueRefPtr::from_addrefed(
Gecko_NewGridTemplateAreasValue(v.0.areas.len() as u32, v.0.strings.len() as u32, v.0.width))
};
for (servo, gecko) in v.0.areas.iter().zip(refptr.mNamedAreas.iter_mut()) {
gecko.mName.assign_str(&*servo.name);
gecko.mColumnStart = servo.columns.start;
gecko.mColumnEnd = servo.columns.end;
gecko.mRowStart = servo.rows.start;
gecko.mRowEnd = servo.rows.end;
}
for (servo, gecko) in v.0.strings.iter().zip(refptr.mTemplates.iter_mut()) {
gecko.assign_str(&*servo);
}
self.gecko.mGridTemplateAreas.set_move(refptr.get())
}
pub fn copy_grid_template_areas_from(&mut self, other: &Self) {
unsafe { self.gecko.mGridTemplateAreas.set(&other.gecko.mGridTemplateAreas) }
}
pub fn reset_grid_template_areas(&mut self, other: &Self) {
self.copy_grid_template_areas_from(other)
}
pub fn clone_grid_template_areas(&self) -> values::computed::position::GridTemplateAreas {
use crate::values::None_;
use crate::values::specified::position::{NamedArea, TemplateAreas, TemplateAreasArc, UnsignedRange};
if self.gecko.mGridTemplateAreas.mRawPtr.is_null() {
return Either::Second(None_);
}
let gecko_grid_template_areas = self.gecko.mGridTemplateAreas.mRawPtr;
let areas = unsafe {
let vec: Vec<NamedArea> =
(*gecko_grid_template_areas).mNamedAreas.iter().map(|gecko_name_area| {
let name = gecko_name_area.mName.to_string().into();
let rows = UnsignedRange {
start: gecko_name_area.mRowStart,
end: gecko_name_area.mRowEnd
};
let columns = UnsignedRange {
start: gecko_name_area.mColumnStart,
end: gecko_name_area.mColumnEnd
};
NamedArea { name, rows, columns }
}).collect();
vec.into()
};
let strings = unsafe {
let vec: Vec<crate::OwnedStr> =
(*gecko_grid_template_areas).mTemplates.iter().map(|gecko_template| {
gecko_template.to_string().into()
}).collect();
vec.into()
};
let width = unsafe {
(*gecko_grid_template_areas).mNColumns
};
Either::First(TemplateAreasArc(Arc::new(TemplateAreas { areas, strings, width })))
}
</%self:impl_trait>
<% skip_outline_longhands = " ".join("outline-style outline-width".split() +