auto merge of #2478 : SimonSapin/servo/style-getters, r=metajack

This isolates layout code from upcoming refactoring in properties.rs.mako.
This commit is contained in:
bors-servo 2014-05-28 17:49:05 -04:00
commit 50c2af8ef1
18 changed files with 207 additions and 278 deletions

View file

@ -299,21 +299,21 @@ impl CandidateHeightIterator {
// the containing block. If that is not determined yet by the time we need to resolve // the containing block. If that is not determined yet by the time we need to resolve
// `min-height` and `max-height`, percentage values are ignored. // `min-height` and `max-height`, percentage values are ignored.
let height = match (style.Box.get().height, block_container_height) { let height = match (style.get_box().height, block_container_height) {
(LPA_Percentage(percent), Some(block_container_height)) => { (LPA_Percentage(percent), Some(block_container_height)) => {
Specified(block_container_height.scale_by(percent)) Specified(block_container_height.scale_by(percent))
} }
(LPA_Percentage(_), None) | (LPA_Auto, _) => Auto, (LPA_Percentage(_), None) | (LPA_Auto, _) => Auto,
(LPA_Length(length), _) => Specified(length), (LPA_Length(length), _) => Specified(length),
}; };
let max_height = match (style.Box.get().max_height, block_container_height) { let max_height = match (style.get_box().max_height, block_container_height) {
(LPN_Percentage(percent), Some(block_container_height)) => { (LPN_Percentage(percent), Some(block_container_height)) => {
Some(block_container_height.scale_by(percent)) Some(block_container_height.scale_by(percent))
} }
(LPN_Percentage(_), None) | (LPN_None, _) => None, (LPN_Percentage(_), None) | (LPN_None, _) => None,
(LPN_Length(length), _) => Some(length), (LPN_Length(length), _) => Some(length),
}; };
let min_height = match (style.Box.get().min_height, block_container_height) { let min_height = match (style.get_box().min_height, block_container_height) {
(LP_Percentage(percent), Some(block_container_height)) => { (LP_Percentage(percent), Some(block_container_height)) => {
block_container_height.scale_by(percent) block_container_height.scale_by(percent)
} }
@ -1183,11 +1183,11 @@ impl BlockFlow {
{ {
// Non-auto margin-top and margin-bottom values have already been // Non-auto margin-top and margin-bottom values have already been
// calculated during assign-width. // calculated during assign-width.
let margin_top = match self.box_.style().Margin.get().margin_top { let margin_top = match self.box_.style().get_margin().margin_top {
LPA_Auto => Auto, LPA_Auto => Auto,
_ => Specified(self.box_.margin.top) _ => Specified(self.box_.margin.top)
}; };
let margin_bottom = match self.box_.style().Margin.get().margin_bottom { let margin_bottom = match self.box_.style().get_margin().margin_bottom {
LPA_Auto => Auto, LPA_Auto => Auto,
_ => Specified(self.box_.margin.bottom) _ => Specified(self.box_.margin.bottom)
}; };
@ -1195,7 +1195,7 @@ impl BlockFlow {
let top; let top;
let bottom; let bottom;
{ {
let position_style = self.box_.style().PositionOffsets.get(); let position_style = self.box_.style().get_positionoffsets();
top = MaybeAuto::from_style(position_style.top, containing_block_height); top = MaybeAuto::from_style(position_style.top, containing_block_height);
bottom = MaybeAuto::from_style(position_style.bottom, containing_block_height); bottom = MaybeAuto::from_style(position_style.bottom, containing_block_height);
} }
@ -1397,15 +1397,15 @@ impl BlockFlow {
/// `FormattingContextType`. /// `FormattingContextType`.
fn formatting_context_type(&self) -> FormattingContextType { fn formatting_context_type(&self) -> FormattingContextType {
let style = self.box_.style(); let style = self.box_.style();
if style.Box.get().float != float::none { if style.get_box().float != float::none {
return OtherFormattingContext return OtherFormattingContext
} }
match style.Box.get().display { match style.get_box().display {
display::table_cell | display::table_caption | display::inline_block => { display::table_cell | display::table_caption | display::inline_block => {
OtherFormattingContext OtherFormattingContext
} }
_ if style.Box.get().position == position::static_ && _ if style.get_box().position == position::static_ &&
style.Box.get().overflow != overflow::visible => { style.get_box().overflow != overflow::visible => {
BlockFormattingContext BlockFormattingContext
} }
_ => NonformattingContext, _ => NonformattingContext,
@ -1424,7 +1424,7 @@ impl Flow for BlockFlow {
/// Returns the direction that this flow clears floats in, if any. /// Returns the direction that this flow clears floats in, if any.
fn float_clearance(&self) -> clear::T { fn float_clearance(&self) -> clear::T {
self.box_.style().Box.get().clear self.box_.style().get_box().clear
} }
/// Pass 1 of reflow: computes minimum and preferred widths. /// Pass 1 of reflow: computes minimum and preferred widths.
@ -1466,7 +1466,7 @@ impl Flow for BlockFlow {
intrinsic_widths.surround_width = box_intrinsic_widths.surround_width; intrinsic_widths.surround_width = box_intrinsic_widths.surround_width;
self.base.intrinsic_widths = intrinsic_widths; self.base.intrinsic_widths = intrinsic_widths;
match self.box_.style().Box.get().float { match self.box_.style().get_box().float {
float::none => {} float::none => {}
float::left => flags.set_has_left_floated_descendants(true), float::left => flags.set_has_left_floated_descendants(true),
float::right => flags.set_has_right_floated_descendants(true), float::right => flags.set_has_right_floated_descendants(true),
@ -1666,7 +1666,7 @@ impl Flow for BlockFlow {
/// The 'position' property of this flow. /// The 'position' property of this flow.
fn positioning(&self) -> position::T { fn positioning(&self) -> position::T {
self.box_.style.Box.get().position self.box_.style.get_box().position
} }
/// Return true if this is the root of an Absolute flow tree. /// Return true if this is the root of an Absolute flow tree.
@ -1799,15 +1799,15 @@ pub trait WidthAndMarginsComputer {
let style = block.box_.style(); let style = block.box_.style();
// The text alignment of a block flow is the text alignment of its box's style. // The text alignment of a block flow is the text alignment of its box's style.
block.base.flags.set_text_align(style.InheritedText.get().text_align); block.base.flags.set_text_align(style.get_inheritedtext().text_align);
let (margin_left, margin_right) = let (margin_left, margin_right) =
(MaybeAuto::from_style(style.Margin.get().margin_left, containing_block_width), (MaybeAuto::from_style(style.get_margin().margin_left, containing_block_width),
MaybeAuto::from_style(style.Margin.get().margin_right, containing_block_width)); MaybeAuto::from_style(style.get_margin().margin_right, containing_block_width));
let (left, right) = let (left, right) =
(MaybeAuto::from_style(style.PositionOffsets.get().left, containing_block_width), (MaybeAuto::from_style(style.get_positionoffsets().left, containing_block_width),
MaybeAuto::from_style(style.PositionOffsets.get().right, containing_block_width)); MaybeAuto::from_style(style.get_positionoffsets().right, containing_block_width));
let available_width = containing_block_width - block.box_.border_padding.horizontal(); let available_width = containing_block_width - block.box_.border_padding.horizontal();
return WidthConstraintInput::new(computed_width, return WidthConstraintInput::new(computed_width,
margin_left, margin_left,
@ -1854,7 +1854,7 @@ pub trait WidthAndMarginsComputer {
parent_flow_width: Au, parent_flow_width: Au,
ctx: &mut LayoutContext) ctx: &mut LayoutContext)
-> MaybeAuto { -> MaybeAuto {
MaybeAuto::from_style(block.box_().style().Box.get().width, MaybeAuto::from_style(block.box_().style().get_box().width,
self.containing_block_width(block, parent_flow_width, ctx)) self.containing_block_width(block, parent_flow_width, ctx))
} }
@ -1881,7 +1881,7 @@ pub trait WidthAndMarginsComputer {
// If the tentative used width is greater than 'max-width', width should be recalculated, // If the tentative used width is greater than 'max-width', width should be recalculated,
// but this time using the computed value of 'max-width' as the computed value for 'width'. // but this time using the computed value of 'max-width' as the computed value for 'width'.
match specified_or_none(block.box_().style().Box.get().max_width, containing_block_width) { match specified_or_none(block.box_().style().get_box().max_width, containing_block_width) {
Some(max_width) if max_width < solution.width => { Some(max_width) if max_width < solution.width => {
input.computed_width = Specified(max_width); input.computed_width = Specified(max_width);
solution = self.solve_width_constraints(block, &input); solution = self.solve_width_constraints(block, &input);
@ -1891,7 +1891,7 @@ pub trait WidthAndMarginsComputer {
// If the resulting width is smaller than 'min-width', width should be recalculated, // If the resulting width is smaller than 'min-width', width should be recalculated,
// but this time using the value of 'min-width' as the computed value for 'width'. // but this time using the value of 'min-width' as the computed value for 'width'.
let computed_min_width = specified(block.box_().style().Box.get().min_width, let computed_min_width = specified(block.box_().style().get_box().min_width,
containing_block_width); containing_block_width);
if computed_min_width > solution.width { if computed_min_width > solution.width {
input.computed_width = Specified(computed_min_width); input.computed_width = Specified(computed_min_width);

View file

@ -416,18 +416,18 @@ impl Box {
}; };
let style = self.style(); let style = self.style();
let width = MaybeAuto::from_style(style.Box.get().width, Au::new(0)).specified_or_zero(); let width = MaybeAuto::from_style(style.get_box().width, Au::new(0)).specified_or_zero();
let (margin_left, margin_right) = if use_margins { let (margin_left, margin_right) = if use_margins {
(MaybeAuto::from_style(style.Margin.get().margin_left, Au(0)).specified_or_zero(), (MaybeAuto::from_style(style.get_margin().margin_left, Au(0)).specified_or_zero(),
MaybeAuto::from_style(style.Margin.get().margin_right, Au(0)).specified_or_zero()) MaybeAuto::from_style(style.get_margin().margin_right, Au(0)).specified_or_zero())
} else { } else {
(Au(0), Au(0)) (Au(0), Au(0))
}; };
let (padding_left, padding_right) = if use_padding { let (padding_left, padding_right) = if use_padding {
(model::specified(style.Padding.get().padding_left, Au(0)), (model::specified(style.get_padding().padding_left, Au(0)),
model::specified(style.Padding.get().padding_right, Au(0))) model::specified(style.get_padding().padding_right, Au(0)))
} else { } else {
(Au(0), Au(0)) (Au(0), Au(0))
}; };
@ -478,10 +478,10 @@ impl Box {
_ => { _ => {
// NB: Percentages are relative to containing block width (not height) per CSS 2.1. // NB: Percentages are relative to containing block width (not height) per CSS 2.1.
self.margin.top = self.margin.top =
MaybeAuto::from_style(self.style().Margin.get().margin_top, MaybeAuto::from_style(self.style().get_margin().margin_top,
containing_block_width).specified_or_zero(); containing_block_width).specified_or_zero();
self.margin.bottom = self.margin.bottom =
MaybeAuto::from_style(self.style().Margin.get().margin_bottom, MaybeAuto::from_style(self.style().get_margin().margin_bottom,
containing_block_width).specified_or_zero() containing_block_width).specified_or_zero()
} }
} }
@ -517,26 +517,26 @@ impl Box {
-> Point2D<Au> { -> Point2D<Au> {
fn left_right(style: &ComputedValues, block_width: Au) -> Au { fn left_right(style: &ComputedValues, block_width: Au) -> Au {
// TODO(ksh8281) : consider RTL(right-to-left) culture // TODO(ksh8281) : consider RTL(right-to-left) culture
match (style.PositionOffsets.get().left, style.PositionOffsets.get().right) { match (style.get_positionoffsets().left, style.get_positionoffsets().right) {
(LPA_Auto, _) => { (LPA_Auto, _) => {
-MaybeAuto::from_style(style.PositionOffsets.get().right, block_width) -MaybeAuto::from_style(style.get_positionoffsets().right, block_width)
.specified_or_zero() .specified_or_zero()
} }
(_, _) => { (_, _) => {
MaybeAuto::from_style(style.PositionOffsets.get().left, block_width) MaybeAuto::from_style(style.get_positionoffsets().left, block_width)
.specified_or_zero() .specified_or_zero()
} }
} }
} }
fn top_bottom(style: &ComputedValues,block_height: Au) -> Au { fn top_bottom(style: &ComputedValues,block_height: Au) -> Au {
match (style.PositionOffsets.get().top, style.PositionOffsets.get().bottom) { match (style.get_positionoffsets().top, style.get_positionoffsets().bottom) {
(LPA_Auto, _) => { (LPA_Auto, _) => {
-MaybeAuto::from_style(style.PositionOffsets.get().bottom, block_height) -MaybeAuto::from_style(style.get_positionoffsets().bottom, block_height)
.specified_or_zero() .specified_or_zero()
} }
(_, _) => { (_, _) => {
MaybeAuto::from_style(style.PositionOffsets.get().top, block_height) MaybeAuto::from_style(style.get_positionoffsets().top, block_height)
.specified_or_zero() .specified_or_zero()
} }
} }
@ -546,14 +546,14 @@ impl Box {
let mut rel_pos: Point2D<Au> = Zero::zero(); let mut rel_pos: Point2D<Au> = Zero::zero();
match inline_fragment_context { match inline_fragment_context {
None => { None => {
if self.style().Box.get().position == position::relative { if self.style().get_box().position == position::relative {
rel_pos.x = rel_pos.x + left_right(self.style(), container_block_size.width); rel_pos.x = rel_pos.x + left_right(self.style(), container_block_size.width);
rel_pos.y = rel_pos.y + top_bottom(self.style(), container_block_size.height); rel_pos.y = rel_pos.y + top_bottom(self.style(), container_block_size.height);
} }
} }
Some(inline_fragment_context) => { Some(inline_fragment_context) => {
for range in inline_fragment_context.ranges() { for range in inline_fragment_context.ranges() {
if range.style.Box.get().position == position::relative { if range.style.get_box().position == position::relative {
rel_pos.x = rel_pos.x + left_right(&*range.style, rel_pos.x = rel_pos.x + left_right(&*range.style,
container_block_size.width); container_block_size.width);
rel_pos.y = rel_pos.y + top_bottom(&*range.style, rel_pos.y = rel_pos.y + top_bottom(&*range.style,
@ -572,7 +572,7 @@ impl Box {
#[inline(always)] #[inline(always)]
pub fn clear(&self) -> Option<ClearType> { pub fn clear(&self) -> Option<ClearType> {
let style = self.style(); let style = self.style();
match style.Box.get().clear { match style.get_box().clear {
clear::none => None, clear::none => None,
clear::left => Some(ClearLeft), clear::left => Some(ClearLeft),
clear::right => Some(ClearRight), clear::right => Some(ClearRight),
@ -593,15 +593,15 @@ impl Box {
/// Returns the text alignment of the computed style of the nearest ancestor-or-self `Element` /// Returns the text alignment of the computed style of the nearest ancestor-or-self `Element`
/// node. /// node.
pub fn text_align(&self) -> text_align::T { pub fn text_align(&self) -> text_align::T {
self.style().InheritedText.get().text_align self.style().get_inheritedtext().text_align
} }
pub fn vertical_align(&self) -> vertical_align::T { pub fn vertical_align(&self) -> vertical_align::T {
self.style().Box.get().vertical_align self.style().get_box().vertical_align
} }
pub fn white_space(&self) -> white_space::T { pub fn white_space(&self) -> white_space::T {
self.style().InheritedText.get().white_space self.style().get_inheritedtext().white_space
} }
/// Returns the text decoration of this box, according to the style of the nearest ancestor /// Returns the text decoration of this box, according to the style of the nearest ancestor
@ -612,7 +612,7 @@ impl Box {
/// model. Therefore, this is a best lower bound approximation, but the end result may actually /// model. Therefore, this is a best lower bound approximation, but the end result may actually
/// have the various decoration flags turned on afterward. /// have the various decoration flags turned on afterward.
pub fn text_decoration(&self) -> text_decoration::T { pub fn text_decoration(&self) -> text_decoration::T {
self.style().Text.get().text_decoration self.style().get_text().text_decoration
} }
/// Returns the left offset from margin edge to content edge. /// Returns the left offset from margin edge to content edge.
@ -648,7 +648,7 @@ impl Box {
// inefficient. What we really want is something like "nearest ancestor element that // inefficient. What we really want is something like "nearest ancestor element that
// doesn't have a box". // doesn't have a box".
let style = self.style(); let style = self.style();
let background_color = style.resolve_color(style.Background.get().background_color); let background_color = style.resolve_color(style.get_background().background_color);
if !background_color.alpha.approx_eq(&0.0) { if !background_color.alpha.approx_eq(&0.0) {
let display_item = box SolidColorDisplayItem { let display_item = box SolidColorDisplayItem {
base: BaseDisplayItem::new(*absolute_bounds, self.node, level), base: BaseDisplayItem::new(*absolute_bounds, self.node, level),
@ -661,7 +661,7 @@ impl Box {
// The background image is painted on top of the background color. // The background image is painted on top of the background color.
// Implements background image, per spec: // Implements background image, per spec:
// http://www.w3.org/TR/CSS21/colors.html#background // http://www.w3.org/TR/CSS21/colors.html#background
let background = style.Background.get(); let background = style.get_background();
let image_url = match background.background_image { let image_url = match background.background_image {
None => return, None => return,
Some(ref image_url) => image_url, Some(ref image_url) => image_url,
@ -757,10 +757,10 @@ impl Box {
} }
let style = self.style(); let style = self.style();
let top_color = style.resolve_color(style.Border.get().border_top_color); let top_color = style.resolve_color(style.get_border().border_top_color);
let right_color = style.resolve_color(style.Border.get().border_right_color); let right_color = style.resolve_color(style.get_border().border_right_color);
let bottom_color = style.resolve_color(style.Border.get().border_bottom_color); let bottom_color = style.resolve_color(style.get_border().border_bottom_color);
let left_color = style.resolve_color(style.Border.get().border_left_color); let left_color = style.resolve_color(style.get_border().border_left_color);
// Append the border to the display list. // Append the border to the display list.
let border_display_item = box BorderDisplayItem { let border_display_item = box BorderDisplayItem {
@ -770,10 +770,10 @@ impl Box {
right_color.to_gfx_color(), right_color.to_gfx_color(),
bottom_color.to_gfx_color(), bottom_color.to_gfx_color(),
left_color.to_gfx_color()), left_color.to_gfx_color()),
style: SideOffsets2D::new(style.Border.get().border_top_style, style: SideOffsets2D::new(style.get_border().border_top_style,
style.Border.get().border_right_style, style.get_border().border_right_style,
style.Border.get().border_bottom_style, style.get_border().border_bottom_style,
style.Border.get().border_left_style) style.get_border().border_left_style)
}; };
list.push(BorderDisplayItemClass(border_display_item)) list.push(BorderDisplayItemClass(border_display_item))
@ -859,7 +859,7 @@ impl Box {
absolute_box_bounds, absolute_box_bounds,
self.node, self.node,
ContentStackingLevel); ContentStackingLevel);
if self.style().InheritedBox.get().visibility != visibility::visible { if self.style().get_inheritedbox().visibility != visibility::visible {
return accumulator return accumulator
} }
@ -899,12 +899,11 @@ impl Box {
TableColumnBox(_) => fail!("Shouldn't see table column boxes here."), TableColumnBox(_) => fail!("Shouldn't see table column boxes here."),
ScannedTextBox(ref text_box) => { ScannedTextBox(ref text_box) => {
// Compute text color. // Compute text color.
let text_color = self.style().Color.get().color.to_gfx_color(); let text_color = self.style().get_color().color.to_gfx_color();
// Compute text decorations. // Compute text decorations.
let text_decorations_in_effect = self.style() let text_decorations_in_effect = self.style()
.InheritedText .get_inheritedtext()
.get()
._servo_text_decorations_in_effect; ._servo_text_decorations_in_effect;
let text_decorations = TextDecorations { let text_decorations = TextDecorations {
underline: text_decorations_in_effect.underline.map(|c| c.to_gfx_color()), underline: text_decorations_in_effect.underline.map(|c| c.to_gfx_color()),
@ -1271,8 +1270,8 @@ impl Box {
self.compute_border_padding_margins(container_width, inline_fragment_context); self.compute_border_padding_margins(container_width, inline_fragment_context);
let style_width = self.style().Box.get().width; let style_width = self.style().get_box().width;
let style_height = self.style().Box.get().height; let style_height = self.style().get_box().height;
let noncontent_width = self.border_padding.horizontal(); let noncontent_width = self.border_padding.horizontal();
match self.specific { match self.specific {
@ -1320,8 +1319,8 @@ impl Box {
ImageBox(_) | ScannedTextBox(_) => {} ImageBox(_) | ScannedTextBox(_) => {}
} }
let style_width = self.style().Box.get().width; let style_width = self.style().get_box().width;
let style_height = self.style().Box.get().height; let style_height = self.style().get_box().height;
let noncontent_height = self.border_padding.vertical(); let noncontent_height = self.border_padding.vertical();
match self.specific { match self.specific {
@ -1374,7 +1373,7 @@ impl Box {
} }
ScannedTextBox(ref text_box) => { ScannedTextBox(ref text_box) => {
// See CSS 2.1 § 10.8.1. // See CSS 2.1 § 10.8.1.
let font_size = self.style().Font.get().font_size; let font_size = self.style().get_font().font_size;
let line_height = self.calculate_line_height(font_size); let line_height = self.calculate_line_height(font_size);
InlineMetrics::from_font_metrics(&text_box.run.font_metrics, line_height) InlineMetrics::from_font_metrics(&text_box.run.font_metrics, line_height)
} }
@ -1401,7 +1400,7 @@ impl Box {
/// Returns true if the contents should be clipped (i.e. if `overflow` is `hidden`). /// Returns true if the contents should be clipped (i.e. if `overflow` is `hidden`).
pub fn needs_clip(&self) -> bool { pub fn needs_clip(&self) -> bool {
self.style().Box.get().overflow == overflow::hidden self.style().get_box().overflow == overflow::hidden
} }
/// A helper function to return a debug string describing the side offsets for one of the rect /// A helper function to return a debug string describing the side offsets for one of the rect
@ -1478,7 +1477,7 @@ impl ChildDisplayListAccumulator {
fn new(style: &ComputedValues, bounds: Rect<Au>, node: OpaqueNode, level: StackingLevel) fn new(style: &ComputedValues, bounds: Rect<Au>, node: OpaqueNode, level: StackingLevel)
-> ChildDisplayListAccumulator { -> ChildDisplayListAccumulator {
ChildDisplayListAccumulator { ChildDisplayListAccumulator {
clip_display_item: match style.Box.get().overflow { clip_display_item: match style.get_box().overflow {
overflow::hidden => { overflow::hidden => {
Some(box ClipDisplayItem { Some(box ClipDisplayItem {
base: BaseDisplayItem::new(bounds, node, level), base: BaseDisplayItem::new(bounds, node, level),

View file

@ -843,11 +843,11 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
None => { None => {
// Pseudo-element. // Pseudo-element.
let style = node.style(); let style = node.style();
(display::inline, style.Box.get().float, style.Box.get().position) (display::inline, style.get_box().float, style.get_box().position)
} }
Some(ElementNodeTypeId(_)) => { Some(ElementNodeTypeId(_)) => {
let style = node.style(); let style = node.style();
(style.Box.get().display, style.Box.get().float, style.Box.get().position) (style.get_box().display, style.get_box().float, style.get_box().position)
} }
Some(TextNodeTypeId) => (display::inline, float::none, position::static_), Some(TextNodeTypeId) => (display::inline, float::none, position::static_),
Some(CommentNodeTypeId) | Some(CommentNodeTypeId) |
@ -999,7 +999,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
// //
// If you implement other values for this property, you will almost certainly // If you implement other values for this property, you will almost certainly
// want to update this check. // want to update this check.
match self.style().InheritedText.get().white_space { match self.style().get_inheritedtext().white_space {
white_space::normal => true, white_space::normal => true,
_ => false, _ => false,
} }

View file

@ -5,11 +5,11 @@
use geom::point::Point2D; use geom::point::Point2D;
use geom::rect::Rect; use geom::rect::Rect;
use geom::size::Size2D; use geom::size::Size2D;
use servo_util::cowarc::CowArc;
use servo_util::geometry::{Au, max, min}; use servo_util::geometry::{Au, max, min};
use std::i32; use std::i32;
use std::fmt; use std::fmt;
use style::computed_values::float; use style::computed_values::float;
use sync::Arc;
/// The kind of float: left or right. /// The kind of float: left or right.
#[deriving(Clone)] #[deriving(Clone)]
@ -82,7 +82,7 @@ impl fmt::Show for FloatList {
/// FIXME(pcwalton): When we have fast `MutexArc`s, try removing `CowArc` and use a mutex instead. /// FIXME(pcwalton): When we have fast `MutexArc`s, try removing `CowArc` and use a mutex instead.
#[deriving(Clone)] #[deriving(Clone)]
struct FloatListRef { struct FloatListRef {
list: Option<CowArc<FloatList>>, list: Option<Arc<FloatList>>,
} }
impl FloatListRef { impl FloatListRef {
@ -102,16 +102,17 @@ impl FloatListRef {
fn get<'a>(&'a self) -> Option<&'a FloatList> { fn get<'a>(&'a self) -> Option<&'a FloatList> {
match self.list { match self.list {
None => None, None => None,
Some(ref list) => Some(list.get()), Some(ref list) => Some(&**list),
} }
} }
#[allow(experimental)]
#[inline] #[inline]
fn get_mut<'a>(&'a mut self) -> &'a mut FloatList { fn get_mut<'a>(&'a mut self) -> &'a mut FloatList {
if self.list.is_none() { if self.list.is_none() {
self.list = Some(CowArc::new(FloatList::new())) self.list = Some(Arc::new(FloatList::new()))
} }
self.list.as_mut().unwrap().get_mut() self.list.as_mut().unwrap().make_unique()
} }
} }

View file

@ -106,8 +106,8 @@ impl RestyleDamage {
// breakage on modifications. // breakage on modifications.
macro_rules! add_if_not_equal( macro_rules! add_if_not_equal(
($old:ident, $new:ident, $damage:ident, ($old:ident, $new:ident, $damage:ident,
[ $($effect:ident),* ], [ $($style_struct:ident.$name:ident),* ]) => ({ [ $($effect:ident),* ], [ $($style_struct_getter:ident.$name:ident),* ]) => ({
if $( ($old.$style_struct.get().$name != $new.$style_struct.get().$name) )||* { if $( ($old.$style_struct_getter().$name != $new.$style_struct_getter().$name) )||* {
$damage.union_in_place( restyle_damage!( $($effect),* ) ); $damage.union_in_place( restyle_damage!( $($effect),* ) );
} }
}) })
@ -123,18 +123,20 @@ pub fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> RestyleDama
// FIXME: We can short-circuit more of this. // FIXME: We can short-circuit more of this.
add_if_not_equal!(old, new, damage, [ Repaint ], add_if_not_equal!(old, new, damage, [ Repaint ],
[ Color.color, Background.background_color, [ get_color.color, get_background.background_color,
Border.border_top_color, Border.border_right_color, get_border.border_top_color, get_border.border_right_color,
Border.border_bottom_color, Border.border_left_color ]); get_border.border_bottom_color, get_border.border_left_color ]);
add_if_not_equal!(old, new, damage, [ Repaint, BubbleWidths, Reflow ], add_if_not_equal!(old, new, damage, [ Repaint, BubbleWidths, Reflow ],
[ Border.border_top_width, Border.border_right_width, [ get_border.border_top_width, get_border.border_right_width,
Border.border_bottom_width, Border.border_left_width, get_border.border_bottom_width, get_border.border_left_width,
Margin.margin_top, Margin.margin_right, Margin.margin_bottom, Margin.margin_left, get_margin.margin_top, get_margin.margin_right,
Padding.padding_top, Padding.padding_right, Padding.padding_bottom, Padding.padding_left, get_margin.margin_bottom, get_margin.margin_left,
Box.position, Box.width, Box.height, Box.float, Box.display, get_padding.padding_top, get_padding.padding_right,
Font.font_family, Font.font_size, Font.font_style, Font.font_weight, get_padding.padding_bottom, get_padding.padding_left,
InheritedText.text_align, Text.text_decoration, InheritedBox.line_height ]); get_box.position, get_box.width, get_box.height, get_box.float, get_box.display,
get_font.font_family, get_font.font_size, get_font.font_style, get_font.font_weight,
get_inheritedtext.text_align, get_text.text_decoration, get_inheritedbox.line_height ]);
// FIXME: test somehow that we checked every CSS property // FIXME: test somehow that we checked every CSS property

View file

@ -857,7 +857,7 @@ impl InlineFlow {
style: &ComputedValues) { style: &ComputedValues) {
let font_style = text::computed_style_to_font_style(style); let font_style = text::computed_style_to_font_style(style);
let font_metrics = text::font_metrics_for_style(font_context, &font_style); let font_metrics = text::font_metrics_for_style(font_context, &font_style);
let line_height = text::line_height_from_style(style, style.Font.get().font_size); let line_height = text::line_height_from_style(style, style.get_font().font_size);
let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height); let inline_metrics = InlineMetrics::from_font_metrics(&font_metrics, line_height);
self.minimum_height_above_baseline = inline_metrics.height_above_baseline; self.minimum_height_above_baseline = inline_metrics.height_above_baseline;
self.minimum_depth_below_baseline = inline_metrics.depth_below_baseline; self.minimum_depth_below_baseline = inline_metrics.depth_below_baseline;
@ -993,7 +993,7 @@ impl Flow for InlineFlow {
// //
// CSS 2.1 does not state which font to use. Previous versions of the code used // CSS 2.1 does not state which font to use. Previous versions of the code used
// the parent's font; this code uses the current font. // the parent's font; this code uses the current font.
let parent_text_top = fragment.style().Font.get().font_size; let parent_text_top = fragment.style().get_font().font_size;
// We should calculate the distance from baseline to the bottom of the parent's // We should calculate the distance from baseline to the bottom of the parent's
// content area. But for now we assume it's zero. // content area. But for now we assume it's zero.

View file

@ -689,8 +689,7 @@ impl LayoutTask {
let thread_safe_child = ThreadSafeLayoutNode::new(&child); let thread_safe_child = ThreadSafeLayoutNode::new(&child);
thread_safe_child.style() thread_safe_child.style()
.resolve_color(thread_safe_child.style() .resolve_color(thread_safe_child.style()
.Background .get_background()
.get()
.background_color) .background_color)
.to_gfx_color() .to_gfx_color()
}; };

View file

@ -113,9 +113,9 @@ impl MarginCollapseInfo {
-> (CollapsibleMargins, Au) { -> (CollapsibleMargins, Au) {
let state = match self.state { let state = match self.state {
AccumulatingCollapsibleTopMargin => { AccumulatingCollapsibleTopMargin => {
match fragment.style().Box.get().height { match fragment.style().get_box().height {
LPA_Auto | LPA_Length(Au(0)) | LPA_Percentage(0.) => { LPA_Auto | LPA_Length(Au(0)) | LPA_Percentage(0.) => {
match fragment.style().Box.get().min_height { match fragment.style().get_box().min_height {
LP_Length(Au(0)) | LP_Percentage(0.) => { LP_Length(Au(0)) | LP_Percentage(0.) => {
MarginsCollapseThroughFinalMarginState MarginsCollapseThroughFinalMarginState
}, },
@ -322,7 +322,7 @@ pub fn specified(length: computed::LengthOrPercentage, containing_length: Au) ->
#[inline] #[inline]
pub fn border_from_style(style: &ComputedValues) -> SideOffsets2D<Au> { pub fn border_from_style(style: &ComputedValues) -> SideOffsets2D<Au> {
let border_style = style.Border.get(); let border_style = style.get_border();
SideOffsets2D::new(border_style.border_top_width, SideOffsets2D::new(border_style.border_top_width,
border_style.border_right_width, border_style.border_right_width,
border_style.border_bottom_width, border_style.border_bottom_width,
@ -332,7 +332,7 @@ pub fn border_from_style(style: &ComputedValues) -> SideOffsets2D<Au> {
#[inline] #[inline]
pub fn padding_from_style(style: &ComputedValues, containing_block_width: Au) pub fn padding_from_style(style: &ComputedValues, containing_block_width: Au)
-> SideOffsets2D<Au> { -> SideOffsets2D<Au> {
let padding_style = style.Padding.get(); let padding_style = style.get_padding();
SideOffsets2D::new(specified(padding_style.padding_top, containing_block_width), SideOffsets2D::new(specified(padding_style.padding_top, containing_block_width),
specified(padding_style.padding_right, containing_block_width), specified(padding_style.padding_right, containing_block_width),
specified(padding_style.padding_bottom, containing_block_width), specified(padding_style.padding_bottom, containing_block_width),

View file

@ -43,7 +43,7 @@ impl TableFlow {
box_: Box) box_: Box)
-> TableFlow { -> TableFlow {
let mut block_flow = BlockFlow::from_node_and_box(node, box_); let mut block_flow = BlockFlow::from_node_and_box(node, box_);
let table_layout = if block_flow.box_().style().Table.get().table_layout == let table_layout = if block_flow.box_().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -62,7 +62,7 @@ impl TableFlow {
node: &ThreadSafeLayoutNode) node: &ThreadSafeLayoutNode)
-> TableFlow { -> TableFlow {
let mut block_flow = BlockFlow::from_node(constructor, node); let mut block_flow = BlockFlow::from_node(constructor, node);
let table_layout = if block_flow.box_().style().Table.get().table_layout == let table_layout = if block_flow.box_().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -82,7 +82,7 @@ impl TableFlow {
float_kind: FloatKind) float_kind: FloatKind)
-> TableFlow { -> TableFlow {
let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind); let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
let table_layout = if block_flow.box_().style().Table.get().table_layout == let table_layout = if block_flow.box_().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {

View file

@ -69,7 +69,7 @@ impl Flow for TableCellFlow {
/// Minimum/preferred widths set by this function are used in automatic table layout calculation. /// Minimum/preferred widths set by this function are used in automatic table layout calculation.
fn bubble_widths(&mut self, ctx: &mut LayoutContext) { fn bubble_widths(&mut self, ctx: &mut LayoutContext) {
self.block_flow.bubble_widths(ctx); self.block_flow.bubble_widths(ctx);
let specified_width = MaybeAuto::from_style(self.block_flow.box_.style().Box.get().width, let specified_width = MaybeAuto::from_style(self.block_flow.box_.style().get_box().width,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
if self.block_flow.base.intrinsic_widths.minimum_width < specified_width { if self.block_flow.base.intrinsic_widths.minimum_width < specified_width {
self.block_flow.base.intrinsic_widths.minimum_width = specified_width; self.block_flow.base.intrinsic_widths.minimum_width = specified_width;

View file

@ -53,7 +53,7 @@ impl Flow for TableColGroupFlow {
fn bubble_widths(&mut self, _: &mut LayoutContext) { fn bubble_widths(&mut self, _: &mut LayoutContext) {
for box_ in self.cols.iter() { for box_ in self.cols.iter() {
// get the specified value from width property // get the specified value from width property
let width = MaybeAuto::from_style(box_.style().Box.get().width, let width = MaybeAuto::from_style(box_.style().get_box().width,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
let span: int = match box_.specific { let span: int = match box_.specific {

View file

@ -86,7 +86,7 @@ impl TableRowFlow {
{ {
let child_box = kid.as_table_cell().box_(); let child_box = kid.as_table_cell().box_();
// TODO: Percentage height // TODO: Percentage height
let child_specified_height = MaybeAuto::from_style(child_box.style().Box.get().height, let child_specified_height = MaybeAuto::from_style(child_box.style().get_box().height,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
max_y = max_y =
geometry::max(max_y, geometry::max(max_y,
@ -99,7 +99,7 @@ impl TableRowFlow {
let mut height = max_y; let mut height = max_y;
// TODO: Percentage height // TODO: Percentage height
height = match MaybeAuto::from_style(self.block_flow.box_.style().Box.get().height, Au(0)) { height = match MaybeAuto::from_style(self.block_flow.box_.style().get_box().height, Au(0)) {
Auto => height, Auto => height,
Specified(value) => geometry::max(value, height) Specified(value) => geometry::max(value, height)
}; };
@ -173,7 +173,7 @@ impl Flow for TableRowFlow {
// collect the specified column widths of cells. These are used in fixed table layout calculation. // collect the specified column widths of cells. These are used in fixed table layout calculation.
{ {
let child_box = kid.as_table_cell().box_(); let child_box = kid.as_table_cell().box_();
let child_specified_width = MaybeAuto::from_style(child_box.style().Box.get().width, let child_specified_width = MaybeAuto::from_style(child_box.style().get_box().width,
Au::new(0)).specified_or_zero(); Au::new(0)).specified_or_zero();
self.col_widths.push(child_specified_width); self.col_widths.push(child_specified_width);
} }

View file

@ -40,7 +40,7 @@ impl TableWrapperFlow {
box_: Box) box_: Box)
-> TableWrapperFlow { -> TableWrapperFlow {
let mut block_flow = BlockFlow::from_node_and_box(node, box_); let mut block_flow = BlockFlow::from_node_and_box(node, box_);
let table_layout = if block_flow.box_().style().Table.get().table_layout == let table_layout = if block_flow.box_().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -57,7 +57,7 @@ impl TableWrapperFlow {
node: &ThreadSafeLayoutNode) node: &ThreadSafeLayoutNode)
-> TableWrapperFlow { -> TableWrapperFlow {
let mut block_flow = BlockFlow::from_node(constructor, node); let mut block_flow = BlockFlow::from_node(constructor, node);
let table_layout = if block_flow.box_().style().Table.get().table_layout == let table_layout = if block_flow.box_().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -75,7 +75,7 @@ impl TableWrapperFlow {
float_kind: FloatKind) float_kind: FloatKind)
-> TableWrapperFlow { -> TableWrapperFlow {
let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind); let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
let table_layout = if block_flow.box_().style().Table.get().table_layout == let table_layout = if block_flow.box_().style().get_table().table_layout ==
table_layout::fixed { table_layout::fixed {
FixedLayout FixedLayout
} else { } else {
@ -237,12 +237,12 @@ impl TableWrapper {
// Get left and right paddings, borders for table. // Get left and right paddings, borders for table.
// We get these values from the box's style since table_wrapper doesn't have it's own border or padding. // We get these values from the box's style since table_wrapper doesn't have it's own border or padding.
// input.available_width is same as containing_block_width in table_wrapper. // input.available_width is same as containing_block_width in table_wrapper.
let padding_left = specified(style.Padding.get().padding_left, let padding_left = specified(style.get_padding().padding_left,
input.available_width); input.available_width);
let padding_right = specified(style.Padding.get().padding_right, let padding_right = specified(style.get_padding().padding_right,
input.available_width); input.available_width);
let border_left = style.Border.get().border_left_width; let border_left = style.get_border().border_left_width;
let border_right = style.Border.get().border_right_width; let border_right = style.get_border().border_right_width;
let padding_and_borders = padding_left + padding_right + border_left + border_right; let padding_and_borders = padding_left + padding_right + border_left + border_right;
// Compare border-edge widths. Because fixed_cells_width indicates content-width, // Compare border-edge widths. Because fixed_cells_width indicates content-width,
// padding and border values are added to fixed_cells_width. // padding and border values are added to fixed_cells_width.

View file

@ -278,20 +278,20 @@ pub fn computed_style_to_font_style(style: &ComputedValues) -> FontStyle {
debug!("(font style) start"); debug!("(font style) start");
// FIXME: Too much allocation here. // FIXME: Too much allocation here.
let mut font_families = style.Font.get().font_family.iter().map(|family| { let mut font_families = style.get_font().font_family.iter().map(|family| {
match *family { match *family {
font_family::FamilyName(ref name) => (*name).clone(), font_family::FamilyName(ref name) => (*name).clone(),
} }
}); });
debug!("(font style) font families: `{:?}`", font_families); debug!("(font style) font families: `{:?}`", font_families);
let font_size = style.Font.get().font_size.to_f64().unwrap() / 60.0; let font_size = style.get_font().font_size.to_f64().unwrap() / 60.0;
debug!("(font style) font size: `{:f}px`", font_size); debug!("(font style) font size: `{:f}px`", font_size);
FontStyle { FontStyle {
pt_size: font_size, pt_size: font_size,
weight: style.Font.get().font_weight, weight: style.get_font().font_weight,
style: style.Font.get().font_style, style: style.get_font().font_style,
families: font_families.collect(), families: font_families.collect(),
} }
} }
@ -300,12 +300,12 @@ pub fn computed_style_to_font_style(style: &ComputedValues) -> FontStyle {
/// ///
/// FIXME(pcwalton): I believe this should not take a separate `font-size` parameter. /// FIXME(pcwalton): I believe this should not take a separate `font-size` parameter.
pub fn line_height_from_style(style: &ComputedValues, font_size: Au) -> Au { pub fn line_height_from_style(style: &ComputedValues, font_size: Au) -> Au {
let from_inline = match style.InheritedBox.get().line_height { let from_inline = match style.get_inheritedbox().line_height {
line_height::Normal => font_size.scale_by(1.14), line_height::Normal => font_size.scale_by(1.14),
line_height::Number(l) => font_size.scale_by(l), line_height::Number(l) => font_size.scale_by(l),
line_height::Length(l) => l line_height::Length(l) => l
}; };
let minimum = style.InheritedBox.get()._servo_minimum_line_height; let minimum = style.get_inheritedbox()._servo_minimum_line_height;
Au::max(from_inline, minimum) Au::max(from_inline, minimum)
} }

View file

@ -474,10 +474,10 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
if self.pseudo == Before { if self.pseudo == Before {
let before_style = node_layout_data_wrapper.data.before_style.get_ref(); let before_style = node_layout_data_wrapper.data.before_style.get_ref();
return get_content(&before_style.Box.get().content) return get_content(&before_style.get_box().content)
} else { } else {
let after_style = node_layout_data_wrapper.data.after_style.get_ref(); let after_style = node_layout_data_wrapper.data.after_style.get_ref();
return get_content(&after_style.Box.get().content) return get_content(&after_style.get_box().content)
} }
} }
@ -553,15 +553,15 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
let display = match kind { let display = match kind {
Before | BeforeBlock => { Before | BeforeBlock => {
let before_style = node_layout_data_wrapper.data.before_style.get_ref(); let before_style = node_layout_data_wrapper.data.before_style.get_ref();
before_style.Box.get().display before_style.get_box().display
} }
After | AfterBlock => { After | AfterBlock => {
let after_style = node_layout_data_wrapper.data.after_style.get_ref(); let after_style = node_layout_data_wrapper.data.after_style.get_ref();
after_style.Box.get().display after_style.get_box().display
} }
Normal => { Normal => {
let after_style = node_layout_data_wrapper.shared_data.style.get_ref(); let after_style = node_layout_data_wrapper.shared_data.style.get_ref();
after_style.Box.get().display after_style.get_box().display
} }
}; };

View file

@ -4,15 +4,12 @@
// This file is a Mako template: http://www.makotemplates.org/ // This file is a Mako template: http://www.makotemplates.org/
#![allow(non_camel_case_types, uppercase_variables)]
pub use std::ascii::StrAsciiExt; pub use std::ascii::StrAsciiExt;
use serialize::{Encodable, Encoder}; use serialize::{Encodable, Encoder};
pub use servo_util::url::parse_url; pub use servo_util::url::parse_url;
use sync::Arc; use sync::Arc;
pub use url::Url; pub use url::Url;
use servo_util::cowarc::CowArc;
pub use cssparser::*; pub use cssparser::*;
pub use cssparser::ast::*; pub use cssparser::ast::*;
@ -29,9 +26,11 @@ pub mod common_types;
<%! <%!
import re
def to_rust_ident(name): def to_rust_ident(name):
name = name.replace("-", "_") name = name.replace("-", "_")
if name in ["static", "super"]: # Rust keywords if name in ["static", "super", "box"]: # Rust keywords
name += "_" name += "_"
return name return name
@ -39,6 +38,10 @@ class Longhand(object):
def __init__(self, name, derived_from=None): def __init__(self, name, derived_from=None):
self.name = name self.name = name
self.ident = to_rust_ident(name) self.ident = to_rust_ident(name)
self.camel_case, _ = re.subn(
"_([a-z])",
lambda m: m.group(1).upper(),
self.ident.strip("_").capitalize())
self.style_struct = THIS_STYLE_STRUCT self.style_struct = THIS_STYLE_STRUCT
if derived_from is None: if derived_from is None:
self.derived_from = None self.derived_from = None
@ -54,6 +57,7 @@ class Shorthand(object):
class StyleStruct(object): class StyleStruct(object):
def __init__(self, name, inherited): def __init__(self, name, inherited):
self.name = name self.name = name
self.ident = to_rust_ident(name.lower())
self.longhands = [] self.longhands = []
self.inherited = inherited self.inherited = inherited
@ -149,6 +153,7 @@ pub mod longhands {
<%self:single_component_value name="${name}"> <%self:single_component_value name="${name}">
${caller.body()} ${caller.body()}
pub mod computed_value { pub mod computed_value {
#[allow(non_camel_case_types)]
#[deriving(Eq, Clone, FromPrimitive)] #[deriving(Eq, Clone, FromPrimitive)]
pub enum T { pub enum T {
% for value in values.split(): % for value in values.split():
@ -447,6 +452,7 @@ pub mod longhands {
<%self:single_component_value name="vertical-align"> <%self:single_component_value name="vertical-align">
<% vertical_align_keywords = ( <% vertical_align_keywords = (
"baseline sub super top text-top middle bottom text-bottom".split()) %> "baseline sub super top text-top middle bottom text-bottom".split()) %>
#[allow(non_camel_case_types)]
#[deriving(Clone)] #[deriving(Clone)]
pub enum SpecifiedValue { pub enum SpecifiedValue {
% for keyword in vertical_align_keywords: % for keyword in vertical_align_keywords:
@ -473,6 +479,7 @@ pub mod longhands {
} }
pub mod computed_value { pub mod computed_value {
use super::super::{Au, CSSFloat}; use super::super::{Au, CSSFloat};
#[allow(non_camel_case_types)]
#[deriving(Eq, Clone)] #[deriving(Eq, Clone)]
pub enum T { pub enum T {
% for keyword in vertical_align_keywords: % for keyword in vertical_align_keywords:
@ -520,6 +527,7 @@ pub mod longhands {
pub enum Content { pub enum Content {
StringContent(~str), StringContent(~str),
} }
#[allow(non_camel_case_types)]
#[deriving(Eq, Clone)] #[deriving(Eq, Clone)]
pub enum T { pub enum T {
normal, normal,
@ -1450,7 +1458,7 @@ pub enum DeclaredValue<T> {
#[deriving(Clone)] #[deriving(Clone)]
pub enum PropertyDeclaration { pub enum PropertyDeclaration {
% for property in LONGHANDS: % for property in LONGHANDS:
${property.ident}_declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>), ${property.camel_case}Declaration(DeclaredValue<longhands::${property.ident}::SpecifiedValue>),
% endfor % endfor
} }
@ -1479,7 +1487,7 @@ impl PropertyDeclaration {
match longhands::${property.ident}::parse_declared(value, base_url) { match longhands::${property.ident}::parse_declared(value, base_url) {
Some(value) => { Some(value) => {
seen.set_${property.ident}(); seen.set_${property.ident}();
result_list.push(${property.ident}_declaration(value)); result_list.push(${property.camel_case}Declaration(value));
ValidOrIgnoredDeclaration ValidOrIgnoredDeclaration
}, },
None => InvalidValue, None => InvalidValue,
@ -1500,7 +1508,7 @@ impl PropertyDeclaration {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
if !seen.get_${sub_property.ident}() { if !seen.get_${sub_property.ident}() {
seen.set_${sub_property.ident}(); seen.set_${sub_property.ident}();
result_list.push(${sub_property.ident}_declaration( result_list.push(${sub_property.camel_case}Declaration(
CSSWideKeyword(keyword))); CSSWideKeyword(keyword)));
} }
% endfor % endfor
@ -1510,7 +1518,7 @@ impl PropertyDeclaration {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
if !seen.get_${sub_property.ident}() { if !seen.get_${sub_property.ident}() {
seen.set_${sub_property.ident}(); seen.set_${sub_property.ident}();
result_list.push(${sub_property.ident}_declaration( result_list.push(${sub_property.camel_case}Declaration(
CSSWideKeyword( CSSWideKeyword(
${"Inherit" if sub_property.style_struct.inherited else "Initial"} ${"Inherit" if sub_property.style_struct.inherited else "Initial"}
) )
@ -1524,7 +1532,7 @@ impl PropertyDeclaration {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
if !seen.get_${sub_property.ident}() { if !seen.get_${sub_property.ident}() {
seen.set_${sub_property.ident}(); seen.set_${sub_property.ident}();
result_list.push(${sub_property.ident}_declaration( result_list.push(${sub_property.camel_case}Declaration(
match result.${sub_property.ident} { match result.${sub_property.ident} {
Some(value) => SpecifiedValue(value), Some(value) => SpecifiedValue(value),
None => CSSWideKeyword(Initial), None => CSSWideKeyword(Initial),
@ -1557,10 +1565,10 @@ pub mod style_structs {
% endfor % endfor
} }
#[deriving(Eq, Clone)] #[deriving(Clone)]
pub struct ComputedValues { pub struct ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
pub ${style_struct.name}: CowArc<style_structs::${style_struct.name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor % endfor
shareable: bool, shareable: bool,
} }
@ -1576,16 +1584,23 @@ impl ComputedValues {
pub fn resolve_color(&self, color: computed::CSSColor) -> RGBA { pub fn resolve_color(&self, color: computed::CSSColor) -> RGBA {
match color { match color {
RGBA(rgba) => rgba, RGBA(rgba) => rgba,
CurrentColor => self.Color.get().color, CurrentColor => self.get_color().color,
} }
} }
% for style_struct in STYLE_STRUCTS:
pub fn get_${style_struct.name.lower()}
<'a>(&'a self) -> &'a style_structs::${style_struct.name} {
&*self.${style_struct.ident}
}
% endfor
} }
/// The initial values for all style structs as defined by the specification. /// The initial values for all style structs as defined by the specification.
lazy_init! { lazy_init! {
static ref INITIAL_VALUES: ComputedValues = ComputedValues { static ref INITIAL_VALUES: ComputedValues = ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
${style_struct.name}: CowArc::new(style_structs::${style_struct.name} { ${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
% endfor % endfor
@ -1595,6 +1610,20 @@ lazy_init! {
}; };
} }
/// This only exists to limit the scope of #[allow(experimental)]
/// FIXME: remove this when Arc::make_unique() is not experimental anymore.
trait ArcExperimental<T> {
fn make_unique_experimental<'a>(&'a mut self) -> &'a mut T;
}
impl<T: Send + Share + Clone> ArcExperimental<T> for Arc<T> {
#[inline]
#[allow(experimental)]
fn make_unique_experimental<'a>(&'a mut self) -> &'a mut T {
self.make_unique()
}
}
/// Fast path for the function below. Only computes new inherited styles. /// Fast path for the function below. Only computes new inherited styles.
fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty], fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
shareable: bool, shareable: bool,
@ -1604,9 +1633,9 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
-> ComputedValues { -> ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
% if style_struct.inherited: % if style_struct.inherited:
let mut style_${style_struct.name} = parent_style.${style_struct.name}.clone(); let mut style_${style_struct.ident} = parent_style.${style_struct.ident}.clone();
% else: % else:
let style_${style_struct.name} = cached_style.${style_struct.name}.clone(); let style_${style_struct.ident} = cached_style.${style_struct.ident}.clone();
% endif % endif
% endfor % endfor
@ -1621,7 +1650,7 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
% if style_struct.inherited: % if style_struct.inherited:
% for property in style_struct.longhands: % for property in style_struct.longhands:
% if property.derived_from is None: % if property.derived_from is None:
${property.ident}_declaration(ref declared_value) => { ${property.camel_case}Declaration(ref declared_value) => {
if seen.get_${property.ident}() { if seen.get_${property.ident}() {
continue continue
} }
@ -1639,19 +1668,19 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
// matter. // matter.
// //
// FIXME: is it still? // FIXME: is it still?
parent_style.${style_struct.name} parent_style.${style_struct.ident}
.get()
.${property.ident} .${property.ident}
.clone() .clone()
} }
}; };
style_${style_struct.name}.get_mut().${property.ident} = style_${style_struct.ident}.make_unique_experimental()
computed_value; .${property.ident} = computed_value;
% if property.name in DERIVED_LONGHANDS: % if property.name in DERIVED_LONGHANDS:
% for derived in DERIVED_LONGHANDS[property.name]: % for derived in DERIVED_LONGHANDS[property.name]:
style_${derived.style_struct.name}.get_mut() style_${derived.style_struct.ident}
.${derived.ident} = .make_unique_experimental()
.${derived.ident} =
longhands::${derived.ident} longhands::${derived.ident}
::derive_from_${property.ident}( ::derive_from_${property.ident}(
computed_value, computed_value,
@ -1660,7 +1689,7 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
% endif % endif
} }
% else: % else:
${property.ident}_declaration(_) => { ${property.camel_case}Declaration(_) => {
// Do not allow stylesheets to set derived properties. // Do not allow stylesheets to set derived properties.
} }
% endif % endif
@ -1674,7 +1703,7 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
ComputedValues { ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
${style_struct.name}: style_${style_struct.name}, ${style_struct.ident}: style_${style_struct.ident},
% endfor % endfor
shareable: shareable, shareable: shareable,
} }
@ -1708,21 +1737,20 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
}; };
let mut context = { let mut context = {
let inherited_font_style = inherited_style.Font.get(); let inherited_font_style = inherited_style.get_font();
computed::Context { computed::Context {
is_root_element: is_root_element, is_root_element: is_root_element,
inherited_font_weight: inherited_font_style.font_weight, inherited_font_weight: inherited_font_style.font_weight,
inherited_font_size: inherited_font_style.font_size, inherited_font_size: inherited_font_style.font_size,
inherited_height: inherited_style.Box.get().height, inherited_height: inherited_style.get_box().height,
inherited_minimum_line_height: inherited_style.InheritedBox inherited_minimum_line_height: inherited_style.get_inheritedbox()
.get()
._servo_minimum_line_height, ._servo_minimum_line_height,
inherited_text_decorations_in_effect: inherited_text_decorations_in_effect:
inherited_style.InheritedText.get()._servo_text_decorations_in_effect, inherited_style.get_inheritedtext()._servo_text_decorations_in_effect,
// To be overridden by applicable declarations: // To be overridden by applicable declarations:
font_size: inherited_font_style.font_size, font_size: inherited_font_style.font_size,
display: longhands::display::get_initial_value(), display: longhands::display::get_initial_value(),
color: inherited_style.Color.get().color, color: inherited_style.get_color().color,
text_decoration: longhands::text_decoration::get_initial_value(), text_decoration: longhands::text_decoration::get_initial_value(),
positioned: false, positioned: false,
floated: false, floated: false,
@ -1735,11 +1763,11 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
// This assumes that the computed and specified values have the same Rust type. // This assumes that the computed and specified values have the same Rust type.
macro_rules! get_specified( macro_rules! get_specified(
($style_struct: ident, $property: ident, $declared_value: expr) => { ($style_struct_getter: ident, $property: ident, $declared_value: expr) => {
match *$declared_value { match *$declared_value {
SpecifiedValue(specified_value) => specified_value, SpecifiedValue(specified_value) => specified_value,
CSSWideKeyword(Initial) => longhands::$property::get_initial_value(), CSSWideKeyword(Initial) => longhands::$property::get_initial_value(),
CSSWideKeyword(Inherit) => inherited_style.$style_struct.get().$property.clone(), CSSWideKeyword(Inherit) => inherited_style.$style_struct_getter().$property.clone(),
} }
}; };
) )
@ -1750,7 +1778,7 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
// Declarations are stored in reverse source order, we want them in forward order here. // Declarations are stored in reverse source order, we want them in forward order here.
for declaration in sub_list.declarations.iter().rev() { for declaration in sub_list.declarations.iter().rev() {
match *declaration { match *declaration {
font_size_declaration(ref value) => { FontSizeDeclaration(ref value) => {
context.font_size = match *value { context.font_size = match *value {
SpecifiedValue(specified_value) => computed::compute_Au_with_font_size( SpecifiedValue(specified_value) => computed::compute_Au_with_font_size(
specified_value, context.inherited_font_size), specified_value, context.inherited_font_size),
@ -1758,28 +1786,29 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
CSSWideKeyword(Inherit) => context.inherited_font_size, CSSWideKeyword(Inherit) => context.inherited_font_size,
} }
} }
color_declaration(ref value) => { ColorDeclaration(ref value) => {
context.color = get_specified!(Color, color, value); context.color = get_specified!(get_color, color, value);
} }
display_declaration(ref value) => { DisplayDeclaration(ref value) => {
context.display = get_specified!(Box, display, value); context.display = get_specified!(get_box, display, value);
} }
position_declaration(ref value) => { PositionDeclaration(ref value) => {
context.positioned = match get_specified!(Box, position, value) { context.positioned = match get_specified!(get_box, position, value) {
longhands::position::absolute | longhands::position::fixed => true, longhands::position::absolute | longhands::position::fixed => true,
_ => false, _ => false,
} }
} }
float_declaration(ref value) => { FloatDeclaration(ref value) => {
context.floated = get_specified!(Box, float, value) != longhands::float::none; context.floated = get_specified!(get_box, float, value)
!= longhands::float::none;
} }
text_decoration_declaration(ref value) => { TextDecorationDeclaration(ref value) => {
context.text_decoration = get_specified!(Text, text_decoration, value); context.text_decoration = get_specified!(get_text, text_decoration, value);
} }
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
border_${side}_style_declaration(ref value) => { Border${side.capitalize()}StyleDeclaration(ref value) => {
context.border_${side}_present = context.border_${side}_present =
match get_specified!(Border, border_${side}_style, value) { match get_specified!(get_border, border_${side}_style, value) {
longhands::border_top_style::none | longhands::border_top_style::none |
longhands::border_top_style::hidden => false, longhands::border_top_style::hidden => false,
_ => true, _ => true,
@ -1804,13 +1833,13 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
// Set computed values, overwriting earlier declarations for the same property. // Set computed values, overwriting earlier declarations for the same property.
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
let mut style_${style_struct.name} = let mut style_${style_struct.ident} =
% if style_struct.inherited: % if style_struct.inherited:
inherited_style inherited_style
% else: % else:
initial_values initial_values
% endif % endif
.${style_struct.name}.clone(); .${style_struct.ident}.clone();
% endfor % endfor
let mut cacheable = true; let mut cacheable = true;
let mut seen = PropertyBitField::new(); let mut seen = PropertyBitField::new();
@ -1823,7 +1852,7 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
% for property in style_struct.longhands: % for property in style_struct.longhands:
% if property.derived_from is None: % if property.derived_from is None:
${property.ident}_declaration(ref declared_value) => { ${property.camel_case}Declaration(ref declared_value) => {
if seen.get_${property.ident}() { if seen.get_${property.ident}() {
continue continue
} }
@ -1842,19 +1871,19 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
// //
// FIXME: is it still? // FIXME: is it still?
cacheable = false; cacheable = false;
inherited_style.${style_struct.name} inherited_style.${style_struct.ident}
.get()
.${property.ident} .${property.ident}
.clone() .clone()
} }
}; };
style_${style_struct.name}.get_mut().${property.ident} = style_${style_struct.ident}.make_unique_experimental()
computed_value; .${property.ident} = computed_value;
% if property.name in DERIVED_LONGHANDS: % if property.name in DERIVED_LONGHANDS:
% for derived in DERIVED_LONGHANDS[property.name]: % for derived in DERIVED_LONGHANDS[property.name]:
style_${derived.style_struct.name}.get_mut() style_${derived.style_struct.ident}
.${derived.ident} = .make_unique_experimental()
.${derived.ident} =
longhands::${derived.ident} longhands::${derived.ident}
::derive_from_${property.ident}( ::derive_from_${property.ident}(
computed_value, computed_value,
@ -1863,7 +1892,7 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
% endif % endif
} }
% else: % else:
${property.ident}_declaration(_) => { ${property.camel_case}Declaration(_) => {
// Do not allow stylesheets to set derived properties. // Do not allow stylesheets to set derived properties.
} }
% endif % endif
@ -1875,7 +1904,7 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
// The initial value of border-*-width may be changed at computed value time. // The initial value of border-*-width may be changed at computed value time.
{ {
let border = style_Border.get_mut(); let border = style_border.make_unique_experimental();
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
// Like calling to_computed_value, which wouldn't type check. // Like calling to_computed_value, which wouldn't type check.
if !context.border_${side}_present { if !context.border_${side}_present {
@ -1886,13 +1915,13 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
// The initial value of display may be changed at computed value time. // The initial value of display may be changed at computed value time.
if !seen.get_display() { if !seen.get_display() {
let box_ = style_Box.get_mut(); let box_ = style_box_.make_unique_experimental();
box_.display = longhands::display::to_computed_value(box_.display, &context); box_.display = longhands::display::to_computed_value(box_.display, &context);
} }
(ComputedValues { (ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
${style_struct.name}: style_${style_struct.name}, ${style_struct.ident}: style_${style_struct.ident},
% endfor % endfor
shareable: shareable, shareable: shareable,
}, cacheable) }, cacheable)
@ -1907,18 +1936,18 @@ pub fn cascade_anonymous(parent_style: &ComputedValues) -> ComputedValues {
let initial_values = &*INITIAL_VALUES; let initial_values = &*INITIAL_VALUES;
let mut result = ComputedValues { let mut result = ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
${style_struct.name}: ${style_struct.ident}:
% if style_struct.inherited: % if style_struct.inherited:
parent_style parent_style
% else: % else:
initial_values initial_values
% endif % endif
.${style_struct.name}.clone(), .${style_struct.ident}.clone(),
% endfor % endfor
shareable: false, shareable: false,
}; };
{ {
let border = result.Border.get_mut(); let border = result.border.make_unique_experimental();
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
// Like calling to_computed_value, which wouldn't type check. // Like calling to_computed_value, which wouldn't type check.
border.border_${side}_width = Au(0); border.border_${side}_width = Au(0);

View file

@ -1,100 +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 http://mozilla.org/MPL/2.0/. */
//! An atomically reference counted type that copies itself on mutation.
use std::cast;
use std::ptr;
use std::sync::atomics::{AtomicUint, SeqCst};
struct CowArcAlloc<T> {
ref_count: AtomicUint,
data: T,
}
#[unsafe_no_drop_flag]
pub struct CowArc<T> {
ptr: *mut CowArcAlloc<T>,
}
#[unsafe_destructor]
impl<T> Drop for CowArc<T> {
#[inline]
fn drop(&mut self) {
unsafe {
if self.ptr != ptr::mut_null() && (*self.ptr).ref_count.fetch_sub(1, SeqCst) == 1 {
let _kill_it: Box<CowArcAlloc<T>> = cast::transmute(self.ptr);
self.ptr = ptr::mut_null()
}
}
}
}
impl<T:Eq + Clone> Eq for CowArc<T> {
fn eq(&self, other: &CowArc<T>) -> bool {
self.get() == other.get()
}
}
impl<T:Clone> Clone for CowArc<T> {
#[inline]
fn clone(&self) -> CowArc<T> {
unsafe {
drop((*self.ptr).ref_count.fetch_add(1, SeqCst));
}
CowArc {
ptr: self.ptr
}
}
}
impl<T:Clone> CowArc<T> {
#[inline]
pub fn new(value: T) -> CowArc<T> {
let alloc = box CowArcAlloc {
ref_count: AtomicUint::new(1),
data: value,
};
unsafe {
CowArc {
ptr: cast::transmute(alloc),
}
}
}
#[inline]
pub fn shared(&self) -> bool {
unsafe {
(*self.ptr).ref_count.load(SeqCst) != 1
}
}
#[inline]
pub fn get<'a>(&'a self) -> &'a T {
unsafe {
cast::transmute(&(*self.ptr).data)
}
}
#[inline(always)]
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
unsafe {
if (*self.ptr).ref_count.load(SeqCst) == 1 {
return cast::transmute(&mut (*self.ptr).data)
}
let copy = box CowArcAlloc {
ref_count: AtomicUint::new(1),
data: (*self.ptr).data.clone(),
};
*self = CowArc {
ptr: cast::transmute(copy),
};
cast::transmute(&mut (*self.ptr).data)
}
}
}

View file

@ -26,7 +26,6 @@ extern crate std_url = "url";
pub mod cache; pub mod cache;
pub mod concurrentmap; pub mod concurrentmap;
pub mod cowarc;
pub mod debug; pub mod debug;
pub mod geometry; pub mod geometry;
pub mod namespace; pub mod namespace;