Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of changes #2 #512

Merged
merged 42 commits into from Jun 11, 2013
Merged
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c14a137
Update rust-geom
pcwalton May 29, 2013
233a204
Implement the beginnings of the box model for render boxes
pcwalton May 29, 2013
a1d1289
Add NSPR and NSS submodules
pcwalton May 29, 2013
0af3bbf
Add NSS and NSPR to the build
pcwalton May 29, 2013
2d1a00c
Don't clip layers to the screen area
pcwalton May 29, 2013
67eb533
Clamp scrolling to the page boundaries
pcwalton May 29, 2013
d97f002
Stop hammering on the compositor
pcwalton May 29, 2013
02c5772
Fix corrupted textures when resizing.
pcwalton May 30, 2013
dcfabb7
Don't try to remove whitespace twice if it's the only node.
pcwalton May 30, 2013
e2bcd36
Color links blue
pcwalton May 30, 2013
2e4cecc
Add flows if requested to the display list info.
pcwalton May 30, 2013
ea1a406
base and bounds methods for DisplayItem
May 25, 2013
f77eef5
Basic hit testing functionality
pcwalton May 31, 2013
facb707
Update rust-css and rust-netsurfcss
pcwalton May 31, 2013
d5e4793
Add horizontal borders, margins and padding. Broken until rust-css su…
May 30, 2013
708f9b4
Fix method names and dynamic borrow check failures
pcwalton May 31, 2013
0b91af3
Refactor a bit and compute vertical margins as well.
pcwalton May 31, 2013
72ca765
Update rust-css and fix some dynamic borrow check failures
pcwalton Jun 1, 2013
f1fcd4d
Add comments and compute heights properly
pcwalton Jun 1, 2013
cddf67a
Update border rendering
May 31, 2013
fb2ce2c
Rename `with_imm_base` to `with_base`.
pcwalton Jun 3, 2013
e6ff135
test_slam_layout, a new layout perf test case
pcwalton Jun 4, 2013
8d3b6ae
Stop rendering when script queries layout
pcwalton Jun 4, 2013
40a69fc
Address review comments
pcwalton Jun 4, 2013
7a435fc
Refactor document damage to distinguish it from layout/style damage.
pcwalton Jun 5, 2013
5750069
Use the scroll hack
pcwalton Jun 6, 2013
ae5b2df
Roll up block layout changes
pcwalton Jun 6, 2013
9c25474
Only warn, don't assert, if the node range length is zero.
pcwalton Jun 6, 2013
97eb567
Update the configure script to pass --enable-64bit
pcwalton Jun 6, 2013
c65d51f
Address review comments
pcwalton Jun 6, 2013
98a730c
Use full paths for submodules in the configure script
pcwalton Jun 6, 2013
bb6ae7a
Update NSS to fix build issues.
metajack Jun 11, 2013
5425154
Merge remote-tracking branch 'origin/master' into pcwalton-master
metajack Jun 11, 2013
a2c4f72
Fix spacing.
metajack Jun 11, 2013
4cf4302
Update nss.
metajack Jun 11, 2013
ea1c883
Fix warning.
metajack Jun 11, 2013
16ca6f2
Add missing field.
metajack Jun 11, 2013
a42cf9b
Fix types.
metajack Jun 11, 2013
b635079
Revert rust-css and rust-netsurfcss to working versions.
metajack Jun 11, 2013
f0692e5
Update rust-glut.
metajack Jun 11, 2013
a5e3605
Fix rust-css tests.
metajack Jun 11, 2013
cdd5de7
Disable tests for nspr and nss.
metajack Jun 11, 2013
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Add horizontal borders, margins and padding. Broken until rust-css su…

…pports padding
  • Loading branch information
Eric Atkinson authored and pcwalton committed May 31, 2013
commit d5e47933abd2a9df10dd7ea0c2010124f0948f0b
@@ -10,6 +10,7 @@ use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::display_list_builder::{FlowDisplayListBuilderMethods};
use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow};
use layout::inline::InlineLayout;
use layout::model::{MaybeAuto, Specified, Auto};

use core::cell::Cell;
use geom::point::Point2D;
@@ -104,6 +105,8 @@ impl BlockFlowData {
/* if not an anonymous block context, add in block box's widths.
these widths will not include child elements, just padding etc. */
self.box.map(|&box| {
//Can compute border width here since it doesn't depend on anything
box.compute_borders();
min_width = min_width.add(&box.get_min_width(ctx));
pref_width = pref_width.add(&box.get_pref_width(ctx));
});
@@ -112,6 +115,57 @@ impl BlockFlowData {
self.common.pref_width = pref_width;
}

/// Computes left and right margins and width based on CSS 2.1 secion 10.3.3.
/// Requires borders and padding to already be computed
priv fn compute_horiz( &self,
width: MaybeAuto,
left_margin: MaybeAuto,
right_margin: MaybeAuto,
available_width: Au) -> (Au, Au, Au) {

//If width is not 'auto', and width + margins > available_width, all 'auto' margins are treated as '0'
let (left_margin, right_margin) = match width{
Auto => (left_margin, right_margin),
Specified(width) => {
let left = left_margin.spec_or_default(Au(0));
let right = right_margin.spec_or_default(Au(0));

if((left + right + width) > available_width) {
(Specified(left), Specified(right))
} else {
(left_margin, right_margin)
}
}
};

//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) {
//If all have a computed value other than 'auto', the system is over-constrained and we need to discard a margin.
//if direction is ltr, ignore the specified right margin and solve for it. If it is rtl, ignore the specified
//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 )),

//If exactly one value is 'auto', solve for it
(Auto, Specified(width), Specified(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)),

//If width is set to 'auto', any other 'auto' value becomes '0', and width is solved for
(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)),
(Auto, Auto, Auto) => (Au(0), available_width, Au(0)),

//If left and right margins are auto, they become equal
(Auto, Specified(width), Auto) => {
let margin = (available_width - width).scale_by(0.5);
(margin, width, margin)
}

};
//return values in same order as params
(width_Au, left_margin_Au, right_margin_Au)
}

/// Recursively (top-down) determines the actual width of child contexts and boxes. When called
/// on this context, the context has had its width set by the parent context.
///
@@ -123,24 +177,28 @@ impl BlockFlowData {
self.common.position.size.width = ctx.screen_size.size.width;
}

//position was set to the containing block by the flow's parent
let mut remaining_width = self.common.position.size.width;
let left_used = Au(0);
let mut x_offset = Au(0);

// Let the box consume some width. It will return the amount remaining for its children.
self.box.map(|&box| {
do box.with_mut_base |base| {
base.position.size.width = remaining_width;
box.compute_padding(remaining_width);
let available_width = remaining_width - box.get_noncontent_width();

let (left_used, right_used) = box.get_used_width();
remaining_width -= left_used.add(&right_used);
do box.compute_width(remaining_width) |width, left_margin, right_margin| {
self.compute_horiz(width, left_margin, right_margin, available_width)
}

let content_box = box.content_box();
x_offset = content_box.origin.x;
remaining_width = content_box.size.width;
});

for BlockFlow(self).each_child |kid| {
assert!(kid.starts_block_flow() || kid.starts_inline_flow());

do kid.with_mut_base |child_node| {
child_node.position.origin.x = left_used;
child_node.position.origin.x = x_offset;
child_node.position.size.width = remaining_width;
}
}
@@ -8,7 +8,7 @@ use css::node_style::StyledNode;
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor};
use layout::flow::FlowContext;
use layout::model::BoxModel;
use layout::model::{BoxModel,MaybeAuto};
use layout::text;

use core::cell::Cell;
@@ -374,14 +374,6 @@ pub impl RenderBox {
fn get_min_width(&self, _: &LayoutContext) -> Au {
// FIXME(pcwalton): I think we only need to calculate this if the damage says that CSS
// needs to be restyled.
do self.with_mut_base |base| {
// TODO(pcwalton): Hmm, it seems wasteful to have the box model stuff inside every
// render box if they can only be nonzero if the box is an element.
if base.node.is_element() {
base.model.populate(base.node.style())
}
}

match *self {
// TODO: This should account for the minimum width of the box element in isolation.
// That includes borders, margins, and padding, but not child widths. The block
@@ -456,37 +448,51 @@ pub impl RenderBox {
(Au(0), Au(0))
}

/// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
/// the owning flow.
fn content_box(&self) -> Rect<Au> {
let origin = self.position().origin;
match *self {
ImageRenderBoxClass(image_box) => {
Rect {
origin: origin,
size: image_box.base.position.size,
}
},
GenericRenderBoxClass(*) => {
self.position()
fn compute_padding(&self, cb_width: Au) {
do self.with_imm_base |base| {
base.model.compute_padding(self.style(), cb_width);
}
}

// FIXME: The following hits an ICE for whatever reason.
fn compute_borders(&self){
do self.with_imm_base |base| {
base.model.compute_borders(self.style());
}
}

/*
let origin = self.d().position.origin;
let size = self.d().position.size;
let (offset_left, offset_right) = self.get_used_width();
let (offset_top, offset_bottom) = self.get_used_height();
fn get_noncontent_width(&self) -> Au {
do self.with_imm_base |base| {
base.model.border.left + base.model.padding.left + base.model.border.right +
base.model.padding.right
}
}

Rect {
origin: Point2D(origin.x + offset_left, origin.y + offset_top),
size: Size2D(size.width - (offset_left + offset_right),
size.height - (offset_top + offset_bottom))
}
*/
},
TextRenderBoxClass(*) => self.position(),
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here.")
fn compute_width (&self, cb_width: Au,
callback: &fn(MaybeAuto, MaybeAuto, MaybeAuto) -> (Au, Au, Au)) {
let computed_width = MaybeAuto::from_width(self.style().width());
let computed_margin_left = MaybeAuto::from_margin(self.style().margin_left());
let computed_margin_right = MaybeAuto::from_margin(self.style().margin_right());

let (used_width, used_margin_left, used_margin_right) =
callback(computed_width, computed_margin_left, computed_margin_right);

do self.with_mut_base |base| {
base.model.margin.left = used_margin_left;
base.model.margin.right = used_margin_right;
base.position.size.width = used_width + self.get_noncontent_width();
base.position.origin.x = used_margin_left;
}
}

/// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
/// the owning flow.
fn content_box(&self) -> Rect<Au> {
do self.with_imm_base |base| {
let origin = Point2D(base.position.origin.x + base.model.border.left + base.model.padding.left,
base.position.origin.y);
let size = Size2D(base.position.size.width - self.get_noncontent_width(),
base.position.size.height);
Rect(origin, size)
}
}

@@ -19,12 +19,54 @@ use newcss::complete::CompleteStyle;
use newcss::units::{Em, Pt, Px};
use newcss::values::{CSSBorderWidth, CSSBorderWidthLength, CSSBorderWidthMedium};
use newcss::values::{CSSBorderWidthThick, CSSBorderWidthThin};

use newcss::values::{CSSWidth, CSSWidthLength, CSSWidthPercentage, CSSWidthAuto};
use newcss::values::{CSSMargin, CSSMarginLength, CSSMarginPercentage, CSSMarginAuto};
use newcss::values::{CSSPadding, CSSPaddingLength, CSSPaddingPercentage};
/// Encapsulates the borders, padding, and margins, which we collectively call the "box model".
pub struct BoxModel {
border: SideOffsets2D<Au>,
padding: SideOffsets2D<Au>,
margin: SideOffsets2D<Au>,
content_width: Au,
}

/// Useful helper data type when computing values for blocks and positioned elements.
pub enum MaybeAuto{
Auto,
Specified(Au),
}

impl MaybeAuto{
pub fn from_margin(margin: CSSMargin) -> MaybeAuto{
match margin {
CSSMarginAuto => Auto,
//FIXME(eatkinson): Compute percents properly
CSSMarginPercentage(_) => Specified(Au(0)),
//FIXME(eatkinson): Compute pt and em values properly
CSSMarginLength(Px(v)) |
CSSMarginLength(Pt(v)) |
CSSMarginLength(Em(v)) => Specified(Au::from_frac_px(v)),
}
}

pub fn from_width(width: CSSWidth) -> MaybeAuto{
match width{
CSSWidthAuto => Auto,
//FIXME(eatkinson): Compute percents properly
CSSWidthPercentage(_) => Specified(Au(0)),
//FIXME(eatkinson): Compute pt and em values properly
CSSWidthLength(Px(v)) |
CSSWidthLength(Pt(v)) |
CSSWidthLength(Em(v)) => Specified(Au::from_frac_px(v)),
}
}

pub fn spec_or_default(&self, default: Au) -> Au{
match *self{
Auto => default,
Specified(value) => value
}
}
}

impl Zero for BoxModel {
@@ -33,24 +75,31 @@ impl Zero for BoxModel {
border: Zero::zero(),
padding: Zero::zero(),
margin: Zero::zero(),
content_width: Zero::zero(),
}
}

fn is_zero(&self) -> bool {
self.padding.is_zero() && self.border.is_zero() && self.margin.is_zero()
self.padding.is_zero() && self.border.is_zero() && self.margin.is_zero() &&
self.content_width.is_zero()
}
}

impl BoxModel {
/// Populates the box model parameters from the given computed style.
pub fn populate(&mut self, style: CompleteStyle) {
// Populate the borders.
pub fn compute_borders(&mut self, style: CompleteStyle) {
// Compute the borders.
self.border.top = self.compute_border_width(style.border_top_width());
self.border.right = self.compute_border_width(style.border_right_width());
self.border.bottom = self.compute_border_width(style.border_bottom_width());
self.border.left = self.compute_border_width(style.border_left_width());
}

// TODO(pcwalton): Padding, margins.
pub fn compute_padding(&mut self, style: CompleteStyle, cb_width: Au){
self.padding.top = self.compute_padding(style.padding_top(), cb_width);
self.padding.right = self.compute_padding(style.padding_right(), cb_width);
self.padding.bottom = self.compute_padding(style.padding_bottom(), cb_width);
self.padding.left = self.compute_padding(style.padding_left(), cb_width);
}

/// Helper function to compute the border width in app units from the CSS border width.
@@ -67,6 +116,18 @@ impl BoxModel {
CSSBorderWidthThick => Au::from_px(10),
}
}

fn compute_padding(&self, padding: CSSPadding, cb_width: Au) -> Au{
match padding {
CSSPaddingLength(Px(v)) |
CSSPaddingLength(Pt(v)) |
CSSPaddingLength(Em(v)) => {
// FIXME(eatkinson): Handle 'em' and 'pt' correctly
Au::from_frac_px(v)
}
CSSPaddingPercentage(p) => cb_width.scale_by(p)
}
}
}

//
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.