layout: Store containing block inline-size separately rather than

writing it to a temporary location and overwriting it.

This makes layout more idempotent, which is important for incremental
layout.

Also converts `is_root` to a set of flags and fixes a `TODO` concerning
percentage inline heights of images.
This commit is contained in:
Patrick Walton 2014-10-09 22:21:20 -07:00
parent 6e3c776387
commit 423f5f0ebf
9 changed files with 141 additions and 106 deletions

View file

@ -35,6 +35,7 @@ use gfx::display_list::{BackgroundAndBorderLevel, BlockLevel, ContentStackingLev
use gfx::display_list::{FloatStackingLevel, PositionedDescendantStackingLevel}; use gfx::display_list::{FloatStackingLevel, PositionedDescendantStackingLevel};
use gfx::display_list::{RootOfStackingContextLevel}; use gfx::display_list::{RootOfStackingContextLevel};
use gfx::render_task::RenderLayer; use gfx::render_task::RenderLayer;
use serialize::{Encoder, Encodable};
use servo_msg::compositor_msg::{FixedPosition, LayerId, Scrollable}; use servo_msg::compositor_msg::{FixedPosition, LayerId, Scrollable};
use servo_util::geometry::{Au, MAX_AU}; use servo_util::geometry::{Au, MAX_AU};
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize}; use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
@ -511,10 +512,6 @@ pub struct BlockFlow {
/// The associated fragment. /// The associated fragment.
pub fragment: Fragment, pub fragment: Fragment,
/// TODO: is_root should be a bit field to conserve memory.
/// Whether this block flow is the root flow.
pub is_root: bool,
/// Static y offset of an absolute flow from its CB. /// Static y offset of an absolute flow from its CB.
pub static_b_offset: Au, pub static_b_offset: Au,
@ -527,7 +524,23 @@ pub struct BlockFlow {
inline_size_of_preceding_right_floats: Au, inline_size_of_preceding_right_floats: Au,
/// Additional floating flow members. /// Additional floating flow members.
pub float: Option<Box<FloatedBlockInfo>> pub float: Option<Box<FloatedBlockInfo>>,
/// Various flags.
pub flags: BlockFlowFlags,
}
bitflags! {
flags BlockFlowFlags: u8 {
#[doc="If this is set, then this block flow is the root flow."]
static IsRoot = 0x01,
}
}
impl<'a,E,S> Encodable<S,E> for BlockFlowFlags where S: Encoder<E> {
fn encode(&self, e: &mut S) -> Result<(),E> {
self.bits().encode(e)
}
} }
impl BlockFlow { impl BlockFlow {
@ -535,11 +548,11 @@ impl BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
fragment: Fragment::new(constructor, node), fragment: Fragment::new(constructor, node),
is_root: false,
static_b_offset: Au::new(0), static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0), inline_size_of_preceding_left_floats: Au(0),
inline_size_of_preceding_right_floats: Au(0), inline_size_of_preceding_right_floats: Au(0),
float: None float: None,
flags: BlockFlowFlags::empty(),
} }
} }
@ -547,11 +560,11 @@ impl BlockFlow {
BlockFlow { BlockFlow {
base: BaseFlow::new((*node).clone()), base: BaseFlow::new((*node).clone()),
fragment: fragment, fragment: fragment,
is_root: false,
static_b_offset: Au::new(0), static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0), inline_size_of_preceding_left_floats: Au(0),
inline_size_of_preceding_right_floats: Au(0), inline_size_of_preceding_right_floats: Au(0),
float: None float: None,
flags: BlockFlowFlags::empty(),
} }
} }
@ -562,12 +575,12 @@ impl BlockFlow {
let base = BaseFlow::new((*node).clone()); let base = BaseFlow::new((*node).clone());
BlockFlow { BlockFlow {
fragment: Fragment::new(constructor, node), fragment: Fragment::new(constructor, node),
is_root: false,
static_b_offset: Au::new(0), static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0), inline_size_of_preceding_left_floats: Au(0),
inline_size_of_preceding_right_floats: Au(0), inline_size_of_preceding_right_floats: Au(0),
float: Some(box FloatedBlockInfo::new(float_kind)), float: Some(box FloatedBlockInfo::new(float_kind)),
base: base, base: base,
flags: BlockFlowFlags::empty(),
} }
} }
@ -578,12 +591,12 @@ impl BlockFlow {
let base = BaseFlow::new((*node).clone()); let base = BaseFlow::new((*node).clone());
BlockFlow { BlockFlow {
fragment: fragment, fragment: fragment,
is_root: false,
static_b_offset: Au::new(0), static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0), inline_size_of_preceding_left_floats: Au(0),
inline_size_of_preceding_right_floats: Au(0), inline_size_of_preceding_right_floats: Au(0),
float: Some(box FloatedBlockInfo::new(float_kind)), float: Some(box FloatedBlockInfo::new(float_kind)),
base: base, base: base,
flags: BlockFlowFlags::empty(),
} }
} }
@ -1164,7 +1177,7 @@ impl BlockFlow {
// Calculate used value of block-size just like we do for inline replaced elements. // Calculate used value of block-size just like we do for inline replaced elements.
// TODO: Pass in the containing block block-size when Fragment's // TODO: Pass in the containing block block-size when Fragment's
// assign-block-size can handle it correctly. // assign-block-size can handle it correctly.
self.fragment.assign_replaced_block_size_if_necessary(); self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
// TODO: Right now, this content block-size value includes the // TODO: Right now, this content block-size value includes the
// margin because of erroneous block-size calculation in fragment. // margin because of erroneous block-size calculation in fragment.
// Check this when that has been fixed. // Check this when that has been fixed.
@ -1346,7 +1359,7 @@ impl BlockFlow {
// The inline-start margin edge of the child flow is at our inline-start content edge, // The inline-start margin edge of the child flow is at our inline-start content edge,
// and its inline-size is our content inline-size. // and its inline-size is our content inline-size.
flow::mut_base(kid).position.start.i = inline_start_content_edge; flow::mut_base(kid).position.start.i = inline_start_content_edge;
flow::mut_base(kid).position.size.inline = content_inline_size; flow::mut_base(kid).block_container_inline_size = content_inline_size;
// Determine float impaction. // Determine float impaction.
match kid.float_clearance() { match kid.float_clearance() {
@ -1575,7 +1588,7 @@ impl Flow for BlockFlow {
if self.is_root() { if self.is_root() {
debug!("Setting root position"); debug!("Setting root position");
self.base.position.start = LogicalPoint::zero(self.base.writing_mode); self.base.position.start = LogicalPoint::zero(self.base.writing_mode);
self.base.position.size.inline = LogicalSize::from_physical( self.base.block_container_inline_size = LogicalSize::from_physical(
self.base.writing_mode, layout_context.shared.screen_size).inline; self.base.writing_mode, layout_context.shared.screen_size).inline;
self.base.floats = Floats::new(self.base.writing_mode); self.base.floats = Floats::new(self.base.writing_mode);
@ -1584,9 +1597,9 @@ impl Flow for BlockFlow {
self.base.flags.set_impacted_by_right_floats(false); self.base.flags.set_impacted_by_right_floats(false);
} }
// Our inline-size was set to the inline-size of the containing block by the flow's parent. Now compute // Our inline-size was set to the inline-size of the containing block by the flow's parent.
// the real value. // Now compute the real value.
let containing_block_inline_size = self.base.position.size.inline; let containing_block_inline_size = self.base.block_container_inline_size;
self.compute_used_inline_size(layout_context, containing_block_inline_size); self.compute_used_inline_size(layout_context, containing_block_inline_size);
if self.is_float() { if self.is_float() {
self.float.as_mut().unwrap().containing_inline_size = containing_block_inline_size; self.float.as_mut().unwrap().containing_inline_size = containing_block_inline_size;
@ -1664,7 +1677,9 @@ impl Flow for BlockFlow {
self.base.debug_id()); self.base.debug_id());
// Assign block-size for fragment if it is an image fragment. // Assign block-size for fragment if it is an image fragment.
self.fragment.assign_replaced_block_size_if_necessary(); let containing_block_block_size =
self.base.block_container_explicit_block_size.unwrap_or(Au(0));
self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size);
self.base.position.size.block = self.fragment.border_box.size.block; self.base.position.size.block = self.fragment.border_box.size.block;
} else if self.is_root() || self.is_float() { } else if self.is_root() || self.is_float() {
// Root element margins should never be collapsed according to CSS § 8.3.1. // Root element margins should never be collapsed according to CSS § 8.3.1.
@ -1742,7 +1757,7 @@ impl Flow for BlockFlow {
} }
fn mark_as_root(&mut self) { fn mark_as_root(&mut self) {
self.is_root = true self.flags.insert(IsRoot)
} }
/// Return true if store overflow is delayed for this flow. /// Return true if store overflow is delayed for this flow.
@ -1753,7 +1768,7 @@ impl Flow for BlockFlow {
} }
fn is_root(&self) -> bool { fn is_root(&self) -> bool {
self.is_root self.flags.contains(IsRoot)
} }
fn is_float(&self) -> bool { fn is_float(&self) -> bool {
@ -2017,7 +2032,8 @@ pub trait ISizeAndMarginsComputer {
let containing_block_inline_size = self.containing_block_inline_size( let containing_block_inline_size = self.containing_block_inline_size(
block, block,
parent_flow_inline_size, ctx); parent_flow_inline_size,
ctx);
let mut solution = self.solve_inline_size_constraints(block, &input); let mut solution = self.solve_inline_size_constraints(block, &input);
@ -2528,5 +2544,5 @@ fn propagate_column_inline_sizes_to_child(kid: &mut Flow,
let kid_base = flow::mut_base(kid); let kid_base = flow::mut_base(kid);
kid_base.position.start.i = *inline_start_margin_edge; kid_base.position.start.i = *inline_start_margin_edge;
kid_base.position.size.inline = inline_size; kid_base.block_container_inline_size = inline_size;
} }

View file

@ -184,10 +184,10 @@ pub trait Flow: fmt::Show + ToString + Sync {
/// Pass 1 of reflow: computes minimum and preferred inline-sizes. /// Pass 1 of reflow: computes minimum and preferred inline-sizes.
/// ///
/// Recursively (bottom-up) determine the flow's minimum and preferred inline-sizes. When called on /// Recursively (bottom-up) determine the flow's minimum and preferred inline-sizes. When
/// this flow, all child flows have had their minimum and preferred inline-sizes set. This function /// called on this flow, all child flows have had their minimum and preferred inline-sizes set.
/// must decide minimum/preferred inline-sizes based on its children's inline-sizes and the dimensions of /// This function must decide minimum/preferred inline-sizes based on its children's inline-
/// any boxes it is responsible for flowing. /// sizes and the dimensions of any boxes it is responsible for flowing.
fn bubble_inline_sizes(&mut self, _ctx: &LayoutContext) { fn bubble_inline_sizes(&mut self, _ctx: &LayoutContext) {
fail!("bubble_inline_sizes not yet implemented") fail!("bubble_inline_sizes not yet implemented")
} }
@ -203,10 +203,11 @@ pub trait Flow: fmt::Show + ToString + Sync {
} }
/// Assigns block-sizes in-order; or, if this is a float, places the float. The default /// Assigns block-sizes in-order; or, if this is a float, places the float. The default
/// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true if /// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
/// this child was impacted by floats or false otherwise. /// if this child was impacted by floats or false otherwise.
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self, layout_context: &'a LayoutContext<'a>) fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
-> bool { layout_context: &'a LayoutContext<'a>)
-> bool {
let impacted = base(&*self).flags.impacted_by_floats(); let impacted = base(&*self).flags.impacted_by_floats();
if impacted { if impacted {
self.assign_block_size(layout_context); self.assign_block_size(layout_context);
@ -745,6 +746,10 @@ pub struct BaseFlow {
/// containing block. This is in tree order. This includes any direct children. /// containing block. This is in tree order. This includes any direct children.
pub abs_descendants: AbsDescendants, pub abs_descendants: AbsDescendants,
/// The inline-size of the block container of this flow. Used for computing percentage and
/// automatic values for `width`.
pub block_container_inline_size: Au,
/// The block-size of the block container of this flow, if it is an explicit size (does not /// The block-size of the block container of this flow, if it is an explicit size (does not
/// depend on content heights). Used for computing percentage values for `height`. /// depend on content heights). Used for computing percentage values for `height`.
pub block_container_explicit_block_size: Option<Au>, pub block_container_explicit_block_size: Option<Au>,
@ -780,7 +785,8 @@ pub struct BaseFlow {
impl fmt::Show for BaseFlow { impl fmt::Show for BaseFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, write!(f,
"CC {}, ADC {}, CADC {}", "@ {}, CC {}, ADC {}, CADC {}",
self.position,
self.parallel.children_count.load(SeqCst), self.parallel.children_count.load(SeqCst),
self.abs_descendants.len(), self.abs_descendants.len(),
self.parallel.children_and_absolute_descendant_count.load(SeqCst)) self.parallel.children_and_absolute_descendant_count.load(SeqCst))
@ -837,8 +843,9 @@ impl BaseFlow {
collapsible_margins: CollapsibleMargins::new(), collapsible_margins: CollapsibleMargins::new(),
abs_position: Zero::zero(), abs_position: Zero::zero(),
abs_descendants: Descendants::new(), abs_descendants: Descendants::new(),
absolute_static_i_offset: Au::new(0), absolute_static_i_offset: Au(0),
fixed_static_i_offset: Au::new(0), fixed_static_i_offset: Au(0),
block_container_inline_size: Au(0),
block_container_explicit_block_size: None, block_container_explicit_block_size: None,
absolute_cb: ContainingBlockLink::new(), absolute_cb: ContainingBlockLink::new(),
display_list: DisplayList::new(), display_list: DisplayList::new(),

View file

@ -215,8 +215,8 @@ pub struct ImageFragmentInfo {
impl ImageFragmentInfo { impl ImageFragmentInfo {
/// Creates a new image fragment from the given URL and local image cache. /// Creates a new image fragment from the given URL and local image cache.
/// ///
/// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little sense to /// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little
/// me. /// sense to me.
pub fn new(node: &ThreadSafeLayoutNode, pub fn new(node: &ThreadSafeLayoutNode,
image_url: Url, image_url: Url,
local_image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>) local_image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>)
@ -1041,7 +1041,9 @@ impl Fragment {
StackingLevel::from_background_and_border_level(background_and_border_level); StackingLevel::from_background_and_border_level(background_and_border_level);
// Add a pseudo-display item for content box queries. This is a very bogus thing to do. // Add a pseudo-display item for content box queries. This is a very bogus thing to do.
let base_display_item = box BaseDisplayItem::new(absolute_fragment_bounds, self.node, level); let base_display_item = box BaseDisplayItem::new(absolute_fragment_bounds,
self.node,
level);
display_list.push(PseudoDisplayItemClass(base_display_item)); display_list.push(PseudoDisplayItemClass(base_display_item));
// Add the background to the list, if applicable. // Add the background to the list, if applicable.
@ -1061,11 +1063,12 @@ impl Fragment {
match self.specific { match self.specific {
ScannedTextFragment(_) => {}, ScannedTextFragment(_) => {},
_ => { _ => {
self.build_display_list_for_background_if_applicable(&*self.style, self.build_display_list_for_background_if_applicable(
display_list, &*self.style,
layout_context, display_list,
level, layout_context,
&absolute_fragment_bounds); level,
&absolute_fragment_bounds);
} }
} }
@ -1075,10 +1078,11 @@ impl Fragment {
match self.inline_context { match self.inline_context {
Some(ref inline_context) => { Some(ref inline_context) => {
for style in inline_context.styles.iter().rev() { for style in inline_context.styles.iter().rev() {
self.build_display_list_for_borders_if_applicable(&**style, self.build_display_list_for_borders_if_applicable(
display_list, &**style,
&absolute_fragment_bounds, display_list,
level); &absolute_fragment_bounds,
level);
} }
} }
None => {} None => {}
@ -1187,42 +1191,37 @@ impl Fragment {
// should have a real `SERVO_DEBUG` system. // should have a real `SERVO_DEBUG` system.
debug!("{:?}", self.build_debug_borders_around_fragment(display_list, flow_origin)) debug!("{:?}", self.build_debug_borders_around_fragment(display_list, flow_origin))
} }
ImageFragment(_) => { ImageFragment(ref mut image_fragment) => {
match self.specific { let image_ref = &mut image_fragment.image;
ImageFragment(ref mut image_fragment) => { match image_ref.get_image(self.node.to_untrusted_node_address()) {
let image_ref = &mut image_fragment.image; Some(image) => {
match image_ref.get_image(self.node.to_untrusted_node_address()) { debug!("(building display list) building image fragment");
Some(image) => {
debug!("(building display list) building image fragment");
// Place the image into the display list. // Place the image into the display list.
let image_display_item = box ImageDisplayItem { let image_display_item = box ImageDisplayItem {
base: BaseDisplayItem::new(absolute_content_box, base: BaseDisplayItem::new(absolute_content_box,
self.node, self.node,
ContentStackingLevel), ContentStackingLevel),
image: image.clone(), image: image.clone(),
stretch_size: absolute_content_box.size, stretch_size: absolute_content_box.size,
}; };
accumulator.push(display_list,
ImageDisplayItemClass(image_display_item)) accumulator.push(display_list, ImageDisplayItemClass(image_display_item))
} }
None => { None => {
// No image data at all? Do nothing. // No image data at all? Do nothing.
// //
// TODO: Add some kind of placeholder image. // TODO: Add some kind of placeholder image.
debug!("(building display list) no image :("); debug!("(building display list) no image :(");
}
}
} }
_ => fail!("shouldn't get here"),
} }
// FIXME(pcwalton): This is a bit of an abuse of the logging
// infrastructure. We should have a real `SERVO_DEBUG` system.
debug!("{:?}", self.build_debug_borders_around_fragment(display_list, flow_origin))
} }
} }
// FIXME(pcwalton): This is a bit of an abuse of the logging
// infrastructure. We should have a real `SERVO_DEBUG` system.
debug!("{:?}", self.build_debug_borders_around_fragment(display_list, flow_origin))
// If this is an iframe, then send its position and size up to the constellation. // If this is an iframe, then send its position and size up to the constellation.
// //
// FIXME(pcwalton): Doing this during display list construction seems potentially // FIXME(pcwalton): Doing this during display list construction seems potentially
@ -1538,7 +1537,7 @@ impl Fragment {
match self.specific { match self.specific {
InlineAbsoluteHypotheticalFragment(ref mut info) => { InlineAbsoluteHypotheticalFragment(ref mut info) => {
let block_flow = info.flow_ref.get_mut().as_block(); let block_flow = info.flow_ref.get_mut().as_block();
block_flow.base.position.size.inline = block_flow.base.block_container_inline_size =
block_flow.base.intrinsic_inline_sizes.preferred_inline_size + block_flow.base.intrinsic_inline_sizes.preferred_inline_size +
block_flow.base.intrinsic_inline_sizes.surround_inline_size; block_flow.base.intrinsic_inline_sizes.surround_inline_size;
@ -1549,18 +1548,19 @@ impl Fragment {
let block_flow = info.flow_ref.get_mut().as_block(); let block_flow = info.flow_ref.get_mut().as_block();
self.border_box.size.inline = block_flow.base.intrinsic_inline_sizes.preferred_inline_size + self.border_box.size.inline = block_flow.base.intrinsic_inline_sizes.preferred_inline_size +
block_flow.base.intrinsic_inline_sizes.surround_inline_size; block_flow.base.intrinsic_inline_sizes.surround_inline_size;
block_flow.base.position.size.inline = self.border_box.size.inline; block_flow.base.block_container_inline_size = self.border_box.size.inline;
} }
ScannedTextFragment(_) => { ScannedTextFragment(_) => {
// Scanned text fragments will have already had their content inline-sizes assigned by this // Scanned text fragments will have already had their content inline-sizes assigned
// point. // by this point.
self.border_box.size.inline = self.border_box.size.inline + noncontent_inline_size self.border_box.size.inline = self.border_box.size.inline + noncontent_inline_size
} }
ImageFragment(ref mut image_fragment_info) => { ImageFragment(ref mut image_fragment_info) => {
// TODO(ksh8281): compute border,margin // TODO(ksh8281): compute border,margin
let inline_size = ImageFragmentInfo::style_length(style_inline_size, let inline_size = ImageFragmentInfo::style_length(
image_fragment_info.dom_inline_size, style_inline_size,
container_inline_size); image_fragment_info.dom_inline_size,
container_inline_size);
let inline_size = match inline_size { let inline_size = match inline_size {
Auto => { Auto => {
@ -1573,18 +1573,20 @@ impl Fragment {
let ratio = intrinsic_width.to_f32().unwrap() / let ratio = intrinsic_width.to_f32().unwrap() /
intrinsic_height.to_f32().unwrap(); intrinsic_height.to_f32().unwrap();
let specified_height = ImageFragmentInfo::style_length(style_block_size, let specified_height = ImageFragmentInfo::style_length(
image_fragment_info.dom_block_size, style_block_size,
Au(0)); image_fragment_info.dom_block_size,
Au(0));
let specified_height = match specified_height { let specified_height = match specified_height {
Auto => intrinsic_height, Auto => intrinsic_height,
Specified(h) => h, Specified(h) => h,
}; };
let specified_height = ImageFragmentInfo::clamp_size(specified_height, let specified_height = ImageFragmentInfo::clamp_size(
style_min_block_size, specified_height,
style_max_block_size, style_min_block_size,
Au(0)); style_max_block_size,
Au::new((specified_height.to_f32().unwrap() * ratio) as i32) Au(0));
Au((specified_height.to_f32().unwrap() * ratio) as i32)
} }
}, },
Specified(w) => w, Specified(w) => w,
@ -1606,7 +1608,7 @@ impl Fragment {
/// been assigned first. /// been assigned first.
/// ///
/// Ideally, this should follow CSS 2.1 § 10.6.2. /// Ideally, this should follow CSS 2.1 § 10.6.2.
pub fn assign_replaced_block_size_if_necessary(&mut self) { pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
match self.specific { match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment | GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InputFragment(_) => return, TableRowFragment | TableWrapperFragment | InputFragment(_) => return,
@ -1627,17 +1629,17 @@ impl Fragment {
ImageFragment(ref mut image_fragment_info) => { ImageFragment(ref mut image_fragment_info) => {
// TODO(ksh8281): compute border,margin,padding // TODO(ksh8281): compute border,margin,padding
let inline_size = image_fragment_info.computed_inline_size(); let inline_size = image_fragment_info.computed_inline_size();
// FIXME(ksh8281): we shouldn't assign block-size this way let block_size = ImageFragmentInfo::style_length(
// we don't know about size of parent's block-size style_block_size,
let block_size = ImageFragmentInfo::style_length(style_block_size, image_fragment_info.dom_block_size,
image_fragment_info.dom_block_size, containing_block_block_size);
Au(0));
let block_size = match block_size { let block_size = match block_size {
Auto => { Auto => {
let scale = image_fragment_info.image_inline_size().to_f32().unwrap() let scale = image_fragment_info.image_inline_size().to_f32().unwrap()
/ inline_size.to_f32().unwrap(); / inline_size.to_f32().unwrap();
Au::new((image_fragment_info.image_block_size().to_f32().unwrap() / scale) as i32) Au((image_fragment_info.image_block_size().to_f32().unwrap() / scale)
as i32)
}, },
Specified(h) => { Specified(h) => {
h h
@ -1652,8 +1654,8 @@ impl Fragment {
self.border_box.size.block = block_size + noncontent_block_size self.border_box.size.block = block_size + noncontent_block_size
} }
ScannedTextFragment(_) => { ScannedTextFragment(_) => {
// Scanned text fragments' content block-sizes are calculated by the text run scanner // Scanned text fragments' content block-sizes are calculated by the text run
// during flow construction. // scanner during flow construction.
self.border_box.size.block = self.border_box.size.block + noncontent_block_size self.border_box.size.block = self.border_box.size.block + noncontent_block_size
} }
InlineBlockFragment(ref mut info) => { InlineBlockFragment(ref mut info) => {

View file

@ -775,6 +775,10 @@ impl InlineFlow {
pub fn build_display_list_inline(&mut self, layout_context: &LayoutContext) { pub fn build_display_list_inline(&mut self, layout_context: &LayoutContext) {
let size = self.base.position.size.to_physical(self.base.writing_mode); let size = self.base.position.size.to_physical(self.base.writing_mode);
if !Rect(self.base.abs_position, size).intersects(&layout_context.shared.dirty) { if !Rect(self.base.abs_position, size).intersects(&layout_context.shared.dirty) {
println!("inline block (abs pos {}, size {}) didn't intersect \
dirty rect owo",
self.base.abs_position,
size);
return return
} }
@ -1030,10 +1034,13 @@ impl Flow for InlineFlow {
// Initialize content fragment inline-sizes if they haven't been initialized already. // Initialize content fragment inline-sizes if they haven't been initialized already.
// //
// TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into `Fragment`. // TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into
// `Fragment`.
debug!("InlineFlow::assign_inline_sizes: floats in: {:?}", self.base.floats); debug!("InlineFlow::assign_inline_sizes: floats in: {:?}", self.base.floats);
self.base.position.size.inline = self.base.block_container_inline_size;
{ {
let inline_size = self.base.position.size.inline; let inline_size = self.base.position.size.inline;
let this = &mut *self; let this = &mut *self;
@ -1070,8 +1077,11 @@ impl Flow for InlineFlow {
debug!("assign_block_size_inline: floats in: {:?}", self.base.floats); debug!("assign_block_size_inline: floats in: {:?}", self.base.floats);
// assign block-size for inline fragments // assign block-size for inline fragments
let containing_block_block_size =
self.base.block_container_explicit_block_size.unwrap_or(Au(0));
for fragment in self.fragments.fragments.iter_mut() { for fragment in self.fragments.fragments.iter_mut() {
fragment.assign_replaced_block_size_if_necessary(); fragment.assign_replaced_block_size_if_necessary(
containing_block_block_size);
} }
let scanner_floats = self.base.floats.clone(); let scanner_floats = self.base.floats.clone();

View file

@ -256,7 +256,7 @@ impl Flow for TableFlow {
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table"); debug!("assign_inline_sizes({}): assigning inline_size for flow", "table");
// The position was set to the containing block by the flow's parent. // The position was set to the containing block by the flow's parent.
let containing_block_inline_size = self.block_flow.base.position.size.inline; let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
let mut num_unspecified_inline_sizes = 0; let mut num_unspecified_inline_sizes = 0;
let mut total_column_inline_size = Au::new(0); let mut total_column_inline_size = Au::new(0);

View file

@ -100,7 +100,7 @@ impl Flow for TableCellFlow {
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_cell"); debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_cell");
// The position was set to the column inline-size by the parent flow, table row flow. // The position was set to the column inline-size by the parent flow, table row flow.
let containing_block_inline_size = self.block_flow.base.position.size.inline; let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
let inline_size_computer = InternalTable; let inline_size_computer = InternalTable;
inline_size_computer.compute_used_inline_size(&mut self.block_flow, ctx, containing_block_inline_size); inline_size_computer.compute_used_inline_size(&mut self.block_flow, ctx, containing_block_inline_size);

View file

@ -209,7 +209,7 @@ impl Flow for TableRowFlow {
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_row"); debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_row");
// The position was set to the containing block by the flow's parent. // The position was set to the containing block by the flow's parent.
let containing_block_inline_size = self.block_flow.base.position.size.inline; let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
// FIXME: In case of border-collapse: collapse, inline-start_content_edge should be border-inline-start // FIXME: In case of border-collapse: collapse, inline-start_content_edge should be border-inline-start
let inline_start_content_edge = Au::new(0); let inline_start_content_edge = Au::new(0);

View file

@ -190,7 +190,7 @@ impl Flow for TableRowGroupFlow {
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_rowgroup"); debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_rowgroup");
// The position was set to the containing block by the flow's parent. // The position was set to the containing block by the flow's parent.
let containing_block_inline_size = self.block_flow.base.position.size.inline; let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
// FIXME: In case of border-collapse: collapse, inline-start_content_edge should be // FIXME: In case of border-collapse: collapse, inline-start_content_edge should be
// the border width on the inline-start side. // the border width on the inline-start side.
let inline_start_content_edge = Au::new(0); let inline_start_content_edge = Au::new(0);

View file

@ -288,7 +288,7 @@ impl Flow for TableWrapperFlow {
// Our inline-size was set to the inline-size of the containing block by the flow's parent. // Our inline-size was set to the inline-size of the containing block by the flow's parent.
// Now compute the real value. // Now compute the real value.
let containing_block_inline_size = self.block_flow.base.position.size.inline; let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
if self.is_float() { if self.is_float() {
self.block_flow.float.as_mut().unwrap().containing_inline_size = self.block_flow.float.as_mut().unwrap().containing_inline_size =
containing_block_inline_size; containing_block_inline_size;