Merge in servo/master

This commit is contained in:
Dan Fox 2015-03-05 17:34:18 +00:00
commit 19686acdec
78 changed files with 2000 additions and 989 deletions

View file

@ -52,14 +52,16 @@ use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{ClippingRegion, DisplayList};
use rustc_serialize::{Encoder, Encodable};
use msg::compositor_msg::LayerId;
use msg::constellation_msg::ConstellationChan;
use servo_util::geometry::{Au, MAX_AU};
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
use servo_util::opts;
use std::cmp::{max, min};
use std::fmt;
use style::computed_values::{overflow_x, overflow_y, position, box_sizing, display, float};
use style::properties::ComputedValues;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use style::computed_values::{overflow, position, box_sizing, display, float};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentageOrNone};
use std::sync::Arc;
/// Information specific to floated blocks.
@ -1431,7 +1433,10 @@ impl BlockFlow {
display::T::inline_block => {
FormattingContextType::Other
}
_ if style.get_box().overflow != overflow::T::visible => FormattingContextType::Block,
_ if style.get_box().overflow_x != overflow_x::T::visible ||
style.get_box().overflow_y != overflow_y::T(overflow_x::T::visible) => {
FormattingContextType::Block
}
_ => FormattingContextType::None,
}
}
@ -1915,6 +1920,10 @@ impl Flow for BlockFlow {
CoordinateSystem::Parent)
.translate(stacking_context_position));
}
fn remove_compositor_layers(&self, constellation_chan: ConstellationChan) {
self.fragment.remove_compositor_layers(constellation_chan);
}
}
impl fmt::Debug for BlockFlow {

View file

@ -233,6 +233,20 @@ impl<'a> FlowConstructor<'a> {
}
}
#[inline]
fn set_flow_construction_result(&self, node: &ThreadSafeLayoutNode, result: ConstructionResult) {
match result {
ConstructionResult::None => {
let mut layout_data_ref = node.mutate_layout_data();
let layout_data = layout_data_ref.as_mut().expect("no layout data");
layout_data.remove_compositor_layers(self.layout_context.shared.constellation_chan.clone());
}
_ => {}
}
node.set_flow_construction_result(result);
}
/// Builds the `ImageFragmentInfo` for the given image. This is out of line to guide inlining.
fn build_fragment_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>)
-> SpecificFragmentInfo {
@ -381,7 +395,7 @@ impl<'a> FlowConstructor<'a> {
// If kid_flow is TableCaptionFlow, kid_flow should be added under
// TableWrapperFlow.
if flow.is_table() && kid_flow.is_table_caption() {
kid.set_flow_construction_result(ConstructionResult::Flow(kid_flow,
self.set_flow_construction_result(&kid, ConstructionResult::Flow(kid_flow,
Descendants::new()))
} else if flow.need_anonymous_flow(&*kid_flow) {
consecutive_siblings.push(kid_flow)
@ -562,7 +576,7 @@ impl<'a> FlowConstructor<'a> {
// box, so don't construct them.
if node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement))) {
for kid in node.children() {
kid.set_flow_construction_result(ConstructionResult::None)
self.set_flow_construction_result(&kid, ConstructionResult::None)
}
}
Some(Fragment::new_from_specific_info(
@ -692,7 +706,7 @@ impl<'a> FlowConstructor<'a> {
fn build_fragments_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
for kid in node.children() {
kid.set_flow_construction_result(ConstructionResult::None)
self.set_flow_construction_result(&kid, ConstructionResult::None)
}
// If this node is ignorable whitespace, bail out now.
@ -1046,7 +1060,7 @@ impl<'a> FlowConstructor<'a> {
-> ConstructionResult {
// CSS 2.1 § 17.2.1. Treat all child fragments of a `table-column` as `display: none`.
for kid in node.children() {
kid.set_flow_construction_result(ConstructionResult::None)
self.set_flow_construction_result(&kid, ConstructionResult::None)
}
let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
@ -1174,15 +1188,15 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// results of children.
(display::T::none, _, _) => {
for child in node.children() {
child.set_flow_construction_result(ConstructionResult::None);
self.set_flow_construction_result(&child, ConstructionResult::None);
}
node.set_flow_construction_result(ConstructionResult::None);
self.set_flow_construction_result(node, ConstructionResult::None);
}
// Table items contribute table flow construction results.
(display::T::table, float_value, _) => {
let construction_result = self.build_flow_for_table_wrapper(node, float_value);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Absolutely positioned elements will have computed value of
@ -1193,13 +1207,14 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// below.
(display::T::block, _, position::T::absolute) |
(_, _, position::T::fixed) => {
node.set_flow_construction_result(self.build_flow_for_nonfloated_block(node))
let construction_result = self.build_flow_for_nonfloated_block(node);
self.set_flow_construction_result(node, construction_result)
}
// List items contribute their own special flows.
(display::T::list_item, float_value, _) => {
node.set_flow_construction_result(self.build_flow_for_list_item(node,
float_value))
let construction_result = self.build_flow_for_list_item(node, float_value);
self.set_flow_construction_result(node, construction_result)
}
// Inline items that are absolutely-positioned contribute inline fragment construction
@ -1207,7 +1222,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
(display::T::inline, _, position::T::absolute) => {
let construction_result =
self.build_fragment_for_absolutely_positioned_inline(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Inline items contribute inline fragment construction results.
@ -1215,31 +1230,31 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// FIXME(pcwalton, #3307): This is not sufficient to handle floated generated content.
(display::T::inline, float::T::none, _) => {
let construction_result = self.build_fragments_for_inline(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Inline-block items contribute inline fragment construction results.
(display::T::inline_block, float::T::none, _) => {
let construction_result = self.build_fragment_for_inline_block(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Table items contribute table flow construction results.
(display::T::table_caption, _, _) => {
let construction_result = self.build_flow_for_table_caption(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Table items contribute table flow construction results.
(display::T::table_column_group, _, _) => {
let construction_result = self.build_flow_for_table_colgroup(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Table items contribute table flow construction results.
(display::T::table_column, _, _) => {
let construction_result = self.build_fragments_for_table_column(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Table items contribute table flow construction results.
@ -1247,19 +1262,19 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
(display::T::table_header_group, _, _) |
(display::T::table_footer_group, _, _) => {
let construction_result = self.build_flow_for_table_rowgroup(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Table items contribute table flow construction results.
(display::T::table_row, _, _) => {
let construction_result = self.build_flow_for_table_row(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Table items contribute table flow construction results.
(display::T::table_cell, _, _) => {
let construction_result = self.build_flow_for_table_cell(node);
node.set_flow_construction_result(construction_result)
self.set_flow_construction_result(node, construction_result)
}
// Block flows that are not floated contribute block flow construction results.
@ -1268,14 +1283,15 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// properties separately.
(_, float::T::none, _) => {
node.set_flow_construction_result(self.build_flow_for_nonfloated_block(node))
let construction_result = self.build_flow_for_nonfloated_block(node);
self.set_flow_construction_result(node, construction_result)
}
// Floated flows contribute float flow construction results.
(_, float_value, _) => {
let float_kind = FloatKind::from_property(float_value);
node.set_flow_construction_result(
self.build_flow_for_floated_block(node, float_kind))
let construction_result = self.build_flow_for_floated_block(node, float_kind);
self.set_flow_construction_result(node, construction_result)
}
}
@ -1330,13 +1346,6 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
let mut layout_data_ref = self.mutate_layout_data();
let layout_data = layout_data_ref.as_mut().expect("no layout data");
match result {
ConstructionResult::None => {
layout_data.clear();
}
_ => {}
}
let dst = self.get_construction_result(layout_data);
*dst = result;

View file

@ -4,17 +4,17 @@
#![allow(unsafe_blocks)]
use construct::ConstructionResult;
use construct::{ConstructionItem, ConstructionResult};
use incremental::RestyleDamage;
use msg::constellation_msg::ConstellationChan;
use parallel::DomParallelInfo;
use wrapper::{LayoutNode, TLayoutNode};
use script::dom::node::SharedLayoutData;
use script::layout_interface::LayoutChan;
use std::mem;
use std::cell::{Ref, RefMut};
use style::properties::ComputedValues;
use std::mem;
use std::sync::Arc;
use style::properties::ComputedValues;
use wrapper::{LayoutNode, TLayoutNode};
/// Data that layout associates with a node.
pub struct PrivateLayoutData {
@ -72,8 +72,26 @@ pub struct LayoutDataWrapper {
}
impl LayoutDataWrapper {
pub fn clear(&self) {
// TODO: Clear items related to this node, e.g. compositor layers
pub fn remove_compositor_layers(&self, constellation_chan: ConstellationChan) {
match self.data.flow_construction_result {
ConstructionResult::None => {}
ConstructionResult::Flow(ref flow_ref, _) => {
flow_ref.remove_compositor_layers(constellation_chan);
}
ConstructionResult::ConstructionItem(ref construction_item) => {
match construction_item {
&ConstructionItem::InlineFragments(ref inline_fragments) => {
for fragment in inline_fragments.fragments.iter() {
fragment.remove_compositor_layers(constellation_chan.clone());
}
}
&ConstructionItem::Whitespace(..) => {}
&ConstructionItem::TableColumnFragment(ref fragment) => {
fragment.remove_compositor_layers(constellation_chan.clone());
}
}
}
}
}
}

View file

@ -19,7 +19,7 @@ use fragment::{CoordinateSystem, Fragment, IframeFragmentInfo, ImageFragmentInfo
use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo};
use inline::InlineFlow;
use list_item::ListItemFlow;
use model;
use model::{self, MaybeAuto};
use opaque_node::OpaqueNodeMethods;
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
@ -32,8 +32,7 @@ use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem};
use gfx::display_list::{OpaqueNode, SolidColorDisplayItem};
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
use gfx::paint_task::{PaintLayer, THREAD_TINT_COLORS};
use png;
use png::PixelsByColorType;
use png::{self, PixelsByColorType};
use msg::compositor_msg::ScrollPolicy;
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::constellation_msg::ConstellationChan;
@ -42,15 +41,16 @@ use servo_util::cursor::Cursor;
use servo_util::geometry::{self, Au, ZERO_POINT, to_px, to_frac_px};
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
use servo_util::opts;
use std::cmp;
use std::default::Default;
use std::iter::repeat;
use std::num::Float;
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
use style::values::computed::{Image, LinearGradient, LengthOrPercentage};
use style::values::computed::{Image, LinearGradient, LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::RGBA;
use style::computed_values::filter::Filter;
use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
use style::computed_values::{position, visibility};
use style::computed_values::{background_attachment, background_repeat, background_size};
use style::computed_values::{border_style, image_rendering, overflow_x, position, visibility};
use style::properties::style_structs::Border;
use style::properties::ComputedValues;
use std::num::ToPrimitive;
@ -93,6 +93,14 @@ pub trait FragmentDisplayListBuilding {
absolute_bounds: &Rect<Au>,
clip: &ClippingRegion);
/// Computes the background size for an image with the given background area according to the
/// rules in CSS-BACKGROUNDS § 3.9.
fn compute_background_image_size(&self,
style: &ComputedValues,
bounds: &Rect<Au>,
image: &png::Image)
-> Size2D<Au>;
/// Adds the display items necessary to paint the background image of this fragment to the
/// display list at the appropriate stacking level.
fn build_display_list_for_background_image(&self,
@ -326,6 +334,59 @@ impl FragmentDisplayListBuilding for Fragment {
}
}
fn compute_background_image_size(&self,
style: &ComputedValues,
bounds: &Rect<Au>,
image: &png::Image)
-> Size2D<Au> {
// If `image_aspect_ratio` < `bounds_aspect_ratio`, the image is tall; otherwise, it is
// wide.
let image_aspect_ratio = (image.width as f64) / (image.height as f64);
let bounds_aspect_ratio = bounds.size.width.to_subpx() / bounds.size.height.to_subpx();
let intrinsic_size = Size2D(Au::from_px(image.width as int),
Au::from_px(image.height as int));
match (style.get_background().background_size.clone(),
image_aspect_ratio < bounds_aspect_ratio) {
(background_size::T::Contain, false) | (background_size::T::Cover, true) => {
Size2D(bounds.size.width,
Au::from_frac_px(bounds.size.width.to_subpx() / image_aspect_ratio))
}
(background_size::T::Contain, true) | (background_size::T::Cover, false) => {
Size2D(Au::from_frac_px(bounds.size.height.to_subpx() * image_aspect_ratio),
bounds.size.height)
}
(background_size::T::Explicit(background_size::ExplicitSize {
width,
height: LengthOrPercentageOrAuto::Auto,
}), _) => {
let width = MaybeAuto::from_style(width, bounds.size.width)
.specified_or_default(intrinsic_size.width);
Size2D(width, Au::from_frac_px(width.to_subpx() / image_aspect_ratio))
}
(background_size::T::Explicit(background_size::ExplicitSize {
width: LengthOrPercentageOrAuto::Auto,
height
}), _) => {
let height = MaybeAuto::from_style(height, bounds.size.height)
.specified_or_default(intrinsic_size.height);
Size2D(Au::from_frac_px(height.to_subpx() * image_aspect_ratio), height)
}
(background_size::T::Explicit(background_size::ExplicitSize {
width,
height
}), _) => {
Size2D(MaybeAuto::from_style(width, bounds.size.width)
.specified_or_default(intrinsic_size.width),
MaybeAuto::from_style(height, bounds.size.height)
.specified_or_default(intrinsic_size.height))
}
}
}
fn build_display_list_for_background_image(&self,
style: &ComputedValues,
display_list: &mut DisplayList,
@ -349,16 +410,16 @@ impl FragmentDisplayListBuilding for Fragment {
};
debug!("(building display list) building background image");
let image_width = Au::from_px(image.width as int);
let image_height = Au::from_px(image.height as int);
// Use `background-size` to get the size.
let mut bounds = *absolute_bounds;
let image_size = self.compute_background_image_size(style, &bounds, &**image);
// Clip.
//
// TODO: Check the bounds to see if a clip item is actually required.
let clip = clip.clone().intersect_rect(&bounds);
// Use background-attachment to get the initial virtual origin
// Use `background-attachment` to get the initial virtual origin
let (virtual_origin_x, virtual_origin_y) = match background.background_attachment {
background_attachment::T::scroll => {
(absolute_bounds.origin.x, absolute_bounds.origin.y)
@ -368,11 +429,11 @@ impl FragmentDisplayListBuilding for Fragment {
}
};
// Use background-position to get the offset
// Use `background-position` to get the offset.
let horizontal_position = model::specified(background.background_position.horizontal,
bounds.size.width - image_width);
bounds.size.width - image_size.width);
let vertical_position = model::specified(background.background_position.vertical,
bounds.size.height - image_height);
bounds.size.height - image_size.height);
let abs_x = virtual_origin_x + horizontal_position;
let abs_y = virtual_origin_y + vertical_position;
@ -382,26 +443,34 @@ impl FragmentDisplayListBuilding for Fragment {
background_repeat::T::no_repeat => {
bounds.origin.x = abs_x;
bounds.origin.y = abs_y;
bounds.size.width = image_width;
bounds.size.height = image_height;
bounds.size.width = image_size.width;
bounds.size.height = image_size.height;
}
background_repeat::T::repeat_x => {
bounds.origin.y = abs_y;
bounds.size.height = image_height;
ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width,
abs_x, image.width);
bounds.size.height = image_size.height;
ImageFragmentInfo::tile_image(&mut bounds.origin.x,
&mut bounds.size.width,
abs_x,
image_size.width.to_nearest_px() as u32);
}
background_repeat::T::repeat_y => {
bounds.origin.x = abs_x;
bounds.size.width = image_width;
ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height,
abs_y, image.height);
bounds.size.width = image_size.width;
ImageFragmentInfo::tile_image(&mut bounds.origin.y,
&mut bounds.size.height,
abs_y,
image_size.height.to_nearest_px() as u32);
}
background_repeat::T::repeat => {
ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width,
abs_x, image.width);
ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height,
abs_y, image.height);
ImageFragmentInfo::tile_image(&mut bounds.origin.x,
&mut bounds.size.width,
abs_x,
image_size.width.to_nearest_px() as u32);
ImageFragmentInfo::tile_image(&mut bounds.origin.y,
&mut bounds.size.height,
abs_y,
image_size.height.to_nearest_px() as u32);
}
};
@ -413,8 +482,8 @@ impl FragmentDisplayListBuilding for Fragment {
Cursor::DefaultCursor),
clip),
image: image.clone(),
stretch_size: Size2D(Au::from_px(image.width as int),
Au::from_px(image.height as int)),
stretch_size: Size2D(image_size.width, image_size.height),
image_rendering: style.get_effects().image_rendering.clone(),
}), level);
}
@ -912,6 +981,7 @@ impl FragmentDisplayListBuilding for Fragment {
(*clip).clone()),
image: image.clone(),
stretch_size: stacking_relative_content_box.size,
image_rendering: self.style.get_effects().image_rendering.clone(),
}));
} else {
// No image data at all? Do nothing.
@ -947,6 +1017,7 @@ impl FragmentDisplayListBuilding for Fragment {
pixels: PixelsByColorType::RGBA8(canvas_data),
}),
stretch_size: stacking_relative_content_box.size,
image_rendering: image_rendering::T::Auto,
};
display_list.content.push_back(DisplayItem::ImageClass(canvas_display_item));
@ -991,17 +1062,37 @@ impl FragmentDisplayListBuilding for Fragment {
}
// Account for style-specified `clip`.
let current_clip = self.calculate_style_specified_clip(current_clip,
stacking_relative_border_box);
let mut current_clip = self.calculate_style_specified_clip(current_clip,
stacking_relative_border_box);
// Only clip if `overflow` tells us to.
match self.style.get_box().overflow {
overflow::T::hidden | overflow::T::auto | overflow::T::scroll => {
// Create a new clip rect.
current_clip.intersect_rect(stacking_relative_border_box)
// Clip according to the values of `overflow-x` and `overflow-y`.
//
// TODO(pcwalton): Support scrolling.
// FIXME(pcwalton): This may be more complex than it needs to be, since it seems to be
// impossible with the computed value rules as they are to have `overflow-x: visible` with
// `overflow-y: <scrolling>` or vice versa!
match self.style.get_box().overflow_x {
overflow_x::T::hidden | overflow_x::T::auto | overflow_x::T::scroll => {
let mut bounds = current_clip.bounding_rect();
let max_x = cmp::min(bounds.max_x(), stacking_relative_border_box.max_x());
bounds.origin.x = cmp::max(bounds.origin.x, stacking_relative_border_box.origin.x);
bounds.size.width = max_x - bounds.origin.x;
current_clip = current_clip.intersect_rect(&bounds)
}
_ => current_clip,
_ => {}
}
match self.style.get_box().overflow_y.0 {
overflow_x::T::hidden | overflow_x::T::auto | overflow_x::T::scroll => {
let mut bounds = current_clip.bounding_rect();
let max_y = cmp::min(bounds.max_y(), stacking_relative_border_box.max_y());
bounds.origin.y = cmp::max(bounds.origin.y, stacking_relative_border_box.origin.y);
bounds.size.height = max_y - bounds.origin.y;
current_clip = current_clip.intersect_rect(&bounds)
}
_ => {}
}
current_clip
}
fn build_display_list_for_text_fragment(&self,

View file

@ -49,6 +49,7 @@ use wrapper::ThreadSafeLayoutNode;
use geom::{Point2D, Rect, Size2D};
use gfx::display_list::ClippingRegion;
use rustc_serialize::{Encoder, Encodable};
use msg::constellation_msg::ConstellationChan;
use msg::compositor_msg::LayerId;
use servo_util::geometry::{Au, ZERO_RECT};
use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
@ -312,6 +313,9 @@ pub trait Flow: fmt::Debug + Sync {
/// Attempts to perform incremental fixup of this flow by replacing its fragment's style with
/// the new style. This can only succeed if the flow has exactly one fragment.
fn repair_style(&mut self, new_style: &Arc<ComputedValues>);
/// Remove any compositor layers associated with this flow
fn remove_compositor_layers(&self, _: ConstellationChan) {}
}
// Base access

View file

@ -30,7 +30,7 @@ use gfx::text::glyph::CharIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
use script_traits::UntrustedNodeAddress;
use rustc_serialize::{Encodable, Encoder};
use msg::constellation_msg::{PipelineId, SubpageId};
use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId};
use net::image::holder::ImageHolder;
use net::local_image_cache::LocalImageCache;
use servo_util::geometry::{self, Au, ZERO_POINT};
@ -982,10 +982,11 @@ impl Fragment {
fn style_specified_intrinsic_inline_size(&self) -> IntrinsicISizesContribution {
let flags = self.quantities_included_in_intrinsic_inline_size();
let style = self.style();
let specified = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
MaybeAuto::from_style(style.content_inline_size(), Au(0)).specified_or_zero()
let (min_inline_size, specified) = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
(model::specified(style.min_inline_size(), Au(0)),
MaybeAuto::from_style(style.content_inline_size(), Au(0)).specified_or_zero())
} else {
Au(0)
(Au(0), Au(0))
};
// FIXME(#2261, pcwalton): This won't work well for inlines: is this OK?
@ -993,7 +994,7 @@ impl Fragment {
IntrinsicISizesContribution {
content_intrinsic_sizes: IntrinsicISizes {
minimum_inline_size: specified,
minimum_inline_size: min_inline_size,
preferred_inline_size: specified,
},
surrounding_size: surrounding_inline_size,
@ -1721,7 +1722,8 @@ impl Fragment {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
let block_flow = info.flow_ref.as_block();
self.border_box.size.inline =
block_flow.base.intrinsic_inline_sizes.preferred_inline_size;
max(block_flow.base.intrinsic_inline_sizes.minimum_inline_size,
block_flow.base.intrinsic_inline_sizes.preferred_inline_size);
block_flow.base.block_container_inline_size = self.border_box.size.inline;
}
SpecificFragmentInfo::ScannedText(ref info) => {
@ -2058,6 +2060,23 @@ impl Fragment {
// box too.
overflow
}
/// Remove any compositor layers associated with this fragment - it is being
/// removed from the tree or had its display property set to none.
/// TODO(gw): This just hides the compositor layer for now. In the future
/// it probably makes sense to provide a hint to the compositor whether
/// the layers should be destroyed to free memory.
pub fn remove_compositor_layers(&self, constellation_chan: ConstellationChan) {
match self.specific {
SpecificFragmentInfo::Iframe(ref iframe_info) => {
let ConstellationChan(ref chan) = constellation_chan;
chan.send(Msg::FrameRect(iframe_info.pipeline_id,
iframe_info.subpage_id,
Rect::zero())).unwrap();
}
_ => {}
}
}
}
impl fmt::Debug for Fragment {

View file

@ -34,7 +34,7 @@ use std::mem;
use std::num::ToPrimitive;
use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXor};
use std::u16;
use style::computed_values::{overflow, text_align, text_justify, text_overflow, vertical_align};
use style::computed_values::{overflow_x, text_align, text_justify, text_overflow, vertical_align};
use style::computed_values::{white_space};
use style::properties::ComputedValues;
use std::sync::Arc;
@ -653,8 +653,8 @@ impl LineBreaker {
let available_inline_size = self.pending_line.green_zone.inline -
self.pending_line.bounds.size.inline - indentation;
match (fragment.style().get_inheritedtext().text_overflow,
fragment.style().get_box().overflow) {
(text_overflow::T::clip, _) | (_, overflow::T::visible) => {}
fragment.style().get_box().overflow_x) {
(text_overflow::T::clip, _) | (_, overflow_x::T::visible) => {}
(text_overflow::T::ellipsis, _) => {
need_ellipsis = fragment.border_box.size.inline > available_inline_size;
}

View file

@ -126,6 +126,9 @@ pub struct LayoutTask {
//// The channel to send messages to ourself.
pub chan: LayoutChan,
/// The channel on which messages can be sent to the constellation.
pub constellation_chan: ConstellationChan,
/// The channel on which messages can be sent to the script task.
pub script_chan: ScriptControlChan,
@ -274,6 +277,7 @@ impl LayoutTask {
pipeline_port: pipeline_port,
chan: chan,
script_chan: script_chan,
constellation_chan: constellation_chan.clone(),
paint_chan: paint_chan,
time_profiler_chan: time_profiler_chan,
resource_task: resource_task,
@ -414,7 +418,7 @@ impl LayoutTask {
},
Msg::ReapLayoutData(dead_layout_data) => {
unsafe {
LayoutTask::handle_reap_layout_data(dead_layout_data)
self.handle_reap_layout_data(dead_layout_data)
}
},
Msg::PrepareToExit(response_chan) => {
@ -443,7 +447,7 @@ impl LayoutTask {
match self.port.recv().unwrap() {
Msg::ReapLayoutData(dead_layout_data) => {
unsafe {
LayoutTask::handle_reap_layout_data(dead_layout_data)
self.handle_reap_layout_data(dead_layout_data)
}
}
Msg::ExitNow(exit_type) => {
@ -940,9 +944,9 @@ impl LayoutTask {
/// Handles a message to destroy layout data. Layout data must be destroyed on *this* task
/// because the struct type is transmuted to a different type on the script side.
unsafe fn handle_reap_layout_data(layout_data: LayoutData) {
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutData) {
let layout_data_wrapper: LayoutDataWrapper = mem::transmute(layout_data);
layout_data_wrapper.clear();
layout_data_wrapper.remove_compositor_layers(self.constellation_chan.clone());
}
/// Returns profiling information which is passed to the time profiler.