mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Fix some bugs in display list construction/dirty rect intersection. Rename some variables to emphasize that dirty rect is w.r.t. global coords.
This commit is contained in:
parent
5fd7e72d06
commit
3c58145f1a
3 changed files with 39 additions and 25 deletions
|
@ -109,7 +109,7 @@ impl FlowContext : BlockLayout {
|
|||
do self.with_block_box |box| {
|
||||
box.d().position.size.width = remaining_width;
|
||||
let (left_used, right_used) = box.get_used_width();
|
||||
remaining_width = remaining_width.sub(&left_used.add(&right_used));
|
||||
remaining_width -= left_used.add(&right_used);
|
||||
}
|
||||
|
||||
for FlowTree.each_child(self) |child_ctx| {
|
||||
|
@ -126,7 +126,7 @@ impl FlowContext : BlockLayout {
|
|||
|
||||
for FlowTree.each_child(self) |child_ctx| {
|
||||
child_ctx.d().position.origin.y = cur_y;
|
||||
cur_y = cur_y.add(&child_ctx.d().position.size.height);
|
||||
cur_y += child_ctx.d().position.size.height;
|
||||
}
|
||||
|
||||
self.d().position.size.height = cur_y;
|
||||
|
|
|
@ -408,7 +408,7 @@ impl RenderBox : RenderBoxMethods {
|
|||
offset: &Point2D<au>, list: &dl::DisplayList) {
|
||||
|
||||
let style = self.d().node.style();
|
||||
let bounds : Rect<au> = match style.position {
|
||||
let box_bounds : Rect<au> = match style.position {
|
||||
Specified(PosAbsolute) => {
|
||||
let x_offset = match style.left {
|
||||
Specified(Px(px)) => au::from_frac_px(px),
|
||||
|
@ -421,21 +421,27 @@ impl RenderBox : RenderBoxMethods {
|
|||
Rect(Point2D(x_offset, y_offset), copy self.d().position.size)
|
||||
}
|
||||
_ => {
|
||||
self.d().position.translate(offset)
|
||||
self.d().position
|
||||
}
|
||||
};
|
||||
|
||||
debug!("RenderBox::build_display_list at %?: %s", self.d().position, self.debug_str());
|
||||
let abs_box_bounds = box_bounds.translate(offset);
|
||||
debug!("RenderBox::build_display_list at rel=%?, abs=%?: %s",
|
||||
box_bounds, abs_box_bounds, self.debug_str());
|
||||
debug!("RenderBox::build_display_list: dirty=%?, offset=%?", dirty, offset);
|
||||
// TODO: don't make display item if box not in dirty rect
|
||||
//if !self.d().position.intersects(dirty) { return; }
|
||||
if abs_box_bounds.intersects(dirty) {
|
||||
debug!("RenderBox::build_display_list: intersected. Adding display item...");
|
||||
} else {
|
||||
debug!("RenderBox::build_display_list: Did not intersect...");
|
||||
return;
|
||||
}
|
||||
|
||||
self.add_bgcolor_to_list(list, &bounds);
|
||||
self.add_bgcolor_to_list(list, &abs_box_bounds);
|
||||
|
||||
match *self {
|
||||
UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
|
||||
TextBox(_,d) => {
|
||||
list.append_item(~dl::Text(copy bounds, text_run::serialize(builder.ctx.font_cache, d.run),
|
||||
list.append_item(~dl::Text(copy abs_box_bounds, text_run::serialize(builder.ctx.font_cache, d.run),
|
||||
d.offset, d.length))
|
||||
},
|
||||
// TODO: items for background, border, outline
|
||||
|
@ -443,17 +449,17 @@ impl RenderBox : RenderBoxMethods {
|
|||
},
|
||||
ImageBox(_,i) => {
|
||||
match i.get_image() {
|
||||
Some(image) => list.append_item(~dl::Image(copy bounds, arc::clone(&image))),
|
||||
Some(image) => list.append_item(~dl::Image(copy abs_box_bounds, arc::clone(&image))),
|
||||
/* No image data at all? Okay, add some fallback content instead. */
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.add_border_to_list(list, bounds);
|
||||
self.add_border_to_list(list, abs_box_bounds);
|
||||
}
|
||||
|
||||
fn add_bgcolor_to_list(list: &dl::DisplayList, bounds: &Rect<au>) {
|
||||
fn add_bgcolor_to_list(list: &dl::DisplayList, abs_bounds: &Rect<au>) {
|
||||
use std::cmp::FuzzyEq;
|
||||
// TODO: shouldn't need to unbox CSSValue by now
|
||||
let boxed_bgcolor = self.d().node.style().background_color;
|
||||
|
@ -462,31 +468,31 @@ impl RenderBox : RenderBoxMethods {
|
|||
Specified(BgColorTransparent) | _ => util::color::rgba(0,0,0,0.0)
|
||||
};
|
||||
if !bgcolor.alpha.fuzzy_eq(&0.0) {
|
||||
list.append_item(~dl::SolidColor(copy *bounds, bgcolor.red, bgcolor.green, bgcolor.blue));
|
||||
list.append_item(~dl::SolidColor(copy *abs_bounds, bgcolor.red, bgcolor.green, bgcolor.blue));
|
||||
}
|
||||
}
|
||||
|
||||
fn add_border_to_list(list: &dl::DisplayList, bounds: Rect<au>) {
|
||||
fn add_border_to_list(list: &dl::DisplayList, abs_bounds: Rect<au>) {
|
||||
let style = self.d().node.style();
|
||||
match style.border_width {
|
||||
Specified(Px(px)) => {
|
||||
// If there's a border, let's try to display *something*
|
||||
let border_width = au::from_frac_px(px);
|
||||
let bounds = Rect {
|
||||
let abs_bounds = Rect {
|
||||
origin: Point2D {
|
||||
x: bounds.origin.x - border_width / au(2),
|
||||
y: bounds.origin.y - border_width / au(2),
|
||||
x: abs_bounds.origin.x - border_width / au(2),
|
||||
y: abs_bounds.origin.y - border_width / au(2),
|
||||
},
|
||||
size: Size2D {
|
||||
width: bounds.size.width + border_width,
|
||||
height: bounds.size.height + border_width
|
||||
width: abs_bounds.size.width + border_width,
|
||||
height: abs_bounds.size.height + border_width
|
||||
}
|
||||
};
|
||||
let color = match style.border_color {
|
||||
Specified(BdrColor(color)) => color,
|
||||
_ => rgb(0, 0, 0) // FIXME
|
||||
};
|
||||
list.push(~dl::Border(bounds, border_width, color.red, color.green, color.blue));
|
||||
list.push(~dl::Border(abs_bounds, border_width, color.red, color.green, color.blue));
|
||||
}
|
||||
_ => () // TODO
|
||||
}
|
||||
|
|
|
@ -44,16 +44,24 @@ impl FlowContext: FlowDisplayListBuilderMethods {
|
|||
self.build_display_list_recurse(builder, dirty, &zero, list);
|
||||
}
|
||||
|
||||
fn build_display_list_for_child(@self, builder: &DisplayListBuilder, child: @FlowContext,
|
||||
fn build_display_list_for_child(@self, builder: &DisplayListBuilder, child_flow: @FlowContext,
|
||||
dirty: &Rect<au>, offset: &Point2D<au>,
|
||||
list: &dl::DisplayList) {
|
||||
|
||||
// adjust the dirty rect to child flow context coordinates
|
||||
let adj_dirty = dirty.translate(&child.d().position.origin);
|
||||
let adj_offset = offset.add(&child.d().position.origin);
|
||||
let abs_flow_bounds = child_flow.d().position.translate(offset);
|
||||
let adj_offset = offset.add(&child_flow.d().position.origin);
|
||||
|
||||
if (adj_dirty.intersects(&child.d().position)) {
|
||||
child.build_display_list_recurse(builder, &adj_dirty, &adj_offset, list);
|
||||
debug!("build_display_list_for_child: rel=%?, abs=%?",
|
||||
child_flow.d().position, abs_flow_bounds);
|
||||
debug!("build_display_list_for_child: dirty=%?, offset=%?",
|
||||
dirty, offset);
|
||||
|
||||
if dirty.intersects(&abs_flow_bounds) {
|
||||
debug!("build_display_list_for_child: intersected. recursing into child flow...");
|
||||
child_flow.build_display_list_recurse(builder, dirty, &adj_offset, list);
|
||||
} else {
|
||||
debug!("build_display_list_for_child: Did not intersect...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue