mirror of
https://github.com/servo/servo.git
synced 2025-06-21 23:59:00 +01:00
Multiple display list support
This commit is contained in:
parent
7e3075522d
commit
0892fada74
7 changed files with 172 additions and 103 deletions
|
@ -27,11 +27,62 @@ use std::cast::transmute_region;
|
|||
use std::vec::VecIterator;
|
||||
use style::computed_values::border_style;
|
||||
|
||||
pub struct DisplayListCollection<E> {
|
||||
lists: ~[DisplayList<E>]
|
||||
}
|
||||
|
||||
impl<E> DisplayListCollection<E> {
|
||||
pub fn new() -> DisplayListCollection<E> {
|
||||
DisplayListCollection {
|
||||
lists: ~[]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> DisplayListIterator<'a,E> {
|
||||
ParentDisplayListIterator(self.lists.iter())
|
||||
}
|
||||
|
||||
pub fn add_list(&mut self, list: DisplayList<E>) {
|
||||
self.lists.push(list);
|
||||
}
|
||||
|
||||
pub fn draw_lists_into_context(&self, render_context: &mut RenderContext) {
|
||||
for list in self.lists.iter() {
|
||||
list.draw_into_context(render_context);
|
||||
}
|
||||
debug!("{:?}", self.dump());
|
||||
}
|
||||
|
||||
fn dump(&self) {
|
||||
let mut index = 0;
|
||||
for list in self.lists.iter() {
|
||||
debug!("dumping display list {:d}:", index);
|
||||
list.dump();
|
||||
index = index + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of rendering operations to be performed.
|
||||
pub struct DisplayList<E> {
|
||||
list: ~[DisplayItem<E>]
|
||||
}
|
||||
|
||||
pub enum DisplayListIterator<'a,E> {
|
||||
EmptyDisplayListIterator,
|
||||
ParentDisplayListIterator(VecIterator<'a,DisplayList<E>>),
|
||||
}
|
||||
|
||||
impl<'a,E> Iterator<&'a DisplayList<E>> for DisplayListIterator<'a,E> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a DisplayList<E>> {
|
||||
match *self {
|
||||
EmptyDisplayListIterator => None,
|
||||
ParentDisplayListIterator(ref mut subiterator) => subiterator.next(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> DisplayList<E> {
|
||||
/// Creates a new display list.
|
||||
pub fn new() -> DisplayList<E> {
|
||||
|
@ -62,7 +113,6 @@ impl<E> DisplayList<E> {
|
|||
item.draw_into_context(render_context)
|
||||
}
|
||||
debug!("Ending display list.");
|
||||
debug!("{:?}", self.dump());
|
||||
}
|
||||
|
||||
/// Returns a preorder iterator over the given display list.
|
||||
|
|
|
@ -24,13 +24,14 @@ use std::comm::{Chan, Port, SharedChan};
|
|||
use extra::arc::Arc;
|
||||
|
||||
use buffer_map::BufferMap;
|
||||
use display_list::DisplayList;
|
||||
use font_context::{FontContext, FontContextInfo};
|
||||
use display_list::DisplayListCollection;
|
||||
use font_context::{FontContext, FontContextInfo};
|
||||
use opts::Opts;
|
||||
use render_context::RenderContext;
|
||||
|
||||
pub struct RenderLayer<T> {
|
||||
display_list: Arc<DisplayList<T>>,
|
||||
display_list_collection: Arc<DisplayListCollection<T>>,
|
||||
size: Size2D<uint>,
|
||||
color: Color
|
||||
}
|
||||
|
@ -305,7 +306,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
|||
|
||||
// Draw the display list.
|
||||
profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || {
|
||||
render_layer.display_list.get().draw_into_context(&mut ctx);
|
||||
render_layer.display_list_collection.get().draw_lists_into_context(&mut ctx);
|
||||
ctx.draw_target.flush();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType};
|
|||
|
||||
use std::cell::RefCell;
|
||||
use geom::{Point2D, Rect, SideOffsets2D};
|
||||
use gfx::display_list::DisplayList;
|
||||
use gfx::display_list::{DisplayList, DisplayListCollection};
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::geometry;
|
||||
|
||||
|
@ -496,22 +496,31 @@ impl BlockFlow {
|
|||
&mut self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
list: &RefCell<DisplayList<E>>)
|
||||
-> bool {
|
||||
mut index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>)
|
||||
-> uint {
|
||||
if self.is_float() {
|
||||
return self.build_display_list_float(builder, dirty, list);
|
||||
self.build_display_list_float(builder, dirty, index, lists);
|
||||
return index;
|
||||
}
|
||||
|
||||
if self.is_fixed {
|
||||
lists.with_mut(|lists| {
|
||||
index = lists.lists.len();
|
||||
lists.add_list(DisplayList::<E>::new());
|
||||
});
|
||||
}
|
||||
|
||||
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
|
||||
if !abs_rect.intersects(dirty) {
|
||||
return true;
|
||||
return index;
|
||||
}
|
||||
|
||||
debug!("build_display_list_block: adding display element");
|
||||
|
||||
// add box that starts block context
|
||||
for box_ in self.box_.iter() {
|
||||
box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list)
|
||||
box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, index, lists);
|
||||
}
|
||||
// TODO: handle any out-of-flow elements
|
||||
let this_position = self.base.abs_position;
|
||||
|
@ -521,24 +530,26 @@ impl BlockFlow {
|
|||
child_base.abs_position = this_position + child_base.position.origin;
|
||||
}
|
||||
|
||||
false
|
||||
index
|
||||
}
|
||||
|
||||
pub fn build_display_list_float<E:ExtraDisplayListData>(
|
||||
&mut self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
list: &RefCell<DisplayList<E>>)
|
||||
index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>)
|
||||
-> bool {
|
||||
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
|
||||
if !abs_rect.intersects(dirty) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
let offset = self.base.abs_position + self.float.get_ref().rel_pos;
|
||||
// add box that starts block context
|
||||
for box_ in self.box_.iter() {
|
||||
box_.build_display_list(builder, dirty, offset, (&*self) as &Flow, list)
|
||||
box_.build_display_list(builder, dirty, offset, (&*self) as &Flow, index, lists);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ use extra::arc::{MutexArc, Arc};
|
|||
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
|
||||
use gfx::color::rgb;
|
||||
use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass};
|
||||
use gfx::display_list::{DisplayList, ImageDisplayItem, ImageDisplayItemClass};
|
||||
use gfx::display_list::{ImageDisplayItem, ImageDisplayItemClass};
|
||||
use gfx::display_list::{SolidColorDisplayItem, SolidColorDisplayItemClass, TextDisplayItem};
|
||||
use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayItem};
|
||||
use gfx::display_list::{ClipDisplayItemClass};
|
||||
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection};
|
||||
use gfx::font::FontStyle;
|
||||
|
||||
use gfx::text::text_run::TextRun;
|
||||
|
@ -784,7 +784,8 @@ impl Box {
|
|||
|
||||
pub fn paint_inline_background_border_if_applicable<E:ExtraDisplayListData>(
|
||||
&self,
|
||||
list: &RefCell<DisplayList<E>>,
|
||||
index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>,
|
||||
absolute_bounds: &Rect<Au>,
|
||||
offset: &Point2D<Au>) {
|
||||
// FIXME: This causes a lot of background colors to be displayed when they are clearly not
|
||||
|
@ -803,7 +804,7 @@ impl Box {
|
|||
info.style.get().Background.background_color);
|
||||
|
||||
if !background_color.alpha.approx_eq(&0.0) {
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let solid_color_display_item = ~SolidColorDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: bg_rect.clone(),
|
||||
|
@ -812,7 +813,7 @@ impl Box {
|
|||
color: background_color.to_gfx_color(),
|
||||
};
|
||||
|
||||
list.append_item(SolidColorDisplayItemClass(solid_color_display_item))
|
||||
lists.lists[index].append_item(SolidColorDisplayItemClass(solid_color_display_item))
|
||||
});
|
||||
}
|
||||
let border = &info.border;
|
||||
|
@ -834,7 +835,7 @@ impl Box {
|
|||
let left_style = style.Border.border_left_style;
|
||||
|
||||
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let border_display_item = ~BorderDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: bg_rect,
|
||||
|
@ -851,7 +852,7 @@ impl Box {
|
|||
left_style)
|
||||
};
|
||||
|
||||
list.append_item(BorderDisplayItemClass(border_display_item))
|
||||
lists.lists[index].append_item(BorderDisplayItemClass(border_display_item))
|
||||
});
|
||||
|
||||
bg_rect.origin.x = bg_rect.origin.x + border.left;
|
||||
|
@ -865,7 +866,8 @@ impl Box {
|
|||
/// necessary.
|
||||
pub fn paint_background_if_applicable<E:ExtraDisplayListData>(
|
||||
&self,
|
||||
list: &RefCell<DisplayList<E>>,
|
||||
index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>,
|
||||
absolute_bounds: &Rect<Au>) {
|
||||
// FIXME: This causes a lot of background colors to be displayed when they are clearly not
|
||||
// needed. We could use display list optimization to clean this up, but it still seems
|
||||
|
@ -874,7 +876,7 @@ impl Box {
|
|||
let style = self.style();
|
||||
let background_color = style.resolve_color(style.Background.background_color);
|
||||
if !background_color.alpha.approx_eq(&0.0) {
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let solid_color_display_item = ~SolidColorDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: *absolute_bounds,
|
||||
|
@ -883,8 +885,8 @@ impl Box {
|
|||
color: background_color.to_gfx_color(),
|
||||
};
|
||||
|
||||
list.append_item(SolidColorDisplayItemClass(solid_color_display_item))
|
||||
})
|
||||
lists.lists[index].append_item(SolidColorDisplayItemClass(solid_color_display_item))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,7 +894,8 @@ impl Box {
|
|||
/// necessary.
|
||||
pub fn paint_borders_if_applicable<E:ExtraDisplayListData>(
|
||||
&self,
|
||||
list: &RefCell<DisplayList<E>>,
|
||||
index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>,
|
||||
abs_bounds: &Rect<Au>) {
|
||||
// Fast path.
|
||||
let border = self.border.get();
|
||||
|
@ -916,7 +919,7 @@ impl Box {
|
|||
- self.noncontent_inline_right();
|
||||
|
||||
// Append the border to the display list.
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let border_display_item = ~BorderDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: abs_bounds,
|
||||
|
@ -933,7 +936,7 @@ impl Box {
|
|||
left_style)
|
||||
};
|
||||
|
||||
list.append_item(BorderDisplayItemClass(border_display_item))
|
||||
lists.lists[index].append_item(BorderDisplayItemClass(border_display_item))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -957,7 +960,8 @@ impl Box {
|
|||
dirty: &Rect<Au>,
|
||||
offset: Point2D<Au>,
|
||||
flow: &Flow,
|
||||
list: &RefCell<DisplayList<E>>) {
|
||||
index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>) {
|
||||
let box_bounds = self.position.get();
|
||||
let absolute_box_bounds = box_bounds.translate(&offset);
|
||||
debug!("Box::build_display_list at rel={}, abs={}: {:s}",
|
||||
|
@ -975,14 +979,14 @@ impl Box {
|
|||
return;
|
||||
}
|
||||
|
||||
self.paint_inline_background_border_if_applicable(list, &absolute_box_bounds, &offset);
|
||||
self.paint_inline_background_border_if_applicable(index, lists, &absolute_box_bounds, &offset);
|
||||
// Add the background to the list, if applicable.
|
||||
self.paint_background_if_applicable(list, &absolute_box_bounds);
|
||||
self.paint_background_if_applicable(index, lists, &absolute_box_bounds);
|
||||
|
||||
match self.specific {
|
||||
UnscannedTextBox(_) => fail!("Shouldn't see unscanned boxes here."),
|
||||
ScannedTextBox(ref text_box) => {
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let item = ~ClipDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: absolute_box_bounds,
|
||||
|
@ -991,7 +995,7 @@ impl Box {
|
|||
child_list: ~[],
|
||||
need_clip: false
|
||||
};
|
||||
list.append_item(ClipDisplayItemClass(item));
|
||||
lists.lists[index].append_item(ClipDisplayItemClass(item));
|
||||
});
|
||||
|
||||
let text_color = self.style().Color.color.to_gfx_color();
|
||||
|
@ -1022,7 +1026,7 @@ impl Box {
|
|||
- self.noncontent_inline_right();
|
||||
|
||||
// Create the text box.
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let text_display_item = ~TextDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: bounds,
|
||||
|
@ -1037,7 +1041,7 @@ impl Box {
|
|||
flags: text_flags,
|
||||
};
|
||||
|
||||
list.append_item(TextDisplayItemClass(text_display_item))
|
||||
lists.lists[index].append_item(TextDisplayItemClass(text_display_item));
|
||||
});
|
||||
|
||||
// Draw debug frames for text bounds.
|
||||
|
@ -1048,7 +1052,7 @@ impl Box {
|
|||
// Compute the text box bounds and draw a border surrounding them.
|
||||
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
|
||||
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let border_display_item = ~BorderDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: absolute_box_bounds,
|
||||
|
@ -1059,7 +1063,7 @@ impl Box {
|
|||
style: SideOffsets2D::new_all_same(border_style::solid)
|
||||
|
||||
};
|
||||
list.append_item(BorderDisplayItemClass(border_display_item))
|
||||
lists.lists[index].append_item(BorderDisplayItemClass(border_display_item));
|
||||
});
|
||||
|
||||
// Draw a rectangle representing the baselines.
|
||||
|
@ -1070,7 +1074,7 @@ impl Box {
|
|||
let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent),
|
||||
Size2D(absolute_box_bounds.size.width, Au(0)));
|
||||
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let border_display_item = ~BorderDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: baseline,
|
||||
|
@ -1081,12 +1085,12 @@ impl Box {
|
|||
style: SideOffsets2D::new_all_same(border_style::dashed)
|
||||
|
||||
};
|
||||
list.append_item(BorderDisplayItemClass(border_display_item))
|
||||
lists.lists[index].append_item(BorderDisplayItemClass(border_display_item));
|
||||
});
|
||||
});
|
||||
},
|
||||
GenericBox | IframeBox(..) => {
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let item = ~ClipDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: absolute_box_bounds,
|
||||
|
@ -1095,7 +1099,7 @@ impl Box {
|
|||
child_list: ~[],
|
||||
need_clip: self.needs_clip()
|
||||
};
|
||||
list.append_item(ClipDisplayItemClass(item));
|
||||
lists.lists[index].append_item(ClipDisplayItemClass(item));
|
||||
});
|
||||
|
||||
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
|
||||
|
@ -1103,7 +1107,7 @@ impl Box {
|
|||
debug!("{:?}", {
|
||||
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
|
||||
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let border_display_item = ~BorderDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: absolute_box_bounds,
|
||||
|
@ -1114,12 +1118,12 @@ impl Box {
|
|||
style: SideOffsets2D::new_all_same(border_style::solid)
|
||||
|
||||
};
|
||||
list.append_item(BorderDisplayItemClass(border_display_item))
|
||||
lists.lists[index].append_item(BorderDisplayItemClass(border_display_item));
|
||||
});
|
||||
});
|
||||
},
|
||||
ImageBox(ref image_box) => {
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let item = ~ClipDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: absolute_box_bounds,
|
||||
|
@ -1128,7 +1132,7 @@ impl Box {
|
|||
child_list: ~[],
|
||||
need_clip: false
|
||||
};
|
||||
list.append_item(ClipDisplayItemClass(item));
|
||||
lists.lists[index].append_item(ClipDisplayItemClass(item));
|
||||
});
|
||||
|
||||
let mut image_ref = image_box.image.borrow_mut();
|
||||
|
@ -1146,7 +1150,7 @@ impl Box {
|
|||
debug!("(building display list) building image box");
|
||||
|
||||
// Place the image into the display list.
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let image_display_item = ~ImageDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: bounds,
|
||||
|
@ -1154,7 +1158,7 @@ impl Box {
|
|||
},
|
||||
image: image.clone(),
|
||||
};
|
||||
list.append_item(ImageDisplayItemClass(image_display_item));
|
||||
lists.lists[index].append_item(ImageDisplayItemClass(image_display_item));
|
||||
});
|
||||
}
|
||||
None => {
|
||||
|
@ -1169,7 +1173,7 @@ impl Box {
|
|||
debug!("{:?}", {
|
||||
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
|
||||
|
||||
list.with_mut(|list| {
|
||||
lists.with_mut(|lists| {
|
||||
let border_display_item = ~BorderDisplayItem {
|
||||
base: BaseDisplayItem {
|
||||
bounds: absolute_box_bounds,
|
||||
|
@ -1180,7 +1184,7 @@ impl Box {
|
|||
style: SideOffsets2D::new_all_same(border_style::solid)
|
||||
|
||||
};
|
||||
list.append_item(BorderDisplayItemClass(border_display_item))
|
||||
lists.lists[index].append_item(BorderDisplayItemClass(border_display_item))
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1207,7 +1211,8 @@ impl Box {
|
|||
// Add a border, if applicable.
|
||||
//
|
||||
// TODO: Outlines.
|
||||
self.paint_borders_if_applicable(list, &absolute_box_bounds);
|
||||
self.paint_borders_if_applicable(index, lists, &absolute_box_bounds);
|
||||
|
||||
}
|
||||
|
||||
/// Returns the *minimum width* and *preferred width* of this box as defined by CSS 2.1.
|
||||
|
|
|
@ -41,7 +41,7 @@ use extra::dlist::{DList, DListIterator, MutDListIterator};
|
|||
use extra::container::Deque;
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use gfx::display_list::{ClipDisplayItemClass, DisplayList};
|
||||
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection, DisplayList};
|
||||
use layout::display_list_builder::ToGfxColor;
|
||||
use gfx::color::Color;
|
||||
use servo_util::geometry::Au;
|
||||
|
@ -206,12 +206,13 @@ pub trait MutableFlowUtils {
|
|||
/// Computes the overflow region for this flow.
|
||||
fn store_overflow(self, _: &mut LayoutContext);
|
||||
|
||||
/// Builds a display list for this flow and its children.
|
||||
fn build_display_list<E:ExtraDisplayListData>(
|
||||
/// builds the display lists
|
||||
fn build_display_lists<E:ExtraDisplayListData>(
|
||||
self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
list: &RefCell<DisplayList<E>>)
|
||||
index: uint,
|
||||
mut list: &RefCell<DisplayListCollection<E>>)
|
||||
-> bool;
|
||||
}
|
||||
|
||||
|
@ -699,33 +700,37 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
|
|||
mut_base(self).overflow = overflow
|
||||
}
|
||||
|
||||
fn build_display_list<E:ExtraDisplayListData>(
|
||||
fn build_display_lists<E:ExtraDisplayListData>(
|
||||
self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
list: &RefCell<DisplayList<E>>)
|
||||
mut index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>)
|
||||
-> bool {
|
||||
debug!("Flow: building display list for f{}", base(self).id);
|
||||
match self.class() {
|
||||
BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, list),
|
||||
InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, list),
|
||||
index = match self.class() {
|
||||
BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, index, lists),
|
||||
InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, index, lists),
|
||||
};
|
||||
|
||||
if list.with_mut(|list| list.list.len() == 0) {
|
||||
if lists.with_mut(|lists| lists.lists[index].list.len() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let child_list = ~RefCell::new(DisplayList::new());
|
||||
let mut child_lists = DisplayListCollection::new();
|
||||
child_lists.add_list(DisplayList::new());
|
||||
let child_lists = RefCell::new(child_lists);
|
||||
for kid in child_iter(self) {
|
||||
kid.build_display_list(builder,dirty,child_list);
|
||||
kid.build_display_lists(builder, dirty, 0u, &child_lists);
|
||||
}
|
||||
|
||||
let mut child_list = Some(child_list.unwrap());
|
||||
list.with_mut(|list| {
|
||||
let result = list.list.mut_rev_iter().position(|item| {
|
||||
let mut child_lists = Some(child_lists.unwrap());
|
||||
lists.with_mut(|lists| {
|
||||
let mut child_lists = child_lists.take_unwrap();
|
||||
let result = lists.lists[index].list.mut_rev_iter().position(|item| {
|
||||
match *item {
|
||||
ClipDisplayItemClass(ref mut item) => {
|
||||
item.child_list.push_all_move(child_list.take_unwrap().list);
|
||||
item.child_list.push_all_move(child_lists.lists.shift().list);
|
||||
true
|
||||
},
|
||||
_ => false,
|
||||
|
@ -736,6 +741,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
|
|||
fail!("fail to find parent item");
|
||||
}
|
||||
|
||||
lists.lists.push_all_move(child_lists.lists);
|
||||
});
|
||||
true
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use layout::float_context::{PlacementInfo, FloatLeft};
|
|||
use extra::container::Deque;
|
||||
use extra::ringbuf::RingBuf;
|
||||
use geom::{Point2D, Rect, Size2D};
|
||||
use gfx::display_list::DisplayList;
|
||||
use gfx::display_list::DisplayListCollection;
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::range::Range;
|
||||
use std::cell::RefCell;
|
||||
|
@ -495,11 +495,12 @@ impl InlineFlow {
|
|||
&self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
list: &RefCell<DisplayList<E>>)
|
||||
-> bool {
|
||||
index: uint,
|
||||
lists: &RefCell<DisplayListCollection<E>>)
|
||||
-> uint {
|
||||
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
|
||||
if !abs_rect.intersects(dirty) {
|
||||
return true;
|
||||
return index;
|
||||
}
|
||||
|
||||
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and
|
||||
|
@ -509,14 +510,14 @@ impl InlineFlow {
|
|||
self.boxes.len());
|
||||
|
||||
for box_ in self.boxes.iter() {
|
||||
box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list)
|
||||
box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, index, lists);
|
||||
}
|
||||
|
||||
// TODO(#225): Should `inline-block` elements have flows as children of the inline flow or
|
||||
// should the flow be nested inside the box somehow?
|
||||
|
||||
// For now, don't traverse the subtree rooted here
|
||||
true
|
||||
index
|
||||
}
|
||||
|
||||
/// Returns the relative offset from the baseline for this box, taking into account the value
|
||||
|
|
|
@ -25,7 +25,8 @@ use layout::wrapper::LayoutNode;
|
|||
use extra::arc::{Arc, MutexArc};
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator, DisplayList};
|
||||
use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator};
|
||||
use gfx::display_list::{DisplayList, DisplayListCollection};
|
||||
use gfx::font_context::FontContextInfo;
|
||||
use gfx::opts::Opts;
|
||||
use gfx::render_task::{RenderMsg, RenderChan, RenderLayer};
|
||||
|
@ -89,7 +90,7 @@ pub struct LayoutTask {
|
|||
screen_size: Size2D<Au>,
|
||||
|
||||
/// A cached display list.
|
||||
display_list: Option<Arc<DisplayList<OpaqueNode>>>,
|
||||
display_list_collection: Option<Arc<DisplayListCollection<OpaqueNode>>>,
|
||||
|
||||
stylist: ~Stylist,
|
||||
|
||||
|
@ -273,7 +274,7 @@ impl LayoutTask {
|
|||
screen_size: screen_size,
|
||||
leaf_set: MutexArc::new(LeafSet::new()),
|
||||
|
||||
display_list: None,
|
||||
display_list_collection: None,
|
||||
stylist: ~new_stylist(),
|
||||
parallel_traversal: parallel_traversal,
|
||||
profiler_chan: profiler_chan,
|
||||
|
@ -575,14 +576,16 @@ impl LayoutTask {
|
|||
if data.goal == ReflowForDisplay {
|
||||
profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone(), || {
|
||||
let root_size = flow::base(layout_root).position.size;
|
||||
let display_list = ~RefCell::new(DisplayList::<OpaqueNode>::new());
|
||||
let mut display_list_collection = DisplayListCollection::new();
|
||||
display_list_collection.add_list(DisplayList::<OpaqueNode>::new());
|
||||
let display_list_collection = ~RefCell::new(display_list_collection);
|
||||
let dirty = flow::base(layout_root).position.clone();
|
||||
let display_list_builder = DisplayListBuilder {
|
||||
ctx: &layout_ctx,
|
||||
};
|
||||
layout_root.build_display_list(&display_list_builder, &dirty, display_list);
|
||||
layout_root.build_display_lists(&display_list_builder, &dirty, 0u, display_list_collection);
|
||||
|
||||
let display_list = Arc::new(display_list.unwrap());
|
||||
let display_list_collection = Arc::new(display_list_collection.unwrap());
|
||||
|
||||
let mut color = color::rgba(255.0, 255.0, 255.0, 255.0);
|
||||
|
||||
|
@ -607,13 +610,13 @@ impl LayoutTask {
|
|||
}
|
||||
|
||||
let render_layer = RenderLayer {
|
||||
display_list: display_list.clone(),
|
||||
display_list_collection: display_list_collection.clone(),
|
||||
size: Size2D(root_size.width.to_nearest_px() as uint,
|
||||
root_size.height.to_nearest_px() as uint),
|
||||
color: color
|
||||
};
|
||||
|
||||
self.display_list = Some(display_list.clone());
|
||||
self.display_list_collection = Some(display_list_collection.clone());
|
||||
|
||||
debug!("Layout done!");
|
||||
|
||||
|
@ -656,8 +659,9 @@ impl LayoutTask {
|
|||
}
|
||||
|
||||
let mut rect = None;
|
||||
let display_list = self.display_list.as_ref().unwrap().get();
|
||||
union_boxes_for_node(&mut rect, display_list.iter(), node);
|
||||
for display_list in self.display_list_collection.as_ref().unwrap().get().iter() {
|
||||
union_boxes_for_node(&mut rect, display_list.iter(), node);
|
||||
}
|
||||
reply_chan.send(ContentBoxResponse(rect.unwrap_or(Au::zero_rect())))
|
||||
}
|
||||
ContentBoxesQuery(node, reply_chan) => {
|
||||
|
@ -676,8 +680,9 @@ impl LayoutTask {
|
|||
}
|
||||
|
||||
let mut boxes = ~[];
|
||||
let display_list = self.display_list.as_ref().unwrap().get();
|
||||
add_boxes_for_node(&mut boxes, display_list.iter(), node);
|
||||
for display_list in self.display_list_collection.as_ref().unwrap().get().iter() {
|
||||
add_boxes_for_node(&mut boxes, display_list.iter(), node);
|
||||
}
|
||||
reply_chan.send(ContentBoxesResponse(boxes))
|
||||
}
|
||||
HitTestQuery(_, point, reply_chan) => {
|
||||
|
@ -717,27 +722,17 @@ impl LayoutTask {
|
|||
let ret: Option<HitTestResponse> = None;
|
||||
ret
|
||||
}
|
||||
let response = {
|
||||
match self.display_list {
|
||||
Some(ref list) => {
|
||||
let display_list = list.get();
|
||||
let (x, y) = (Au::from_frac_px(point.x as f64),
|
||||
Au::from_frac_px(point.y as f64));
|
||||
let resp = hit_test(x,y,display_list.list);
|
||||
if resp.is_none() {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(resp.unwrap())
|
||||
}
|
||||
}
|
||||
None => {
|
||||
error!("Can't hit test: no display list");
|
||||
Err(())
|
||||
},
|
||||
for display_list in self.display_list_collection.as_ref().unwrap().get().lists.rev_iter() {
|
||||
let (x, y) = (Au::from_frac_px(point.x as f64),
|
||||
Au::from_frac_px(point.y as f64));
|
||||
let resp = hit_test(x,y,display_list.list);
|
||||
if resp.is_some() {
|
||||
reply_chan.send(Ok(resp.unwrap()));
|
||||
return
|
||||
}
|
||||
};
|
||||
}
|
||||
reply_chan.send(Err(()));
|
||||
|
||||
reply_chan.send(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue