mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Merge pull request #17 from mmeyerho/fix_layout
Fix borrowck errors and erros in layout positioning
This commit is contained in:
commit
9597caf42b
16 changed files with 155 additions and 63 deletions
|
@ -97,7 +97,7 @@ impl private_methods<T:send,A> for handle<T,A> {
|
|||
fn set_rd_aux(t: *A) unsafe { (**self).rd_aux = t; }
|
||||
fn set_next_dirty(+h: handle<T,A>) unsafe { (**self).next_dirty = h; }
|
||||
|
||||
fn is_null() -> bool { (*self).is_null() }
|
||||
pure fn is_null() -> bool { (*self).is_null() }
|
||||
fn is_not_null() -> bool { (*self).is_not_null() }
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,10 @@ fn zero_size_au() -> size<au> {
|
|||
{width: au(0), height: au(0)}
|
||||
}
|
||||
|
||||
fn px_to_au(i: int) -> au {
|
||||
pure fn px_to_au(i: int) -> au {
|
||||
au(i * 60)
|
||||
}
|
||||
|
||||
fn au_to_px(au: au) -> int {
|
||||
pure fn au_to_px(au: au) -> int {
|
||||
*au / 60
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ impl layout_methods for @box {
|
|||
fn reflow_intrinsic(size: geom::size<au>) {
|
||||
self.bounds.size = copy size;
|
||||
|
||||
#debug["reflow_intrinsic size=%?", self.bounds];
|
||||
#debug["reflow_intrinsic size=%?", copy self.bounds];
|
||||
}
|
||||
|
||||
#[doc="Dumps the box tree, for debugging."]
|
||||
|
|
|
@ -10,6 +10,8 @@ impl block_layout_methods for @box {
|
|||
fn reflow_block(available_width: au) {
|
||||
assert self.kind == bk_block;
|
||||
|
||||
#debug["starting reflow block"];
|
||||
|
||||
// Root here is the root of the reflow, not necessarily the doc as
|
||||
// a whole.
|
||||
//
|
||||
|
@ -30,7 +32,7 @@ impl block_layout_methods for @box {
|
|||
self.bounds.size = {width: available_width, // FIXME
|
||||
height: au(current_height)};
|
||||
|
||||
#debug["reflow_block size=%?", self.bounds];
|
||||
#debug["reflow_block size=%?", copy self.bounds];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import /*layout::*/base::{rd_tree_ops, wr_tree_ops};
|
|||
import /*layout::*/style::style::{style_methods};
|
||||
import /*layout::*/text::text_box;
|
||||
import util::tree;
|
||||
import option::is_none;
|
||||
|
||||
export box_builder_methods;
|
||||
|
||||
|
@ -69,7 +70,12 @@ impl methods for ctxt {
|
|||
di_inline {
|
||||
let anon_box = alt self.anon_box {
|
||||
none {
|
||||
let b = new_box(kid, bk_inline);
|
||||
// the anonymous box inherits the attributes
|
||||
// of its parents for now, so that
|
||||
// properties of intrinsic boxes are not
|
||||
// spread to their parenting anonymous box.
|
||||
// TODO: check what css actually specifies
|
||||
let b = new_box(self.parent_node, bk_inline);
|
||||
self.anon_box = some(b);
|
||||
b
|
||||
}
|
||||
|
@ -130,7 +136,7 @@ impl methods for ctxt {
|
|||
}
|
||||
|
||||
self.finish_anonymous_box_if_necessary();
|
||||
assert self.anon_box.is_none();
|
||||
assert is_none(self.anon_box);
|
||||
}
|
||||
|
||||
#[doc="
|
||||
|
@ -138,7 +144,7 @@ impl methods for ctxt {
|
|||
anonymous box to the block.
|
||||
"]
|
||||
fn finish_anonymous_box_if_necessary() {
|
||||
alt self.anon_box {
|
||||
alt copy self.anon_box {
|
||||
none { /* Nothing to do. */ }
|
||||
some(b) { btree.add_child(self.parent_box, b); }
|
||||
}
|
||||
|
|
|
@ -12,14 +12,16 @@ impl inline_layout_methods for @box {
|
|||
fn reflow_inline(available_width: au) {
|
||||
assert self.kind == bk_inline;
|
||||
|
||||
#debug["starting reflow inline"];
|
||||
|
||||
// FIXME: This is clownshoes inline layout and is not even close to
|
||||
// correct.
|
||||
let y = self.bounds.origin.y;
|
||||
let y = 0;
|
||||
let mut x = 0, inline_available_width = *available_width;
|
||||
let mut current_height = 0;
|
||||
for tree::each_child(btree, self) {
|
||||
|kid|
|
||||
kid.bounds.origin = { x: au(x), y: y };
|
||||
kid.bounds.origin = { x: au(x), y: au(y) };
|
||||
kid.reflow(au(inline_available_width));
|
||||
inline_available_width -= *kid.bounds.size.width;
|
||||
x += *kid.bounds.size.width;
|
||||
|
@ -29,7 +31,7 @@ impl inline_layout_methods for @box {
|
|||
self.bounds.size = { width: available_width,
|
||||
height: au(current_height) };
|
||||
|
||||
#debug["reflow_inline size=%?", self.bounds];
|
||||
#debug["reflow_inline size=%?", copy self.bounds];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ them to be rendered
|
|||
|
||||
import task::*;
|
||||
import comm::*;
|
||||
import gfx::geom;
|
||||
import gfx::geom::{au, au_to_px, px_to_au, point, box};
|
||||
import gfx::renderer;
|
||||
import dom::base::node;
|
||||
import dom::rcu::scope;
|
||||
|
@ -40,7 +40,7 @@ fn layout(to_renderer: chan<renderer::msg>) -> chan<msg> {
|
|||
this_box.dump();
|
||||
|
||||
this_box.apply_style_for_subtree();
|
||||
this_box.reflow(geom::px_to_au(800));
|
||||
this_box.reflow(px_to_au(800));
|
||||
|
||||
let dlist = build_display_list(this_box);
|
||||
to_renderer.send(renderer::render(dlist));
|
||||
|
@ -50,52 +50,84 @@ fn layout(to_renderer: chan<renderer::msg>) -> chan<msg> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_display_list(box: @base::box) -> display_list::display_list {
|
||||
let mut list = [box_to_display_item(box)];
|
||||
#[doc="
|
||||
|
||||
Builds a display list for a box and all its children.
|
||||
Args:
|
||||
-box: the box to build the display list for
|
||||
-origin: the coordinates of upper-left corner of the box containing
|
||||
the passed in box.
|
||||
|
||||
"]
|
||||
fn build_display_list_from_origin(box: @base::box, origin : point<au>)
|
||||
-> dl::display_list {
|
||||
let box_origin = point(
|
||||
px_to_au(au_to_px(origin.x) + au_to_px(box.bounds.origin.x)),
|
||||
px_to_au(au_to_px(origin.y) + au_to_px(box.bounds.origin.y)));
|
||||
#debug("Handed origin %?, box has bounds %?, starting with origin %?", origin, copy box.bounds, box_origin);
|
||||
|
||||
let mut list = [box_to_display_item(box, box_origin)];
|
||||
|
||||
for btree.each_child(box) {|c|
|
||||
list += build_display_list(c);
|
||||
#debug("Recursively building display list with origin %?", box_origin);
|
||||
list += build_display_list_from_origin(c, box_origin);
|
||||
}
|
||||
|
||||
#debug("display_list: %?", list);
|
||||
ret list;
|
||||
}
|
||||
|
||||
fn box_to_display_item(box: @base::box) -> dl::display_item {
|
||||
fn build_display_list(box : @base::box) -> dl::display_list {
|
||||
ret build_display_list_from_origin(box, point(au(0), au(0)));
|
||||
}
|
||||
|
||||
#[doc="
|
||||
|
||||
Creates a display list item for a single block.
|
||||
Args:
|
||||
-box: the box to build the display list for
|
||||
-origin: the coordinates of upper-left corner of the passed in box.
|
||||
|
||||
"]
|
||||
fn box_to_display_item(box: @base::box, origin : point<au>)
|
||||
-> dl::display_item {
|
||||
let mut item;
|
||||
alt box.appearance.background_image {
|
||||
some(image) {
|
||||
|
||||
#debug("request to display a box from origin %?", origin);
|
||||
|
||||
let bounds = {origin : origin, size : box.bounds.size};
|
||||
|
||||
alt (box.appearance.background_image, box.appearance.background_color) {
|
||||
(some(image), some(*)) | (some(image), none) {
|
||||
item = dl::display_item({
|
||||
item_type: dl::display_item_image(~copy *image),
|
||||
bounds: copy box.bounds
|
||||
bounds: bounds
|
||||
});
|
||||
}
|
||||
none {
|
||||
alt box.appearance.background_color {
|
||||
some(col) {
|
||||
(none, some(col)) {
|
||||
let red_col = (col >> 16u) & 255u;
|
||||
let green_col = (col >> 8u) & 255u;
|
||||
let blue_col = col & 255u;
|
||||
|
||||
#debug("Assigning colors (%d, %d, %d) to box with bounds %?", red_col as int, green_col as int, blue_col as int, bounds);
|
||||
|
||||
item = dl::display_item({
|
||||
item_type: dl::display_item_solid_color(red_col as u8,
|
||||
green_col as u8,
|
||||
blue_col as u8),
|
||||
bounds: copy box.bounds
|
||||
bounds: bounds
|
||||
});
|
||||
}
|
||||
none {
|
||||
(none, none) {
|
||||
let r = rand::rng();
|
||||
item = dl::display_item({
|
||||
item_type: dl::display_item_solid_color(r.next() as u8,
|
||||
r.next() as u8,
|
||||
r.next() as u8),
|
||||
bounds: copy box.bounds
|
||||
bounds: bounds
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#debug("layout: display item: %?", item);
|
||||
ret item;
|
||||
|
|
|
@ -9,19 +9,20 @@ import parser::lexer::css::{token, to_start_desc, to_end_desc,
|
|||
to_comma, to_elmt, to_attr, to_desc,
|
||||
to_eof};
|
||||
import comm::recv;
|
||||
import option::is_none;
|
||||
|
||||
type token_reader = {stream : port<token>, mut lookahead : option<token>};
|
||||
|
||||
impl methods for token_reader {
|
||||
fn get() -> token {
|
||||
alt self.lookahead {
|
||||
alt copy self.lookahead {
|
||||
some(tok) { self.lookahead = none; tok }
|
||||
none { recv(self.stream) }
|
||||
}
|
||||
}
|
||||
|
||||
fn unget(tok : token) {
|
||||
assert self.lookahead.is_none();
|
||||
assert is_none(self.lookahead);
|
||||
self.lookahead = some(tok);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import comm::{port, chan};
|
|||
import html::html_methods;
|
||||
import css::css_methods;
|
||||
import dom::style;
|
||||
import option::is_none;
|
||||
|
||||
enum parse_state {
|
||||
ps_html_normal,
|
||||
|
@ -43,7 +44,7 @@ impl u8_vec_methods for [u8] {
|
|||
|
||||
impl util_methods for parser {
|
||||
fn get() -> char_or_eof {
|
||||
alt self.lookahead {
|
||||
alt copy self.lookahead {
|
||||
some(coe) {
|
||||
let rv = coe;
|
||||
self.lookahead = none;
|
||||
|
@ -59,7 +60,7 @@ impl util_methods for parser {
|
|||
}
|
||||
|
||||
fn unget(ch: u8) {
|
||||
assert self.lookahead.is_none();
|
||||
assert is_none(self.lookahead);
|
||||
self.lookahead = some(coe_char(ch));
|
||||
}
|
||||
|
||||
|
@ -316,7 +317,7 @@ mod css {
|
|||
}
|
||||
|
||||
fn parse_css_element(c : u8) -> token {
|
||||
assert self.lookahead.is_none();
|
||||
assert is_none(self.lookahead);
|
||||
|
||||
/* Check for special attributes with an implied element,
|
||||
or a wildcard which is not a alphabet character.*/
|
||||
|
|
|
@ -23,7 +23,7 @@ fn each_child<T:copy,O:rd_tree_ops<T>>(
|
|||
|
||||
let mut p = ops.with_tree_fields(node) { |f| f.first_child };
|
||||
loop {
|
||||
alt p {
|
||||
alt copy p {
|
||||
none { ret; }
|
||||
some(c) {
|
||||
if !f(c) { ret; }
|
||||
|
@ -54,11 +54,10 @@ fn add_child<T:copy,O:wr_tree_ops<T>>(
|
|||
assert child_tf.next_sibling == none;
|
||||
|
||||
ops.with_tree_fields(parent) { |parent_tf|
|
||||
alt parent_tf.last_child {
|
||||
alt copy parent_tf.last_child {
|
||||
none {
|
||||
parent_tf.first_child = some(child);
|
||||
}
|
||||
|
||||
some(lc) {
|
||||
let lc = lc; // satisfy alias checker
|
||||
ops.with_tree_fields(lc) { |lc_tf|
|
||||
|
|
16
src/test/small-layout-test.css
Normal file
16
src/test/small-layout-test.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
.green {background-color : green}
|
||||
.blue {background-color : blue}
|
||||
.red {background-color : red}
|
||||
.white {background-color : white}
|
||||
.black {background-color : black}
|
||||
.brown {background-color : rgb(200,100,0)}
|
||||
.gray {background-color : rgb(100,100,100)}
|
||||
.lightgray {background-color : rgb(200,200,200)}
|
||||
.darkgray {background-color : rgb(50,50,50)}
|
||||
.cyan {background-color : rgb(0,255,255)}
|
||||
.maroon {background-color : rgb(100,0,20)}
|
||||
.pink {background-color : rgb(255,0,255)}
|
||||
.orange {background-color : rgb(255,175,0)}
|
||||
.violet {background-color : rgb(100,0,150)}
|
||||
.darkgreen {background-color : rgb(0,100,0)}
|
||||
.darkblue {background-color : rgb(0,0,100)}
|
4
src/test/small-layout-test.html
Normal file
4
src/test/small-layout-test.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
<div class="gray">
|
||||
<img class="green"></img>
|
||||
<div class="blue"><img class="red"></img></div>
|
||||
</div>
|
|
@ -4,7 +4,8 @@ p.blue > p.green + p.red { background-color : blue ;color : green }
|
|||
img[class] .pastoral *[lang|=en] { display:inline}
|
||||
.book > #novel + *[type=novella] p { color : blue; color : white }
|
||||
* {background-color : red}
|
||||
* * * * {background-color : black}
|
||||
* * * * {background-color : white}
|
||||
* * * * * {background-color : rgb(200,0,200)}
|
||||
div div {background-color : green}
|
||||
* * div {background-color : blue}
|
||||
div div div {background-color : rgb(100,100,100)}
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
<div class="darkgrey">
|
||||
<div class="green">
|
||||
<div class="darkblue"><img class="maroon"></img><div class="darkgreen"><img class="gray"></img></div></div>
|
||||
<div class="darkgray">
|
||||
<div class="darkblue">
|
||||
<img class="maroon"></img>
|
||||
<div class="darkgreen">
|
||||
<img class="gray"></img>
|
||||
</div>
|
||||
</div>
|
||||
<img class="black"></img>
|
||||
<img class="brown"></img>
|
||||
<div class="pink"><img class="orange"></img><img class="violet"></img></div>
|
||||
<div class="pink">
|
||||
<img class="orange"></img>
|
||||
<img class="violet"></img>
|
||||
</div>
|
||||
<div class="lightgray">
|
||||
<img class="blue"></img>
|
||||
<img class="red"></img>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
16
src/test/test_inline_boxes.css
Normal file
16
src/test/test_inline_boxes.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
.green {background-color : green}
|
||||
.blue {background-color : blue}
|
||||
.red {background-color : red}
|
||||
.white {background-color : white}
|
||||
.black {background-color : black}
|
||||
.brown {background-color : rgb(200,100,0)}
|
||||
.gray {background-color : rgb(100,100,100)}
|
||||
.lightgray {background-color : rgb(200,200,200)}
|
||||
.darkgray {background-color : rgb(50,50,50)}
|
||||
.cyan {background-color : rgb(0,255,255)}
|
||||
.maroon {background-color : rgb(100,0,20)}
|
||||
.pink {background-color : rgb(255,0,255)}
|
||||
.orange {background-color : rgb(255,175,0)}
|
||||
.violet {background-color : rgb(100,0,150)}
|
||||
.darkgreen {background-color : rgb(0,100,0)}
|
||||
.darkblue {background-color : rgb(0,0,100)}
|
6
src/test/test_inline_boxes.html
Normal file
6
src/test/test_inline_boxes.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<div class="darkgray">
|
||||
<div class="blue">
|
||||
<img class="red"></img>
|
||||
</div>
|
||||
<img class="green"></img>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue