mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Roll up block layout changes
This commit is contained in:
parent
5750069e0a
commit
ae5b2dfc72
4 changed files with 44 additions and 64 deletions
|
@ -102,39 +102,38 @@ impl BlockFlowData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not an anonymous block context, add in the block box's widths. These widths will not
|
/* if not an anonymous block context, add in block box's widths.
|
||||||
// include child elements, just padding etc.
|
these widths will not include child elements, just padding etc. */
|
||||||
for self.box.each |&box| {
|
self.box.map(|&box| {
|
||||||
// Can compute border width here since it doesn't depend on anything.
|
//Can compute border width here since it doesn't depend on anything
|
||||||
let style = box.style();
|
let style = box.style();
|
||||||
do box.with_model |model| {
|
do box.with_model |model| {
|
||||||
model.compute_borders(style)
|
model.compute_borders(style)
|
||||||
}
|
}
|
||||||
min_width = min_width.add(&box.get_min_width(ctx));
|
min_width = min_width.add(&box.get_min_width(ctx));
|
||||||
pref_width = pref_width.add(&box.get_pref_width(ctx));
|
pref_width = pref_width.add(&box.get_pref_width(ctx));
|
||||||
}
|
});
|
||||||
|
|
||||||
self.common.min_width = min_width;
|
self.common.min_width = min_width;
|
||||||
self.common.pref_width = pref_width;
|
self.common.pref_width = pref_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes left and right margins and width based on CSS 2.1 secion 10.3.3.
|
/// Computes left and right margins and width based on CSS 2.1 secion 10.3.3.
|
||||||
/// Requires borders and padding to already be computed.
|
/// Requires borders and padding to already be computed
|
||||||
fn compute_horiz(&self,
|
priv fn compute_horiz( &self,
|
||||||
width: MaybeAuto,
|
width: MaybeAuto,
|
||||||
left_margin: MaybeAuto,
|
left_margin: MaybeAuto,
|
||||||
right_margin: MaybeAuto,
|
right_margin: MaybeAuto,
|
||||||
available_width: Au)
|
available_width: Au) -> (Au, Au, Au) {
|
||||||
-> (Au, Au, Au) {
|
|
||||||
// If width is not 'auto', and width + margins > available_width, all 'auto' margins are
|
//If width is not 'auto', and width + margins > available_width, all 'auto' margins are treated as '0'
|
||||||
// treated as '0'.
|
|
||||||
let (left_margin, right_margin) = match width{
|
let (left_margin, right_margin) = match width{
|
||||||
Auto => (left_margin, right_margin),
|
Auto => (left_margin, right_margin),
|
||||||
Specified(width) => {
|
Specified(width) => {
|
||||||
let left = left_margin.spec_or_default(Au(0));
|
let left = left_margin.spec_or_default(Au(0));
|
||||||
let right = right_margin.spec_or_default(Au(0));
|
let right = right_margin.spec_or_default(Au(0));
|
||||||
|
|
||||||
if (left + right + width) > available_width {
|
if((left + right + width) > available_width) {
|
||||||
(Specified(left), Specified(right))
|
(Specified(left), Specified(right))
|
||||||
} else {
|
} else {
|
||||||
(left_margin, right_margin)
|
(left_margin, right_margin)
|
||||||
|
@ -144,41 +143,29 @@ impl BlockFlowData {
|
||||||
|
|
||||||
//Invariant: left_margin_Au + width_Au + right_margin_Au == available_width
|
//Invariant: left_margin_Au + width_Au + right_margin_Au == available_width
|
||||||
let (left_margin_Au, width_Au, right_margin_Au) = match (left_margin, width, right_margin) {
|
let (left_margin_Au, width_Au, right_margin_Au) = match (left_margin, width, right_margin) {
|
||||||
// If all have a computed value other than 'auto', the system is over-constrained and
|
//If all have a computed value other than 'auto', the system is over-constrained and we need to discard a margin.
|
||||||
// we need to discard a margin. If direction is ltr, ignore the specified right margin
|
//if direction is ltr, ignore the specified right margin and solve for it. If it is rtl, ignore the specified
|
||||||
// and solve for it. If it is rtl, ignore the specified left margin.
|
//left margin. FIXME(eatkinson): this assumes the direction is ltr
|
||||||
//
|
(Specified(margin_l), Specified(width), Specified(margin_r)) => (margin_l, width, available_width - (margin_l + width )),
|
||||||
// FIXME(eatkinson): this assumes the direction is ltr
|
|
||||||
(Specified(margin_l), Specified(width), Specified(_)) => {
|
|
||||||
(margin_l, width, available_width - (margin_l + width))
|
|
||||||
}
|
|
||||||
|
|
||||||
//If exactly one value is 'auto', solve for it
|
//If exactly one value is 'auto', solve for it
|
||||||
(Auto, Specified(width), Specified(margin_r)) => {
|
(Auto, Specified(width), Specified(margin_r)) => (available_width - (width + margin_r), width, margin_r),
|
||||||
(available_width - (width + margin_r), width, margin_r)
|
(Specified(margin_l), Auto, Specified(margin_r)) => (margin_l, available_width - (margin_l + margin_r), margin_r),
|
||||||
}
|
(Specified(margin_l), Specified(width), Auto) => (margin_l, width, available_width - (margin_l + width)),
|
||||||
(Specified(margin_l), Auto, Specified(margin_r)) => {
|
|
||||||
(margin_l, available_width - (margin_l + margin_r), margin_r)
|
|
||||||
}
|
|
||||||
(Specified(margin_l), Specified(width), Auto) => {
|
|
||||||
(margin_l, width, available_width - (margin_l + width))
|
|
||||||
}
|
|
||||||
|
|
||||||
// If width is set to 'auto', any other 'auto' value becomes '0', and width is solved
|
//If width is set to 'auto', any other 'auto' value becomes '0', and width is solved for
|
||||||
// for.
|
|
||||||
(Auto, Auto, Specified(margin_r)) => (Au(0), available_width - margin_r, margin_r),
|
(Auto, Auto, Specified(margin_r)) => (Au(0), available_width - margin_r, margin_r),
|
||||||
(Specified(margin_l), Auto, Auto) => (margin_l, available_width - margin_l, Au(0)),
|
(Specified(margin_l), Auto, Auto) => (margin_l, available_width - margin_l, Au(0)),
|
||||||
(Auto, Auto, Auto) => (Au(0), available_width, Au(0)),
|
(Auto, Auto, Auto) => (Au(0), available_width, Au(0)),
|
||||||
|
|
||||||
// If left and right margins are auto, they become equal.
|
//If left and right margins are auto, they become equal
|
||||||
(Auto, Specified(width), Auto) => {
|
(Auto, Specified(width), Auto) => {
|
||||||
let margin = (available_width - width).scale_by(0.5);
|
let margin = (available_width - width).scale_by(0.5);
|
||||||
(margin, width, margin)
|
(margin, width, margin)
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
//return values in same order as params
|
||||||
// Return values in same order as params.
|
|
||||||
(width_Au, left_margin_Au, right_margin_Au)
|
(width_Au, left_margin_Au, right_margin_Au)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,11 +242,11 @@ impl BlockFlowData {
|
||||||
pub fn assign_height_block(@mut self, ctx: &LayoutContext) {
|
pub fn assign_height_block(@mut self, ctx: &LayoutContext) {
|
||||||
let mut cur_y = Au(0);
|
let mut cur_y = Au(0);
|
||||||
|
|
||||||
self.box.map(|&box| {
|
for self.box.each |&box| {
|
||||||
do box.with_model |model| {
|
do box.with_model |model| {
|
||||||
cur_y += model.margin.top + model.border.top + model.padding.top;
|
cur_y += model.margin.top + model.border.top + model.padding.top;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
for BlockFlow(self).each_child |kid| {
|
for BlockFlow(self).each_child |kid| {
|
||||||
do kid.with_mut_base |child_node| {
|
do kid.with_mut_base |child_node| {
|
||||||
|
|
|
@ -8,10 +8,12 @@ use geom::rect::Rect;
|
||||||
use gfx::font_context::FontContext;
|
use gfx::font_context::FontContext;
|
||||||
use gfx::geometry::Au;
|
use gfx::geometry::Au;
|
||||||
use servo_net::local_image_cache::LocalImageCache;
|
use servo_net::local_image_cache::LocalImageCache;
|
||||||
|
use std::net::url::Url;
|
||||||
|
|
||||||
/// Data needed by the layout task.
|
/// Data needed by the layout task.
|
||||||
pub struct LayoutContext {
|
pub struct LayoutContext {
|
||||||
font_ctx: @mut FontContext,
|
font_ctx: @mut FontContext,
|
||||||
image_cache: @mut LocalImageCache,
|
image_cache: @mut LocalImageCache,
|
||||||
screen_size: Rect<Au>,
|
doc_url: Url,
|
||||||
|
screen_size: Rect<Au>
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,12 @@ impl Layout {
|
||||||
let image_cache = self.local_image_cache;
|
let image_cache = self.local_image_cache;
|
||||||
let font_ctx = self.font_ctx;
|
let font_ctx = self.font_ctx;
|
||||||
let screen_size = self.screen_size.unwrap();
|
let screen_size = self.screen_size.unwrap();
|
||||||
|
let doc_url = self.doc_url.clone();
|
||||||
|
|
||||||
LayoutContext {
|
LayoutContext {
|
||||||
image_cache: image_cache,
|
image_cache: image_cache,
|
||||||
font_ctx: font_ctx,
|
font_ctx: font_ctx,
|
||||||
|
doc_url: doc_url.unwrap(),
|
||||||
screen_size: Rect(Point2D(Au(0), Au(0)), screen_size),
|
screen_size: Rect(Point2D(Au(0), Au(0)), screen_size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,12 +349,10 @@ impl Layout {
|
||||||
let display_list = &display_list.take().list;
|
let display_list = &display_list.take().list;
|
||||||
for display_list.each_reverse |display_item| {
|
for display_list.each_reverse |display_item| {
|
||||||
let bounds = display_item.bounds();
|
let bounds = display_item.bounds();
|
||||||
|
|
||||||
// FIXME(pcwalton): Move this to be a method on Rect.
|
|
||||||
if x <= bounds.origin.x + bounds.size.width &&
|
if x <= bounds.origin.x + bounds.size.width &&
|
||||||
x >= bounds.origin.x &&
|
bounds.origin.x <= x &&
|
||||||
y < bounds.origin.y + bounds.size.height &&
|
y < bounds.origin.y + bounds.size.height &&
|
||||||
y >= bounds.origin.y {
|
bounds.origin.y < y {
|
||||||
resp = Ok(HitTestResponse(display_item.base().extra.node()));
|
resp = Ok(HitTestResponse(display_item.base().extra.node()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,10 @@ use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin};
|
||||||
use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto};
|
use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto};
|
||||||
use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto};
|
use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto};
|
||||||
use newcss::values::{CSSPadding, CSSPaddingLength, CSSPaddingPercentage};
|
use newcss::values::{CSSPadding, CSSPaddingLength, CSSPaddingPercentage};
|
||||||
|
|
||||||
/// Encapsulates the borders, padding, and margins, which we collectively call the "box model".
|
/// Encapsulates the borders, padding, and margins, which we collectively call the "box model".
|
||||||
pub struct BoxModel {
|
pub struct BoxModel {
|
||||||
/// The size of the borders.
|
|
||||||
border: SideOffsets2D<Au>,
|
border: SideOffsets2D<Au>,
|
||||||
/// The size of the padding.
|
|
||||||
padding: SideOffsets2D<Au>,
|
padding: SideOffsets2D<Au>,
|
||||||
/// The size of the margins.
|
|
||||||
margin: SideOffsets2D<Au>,
|
margin: SideOffsets2D<Au>,
|
||||||
/// The width of the content box.
|
/// The width of the content box.
|
||||||
content_box_width: Au,
|
content_box_width: Au,
|
||||||
|
@ -90,7 +86,7 @@ impl Zero for BoxModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoxModel {
|
impl BoxModel {
|
||||||
/// Populates the box model border parameters from the given computed style.
|
/// Populates the box model parameters from the given computed style.
|
||||||
pub fn compute_borders(&mut self, style: CompleteStyle) {
|
pub fn compute_borders(&mut self, style: CompleteStyle) {
|
||||||
// Compute the borders.
|
// Compute the borders.
|
||||||
self.border.top = self.compute_border_width(style.border_top_width());
|
self.border.top = self.compute_border_width(style.border_top_width());
|
||||||
|
@ -99,16 +95,11 @@ impl BoxModel {
|
||||||
self.border.left = self.compute_border_width(style.border_left_width());
|
self.border.left = self.compute_border_width(style.border_left_width());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Populates the box model padding parameters from the given computed style.
|
pub fn compute_padding(&mut self, style: CompleteStyle, cb_width: Au){
|
||||||
pub fn compute_padding(&mut self, style: CompleteStyle, content_box_width: Au) {
|
self.padding.top = self.compute_padding_length(style.padding_top(), cb_width);
|
||||||
self.padding.top = self.compute_padding_length(style.padding_top(),
|
self.padding.right = self.compute_padding_length(style.padding_right(), cb_width);
|
||||||
content_box_width);
|
self.padding.bottom = self.compute_padding_length(style.padding_bottom(), cb_width);
|
||||||
self.padding.right = self.compute_padding_length(style.padding_right(),
|
self.padding.left = self.compute_padding_length(style.padding_left(), cb_width);
|
||||||
content_box_width);
|
|
||||||
self.padding.bottom = self.compute_padding_length(style.padding_bottom(),
|
|
||||||
content_box_width);
|
|
||||||
self.padding.left = self.compute_padding_length(style.padding_left(),
|
|
||||||
content_box_width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn noncontent_width(&self) -> Au {
|
pub fn noncontent_width(&self) -> Au {
|
||||||
|
@ -122,7 +113,7 @@ impl BoxModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to compute the border width in app units from the CSS border width.
|
/// Helper function to compute the border width in app units from the CSS border width.
|
||||||
fn compute_border_width(&self, width: CSSBorderWidth) -> Au {
|
priv fn compute_border_width(&self, width: CSSBorderWidth) -> Au {
|
||||||
match width {
|
match width {
|
||||||
CSSBorderWidthLength(Px(v)) |
|
CSSBorderWidthLength(Px(v)) |
|
||||||
CSSBorderWidthLength(Em(v)) |
|
CSSBorderWidthLength(Em(v)) |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue