mirror of
https://github.com/servo/servo.git
synced 2025-07-13 18:33:40 +01:00
Remove extraneous references to flow tree objects.
This commit is contained in:
parent
e4bfad144e
commit
eb58e4f5d1
6 changed files with 133 additions and 119 deletions
|
@ -19,19 +19,22 @@ use render_context::RenderContext;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::comm::{Chan, Port, SharedChan};
|
use std::comm::{Chan, Port, SharedChan};
|
||||||
|
use extra::arc::Arc;
|
||||||
|
|
||||||
use servo_util::time::{ProfilerChan, profile};
|
use servo_util::time::{ProfilerChan, profile};
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
|
|
||||||
use extra::arc;
|
use extra::arc;
|
||||||
|
|
||||||
pub struct RenderLayer {
|
|
||||||
display_list: DisplayList<()>,
|
|
||||||
|
pub struct RenderLayer<T> {
|
||||||
|
display_list: Arc<DisplayList<T>>,
|
||||||
size: Size2D<uint>
|
size: Size2D<uint>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Msg {
|
pub enum Msg<T> {
|
||||||
RenderMsg(RenderLayer),
|
RenderMsg(RenderLayer<T>),
|
||||||
ReRenderMsg(~[BufferRequest], f32, PipelineId, Epoch),
|
ReRenderMsg(~[BufferRequest], f32, PipelineId, Epoch),
|
||||||
PaintPermissionGranted,
|
PaintPermissionGranted,
|
||||||
PaintPermissionRevoked,
|
PaintPermissionRevoked,
|
||||||
|
@ -56,24 +59,24 @@ pub fn BufferRequest(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferReq
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct RenderChan {
|
pub struct RenderChan<T> {
|
||||||
chan: SharedChan<Msg>,
|
chan: SharedChan<Msg<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderChan {
|
impl<T> RenderChan<T> {
|
||||||
pub fn new(chan: Chan<Msg>) -> RenderChan {
|
pub fn new(chan: Chan<Msg<T>>) -> RenderChan<T> {
|
||||||
RenderChan {
|
RenderChan {
|
||||||
chan: SharedChan::new(chan),
|
chan: SharedChan::new(chan),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn send(&self, msg: Msg) {
|
pub fn send(&self, msg: Msg<T>) {
|
||||||
self.chan.send(msg);
|
self.chan.send(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderTask<C> {
|
struct RenderTask<C,T> {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
port: Port<Msg>,
|
port: Port<Msg<T>>,
|
||||||
compositor: C,
|
compositor: C,
|
||||||
font_ctx: @mut FontContext,
|
font_ctx: @mut FontContext,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
|
@ -84,7 +87,7 @@ struct RenderTask<C> {
|
||||||
share_gl_context: AzGLContext,
|
share_gl_context: AzGLContext,
|
||||||
|
|
||||||
/// The layer to be rendered
|
/// The layer to be rendered
|
||||||
render_layer: Option<RenderLayer>,
|
render_layer: Option<RenderLayer<T>>,
|
||||||
/// Permission to send paint messages to the compositor
|
/// Permission to send paint messages to the compositor
|
||||||
paint_permission: bool,
|
paint_permission: bool,
|
||||||
/// Cached copy of last layers rendered
|
/// Cached copy of last layers rendered
|
||||||
|
@ -93,9 +96,9 @@ struct RenderTask<C> {
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: RenderListener + Send> RenderTask<C> {
|
impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
|
||||||
pub fn create(id: PipelineId,
|
pub fn create(id: PipelineId,
|
||||||
port: Port<Msg>,
|
port: Port<Msg<T>>,
|
||||||
compositor: C,
|
compositor: C,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
profiler_chan: ProfilerChan) {
|
profiler_chan: ProfilerChan) {
|
||||||
|
@ -226,7 +229,7 @@ impl<C: RenderListener + Send> RenderTask<C> {
|
||||||
|
|
||||||
// Draw the display list.
|
// Draw the display list.
|
||||||
do profile(time::RenderingDrawingCategory, self.profiler_chan.clone()) {
|
do profile(time::RenderingDrawingCategory, self.profiler_chan.clone()) {
|
||||||
render_layer.display_list.draw_into_context(&ctx);
|
render_layer.display_list.get().draw_into_context(&ctx);
|
||||||
ctx.canvas.draw_target.flush();
|
ctx.canvas.draw_target.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,20 @@
|
||||||
|
|
||||||
//! Code for managing the layout data in the DOM.
|
//! Code for managing the layout data in the DOM.
|
||||||
|
|
||||||
use layout::flow::FlowContext;
|
|
||||||
use layout::incremental::RestyleDamage;
|
use layout::incremental::RestyleDamage;
|
||||||
|
use gfx::display_list::DisplayList;
|
||||||
|
use servo_util::range::Range;
|
||||||
|
|
||||||
|
use extra::arc::Arc;
|
||||||
use newcss::complete::CompleteSelectResults;
|
use newcss::complete::CompleteSelectResults;
|
||||||
use script::dom::node::{AbstractNode, LayoutView};
|
use script::dom::node::{AbstractNode, LayoutView};
|
||||||
use servo_util::tree::TreeNodeRef;
|
use servo_util::tree::TreeNodeRef;
|
||||||
|
|
||||||
|
pub struct DisplayBoxes {
|
||||||
|
display_list: Option<Arc<DisplayList<AbstractNode<()>>>>,
|
||||||
|
range: Option<Range>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Data that layout associates with a node.
|
/// Data that layout associates with a node.
|
||||||
pub struct LayoutData {
|
pub struct LayoutData {
|
||||||
/// The results of CSS styling for this node.
|
/// The results of CSS styling for this node.
|
||||||
|
@ -19,8 +26,9 @@ pub struct LayoutData {
|
||||||
/// Description of how to account for recent style changes.
|
/// Description of how to account for recent style changes.
|
||||||
restyle_damage: Option<RestyleDamage>,
|
restyle_damage: Option<RestyleDamage>,
|
||||||
|
|
||||||
/// The CSS flow that this node is associated with.
|
/// The boxes assosiated with this flow.
|
||||||
flow: Option<FlowContext>,
|
/// Used for getBoundingClientRect and friends.
|
||||||
|
boxes: DisplayBoxes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutData {
|
impl LayoutData {
|
||||||
|
@ -29,7 +37,7 @@ impl LayoutData {
|
||||||
LayoutData {
|
LayoutData {
|
||||||
style: None,
|
style: None,
|
||||||
restyle_damage: None,
|
restyle_damage: None,
|
||||||
flow: None,
|
boxes: DisplayBoxes{ display_list: None, range: None },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,14 +73,8 @@ impl LayoutAuxMethods for AbstractNode<LayoutView> {
|
||||||
/// box in the COW model) and populates it with an empty style object.
|
/// box in the COW model) and populates it with an empty style object.
|
||||||
fn initialize_layout_data(self) -> Option<@mut LayoutData> {
|
fn initialize_layout_data(self) -> Option<@mut LayoutData> {
|
||||||
if self.has_layout_data() {
|
if self.has_layout_data() {
|
||||||
{
|
self.layout_data().boxes.display_list = None;
|
||||||
let layout_data = &mut self.layout_data().flow;
|
self.layout_data().boxes.range = None;
|
||||||
match *layout_data {
|
|
||||||
Some(ref flow) => flow.teardown(),
|
|
||||||
None => ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.layout_data().flow = None;
|
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let data = @mut LayoutData::new();
|
let data = @mut LayoutData::new();
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
//! Creates CSS boxes from a DOM tree.
|
//! Creates CSS boxes from a DOM tree.
|
||||||
|
|
||||||
use layout::aux::LayoutAuxMethods;
|
|
||||||
use layout::block::BlockFlowData;
|
use layout::block::BlockFlowData;
|
||||||
use layout::float::FloatFlowData;
|
use layout::float::FloatFlowData;
|
||||||
use layout::box::{GenericRenderBoxClass, ImageRenderBox, ImageRenderBoxClass, RenderBox};
|
use layout::box::{GenericRenderBoxClass, ImageRenderBox, ImageRenderBoxClass, RenderBox};
|
||||||
|
@ -334,18 +333,6 @@ impl LayoutTreeBuilder {
|
||||||
this_generator.pop_node(layout_ctx, cur_node);
|
this_generator.pop_node(layout_ctx, cur_node);
|
||||||
self.simplify_children_of_flow(layout_ctx, &mut this_generator.flow);
|
self.simplify_children_of_flow(layout_ctx, &mut this_generator.flow);
|
||||||
|
|
||||||
// store reference to the flow context which contains any
|
|
||||||
// boxes that correspond to child_flow.node. These boxes may
|
|
||||||
// eventually be elided or split, but the mapping between
|
|
||||||
// nodes and FlowContexts should not change during layout.
|
|
||||||
let flow: &FlowContext = &this_generator.flow;
|
|
||||||
for child_flow in flow.children() {
|
|
||||||
do child_flow.with_base |child_node| {
|
|
||||||
let dom_node = child_node.node;
|
|
||||||
assert!(dom_node.has_layout_data());
|
|
||||||
dom_node.layout_data().flow = Some(child_flow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(next_generator)
|
Some(next_generator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,20 +6,29 @@
|
||||||
|
|
||||||
use layout::box::RenderBox;
|
use layout::box::RenderBox;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
|
use std::cast::transmute;
|
||||||
|
use script::dom::node::AbstractNode;
|
||||||
|
|
||||||
use gfx;
|
use gfx;
|
||||||
use newcss;
|
use newcss;
|
||||||
|
|
||||||
/// Extra display list data is either nothing (if the display list is to be rendered) or the
|
/// Display list data is usually an AbstractNode with view () to indicate
|
||||||
/// originating render box (if the display list is generated for hit testing).
|
/// that nodes in this view shoud not really be touched. The idea is to
|
||||||
|
/// store the nodes in the display list and have layout transmute them.
|
||||||
pub trait ExtraDisplayListData {
|
pub trait ExtraDisplayListData {
|
||||||
fn new(box: RenderBox) -> Self;
|
fn new(box: RenderBox) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type representing the lack of extra display list data. This is used when sending display
|
|
||||||
/// list data off to be rendered.
|
|
||||||
pub type Nothing = ();
|
pub type Nothing = ();
|
||||||
|
|
||||||
|
impl ExtraDisplayListData for AbstractNode<()> {
|
||||||
|
fn new (box: RenderBox) -> AbstractNode<()> {
|
||||||
|
unsafe {
|
||||||
|
transmute(box.node())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ExtraDisplayListData for Nothing {
|
impl ExtraDisplayListData for Nothing {
|
||||||
fn new(_: RenderBox) -> Nothing {
|
fn new(_: RenderBox) -> Nothing {
|
||||||
()
|
()
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
use css::matching::MatchMethods;
|
use css::matching::MatchMethods;
|
||||||
use css::select::new_css_select_ctx;
|
use css::select::new_css_select_ctx;
|
||||||
use layout::aux::{LayoutData, LayoutAuxMethods};
|
use layout::aux::{LayoutData, LayoutAuxMethods};
|
||||||
use layout::box::RenderBox;
|
|
||||||
use layout::box_builder::LayoutTreeBuilder;
|
use layout::box_builder::LayoutTreeBuilder;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder};
|
use layout::display_list_builder::{DisplayListBuilder};
|
||||||
|
@ -17,7 +16,9 @@ use layout::incremental::{RestyleDamage, BubbleWidths};
|
||||||
|
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::uint;
|
||||||
use std::comm::{Port};
|
use std::comm::{Port};
|
||||||
|
use extra::arc::Arc;
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
|
@ -44,6 +45,7 @@ use servo_net::local_image_cache::LocalImageCache;
|
||||||
use servo_util::tree::TreeNodeRef;
|
use servo_util::tree::TreeNodeRef;
|
||||||
use servo_util::time::{ProfilerChan, profile};
|
use servo_util::time::{ProfilerChan, profile};
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
|
use servo_util::range::Range;
|
||||||
use extra::url::Url;
|
use extra::url::Url;
|
||||||
|
|
||||||
struct LayoutTask {
|
struct LayoutTask {
|
||||||
|
@ -51,7 +53,7 @@ struct LayoutTask {
|
||||||
port: Port<Msg>,
|
port: Port<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
render_chan: RenderChan,
|
render_chan: RenderChan<AbstractNode<()>>,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
local_image_cache: @mut LocalImageCache,
|
local_image_cache: @mut LocalImageCache,
|
||||||
font_ctx: @mut FontContext,
|
font_ctx: @mut FontContext,
|
||||||
|
@ -61,6 +63,8 @@ struct LayoutTask {
|
||||||
/// This is used to root reader data.
|
/// This is used to root reader data.
|
||||||
layout_refs: ~[@mut LayoutData],
|
layout_refs: ~[@mut LayoutData],
|
||||||
|
|
||||||
|
display_list: Option<Arc<DisplayList<AbstractNode<()>>>>,
|
||||||
|
|
||||||
css_select_ctx: @mut SelectCtx,
|
css_select_ctx: @mut SelectCtx,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
}
|
}
|
||||||
|
@ -70,7 +74,7 @@ impl LayoutTask {
|
||||||
port: Port<Msg>,
|
port: Port<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
render_chan: RenderChan,
|
render_chan: RenderChan<AbstractNode<()>>,
|
||||||
img_cache_task: ImageCacheTask,
|
img_cache_task: ImageCacheTask,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
profiler_chan: ProfilerChan) {
|
profiler_chan: ProfilerChan) {
|
||||||
|
@ -99,7 +103,7 @@ impl LayoutTask {
|
||||||
port: Port<Msg>,
|
port: Port<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
render_chan: RenderChan,
|
render_chan: RenderChan<AbstractNode<()>>,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
opts: &Opts,
|
opts: &Opts,
|
||||||
profiler_chan: ProfilerChan)
|
profiler_chan: ProfilerChan)
|
||||||
|
@ -117,6 +121,8 @@ impl LayoutTask {
|
||||||
font_ctx: fctx,
|
font_ctx: fctx,
|
||||||
doc_url: None,
|
doc_url: None,
|
||||||
screen_size: None,
|
screen_size: None,
|
||||||
|
|
||||||
|
display_list: None,
|
||||||
|
|
||||||
layout_refs: ~[],
|
layout_refs: ~[],
|
||||||
css_select_ctx: @mut new_css_select_ctx(),
|
css_select_ctx: @mut new_css_select_ctx(),
|
||||||
|
@ -271,7 +277,7 @@ impl LayoutTask {
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: We want to do
|
// FIXME: We want to do
|
||||||
// for flow in layout_root.traverse_preorder_prune(|f| f.restyle_damage().lacks(Reflow)) {
|
// for flow in layout_root.traverse_preorder_prune(|f| f.restyle_damage().lacks(Reflow))
|
||||||
// but FloatContext values can't be reused, so we need to recompute them every time.
|
// but FloatContext values can't be reused, so we need to recompute them every time.
|
||||||
for flow in layout_root.traverse_preorder() {
|
for flow in layout_root.traverse_preorder() {
|
||||||
flow.assign_widths(&mut layout_ctx);
|
flow.assign_widths(&mut layout_ctx);
|
||||||
|
@ -291,7 +297,7 @@ impl LayoutTask {
|
||||||
ctx: &layout_ctx,
|
ctx: &layout_ctx,
|
||||||
};
|
};
|
||||||
|
|
||||||
let display_list = @Cell::new(DisplayList::new());
|
let display_list = ~Cell::new(DisplayList::new::<AbstractNode<()>>());
|
||||||
|
|
||||||
// TODO: Set options on the builder before building.
|
// TODO: Set options on the builder before building.
|
||||||
// TODO: Be smarter about what needs painting.
|
// TODO: Be smarter about what needs painting.
|
||||||
|
@ -303,11 +309,39 @@ impl LayoutTask {
|
||||||
base.position.size
|
base.position.size
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let display_list = Arc::new(display_list.take());
|
||||||
|
|
||||||
|
for i in range(0,display_list.get().list.len()) {
|
||||||
|
let node: AbstractNode<LayoutView> = unsafe {
|
||||||
|
transmute(display_list.get().list[i].base().extra)
|
||||||
|
};
|
||||||
|
assert!(node.has_layout_data(), "Node has display item but no layout data");
|
||||||
|
|
||||||
|
let layout_data = node.layout_data();
|
||||||
|
layout_data.boxes.display_list = Some(display_list.clone());
|
||||||
|
|
||||||
|
if layout_data.boxes.range.is_none() {
|
||||||
|
debug!("Creating initial range for node");
|
||||||
|
layout_data.boxes.range = Some(Range::new(i,1));
|
||||||
|
} else {
|
||||||
|
debug!("Appending item to range");
|
||||||
|
unsafe {
|
||||||
|
let old_node: AbstractNode<()> = transmute(node);
|
||||||
|
assert!(old_node == display_list.get().list[i-1].base().extra,
|
||||||
|
"Non-contiguous arrangement of display items");
|
||||||
|
}
|
||||||
|
|
||||||
|
layout_data.boxes.range.unwrap().extend_by(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let render_layer = RenderLayer {
|
let render_layer = RenderLayer {
|
||||||
display_list: display_list.take(),
|
display_list: display_list.clone(),
|
||||||
size: Size2D(root_size.width.to_px() as uint, root_size.height.to_px() as uint)
|
size: Size2D(root_size.width.to_px() as uint, root_size.height.to_px() as uint)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.display_list = Some(display_list.clone());
|
||||||
|
|
||||||
self.render_chan.send(RenderMsg(render_layer));
|
self.render_chan.send(RenderMsg(render_layer));
|
||||||
} // time(layout: display list building)
|
} // time(layout: display list building)
|
||||||
}
|
}
|
||||||
|
@ -330,19 +364,15 @@ impl LayoutTask {
|
||||||
transmute(node)
|
transmute(node)
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = match node.layout_data().flow {
|
let response = match (node.layout_data().boxes.display_list.clone(), node.layout_data().boxes.range) {
|
||||||
None => {
|
(Some(display_list), Some(range)) => {
|
||||||
error!("no flow present");
|
let mut rect: Option<Rect<Au>> = None;
|
||||||
Err(())
|
for i in range.eachi() {
|
||||||
}
|
rect = match rect {
|
||||||
Some(flow) => {
|
Some(acc) => Some(acc.union(&display_list.get().list[i].bounds())),
|
||||||
let start_val: Option<Rect<Au>> = None;
|
None => Some(display_list.get().list[i].bounds())
|
||||||
let rect = do flow.foldl_boxes_for_node(node, start_val) |acc, box| {
|
|
||||||
match acc {
|
|
||||||
Some(acc) => Some(acc.union(&box.content_box())),
|
|
||||||
None => Some(box.content_box())
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
match rect {
|
match rect {
|
||||||
None => {
|
None => {
|
||||||
|
@ -352,6 +382,10 @@ impl LayoutTask {
|
||||||
Some(rect) => Ok(ContentBoxResponse(rect))
|
Some(rect) => Ok(ContentBoxResponse(rect))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
|
error!("no display list present");
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
reply_chan.send(response)
|
reply_chan.send(response)
|
||||||
|
@ -362,71 +396,49 @@ impl LayoutTask {
|
||||||
transmute(node)
|
transmute(node)
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = match node.layout_data().flow {
|
let response = match (node.layout_data().boxes.display_list.clone(), node.layout_data().boxes.range) {
|
||||||
None => Err(()),
|
(Some(display_list), Some(range)) => {
|
||||||
Some(flow) => {
|
|
||||||
let mut boxes = ~[];
|
let mut boxes = ~[];
|
||||||
for box in flow.iter_all_boxes() {
|
for i in range.eachi() {
|
||||||
if box.node() == node {
|
boxes.push(display_list.get().list[i].bounds());
|
||||||
boxes.push(box.content_box());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ContentBoxesResponse(boxes))
|
Ok(ContentBoxesResponse(boxes))
|
||||||
}
|
}
|
||||||
|
_ => Err(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
reply_chan.send(response)
|
reply_chan.send(response)
|
||||||
}
|
}
|
||||||
HitTestQuery(node, point, reply_chan) => {
|
HitTestQuery(_, point, reply_chan) => {
|
||||||
// FIXME: Isolate this transmutation into a single "bridge" module.
|
let response = {
|
||||||
let node: AbstractNode<LayoutView> = unsafe {
|
match self.display_list {
|
||||||
transmute(node)
|
Some(ref list) => {
|
||||||
};
|
let display_list = list.get();
|
||||||
let mut flow_node: AbstractNode<LayoutView> = node;
|
let (x, y) = (Au::from_frac_px(point.x as float),
|
||||||
for node in node.traverse_preorder() {
|
Au::from_frac_px(point.y as float));
|
||||||
if node.layout_data().flow.is_some() {
|
let mut resp = Err(());
|
||||||
flow_node = node;
|
// iterate in reverse to ensure we have the most recently painted render box
|
||||||
break;
|
for display_item in display_list.list.rev_iter() {
|
||||||
}
|
let bounds = display_item.bounds();
|
||||||
};
|
// TODO this check should really be performed by a method of DisplayItem
|
||||||
|
if x <= bounds.origin.x + bounds.size.width &&
|
||||||
let response = match flow_node.layout_data().flow {
|
bounds.origin.x <= x &&
|
||||||
None => {
|
y < bounds.origin.y + bounds.size.height &&
|
||||||
debug!("HitTestQuery: flow is None");
|
bounds.origin.y < y {
|
||||||
Err(())
|
let node: AbstractNode<LayoutView> = unsafe {
|
||||||
}
|
transmute(display_item.base().extra)
|
||||||
Some(flow) => {
|
};
|
||||||
let layout_ctx = self.build_layout_context();
|
resp = Ok(HitTestResponse(node));
|
||||||
let builder = DisplayListBuilder {
|
break;
|
||||||
ctx: &layout_ctx,
|
}
|
||||||
};
|
|
||||||
let display_list: @Cell<DisplayList<RenderBox>> =
|
|
||||||
@Cell::new(DisplayList::new());
|
|
||||||
|
|
||||||
do flow.partially_traverse_preorder |this_flow| {
|
|
||||||
this_flow.build_display_list(&builder,
|
|
||||||
&flow.position(),
|
|
||||||
display_list)
|
|
||||||
|
|
||||||
}
|
|
||||||
let (x, y) = (Au::from_frac_px(point.x as float),
|
|
||||||
Au::from_frac_px(point.y as float));
|
|
||||||
let mut resp = Err(());
|
|
||||||
let display_list = &display_list.take().list;
|
|
||||||
// iterate in reverse to ensure we have the most recently painted render box
|
|
||||||
for display_item in display_list.rev_iter() {
|
|
||||||
let bounds = display_item.bounds();
|
|
||||||
// TODO this check should really be performed by a method of DisplayItem
|
|
||||||
if x <= bounds.origin.x + bounds.size.width &&
|
|
||||||
bounds.origin.x <= x &&
|
|
||||||
y < bounds.origin.y + bounds.size.height &&
|
|
||||||
bounds.origin.y < y {
|
|
||||||
resp = Ok(HitTestResponse(display_item.base().extra.node()));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
resp
|
||||||
}
|
}
|
||||||
resp
|
None => {
|
||||||
|
error!("Can't hit test: no display list");
|
||||||
|
Err(())
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use layout::layout_task::LayoutTask;
|
||||||
use script::layout_interface::LayoutChan;
|
use script::layout_interface::LayoutChan;
|
||||||
use script::script_task::{ExecuteMsg, LoadMsg};
|
use script::script_task::{ExecuteMsg, LoadMsg};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, SubpageId};
|
||||||
|
use script::dom::node::AbstractNode;
|
||||||
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
|
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
|
||||||
use script::script_task;
|
use script::script_task;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
|
@ -28,7 +29,7 @@ pub struct Pipeline {
|
||||||
subpage_id: Option<SubpageId>,
|
subpage_id: Option<SubpageId>,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
render_chan: RenderChan,
|
render_chan: RenderChan<AbstractNode<()>>,
|
||||||
/// The most recently loaded url
|
/// The most recently loaded url
|
||||||
url: Option<Url>,
|
url: Option<Url>,
|
||||||
}
|
}
|
||||||
|
@ -130,7 +131,7 @@ impl Pipeline {
|
||||||
subpage_id: Option<SubpageId>,
|
subpage_id: Option<SubpageId>,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
render_chan: RenderChan)
|
render_chan: RenderChan<AbstractNode<()>>)
|
||||||
-> Pipeline {
|
-> Pipeline {
|
||||||
Pipeline {
|
Pipeline {
|
||||||
id: id,
|
id: id,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue