mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Merge in servo/master
This commit is contained in:
commit
19686acdec
78 changed files with 2000 additions and 989 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue