mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
servo: Merge #4719 - Update rustc to 00b112c45a604fa6f4b59af2a40c9deeadfdb7c6/rustc-1.0.0-dev (from servo:rustup_20150109); r=jdm
Source-Repo: https://github.com/servo/servo Source-Revision: 3f9012864a2cd927cf17a8e11dfa6922add1b7df
This commit is contained in:
parent
9b3f8fdb5e
commit
78741af324
@ -1 +1 @@
|
||||
2014-12-18
|
||||
2015-01-09
|
||||
|
@ -9,9 +9,9 @@ use geom::size::Size2D;
|
||||
use servo_util::task::spawn_named;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::comm;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum CanvasMsg {
|
||||
FillRect(Rect<f32>),
|
||||
ClearRect(Rect<f32>),
|
||||
@ -39,12 +39,12 @@ impl CanvasPaintTask {
|
||||
}
|
||||
|
||||
pub fn start(size: Size2D<i32>) -> Sender<CanvasMsg> {
|
||||
let (chan, port) = comm::channel::<CanvasMsg>();
|
||||
spawn_named("CanvasTask".to_owned(), proc() {
|
||||
let (chan, port) = channel::<CanvasMsg>();
|
||||
spawn_named("CanvasTask".to_owned(), move || {
|
||||
let mut painter = CanvasPaintTask::new(size);
|
||||
|
||||
loop {
|
||||
match port.recv() {
|
||||
match port.recv().unwrap() {
|
||||
CanvasMsg::FillRect(ref rect) => painter.fill_rect(rect),
|
||||
CanvasMsg::StrokeRect(ref rect) => painter.stroke_rect(rect),
|
||||
CanvasMsg::ClearRect(ref rect) => painter.clear_rect(rect),
|
||||
@ -81,7 +81,7 @@ impl CanvasPaintTask {
|
||||
|
||||
fn send_pixel_contents(&mut self, chan: Sender<Vec<u8>>) {
|
||||
self.drawtarget.snapshot().get_data_surface().with_data(|element| {
|
||||
chan.send(element.to_vec());
|
||||
chan.send(element.to_vec()).unwrap();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -43,9 +43,6 @@ git = "https://github.com/servo/rust-layers"
|
||||
[dependencies.png]
|
||||
git = "https://github.com/servo/rust-png"
|
||||
|
||||
[dependencies.url]
|
||||
git = "https://github.com/servo/rust-url"
|
||||
|
||||
[dependencies.core_graphics]
|
||||
git = "https://github.com/servo/rust-core-graphics"
|
||||
|
||||
@ -55,5 +52,6 @@ git = "https://github.com/servo/rust-core-text"
|
||||
[dependencies.gleam]
|
||||
git = "https://github.com/servo/gleam"
|
||||
|
||||
[dependencies.time]
|
||||
git = "https://github.com/rust-lang/time"
|
||||
[dependencies]
|
||||
url = "*"
|
||||
time = "*"
|
@ -41,11 +41,12 @@ use servo_util::opts;
|
||||
use servo_util::time::{TimeProfilerCategory, profile, TimeProfilerChan};
|
||||
use servo_util::{memory, time};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::{Occupied, Vacant};
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::path::Path;
|
||||
use std::num::FloatMath;
|
||||
use std::num::Float;
|
||||
use std::rc::Rc;
|
||||
use std::slice::bytes::copy_memory;
|
||||
use std::sync::mpsc::Sender;
|
||||
use time::{precise_time_ns, precise_time_s};
|
||||
use url::Url;
|
||||
|
||||
@ -71,7 +72,7 @@ pub struct IOCompositor<Window: WindowMethods> {
|
||||
scene: Scene<CompositorData>,
|
||||
|
||||
/// The application window size.
|
||||
window_size: TypedSize2D<DevicePixel, uint>,
|
||||
window_size: TypedSize2D<DevicePixel, u32>,
|
||||
|
||||
/// "Mobile-style" zoom that does not reflow the page.
|
||||
viewport_zoom: ScaleFactor<PagePx, ViewportPx, f32>,
|
||||
@ -134,14 +135,14 @@ pub struct ScrollEvent {
|
||||
cursor: TypedPoint2D<DevicePixel,i32>,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
#[derive(PartialEq)]
|
||||
enum CompositionRequest {
|
||||
NoCompositingNecessary,
|
||||
CompositeOnScrollTimeout(u64),
|
||||
CompositeNow,
|
||||
}
|
||||
|
||||
#[deriving(Copy, PartialEq, Show)]
|
||||
#[derive(Copy, PartialEq, Show)]
|
||||
enum ShutdownState {
|
||||
NotShuttingDown,
|
||||
ShuttingDown,
|
||||
@ -250,8 +251,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
(Msg::Exit(chan), _) => {
|
||||
debug!("shutting down the constellation");
|
||||
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
||||
con_chan.send(ConstellationMsg::Exit);
|
||||
chan.send(());
|
||||
con_chan.send(ConstellationMsg::Exit).unwrap();
|
||||
chan.send(()).unwrap();
|
||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
||||
}
|
||||
|
||||
@ -292,13 +293,13 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
(Msg::ChangeLayerPipelineAndRemoveChildren(old_pipeline, new_pipeline, response_channel),
|
||||
ShutdownState::NotShuttingDown) => {
|
||||
self.handle_change_layer_pipeline_and_remove_children(old_pipeline, new_pipeline);
|
||||
response_channel.send(());
|
||||
response_channel.send(()).unwrap();
|
||||
}
|
||||
|
||||
(Msg::CreateRootLayerForPipeline(parent_pipeline, pipeline, rect, response_channel),
|
||||
ShutdownState::NotShuttingDown) => {
|
||||
self.handle_create_root_layer_for_pipeline(parent_pipeline, pipeline, rect);
|
||||
response_channel.send(());
|
||||
response_channel.send(()).unwrap();
|
||||
}
|
||||
|
||||
(Msg::CreateOrUpdateBaseLayer(layer_properties), ShutdownState::NotShuttingDown) => {
|
||||
@ -311,7 +312,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
}
|
||||
|
||||
(Msg::GetGraphicsMetadata(chan), ShutdownState::NotShuttingDown) => {
|
||||
chan.send(Some(self.window.native_metadata()));
|
||||
chan.send(Some(self.window.native_metadata())).unwrap();
|
||||
}
|
||||
|
||||
(Msg::SetLayerOrigin(pipeline_id, layer_id, origin),
|
||||
@ -419,12 +420,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
Some(ref details) => {
|
||||
match details.pipeline {
|
||||
Some(ref pipeline) => pipeline,
|
||||
None => panic!("Compositor layer has an unitialized pipeline ({}).",
|
||||
None => panic!("Compositor layer has an unitialized pipeline ({:?}).",
|
||||
pipeline_id),
|
||||
|
||||
}
|
||||
}
|
||||
None => panic!("Compositor layer has an unknown pipeline ({}).", pipeline_id),
|
||||
None => panic!("Compositor layer has an unknown pipeline ({:?}).", pipeline_id),
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,7 +460,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
if !self.has_paint_msg_tracking() {
|
||||
return;
|
||||
}
|
||||
debug!("add_outstanding_paint_msg {}", self.outstanding_paint_msgs);
|
||||
debug!("add_outstanding_paint_msg {:?}", self.outstanding_paint_msgs);
|
||||
self.outstanding_paint_msgs += count;
|
||||
}
|
||||
|
||||
@ -478,7 +479,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
frame_tree: &SendableFrameTree,
|
||||
response_chan: Sender<()>,
|
||||
new_constellation_chan: ConstellationChan) {
|
||||
response_chan.send(());
|
||||
response_chan.send(()).unwrap();
|
||||
|
||||
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
||||
|
||||
@ -546,7 +547,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
let root_layer = match self.find_pipeline_root_layer(old_pipeline.id) {
|
||||
Some(root_layer) => root_layer,
|
||||
None => {
|
||||
debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message for pipeline ({}) shutting down.",
|
||||
debug!("Ignoring ChangeLayerPipelineAndRemoveChildren message \
|
||||
for pipeline ({:?}) shutting down.",
|
||||
old_pipeline.id);
|
||||
return;
|
||||
}
|
||||
@ -581,7 +583,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
let parent_layer = match self.find_pipeline_root_layer(pipeline_id) {
|
||||
Some(root_layer) => root_layer,
|
||||
None => {
|
||||
debug!("Ignoring FrameTreeUpdate message for pipeline ({}) shutting down.",
|
||||
debug!("Ignoring FrameTreeUpdate message for pipeline ({:?}) \
|
||||
shutting down.",
|
||||
pipeline_id);
|
||||
return;
|
||||
}
|
||||
@ -611,7 +614,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
let root_layer = match self.find_pipeline_root_layer(pipeline_id) {
|
||||
Some(root_layer) => root_layer,
|
||||
None => {
|
||||
debug!("Ignoring CreateOrUpdateBaseLayer message for pipeline ({}) shutting down.",
|
||||
debug!("Ignoring CreateOrUpdateBaseLayer message for pipeline \
|
||||
({:?}) shutting down.",
|
||||
pipeline_id);
|
||||
return;
|
||||
}
|
||||
@ -669,7 +673,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
device_pixel_ratio: dppx,
|
||||
initial_viewport: initial_viewport,
|
||||
visible_viewport: visible_viewport,
|
||||
}));
|
||||
})).unwrap()
|
||||
}
|
||||
|
||||
pub fn move_layer(&self,
|
||||
@ -723,7 +727,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
Some(ref layer) => {
|
||||
layer.bounds.borrow_mut().origin = Point2D::from_untyped(&new_origin)
|
||||
}
|
||||
None => panic!("Compositor received SetLayerOrigin for nonexistent layer: {}", pipeline_id),
|
||||
None => panic!("Compositor received SetLayerOrigin for nonexistent \
|
||||
layer: {:?}", pipeline_id),
|
||||
};
|
||||
|
||||
self.send_buffer_requests_for_all_layers();
|
||||
@ -744,14 +749,14 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
|
||||
let pipeline = self.get_pipeline(pipeline_id);
|
||||
let message = PaintMsg::UnusedBuffer(new_layer_buffer_set.buffers);
|
||||
let _ = pipeline.paint_chan.send_opt(message);
|
||||
let _ = pipeline.paint_chan.send(message);
|
||||
}
|
||||
|
||||
fn assign_painted_buffers_to_layer(&mut self,
|
||||
layer: Rc<Layer<CompositorData>>,
|
||||
new_layer_buffer_set: Box<LayerBufferSet>,
|
||||
epoch: Epoch) {
|
||||
debug!("compositor received new frame at size {}x{}",
|
||||
debug!("compositor received new frame at size {:?}x{:?}",
|
||||
self.window_size.width.get(),
|
||||
self.window_size.height.get());
|
||||
|
||||
@ -829,14 +834,14 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
WindowEvent::Quit => {
|
||||
debug!("shutting down the constellation for WindowEvent::Quit");
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ConstellationMsg::Exit);
|
||||
chan.send(ConstellationMsg::Exit).unwrap();
|
||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, uint>) {
|
||||
debug!("compositor resizing to {}", new_size.to_untyped());
|
||||
fn on_resize_window_event(&mut self, new_size: TypedSize2D<DevicePixel, u32>) {
|
||||
debug!("compositor resizing to {:?}", new_size.to_untyped());
|
||||
|
||||
// A size change could also mean a resolution change.
|
||||
let new_hidpi_factor = self.window.hidpi_factor();
|
||||
@ -867,7 +872,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
let msg = ConstellationMsg::LoadUrl(root_pipeline_id,
|
||||
LoadData::new(Url::parse(url_string.as_slice()).unwrap()));
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(msg);
|
||||
chan.send(msg).unwrap()
|
||||
}
|
||||
|
||||
fn on_mouse_window_event_class(&self, mouse_window_event: MouseWindowEvent) {
|
||||
@ -986,12 +991,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
windowing::WindowNavigateMsg::Back => NavigationDirection::Back,
|
||||
};
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ConstellationMsg::Navigate(direction))
|
||||
chan.send(ConstellationMsg::Navigate(direction)).unwrap()
|
||||
}
|
||||
|
||||
fn on_key_event(&self, key: Key, state: KeyState, modifiers: KeyModifiers) {
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ConstellationMsg::KeyEvent(key, state, modifiers))
|
||||
chan.send(ConstellationMsg::KeyEvent(key, state, modifiers)).unwrap()
|
||||
}
|
||||
|
||||
fn convert_buffer_requests_to_pipeline_requests_map(&self,
|
||||
@ -1008,7 +1013,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
entry.into_mut()
|
||||
}
|
||||
Vacant(entry) => {
|
||||
entry.set(Vec::new())
|
||||
entry.insert(Vec::new())
|
||||
}
|
||||
};
|
||||
|
||||
@ -1035,7 +1040,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
let unused_buffers = self.scene.collect_unused_buffers();
|
||||
if unused_buffers.len() != 0 {
|
||||
let message = PaintMsg::UnusedBuffer(unused_buffers);
|
||||
let _ = pipeline.paint_chan.send_opt(message);
|
||||
let _ = pipeline.paint_chan.send(message);
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
@ -1048,7 +1053,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
layer.bounds.borrow().size.to_untyped());
|
||||
let pipeline = self.get_pipeline(layer.get_pipeline_id());
|
||||
let ScriptControlChan(ref chan) = pipeline.script_chan;
|
||||
chan.send(ConstellationControlMsg::Viewport(pipeline.id.clone(), layer_rect));
|
||||
chan.send(ConstellationControlMsg::Viewport(pipeline.id.clone(), layer_rect)).unwrap();
|
||||
}
|
||||
|
||||
for kid in layer.children().iter() {
|
||||
@ -1084,7 +1089,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
let mut num_paint_msgs_sent = 0;
|
||||
for (pipeline_id, requests) in pipeline_requests.into_iter() {
|
||||
num_paint_msgs_sent += 1;
|
||||
let _ = self.get_pipeline(pipeline_id).paint_chan.send_opt(PaintMsg::Paint(requests));
|
||||
let _ = self.get_pipeline(pipeline_id).paint_chan.send(PaintMsg::Paint(requests));
|
||||
}
|
||||
|
||||
self.add_outstanding_paint_msg(num_paint_msgs_sent);
|
||||
@ -1125,7 +1130,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
|
||||
let mut framebuffer_ids = vec!();
|
||||
let mut texture_ids = vec!();
|
||||
let (width, height) = (self.window_size.width.get(), self.window_size.height.get());
|
||||
let (width, height) = (self.window_size.width.get() as usize, self.window_size.height.get() as usize);
|
||||
|
||||
if output_image {
|
||||
framebuffer_ids = gl::gen_framebuffers(1);
|
||||
@ -1169,8 +1174,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
});
|
||||
|
||||
if output_image {
|
||||
let path =
|
||||
from_str::<Path>(opts::get().output_file.as_ref().unwrap().as_slice()).unwrap();
|
||||
let path: Path =
|
||||
opts::get().output_file.as_ref().unwrap().as_slice().parse().unwrap();
|
||||
let mut pixels = gl::read_pixels(0, 0,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei,
|
||||
@ -1201,7 +1206,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
||||
|
||||
debug!("shutting down the constellation after generating an output file");
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ConstellationMsg::Exit);
|
||||
chan.send(ConstellationMsg::Exit).unwrap();
|
||||
self.shutdown_state = ShutdownState::ShuttingDown;
|
||||
}
|
||||
|
||||
@ -1393,10 +1398,10 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
|
||||
|
||||
// Tell the profiler, memory profiler, and scrolling timer to shut down.
|
||||
let TimeProfilerChan(ref time_profiler_chan) = self.time_profiler_chan;
|
||||
time_profiler_chan.send(time::TimeProfilerMsg::Exit);
|
||||
time_profiler_chan.send(time::TimeProfilerMsg::Exit).unwrap();
|
||||
|
||||
let MemoryProfilerChan(ref memory_profiler_chan) = self.memory_profiler_chan;
|
||||
memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit);
|
||||
memory_profiler_chan.send(memory::MemoryProfilerMsg::Exit).unwrap();
|
||||
|
||||
self.scrolling_timer.shutdown();
|
||||
}
|
||||
@ -1411,6 +1416,6 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
|
||||
Some(ref root_pipeline) => root_pipeline.id,
|
||||
};
|
||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||
chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id));
|
||||
chan.send(ConstellationMsg::GetPipelineTitle(root_pipeline_id)).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ use script_traits::{ScriptControlChan, ConstellationControlMsg};
|
||||
use servo_msg::compositor_msg::{Epoch, LayerId, ScrollPolicy};
|
||||
use servo_msg::constellation_msg::PipelineId;
|
||||
use std::num::Float;
|
||||
use std::num::FloatMath;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct CompositorData {
|
||||
@ -68,24 +67,25 @@ impl CompositorData {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CompositorLayer<Window: WindowMethods> {
|
||||
pub trait CompositorLayer {
|
||||
fn update_layer_except_bounds(&self, layer_properties: LayerProperties);
|
||||
|
||||
fn update_layer(&self, layer_properties: LayerProperties);
|
||||
|
||||
fn add_buffers(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
new_buffers: Box<LayerBufferSet>,
|
||||
epoch: Epoch)
|
||||
-> bool;
|
||||
fn add_buffers<Window>(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
new_buffers: Box<LayerBufferSet>,
|
||||
epoch: Epoch)
|
||||
-> bool
|
||||
where Window: WindowMethods;
|
||||
|
||||
/// Destroys all layer tiles, sending the buffers back to the painter to be destroyed or
|
||||
/// reused.
|
||||
fn clear(&self, compositor: &IOCompositor<Window>);
|
||||
fn clear<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods;
|
||||
|
||||
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
|
||||
/// painter to be destroyed or reused.
|
||||
fn clear_all_tiles(&self, compositor: &IOCompositor<Window>);
|
||||
fn clear_all_tiles<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods;
|
||||
|
||||
/// Destroys all tiles of all layers, including children, *without* sending them back to the
|
||||
/// painter. You must call this only when the paint task is destined to be going down;
|
||||
@ -107,14 +107,16 @@ pub trait CompositorLayer<Window: WindowMethods> {
|
||||
// Takes in a MouseWindowEvent, determines if it should be passed to children, and
|
||||
// sends the event off to the appropriate pipeline. NB: the cursor position is in
|
||||
// page coordinates.
|
||||
fn send_mouse_event(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
event: MouseWindowEvent,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>);
|
||||
fn send_mouse_event<Window>(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
event: MouseWindowEvent,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>)
|
||||
where Window: WindowMethods;
|
||||
|
||||
fn send_mouse_move_event(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>);
|
||||
fn send_mouse_move_event<Window>(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>)
|
||||
where Window: WindowMethods;
|
||||
|
||||
fn clamp_scroll_offset_and_scroll_layer(&self,
|
||||
new_offset: TypedPoint2D<LayerPixel, f32>)
|
||||
@ -131,7 +133,7 @@ pub trait CompositorLayer<Window: WindowMethods> {
|
||||
fn get_pipeline_id(&self) -> PipelineId;
|
||||
}
|
||||
|
||||
#[deriving(Copy, PartialEq, Clone)]
|
||||
#[derive(Copy, PartialEq, Clone)]
|
||||
pub enum WantsScrollEventsFlag {
|
||||
WantsScrollEvents,
|
||||
DoesntWantScrollEvents,
|
||||
@ -167,14 +169,14 @@ fn calculate_content_size_for_layer(layer: &Layer<CompositorData>)
|
||||
}).size
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
#[derive(PartialEq)]
|
||||
pub enum ScrollEventResult {
|
||||
ScrollEventUnhandled,
|
||||
ScrollPositionChanged,
|
||||
ScrollPositionUnchanged,
|
||||
}
|
||||
|
||||
impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
|
||||
impl CompositorLayer for Layer<CompositorData> {
|
||||
fn update_layer_except_bounds(&self, layer_properties: LayerProperties) {
|
||||
self.extra_data.borrow_mut().epoch = layer_properties.epoch;
|
||||
self.extra_data.borrow_mut().scroll_policy = layer_properties.scroll_policy;
|
||||
@ -199,18 +201,19 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
|
||||
//
|
||||
// If the epoch of the message does not match the layer's epoch, the message is ignored, the
|
||||
// layer buffer set is consumed, and None is returned.
|
||||
fn add_buffers(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
new_buffers: Box<LayerBufferSet>,
|
||||
epoch: Epoch)
|
||||
-> bool {
|
||||
fn add_buffers<Window>(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
new_buffers: Box<LayerBufferSet>,
|
||||
epoch: Epoch)
|
||||
-> bool
|
||||
where Window: WindowMethods {
|
||||
if self.extra_data.borrow().epoch != epoch {
|
||||
debug!("add_buffers: compositor epoch mismatch: {} != {}, id: {}",
|
||||
debug!("add_buffers: compositor epoch mismatch: {:?} != {:?}, id: {:?}",
|
||||
self.extra_data.borrow().epoch,
|
||||
epoch,
|
||||
self.get_pipeline_id());
|
||||
let pipeline = compositor.get_pipeline(self.get_pipeline_id());
|
||||
let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(new_buffers.buffers));
|
||||
let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(new_buffers.buffers));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -221,13 +224,13 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
|
||||
let unused_buffers = self.collect_unused_buffers();
|
||||
if !unused_buffers.is_empty() { // send back unused buffers
|
||||
let pipeline = compositor.get_pipeline(self.get_pipeline_id());
|
||||
let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(unused_buffers));
|
||||
let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(unused_buffers));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn clear(&self, compositor: &IOCompositor<Window>) {
|
||||
fn clear<Window>(&self, compositor: &IOCompositor<Window>) where Window: WindowMethods {
|
||||
let mut buffers = self.collect_buffers();
|
||||
|
||||
if !buffers.is_empty() {
|
||||
@ -239,13 +242,15 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
|
||||
}
|
||||
|
||||
let pipeline = compositor.get_pipeline(self.get_pipeline_id());
|
||||
let _ = pipeline.paint_chan.send_opt(PaintMsg::UnusedBuffer(buffers));
|
||||
let _ = pipeline.paint_chan.send(PaintMsg::UnusedBuffer(buffers));
|
||||
}
|
||||
}
|
||||
|
||||
/// Destroys tiles for this layer and all descendent layers, sending the buffers back to the
|
||||
/// painter to be destroyed or reused.
|
||||
fn clear_all_tiles(&self, compositor: &IOCompositor<Window>) {
|
||||
fn clear_all_tiles<Window>(&self,
|
||||
compositor: &IOCompositor<Window>)
|
||||
where Window: WindowMethods {
|
||||
self.clear(compositor);
|
||||
for kid in self.children().iter() {
|
||||
kid.clear_all_tiles(compositor);
|
||||
@ -325,10 +330,11 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
|
||||
}
|
||||
}
|
||||
|
||||
fn send_mouse_event(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
event: MouseWindowEvent,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>) {
|
||||
fn send_mouse_event<Window>(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
event: MouseWindowEvent,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>)
|
||||
where Window: WindowMethods {
|
||||
let event_point = cursor.to_untyped();
|
||||
let message = match event {
|
||||
MouseWindowEvent::Click(button, _) =>
|
||||
@ -341,16 +347,17 @@ impl<Window: WindowMethods> CompositorLayer<Window> for Layer<CompositorData> {
|
||||
|
||||
let pipeline = compositor.get_pipeline(self.get_pipeline_id());
|
||||
let ScriptControlChan(ref chan) = pipeline.script_chan;
|
||||
let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
|
||||
let _ = chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
|
||||
}
|
||||
|
||||
fn send_mouse_move_event(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>) {
|
||||
fn send_mouse_move_event<Window>(&self,
|
||||
compositor: &IOCompositor<Window>,
|
||||
cursor: TypedPoint2D<LayerPixel, f32>)
|
||||
where Window: WindowMethods {
|
||||
let message = MouseMoveEvent(cursor.to_untyped());
|
||||
let pipeline = compositor.get_pipeline(self.get_pipeline_id());
|
||||
let ScriptControlChan(ref chan) = pipeline.script_chan;
|
||||
let _ = chan.send_opt(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
|
||||
let _ = chan.send(ConstellationControlMsg::SendEvent(pipeline.id.clone(), message));
|
||||
}
|
||||
|
||||
fn scroll_layer_and_all_child_layers(&self, new_offset: TypedPoint2D<LayerPixel, f32>)
|
||||
|
@ -26,7 +26,7 @@ use servo_util::cursor::Cursor;
|
||||
use servo_util::geometry::PagePx;
|
||||
use servo_util::memory::MemoryProfilerChan;
|
||||
use servo_util::time::TimeProfilerChan;
|
||||
use std::comm::{channel, Sender, Receiver};
|
||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||
use std::fmt::{Error, Formatter, Show};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -42,7 +42,7 @@ pub trait CompositorProxy : 'static + Send {
|
||||
|
||||
/// The port that the compositor receives messages on. As above, this is a trait supplied by the
|
||||
/// Servo port.
|
||||
pub trait CompositorReceiver for Sized? : 'static {
|
||||
pub trait CompositorReceiver : 'static {
|
||||
/// Receives the next message inbound for the compositor. This must not block.
|
||||
fn try_recv_compositor_msg(&mut self) -> Option<Msg>;
|
||||
/// Synchronously waits for, and returns, the next message inbound for the compositor.
|
||||
@ -58,7 +58,7 @@ impl CompositorReceiver for Receiver<Msg> {
|
||||
}
|
||||
}
|
||||
fn recv_compositor_msg(&mut self) -> Msg {
|
||||
self.recv()
|
||||
self.recv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ impl ScriptListener for Box<CompositorProxy+'static+Send> {
|
||||
fn close(&mut self) {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::Exit(chan));
|
||||
port.recv();
|
||||
port.recv().unwrap();
|
||||
}
|
||||
|
||||
fn dup(&mut self) -> Box<ScriptListener+'static> {
|
||||
@ -98,7 +98,7 @@ impl ScriptListener for Box<CompositorProxy+'static+Send> {
|
||||
}
|
||||
|
||||
/// Information about each layer that the compositor keeps.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct LayerProperties {
|
||||
pub pipeline_id: PipelineId,
|
||||
pub epoch: Epoch,
|
||||
@ -129,7 +129,7 @@ impl PaintListener for Box<CompositorProxy+'static+Send> {
|
||||
fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata> {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::GetGraphicsMetadata(chan));
|
||||
port.recv()
|
||||
port.recv().unwrap()
|
||||
}
|
||||
|
||||
fn assign_painted_buffers(&mut self,
|
||||
|
@ -17,7 +17,7 @@ use libc;
|
||||
use script_traits::{CompositorEvent, ConstellationControlMsg};
|
||||
use script_traits::{ScriptControlChan, ScriptTaskFactory};
|
||||
use servo_msg::compositor_msg::LayerId;
|
||||
use servo_msg::constellation_msg::{mod, ConstellationChan, Failure};
|
||||
use servo_msg::constellation_msg::{self, ConstellationChan, Failure};
|
||||
use servo_msg::constellation_msg::{IFrameSandboxState, NavigationDirection};
|
||||
use servo_msg::constellation_msg::{Key, KeyState, KeyModifiers};
|
||||
use servo_msg::constellation_msg::{LoadData, NavigationType};
|
||||
@ -39,6 +39,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use std::io;
|
||||
use std::mem::replace;
|
||||
use std::rc::Rc;
|
||||
use std::sync::mpsc::{Receiver, channel};
|
||||
use url::Url;
|
||||
|
||||
/// Maintains the pipelines and navigation context and grants permission to composite.
|
||||
@ -91,7 +92,7 @@ pub struct Constellation<LTF, STF> {
|
||||
}
|
||||
|
||||
/// A unique ID used to identify a frame.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct FrameId(u32);
|
||||
|
||||
/// One frame in the hierarchy.
|
||||
@ -125,7 +126,7 @@ impl FrameTree {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
struct ChildFrameTree {
|
||||
frame_tree: Rc<FrameTree>,
|
||||
/// Clipping rect representing the size and position, in page coordinates, of the visible
|
||||
@ -234,7 +235,8 @@ struct FrameTreeIterator {
|
||||
stack: Vec<Rc<FrameTree>>,
|
||||
}
|
||||
|
||||
impl Iterator<Rc<FrameTree>> for FrameTreeIterator {
|
||||
impl Iterator for FrameTreeIterator {
|
||||
type Item = Rc<FrameTree>;
|
||||
fn next(&mut self) -> Option<Rc<FrameTree>> {
|
||||
match self.stack.pop() {
|
||||
Some(next) => {
|
||||
@ -294,7 +296,7 @@ impl NavigationContext {
|
||||
/// Loads a new set of page frames, returning all evicted frame trees
|
||||
fn load(&mut self, frame_tree: Rc<FrameTree>, compositor_proxy: &mut CompositorProxy)
|
||||
-> Vec<Rc<FrameTree>> {
|
||||
debug!("navigating to {}", frame_tree.pipeline.borrow().id);
|
||||
debug!("navigating to {:?}", frame_tree.pipeline.borrow().id);
|
||||
let evicted = replace(&mut self.next, vec!());
|
||||
match self.current.take() {
|
||||
Some(current) => self.previous.push(current),
|
||||
@ -350,7 +352,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
-> ConstellationChan {
|
||||
let (constellation_port, constellation_chan) = ConstellationChan::new();
|
||||
let constellation_chan_clone = constellation_chan.clone();
|
||||
spawn_named("Constellation".to_owned(), proc() {
|
||||
spawn_named("Constellation".to_owned(), move || {
|
||||
let mut constellation: Constellation<LTF, STF> = Constellation {
|
||||
chan: constellation_chan_clone,
|
||||
request_port: constellation_port,
|
||||
@ -380,7 +382,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
|
||||
fn run(&mut self) {
|
||||
loop {
|
||||
let request = self.request_port.recv();
|
||||
let request = self.request_port.recv().unwrap();
|
||||
if !self.handle_request(request) {
|
||||
break;
|
||||
}
|
||||
@ -517,17 +519,17 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
pipeline.exit(PipelineExitType::Complete);
|
||||
}
|
||||
self.image_cache_task.exit();
|
||||
self.resource_task.send(resource_task::ControlMsg::Exit);
|
||||
self.resource_task.send(resource_task::ControlMsg::Exit).unwrap();
|
||||
self.devtools_chan.as_ref().map(|chan| {
|
||||
chan.send(devtools_traits::ServerExitMsg);
|
||||
chan.send(devtools_traits::ServerExitMsg).unwrap();
|
||||
});
|
||||
self.storage_task.send(StorageTaskMsg::Exit);
|
||||
self.storage_task.send(StorageTaskMsg::Exit).unwrap();
|
||||
self.font_cache_task.exit();
|
||||
self.compositor_proxy.send(CompositorMsg::ShutdownComplete);
|
||||
}
|
||||
|
||||
fn handle_failure_msg(&mut self, pipeline_id: PipelineId, subpage_id: Option<SubpageId>) {
|
||||
debug!("handling failure message from pipeline {}, {}", pipeline_id, subpage_id);
|
||||
debug!("handling failure message from pipeline {:?}, {:?}", pipeline_id, subpage_id);
|
||||
|
||||
if opts::get().hard_fail {
|
||||
// It's quite difficult to make Servo exit cleanly if some tasks have failed.
|
||||
@ -604,11 +606,11 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
|
||||
fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId,
|
||||
rect: TypedRect<PagePx, f32>) {
|
||||
debug!("Received frame rect {} from {}, {}", rect, pipeline_id, subpage_id);
|
||||
debug!("Received frame rect {:?} from {:?}, {:?}", rect, pipeline_id, subpage_id);
|
||||
let mut already_sent = HashSet::new();
|
||||
|
||||
// Returns true if a child frame tree's subpage id matches the given subpage id
|
||||
let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| {
|
||||
let subpage_eq = |&:child_frame_tree: & &mut ChildFrameTree| {
|
||||
child_frame_tree.frame_tree.pipeline.borrow().
|
||||
subpage_id.expect("Constellation:
|
||||
child frame does not have a subpage id. This should not be possible.")
|
||||
@ -679,7 +681,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
visible_viewport: rect.size,
|
||||
initial_viewport: rect.size * ScaleFactor(1.0),
|
||||
device_pixel_ratio: device_pixel_ratio,
|
||||
}));
|
||||
})).unwrap();
|
||||
compositor_proxy.send(CompositorMsg::SetLayerOrigin(
|
||||
pipeline.id,
|
||||
LayerId::null(),
|
||||
@ -697,7 +699,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
old_subpage_id: SubpageId) {
|
||||
let existing_tree = match frame_tree.find_with_subpage_id(Some(old_subpage_id)) {
|
||||
Some(existing_tree) => existing_tree.clone(),
|
||||
None => panic!("Tried to update non-existing frame tree with pipeline={} subpage={}",
|
||||
None => panic!("Tried to update non-existing frame tree with pipeline={:?} subpage={:?}",
|
||||
new_pipeline.id,
|
||||
old_subpage_id),
|
||||
};
|
||||
@ -716,7 +718,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
old_pipeline.to_sendable(),
|
||||
new_pipeline.to_sendable(),
|
||||
chan));
|
||||
let _ = port.recv_opt();
|
||||
let _ = port.recv();
|
||||
}
|
||||
|
||||
fn create_or_update_child_pipeline(&mut self,
|
||||
@ -770,10 +772,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
|
||||
// Reuse the script task if the URL is same-origin
|
||||
let script_pipeline = if same_script {
|
||||
debug!("Constellation: loading same-origin iframe at {}", url);
|
||||
debug!("Constellation: loading same-origin iframe at {:?}", url);
|
||||
Some(source_pipeline.clone())
|
||||
} else {
|
||||
debug!("Constellation: loading cross-origin iframe at {}", url);
|
||||
debug!("Constellation: loading cross-origin iframe at {:?}", url);
|
||||
None
|
||||
};
|
||||
|
||||
@ -801,7 +803,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
|
||||
fn handle_load_url_msg(&mut self, source_id: PipelineId, load_data: LoadData) {
|
||||
let url = load_data.url.to_string();
|
||||
debug!("Constellation: received message to load {}", url);
|
||||
debug!("Constellation: received message to load {:?}", url);
|
||||
// Make sure no pending page would be overridden.
|
||||
let source_frame = self.current_frame().as_ref().unwrap().find(source_id).expect(
|
||||
"Constellation: received a LoadUrl message from a pipeline_id associated
|
||||
@ -837,7 +839,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
}
|
||||
|
||||
fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) {
|
||||
debug!("received message to navigate {}", direction);
|
||||
debug!("received message to navigate {:?}", direction);
|
||||
|
||||
// TODO(tkuehn): what is the "critical point" beyond which pending frames
|
||||
// should not be cleared? Currently, the behavior is that forward/back
|
||||
@ -886,7 +888,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
self.current_frame().as_ref().map(|frame| {
|
||||
let ScriptControlChan(ref chan) = frame.pipeline.borrow().script_chan;
|
||||
chan.send(ConstellationControlMsg::SendEvent(
|
||||
frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods)));
|
||||
frame.pipeline.borrow().id, CompositorEvent::KeyEvent(key, state, mods))).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
@ -895,13 +897,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
None => self.compositor_proxy.send(CompositorMsg::ChangePageTitle(pipeline_id, None)),
|
||||
Some(pipeline) => {
|
||||
let ScriptControlChan(ref script_channel) = pipeline.script_chan;
|
||||
script_channel.send(ConstellationControlMsg::GetTitle(pipeline_id));
|
||||
script_channel.send(ConstellationControlMsg::GetTitle(pipeline_id)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_painter_ready_msg(&mut self, pipeline_id: PipelineId) {
|
||||
debug!("Painter {} ready to send paint msg", pipeline_id);
|
||||
debug!("Painter {:?} ready to send paint msg", pipeline_id);
|
||||
// This message could originate from a pipeline in the navigation context or
|
||||
// from a pending frame. The only time that we will grant paint permission is
|
||||
// when the message originates from a pending frame or the current frame.
|
||||
@ -921,7 +923,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
});
|
||||
match pending_index {
|
||||
Some(pending_index) => {
|
||||
let frame_change = self.pending_frames.swap_remove(pending_index).unwrap();
|
||||
let frame_change = self.pending_frames.swap_remove(pending_index);
|
||||
let to_add = frame_change.after.clone();
|
||||
|
||||
// Create the next frame tree that will be given to the compositor
|
||||
@ -935,7 +937,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
// If there are frames to revoke permission from, do so now.
|
||||
match frame_change.before {
|
||||
Some(revoke_id) if self.current_frame().is_some() => {
|
||||
debug!("Constellation: revoking permission from {}", revoke_id);
|
||||
debug!("Constellation: revoking permission from {:?}", revoke_id);
|
||||
let current_frame = self.current_frame().as_ref().unwrap();
|
||||
|
||||
let to_revoke = current_frame.find(revoke_id).expect(
|
||||
@ -952,7 +954,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
let mut flag = false;
|
||||
{
|
||||
if to_add.parent.borrow().is_some() {
|
||||
debug!("Constellation: replacing {} with {} in {}",
|
||||
debug!("Constellation: replacing {:?} with {:?} in {:?}",
|
||||
revoke_id, to_add.pipeline.borrow().id,
|
||||
next_frame_tree.pipeline.borrow().id);
|
||||
flag = true;
|
||||
@ -994,7 +996,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
debug!("constellation sending resize message to active frame");
|
||||
let pipeline = &*frame_tree.pipeline.borrow();;
|
||||
let ScriptControlChan(ref chan) = pipeline.script_chan;
|
||||
let _ = chan.send_opt(ConstellationControlMsg::Resize(pipeline.id, new_size));
|
||||
let _ = chan.send(ConstellationControlMsg::Resize(pipeline.id, new_size));
|
||||
already_seen.insert(pipeline.id);
|
||||
}
|
||||
for frame_tree in self.navigation_context.previous.iter()
|
||||
@ -1003,7 +1005,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
if !already_seen.contains(&pipeline.id) {
|
||||
debug!("constellation sending resize message to inactive frame");
|
||||
let ScriptControlChan(ref chan) = pipeline.script_chan;
|
||||
let _ = chan.send_opt(ConstellationControlMsg::ResizeInactive(pipeline.id, new_size));
|
||||
let _ = chan.send(ConstellationControlMsg::ResizeInactive(pipeline.id, new_size));
|
||||
already_seen.insert(pipeline.id);
|
||||
}
|
||||
}
|
||||
@ -1013,10 +1015,10 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
for change in self.pending_frames.iter() {
|
||||
let frame_tree = &change.after;
|
||||
if frame_tree.parent.borrow().is_none() {
|
||||
debug!("constellation sending resize message to pending outer frame ({})",
|
||||
debug!("constellation sending resize message to pending outer frame ({:?})",
|
||||
frame_tree.pipeline.borrow().id);
|
||||
let ScriptControlChan(ref chan) = frame_tree.pipeline.borrow().script_chan;
|
||||
let _ = chan.send_opt(ConstellationControlMsg::Resize(
|
||||
let _ = chan.send(ConstellationControlMsg::Resize(
|
||||
frame_tree.pipeline.borrow().id, new_size));
|
||||
}
|
||||
}
|
||||
@ -1071,7 +1073,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
self.compositor_proxy.send(CompositorMsg::SetFrameTree(frame_tree.to_sendable(),
|
||||
chan,
|
||||
self.chan.clone()));
|
||||
if port.recv_opt().is_err() {
|
||||
if port.recv().is_err() {
|
||||
debug!("Compositor has discarded SetFrameTree");
|
||||
return; // Our message has been discarded, probably shutting down.
|
||||
}
|
||||
@ -1126,12 +1128,12 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
||||
child.frame_tree.pipeline.borrow().to_sendable(),
|
||||
child.rect,
|
||||
chan));
|
||||
match port.recv_opt() {
|
||||
match port.recv() {
|
||||
Ok(()) => {
|
||||
child.frame_tree.has_compositor_layer.set(true);
|
||||
child.frame_tree.pipeline.borrow().grant_paint_permission();
|
||||
}
|
||||
Err(()) => {} // The message has been discarded, we are probably shutting down.
|
||||
Err(_) => {} // The message has been discarded, we are probably shutting down.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ impl NullCompositor {
|
||||
initial_viewport: TypedSize2D(640_f32, 480_f32),
|
||||
visible_viewport: TypedSize2D(640_f32, 480_f32),
|
||||
device_pixel_ratio: ScaleFactor(1.0),
|
||||
}));
|
||||
})).unwrap();
|
||||
}
|
||||
|
||||
compositor
|
||||
@ -73,8 +73,8 @@ impl CompositorEventListener for NullCompositor {
|
||||
Msg::Exit(chan) => {
|
||||
debug!("shutting down the constellation");
|
||||
let ConstellationChan(ref con_chan) = self.constellation_chan;
|
||||
con_chan.send(ConstellationMsg::Exit);
|
||||
chan.send(());
|
||||
con_chan.send(ConstellationMsg::Exit).unwrap();
|
||||
chan.send(()).unwrap();
|
||||
}
|
||||
|
||||
Msg::ShutdownComplete => {
|
||||
@ -83,19 +83,19 @@ impl CompositorEventListener for NullCompositor {
|
||||
}
|
||||
|
||||
Msg::GetGraphicsMetadata(chan) => {
|
||||
chan.send(None);
|
||||
chan.send(None).unwrap();
|
||||
}
|
||||
|
||||
Msg::SetFrameTree(_, response_chan, _) => {
|
||||
response_chan.send(());
|
||||
response_chan.send(()).unwrap();
|
||||
}
|
||||
|
||||
Msg::ChangeLayerPipelineAndRemoveChildren(_, _, response_channel) => {
|
||||
response_channel.send(());
|
||||
response_channel.send(()).unwrap();
|
||||
}
|
||||
|
||||
Msg::CreateRootLayerForPipeline(_, _, _, response_channel) => {
|
||||
response_channel.send(());
|
||||
response_channel.send(()).unwrap();
|
||||
}
|
||||
|
||||
// Explicitly list ignored messages so that when we add a new one,
|
||||
|
@ -2,13 +2,15 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![feature(globs, phase, macro_rules)]
|
||||
#![feature(box_syntax, plugin)]
|
||||
#![feature(int_uint)]
|
||||
|
||||
#![deny(unused_imports)]
|
||||
#![deny(unused_variables)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(unstable)]
|
||||
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate azure;
|
||||
@ -21,7 +23,7 @@ extern crate png;
|
||||
extern crate script_traits;
|
||||
extern crate "msg" as servo_msg;
|
||||
extern crate "net" as servo_net;
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate "util" as servo_util;
|
||||
extern crate gleam;
|
||||
|
||||
|
@ -18,6 +18,7 @@ use servo_net::resource_task::ResourceTask;
|
||||
use servo_net::storage_task::StorageTask;
|
||||
use servo_util::time::TimeProfilerChan;
|
||||
use std::rc::Rc;
|
||||
use std::sync::mpsc::{Receiver, channel};
|
||||
|
||||
/// A uniquely-identifiable pipeline of script task, layout task, and paint task.
|
||||
pub struct Pipeline {
|
||||
@ -35,7 +36,7 @@ pub struct Pipeline {
|
||||
}
|
||||
|
||||
/// The subset of the pipeline that is needed for layer composition.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct CompositionPipeline {
|
||||
pub id: PipelineId,
|
||||
pub script_chan: ScriptControlChan,
|
||||
@ -99,7 +100,7 @@ impl Pipeline {
|
||||
};
|
||||
|
||||
let ScriptControlChan(ref chan) = spipe.script_chan;
|
||||
chan.send(ConstellationControlMsg::AttachLayout(new_layout_info));
|
||||
chan.send(ConstellationControlMsg::AttachLayout(new_layout_info)).unwrap();
|
||||
spipe.script_chan.clone()
|
||||
}
|
||||
};
|
||||
@ -161,41 +162,42 @@ impl Pipeline {
|
||||
|
||||
pub fn load(&self) {
|
||||
let ScriptControlChan(ref chan) = self.script_chan;
|
||||
chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone()));
|
||||
chan.send(ConstellationControlMsg::Load(self.id, self.load_data.clone())).unwrap();
|
||||
}
|
||||
|
||||
pub fn grant_paint_permission(&self) {
|
||||
let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionGranted);
|
||||
let _ = self.paint_chan.send(PaintMsg::PaintPermissionGranted);
|
||||
}
|
||||
|
||||
pub fn revoke_paint_permission(&self) {
|
||||
debug!("pipeline revoking paint channel paint permission");
|
||||
let _ = self.paint_chan.send_opt(PaintMsg::PaintPermissionRevoked);
|
||||
let _ = self.paint_chan.send(PaintMsg::PaintPermissionRevoked);
|
||||
}
|
||||
|
||||
pub fn exit(&self, exit_type: PipelineExitType) {
|
||||
debug!("pipeline {} exiting", self.id);
|
||||
debug!("pipeline {:?} exiting", self.id);
|
||||
|
||||
// Script task handles shutting down layout, and layout handles shutting down the painter.
|
||||
// For now, if the script task has failed, we give up on clean shutdown.
|
||||
let ScriptControlChan(ref chan) = self.script_chan;
|
||||
if chan.send_opt(ConstellationControlMsg::ExitPipeline(self.id, exit_type)).is_ok() {
|
||||
if chan.send(ConstellationControlMsg::ExitPipeline(self.id, exit_type)).is_ok() {
|
||||
// Wait until all slave tasks have terminated and run destructors
|
||||
// NOTE: We don't wait for script task as we don't always own it
|
||||
let _ = self.paint_shutdown_port.recv_opt();
|
||||
let _ = self.layout_shutdown_port.recv_opt();
|
||||
let _ = self.paint_shutdown_port.recv();
|
||||
let _ = self.layout_shutdown_port.recv();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn force_exit(&self) {
|
||||
let ScriptControlChan(ref script_channel) = self.script_chan;
|
||||
let _ = script_channel.send_opt(
|
||||
let _ = script_channel.send(
|
||||
ConstellationControlMsg::ExitPipeline(self.id,
|
||||
PipelineExitType::PipelineOnly));
|
||||
let _ = self.paint_chan.send_opt(PaintMsg::Exit(None, PipelineExitType::PipelineOnly));
|
||||
PipelineExitType::PipelineOnly)).unwrap();
|
||||
let _ = self.paint_chan.send(PaintMsg::Exit(None, PipelineExitType::PipelineOnly));
|
||||
let LayoutControlChan(ref layout_channel) = self.layout_chan;
|
||||
let _ = layout_channel.send_opt(LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly));
|
||||
let _ = layout_channel.send(
|
||||
LayoutControlMsg::ExitNowMsg(PipelineExitType::PipelineOnly)).unwrap();
|
||||
}
|
||||
|
||||
pub fn to_sendable(&self) -> CompositionPipeline {
|
||||
|
@ -7,7 +7,8 @@
|
||||
use compositor_task::{CompositorProxy, Msg};
|
||||
|
||||
use std::io::timer;
|
||||
use std::task::TaskBuilder;
|
||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
use std::thread::Builder;
|
||||
use std::time::duration::Duration;
|
||||
use time;
|
||||
|
||||
@ -33,7 +34,7 @@ enum ToScrollingTimerMsg {
|
||||
impl ScrollingTimerProxy {
|
||||
pub fn new(compositor_proxy: Box<CompositorProxy+Send>) -> ScrollingTimerProxy {
|
||||
let (to_scrolling_timer_sender, to_scrolling_timer_receiver) = channel();
|
||||
TaskBuilder::new().spawn(proc() {
|
||||
Builder::new().spawn(move || {
|
||||
let mut scrolling_timer = ScrollingTimer {
|
||||
compositor_proxy: compositor_proxy,
|
||||
receiver: to_scrolling_timer_receiver,
|
||||
@ -46,18 +47,18 @@ impl ScrollingTimerProxy {
|
||||
}
|
||||
|
||||
pub fn scroll_event_processed(&mut self, timestamp: u64) {
|
||||
self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp))
|
||||
self.sender.send(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)).unwrap()
|
||||
}
|
||||
|
||||
pub fn shutdown(&mut self) {
|
||||
self.sender.send(ToScrollingTimerMsg::ExitMsg);
|
||||
self.sender.send(ToScrollingTimerMsg::ExitMsg).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl ScrollingTimer {
|
||||
pub fn run(&mut self) {
|
||||
loop {
|
||||
match self.receiver.recv_opt() {
|
||||
match self.receiver.recv() {
|
||||
Ok(ToScrollingTimerMsg::ScrollEventProcessedMsg(timestamp)) => {
|
||||
let target = timestamp as i64 + TIMEOUT;
|
||||
let delta = target - (time::precise_time_ns() as i64);
|
||||
|
@ -18,21 +18,21 @@ use servo_util::geometry::ScreenPx;
|
||||
use std::fmt::{Error, Formatter, Show};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum MouseWindowEvent {
|
||||
Click(uint, TypedPoint2D<DevicePixel, f32>),
|
||||
MouseDown(uint, TypedPoint2D<DevicePixel, f32>),
|
||||
MouseUp(uint, TypedPoint2D<DevicePixel, f32>),
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum WindowNavigateMsg {
|
||||
Forward,
|
||||
Back,
|
||||
}
|
||||
|
||||
/// Events that the windowing system sends to Servo.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum WindowEvent {
|
||||
/// Sent when no message has arrived, but the event loop was kicked for some reason (perhaps
|
||||
/// by another Servo subsystem).
|
||||
@ -48,7 +48,7 @@ pub enum WindowEvent {
|
||||
/// context when this message is sent.
|
||||
InitializeCompositing,
|
||||
/// Sent when the window is resized.
|
||||
Resize(TypedSize2D<DevicePixel, uint>),
|
||||
Resize(TypedSize2D<DevicePixel, u32>),
|
||||
/// Sent when a new URL is to be loaded.
|
||||
LoadUrl(String),
|
||||
/// Sent when a mouse hit test is to be performed.
|
||||
@ -92,7 +92,7 @@ impl Show for WindowEvent {
|
||||
|
||||
pub trait WindowMethods {
|
||||
/// Returns the size of the window in hardware pixels.
|
||||
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, uint>;
|
||||
fn framebuffer_size(&self) -> TypedSize2D<DevicePixel, u32>;
|
||||
/// Returns the size of the window in density-independent "px" units.
|
||||
fn size(&self) -> TypedSize2D<ScreenPx, f32>;
|
||||
/// Presents the window to the screen (perhaps by page flipping).
|
||||
|
@ -4,13 +4,11 @@
|
||||
|
||||
/// General actor system infrastructure.
|
||||
|
||||
use std::any::{Any, AnyRefExt, AnyMutRefExt};
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::intrinsics::TypeId;
|
||||
use std::io::TcpStream;
|
||||
use std::mem::{transmute, transmute_copy, replace};
|
||||
use std::raw::TraitObject;
|
||||
use std::mem::replace;
|
||||
use serialize::json;
|
||||
|
||||
/// A common trait for all devtools actors that encompasses an immutable name
|
||||
@ -25,46 +23,6 @@ pub trait Actor : Any {
|
||||
fn name(&self) -> String;
|
||||
}
|
||||
|
||||
impl<'a> AnyMutRefExt<'a> for &'a mut (Actor + 'a) {
|
||||
fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
// Get the raw representation of the trait object
|
||||
let to: TraitObject = transmute_copy(&self);
|
||||
|
||||
// Extract the data pointer
|
||||
Some(transmute(to.data))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AnyRefExt<'a> for &'a (Actor + 'a) {
|
||||
fn is<T: 'static>(self) -> bool {
|
||||
// This implementation is only needed so long as there's a Rust bug that
|
||||
// prevents downcast_ref from giving realistic return values.
|
||||
let t = TypeId::of::<T>();
|
||||
let boxed: TypeId = (*self).get_type_id();
|
||||
t == boxed
|
||||
}
|
||||
|
||||
fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
// Get the raw representation of the trait object
|
||||
let to: TraitObject = transmute_copy(&self);
|
||||
|
||||
// Extract the data pointer
|
||||
Some(transmute(to.data))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of known, owned actors.
|
||||
pub struct ActorRegistry {
|
||||
actors: HashMap<String, Box<Actor+Send+Sized>>,
|
||||
@ -130,20 +88,14 @@ impl ActorRegistry {
|
||||
|
||||
/// Find an actor by registered name
|
||||
pub fn find<'a, T: 'static>(&'a self, name: &str) -> &'a T {
|
||||
//FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
|
||||
// fails for unknown reasons.
|
||||
/*let actor: &Actor+Send+Sized = *self.actors.find(&name.to_string()).unwrap();
|
||||
(actor as &Any).downcast_ref::<T>().unwrap()*/
|
||||
self.actors.get(&name.to_string()).unwrap().downcast_ref::<T>().unwrap()
|
||||
let actor: &Any = self.actors.get(&name.to_string()).unwrap();
|
||||
actor.downcast_ref::<T>().unwrap()
|
||||
}
|
||||
|
||||
/// Find an actor by registered name
|
||||
pub fn find_mut<'a, T: 'static>(&'a mut self, name: &str) -> &'a mut T {
|
||||
//FIXME: Rust bug forces us to implement bogus Any for Actor since downcast_ref currently
|
||||
// fails for unknown reasons.
|
||||
/*let actor: &mut Actor+Send+Sized = *self.actors.find_mut(&name.to_string()).unwrap();
|
||||
(actor as &mut Any).downcast_mut::<T>().unwrap()*/
|
||||
self.actors.get_mut(&name.to_string()).unwrap().downcast_mut::<T>().unwrap()
|
||||
let actor: &mut Any = self.actors.get_mut(&name.to_string()).unwrap();
|
||||
actor.downcast_mut::<T>().unwrap()
|
||||
}
|
||||
|
||||
/// Attempt to process a message as directed by its `to` property. If the actor is not
|
||||
|
@ -13,18 +13,19 @@ use devtools_traits::{EvaluateJS, NullValue, VoidValue, NumberValue, StringValue
|
||||
use devtools_traits::{ActorValue, DevtoolScriptControlMsg};
|
||||
use servo_msg::constellation_msg::PipelineId;
|
||||
|
||||
use collections::TreeMap;
|
||||
use collections::BTreeMap;
|
||||
use core::cell::RefCell;
|
||||
use serialize::json::{mod, Json, ToJson};
|
||||
use std::io::TcpStream;
|
||||
use std::num::Float;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct StartedListenersTraits {
|
||||
customNetworkRequest: bool,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct StartedListenersReply {
|
||||
from: String,
|
||||
nativeConsoleAPI: bool,
|
||||
@ -32,13 +33,13 @@ struct StartedListenersReply {
|
||||
traits: StartedListenersTraits,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[allow(dead_code)]
|
||||
struct ConsoleAPIMessage {
|
||||
_type: String, //FIXME: should this be __type__ instead?
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[allow(dead_code)]
|
||||
struct PageErrorMessage {
|
||||
_type: String, //FIXME: should this be __type__ instead?
|
||||
@ -56,7 +57,7 @@ struct PageErrorMessage {
|
||||
private: bool,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[allow(dead_code)]
|
||||
struct LogMessage {
|
||||
_type: String, //FIXME: should this be __type__ instead?
|
||||
@ -64,7 +65,7 @@ struct LogMessage {
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[allow(dead_code)]
|
||||
enum ConsoleMessageType {
|
||||
ConsoleAPIType(ConsoleAPIMessage),
|
||||
@ -72,26 +73,26 @@ enum ConsoleMessageType {
|
||||
LogMessageType(LogMessage),
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetCachedMessagesReply {
|
||||
from: String,
|
||||
messages: Vec<json::Object>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct StopListenersReply {
|
||||
from: String,
|
||||
stoppedListeners: Vec<String>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct AutocompleteReply {
|
||||
from: String,
|
||||
matches: Vec<String>,
|
||||
matchProp: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct EvaluateJSReply {
|
||||
from: String,
|
||||
input: String,
|
||||
@ -220,28 +221,28 @@ impl Actor for ConsoleActor {
|
||||
"evaluateJS" => {
|
||||
let input = msg.get(&"text".to_string()).unwrap().as_string().unwrap().to_string();
|
||||
let (chan, port) = channel();
|
||||
self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan));
|
||||
self.script_chan.send(EvaluateJS(self.pipeline, input.clone(), chan)).unwrap();
|
||||
|
||||
//TODO: extract conversion into protocol module or some other useful place
|
||||
let result = match try!(port.recv_opt()) {
|
||||
let result = match try!(port.recv().map_err(|_| ())) {
|
||||
VoidValue => {
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
m.insert("type".to_string(), "undefined".to_string().to_json());
|
||||
Json::Object(m)
|
||||
}
|
||||
NullValue => {
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
m.insert("type".to_string(), "null".to_string().to_json());
|
||||
Json::Object(m)
|
||||
}
|
||||
BooleanValue(val) => val.to_json(),
|
||||
NumberValue(val) => {
|
||||
if val.is_nan() {
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
m.insert("type".to_string(), "NaN".to_string().to_json());
|
||||
Json::Object(m)
|
||||
} else if val.is_infinite() {
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
if val < 0. {
|
||||
m.insert("type".to_string(), "-Infinity".to_string().to_json());
|
||||
} else {
|
||||
@ -249,7 +250,7 @@ impl Actor for ConsoleActor {
|
||||
}
|
||||
Json::Object(m)
|
||||
} else if val == Float::neg_zero() {
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
m.insert("type".to_string(), "-0".to_string().to_json());
|
||||
Json::Object(m)
|
||||
} else {
|
||||
@ -259,7 +260,7 @@ impl Actor for ConsoleActor {
|
||||
StringValue(s) => s.to_json(),
|
||||
ActorValue(s) => {
|
||||
//TODO: make initial ActorValue message include these properties.
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
m.insert("type".to_string(), "object".to_string().to_json());
|
||||
m.insert("class".to_string(), "???".to_string().to_json());
|
||||
m.insert("actor".to_string(), s.to_json());
|
||||
@ -276,9 +277,9 @@ impl Actor for ConsoleActor {
|
||||
input: input,
|
||||
result: result,
|
||||
timestamp: 0,
|
||||
exception: Json::Object(TreeMap::new()),
|
||||
exception: Json::Object(BTreeMap::new()),
|
||||
exceptionMessage: "".to_string(),
|
||||
helperResult: Json::Object(TreeMap::new()),
|
||||
helperResult: Json::Object(BTreeMap::new()),
|
||||
};
|
||||
stream.write_json_packet(&msg);
|
||||
true
|
||||
|
@ -10,11 +10,12 @@ use devtools_traits::{GetLayout, NodeInfo, ModifyAttribute};
|
||||
use actor::{Actor, ActorRegistry};
|
||||
use protocol::JsonPacketStream;
|
||||
|
||||
use collections::TreeMap;
|
||||
use collections::BTreeMap;
|
||||
use servo_msg::constellation_msg::PipelineId;
|
||||
use serialize::json::{mod, Json, ToJson};
|
||||
use std::cell::RefCell;
|
||||
use std::io::TcpStream;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
use std::num::Float;
|
||||
|
||||
pub struct InspectorActor {
|
||||
@ -26,13 +27,13 @@ pub struct InspectorActor {
|
||||
pub pipeline: PipelineId,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetHighlighterReply {
|
||||
highligter: HighlighterMsg, // sic.
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct HighlighterMsg {
|
||||
actor: String,
|
||||
}
|
||||
@ -47,12 +48,12 @@ pub struct NodeActor {
|
||||
pipeline: PipelineId,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ShowBoxModelReply {
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct HideBoxModelReply {
|
||||
from: String,
|
||||
}
|
||||
@ -89,7 +90,7 @@ impl Actor for HighlighterActor {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ModifyAttributeReply{
|
||||
from: String,
|
||||
}
|
||||
@ -114,7 +115,8 @@ impl Actor for NodeActor {
|
||||
|
||||
self.script_chan.send(ModifyAttribute(self.pipeline,
|
||||
registry.actor_to_script(target.to_string()),
|
||||
modifications));
|
||||
modifications))
|
||||
.unwrap();
|
||||
let reply = ModifyAttributeReply{
|
||||
from: self.name(),
|
||||
};
|
||||
@ -127,26 +129,26 @@ impl Actor for NodeActor {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetWalkerReply {
|
||||
from: String,
|
||||
walker: WalkerMsg,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct WalkerMsg {
|
||||
actor: String,
|
||||
root: NodeActorMsg,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct AttrMsg {
|
||||
namespace: String,
|
||||
name: String,
|
||||
value: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct NodeActorMsg {
|
||||
actor: String,
|
||||
baseURI: String,
|
||||
@ -243,23 +245,23 @@ struct WalkerActor {
|
||||
pipeline: PipelineId,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct QuerySelectorReply {
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct DocumentElementReply {
|
||||
from: String,
|
||||
node: NodeActorMsg,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ClearPseudoclassesReply {
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ChildrenReply {
|
||||
hasFirst: bool,
|
||||
hasLast: bool,
|
||||
@ -288,8 +290,8 @@ impl Actor for WalkerActor {
|
||||
|
||||
"documentElement" => {
|
||||
let (tx, rx) = channel();
|
||||
self.script_chan.send(GetDocumentElement(self.pipeline, tx));
|
||||
let doc_elem_info = rx.recv();
|
||||
self.script_chan.send(GetDocumentElement(self.pipeline, tx)).unwrap();
|
||||
let doc_elem_info = rx.recv().unwrap();
|
||||
let node = doc_elem_info.encode(registry, true, self.script_chan.clone(), self.pipeline);
|
||||
|
||||
let msg = DocumentElementReply {
|
||||
@ -313,8 +315,9 @@ impl Actor for WalkerActor {
|
||||
let (tx, rx) = channel();
|
||||
self.script_chan.send(GetChildren(self.pipeline,
|
||||
registry.actor_to_script(target.to_string()),
|
||||
tx));
|
||||
let children = rx.recv();
|
||||
tx))
|
||||
.unwrap();
|
||||
let children = rx.recv().unwrap();
|
||||
|
||||
let msg = ChildrenReply {
|
||||
hasFirst: true,
|
||||
@ -333,13 +336,13 @@ impl Actor for WalkerActor {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetPageStyleReply {
|
||||
from: String,
|
||||
pageStyle: PageStyleMsg,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct PageStyleMsg {
|
||||
actor: String,
|
||||
}
|
||||
@ -350,7 +353,7 @@ struct PageStyleActor {
|
||||
pipeline: PipelineId,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetAppliedReply {
|
||||
entries: Vec<AppliedEntry>,
|
||||
rules: Vec<AppliedRule>,
|
||||
@ -358,13 +361,13 @@ struct GetAppliedReply {
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetComputedReply {
|
||||
computed: Vec<uint>, //XXX all css props
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct AppliedEntry {
|
||||
rule: String,
|
||||
pseudoElement: Json,
|
||||
@ -372,7 +375,7 @@ struct AppliedEntry {
|
||||
matchedSelectors: Vec<String>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct AppliedRule {
|
||||
actor: String,
|
||||
__type__: uint,
|
||||
@ -383,7 +386,7 @@ struct AppliedRule {
|
||||
parentStyleSheet: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct AppliedSheet {
|
||||
actor: String,
|
||||
href: String,
|
||||
@ -395,7 +398,7 @@ struct AppliedSheet {
|
||||
ruleCount: uint,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct GetLayoutReply {
|
||||
width: int,
|
||||
height: int,
|
||||
@ -403,7 +406,7 @@ struct GetLayoutReply {
|
||||
from: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[allow(dead_code)]
|
||||
struct AutoMargins {
|
||||
top: String,
|
||||
@ -450,9 +453,10 @@ impl Actor for PageStyleActor {
|
||||
let target = msg.get(&"node".to_string()).unwrap().as_string().unwrap();
|
||||
let (tx, rx) = channel();
|
||||
self.script_chan.send(GetLayout(self.pipeline,
|
||||
registry.actor_to_script(target.to_string()),
|
||||
tx));
|
||||
let (width, height) = rx.recv();
|
||||
registry.actor_to_script(target.to_string()),
|
||||
tx))
|
||||
.unwrap();
|
||||
let (width, height) = rx.recv().unwrap();
|
||||
|
||||
let auto_margins = msg.get(&"autoMargins".to_string()).unwrap().as_boolean().unwrap();
|
||||
|
||||
@ -463,7 +467,7 @@ impl Actor for PageStyleActor {
|
||||
height: height.round() as int,
|
||||
autoMargins: if auto_margins {
|
||||
//TODO: real values like processMargins in http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js
|
||||
let mut m = TreeMap::new();
|
||||
let mut m = BTreeMap::new();
|
||||
m.insert("top".to_string(), "auto".to_string().to_json());
|
||||
m.insert("bottom".to_string(), "auto".to_string().to_json());
|
||||
m.insert("left".to_string(), "auto".to_string().to_json());
|
||||
@ -507,8 +511,8 @@ impl Actor for InspectorActor {
|
||||
}
|
||||
|
||||
let (tx, rx) = channel();
|
||||
self.script_chan.send(GetRootNode(self.pipeline, tx));
|
||||
let root_info = rx.recv();
|
||||
self.script_chan.send(GetRootNode(self.pipeline, tx)).unwrap();
|
||||
let root_info = rx.recv().unwrap();
|
||||
|
||||
let node = root_info.encode(registry, false, self.script_chan.clone(), self.pipeline);
|
||||
|
||||
|
@ -13,28 +13,28 @@ use protocol::JsonPacketStream;
|
||||
use serialize::json;
|
||||
use std::io::TcpStream;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ActorTraits {
|
||||
sources: bool,
|
||||
highlightable: bool,
|
||||
customHighlighters: Vec<String>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ErrorReply {
|
||||
from: String,
|
||||
error: String,
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ListTabsReply {
|
||||
from: String,
|
||||
selected: uint,
|
||||
tabs: Vec<TabActorMsg>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct RootActorMsg {
|
||||
from: String,
|
||||
applicationType: String,
|
||||
|
@ -13,10 +13,10 @@ use protocol::JsonPacketStream;
|
||||
use serialize::json;
|
||||
use std::io::TcpStream;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct TabTraits;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct TabAttachedReply {
|
||||
from: String,
|
||||
__type__: String,
|
||||
@ -26,24 +26,24 @@ struct TabAttachedReply {
|
||||
traits: TabTraits,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct TabDetachedReply {
|
||||
from: String,
|
||||
__type__: String,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ReconfigureReply {
|
||||
from: String
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ListFramesReply {
|
||||
from: String,
|
||||
frames: Vec<FrameMsg>,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct FrameMsg {
|
||||
id: uint,
|
||||
url: String,
|
||||
@ -51,7 +51,7 @@ struct FrameMsg {
|
||||
parentID: uint,
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct TabActorMsg {
|
||||
actor: String,
|
||||
title: String,
|
||||
|
@ -10,17 +10,19 @@
|
||||
#![crate_name = "devtools"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#![feature(int_uint, box_syntax)]
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(unstable)]
|
||||
|
||||
#![feature(phase)]
|
||||
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate collections;
|
||||
extern crate core;
|
||||
extern crate devtools_traits;
|
||||
extern crate "serialize" as rustc_serialize;
|
||||
extern crate serialize;
|
||||
extern crate "msg" as servo_msg;
|
||||
extern crate "util" as servo_util;
|
||||
@ -39,8 +41,8 @@ use servo_util::task::spawn_named;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::comm;
|
||||
use std::comm::{Disconnected, Empty};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
|
||||
use std::io::{TcpListener, TcpStream};
|
||||
use std::io::{Acceptor, Listener, TimedOut};
|
||||
use std::sync::{Arc, Mutex};
|
||||
@ -57,8 +59,8 @@ mod protocol;
|
||||
|
||||
/// Spin up a devtools server that listens for connections on the specified port.
|
||||
pub fn start_server(port: u16) -> Sender<DevtoolsControlMsg> {
|
||||
let (sender, receiver) = comm::channel();
|
||||
spawn_named("Devtools".to_owned(), proc() {
|
||||
let (sender, receiver) = channel();
|
||||
spawn_named("Devtools".to_owned(), move || {
|
||||
run_server(receiver, port)
|
||||
});
|
||||
sender
|
||||
@ -92,7 +94,7 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
|
||||
fn handle_client(actors: Arc<Mutex<ActorRegistry>>, mut stream: TcpStream) {
|
||||
println!("connection established to {}", stream.peer_name().unwrap());
|
||||
{
|
||||
let actors = actors.lock();
|
||||
let actors = actors.lock().unwrap();
|
||||
let msg = actors.find::<RootActor>("root").encodable();
|
||||
stream.write_json_packet(&msg);
|
||||
}
|
||||
@ -100,8 +102,9 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
|
||||
'outer: loop {
|
||||
match stream.read_json_packet() {
|
||||
Ok(json_packet) => {
|
||||
match actors.lock().handle_message(json_packet.as_object().unwrap(),
|
||||
&mut stream) {
|
||||
let mut actors = actors.lock().unwrap();
|
||||
match actors.handle_message(json_packet.as_object().unwrap(),
|
||||
&mut stream) {
|
||||
Ok(()) => {},
|
||||
Err(()) => {
|
||||
println!("error: devtools actor stopped responding");
|
||||
@ -127,7 +130,7 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
|
||||
sender: Sender<DevtoolScriptControlMsg>,
|
||||
actor_pipelines: &mut HashMap<PipelineId, String>,
|
||||
page_info: DevtoolsPageInfo) {
|
||||
let mut actors = actors.lock();
|
||||
let mut actors = actors.lock().unwrap();
|
||||
|
||||
//TODO: move all this actor creation into a constructor method on TabActor
|
||||
let (tab, console, inspector) = {
|
||||
@ -185,7 +188,7 @@ fn run_server(receiver: Receiver<DevtoolsControlMsg>, port: u16) {
|
||||
Ok(stream) => {
|
||||
let actors = actors.clone();
|
||||
accepted_connections.push(stream.clone());
|
||||
spawn_named("DevtoolsClientHandler".to_owned(), proc() {
|
||||
spawn_named("DevtoolsClientHandler".to_owned(), move || {
|
||||
// connection succeeded
|
||||
handle_client(actors, stream.clone())
|
||||
})
|
||||
|
@ -12,12 +12,12 @@ use std::io::{IoError, OtherIoError, EndOfFile, TcpStream, IoResult};
|
||||
use std::num;
|
||||
|
||||
pub trait JsonPacketStream {
|
||||
fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T);
|
||||
fn write_json_packet<'a, T: Encodable>(&mut self, obj: &T);
|
||||
fn read_json_packet(&mut self) -> IoResult<Json>;
|
||||
}
|
||||
|
||||
impl JsonPacketStream for TcpStream {
|
||||
fn write_json_packet<'a, T: Encodable<json::Encoder<'a>,IoError>>(&mut self, obj: &T) {
|
||||
fn write_json_packet<'a, T: Encodable>(&mut self, obj: &T) {
|
||||
let s = json::encode(obj).replace("__type__", "type");
|
||||
println!("<- {}", s);
|
||||
self.write_str(s.len().to_string().as_slice()).unwrap();
|
||||
|
@ -9,9 +9,10 @@
|
||||
#![crate_name = "devtools_traits"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#![feature(int_uint)]
|
||||
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![feature(globs)]
|
||||
|
||||
extern crate "msg" as servo_msg;
|
||||
extern crate serialize;
|
||||
@ -27,6 +28,8 @@ use servo_msg::constellation_msg::PipelineId;
|
||||
use servo_util::str::DOMString;
|
||||
use url::Url;
|
||||
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
|
||||
pub type DevtoolsControlChan = Sender<DevtoolsControlMsg>;
|
||||
pub type DevtoolsControlPort = Receiver<DevtoolScriptControlMsg>;
|
||||
|
||||
@ -99,14 +102,14 @@ pub enum ScriptDevtoolControlMsg {
|
||||
ReportConsoleMsg(String),
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(Encodable)]
|
||||
pub struct Modification{
|
||||
pub attributeName: String,
|
||||
pub newValue: Option<String>,
|
||||
}
|
||||
|
||||
impl<D:Decoder<E>, E> Decodable<D, E> for Modification {
|
||||
fn decode(d: &mut D) -> Result<Modification, E> {
|
||||
impl Decodable for Modification {
|
||||
fn decode<D: Decoder>(d: &mut D) -> Result<Modification, D::Error> {
|
||||
d.read_struct("Modification", 2u, |d|
|
||||
Ok(Modification {
|
||||
attributeName: try!(d.read_struct_field("attributeName", 0u, |d| Decodable::decode(d))),
|
||||
|
@ -38,9 +38,6 @@ git = "https://github.com/servo/rust-stb-image"
|
||||
[dependencies.png]
|
||||
git = "https://github.com/servo/rust-png"
|
||||
|
||||
[dependencies.url]
|
||||
git = "https://github.com/servo/rust-url"
|
||||
|
||||
[dependencies.harfbuzz]
|
||||
git = "https://github.com/servo/rust-harfbuzz"
|
||||
|
||||
@ -62,5 +59,6 @@ git = "https://github.com/servo/rust-core-text"
|
||||
[dependencies.script_traits]
|
||||
path = "../script_traits"
|
||||
|
||||
[dependencies.time]
|
||||
git = "https://github.com/rust-lang/time"
|
||||
[dependencies]
|
||||
url = "*"
|
||||
time = "*"
|
@ -3,12 +3,11 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::{Occupied, Vacant};
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use geom::size::Size2D;
|
||||
use layers::platform::surface::NativePaintingGraphicsContext;
|
||||
use layers::layers::LayerBuffer;
|
||||
use std::hash::Hash;
|
||||
use std::hash::sip::SipState;
|
||||
use std::hash::{Hash, Hasher, Writer};
|
||||
use std::mem;
|
||||
|
||||
/// This is a struct used to store buffers when they are not in use.
|
||||
@ -27,11 +26,11 @@ pub struct BufferMap {
|
||||
}
|
||||
|
||||
/// A key with which to store buffers. It is based on the size of the buffer.
|
||||
#[deriving(Eq, Copy)]
|
||||
struct BufferKey([uint, ..2]);
|
||||
#[derive(Eq, Copy)]
|
||||
struct BufferKey([uint; 2]);
|
||||
|
||||
impl Hash for BufferKey {
|
||||
fn hash(&self, state: &mut SipState) {
|
||||
impl<H: Hasher+Writer> Hash<H> for BufferKey {
|
||||
fn hash(&self, state: &mut H) {
|
||||
let BufferKey(ref bytes) = *self;
|
||||
bytes.as_slice().hash(state);
|
||||
}
|
||||
@ -91,7 +90,7 @@ impl BufferMap {
|
||||
entry.into_mut().buffers.push(new_buffer);
|
||||
}
|
||||
Vacant(entry) => {
|
||||
entry.set(BufferValue {
|
||||
entry.insert(BufferValue {
|
||||
buffers: vec!(new_buffer),
|
||||
last_action: *counter,
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ use servo_util::geometry::{mod, Au, MAX_RECT, ZERO_RECT};
|
||||
use servo_util::range::Range;
|
||||
use servo_util::smallvec::{SmallVec, SmallVec8};
|
||||
use std::fmt;
|
||||
use std::slice::Items;
|
||||
use std::slice::Iter;
|
||||
use std::sync::Arc;
|
||||
use style::ComputedValues;
|
||||
use style::computed_values::{border_style, cursor, filter, mix_blend_mode, pointer_events};
|
||||
@ -60,7 +60,7 @@ pub static BOX_SHADOW_INFLATION_FACTOR: i32 = 3;
|
||||
/// Because the script task's GC does not trace layout, node data cannot be safely stored in layout
|
||||
/// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for
|
||||
/// locality reasons. Using `OpaqueNode` enforces this invariant.
|
||||
#[deriving(Clone, PartialEq, Copy)]
|
||||
#[derive(Clone, PartialEq, Copy)]
|
||||
pub struct OpaqueNode(pub uintptr_t);
|
||||
|
||||
impl OpaqueNode {
|
||||
@ -356,7 +356,7 @@ impl StackingContext {
|
||||
result: &mut Vec<DisplayItemMetadata>,
|
||||
topmost_only: bool,
|
||||
mut iterator: I)
|
||||
where I: Iterator<&'a DisplayItem> {
|
||||
where I: Iterator<Item=&'a DisplayItem> {
|
||||
for item in iterator {
|
||||
// TODO(pcwalton): Use a precise algorithm here. This will allow us to properly hit
|
||||
// test elements with `border-radius`, for example.
|
||||
@ -473,7 +473,7 @@ pub fn find_stacking_context_with_layer_id(this: &Arc<StackingContext>, layer_id
|
||||
}
|
||||
|
||||
/// One drawing command in the list.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum DisplayItem {
|
||||
SolidColorClass(Box<SolidColorDisplayItem>),
|
||||
TextClass(Box<TextDisplayItem>),
|
||||
@ -485,7 +485,7 @@ pub enum DisplayItem {
|
||||
}
|
||||
|
||||
/// Information common to all display items.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct BaseDisplayItem {
|
||||
/// The boundaries of the display item, in layer coordinates.
|
||||
pub bounds: Rect<Au>,
|
||||
@ -512,7 +512,7 @@ impl BaseDisplayItem {
|
||||
/// A clipping region for a display item. Currently, this can describe rectangles, rounded
|
||||
/// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms
|
||||
/// are not supported because those are handled by the higher-level `StackingContext` abstraction.
|
||||
#[deriving(Clone, PartialEq, Show)]
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct ClippingRegion {
|
||||
/// The main rectangular region. This does not include any corners.
|
||||
pub main: Rect<Au>,
|
||||
@ -526,7 +526,7 @@ pub struct ClippingRegion {
|
||||
/// A complex clipping region. These don't as easily admit arbitrary intersection operations, so
|
||||
/// they're stored in a list over to the side. Currently a complex clipping region is just a
|
||||
/// rounded rectangle, but the CSS WGs will probably make us throw more stuff in here eventually.
|
||||
#[deriving(Clone, PartialEq, Show)]
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub struct ComplexClippingRegion {
|
||||
/// The boundaries of the rectangle.
|
||||
pub rect: Rect<Au>,
|
||||
@ -637,7 +637,7 @@ impl ClippingRegion {
|
||||
/// Metadata attached to each display item. This is useful for performing auxiliary tasks with
|
||||
/// the display list involving hit testing: finding the originating DOM node and determining the
|
||||
/// cursor to use when the element is hovered over.
|
||||
#[deriving(Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct DisplayItemMetadata {
|
||||
/// The DOM node from which this display item originated.
|
||||
pub node: OpaqueNode,
|
||||
@ -666,14 +666,14 @@ impl DisplayItemMetadata {
|
||||
}
|
||||
|
||||
/// Paints a solid color.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct SolidColorDisplayItem {
|
||||
pub base: BaseDisplayItem,
|
||||
pub color: Color,
|
||||
}
|
||||
|
||||
/// Paints text.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct TextDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
@ -691,7 +691,7 @@ pub struct TextDisplayItem {
|
||||
pub orientation: TextOrientation,
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, PartialEq)]
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub enum TextOrientation {
|
||||
Upright,
|
||||
SidewaysLeft,
|
||||
@ -699,7 +699,7 @@ pub enum TextOrientation {
|
||||
}
|
||||
|
||||
/// Paints an image.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ImageDisplayItem {
|
||||
pub base: BaseDisplayItem,
|
||||
pub image: Arc<Box<Image>>,
|
||||
@ -711,7 +711,7 @@ pub struct ImageDisplayItem {
|
||||
}
|
||||
|
||||
/// Paints a gradient.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct GradientDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
@ -727,7 +727,7 @@ pub struct GradientDisplayItem {
|
||||
}
|
||||
|
||||
/// Paints a border.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct BorderDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
@ -750,7 +750,7 @@ pub struct BorderDisplayItem {
|
||||
/// Information about the border radii.
|
||||
///
|
||||
/// TODO(pcwalton): Elliptical radii.
|
||||
#[deriving(Clone, Default, PartialEq, Show, Copy)]
|
||||
#[derive(Clone, Default, PartialEq, Show, Copy)]
|
||||
pub struct BorderRadii<T> {
|
||||
pub top_left: T,
|
||||
pub top_right: T,
|
||||
@ -768,7 +768,7 @@ impl<T> BorderRadii<T> where T: PartialEq + Zero {
|
||||
}
|
||||
|
||||
/// Paints a line segment.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct LineDisplayItem {
|
||||
pub base: BaseDisplayItem,
|
||||
|
||||
@ -780,7 +780,7 @@ pub struct LineDisplayItem {
|
||||
}
|
||||
|
||||
/// Paints a box shadow per CSS-BACKGROUNDS.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct BoxShadowDisplayItem {
|
||||
/// Fields common to all display items.
|
||||
pub base: BaseDisplayItem,
|
||||
@ -806,10 +806,11 @@ pub struct BoxShadowDisplayItem {
|
||||
|
||||
pub enum DisplayItemIterator<'a> {
|
||||
Empty,
|
||||
Parent(dlist::Items<'a,DisplayItem>),
|
||||
Parent(dlist::Iter<'a,DisplayItem>),
|
||||
}
|
||||
|
||||
impl<'a> Iterator<&'a DisplayItem> for DisplayItemIterator<'a> {
|
||||
impl<'a> Iterator for DisplayItemIterator<'a> {
|
||||
type Item = &'a DisplayItem;
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a DisplayItem> {
|
||||
match *self {
|
||||
@ -836,14 +837,14 @@ impl DisplayItem {
|
||||
}
|
||||
|
||||
DisplayItem::TextClass(ref text) => {
|
||||
debug!("Drawing text at {}.", text.base.bounds);
|
||||
debug!("Drawing text at {:?}.", text.base.bounds);
|
||||
paint_context.draw_text(&**text);
|
||||
}
|
||||
|
||||
DisplayItem::ImageClass(ref image_item) => {
|
||||
// FIXME(pcwalton): This is a really inefficient way to draw a tiled image; use a
|
||||
// brush instead.
|
||||
debug!("Drawing image at {}.", image_item.base.bounds);
|
||||
debug!("Drawing image at {:?}.", image_item.base.bounds);
|
||||
|
||||
let mut y_offset = Au(0);
|
||||
while y_offset < image_item.base.bounds.size.height {
|
||||
@ -926,13 +927,13 @@ impl DisplayItem {
|
||||
for _ in range(0, level) {
|
||||
indent.push_str("| ")
|
||||
}
|
||||
println!("{}+ {}", indent, self);
|
||||
println!("{}+ {:?}", indent, self);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for DisplayItem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} @ {} ({:x})",
|
||||
write!(f, "{} @ {:?} ({:x})",
|
||||
match *self {
|
||||
DisplayItem::SolidColorClass(_) => "SolidColor",
|
||||
DisplayItem::TextClass(_) => "Text",
|
||||
|
@ -44,7 +44,7 @@ impl DisplayListOptimizer {
|
||||
fn add_in_bounds_display_items<'a,I>(&self,
|
||||
result_list: &mut DList<DisplayItem>,
|
||||
mut display_items: I)
|
||||
where I: Iterator<&'a DisplayItem> {
|
||||
where I: Iterator<Item=&'a DisplayItem> {
|
||||
for display_item in display_items {
|
||||
if self.visible_rect.intersects(&display_item.base().bounds) &&
|
||||
display_item.base().clip.might_intersect_rect(&self.visible_rect) {
|
||||
@ -57,7 +57,7 @@ impl DisplayListOptimizer {
|
||||
fn add_in_bounds_stacking_contexts<'a,I>(&self,
|
||||
result_list: &mut DList<Arc<StackingContext>>,
|
||||
mut stacking_contexts: I)
|
||||
where I: Iterator<&'a Arc<StackingContext>> {
|
||||
where I: Iterator<Item=&'a Arc<StackingContext>> {
|
||||
for stacking_context in stacking_contexts {
|
||||
let overflow = stacking_context.overflow.translate(&stacking_context.bounds.origin);
|
||||
if self.visible_rect.intersects(&overflow) {
|
||||
|
@ -9,7 +9,7 @@ use azure::azure_hl::{ColorMatrixAttribute, ColorMatrixInput, CompositeInput, Dr
|
||||
use azure::azure_hl::{FilterNode, FilterType, LinearTransferAttribute, LinearTransferInput};
|
||||
use azure::azure_hl::{Matrix5x4, TableTransferAttribute, TableTransferInput};
|
||||
|
||||
use std::num::FloatMath;
|
||||
use std::num::Float;
|
||||
use style::computed_values::filter;
|
||||
|
||||
/// Creates a filter pipeline from a set of CSS filters. Returns the destination end of the filter
|
||||
|
@ -8,13 +8,13 @@ use std::mem;
|
||||
use std::slice;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use servo_util::cache::{Cache, HashCache};
|
||||
use servo_util::cache::HashCache;
|
||||
use servo_util::smallvec::{SmallVec, SmallVec8};
|
||||
use style::computed_values::{font_variant, font_weight};
|
||||
use style::style_structs::Font as FontStyle;
|
||||
use std::sync::Arc;
|
||||
|
||||
use collections::hash::Hash;
|
||||
use std::hash::Hash;
|
||||
use platform::font_context::FontContextHandle;
|
||||
use platform::font::{FontHandle, FontTable};
|
||||
use servo_util::geometry::Au;
|
||||
@ -66,10 +66,10 @@ impl FontTableTagConversions for FontTableTag {
|
||||
}
|
||||
|
||||
pub trait FontTableMethods {
|
||||
fn with_buffer(&self, |*const u8, uint|);
|
||||
fn with_buffer<F>(&self, F) where F: FnOnce(*const u8, uint);
|
||||
}
|
||||
|
||||
#[deriving(Clone, Show)]
|
||||
#[derive(Clone, Show)]
|
||||
pub struct FontMetrics {
|
||||
pub underline_size: Au,
|
||||
pub underline_offset: Au,
|
||||
@ -101,7 +101,6 @@ pub struct Font {
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[deriving(Copy)]
|
||||
flags ShapingFlags: u8 {
|
||||
#[doc="Set if the text is entirely whitespace."]
|
||||
const IS_WHITESPACE_SHAPING_FLAG = 0x01,
|
||||
@ -113,7 +112,7 @@ bitflags! {
|
||||
}
|
||||
|
||||
/// Various options that control text shaping.
|
||||
#[deriving(Clone, Eq, PartialEq, Hash, Copy)]
|
||||
#[derive(Clone, Eq, PartialEq, Hash, Copy)]
|
||||
pub struct ShapingOptions {
|
||||
/// Spacing to add between each letter. Corresponds to the CSS 2.1 `letter-spacing` property.
|
||||
/// NB: You will probably want to set the `IGNORE_LIGATURES_SHAPING_FLAG` if this is non-null.
|
||||
@ -125,36 +124,25 @@ pub struct ShapingOptions {
|
||||
}
|
||||
|
||||
/// An entry in the shape cache.
|
||||
#[deriving(Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct ShapeCacheEntry {
|
||||
text: String,
|
||||
options: ShapingOptions,
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, PartialEq, Hash)]
|
||||
struct ShapeCacheEntryRef<'a> {
|
||||
text: &'a str,
|
||||
options: &'a ShapingOptions,
|
||||
}
|
||||
|
||||
impl<'a> Equiv<ShapeCacheEntry> for ShapeCacheEntryRef<'a> {
|
||||
fn equiv(&self, other: &ShapeCacheEntry) -> bool {
|
||||
self.text == other.text.as_slice() && *self.options == other.options
|
||||
}
|
||||
}
|
||||
|
||||
impl Font {
|
||||
pub fn shape_text(&mut self, text: &str, options: &ShapingOptions) -> Arc<GlyphStore> {
|
||||
self.make_shaper(options);
|
||||
|
||||
//FIXME: find the equivalent of Equiv and the old ShapeCacheEntryRef
|
||||
let shaper = &self.shaper;
|
||||
let lookup_key = ShapeCacheEntryRef {
|
||||
text: text,
|
||||
options: options,
|
||||
let lookup_key = ShapeCacheEntry {
|
||||
text: text.to_owned(),
|
||||
options: options.clone(),
|
||||
};
|
||||
match self.shape_cache.find_equiv(&lookup_key) {
|
||||
match self.shape_cache.find(&lookup_key) {
|
||||
None => {}
|
||||
Some(glyphs) => return (*glyphs).clone(),
|
||||
Some(glyphs) => return glyphs.clone(),
|
||||
}
|
||||
|
||||
let mut glyphs = GlyphStore::new(text.chars().count() as int,
|
||||
|
@ -12,6 +12,7 @@ use collections::str::Str;
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
||||
use font_template::{FontTemplate, FontTemplateDescriptor};
|
||||
use platform::font_template::FontTemplateData;
|
||||
use servo_net::resource_task::{ResourceTask, load_whole_resource};
|
||||
@ -80,11 +81,15 @@ pub enum Command {
|
||||
Exit(Sender<()>),
|
||||
}
|
||||
|
||||
unsafe impl Send for Command {}
|
||||
|
||||
/// Reply messages sent from the font cache task to the FontContext caller.
|
||||
pub enum Reply {
|
||||
GetFontTemplateReply(Option<Arc<FontTemplateData>>),
|
||||
}
|
||||
|
||||
unsafe impl Send for Reply {}
|
||||
|
||||
/// The font cache task itself. It maintains a list of reference counted
|
||||
/// font templates that are currently in use.
|
||||
struct FontCache {
|
||||
@ -109,7 +114,7 @@ fn add_generic_font(generic_fonts: &mut HashMap<LowercaseString, LowercaseString
|
||||
impl FontCache {
|
||||
fn run(&mut self) {
|
||||
loop {
|
||||
let msg = self.port.recv();
|
||||
let msg = self.port.recv().unwrap();
|
||||
|
||||
match msg {
|
||||
Command::GetFontTemplate(family, descriptor, result) => {
|
||||
@ -138,13 +143,13 @@ impl FontCache {
|
||||
family.add_template(url.to_string().as_slice(), Some(bytes));
|
||||
},
|
||||
Err(_) => {
|
||||
debug!("Failed to load web font: family={} url={}", family_name, url);
|
||||
debug!("Failed to load web font: family={:?} url={}", family_name, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
Source::Local(ref local_family_name) => {
|
||||
let family = &mut self.web_families[family_name];
|
||||
get_variations_for_family(local_family_name.as_slice(), |path| {
|
||||
get_variations_for_family(local_family_name.as_slice(), |&mut:path| {
|
||||
family.add_template(path.as_slice(), None);
|
||||
});
|
||||
}
|
||||
@ -186,7 +191,7 @@ impl FontCache {
|
||||
let s = &mut self.local_families[*family_name];
|
||||
|
||||
if s.templates.len() == 0 {
|
||||
get_variations_for_family(family_name.as_slice(), |path| {
|
||||
get_variations_for_family(family_name.as_slice(), |&mut:path| {
|
||||
s.add_template(path.as_slice(), None);
|
||||
});
|
||||
}
|
||||
@ -244,7 +249,7 @@ impl FontCache {
|
||||
|
||||
/// The public interface to the font cache task, used exclusively by
|
||||
/// the per-thread/task FontContext structures.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct FontCacheTask {
|
||||
chan: Sender<Command>,
|
||||
}
|
||||
@ -253,7 +258,7 @@ impl FontCacheTask {
|
||||
pub fn new(resource_task: ResourceTask) -> FontCacheTask {
|
||||
let (chan, port) = channel();
|
||||
|
||||
spawn_named("FontCacheTask".to_owned(), proc() {
|
||||
spawn_named("FontCacheTask".to_owned(), move || {
|
||||
// TODO: Allow users to specify these.
|
||||
let mut generic_fonts = HashMap::with_capacity(5);
|
||||
add_generic_font(&mut generic_fonts, "serif", "Times New Roman");
|
||||
@ -286,7 +291,7 @@ impl FontCacheTask {
|
||||
let (response_chan, response_port) = channel();
|
||||
self.chan.send(Command::GetFontTemplate(family, desc, response_chan));
|
||||
|
||||
let reply = response_port.recv();
|
||||
let reply = response_port.recv().unwrap();
|
||||
|
||||
match reply {
|
||||
Reply::GetFontTemplateReply(data) => {
|
||||
@ -301,7 +306,7 @@ impl FontCacheTask {
|
||||
let (response_chan, response_port) = channel();
|
||||
self.chan.send(Command::GetLastResortFontTemplate(desc, response_chan));
|
||||
|
||||
let reply = response_port.recv();
|
||||
let reply = response_port.recv().unwrap();
|
||||
|
||||
match reply {
|
||||
Reply::GetFontTemplateReply(data) => {
|
||||
|
@ -15,7 +15,7 @@ use font::FontHandleMethods;
|
||||
/// This is very basic at the moment and needs to be
|
||||
/// expanded or refactored when we support more of the
|
||||
/// font styling parameters.
|
||||
#[deriving(Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FontTemplateDescriptor {
|
||||
pub weight: font_weight::T,
|
||||
pub italic: bool,
|
||||
|
@ -2,14 +2,14 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![feature(globs, macro_rules, phase, unsafe_destructor, default_type_params)]
|
||||
#![feature(unsafe_destructor, int_uint, plugin, box_syntax)]
|
||||
|
||||
#![deny(unused_imports)]
|
||||
#![deny(unused_variables)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(unstable)]
|
||||
|
||||
#![feature(phase)]
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate azure;
|
||||
@ -17,16 +17,15 @@ extern crate collections;
|
||||
extern crate geom;
|
||||
extern crate layers;
|
||||
extern crate libc;
|
||||
extern crate rustrt;
|
||||
extern crate stb_image;
|
||||
extern crate png;
|
||||
extern crate script_traits;
|
||||
extern crate serialize;
|
||||
extern crate "serialize" as rustc_serialize;
|
||||
extern crate unicode;
|
||||
#[phase(plugin)]
|
||||
#[no_link] #[plugin]
|
||||
extern crate "plugins" as servo_plugins;
|
||||
extern crate "net" as servo_net;
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate "util" as servo_util;
|
||||
extern crate "msg" as servo_msg;
|
||||
extern crate style;
|
||||
|
@ -32,7 +32,7 @@ use servo_util::range::Range;
|
||||
use std::default::Default;
|
||||
use std::f32;
|
||||
use std::mem;
|
||||
use std::num::{Float, FloatMath};
|
||||
use std::num::Float;
|
||||
use std::ptr;
|
||||
use style::computed_values::{border_style, filter, mix_blend_mode};
|
||||
use std::sync::Arc;
|
||||
@ -54,7 +54,7 @@ pub struct PaintContext<'a> {
|
||||
pub transient_clip: Option<ClippingRegion>,
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
enum Direction {
|
||||
Top,
|
||||
Left,
|
||||
@ -62,7 +62,7 @@ enum Direction {
|
||||
Bottom
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
enum DashSize {
|
||||
DottedBorder = 1,
|
||||
DashedBorder = 3
|
||||
@ -608,7 +608,7 @@ impl<'a> PaintContext<'a> {
|
||||
let rect = bounds.to_azure_rect();
|
||||
let draw_opts = DrawOptions::new(1u as AzFloat, 0 as uint16_t);
|
||||
let mut stroke_opts = StrokeOptions::new(0u as AzFloat, 10u as AzFloat);
|
||||
let mut dash: [AzFloat, ..2] = [0u as AzFloat, 0u as AzFloat];
|
||||
let mut dash: [AzFloat; 2] = [0u as AzFloat, 0u as AzFloat];
|
||||
|
||||
stroke_opts.set_cap_style(AZ_CAP_BUTT as u8);
|
||||
|
||||
|
@ -31,13 +31,13 @@ use servo_util::smallvec::SmallVec;
|
||||
use servo_util::task::spawn_named_with_send_on_failure;
|
||||
use servo_util::task_state;
|
||||
use servo_util::time::{TimeProfilerChan, TimeProfilerCategory, profile};
|
||||
use std::comm::{Receiver, Sender, channel};
|
||||
use std::mem;
|
||||
use std::task::TaskBuilder;
|
||||
use std::thread::Builder;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
|
||||
/// Information about a hardware graphics layer that layout sends to the painting task.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct PaintLayer {
|
||||
/// A per-pipeline ID describing this layer that should be stable across reflows.
|
||||
pub id: LayerId,
|
||||
@ -74,7 +74,7 @@ pub enum Msg {
|
||||
Exit(Option<Sender<()>>, PipelineExitType),
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct PaintChan(Sender<Msg>);
|
||||
|
||||
impl PaintChan {
|
||||
@ -84,13 +84,12 @@ impl PaintChan {
|
||||
}
|
||||
|
||||
pub fn send(&self, msg: Msg) {
|
||||
let &PaintChan(ref chan) = self;
|
||||
assert!(chan.send_opt(msg).is_ok(), "PaintChan.send: paint port closed")
|
||||
assert!(self.send_opt(msg).is_ok(), "PaintChan.send: paint port closed")
|
||||
}
|
||||
|
||||
pub fn send_opt(&self, msg: Msg) -> Result<(), Msg> {
|
||||
let &PaintChan(ref chan) = self;
|
||||
chan.send_opt(msg)
|
||||
chan.send(msg).map_err(|e| e.0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +131,7 @@ macro_rules! native_graphics_context(
|
||||
($task:expr) => (
|
||||
$task.native_graphics_context.as_ref().expect("Need a graphics context to do painting")
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
impl<C> PaintTask<C> where C: PaintListener + Send {
|
||||
pub fn create(id: PipelineId,
|
||||
@ -144,7 +143,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send {
|
||||
time_profiler_chan: TimeProfilerChan,
|
||||
shutdown_chan: Sender<()>) {
|
||||
let ConstellationChan(c) = constellation_chan.clone();
|
||||
spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, proc() {
|
||||
spawn_named_with_send_on_failure("PaintTask", task_state::PAINT, move |:| {
|
||||
{
|
||||
// Ensures that the paint task and graphics context are destroyed before the
|
||||
// shutdown message.
|
||||
@ -196,7 +195,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send {
|
||||
let mut exit_response_channel : Option<Sender<()>> = None;
|
||||
let mut waiting_for_compositor_buffers_to_exit = false;
|
||||
loop {
|
||||
match self.port.recv() {
|
||||
match self.port.recv().unwrap() {
|
||||
Msg::PaintInit(stacking_context) => {
|
||||
self.root_stacking_context = Some(stacking_context.clone());
|
||||
|
||||
@ -226,7 +225,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send {
|
||||
if self.epoch == epoch {
|
||||
self.paint(&mut replies, buffer_requests, scale, layer_id);
|
||||
} else {
|
||||
debug!("painter epoch mismatch: {} != {}", self.epoch, epoch);
|
||||
debug!("painter epoch mismatch: {:?} != {:?}", self.epoch, epoch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,7 +335,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send {
|
||||
mut tiles: Vec<BufferRequest>,
|
||||
scale: f32,
|
||||
layer_id: LayerId) {
|
||||
profile(TimeProfilerCategory::Painting, None, self.time_profiler_chan.clone(), || {
|
||||
profile(TimeProfilerCategory::Painting, None, self.time_profiler_chan.clone(), |:| {
|
||||
// Bail out if there is no appropriate stacking context.
|
||||
let stacking_context = if let Some(ref stacking_context) = self.root_stacking_context {
|
||||
match display_list::find_stacking_context_with_layer_id(stacking_context,
|
||||
@ -360,10 +359,10 @@ impl<C> PaintTask<C> where C: PaintListener + Send {
|
||||
stacking_context.clone(),
|
||||
scale);
|
||||
}
|
||||
let new_buffers = Vec::from_fn(tile_count, |i| {
|
||||
let new_buffers = (0..tile_count).map(|&mut :i| {
|
||||
let thread_id = i % self.worker_threads.len();
|
||||
self.worker_threads[thread_id].get_painted_tile_buffer()
|
||||
});
|
||||
}).collect();
|
||||
|
||||
let layer_buffer_set = box LayerBufferSet {
|
||||
buffers: new_buffers,
|
||||
@ -425,13 +424,13 @@ impl WorkerThreadProxy {
|
||||
} else {
|
||||
opts::get().layout_threads
|
||||
};
|
||||
Vec::from_fn(thread_count, |_| {
|
||||
(0..thread_count).map(|&:_| {
|
||||
let (from_worker_sender, from_worker_receiver) = channel();
|
||||
let (to_worker_sender, to_worker_receiver) = channel();
|
||||
let native_graphics_metadata = native_graphics_metadata.clone();
|
||||
let font_cache_task = font_cache_task.clone();
|
||||
let time_profiler_chan = time_profiler_chan.clone();
|
||||
TaskBuilder::new().spawn(proc() {
|
||||
Builder::new().spawn(move || {
|
||||
let mut worker_thread = WorkerThread::new(from_worker_sender,
|
||||
to_worker_receiver,
|
||||
native_graphics_metadata,
|
||||
@ -443,7 +442,7 @@ impl WorkerThreadProxy {
|
||||
receiver: from_worker_receiver,
|
||||
sender: to_worker_sender,
|
||||
}
|
||||
})
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn paint_tile(&mut self,
|
||||
@ -451,17 +450,17 @@ impl WorkerThreadProxy {
|
||||
layer_buffer: Option<Box<LayerBuffer>>,
|
||||
stacking_context: Arc<StackingContext>,
|
||||
scale: f32) {
|
||||
self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale))
|
||||
self.sender.send(MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale)).unwrap()
|
||||
}
|
||||
|
||||
fn get_painted_tile_buffer(&mut self) -> Box<LayerBuffer> {
|
||||
match self.receiver.recv() {
|
||||
match self.receiver.recv().unwrap() {
|
||||
MsgFromWorkerThread::PaintedTile(layer_buffer) => layer_buffer,
|
||||
}
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
self.sender.send(MsgToWorkerThread::Exit)
|
||||
self.sender.send(MsgToWorkerThread::Exit).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,7 +492,7 @@ impl WorkerThread {
|
||||
|
||||
fn main(&mut self) {
|
||||
loop {
|
||||
match self.receiver.recv() {
|
||||
match self.receiver.recv().unwrap() {
|
||||
MsgToWorkerThread::Exit => break,
|
||||
MsgToWorkerThread::PaintTile(tile, layer_buffer, stacking_context, scale) => {
|
||||
let draw_target = self.optimize_and_paint_tile(&tile, stacking_context, scale);
|
||||
@ -501,7 +500,7 @@ impl WorkerThread {
|
||||
layer_buffer,
|
||||
draw_target,
|
||||
scale);
|
||||
self.sender.send(MsgFromWorkerThread::PaintedTile(buffer))
|
||||
self.sender.send(MsgFromWorkerThread::PaintedTile(buffer)).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -582,7 +581,7 @@ impl WorkerThread {
|
||||
// GPU painting mode, so that it doesn't have to recreate it.
|
||||
if !opts::get().gpu_painting {
|
||||
let mut buffer = layer_buffer.unwrap();
|
||||
draw_target.snapshot().get_data_surface().with_data(|data| {
|
||||
draw_target.snapshot().get_data_surface().with_data(|&mut:data| {
|
||||
buffer.native_surface.upload(native_graphics_context!(self), data);
|
||||
debug!("painting worker thread uploading to native surface {}",
|
||||
buffer.native_surface.get_id());
|
||||
|
@ -8,6 +8,7 @@ use font::{FontHandleMethods, FontMetrics, FontTableMethods};
|
||||
use font::{FontTableTag, FractionalPixel};
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::geometry;
|
||||
use servo_util::str::c_str_to_string;
|
||||
use platform::font_context::FontContextHandle;
|
||||
use text::glyph::GlyphId;
|
||||
use text::util::{float_to_fixed, fixed_to_float};
|
||||
@ -25,11 +26,10 @@ use freetype::freetype::{FT_SizeRec, FT_UInt, FT_Size_Metrics, struct_FT_Vector_
|
||||
use freetype::freetype::{ft_sfnt_os2};
|
||||
use freetype::tt_os2::TT_OS2;
|
||||
|
||||
use libc::c_char;
|
||||
use std::mem;
|
||||
use std::num::Float;
|
||||
use std::ptr;
|
||||
use std::string::String;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
fn float_to_fixed_ft(f: f64) -> i32 {
|
||||
@ -43,7 +43,7 @@ fn fixed_to_float_ft(f: i32) -> f64 {
|
||||
pub struct FontTable;
|
||||
|
||||
impl FontTableMethods for FontTable {
|
||||
fn with_buffer(&self, _blk: |*const u8, uint|) {
|
||||
fn with_buffer<F>(&self, _blk: F) where F: FnOnce(*const u8, uint) {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
@ -121,10 +121,14 @@ impl FontHandleMethods for FontHandle {
|
||||
self.font_data.clone()
|
||||
}
|
||||
fn family_name(&self) -> String {
|
||||
unsafe { String::from_raw_buf(&*(*self.face).family_name as *const i8 as *const u8) }
|
||||
unsafe {
|
||||
c_str_to_string((*self.face).family_name as *const c_char)
|
||||
}
|
||||
}
|
||||
fn face_name(&self) -> String {
|
||||
unsafe { String::from_raw_buf(&*FT_Get_Postscript_Name(self.face) as *const i8 as *const u8) }
|
||||
unsafe {
|
||||
c_str_to_string(FT_Get_Postscript_Name(self.face) as *const c_char)
|
||||
}
|
||||
}
|
||||
fn is_italic(&self) -> bool {
|
||||
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
|
||||
@ -253,7 +257,7 @@ impl FontHandleMethods for FontHandle {
|
||||
line_gap: height,
|
||||
};
|
||||
|
||||
debug!("Font metrics (@{} pt): {}", geometry::to_pt(em_size), metrics);
|
||||
debug!("Font metrics (@{} pt): {:?}", geometry::to_pt(em_size), metrics);
|
||||
return metrics;
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,12 @@ extern fn ft_realloc(_mem: FT_Memory, _cur_size: c_long, new_size: c_long, block
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct FreeTypeLibraryHandle {
|
||||
pub ctx: FT_Library,
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct FontContextHandle {
|
||||
pub ctx: Rc<FreeTypeLibraryHandle>,
|
||||
}
|
||||
|
@ -20,17 +20,19 @@ use fontconfig::fontconfig::{
|
||||
FcObjectSetAdd, FcPatternGetInteger
|
||||
};
|
||||
|
||||
use servo_util::str::c_str_to_string;
|
||||
|
||||
use libc;
|
||||
use libc::c_int;
|
||||
use libc::{c_int, c_char};
|
||||
use std::borrow::ToOwned;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
use std::string::String;
|
||||
|
||||
static FC_FAMILY: &'static [u8] = b"family\0";
|
||||
static FC_FILE: &'static [u8] = b"file\0";
|
||||
static FC_INDEX: &'static [u8] = b"index\0";
|
||||
|
||||
pub fn get_available_families(callback: |String|) {
|
||||
pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) {
|
||||
unsafe {
|
||||
let config = FcConfigGetCurrent();
|
||||
let fontSet = FcConfigGetFonts(config, FcSetSystem);
|
||||
@ -38,8 +40,8 @@ pub fn get_available_families(callback: |String|) {
|
||||
let font = (*fontSet).fonts.offset(i);
|
||||
let mut family: *mut FcChar8 = ptr::null_mut();
|
||||
let mut v: c_int = 0;
|
||||
while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut i8, v, &mut family) == FcResultMatch {
|
||||
let family_name = String::from_raw_buf(family as *const i8 as *const u8);
|
||||
while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut c_char, v, &mut family) == FcResultMatch {
|
||||
let family_name = c_str_to_string(family as *const c_char);
|
||||
callback(family_name);
|
||||
v += 1;
|
||||
}
|
||||
@ -47,7 +49,9 @@ pub fn get_available_families(callback: |String|) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_variations_for_family(family_name: &str, callback: |String|) {
|
||||
pub fn get_variations_for_family<F>(family_name: &str, mut callback: F)
|
||||
where F: FnMut(String)
|
||||
{
|
||||
debug!("getting variations for {}", family_name);
|
||||
unsafe {
|
||||
let config = FcConfigGetCurrent();
|
||||
@ -55,16 +59,16 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) {
|
||||
let font_set_array_ptr = &mut font_set;
|
||||
let pattern = FcPatternCreate();
|
||||
assert!(!pattern.is_null());
|
||||
let mut family_name_c = family_name.to_c_str();
|
||||
let family_name = family_name_c.as_mut_ptr();
|
||||
let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut i8, family_name as *mut FcChar8);
|
||||
let family_name_c = CString::from_slice(family_name.as_bytes());
|
||||
let family_name = family_name_c.as_ptr();
|
||||
let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut c_char, family_name as *mut FcChar8);
|
||||
assert!(ok != 0);
|
||||
|
||||
let object_set = FcObjectSetCreate();
|
||||
assert!(!object_set.is_null());
|
||||
|
||||
FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut i8);
|
||||
FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut i8);
|
||||
FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut c_char);
|
||||
FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut c_char);
|
||||
|
||||
let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set);
|
||||
|
||||
@ -73,13 +77,13 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) {
|
||||
for i in range(0, (*matches).nfont as int) {
|
||||
let font = (*matches).fonts.offset(i);
|
||||
let mut file: *mut FcChar8 = ptr::null_mut();
|
||||
let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut i8, 0, &mut file) == FcResultMatch {
|
||||
String::from_raw_buf(file as *const i8 as *const u8)
|
||||
let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut c_char, 0, &mut file) == FcResultMatch {
|
||||
c_str_to_string(file as *const c_char)
|
||||
} else {
|
||||
panic!();
|
||||
};
|
||||
let mut index: libc::c_int = 0;
|
||||
let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut i8, 0, &mut index) == FcResultMatch {
|
||||
let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut c_char, 0, &mut index) == FcResultMatch {
|
||||
index
|
||||
} else {
|
||||
panic!();
|
||||
@ -98,8 +102,8 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) {
|
||||
}
|
||||
|
||||
pub fn get_system_default_family(generic_name: &str) -> Option<String> {
|
||||
let mut generic_name_c = generic_name.to_c_str();
|
||||
let generic_name_ptr = generic_name_c.as_mut_ptr();
|
||||
let generic_name_c = CString::from_slice(generic_name.as_bytes());
|
||||
let generic_name_ptr = generic_name_c.as_ptr();
|
||||
|
||||
unsafe {
|
||||
let pattern = FcNameParse(generic_name_ptr as *mut FcChar8);
|
||||
@ -112,8 +116,8 @@ pub fn get_system_default_family(generic_name: &str) -> Option<String> {
|
||||
|
||||
let family_name = if result == FcResultMatch {
|
||||
let mut match_string: *mut FcChar8 = ptr::null_mut();
|
||||
FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut i8, 0, &mut match_string);
|
||||
let result = String::from_raw_buf(match_string as *const i8 as *const u8);
|
||||
FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut c_char, 0, &mut match_string);
|
||||
let result = c_str_to_string(match_string as *const c_char);
|
||||
FcPatternDestroy(family_match);
|
||||
Some(result)
|
||||
} else {
|
||||
|
@ -47,7 +47,7 @@ impl FontTable {
|
||||
}
|
||||
|
||||
impl FontTableMethods for FontTable {
|
||||
fn with_buffer(&self, blk: |*const u8, uint|) {
|
||||
fn with_buffer<F>(&self, blk: F) where F: FnOnce(*const u8, uint) {
|
||||
blk(self.data.bytes().as_ptr(), self.data.len() as uint);
|
||||
}
|
||||
}
|
||||
@ -112,8 +112,8 @@ impl FontHandleMethods for FontHandle {
|
||||
}
|
||||
|
||||
fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
|
||||
let characters: [UniChar, ..1] = [codepoint as UniChar];
|
||||
let mut glyphs: [CGGlyph, ..1] = [0 as CGGlyph];
|
||||
let characters: [UniChar; 1] = [codepoint as UniChar];
|
||||
let mut glyphs: [CGGlyph; 1] = [0 as CGGlyph];
|
||||
let count: CFIndex = 1;
|
||||
|
||||
let result = self.ctfont.get_glyphs_for_characters(&characters[0],
|
||||
@ -179,7 +179,7 @@ impl FontHandleMethods for FontHandle {
|
||||
average_advance: average_advance,
|
||||
line_gap: Au::from_frac_px(line_gap),
|
||||
};
|
||||
debug!("Font metrics (@{} pt): {}", self.ctfont.pt_size() as f64, metrics);
|
||||
debug!("Font metrics (@{} pt): {:?}", self.ctfont.pt_size() as f64, metrics);
|
||||
return metrics;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct FontContextHandle {
|
||||
ctx: ()
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use core_text;
|
||||
use std::borrow::ToOwned;
|
||||
use std::mem;
|
||||
|
||||
pub fn get_available_families(callback: |String|) {
|
||||
pub fn get_available_families<F>(mut callback: F) where F: FnMut(String) {
|
||||
let family_names = core_text::font_collection::get_family_names();
|
||||
for strref in family_names.iter() {
|
||||
let family_name_ref: CFStringRef = unsafe { mem::transmute(strref) };
|
||||
@ -20,7 +20,7 @@ pub fn get_available_families(callback: |String|) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_variations_for_family(family_name: &str, callback: |String|) {
|
||||
pub fn get_variations_for_family<F>(family_name: &str, mut callback: F) where F: FnMut(String) {
|
||||
debug!("Looking for faces of family: {}", family_name);
|
||||
|
||||
let family_collection =
|
||||
|
@ -18,6 +18,9 @@ pub struct FontTemplateData {
|
||||
pub identifier: String,
|
||||
}
|
||||
|
||||
unsafe impl Send for FontTemplateData {}
|
||||
unsafe impl Sync for FontTemplateData {}
|
||||
|
||||
impl FontTemplateData {
|
||||
pub fn new(identifier: &str, font_data: Option<Vec<u8>>) -> FontTemplateData {
|
||||
let ctfont = match font_data {
|
||||
|
@ -9,8 +9,9 @@ use servo_util::geometry::Au;
|
||||
|
||||
use std::cmp::{Ordering, PartialOrd};
|
||||
use std::iter::repeat;
|
||||
use std::num::NumCast;
|
||||
use std::num::{ToPrimitive, NumCast};
|
||||
use std::mem;
|
||||
use std::ops::{Add, Sub, Mul, Neg, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr, Not};
|
||||
use std::u16;
|
||||
use std::vec::Vec;
|
||||
use geom::point::Point2D;
|
||||
@ -23,7 +24,7 @@ use geom::point::Point2D;
|
||||
/// In the uncommon case (multiple glyphs per unicode character, large glyph index/advance, or
|
||||
/// glyph offsets), we pack the glyph count into GlyphEntry, and store the other glyph information
|
||||
/// in DetailedGlyphStore.
|
||||
#[deriving(Clone, Show, Copy)]
|
||||
#[derive(Clone, Show, Copy)]
|
||||
struct GlyphEntry {
|
||||
value: u32,
|
||||
}
|
||||
@ -88,7 +89,7 @@ impl GlyphEntry {
|
||||
pub type GlyphId = u32;
|
||||
|
||||
// TODO: unify with bit flags?
|
||||
#[deriving(PartialEq, Copy)]
|
||||
#[derive(PartialEq, Copy)]
|
||||
pub enum BreakType {
|
||||
None,
|
||||
Normal,
|
||||
@ -252,7 +253,7 @@ impl GlyphEntry {
|
||||
|
||||
// Stores data for a detailed glyph, in the case that several glyphs
|
||||
// correspond to one character, or the glyph's data couldn't be packed.
|
||||
#[deriving(Clone, Show, Copy)]
|
||||
#[derive(Clone, Show, Copy)]
|
||||
struct DetailedGlyph {
|
||||
id: GlyphId,
|
||||
// glyph's advance, in the text's direction (RTL or RTL)
|
||||
@ -271,7 +272,7 @@ impl DetailedGlyph {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Clone, Eq, Show, Copy)]
|
||||
#[derive(PartialEq, Clone, Eq, Show, Copy)]
|
||||
struct DetailedGlyphRecord {
|
||||
// source string offset/GlyphEntry offset in the TextRun
|
||||
entry_offset: CharIndex,
|
||||
@ -320,7 +321,7 @@ impl<'a> DetailedGlyphStore {
|
||||
detail_offset: self.detail_buffer.len() as int,
|
||||
};
|
||||
|
||||
debug!("Adding entry[off={}] for detailed glyphs: {}", entry_offset, glyphs);
|
||||
debug!("Adding entry[off={:?}] for detailed glyphs: {:?}", entry_offset, glyphs);
|
||||
|
||||
/* TODO: don't actually assert this until asserts are compiled
|
||||
in/out based on severity, debug/release, etc. This assertion
|
||||
@ -340,7 +341,7 @@ impl<'a> DetailedGlyphStore {
|
||||
|
||||
fn get_detailed_glyphs_for_entry(&'a self, entry_offset: CharIndex, count: u16)
|
||||
-> &'a [DetailedGlyph] {
|
||||
debug!("Requesting detailed glyphs[n={}] for entry[off={}]", count, entry_offset);
|
||||
debug!("Requesting detailed glyphs[n={}] for entry[off={:?}]", count, entry_offset);
|
||||
|
||||
// FIXME: Is this right? --pcwalton
|
||||
// TODO: should fix this somewhere else
|
||||
@ -412,7 +413,7 @@ impl<'a> DetailedGlyphStore {
|
||||
|
||||
// This struct is used by GlyphStore clients to provide new glyph data.
|
||||
// It should be allocated on the stack and passed by reference to GlyphStore.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct GlyphData {
|
||||
id: GlyphId,
|
||||
advance: Au,
|
||||
@ -445,7 +446,7 @@ impl GlyphData {
|
||||
// through glyphs (either for a particular TextRun offset, or all glyphs).
|
||||
// Rather than eagerly assembling and copying glyph data, it only retrieves
|
||||
// values as they are needed from the GlyphStore, using provided offsets.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum GlyphInfo<'a> {
|
||||
Simple(&'a GlyphStore, CharIndex),
|
||||
Detail(&'a GlyphStore, CharIndex, u16),
|
||||
@ -514,7 +515,7 @@ pub struct GlyphStore {
|
||||
}
|
||||
|
||||
int_range_index! {
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[doc = "An index that refers to a character in a text run. This could \
|
||||
point to the middle of a glyph."]
|
||||
struct CharIndex(int)
|
||||
@ -580,11 +581,11 @@ impl<'a> GlyphStore {
|
||||
let entry = match first_glyph_data.is_missing {
|
||||
true => GlyphEntry::missing(glyph_count),
|
||||
false => {
|
||||
let glyphs_vec = Vec::from_fn(glyph_count as uint, |i| {
|
||||
let glyphs_vec: Vec<DetailedGlyph> = (0..glyph_count as uint).map(|&:i| {
|
||||
DetailedGlyph::new(data_for_glyphs[i].id,
|
||||
data_for_glyphs[i].advance,
|
||||
data_for_glyphs[i].offset)
|
||||
});
|
||||
}).collect();
|
||||
|
||||
self.detail_store.add_detailed_glyphs_for_entry(i, glyphs_vec.as_slice());
|
||||
GlyphEntry::complex(first_glyph_data.cluster_start,
|
||||
@ -593,7 +594,7 @@ impl<'a> GlyphStore {
|
||||
}
|
||||
}.adapt_character_flags_of_entry(self.entry_buffer[i.to_uint()]);
|
||||
|
||||
debug!("Adding multiple glyphs[idx={}, count={}]: {}", i, glyph_count, entry);
|
||||
debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry);
|
||||
|
||||
self.entry_buffer[i.to_uint()] = entry;
|
||||
}
|
||||
@ -603,7 +604,7 @@ impl<'a> GlyphStore {
|
||||
assert!(i < self.char_len());
|
||||
|
||||
let entry = GlyphEntry::complex(cluster_start, ligature_start, 0);
|
||||
debug!("adding spacer for chracter without associated glyph[idx={}]", i);
|
||||
debug!("adding spacer for chracter without associated glyph[idx={:?}]", i);
|
||||
|
||||
self.entry_buffer[i.to_uint()] = entry;
|
||||
}
|
||||
@ -725,7 +726,9 @@ impl<'a> GlyphIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<(CharIndex, GlyphInfo<'a>)> for GlyphIterator<'a> {
|
||||
impl<'a> Iterator for GlyphIterator<'a> {
|
||||
type Item = (CharIndex, GlyphInfo<'a>);
|
||||
|
||||
// I tried to start with something simpler and apply FlatMap, but the
|
||||
// inability to store free variables in the FlatMap struct was problematic.
|
||||
//
|
||||
@ -740,7 +743,7 @@ impl<'a> Iterator<(CharIndex, GlyphInfo<'a>)> for GlyphIterator<'a> {
|
||||
self.next_glyph_range()
|
||||
} else {
|
||||
// No glyph range. Look at next character.
|
||||
self.char_range.next().and_then(|i| {
|
||||
self.char_range.next().and_then(|:i| {
|
||||
self.char_index = i;
|
||||
assert!(i < self.store.char_len());
|
||||
let entry = self.store.entry_buffer[i.to_uint()];
|
||||
|
@ -9,12 +9,12 @@ use servo_util::geometry::Au;
|
||||
use servo_util::range::Range;
|
||||
use servo_util::vec::{Comparator, FullBinarySearchMethods};
|
||||
use std::cmp::Ordering;
|
||||
use std::slice::Items;
|
||||
use std::slice::Iter;
|
||||
use std::sync::Arc;
|
||||
use text::glyph::{CharIndex, GlyphStore};
|
||||
|
||||
/// A single "paragraph" of text in one font size and style.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct TextRun {
|
||||
pub text: Arc<String>,
|
||||
pub font_template: Arc<FontTemplateData>,
|
||||
@ -25,7 +25,7 @@ pub struct TextRun {
|
||||
}
|
||||
|
||||
/// A single series of glyphs within a text run.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct GlyphRun {
|
||||
/// The glyphs.
|
||||
pub glyph_store: Arc<GlyphStore>,
|
||||
@ -34,7 +34,7 @@ pub struct GlyphRun {
|
||||
}
|
||||
|
||||
pub struct NaturalWordSliceIterator<'a> {
|
||||
glyph_iter: Items<'a, GlyphRun>,
|
||||
glyph_iter: Iter<'a, GlyphRun>,
|
||||
range: Range<CharIndex>,
|
||||
}
|
||||
|
||||
@ -73,7 +73,9 @@ impl<'a> TextRunSlice<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<TextRunSlice<'a>> for NaturalWordSliceIterator<'a> {
|
||||
impl<'a> Iterator for NaturalWordSliceIterator<'a> {
|
||||
type Item = TextRunSlice<'a>;
|
||||
|
||||
// inline(always) due to the inefficient rt failures messing up inline heuristics, I think.
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<TextRunSlice<'a>> {
|
||||
@ -101,11 +103,13 @@ impl<'a> Iterator<TextRunSlice<'a>> for NaturalWordSliceIterator<'a> {
|
||||
|
||||
pub struct CharacterSliceIterator<'a> {
|
||||
glyph_run: Option<&'a GlyphRun>,
|
||||
glyph_run_iter: Items<'a, GlyphRun>,
|
||||
glyph_run_iter: Iter<'a, GlyphRun>,
|
||||
range: Range<CharIndex>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator<TextRunSlice<'a>> for CharacterSliceIterator<'a> {
|
||||
impl<'a> Iterator for CharacterSliceIterator<'a> {
|
||||
type Item = TextRunSlice<'a>;
|
||||
|
||||
// inline(always) due to the inefficient rt failures messing up inline heuristics, I think.
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<TextRunSlice<'a>> {
|
||||
@ -140,7 +144,9 @@ pub struct LineIterator<'a> {
|
||||
slices: NaturalWordSliceIterator<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator<Range<CharIndex>> for LineIterator<'a> {
|
||||
impl<'a> Iterator for LineIterator<'a> {
|
||||
type Item = Range<CharIndex>;
|
||||
|
||||
fn next(&mut self) -> Option<Range<CharIndex>> {
|
||||
// Loop until we hit whitespace and are in a clump.
|
||||
loop {
|
||||
@ -311,9 +317,9 @@ impl<'a> TextRun {
|
||||
}
|
||||
|
||||
pub fn min_width_for_range(&self, range: &Range<CharIndex>) -> Au {
|
||||
debug!("iterating outer range {}", range);
|
||||
debug!("iterating outer range {:?}", range);
|
||||
self.natural_word_slices_in_range(range).fold(Au(0), |max_piece_width, slice| {
|
||||
debug!("iterated on {}[{}]", slice.offset, slice.range);
|
||||
debug!("iterated on {:?}[{:?}]", slice.offset, slice.range);
|
||||
Au::max(max_piece_width, self.advance_for_range(&slice.range))
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use text::glyph::CharIndex;
|
||||
|
||||
#[deriving(PartialEq, Eq, Copy)]
|
||||
#[derive(PartialEq, Eq, Copy)]
|
||||
pub enum CompressionMode {
|
||||
CompressNone,
|
||||
CompressWhitespace,
|
||||
|
@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"]
|
||||
name = "layout"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.canvas]
|
||||
path = "../canvas"
|
||||
|
||||
[dependencies.gfx]
|
||||
path = "../gfx"
|
||||
|
||||
@ -37,9 +40,6 @@ git = "https://github.com/servo/rust-cssparser"
|
||||
[dependencies.geom]
|
||||
git = "https://github.com/servo/rust-geom"
|
||||
|
||||
[dependencies.url]
|
||||
git = "https://github.com/servo/rust-url"
|
||||
|
||||
[dependencies.string_cache]
|
||||
git = "https://github.com/servo/string-cache"
|
||||
|
||||
@ -48,3 +48,4 @@ git = "https://github.com/servo/string-cache"
|
||||
|
||||
[dependencies]
|
||||
encoding = "0.2"
|
||||
url = "*"
|
@ -64,7 +64,7 @@ use style::computed_values::{overflow, position};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Information specific to floated blocks.
|
||||
#[deriving(Clone, Encodable)]
|
||||
#[derive(Clone, Encodable)]
|
||||
pub struct FloatedBlockInfo {
|
||||
/// The amount of inline size that is available for the float.
|
||||
pub containing_inline_size: Au,
|
||||
@ -92,7 +92,7 @@ impl FloatedBlockInfo {
|
||||
}
|
||||
|
||||
/// The solutions for the block-size-and-margins constraint equation.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
struct BSizeConstraintSolution {
|
||||
block_start: Au,
|
||||
_block_end: Au,
|
||||
@ -366,7 +366,8 @@ impl CandidateBSizeIterator {
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator<MaybeAuto> for CandidateBSizeIterator {
|
||||
impl Iterator for CandidateBSizeIterator {
|
||||
type Item = MaybeAuto;
|
||||
fn next(&mut self) -> Option<MaybeAuto> {
|
||||
self.status = match self.status {
|
||||
CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying,
|
||||
@ -487,13 +488,13 @@ pub enum BlockType {
|
||||
FloatNonReplaced,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum MarginsMayCollapseFlag {
|
||||
MarginsMayCollapse,
|
||||
MarginsMayNotCollapse,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
#[derive(PartialEq)]
|
||||
enum FormattingContextType {
|
||||
None,
|
||||
Block,
|
||||
@ -525,7 +526,7 @@ fn propagate_layer_flag_from_child(layers_needed_for_descendants: &mut bool, kid
|
||||
}
|
||||
|
||||
// A block formatting context.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct BlockFlow {
|
||||
/// Data common to all flows.
|
||||
pub base: BaseFlow,
|
||||
@ -561,8 +562,8 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,E,S> Encodable<S,E> for BlockFlowFlags where S: Encoder<E> {
|
||||
fn encode(&self, e: &mut S) -> Result<(),E> {
|
||||
impl Encodable for BlockFlowFlags {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
self.bits().encode(e)
|
||||
}
|
||||
}
|
||||
@ -1905,7 +1906,7 @@ impl Flow for BlockFlow {
|
||||
impl fmt::Show for BlockFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f,
|
||||
"{} - {:x}: frag={} ({})",
|
||||
"{:?} - {:x}: frag={:?} ({:?})",
|
||||
self.class(),
|
||||
self.base.debug_id(),
|
||||
self.fragment,
|
||||
@ -1914,7 +1915,7 @@ impl fmt::Show for BlockFlow {
|
||||
}
|
||||
|
||||
/// The inputs for the inline-sizes-and-margins constraint equation.
|
||||
#[deriving(Show, Copy)]
|
||||
#[derive(Show, Copy)]
|
||||
pub struct ISizeConstraintInput {
|
||||
pub computed_inline_size: MaybeAuto,
|
||||
pub inline_start_margin: MaybeAuto,
|
||||
@ -1947,7 +1948,7 @@ impl ISizeConstraintInput {
|
||||
}
|
||||
|
||||
/// The solutions for the inline-size-and-margins constraint equation.
|
||||
#[deriving(Copy, Show)]
|
||||
#[derive(Copy, Show)]
|
||||
pub struct ISizeConstraintSolution {
|
||||
pub inline_start: Au,
|
||||
pub inline_end: Au,
|
||||
@ -2560,7 +2561,7 @@ impl ISizeAndMarginsComputer for FloatNonReplaced {
|
||||
let available_inline_size_float = available_inline_size - margin_inline_start - margin_inline_end;
|
||||
let shrink_to_fit = block.get_shrink_to_fit_inline_size(available_inline_size_float);
|
||||
let inline_size = computed_inline_size.specified_or_default(shrink_to_fit);
|
||||
debug!("assign_inline_sizes_float -- inline_size: {}", inline_size);
|
||||
debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size);
|
||||
ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end)
|
||||
}
|
||||
}
|
||||
@ -2580,7 +2581,7 @@ impl ISizeAndMarginsComputer for FloatReplaced {
|
||||
MaybeAuto::Specified(w) => w,
|
||||
MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now")
|
||||
};
|
||||
debug!("assign_inline_sizes_float -- inline_size: {}", inline_size);
|
||||
debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size);
|
||||
ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end)
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ use std::sync::Arc;
|
||||
use url::Url;
|
||||
|
||||
/// The results of flow construction for a DOM node.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum ConstructionResult {
|
||||
/// This node contributes nothing at all (`display: none`). Alternately, this is what newly
|
||||
/// created nodes have their `ConstructionResult` set to.
|
||||
@ -98,7 +98,7 @@ impl ConstructionResult {
|
||||
/// Represents the output of flow construction for a DOM node that has not yet resulted in a
|
||||
/// complete flow. Construction items bubble up the tree until they find a `Flow` to be attached
|
||||
/// to.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum ConstructionItem {
|
||||
/// Inline fragments and associated {ib} splits that have not yet found flows.
|
||||
InlineFragments(InlineFragmentsConstructionResult),
|
||||
@ -109,7 +109,7 @@ pub enum ConstructionItem {
|
||||
}
|
||||
|
||||
/// Represents inline fragments and {ib} splits that are bubbling up from an inline.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct InlineFragmentsConstructionResult {
|
||||
/// Any {ib} splits that we're bubbling up.
|
||||
pub splits: DList<InlineBlockSplit>,
|
||||
@ -147,7 +147,7 @@ pub struct InlineFragmentsConstructionResult {
|
||||
/// C
|
||||
/// ])
|
||||
/// ```
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct InlineBlockSplit {
|
||||
/// The inline fragments that precede the flow.
|
||||
pub predecessors: DList<Fragment>,
|
||||
@ -1150,7 +1150,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
debug!("building flow for node: {} {} {}", display, float, node.type_id());
|
||||
debug!("building flow for node: {:?} {:?} {:?}", display, float, node.type_id());
|
||||
|
||||
// Switch on display and floatedness.
|
||||
match (display, float, positioning) {
|
||||
|
@ -28,7 +28,7 @@ struct LocalLayoutContext {
|
||||
style_sharing_candidate_cache: StyleSharingCandidateCache,
|
||||
}
|
||||
|
||||
thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut()))
|
||||
thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut()));
|
||||
|
||||
fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext {
|
||||
LOCAL_CONTEXT_KEY.with(|ref r| {
|
||||
@ -80,6 +80,9 @@ pub struct SharedLayoutContext {
|
||||
pub generation: uint,
|
||||
}
|
||||
|
||||
pub struct SharedLayoutContextWrapper(pub *const SharedLayoutContext);
|
||||
unsafe impl Send for SharedLayoutContextWrapper {}
|
||||
|
||||
pub struct LayoutContext<'a> {
|
||||
pub shared: &'a SharedLayoutContext,
|
||||
cached_local_layout_context: *mut LocalLayoutContext,
|
||||
|
@ -11,13 +11,13 @@ use wrapper::{LayoutElement, LayoutNode, TLayoutNode};
|
||||
|
||||
use script::dom::node::NodeTypeId;
|
||||
use servo_util::bloom::BloomFilter;
|
||||
use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
|
||||
use servo_util::cache::{LRUCache, SimpleHashCache};
|
||||
use servo_util::smallvec::{SmallVec, SmallVec16};
|
||||
use servo_util::arc_ptr_eq;
|
||||
use std::borrow::ToOwned;
|
||||
use std::mem;
|
||||
use std::hash::{Hash, sip};
|
||||
use std::slice::Items;
|
||||
use std::hash::{Hash, Hasher, Writer};
|
||||
use std::slice::Iter;
|
||||
use string_cache::{Atom, Namespace};
|
||||
use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
|
||||
use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade};
|
||||
@ -50,7 +50,7 @@ impl ApplicableDeclarations {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ApplicableDeclarationsCacheEntry {
|
||||
pub declarations: Vec<DeclarationBlock>,
|
||||
}
|
||||
@ -66,12 +66,13 @@ impl ApplicableDeclarationsCacheEntry {
|
||||
impl PartialEq for ApplicableDeclarationsCacheEntry {
|
||||
fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool {
|
||||
let this_as_query = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice());
|
||||
this_as_query.equiv(other)
|
||||
this_as_query.eq(other)
|
||||
}
|
||||
}
|
||||
impl Eq for ApplicableDeclarationsCacheEntry {}
|
||||
|
||||
impl Hash for ApplicableDeclarationsCacheEntry {
|
||||
fn hash(&self, state: &mut sip::SipState) {
|
||||
impl<H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheEntry {
|
||||
fn hash(&self, state: &mut H) {
|
||||
let tmp = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice());
|
||||
tmp.hash(state);
|
||||
}
|
||||
@ -89,8 +90,8 @@ impl<'a> ApplicableDeclarationsCacheQuery<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> {
|
||||
fn equiv(&self, other: &ApplicableDeclarationsCacheEntry) -> bool {
|
||||
impl<'a> PartialEq for ApplicableDeclarationsCacheQuery<'a> {
|
||||
fn eq(&self, other: &ApplicableDeclarationsCacheQuery<'a>) -> bool {
|
||||
if self.declarations.len() != other.declarations.len() {
|
||||
return false
|
||||
}
|
||||
@ -102,10 +103,17 @@ impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCache
|
||||
return true
|
||||
}
|
||||
}
|
||||
impl<'a> Eq for ApplicableDeclarationsCacheQuery<'a> {}
|
||||
|
||||
impl<'a> PartialEq<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> {
|
||||
fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool {
|
||||
let other_as_query = ApplicableDeclarationsCacheQuery::new(other.declarations.as_slice());
|
||||
self.eq(&other_as_query)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
|
||||
fn hash(&self, state: &mut sip::SipState) {
|
||||
impl<'a, H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheQuery<'a> {
|
||||
fn hash(&self, state: &mut H) {
|
||||
for declaration in self.declarations.iter() {
|
||||
let ptr: uint = unsafe {
|
||||
mem::transmute_copy(declaration)
|
||||
@ -129,7 +137,7 @@ impl ApplicableDeclarationsCache {
|
||||
}
|
||||
|
||||
fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> {
|
||||
match self.cache.find_equiv(&ApplicableDeclarationsCacheQuery::new(declarations)) {
|
||||
match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) {
|
||||
None => None,
|
||||
Some(ref values) => Some((*values).clone()),
|
||||
}
|
||||
@ -168,7 +176,7 @@ fn create_common_style_affecting_attributes_from_element(element: &LayoutElement
|
||||
flags
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct StyleSharingCandidate {
|
||||
pub style: Arc<ComputedValues>,
|
||||
pub parent_style: Arc<ComputedValues>,
|
||||
@ -321,7 +329,7 @@ impl StyleSharingCandidateCache {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> Items<'a,(StyleSharingCandidate,())> {
|
||||
pub fn iter<'a>(&'a self) -> Iter<'a,(StyleSharingCandidate,())> {
|
||||
self.cache.iter()
|
||||
}
|
||||
|
||||
@ -608,8 +616,8 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
||||
|
||||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
match &mut *layout_data_ref {
|
||||
&None => panic!("no layout data"),
|
||||
&Some(ref mut layout_data) => {
|
||||
&mut None => panic!("no layout data"),
|
||||
&mut Some(ref mut layout_data) => {
|
||||
match self.type_id() {
|
||||
Some(NodeTypeId::Text) => {
|
||||
// Text nodes get a copy of the parent style. This ensures
|
||||
|
@ -45,7 +45,7 @@ use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
|
||||
use servo_util::opts;
|
||||
use std::default::Default;
|
||||
use std::iter::repeat;
|
||||
use std::num::FloatMath;
|
||||
use std::num::Float;
|
||||
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
|
||||
use style::computed::{Image, LinearGradient, LengthOrPercentage};
|
||||
use style::computed_values::filter::Filter;
|
||||
@ -53,7 +53,9 @@ use style::computed_values::{background_attachment, background_repeat, border_st
|
||||
use style::computed_values::{position, visibility};
|
||||
use style::style_structs::Border;
|
||||
use style::{ComputedValues, RGBA};
|
||||
use std::num::ToPrimitive;
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::channel;
|
||||
use url::Url;
|
||||
|
||||
/// The results of display list building for a single flow.
|
||||
@ -689,7 +691,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||
relative_containing_block_size,
|
||||
CoordinateSystem::Self);
|
||||
|
||||
debug!("Fragment::build_display_list at rel={}, abs={}, dirty={}, flow origin={}: {}",
|
||||
debug!("Fragment::build_display_list at rel={:?}, abs={:?}, dirty={:?}, flow origin={:?}: {:?}",
|
||||
self.border_box,
|
||||
stacking_relative_border_box,
|
||||
layout_context.shared.dirty,
|
||||
@ -879,8 +881,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||
let (sender, receiver) = channel::<Vec<u8>>();
|
||||
let canvas_data = match canvas_fragment_info.renderer {
|
||||
Some(ref renderer) => {
|
||||
renderer.lock().send(SendPixelContents(sender));
|
||||
receiver.recv()
|
||||
renderer.lock().unwrap().send(SendPixelContents(sender));
|
||||
receiver.recv().unwrap()
|
||||
},
|
||||
None => repeat(0xFFu8).take(width * height * 4).collect(),
|
||||
};
|
||||
@ -916,7 +918,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||
Size2D(geometry::to_frac_px(content_size.width) as f32,
|
||||
geometry::to_frac_px(content_size.height) as f32));
|
||||
|
||||
debug!("finalizing position and size of iframe for {},{}",
|
||||
debug!("finalizing position and size of iframe for {:?},{:?}",
|
||||
iframe_fragment.pipeline_id,
|
||||
iframe_fragment.subpage_id);
|
||||
let ConstellationChan(ref chan) = layout_context.shared.constellation_chan;
|
||||
@ -1276,7 +1278,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
|
||||
}
|
||||
|
||||
// A helper data structure for gradients.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
struct StopRun {
|
||||
start_offset: f32,
|
||||
end_offset: f32,
|
||||
@ -1300,7 +1302,7 @@ fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32
|
||||
}
|
||||
|
||||
/// "Steps" as defined by CSS 2.1 § E.2.
|
||||
#[deriving(Clone, PartialEq, Show, Copy)]
|
||||
#[derive(Clone, PartialEq, Show, Copy)]
|
||||
pub enum StackingLevel {
|
||||
/// The border and backgrounds for the root of this stacking context: steps 1 and 2.
|
||||
BackgroundAndBorders,
|
||||
|
@ -12,7 +12,7 @@ use std::fmt;
|
||||
use style::computed_values::float;
|
||||
|
||||
/// The kind of float: left or right.
|
||||
#[deriving(Clone, Encodable, Show, Copy)]
|
||||
#[derive(Clone, RustcEncodable, Show, Copy)]
|
||||
pub enum FloatKind {
|
||||
Left,
|
||||
Right
|
||||
@ -29,7 +29,7 @@ impl FloatKind {
|
||||
}
|
||||
|
||||
/// The kind of clearance: left, right, or both.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum ClearType {
|
||||
Left,
|
||||
Right,
|
||||
@ -37,7 +37,7 @@ pub enum ClearType {
|
||||
}
|
||||
|
||||
/// Information about a single float.
|
||||
#[deriving(Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct Float {
|
||||
/// The boundaries of this float.
|
||||
bounds: LogicalRect<Au>,
|
||||
@ -47,12 +47,12 @@ struct Float {
|
||||
|
||||
impl fmt::Show for Float {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "bounds={} kind={}", self.bounds, self.kind)
|
||||
write!(f, "bounds={:?} kind={:?}", self.bounds, self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about the floats next to a flow.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
struct FloatList {
|
||||
/// Information about each of the floats here.
|
||||
floats: PersistentList<Float>,
|
||||
@ -77,7 +77,7 @@ impl FloatList {
|
||||
|
||||
impl fmt::Show for FloatList {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "max_block_start={} floats={}", self.max_block_start, self.floats.len())
|
||||
write!(f, "max_block_start={:?} floats={}", self.max_block_start, self.floats.len())
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ pub struct PlacementInfo {
|
||||
impl fmt::Show for PlacementInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f,
|
||||
"size={} ceiling={} max_inline_size={} kind={}",
|
||||
"size={:?} ceiling={:?} max_inline_size={:?} kind={:?}",
|
||||
self.size,
|
||||
self.ceiling,
|
||||
self.max_inline_size,
|
||||
@ -110,7 +110,7 @@ fn range_intersect(block_start_1: Au, block_end_1: Au, block_start_2: Au, block_
|
||||
|
||||
/// Encapsulates information about floats. This is optimized to avoid allocation if there are
|
||||
/// no floats, and to avoid copying when translating the list of floats downward.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct Floats {
|
||||
/// The list of floats.
|
||||
list: FloatList,
|
||||
@ -125,7 +125,7 @@ impl fmt::Show for Floats {
|
||||
if !self.list.is_present() {
|
||||
write!(f, "[empty]")
|
||||
} else {
|
||||
write!(f, "offset={} floats={}", self.offset, self.list)
|
||||
write!(f, "offset={:?} floats={:?}", self.offset, self.list)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,7 +166,7 @@ impl Floats {
|
||||
let list = &self.list;
|
||||
let block_start = block_start - self.offset.block;
|
||||
|
||||
debug!("available_rect: trying to find space at {}", block_start);
|
||||
debug!("available_rect: trying to find space at {:?}", block_start);
|
||||
|
||||
// Relevant dimensions for the inline-end-most inline-start float
|
||||
let mut max_inline_start = Au(0) - self.offset.inline;
|
||||
@ -183,7 +183,7 @@ impl Floats {
|
||||
let float_pos = float.bounds.start;
|
||||
let float_size = float.bounds.size;
|
||||
|
||||
debug!("float_pos: {}, float_size: {}", float_pos, float_size);
|
||||
debug!("float_pos: {:?}, float_size: {:?}", float_pos, float_size);
|
||||
match float.kind {
|
||||
FloatKind::Left if float_pos.i + float_size.inline > max_inline_start &&
|
||||
float_pos.b + float_size.block > block_start &&
|
||||
@ -194,7 +194,7 @@ impl Floats {
|
||||
l_block_end = Some(float_pos.b + float_size.block);
|
||||
|
||||
debug!("available_rect: collision with inline_start float: new \
|
||||
max_inline_start is {}",
|
||||
max_inline_start is {:?}",
|
||||
max_inline_start);
|
||||
}
|
||||
FloatKind::Right if float_pos.i < min_inline_end &&
|
||||
@ -205,7 +205,7 @@ impl Floats {
|
||||
r_block_start = Some(float_pos.b);
|
||||
r_block_end = Some(float_pos.b + float_size.block);
|
||||
debug!("available_rect: collision with inline_end float: new min_inline_end \
|
||||
is {}",
|
||||
is {:?}",
|
||||
min_inline_end);
|
||||
}
|
||||
FloatKind::Left | FloatKind::Right => {}
|
||||
@ -262,7 +262,7 @@ impl Floats {
|
||||
}
|
||||
}
|
||||
|
||||
debug!("add_float: added float with info {}", new_info);
|
||||
debug!("add_float: added float with info {:?}", new_info);
|
||||
|
||||
let new_float = Float {
|
||||
bounds: LogicalRect::from_point_size(
|
||||
@ -303,7 +303,7 @@ impl Floats {
|
||||
/// Given placement information, finds the closest place a fragment can be positioned without
|
||||
/// colliding with any floats.
|
||||
pub fn place_between_floats(&self, info: &PlacementInfo) -> LogicalRect<Au> {
|
||||
debug!("place_between_floats: Placing object with {}", info.size);
|
||||
debug!("place_between_floats: Placing object with {:?}", info.size);
|
||||
|
||||
// If no floats, use this fast path.
|
||||
if !self.list.is_present() {
|
||||
@ -333,7 +333,7 @@ impl Floats {
|
||||
let maybe_location = self.available_rect(float_b,
|
||||
info.size.block,
|
||||
info.max_inline_size);
|
||||
debug!("place_float: Got available rect: {} for y-pos: {}", maybe_location, float_b);
|
||||
debug!("place_float: Got available rect: {:?} for y-pos: {:?}", maybe_location, float_b);
|
||||
match maybe_location {
|
||||
// If there are no floats blocking us, return the current location
|
||||
// TODO(eatkinson): integrate with overflow
|
||||
|
@ -55,9 +55,10 @@ use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
|
||||
use std::mem;
|
||||
use std::fmt;
|
||||
use std::iter::Zip;
|
||||
use std::num::FromPrimitive;
|
||||
use std::raw;
|
||||
use std::sync::atomic::{AtomicUint, Ordering};
|
||||
use std::slice::MutItems;
|
||||
use std::slice::IterMut;
|
||||
use style::computed_values::{clear, empty_cells, float, position, text_align};
|
||||
use style::ComputedValues;
|
||||
use std::sync::Arc;
|
||||
@ -66,7 +67,7 @@ use std::sync::Arc;
|
||||
///
|
||||
/// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding
|
||||
/// methods to `ImmutableFlowUtils` or `MutableFlowUtils` before adding more methods here.
|
||||
pub trait Flow: fmt::Show + ToString + Sync {
|
||||
pub trait Flow: fmt::Show + Sync {
|
||||
// RTTI
|
||||
//
|
||||
// TODO(pcwalton): Use Rust's RTTI, once that works.
|
||||
@ -82,7 +83,7 @@ pub trait Flow: fmt::Show + ToString + Sync {
|
||||
|
||||
/// If this is a block flow, returns the underlying object. Fails otherwise.
|
||||
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
|
||||
debug!("called as_block() on a flow of type {}", self.class());
|
||||
debug!("called as_block() on a flow of type {:?}", self.class());
|
||||
panic!("called as_block() on a non-block flow")
|
||||
}
|
||||
|
||||
@ -204,10 +205,10 @@ pub trait Flow: fmt::Show + ToString + Sync {
|
||||
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
||||
layout_context: &'a LayoutContext<'a>)
|
||||
-> bool {
|
||||
let impacted = base(&*self).flags.impacted_by_floats();
|
||||
let impacted = base(self).flags.impacted_by_floats();
|
||||
if impacted {
|
||||
self.assign_block_size(layout_context);
|
||||
mut_base(&mut *self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||
mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||
}
|
||||
impacted
|
||||
}
|
||||
@ -295,7 +296,8 @@ pub trait Flow: fmt::Show + ToString + Sync {
|
||||
/// Returns a layer ID for the given fragment.
|
||||
fn layer_id(&self, fragment_id: uint) -> LayerId {
|
||||
unsafe {
|
||||
let pointer: uint = mem::transmute(self);
|
||||
let obj = mem::transmute::<&&Self, &raw::TraitObject>(&self);
|
||||
let pointer: uint = mem::transmute(obj.data);
|
||||
LayerId(pointer, fragment_id)
|
||||
}
|
||||
}
|
||||
@ -308,9 +310,9 @@ pub trait Flow: fmt::Show + ToString + Sync {
|
||||
// Base access
|
||||
|
||||
#[inline(always)]
|
||||
pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow {
|
||||
pub fn base<'a, T: ?Sized + Flow>(this: &'a T) -> &'a BaseFlow {
|
||||
unsafe {
|
||||
let obj = mem::transmute::<&'a Flow, raw::TraitObject>(this);
|
||||
let obj = mem::transmute::<&&'a T, &'a raw::TraitObject>(&this);
|
||||
mem::transmute::<*mut (), &'a BaseFlow>(obj.data)
|
||||
}
|
||||
}
|
||||
@ -321,9 +323,9 @@ pub fn imm_child_iter<'a>(flow: &'a Flow) -> FlowListIterator<'a> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow {
|
||||
pub fn mut_base<'a, T: ?Sized + Flow>(this: &'a mut T) -> &'a mut BaseFlow {
|
||||
unsafe {
|
||||
let obj = mem::transmute::<&'a mut Flow, raw::TraitObject>(this);
|
||||
let obj = mem::transmute::<&&'a mut T, &'a raw::TraitObject>(&this);
|
||||
mem::transmute::<*mut (), &'a mut BaseFlow>(obj.data)
|
||||
}
|
||||
}
|
||||
@ -423,7 +425,7 @@ pub trait MutableOwnedFlowUtils {
|
||||
fn set_absolute_descendants(&mut self, abs_descendants: AbsDescendants);
|
||||
}
|
||||
|
||||
#[deriving(Encodable, PartialEq, Show)]
|
||||
#[derive(RustcEncodable, PartialEq, Show)]
|
||||
pub enum FlowClass {
|
||||
Block,
|
||||
Inline,
|
||||
@ -465,7 +467,6 @@ pub trait PostorderFlowTraversal {
|
||||
|
||||
bitflags! {
|
||||
#[doc = "Flags used in flows."]
|
||||
#[deriving(Copy)]
|
||||
flags FlowFlags: u16 {
|
||||
// floated descendants flags
|
||||
#[doc = "Whether this flow has descendants that float left in the same block formatting"]
|
||||
@ -540,7 +541,7 @@ impl FlowFlags {
|
||||
#[inline]
|
||||
pub fn set_text_align(&mut self, value: text_align::T) {
|
||||
*self = (*self & !TEXT_ALIGN) |
|
||||
FlowFlags::from_bits(value as u16 << TEXT_ALIGN_SHIFT).unwrap();
|
||||
FlowFlags::from_bits((value as u16) << TEXT_ALIGN_SHIFT).unwrap();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -592,7 +593,7 @@ impl FlowFlags {
|
||||
/// The Descendants of a flow.
|
||||
///
|
||||
/// Also, details about their position wrt this flow.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct Descendants {
|
||||
/// Links to every descendant. This must be private because it is unsafe to leak `FlowRef`s to
|
||||
/// layout.
|
||||
@ -650,20 +651,21 @@ impl Descendants {
|
||||
pub type AbsDescendants = Descendants;
|
||||
|
||||
pub struct DescendantIter<'a> {
|
||||
iter: MutItems<'a, FlowRef>,
|
||||
iter: IterMut<'a, FlowRef>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator<&'a mut (Flow + 'a)> for DescendantIter<'a> {
|
||||
impl<'a> Iterator for DescendantIter<'a> {
|
||||
type Item = &'a mut (Flow + 'a);
|
||||
fn next(&mut self) -> Option<&'a mut (Flow + 'a)> {
|
||||
self.iter.next().map(|flow| &mut **flow)
|
||||
}
|
||||
}
|
||||
|
||||
pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, MutItems<'a, Au>>;
|
||||
pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, IterMut<'a, Au>>;
|
||||
|
||||
/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
|
||||
/// confused with absolutely-positioned flows).
|
||||
#[deriving(Encodable, Copy)]
|
||||
#[derive(RustcEncodable, Copy)]
|
||||
pub struct AbsolutePositionInfo {
|
||||
/// The size of the containing block for relatively-positioned descendants.
|
||||
pub relative_containing_block_size: LogicalSize<Au>,
|
||||
@ -776,33 +778,36 @@ pub struct BaseFlow {
|
||||
pub flags: FlowFlags,
|
||||
}
|
||||
|
||||
unsafe impl Send for BaseFlow {}
|
||||
unsafe impl Sync for BaseFlow {}
|
||||
|
||||
impl fmt::Show for BaseFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f,
|
||||
"@ {}, CC {}, ADC {}",
|
||||
"@ {:?}, CC {}, ADC {}",
|
||||
self.position,
|
||||
self.parallel.children_count.load(Ordering::SeqCst),
|
||||
self.abs_descendants.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow {
|
||||
fn encode(&self, e: &mut S) -> Result<(), E> {
|
||||
impl Encodable for BaseFlow {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
e.emit_struct("base", 0, |e| {
|
||||
try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)))
|
||||
try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)));
|
||||
try!(e.emit_struct_field("stacking_relative_position",
|
||||
1,
|
||||
|e| self.stacking_relative_position.encode(e)))
|
||||
|e| self.stacking_relative_position.encode(e)));
|
||||
try!(e.emit_struct_field("intrinsic_inline_sizes",
|
||||
2,
|
||||
|e| self.intrinsic_inline_sizes.encode(e)))
|
||||
try!(e.emit_struct_field("position", 3, |e| self.position.encode(e)))
|
||||
|e| self.intrinsic_inline_sizes.encode(e)));
|
||||
try!(e.emit_struct_field("position", 3, |e| self.position.encode(e)));
|
||||
e.emit_struct_field("children", 4, |e| {
|
||||
e.emit_seq(self.children.len(), |e| {
|
||||
for (i, c) in self.children.iter().enumerate() {
|
||||
try!(e.emit_seq_elt(i, |e| {
|
||||
try!(e.emit_struct("flow", 0, |e| {
|
||||
try!(e.emit_struct_field("class", 0, |e| c.class().encode(e)))
|
||||
try!(e.emit_struct_field("class", 0, |e| c.class().encode(e)));
|
||||
e.emit_struct_field("data", 1, |e| {
|
||||
match c.class() {
|
||||
FlowClass::Block => c.as_immutable_block().encode(e),
|
||||
@ -815,9 +820,9 @@ impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow {
|
||||
_ => { Ok(()) } // TODO: Support captions
|
||||
}
|
||||
})
|
||||
}))
|
||||
}));
|
||||
Ok(())
|
||||
}))
|
||||
}));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
@ -838,7 +843,7 @@ impl Drop for BaseFlow {
|
||||
|
||||
/// Whether a base flow should be forced to be nonfloated. This can affect e.g. `TableFlow`, which
|
||||
/// is never floated because the table wrapper flow is the floated one.
|
||||
#[deriving(Clone, PartialEq)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum ForceNonfloatedFlag {
|
||||
/// The flow should be floated if the node has a `float` property.
|
||||
FloatIfNecessary,
|
||||
@ -951,7 +956,7 @@ impl BaseFlow {
|
||||
}
|
||||
|
||||
if bounds.union(&paint_bounds.bounding_rect()) != bounds {
|
||||
error!("DisplayList item {} outside of Flow overflow ({})", item, paint_bounds);
|
||||
error!("DisplayList item {:?} outside of Flow overflow ({:?})", item, paint_bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1125,7 +1130,8 @@ impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) {
|
||||
indent.push_str("| ")
|
||||
}
|
||||
|
||||
println!("{}+ {}", indent, self.to_string());
|
||||
// TODO: ICE, already fixed in rustc.
|
||||
//println!("{}+ {:?}", indent, self);
|
||||
|
||||
for kid in imm_child_iter(self) {
|
||||
kid.dump_with_level(level + 1)
|
||||
|
@ -15,11 +15,11 @@ pub struct FlowList {
|
||||
}
|
||||
|
||||
pub struct FlowListIterator<'a> {
|
||||
it: dlist::Items<'a, FlowRef>,
|
||||
it: dlist::Iter<'a, FlowRef>,
|
||||
}
|
||||
|
||||
pub struct MutFlowListIterator<'a> {
|
||||
it: dlist::MutItems<'a, FlowRef>,
|
||||
it: dlist::IterMut<'a, FlowRef>,
|
||||
}
|
||||
|
||||
impl FlowList {
|
||||
@ -105,7 +105,8 @@ impl FlowList {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> {
|
||||
impl<'a> Iterator for FlowListIterator<'a> {
|
||||
type Item = &'a (Flow + 'a);
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a (Flow + 'a)> {
|
||||
self.it.next().map(|x| &**x)
|
||||
@ -117,7 +118,8 @@ impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<&'a mut (Flow + 'a)> for MutFlowListIterator<'a> {
|
||||
impl<'a> Iterator for MutFlowListIterator<'a> {
|
||||
type Item = &'a mut (Flow + 'a);
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a mut (Flow + 'a)> {
|
||||
self.it.next().map(|x| &mut **x)
|
||||
|
@ -10,6 +10,7 @@ use flow::Flow;
|
||||
use flow;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ptr;
|
||||
use std::raw;
|
||||
use std::sync::atomic::Ordering;
|
||||
@ -19,6 +20,9 @@ pub struct FlowRef {
|
||||
object: raw::TraitObject,
|
||||
}
|
||||
|
||||
unsafe impl Send for FlowRef {}
|
||||
unsafe impl Sync for FlowRef {}
|
||||
|
||||
impl FlowRef {
|
||||
pub fn new(mut flow: Box<Flow>) -> FlowRef {
|
||||
unsafe {
|
||||
@ -33,7 +37,8 @@ impl FlowRef {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref<Flow + 'a> for FlowRef {
|
||||
impl<'a> Deref for FlowRef {
|
||||
type Target = Flow + 'a;
|
||||
fn deref(&self) -> &(Flow + 'a) {
|
||||
unsafe {
|
||||
mem::transmute_copy::<raw::TraitObject, &(Flow + 'a)>(&self.object)
|
||||
@ -41,7 +46,7 @@ impl<'a> Deref<Flow + 'a> for FlowRef {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut<Flow + 'a> for FlowRef {
|
||||
impl<'a> DerefMut for FlowRef {
|
||||
fn deref_mut<'a>(&mut self) -> &mut (Flow + 'a) {
|
||||
unsafe {
|
||||
mem::transmute_copy::<raw::TraitObject, &mut (Flow + 'a)>(&self.object)
|
||||
|
@ -39,8 +39,10 @@ use servo_util::smallvec::SmallVec;
|
||||
use servo_util::str::is_whitespace;
|
||||
use std::cmp::{max, min};
|
||||
use std::fmt;
|
||||
use std::num::ToPrimitive;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::Sender;
|
||||
use string_cache::Atom;
|
||||
use style::{ComputedValues, TElement, TNode, cascade_anonymous};
|
||||
use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
@ -75,7 +77,7 @@ use url::Url;
|
||||
///
|
||||
/// FIXME(#2260, pcwalton): This can be slimmed down some by (at least) moving `inline_context`
|
||||
/// to be on `InlineFlow` only.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct Fragment {
|
||||
/// An opaque reference to the DOM node that this `Fragment` originates from.
|
||||
pub node: OpaqueNode,
|
||||
@ -111,11 +113,14 @@ pub struct Fragment {
|
||||
pub restyle_damage: RestyleDamage,
|
||||
}
|
||||
|
||||
impl<E, S: Encoder<E>> Encodable<S, E> for Fragment {
|
||||
fn encode(&self, e: &mut S) -> Result<(), E> {
|
||||
unsafe impl Send for Fragment {}
|
||||
unsafe impl Sync for Fragment {}
|
||||
|
||||
impl Encodable for Fragment {
|
||||
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||
e.emit_struct("fragment", 0, |e| {
|
||||
try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)))
|
||||
try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e)))
|
||||
try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e)));
|
||||
try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e)));
|
||||
e.emit_struct_field("margin", 2, |e| self.margin.encode(e))
|
||||
})
|
||||
}
|
||||
@ -124,7 +129,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Fragment {
|
||||
/// Info specific to the kind of fragment.
|
||||
///
|
||||
/// Keep this enum small. As in, no more than one word. Or pcwalton will yell at you.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum SpecificFragmentInfo {
|
||||
Generic,
|
||||
Iframe(Box<IframeFragmentInfo>),
|
||||
@ -191,7 +196,7 @@ impl SpecificFragmentInfo {
|
||||
///
|
||||
/// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout
|
||||
/// can clone it.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct InlineAbsoluteHypotheticalFragmentInfo {
|
||||
pub flow_ref: FlowRef,
|
||||
}
|
||||
@ -208,7 +213,7 @@ impl InlineAbsoluteHypotheticalFragmentInfo {
|
||||
///
|
||||
/// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout
|
||||
/// can clone it.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct InlineBlockFragmentInfo {
|
||||
pub flow_ref: FlowRef,
|
||||
}
|
||||
@ -221,7 +226,7 @@ impl InlineBlockFragmentInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct CanvasFragmentInfo {
|
||||
pub replaced_image_fragment_info: ReplacedImageFragmentInfo,
|
||||
pub renderer: Option<Arc<Mutex<Sender<CanvasMsg>>>>,
|
||||
@ -250,7 +255,7 @@ impl CanvasFragmentInfo {
|
||||
|
||||
|
||||
/// A fragment that represents a replaced content image and its accompanying borders, shadows, etc.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ImageFragmentInfo {
|
||||
/// The image held within this fragment.
|
||||
pub replaced_image_fragment_info: ReplacedImageFragmentInfo,
|
||||
@ -309,7 +314,7 @@ impl ImageFragmentInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ReplacedImageFragmentInfo {
|
||||
pub for_node: UntrustedNodeAddress,
|
||||
pub computed_inline_size: Option<Au>,
|
||||
@ -479,7 +484,7 @@ impl ReplacedImageFragmentInfo {
|
||||
|
||||
/// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the size
|
||||
/// of this iframe can be communicated via the constellation to the iframe's own layout task.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct IframeFragmentInfo {
|
||||
/// The pipeline ID of this iframe.
|
||||
pub pipeline_id: PipelineId,
|
||||
@ -502,7 +507,7 @@ impl IframeFragmentInfo {
|
||||
/// may be split into two or more fragments across line breaks. Several `TextFragment`s may
|
||||
/// correspond to a single DOM text node. Split text fragments are implemented by referring to
|
||||
/// subsets of a single `TextRun` object.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ScannedTextFragmentInfo {
|
||||
/// The text run that this represents.
|
||||
pub run: Arc<Box<TextRun>>,
|
||||
@ -543,7 +548,7 @@ impl ScannedTextFragmentInfo {
|
||||
|
||||
/// Describes how to split a fragment. This is used during line breaking as part of the return
|
||||
/// value of `find_split_info_for_inline_size()`.
|
||||
#[deriving(Show, Clone)]
|
||||
#[derive(Show, Clone)]
|
||||
pub struct SplitInfo {
|
||||
// TODO(bjz): this should only need to be a single character index, but both values are
|
||||
// currently needed for splitting in the `inline::try_append_*` functions.
|
||||
@ -572,7 +577,7 @@ pub struct SplitResult {
|
||||
|
||||
/// Data for an unscanned text fragment. Unscanned text fragments are the results of flow
|
||||
/// construction that have not yet had their inline-size determined.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct UnscannedTextFragmentInfo {
|
||||
/// The text inside the fragment.
|
||||
///
|
||||
@ -600,7 +605,7 @@ impl UnscannedTextFragmentInfo {
|
||||
}
|
||||
|
||||
/// A fragment that represents a table column.
|
||||
#[deriving(Copy, Clone)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct TableColumnFragmentInfo {
|
||||
/// the number of columns a <col> element should span
|
||||
pub span: int,
|
||||
@ -743,7 +748,7 @@ impl Fragment {
|
||||
/// if called on any other type of fragment.
|
||||
pub fn save_new_line_pos(&mut self) {
|
||||
match &mut self.specific {
|
||||
&SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
&mut SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
if !info.new_line_pos.is_empty() {
|
||||
info.original_new_line_pos = Some(info.new_line_pos.clone());
|
||||
}
|
||||
@ -754,7 +759,7 @@ impl Fragment {
|
||||
|
||||
pub fn restore_new_line_pos(&mut self) {
|
||||
match &mut self.specific {
|
||||
&SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
&mut SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
match info.original_new_line_pos.take() {
|
||||
None => {}
|
||||
Some(new_line_pos) => info.new_line_pos = new_line_pos,
|
||||
@ -1278,7 +1283,7 @@ impl Fragment {
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
||||
let mut new_line_pos = text_fragment_info.new_line_pos.clone();
|
||||
let cur_new_line_pos = new_line_pos.remove(0).unwrap();
|
||||
let cur_new_line_pos = new_line_pos.remove(0);
|
||||
|
||||
let inline_start_range = Range::new(text_fragment_info.range.begin(),
|
||||
cur_new_line_pos);
|
||||
@ -1355,7 +1360,7 @@ impl Fragment {
|
||||
max_inline_size: Au,
|
||||
flags: SplitOptions)
|
||||
-> Option<SplitResult>
|
||||
where I: Iterator<TextRunSlice<'a>> {
|
||||
where I: Iterator<Item=TextRunSlice<'a>> {
|
||||
let text_fragment_info =
|
||||
if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific {
|
||||
text_fragment_info
|
||||
@ -1368,15 +1373,15 @@ impl Fragment {
|
||||
let mut inline_start_range = Range::new(text_fragment_info.range.begin(), CharIndex(0));
|
||||
let mut inline_end_range = None;
|
||||
|
||||
debug!("calculate_split_position: splitting text fragment (strlen={}, range={}, \
|
||||
max_inline_size={})",
|
||||
debug!("calculate_split_position: splitting text fragment (strlen={}, range={:?}, \
|
||||
max_inline_size={:?})",
|
||||
text_fragment_info.run.text.len(),
|
||||
text_fragment_info.range,
|
||||
max_inline_size);
|
||||
|
||||
for slice in slice_iterator {
|
||||
debug!("calculate_split_position: considering slice (offset={}, slice range={}, \
|
||||
remaining_inline_size={})",
|
||||
debug!("calculate_split_position: considering slice (offset={:?}, slice range={:?}, \
|
||||
remaining_inline_size={:?})",
|
||||
slice.offset,
|
||||
slice.range,
|
||||
remaining_inline_size);
|
||||
@ -1408,7 +1413,7 @@ impl Fragment {
|
||||
let mut inline_end = slice.text_run_range();
|
||||
inline_end.extend_to(text_fragment_info.range.end());
|
||||
inline_end_range = Some(inline_end);
|
||||
debug!("calculate_split_position: splitting remainder with inline-end range={}",
|
||||
debug!("calculate_split_position: splitting remainder with inline-end range={:?}",
|
||||
inline_end);
|
||||
}
|
||||
|
||||
@ -1816,9 +1821,9 @@ impl Fragment {
|
||||
impl fmt::Show for Fragment {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "({} {} ", self.debug_id(), self.specific.get_type()));
|
||||
try!(write!(f, "bp {}", self.border_padding));
|
||||
try!(write!(f, "bp {:?}", self.border_padding));
|
||||
try!(write!(f, " "));
|
||||
try!(write!(f, "m {}", self.margin));
|
||||
try!(write!(f, "m {:?}", self.margin));
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
@ -1856,7 +1861,7 @@ pub trait FragmentBorderBoxIterator {
|
||||
|
||||
/// The coordinate system used in `stacking_relative_border_box()`. See the documentation of that
|
||||
/// method for details.
|
||||
#[deriving(Clone, PartialEq, Show)]
|
||||
#[derive(Clone, PartialEq, Show)]
|
||||
pub enum CoordinateSystem {
|
||||
/// The border box returned is relative to the fragment's parent stacking context.
|
||||
Parent,
|
||||
|
@ -12,7 +12,6 @@ use style::ComputedValues;
|
||||
|
||||
bitflags! {
|
||||
#[doc = "Individual layout actions that may be necessary after restyling."]
|
||||
#[deriving(Copy)]
|
||||
flags RestyleDamage: u8 {
|
||||
#[doc = "Repaint the node itself."]
|
||||
#[doc = "Currently unused; need to decide how this propagates."]
|
||||
@ -125,7 +124,7 @@ macro_rules! add_if_not_equal(
|
||||
$damage.insert($($effect)|*);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage {
|
||||
let old: &ComputedValues =
|
||||
|
@ -31,6 +31,8 @@ use servo_util::range::{Range, RangeIndex};
|
||||
use std::cmp::max;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::num::ToPrimitive;
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXor};
|
||||
use std::u16;
|
||||
use style::computed_values::{text_align, vertical_align, white_space};
|
||||
use style::ComputedValues;
|
||||
@ -65,7 +67,7 @@ static FONT_SUPERSCRIPT_OFFSET_RATIO: f64 = 0.34;
|
||||
/// with a float or a horizontal wall of the containing block. The block-start
|
||||
/// inline-start corner of the green zone is the same as that of the line, but
|
||||
/// the green zone can be taller and wider than the line itself.
|
||||
#[deriving(Encodable, Show, Copy)]
|
||||
#[derive(RustcEncodable, Show, Copy)]
|
||||
pub struct Line {
|
||||
/// A range of line indices that describe line breaks.
|
||||
///
|
||||
@ -150,7 +152,7 @@ pub struct Line {
|
||||
}
|
||||
|
||||
int_range_index! {
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
#[doc = "The index of a fragment in a flattened vector of DOM elements."]
|
||||
struct FragmentIndex(int)
|
||||
}
|
||||
@ -256,7 +258,7 @@ impl LineBreaker {
|
||||
mut old_fragment_iter: I,
|
||||
flow: &'a InlineFlow,
|
||||
layout_context: &LayoutContext)
|
||||
where I: Iterator<Fragment> {
|
||||
where I: Iterator<Item=Fragment> {
|
||||
loop {
|
||||
// Acquire the next fragment to lay out from the work list or fragment list, as
|
||||
// appropriate.
|
||||
@ -305,18 +307,18 @@ impl LineBreaker {
|
||||
/// Note that you probably don't want to call this method directly in order to be
|
||||
/// incremental-reflow-safe; try `next_unbroken_fragment` instead.
|
||||
fn next_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
|
||||
where I: Iterator<Fragment> {
|
||||
where I: Iterator<Item=Fragment> {
|
||||
if self.work_list.is_empty() {
|
||||
return match old_fragment_iter.next() {
|
||||
None => None,
|
||||
Some(fragment) => {
|
||||
debug!("LineBreaker: working with fragment from flow: {}", fragment);
|
||||
debug!("LineBreaker: working with fragment from flow: {:?}", fragment);
|
||||
Some(fragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("LineBreaker: working with fragment from work list: {}", self.work_list.front());
|
||||
debug!("LineBreaker: working with fragment from work list: {:?}", self.work_list.front());
|
||||
self.work_list.pop_front()
|
||||
}
|
||||
|
||||
@ -325,7 +327,7 @@ impl LineBreaker {
|
||||
/// fragment to lay out, undoing line break operations that any previous reflows may have
|
||||
/// performed. You probably want to be using this method instead of `next_fragment`.
|
||||
fn next_unbroken_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
|
||||
where I: Iterator<Fragment> {
|
||||
where I: Iterator<Item=Fragment> {
|
||||
let mut result = match self.next_fragment(old_fragment_iter) {
|
||||
None => return None,
|
||||
Some(fragment) => fragment,
|
||||
@ -342,7 +344,7 @@ impl LineBreaker {
|
||||
};
|
||||
|
||||
let need_to_merge = match (&mut result.specific, &candidate.specific) {
|
||||
(&SpecificFragmentInfo::ScannedText(ref mut result_info),
|
||||
(&mut SpecificFragmentInfo::ScannedText(ref mut result_info),
|
||||
&SpecificFragmentInfo::ScannedText(ref candidate_info))
|
||||
if arc_ptr_eq(&result_info.run, &candidate_info.run) &&
|
||||
result_info.range.end() + CharIndex(1) == candidate_info.range.begin() => {
|
||||
@ -362,7 +364,7 @@ impl LineBreaker {
|
||||
|
||||
/// Commits a line to the list.
|
||||
fn flush_current_line(&mut self) {
|
||||
debug!("LineBreaker: flushing line {}: {}", self.lines.len(), self.pending_line);
|
||||
debug!("LineBreaker: flushing line {}: {:?}", self.lines.len(), self.pending_line);
|
||||
self.lines.push(self.pending_line);
|
||||
self.cur_b = self.pending_line.bounds.start.b + self.pending_line.bounds.size.block;
|
||||
self.reset_line();
|
||||
@ -388,7 +390,7 @@ impl LineBreaker {
|
||||
first_fragment: &Fragment,
|
||||
ceiling: Au)
|
||||
-> (LogicalRect<Au>, Au) {
|
||||
debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {}, \
|
||||
debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {:?}, \
|
||||
splittable: {}",
|
||||
self.lines.len(),
|
||||
first_fragment.border_box.size,
|
||||
@ -496,7 +498,7 @@ impl LineBreaker {
|
||||
.expect("LineBreaker: this split case makes no sense!");
|
||||
let writing_mode = self.floats.writing_mode;
|
||||
|
||||
let split_fragment = |split: SplitInfo| {
|
||||
let split_fragment = |&:split: SplitInfo| {
|
||||
let info = box ScannedTextFragmentInfo::new(run.clone(),
|
||||
split.range,
|
||||
(*in_fragment.newline_positions()
|
||||
@ -541,7 +543,7 @@ impl LineBreaker {
|
||||
self.pending_line.green_zone = line_bounds.size;
|
||||
}
|
||||
|
||||
debug!("LineBreaker: trying to append to line {} (fragment size: {}, green zone: {}): {}",
|
||||
debug!("LineBreaker: trying to append to line {} (fragment size: {:?}, green zone: {:?}): {:?}",
|
||||
self.lines.len(),
|
||||
fragment.border_box.size,
|
||||
self.pending_line.green_zone,
|
||||
@ -586,13 +588,13 @@ impl LineBreaker {
|
||||
match fragment.calculate_split_position(available_inline_size,
|
||||
self.pending_line_is_empty()) {
|
||||
None => {
|
||||
debug!("LineBreaker: fragment was unsplittable; deferring to next line: {}",
|
||||
debug!("LineBreaker: fragment was unsplittable; deferring to next line: {:?}",
|
||||
fragment);
|
||||
self.work_list.push_front(fragment);
|
||||
return false
|
||||
}
|
||||
Some(split_result) => {
|
||||
let split_fragment = |split: SplitInfo| {
|
||||
let split_fragment = |&:split: SplitInfo| {
|
||||
let info = box ScannedTextFragmentInfo::new(split_result.text_run.clone(),
|
||||
split.range,
|
||||
Vec::new(),
|
||||
@ -657,7 +659,7 @@ impl LineBreaker {
|
||||
}
|
||||
|
||||
/// Represents a list of inline fragments, including element ranges.
|
||||
#[deriving(Encodable, Clone)]
|
||||
#[derive(RustcEncodable, Clone)]
|
||||
pub struct InlineFragments {
|
||||
/// The fragments themselves.
|
||||
pub fragments: Vec<Fragment>,
|
||||
@ -665,7 +667,7 @@ pub struct InlineFragments {
|
||||
|
||||
impl fmt::Show for InlineFragments {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.fragments)
|
||||
write!(f, "{:?}", self.fragments)
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,7 +713,7 @@ impl InlineFragments {
|
||||
}
|
||||
|
||||
/// Flows for inline layout.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct InlineFlow {
|
||||
/// Data common to all flows.
|
||||
pub base: BaseFlow,
|
||||
@ -966,7 +968,7 @@ impl Flow for InlineFlow {
|
||||
|
||||
let mut computation = IntrinsicISizesContribution::new();
|
||||
for fragment in self.fragments.fragments.iter_mut() {
|
||||
debug!("Flow: measuring {}", *fragment);
|
||||
debug!("Flow: measuring {:?}", *fragment);
|
||||
computation.union_inline(&fragment.compute_intrinsic_inline_sizes().finish())
|
||||
}
|
||||
self.base.intrinsic_inline_sizes = computation.finish()
|
||||
@ -982,7 +984,7 @@ impl Flow for InlineFlow {
|
||||
// TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into
|
||||
// `Fragment`.
|
||||
|
||||
debug!("InlineFlow::assign_inline_sizes: floats in: {}", self.base.floats);
|
||||
debug!("InlineFlow::assign_inline_sizes: floats in: {:?}", self.base.floats);
|
||||
|
||||
self.base.position.size.inline = self.base.block_container_inline_size;
|
||||
|
||||
@ -1022,7 +1024,7 @@ impl Flow for InlineFlow {
|
||||
// element to determine its block-size for computing the line's own block-size.
|
||||
//
|
||||
// TODO(pcwalton): Cache the line scanner?
|
||||
debug!("assign_block_size_inline: floats in: {}", self.base.floats);
|
||||
debug!("assign_block_size_inline: floats in: {:?}", self.base.floats);
|
||||
|
||||
// Assign the block-size for the inline fragments.
|
||||
let containing_block_block_size =
|
||||
@ -1254,11 +1256,11 @@ impl Flow for InlineFlow {
|
||||
|
||||
impl fmt::Show for InlineFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} - {:x} - {}", self.class(), self.base.debug_id(), self.fragments)
|
||||
write!(f, "{:?} - {:x} - {:?}", self.class(), self.base.debug_id(), self.fragments)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct InlineFragmentContext {
|
||||
pub styles: Vec<Arc<ComputedValues>>,
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ use serialize::json;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::RefCell;
|
||||
use std::io::File;
|
||||
use std::sync::atomic::{AtomicUint, Ordering, INIT_ATOMIC_UINT};
|
||||
use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT};
|
||||
|
||||
thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None))
|
||||
thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None));
|
||||
|
||||
static mut DEBUG_ID_COUNTER: AtomicUint = INIT_ATOMIC_UINT;
|
||||
static mut DEBUG_ID_COUNTER: AtomicUint = ATOMIC_UINT_INIT;
|
||||
|
||||
pub struct Scope;
|
||||
|
||||
@ -31,9 +31,9 @@ macro_rules! layout_debug_scope(
|
||||
layout_debug::Scope
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
struct ScopeData {
|
||||
name: String,
|
||||
pre: String,
|
||||
@ -63,12 +63,12 @@ impl Scope {
|
||||
pub fn new(name: String) -> Scope {
|
||||
STATE_KEY.with(|ref r| {
|
||||
match &mut *r.borrow_mut() {
|
||||
&Some(ref mut state) => {
|
||||
&mut Some(ref mut state) => {
|
||||
let flow_trace = json::encode(&flow::base(&*state.flow_root));
|
||||
let data = box ScopeData::new(name.clone(), flow_trace);
|
||||
state.scope_stack.push(data);
|
||||
}
|
||||
&None => {}
|
||||
&mut None => {}
|
||||
}
|
||||
});
|
||||
Scope
|
||||
@ -80,13 +80,13 @@ impl Drop for Scope {
|
||||
fn drop(&mut self) {
|
||||
STATE_KEY.with(|ref r| {
|
||||
match &mut *r.borrow_mut() {
|
||||
&Some(ref mut state) => {
|
||||
&mut Some(ref mut state) => {
|
||||
let mut current_scope = state.scope_stack.pop().unwrap();
|
||||
current_scope.post = json::encode(&flow::base(&*state.flow_root));
|
||||
let previous_scope = state.scope_stack.last_mut().unwrap();
|
||||
previous_scope.children.push(current_scope);
|
||||
}
|
||||
&None => {}
|
||||
&mut None => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
use css::node_style::StyledNode;
|
||||
use construct::ConstructionResult;
|
||||
use context::SharedLayoutContext;
|
||||
use context::{SharedLayoutContext, SharedLayoutContextWrapper};
|
||||
use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
|
||||
use flow_ref::FlowRef;
|
||||
use fragment::{Fragment, FragmentBorderBoxIterator};
|
||||
@ -61,7 +61,8 @@ use servo_util::time::{TimerMetadataFrameType, TimerMetadataReflowType, profile}
|
||||
use servo_util::workqueue::WorkQueue;
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Cell;
|
||||
use std::comm::{channel, Sender, Receiver, Select};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use style::computed_values::{filter, mix_blend_mode};
|
||||
@ -89,7 +90,7 @@ pub struct LayoutTaskData {
|
||||
pub stylist: Box<Stylist>,
|
||||
|
||||
/// The workers that we use for parallel operation.
|
||||
pub parallel_traversal: Option<WorkQueue<*const SharedLayoutContext, UnsafeFlow>>,
|
||||
pub parallel_traversal: Option<WorkQueue<SharedLayoutContextWrapper, UnsafeFlow>>,
|
||||
|
||||
/// The dirty rect. Used during display list construction.
|
||||
pub dirty: Rect<Au>,
|
||||
@ -153,19 +154,17 @@ struct LayoutImageResponder {
|
||||
}
|
||||
|
||||
impl ImageResponder<UntrustedNodeAddress> for LayoutImageResponder {
|
||||
fn respond(&self) -> proc(ImageResponseMsg, UntrustedNodeAddress):Send {
|
||||
fn respond(&self) -> Box<Fn(ImageResponseMsg, UntrustedNodeAddress)+Send> {
|
||||
let id = self.id.clone();
|
||||
let script_chan = self.script_chan.clone();
|
||||
let f: proc(ImageResponseMsg, UntrustedNodeAddress):Send =
|
||||
proc(_, node_address) {
|
||||
let ScriptControlChan(chan) = script_chan;
|
||||
debug!("Dirtying {:x}", node_address.0 as uint);
|
||||
let mut nodes = SmallVec1::new();
|
||||
nodes.vec_push(node_address);
|
||||
drop(chan.send_opt(ConstellationControlMsg::SendEvent(
|
||||
id.clone(), CompositorEvent::ReflowEvent(nodes))))
|
||||
};
|
||||
f
|
||||
box move |&:_, node_address| {
|
||||
let ScriptControlChan(ref chan) = script_chan;
|
||||
debug!("Dirtying {:x}", node_address.0 as uint);
|
||||
let mut nodes = SmallVec1::new();
|
||||
nodes.vec_push(node_address);
|
||||
drop(chan.send(ConstellationControlMsg::SendEvent(
|
||||
id, CompositorEvent::ReflowEvent(nodes))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +184,7 @@ impl LayoutTaskFactory for LayoutTask {
|
||||
time_profiler_chan: TimeProfilerChan,
|
||||
shutdown_chan: Sender<()>) {
|
||||
let ConstellationChan(con_chan) = constellation_chan.clone();
|
||||
spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, proc() {
|
||||
spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, move || {
|
||||
{ // Ensures layout task is destroyed before we send shutdown message
|
||||
let sender = chan.sender();
|
||||
let layout =
|
||||
@ -219,7 +218,8 @@ enum RWGuard<'a> {
|
||||
Used(MutexGuard<'a, LayoutTaskData>),
|
||||
}
|
||||
|
||||
impl<'a> Deref<LayoutTaskData> for RWGuard<'a> {
|
||||
impl<'a> Deref for RWGuard<'a> {
|
||||
type Target = LayoutTaskData;
|
||||
fn deref(&self) -> &LayoutTaskData {
|
||||
match *self {
|
||||
RWGuard::Held(ref x) => &**x,
|
||||
@ -228,7 +228,7 @@ impl<'a> Deref<LayoutTaskData> for RWGuard<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut<LayoutTaskData> for RWGuard<'a> {
|
||||
impl<'a> DerefMut for RWGuard<'a> {
|
||||
fn deref_mut(&mut self) -> &mut LayoutTaskData {
|
||||
match *self {
|
||||
RWGuard::Held(ref mut x) => &mut **x,
|
||||
@ -257,7 +257,7 @@ impl LayoutTask {
|
||||
let device = Device::new(MediaType::Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.0));
|
||||
let parallel_traversal = if opts::get().layout_threads != 1 {
|
||||
Some(WorkQueue::new("LayoutWorker", task_state::LAYOUT,
|
||||
opts::get().layout_threads, ptr::null()))
|
||||
opts::get().layout_threads, SharedLayoutContextWrapper(ptr::null())))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -292,7 +292,7 @@ impl LayoutTask {
|
||||
|
||||
/// Starts listening on the port.
|
||||
fn start(self) {
|
||||
let mut possibly_locked_rw_data = Some(self.rw_data.lock());
|
||||
let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap());
|
||||
while self.handle_request(&mut possibly_locked_rw_data) {
|
||||
// Loop indefinitely.
|
||||
}
|
||||
@ -347,14 +347,14 @@ impl LayoutTask {
|
||||
|
||||
match port_to_read {
|
||||
PortToRead::Pipeline => {
|
||||
match self.pipeline_port.recv() {
|
||||
match self.pipeline_port.recv().unwrap() {
|
||||
LayoutControlMsg::ExitNowMsg(exit_type) => {
|
||||
self.handle_script_request(Msg::ExitNow(exit_type), possibly_locked_rw_data)
|
||||
}
|
||||
}
|
||||
},
|
||||
PortToRead::Script => {
|
||||
let msg = self.port.recv();
|
||||
let msg = self.port.recv().unwrap();
|
||||
self.handle_script_request(msg, possibly_locked_rw_data)
|
||||
}
|
||||
}
|
||||
@ -370,7 +370,7 @@ impl LayoutTask {
|
||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
|
||||
-> RWGuard<'a> {
|
||||
match possibly_locked_rw_data.take() {
|
||||
None => RWGuard::Used(self.rw_data.lock()),
|
||||
None => RWGuard::Used((*self.rw_data).lock().unwrap()),
|
||||
Some(x) => RWGuard::Held(x),
|
||||
}
|
||||
}
|
||||
@ -434,7 +434,7 @@ impl LayoutTask {
|
||||
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
|
||||
response_chan.send(());
|
||||
loop {
|
||||
match self.port.recv() {
|
||||
match self.port.recv().unwrap() {
|
||||
Msg::ReapLayoutData(dead_layout_data) => {
|
||||
unsafe {
|
||||
LayoutTask::handle_reap_layout_data(dead_layout_data)
|
||||
@ -470,7 +470,7 @@ impl LayoutTask {
|
||||
}
|
||||
|
||||
self.paint_chan.send(PaintMsg::Exit(Some(response_chan), exit_type));
|
||||
response_port.recv()
|
||||
response_port.recv().unwrap()
|
||||
}
|
||||
|
||||
fn handle_load_stylesheet<'a>(&'a self,
|
||||
@ -499,7 +499,7 @@ impl LayoutTask {
|
||||
// Find all font-face rules and notify the font cache of them.
|
||||
// GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!)
|
||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
||||
iter_font_face_rules(&sheet, &rw_data.stylist.device, |family, src| {
|
||||
iter_font_face_rules(&sheet, &rw_data.stylist.device, &|&:family, src| {
|
||||
self.font_cache_task.add_web_font(family.to_owned(), (*src).clone());
|
||||
});
|
||||
rw_data.stylist.add_stylesheet(sheet);
|
||||
@ -734,7 +734,7 @@ impl LayoutTask {
|
||||
|
||||
{
|
||||
// Reset the image cache.
|
||||
let mut local_image_cache = rw_data.local_image_cache.lock();
|
||||
let mut local_image_cache = rw_data.local_image_cache.lock().unwrap();
|
||||
local_image_cache.next_round(self.make_on_image_available_cb());
|
||||
}
|
||||
|
||||
@ -946,14 +946,14 @@ impl LayoutRPC for LayoutRPCImpl {
|
||||
// need to compare nodes for equality. Thus we can safely work only with `OpaqueNode`.
|
||||
fn content_box(&self) -> ContentBoxResponse {
|
||||
let &LayoutRPCImpl(ref rw_data) = self;
|
||||
let rw_data = rw_data.lock();
|
||||
let rw_data = rw_data.lock().unwrap();
|
||||
ContentBoxResponse(rw_data.content_box_response)
|
||||
}
|
||||
|
||||
/// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
|
||||
fn content_boxes(&self) -> ContentBoxesResponse {
|
||||
let &LayoutRPCImpl(ref rw_data) = self;
|
||||
let rw_data = rw_data.lock();
|
||||
let rw_data = rw_data.lock().unwrap();
|
||||
ContentBoxesResponse(rw_data.content_boxes_response.clone())
|
||||
}
|
||||
|
||||
@ -962,7 +962,7 @@ impl LayoutRPC for LayoutRPCImpl {
|
||||
let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64));
|
||||
let resp = {
|
||||
let &LayoutRPCImpl(ref rw_data) = self;
|
||||
let rw_data = rw_data.lock();
|
||||
let rw_data = rw_data.lock().unwrap();
|
||||
match rw_data.stacking_context {
|
||||
None => panic!("no root stacking context!"),
|
||||
Some(ref stacking_context) => {
|
||||
@ -989,7 +989,7 @@ impl LayoutRPC for LayoutRPCImpl {
|
||||
let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64));
|
||||
{
|
||||
let &LayoutRPCImpl(ref rw_data) = self;
|
||||
let rw_data = rw_data.lock();
|
||||
let rw_data = rw_data.lock().unwrap();
|
||||
match rw_data.stacking_context {
|
||||
None => panic!("no root stacking context!"),
|
||||
Some(ref stacking_context) => {
|
||||
|
@ -2,14 +2,15 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![feature(globs, macro_rules, phase, thread_local, unsafe_destructor)]
|
||||
#![feature(thread_local, unsafe_destructor, box_syntax, plugin, int_uint)]
|
||||
|
||||
#![deny(unused_imports)]
|
||||
#![deny(unused_variables)]
|
||||
#![allow(unrooted_must_root)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(unstable)]
|
||||
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate cssparser;
|
||||
@ -19,17 +20,19 @@ extern crate gfx;
|
||||
extern crate layout_traits;
|
||||
extern crate script;
|
||||
extern crate script_traits;
|
||||
extern crate "serialize" as rustc_serialize;
|
||||
extern crate serialize;
|
||||
extern crate png;
|
||||
extern crate style;
|
||||
#[phase(plugin)]
|
||||
#[macro_use]
|
||||
#[no_link] #[plugin]
|
||||
extern crate "plugins" as servo_plugins;
|
||||
extern crate "net" as servo_net;
|
||||
extern crate "msg" as servo_msg;
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate "util" as servo_util;
|
||||
|
||||
#[phase(plugin)]
|
||||
#[no_link] #[macro_use] #[plugin]
|
||||
extern crate string_cache_macros;
|
||||
extern crate string_cache;
|
||||
|
||||
|
@ -24,7 +24,7 @@ use style::computed_values::list_style_type;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A block with the CSS `display` property equal to `list-item`.
|
||||
#[deriving(Show)]
|
||||
#[derive(Show)]
|
||||
pub struct ListItemFlow {
|
||||
/// Data common to all block flows.
|
||||
pub block_flow: BlockFlow,
|
||||
|
@ -18,7 +18,7 @@ use std::cmp::{max, min};
|
||||
use std::fmt;
|
||||
|
||||
/// A collapsible margin. See CSS 2.1 § 8.3.1.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct AdjoiningMargins {
|
||||
/// The value of the greatest positive margin.
|
||||
pub most_positive: Au,
|
||||
@ -61,7 +61,7 @@ impl AdjoiningMargins {
|
||||
}
|
||||
|
||||
/// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum CollapsibleMargins {
|
||||
/// Margins may not collapse with this flow.
|
||||
None(Au, Au),
|
||||
@ -239,14 +239,14 @@ impl MarginCollapseInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum MarginCollapseState {
|
||||
AccumulatingCollapsibleTopMargin,
|
||||
AccumulatingMarginIn,
|
||||
}
|
||||
|
||||
/// Intrinsic inline-sizes, which consist of minimum and preferred.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct IntrinsicISizes {
|
||||
/// The *minimum inline-size* of the content.
|
||||
pub minimum_inline_size: Au,
|
||||
@ -256,7 +256,7 @@ pub struct IntrinsicISizes {
|
||||
|
||||
impl fmt::Show for IntrinsicISizes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "min={}, pref={}", self.minimum_inline_size, self.preferred_inline_size)
|
||||
write!(f, "min={:?}, pref={:?}", self.minimum_inline_size, self.preferred_inline_size)
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +325,7 @@ impl IntrinsicISizesContribution {
|
||||
}
|
||||
|
||||
/// Useful helper data type when computing values for blocks and positioned elements.
|
||||
#[deriving(Copy, PartialEq, Show)]
|
||||
#[derive(Copy, PartialEq, Show)]
|
||||
pub enum MaybeAuto {
|
||||
Auto,
|
||||
Specified(Au),
|
||||
@ -358,7 +358,7 @@ impl MaybeAuto {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto {
|
||||
pub fn map<F>(&self, mapper: F) -> MaybeAuto where F: FnOnce(Au) -> Au {
|
||||
match *self {
|
||||
MaybeAuto::Auto => MaybeAuto::Auto,
|
||||
MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)),
|
||||
|
@ -6,7 +6,7 @@
|
||||
//!
|
||||
//! This code is highly unsafe. Keep this file small and easy to audit.
|
||||
|
||||
use context::{LayoutContext, SharedLayoutContext};
|
||||
use context::{LayoutContext, SharedLayoutContextWrapper, SharedLayoutContext};
|
||||
use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
|
||||
use flow;
|
||||
use flow_ref::FlowRef;
|
||||
@ -81,17 +81,17 @@ impl DomParallelInfo {
|
||||
pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
|
||||
fn run_parallel(&self,
|
||||
node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>);
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>);
|
||||
|
||||
#[inline(always)]
|
||||
fn run_parallel_helper(&self,
|
||||
unsafe_node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>,
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>,
|
||||
top_down_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<*const SharedLayoutContext,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeLayoutNode>),
|
||||
bottom_up_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<*const SharedLayoutContext,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeFlow>)) {
|
||||
// Get a real layout node.
|
||||
let node: LayoutNode = unsafe {
|
||||
@ -141,7 +141,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal {
|
||||
/// fetch-and-subtract the parent's children count.
|
||||
fn run_parallel(&self,
|
||||
mut unsafe_node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>) {
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>) {
|
||||
loop {
|
||||
// Get a real layout node.
|
||||
let node: LayoutNode = unsafe {
|
||||
@ -151,7 +151,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal {
|
||||
// Perform the appropriate traversal.
|
||||
self.process(node);
|
||||
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
|
||||
let parent =
|
||||
@ -216,7 +216,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
|
||||
/// fetch-and-subtract the parent's children count.
|
||||
fn run_parallel(&self,
|
||||
mut unsafe_flow: UnsafeFlow,
|
||||
_: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
_: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
|
||||
loop {
|
||||
unsafe {
|
||||
// Get a real flow.
|
||||
@ -261,17 +261,17 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
|
||||
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
|
||||
fn run_parallel(&self,
|
||||
unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>);
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>);
|
||||
|
||||
#[inline(always)]
|
||||
fn run_parallel_helper(&self,
|
||||
unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>,
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>,
|
||||
top_down_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<*const SharedLayoutContext,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeFlow>),
|
||||
bottom_up_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<*const SharedLayoutContext,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeFlow>)) {
|
||||
let mut had_children = false;
|
||||
unsafe {
|
||||
@ -306,7 +306,7 @@ impl<'a> ParallelPostorderFlowTraversal for BubbleISizes<'a> {}
|
||||
impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
|
||||
fn run_parallel(&self,
|
||||
unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
|
||||
self.run_parallel_helper(unsafe_flow,
|
||||
proxy,
|
||||
assign_inline_sizes,
|
||||
@ -319,7 +319,7 @@ impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {}
|
||||
impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> {
|
||||
fn run_parallel(&self,
|
||||
unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) {
|
||||
self.run_parallel_helper(unsafe_flow,
|
||||
proxy,
|
||||
compute_absolute_positions,
|
||||
@ -334,7 +334,7 @@ impl<'a> ParallelPostorderDomTraversal for ConstructFlows<'a> {}
|
||||
impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> {
|
||||
fn run_parallel(&self,
|
||||
unsafe_node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
|
||||
self.run_parallel_helper(unsafe_node,
|
||||
proxy,
|
||||
recalc_style,
|
||||
@ -343,8 +343,8 @@ impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> {
|
||||
}
|
||||
|
||||
fn recalc_style(unsafe_node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
let recalc_style_for_node_traversal = RecalcStyleForNode {
|
||||
layout_context: &layout_context,
|
||||
@ -353,8 +353,8 @@ fn recalc_style(unsafe_node: UnsafeLayoutNode,
|
||||
}
|
||||
|
||||
fn construct_flows(unsafe_node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
let construct_flows_traversal = ConstructFlows {
|
||||
layout_context: &layout_context,
|
||||
@ -363,8 +363,8 @@ fn construct_flows(unsafe_node: UnsafeLayoutNode,
|
||||
}
|
||||
|
||||
fn assign_inline_sizes(unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
let assign_inline_sizes_traversal = AssignISizes {
|
||||
layout_context: &layout_context,
|
||||
@ -373,8 +373,8 @@ fn assign_inline_sizes(unsafe_flow: UnsafeFlow,
|
||||
}
|
||||
|
||||
fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow {
|
||||
layout_context: &layout_context,
|
||||
@ -383,8 +383,8 @@ fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow,
|
||||
}
|
||||
|
||||
fn compute_absolute_positions(unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
let compute_absolute_positions_traversal = ComputeAbsolutePositions {
|
||||
layout_context: &layout_context,
|
||||
@ -393,8 +393,8 @@ fn compute_absolute_positions(unsafe_flow: UnsafeFlow,
|
||||
}
|
||||
|
||||
fn build_display_list(unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &**proxy.user_data() };
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) {
|
||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
|
||||
let build_display_list_traversal = BuildDisplayList {
|
||||
@ -406,8 +406,8 @@ fn build_display_list(unsafe_flow: UnsafeFlow,
|
||||
|
||||
pub fn traverse_dom_preorder(root: LayoutNode,
|
||||
shared_layout_context: &SharedLayoutContext,
|
||||
queue: &mut WorkQueue<*const SharedLayoutContext, UnsafeLayoutNode>) {
|
||||
queue.data = shared_layout_context as *const _;
|
||||
queue: &mut WorkQueue<SharedLayoutContextWrapper, UnsafeLayoutNode>) {
|
||||
queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _);
|
||||
|
||||
queue.push(WorkUnit {
|
||||
fun: recalc_style,
|
||||
@ -416,21 +416,21 @@ pub fn traverse_dom_preorder(root: LayoutNode,
|
||||
|
||||
queue.run();
|
||||
|
||||
queue.data = ptr::null();
|
||||
queue.data = SharedLayoutContextWrapper(ptr::null());
|
||||
}
|
||||
|
||||
pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
|
||||
profiler_metadata: ProfilerMetadata,
|
||||
time_profiler_chan: TimeProfilerChan,
|
||||
shared_layout_context: &SharedLayoutContext,
|
||||
queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) {
|
||||
if opts::get().bubble_inline_sizes_separately {
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
|
||||
root.traverse_postorder(&bubble_inline_sizes);
|
||||
}
|
||||
|
||||
queue.data = shared_layout_context as *const _;
|
||||
queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _);
|
||||
|
||||
profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata,
|
||||
time_profiler_chan, || {
|
||||
@ -442,15 +442,15 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
|
||||
|
||||
queue.run();
|
||||
|
||||
queue.data = ptr::null()
|
||||
queue.data = SharedLayoutContextWrapper(ptr::null())
|
||||
}
|
||||
|
||||
pub fn build_display_list_for_subtree(root: &mut FlowRef,
|
||||
profiler_metadata: ProfilerMetadata,
|
||||
time_profiler_chan: TimeProfilerChan,
|
||||
shared_layout_context: &SharedLayoutContext,
|
||||
queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
queue.data = shared_layout_context as *const _;
|
||||
queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) {
|
||||
queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _);
|
||||
|
||||
profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata,
|
||||
time_profiler_chan, || {
|
||||
@ -462,5 +462,5 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef,
|
||||
|
||||
queue.run();
|
||||
|
||||
queue.data = ptr::null()
|
||||
queue.data = SharedLayoutContextWrapper(ptr::null())
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ use std::sync::Arc;
|
||||
/// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
|
||||
/// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
|
||||
/// not table fragment per CSS 2.1 § 10.5.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct TableFlow {
|
||||
pub block_flow: BlockFlow,
|
||||
|
||||
@ -399,7 +399,7 @@ impl Flow for TableFlow {
|
||||
impl fmt::Show for TableFlow {
|
||||
/// Outputs a debugging string describing this table flow.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TableFlow: {}", self.block_flow)
|
||||
write!(f, "TableFlow: {:?}", self.block_flow)
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,7 +441,7 @@ impl ISizeAndMarginsComputer for InternalTable {
|
||||
/// maximum of 100 pixels and 20% of the table), the preceding constraint means that we must
|
||||
/// potentially store both a specified width *and* a specified percentage, so that the inline-size
|
||||
/// assignment phase of layout will know which one to pick.
|
||||
#[deriving(Clone, Encodable, Show, Copy)]
|
||||
#[derive(Clone, RustcEncodable, Show, Copy)]
|
||||
pub struct ColumnIntrinsicInlineSize {
|
||||
/// The preferred intrinsic inline size.
|
||||
pub preferred: Au,
|
||||
@ -485,7 +485,7 @@ impl ColumnIntrinsicInlineSize {
|
||||
///
|
||||
/// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too
|
||||
/// eventually.
|
||||
#[deriving(Encodable, Copy)]
|
||||
#[derive(RustcEncodable, Copy)]
|
||||
pub struct ColumnComputedInlineSize {
|
||||
/// The computed size of this inline column.
|
||||
pub size: Au,
|
||||
|
@ -95,6 +95,6 @@ impl Flow for TableCaptionFlow {
|
||||
|
||||
impl fmt::Show for TableCaptionFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TableCaptionFlow: {}", self.block_flow)
|
||||
write!(f, "TableCaptionFlow: {:?}", self.block_flow)
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use style::{UnsignedIntegerAttribute, ComputedValues};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A table formatting context.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct TableCellFlow {
|
||||
/// Data common to all block flows.
|
||||
pub block_flow: BlockFlow,
|
||||
@ -176,6 +176,6 @@ impl Flow for TableCellFlow {
|
||||
|
||||
impl fmt::Show for TableCellFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TableCellFlow: {}", self.block_flow)
|
||||
write!(f, "TableCellFlow: {:?}", self.block_flow)
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ impl Flow for TableColGroupFlow {
|
||||
impl fmt::Show for TableColGroupFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.fragment {
|
||||
Some(ref rb) => write!(f, "TableColGroupFlow: {}", rb),
|
||||
Some(ref rb) => write!(f, "TableColGroupFlow: {:?}", rb),
|
||||
None => write!(f, "TableColGroupFlow"),
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use style::computed_values::LengthOrPercentageOrAuto;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A single row of a table.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct TableRowFlow {
|
||||
pub block_flow: BlockFlow,
|
||||
|
||||
@ -39,7 +39,7 @@ pub struct TableRowFlow {
|
||||
}
|
||||
|
||||
/// Information about the column inline size and span for each cell.
|
||||
#[deriving(Encodable, Copy)]
|
||||
#[derive(RustcEncodable, Copy)]
|
||||
pub struct CellIntrinsicInlineSize {
|
||||
/// Inline sizes that this cell contributes to the column.
|
||||
pub column_size: ColumnIntrinsicInlineSize,
|
||||
@ -329,6 +329,6 @@ impl Flow for TableRowFlow {
|
||||
|
||||
impl fmt::Show for TableRowFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TableRowFlow: {}", self.block_flow.fragment)
|
||||
write!(f, "TableRowFlow: {:?}", self.block_flow.fragment)
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use style::ComputedValues;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A table formatting context.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct TableRowGroupFlow {
|
||||
/// Fields common to all block flows.
|
||||
pub block_flow: BlockFlow,
|
||||
@ -164,6 +164,6 @@ impl Flow for TableRowGroupFlow {
|
||||
|
||||
impl fmt::Show for TableRowGroupFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TableRowGroupFlow: {}", self.block_flow.fragment)
|
||||
write!(f, "TableRowGroupFlow: {:?}", self.block_flow.fragment)
|
||||
}
|
||||
}
|
||||
|
@ -27,18 +27,19 @@ use geom::{Point2D, Rect};
|
||||
use servo_util::geometry::Au;
|
||||
use std::cmp::{max, min};
|
||||
use std::fmt;
|
||||
use std::ops::Add;
|
||||
use style::{ComputedValues, CSSFloat};
|
||||
use style::computed_values::{table_layout, LengthOrPercentageOrAuto};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[deriving(Copy, Encodable, Show)]
|
||||
#[derive(Copy, RustcEncodable, Show)]
|
||||
pub enum TableLayout {
|
||||
Fixed,
|
||||
Auto
|
||||
}
|
||||
|
||||
/// A table wrapper flow based on a block formatting context.
|
||||
#[deriving(Encodable)]
|
||||
#[derive(RustcEncodable)]
|
||||
pub struct TableWrapperFlow {
|
||||
pub block_flow: BlockFlow,
|
||||
|
||||
@ -144,11 +145,11 @@ impl TableWrapperFlow {
|
||||
// Compute all the guesses for the column sizes, and sum them.
|
||||
let mut total_guess = AutoLayoutCandidateGuess::new();
|
||||
let guesses: Vec<AutoLayoutCandidateGuess> =
|
||||
self.column_intrinsic_inline_sizes.iter().map(|column_intrinsic_inline_size| {
|
||||
self.column_intrinsic_inline_sizes.iter().map(|&mut:column_intrinsic_inline_size| {
|
||||
let guess = AutoLayoutCandidateGuess::from_column_intrinsic_inline_size(
|
||||
column_intrinsic_inline_size,
|
||||
available_inline_size);
|
||||
total_guess = total_guess + guess;
|
||||
total_guess = &total_guess + &guess;
|
||||
guess
|
||||
}).collect();
|
||||
|
||||
@ -383,9 +384,9 @@ impl Flow for TableWrapperFlow {
|
||||
impl fmt::Show for TableWrapperFlow {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.block_flow.base.flags.is_float() {
|
||||
write!(f, "TableWrapperFlow(Float): {}", self.block_flow.fragment)
|
||||
write!(f, "TableWrapperFlow(Float): {:?}", self.block_flow.fragment)
|
||||
} else {
|
||||
write!(f, "TableWrapperFlow: {}", self.block_flow.fragment)
|
||||
write!(f, "TableWrapperFlow: {:?}", self.block_flow.fragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -482,9 +483,10 @@ impl AutoLayoutCandidateGuess {
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandidateGuess {
|
||||
impl<'a> Add for &'a AutoLayoutCandidateGuess {
|
||||
type Output = AutoLayoutCandidateGuess;
|
||||
#[inline]
|
||||
fn add(&self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess {
|
||||
fn add(self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess {
|
||||
AutoLayoutCandidateGuess {
|
||||
minimum_guess: self.minimum_guess + other.minimum_guess,
|
||||
minimum_percentage_guess:
|
||||
@ -497,7 +499,7 @@ impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandid
|
||||
|
||||
/// The `CSSFloat` member specifies the weight of the smaller of the two guesses, on a scale from
|
||||
/// 0.0 to 1.0.
|
||||
#[deriving(Copy, PartialEq, Show)]
|
||||
#[derive(Copy, PartialEq, Show)]
|
||||
enum SelectedAutoLayoutCandidateGuess {
|
||||
UseMinimumGuess,
|
||||
InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(CSSFloat),
|
||||
|
@ -195,13 +195,13 @@ impl TextRunScanner {
|
||||
let range = *new_ranges.get(logical_offset);
|
||||
if range.is_empty() {
|
||||
debug!("Elided an `SpecificFragmentInfo::UnscannedText` because it was zero-length after \
|
||||
compression; {}",
|
||||
compression; {:?}",
|
||||
old_fragment);
|
||||
continue
|
||||
}
|
||||
|
||||
let text_size = old_fragment.border_box.size;
|
||||
let &NewLinePositions(ref mut new_line_positions) =
|
||||
let &mut NewLinePositions(ref mut new_line_positions) =
|
||||
new_line_positions.get_mut(logical_offset);
|
||||
let new_text_fragment_info =
|
||||
box ScannedTextFragmentInfo::new(run.clone(),
|
||||
|
@ -48,7 +48,7 @@ type Generation = uint;
|
||||
/// Since a work-stealing queue is used for styling, sometimes, the bloom filter
|
||||
/// will no longer be the for the parent of the node we're currently on. When
|
||||
/// this happens, the task local bloom filter will be thrown away and rebuilt.
|
||||
thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None))
|
||||
thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None));
|
||||
|
||||
/// Returns the task local bloom filter.
|
||||
///
|
||||
@ -74,7 +74,7 @@ fn take_task_local_bloom_filter(parent_node: Option<LayoutNode>, layout_context:
|
||||
// Hey, the cached parent is our parent! We can reuse the bloom filter.
|
||||
if old_node == layout_node_to_unsafe_layout_node(&parent) &&
|
||||
old_generation == layout_context.shared.generation {
|
||||
debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0());
|
||||
debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.0);
|
||||
bloom_filter.clone()
|
||||
} else {
|
||||
// Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing
|
||||
@ -120,7 +120,7 @@ fn insert_ancestors_into_bloom_filter(bf: &mut Box<BloomFilter>,
|
||||
|
||||
/// The recalc-style-for-node traversal, which styles each node and must run before
|
||||
/// layout computation. This computes the styles applied to each node.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct RecalcStyleForNode<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
}
|
||||
@ -200,7 +200,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
|
||||
|
||||
// Before running the children, we need to insert our nodes into the bloom
|
||||
// filter.
|
||||
debug!("[{}] + {:X}", tid(), unsafe_layout_node.val0());
|
||||
debug!("[{}] + {:X}", tid(), unsafe_layout_node.0);
|
||||
node.insert_into_bloom_filter(&mut *bf);
|
||||
|
||||
// NB: flow construction updates the bloom filter on the way up.
|
||||
@ -209,7 +209,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
|
||||
}
|
||||
|
||||
/// The flow construction traversal, which builds flows for styled nodes.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct ConstructFlows<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
}
|
||||
@ -258,7 +258,7 @@ impl<'a> PostorderDomTraversal for ConstructFlows<'a> {
|
||||
|
||||
match node.layout_parent_node(self.layout_context.shared) {
|
||||
None => {
|
||||
debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.val0());
|
||||
debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.0);
|
||||
// If this is the reflow root, eat the task-local bloom filter.
|
||||
}
|
||||
Some(parent) => {
|
||||
@ -308,7 +308,7 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> {
|
||||
}
|
||||
|
||||
/// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct AssignISizes<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
}
|
||||
@ -329,7 +329,7 @@ impl<'a> PreorderFlowTraversal for AssignISizes<'a> {
|
||||
/// layout computation. Determines the final block-sizes for all layout objects, computes
|
||||
/// positions, and computes overflow regions. In Gecko this corresponds to `Reflow` and
|
||||
/// `FinishAndStoreOverflow`.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct AssignBSizesAndStoreOverflow<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
}
|
||||
@ -354,7 +354,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct ComputeAbsolutePositions<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
}
|
||||
@ -366,7 +366,7 @@ impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct BuildDisplayList<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ impl PrivateLayoutData {
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[deriving(Copy)]
|
||||
flags LayoutDataFlags: u8 {
|
||||
#[doc="Whether a flow has been newly constructed."]
|
||||
const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01
|
||||
@ -77,6 +76,14 @@ pub struct LayoutDataWrapper {
|
||||
pub data: Box<PrivateLayoutData>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn static_assertion(x: Option<LayoutDataWrapper>) {
|
||||
unsafe {
|
||||
let _: Option<::script::dom::node::LayoutData> =
|
||||
::std::intrinsics::transmute(x);
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that allows access to the layout data of a DOM node.
|
||||
pub trait LayoutDataAccess {
|
||||
/// Borrows the layout data without checks.
|
||||
|
@ -49,8 +49,8 @@ use script::dom::htmlelement::HTMLElementTypeId;
|
||||
use script::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers};
|
||||
use script::dom::htmliframeelement::HTMLIFrameElement;
|
||||
use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers;
|
||||
use script::dom::htmlinputelement::LayoutHTMLInputElementHelpers;
|
||||
use script::dom::htmltextareaelement::LayoutHTMLTextAreaElementHelpers;
|
||||
use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
||||
use script::dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers};
|
||||
use script::dom::node::{Node, NodeTypeId};
|
||||
use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers, SharedLayoutData};
|
||||
use script::dom::node::{HAS_CHANGED, IS_DIRTY, HAS_DIRTY_SIBLINGS, HAS_DIRTY_DESCENDANTS};
|
||||
@ -58,8 +58,9 @@ use script::dom::text::Text;
|
||||
use script::layout_interface::LayoutChan;
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||
use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
|
||||
use std::kinds::marker::ContravariantLifetime;
|
||||
use std::marker::ContravariantLifetime;
|
||||
use std::mem;
|
||||
use std::sync::mpsc::Sender;
|
||||
use string_cache::{Atom, Namespace};
|
||||
use style::computed_values::{content, display, white_space};
|
||||
use style::{NamespaceConstraint, AttrSelector, IntegerAttribute};
|
||||
@ -161,7 +162,7 @@ pub trait TLayoutNode {
|
||||
|
||||
/// A wrapper so that layout can access only the methods that it should have access to. Layout must
|
||||
/// only ever see these and must never see instances of `JS`.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct LayoutNode<'a> {
|
||||
/// The wrapped node.
|
||||
node: JS<Node>,
|
||||
@ -212,15 +213,20 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
|
||||
|
||||
fn text(&self) -> String {
|
||||
unsafe {
|
||||
if let Some(text) = TextCast::to_js(self.get_jsmanaged()) {
|
||||
(*text.unsafe_get()).characterdata().data_for_layout().to_owned()
|
||||
} else if let Some(input) = HTMLInputElementCast::to_js(self.get_jsmanaged()) {
|
||||
input.get_value_for_layout()
|
||||
} else if let Some(area) = HTMLTextAreaElementCast::to_js(self.get_jsmanaged()) {
|
||||
area.get_value_for_layout()
|
||||
} else {
|
||||
panic!("not text!")
|
||||
let text: Option<JS<Text>> = TextCast::to_js(self.get_jsmanaged());
|
||||
if let Some(text) = text {
|
||||
return (*text.unsafe_get()).characterdata().data_for_layout().to_owned();
|
||||
}
|
||||
let input: Option<JS<HTMLInputElement>> = HTMLInputElementCast::to_js(self.get_jsmanaged());
|
||||
if let Some(input) = input {
|
||||
return input.get_value_for_layout();
|
||||
}
|
||||
let area: Option<JS<HTMLTextAreaElement>> = HTMLTextAreaElementCast::to_js(self.get_jsmanaged());
|
||||
if let Some(area) = area {
|
||||
return area.get_value_for_layout();
|
||||
}
|
||||
|
||||
panic!("not text!")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -245,7 +251,7 @@ impl<'ln> LayoutNode<'ln> {
|
||||
}
|
||||
|
||||
fn debug_str(self) -> String {
|
||||
format!("{}: changed={} dirty={} dirty_descendants={}",
|
||||
format!("{:?}: changed={} dirty={} dirty_descendants={}",
|
||||
self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants())
|
||||
}
|
||||
|
||||
@ -383,8 +389,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> {
|
||||
self.node_is_document()
|
||||
}
|
||||
|
||||
fn match_attr(self, attr: &AttrSelector, test: |&str| -> bool) -> bool {
|
||||
assert!(self.is_element())
|
||||
fn match_attr<F>(self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool {
|
||||
assert!(self.is_element());
|
||||
let name = if self.is_html_element_in_html_document() {
|
||||
&attr.lower_name
|
||||
} else {
|
||||
@ -448,7 +454,8 @@ pub struct LayoutNodeChildrenIterator<'a> {
|
||||
current: Option<LayoutNode<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> {
|
||||
impl<'a> Iterator for LayoutNodeChildrenIterator<'a> {
|
||||
type Item = LayoutNode<'a>;
|
||||
fn next(&mut self) -> Option<LayoutNode<'a>> {
|
||||
let node = self.current;
|
||||
self.current = node.and_then(|node| node.next_sibling());
|
||||
@ -460,7 +467,8 @@ pub struct LayoutNodeReverseChildrenIterator<'a> {
|
||||
current: Option<LayoutNode<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeReverseChildrenIterator<'a> {
|
||||
impl<'a> Iterator for LayoutNodeReverseChildrenIterator<'a> {
|
||||
type Item = LayoutNode<'a>;
|
||||
fn next(&mut self) -> Option<LayoutNode<'a>> {
|
||||
let node = self.current;
|
||||
self.current = node.and_then(|node| node.prev_sibling());
|
||||
@ -482,7 +490,8 @@ impl<'a> LayoutTreeIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> {
|
||||
impl<'a> Iterator for LayoutTreeIterator<'a> {
|
||||
type Item = LayoutNode<'a>;
|
||||
fn next(&mut self) -> Option<LayoutNode<'a>> {
|
||||
let ret = self.stack.pop();
|
||||
ret.map(|node| self.stack.extend(node.rev_children()));
|
||||
@ -491,7 +500,7 @@ impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> {
|
||||
}
|
||||
|
||||
/// A wrapper around elements that ensures layout can only ever access safe properties.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct LayoutElement<'le> {
|
||||
element: &'le Element,
|
||||
}
|
||||
@ -530,7 +539,8 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
|
||||
|
||||
fn get_link(self) -> Option<&'le str> {
|
||||
// FIXME: This is HTML only.
|
||||
match NodeCast::from_actual(self.element).type_id_for_layout() {
|
||||
let node: &Node = NodeCast::from_actual(self.element);
|
||||
match node.type_id_for_layout() {
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#
|
||||
// selector-link
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||
@ -547,7 +557,8 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
|
||||
#[inline]
|
||||
fn get_hover_state(self) -> bool {
|
||||
unsafe {
|
||||
NodeCast::from_actual(self.element).get_hover_state_for_layout()
|
||||
let node: &Node = NodeCast::from_actual(self.element);
|
||||
node.get_hover_state_for_layout()
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,14 +572,16 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
|
||||
#[inline]
|
||||
fn get_disabled_state(self) -> bool {
|
||||
unsafe {
|
||||
NodeCast::from_actual(self.element).get_disabled_state_for_layout()
|
||||
let node: &Node = NodeCast::from_actual(self.element);
|
||||
node.get_disabled_state_for_layout()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_enabled_state(self) -> bool {
|
||||
unsafe {
|
||||
NodeCast::from_actual(self.element).get_enabled_state_for_layout()
|
||||
let node: &Node = NodeCast::from_actual(self.element);
|
||||
node.get_enabled_state_for_layout()
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,7 +607,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn each_class(self, callback: |&Atom|) {
|
||||
fn each_class<F>(self, mut callback: F) where F: FnMut(&Atom) {
|
||||
unsafe {
|
||||
match self.element.get_classes_for_layout() {
|
||||
None => {}
|
||||
@ -658,7 +671,7 @@ fn get_content(content_list: &content::T) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Copy, PartialEq, Clone)]
|
||||
#[derive(Copy, PartialEq, Clone)]
|
||||
pub enum PseudoElementType {
|
||||
Normal,
|
||||
Before(display::T),
|
||||
@ -683,7 +696,7 @@ impl PseudoElementType {
|
||||
|
||||
/// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout
|
||||
/// node does not allow any parents or siblings of nodes to be accessed, to avoid races.
|
||||
#[deriving(Copy, Clone)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ThreadSafeLayoutNode<'ln> {
|
||||
/// The wrapped node.
|
||||
node: LayoutNode<'ln>,
|
||||
@ -946,7 +959,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||
|
||||
pub fn get_input_value(&self) -> String {
|
||||
unsafe {
|
||||
match HTMLInputElementCast::to_js(self.get_jsmanaged()) {
|
||||
let input: Option<JS<HTMLInputElement>> = HTMLInputElementCast::to_js(self.get_jsmanaged());
|
||||
match input {
|
||||
Some(input) => input.get_value_for_layout(),
|
||||
None => panic!("not an input element!")
|
||||
}
|
||||
@ -965,7 +979,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||
pub fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute)
|
||||
-> Option<u32> {
|
||||
unsafe {
|
||||
match ElementCast::to_js(self.get_jsmanaged()) {
|
||||
let elem: Option<JS<Element>> = ElementCast::to_js(self.get_jsmanaged());
|
||||
match elem {
|
||||
Some(element) => {
|
||||
(*element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute)
|
||||
}
|
||||
@ -985,7 +1000,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||
pub fn set_restyle_damage(self, damage: RestyleDamage) {
|
||||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
match &mut *layout_data_ref {
|
||||
&Some(ref mut layout_data) => layout_data.data.restyle_damage = damage,
|
||||
&mut Some(ref mut layout_data) => layout_data.data.restyle_damage = damage,
|
||||
_ => panic!("no layout data for this node"),
|
||||
}
|
||||
}
|
||||
@ -1004,7 +1019,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||
pub fn insert_flags(self, new_flags: LayoutDataFlags) {
|
||||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
match &mut *layout_data_ref {
|
||||
&Some(ref mut layout_data) => layout_data.data.flags.insert(new_flags),
|
||||
&mut Some(ref mut layout_data) => layout_data.data.flags.insert(new_flags),
|
||||
_ => panic!("no layout data for this node"),
|
||||
}
|
||||
}
|
||||
@ -1013,7 +1028,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||
pub fn remove_flags(self, flags: LayoutDataFlags) {
|
||||
let mut layout_data_ref = self.mutate_layout_data();
|
||||
match &mut *layout_data_ref {
|
||||
&Some(ref mut layout_data) => layout_data.data.flags.remove(flags),
|
||||
&mut Some(ref mut layout_data) => layout_data.data.flags.remove(flags),
|
||||
_ => panic!("no layout data for this node"),
|
||||
}
|
||||
}
|
||||
@ -1033,7 +1048,8 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'a> {
|
||||
parent_node: Option<ThreadSafeLayoutNode<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIterator<'a> {
|
||||
impl<'a> Iterator for ThreadSafeLayoutNodeChildrenIterator<'a> {
|
||||
type Item = ThreadSafeLayoutNode<'a>;
|
||||
fn next(&mut self) -> Option<ThreadSafeLayoutNode<'a>> {
|
||||
let node = self.current_node.clone();
|
||||
|
||||
|
@ -24,7 +24,7 @@ use servo_net::image_cache_task::ImageCacheTask;
|
||||
use servo_net::resource_task::ResourceTask;
|
||||
use servo_util::time::TimeProfilerChan;
|
||||
use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel};
|
||||
use std::comm::Sender;
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
|
||||
/// Messages sent to the layout task from the constellation
|
||||
pub enum LayoutControlMsg {
|
||||
|
@ -33,5 +33,5 @@ git = "https://github.com/servo/rust-core-foundation"
|
||||
[dependencies.io_surface]
|
||||
git = "https://github.com/servo/rust-io-surface"
|
||||
|
||||
[dependencies.url]
|
||||
git = "https://github.com/servo/rust-url"
|
||||
[dependencies]
|
||||
url = "*"
|
@ -14,13 +14,13 @@ use std::fmt;
|
||||
use constellation_msg::PipelineId;
|
||||
|
||||
/// The status of the painter.
|
||||
#[deriving(PartialEq, Eq, Clone, Copy)]
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum PaintState {
|
||||
Idle,
|
||||
Painting,
|
||||
}
|
||||
|
||||
#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Copy)]
|
||||
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Copy)]
|
||||
pub enum ReadyState {
|
||||
/// Informs the compositor that nothing has been done yet. Used for setting status
|
||||
Blank,
|
||||
@ -33,7 +33,7 @@ pub enum ReadyState {
|
||||
}
|
||||
|
||||
/// A newtype struct for denoting the age of messages; prevents race conditions.
|
||||
#[deriving(PartialEq, Eq, Show, Copy)]
|
||||
#[derive(PartialEq, Eq, Show, Copy)]
|
||||
pub struct Epoch(pub uint);
|
||||
|
||||
impl Epoch {
|
||||
@ -43,7 +43,7 @@ impl Epoch {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Copy)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy)]
|
||||
pub struct LayerId(pub uint, pub uint);
|
||||
|
||||
impl Show for LayerId {
|
||||
@ -61,7 +61,7 @@ impl LayerId {
|
||||
}
|
||||
|
||||
/// The scrolling policy of a layer.
|
||||
#[deriving(Clone, PartialEq, Eq, Copy)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy)]
|
||||
pub enum ScrollPolicy {
|
||||
/// These layers scroll when the parent receives a scrolling message.
|
||||
Scrollable,
|
||||
@ -71,7 +71,7 @@ pub enum ScrollPolicy {
|
||||
|
||||
/// All layer-specific information that the painting task sends to the compositor other than the
|
||||
/// buffer contents of the layer itself.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct LayerMetadata {
|
||||
/// An opaque ID. This is usually the address of the flow and index of the box within it.
|
||||
pub id: LayerId,
|
||||
@ -85,7 +85,7 @@ pub struct LayerMetadata {
|
||||
|
||||
/// The interface used by the painter to acquire draw targets for each paint frame and
|
||||
/// submit them to be drawn to the display.
|
||||
pub trait PaintListener for Sized? {
|
||||
pub trait PaintListener {
|
||||
fn get_graphics_metadata(&mut self) -> Option<NativeGraphicsMetadata>;
|
||||
|
||||
/// Informs the compositor of the layers for the given pipeline. The compositor responds by
|
||||
|
@ -13,10 +13,10 @@ use hyper::method::Method;
|
||||
use layers::geometry::DevicePixel;
|
||||
use servo_util::cursor::Cursor;
|
||||
use servo_util::geometry::{PagePx, ViewportPx};
|
||||
use std::comm::{channel, Sender, Receiver};
|
||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||
use url::Url;
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ConstellationChan(pub Sender<Msg>);
|
||||
|
||||
impl ConstellationChan {
|
||||
@ -26,20 +26,20 @@ impl ConstellationChan {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Copy)]
|
||||
#[derive(PartialEq, Eq, Copy)]
|
||||
pub enum IFrameSandboxState {
|
||||
IFrameSandboxed,
|
||||
IFrameUnsandboxed
|
||||
}
|
||||
|
||||
// We pass this info to various tasks, so it lives in a separate, cloneable struct.
|
||||
#[deriving(Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Failure {
|
||||
pub pipeline_id: PipelineId,
|
||||
pub subpage_id: Option<SubpageId>,
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub struct WindowSizeData {
|
||||
/// The size of the initial layout viewport, before parsing an
|
||||
/// http://www.w3.org/TR/css-device-adapt/#initial-viewport
|
||||
@ -52,7 +52,7 @@ pub struct WindowSizeData {
|
||||
pub device_pixel_ratio: ScaleFactor<ViewportPx, DevicePixel, f32>,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Copy, Clone)]
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub enum KeyState {
|
||||
Pressed,
|
||||
Released,
|
||||
@ -60,7 +60,7 @@ pub enum KeyState {
|
||||
}
|
||||
|
||||
//N.B. Straight up copied from glfw-rs
|
||||
#[deriving(Show, PartialEq, Eq, Copy, Clone)]
|
||||
#[derive(Show, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Key {
|
||||
Space,
|
||||
Apostrophe,
|
||||
@ -186,7 +186,6 @@ pub enum Key {
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[deriving(Copy)]
|
||||
flags KeyModifiers: u8 {
|
||||
const SHIFT = 0x01,
|
||||
const CONTROL = 0x02,
|
||||
@ -218,7 +217,7 @@ pub enum Msg {
|
||||
/// Similar to net::resource_task::LoadData
|
||||
/// can be passed to LoadUrl to load a page with GET/POST
|
||||
/// parameters or headers
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct LoadData {
|
||||
pub url: Url,
|
||||
pub method: Method,
|
||||
@ -238,27 +237,27 @@ impl LoadData {
|
||||
}
|
||||
|
||||
/// Represents the two different ways to which a page can be navigated
|
||||
#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
pub enum NavigationType {
|
||||
Load, // entered or clicked on a url
|
||||
Navigate, // browser forward/back buttons
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
pub enum NavigationDirection {
|
||||
Forward,
|
||||
Back,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
pub struct PipelineId(pub uint);
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Show)]
|
||||
pub struct SubpageId(pub uint);
|
||||
|
||||
// The type of pipeline exit. During complete shutdowns, pipelines do not have to
|
||||
// release resources automatically released on process termination.
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum PipelineExitType {
|
||||
PipelineOnly,
|
||||
Complete,
|
||||
|
@ -2,6 +2,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![feature(int_uint)]
|
||||
|
||||
#![deny(unused_imports)]
|
||||
#![deny(unused_variables)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
|
@ -23,8 +23,6 @@ git = "https://github.com/servo/rust-png"
|
||||
[dependencies.stb_image]
|
||||
git = "https://github.com/servo/rust-stb-image"
|
||||
|
||||
[dependencies.url]
|
||||
git = "https://github.com/servo/rust-url"
|
||||
|
||||
[dependencies.time]
|
||||
git = "https://github.com/rust-lang/time"
|
||||
[dependencies]
|
||||
url = "*"
|
||||
time = "*"
|
@ -12,6 +12,7 @@ use servo_util::resource_files::resources_dir_path;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::io::fs::PathExtensions;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
pub fn factory(mut load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
let senders = ResponseSenders {
|
||||
|
@ -10,6 +10,7 @@ use serialize::base64::FromBase64;
|
||||
use hyper::mime::Mime;
|
||||
use url::{percent_decode, SchemeData};
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
// NB: we don't spawn a new task.
|
||||
@ -59,7 +60,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
|
||||
// Parse the content type using rust-http.
|
||||
// FIXME: this can go into an infinite loop! (rust-http #25)
|
||||
let content_type: Option<Mime> = from_str(ct_str);
|
||||
let content_type: Option<Mime> = ct_str.parse();
|
||||
metadata.set_content_type(content_type.as_ref());
|
||||
|
||||
let progress_chan = start_sending(senders, metadata);
|
||||
@ -89,19 +90,19 @@ fn assert_parse(url: &'static str,
|
||||
content_type: Option<(String, String)>,
|
||||
charset: Option<String>,
|
||||
data: Option<Vec<u8>>) {
|
||||
use std::comm;
|
||||
use std::sync::mpsc::channel;
|
||||
use url::Url;
|
||||
use sniffer_task;
|
||||
|
||||
let (start_chan, start_port) = comm::channel();
|
||||
let (start_chan, start_port) = channel();
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
load(LoadData::new(Url::parse(url).unwrap(), start_chan), sniffer_task);
|
||||
|
||||
let response = start_port.recv();
|
||||
let response = start_port.recv().unwrap();
|
||||
assert_eq!(&response.metadata.content_type, &content_type);
|
||||
assert_eq!(&response.metadata.charset, &charset);
|
||||
|
||||
let progress = response.progress_port.recv();
|
||||
let progress = response.progress_port.recv().unwrap();
|
||||
|
||||
match data {
|
||||
None => {
|
||||
@ -109,7 +110,7 @@ fn assert_parse(url: &'static str,
|
||||
}
|
||||
Some(dat) => {
|
||||
assert_eq!(progress, Payload(dat));
|
||||
assert_eq!(response.progress_port.recv(), Done(Ok(())));
|
||||
assert_eq!(response.progress_port.recv().unwrap(), Done(Ok(())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
use hyper::method::Method;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::comm::{Sender, Receiver, channel};
|
||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
||||
use time;
|
||||
use time::{now, Timespec};
|
||||
use url::Url;
|
||||
@ -19,7 +19,7 @@ use url::Url;
|
||||
/// Union type for CORS cache entries
|
||||
///
|
||||
/// Each entry might pertain to a header or method
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum HeaderOrMethod {
|
||||
HeaderData(String),
|
||||
MethodData(Method)
|
||||
@ -42,7 +42,7 @@ impl HeaderOrMethod {
|
||||
}
|
||||
|
||||
/// An entry in the CORS cache
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct CORSCacheEntry {
|
||||
pub origin: Url,
|
||||
pub url: Url,
|
||||
@ -100,7 +100,7 @@ pub trait CORSCache {
|
||||
}
|
||||
|
||||
/// A simple, vector-based CORS Cache
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
#[unstable = "This might later be replaced with a HashMap-like entity, though that requires a separate Origin struct"]
|
||||
pub struct BasicCORSCache(Vec<CORSCacheEntry>);
|
||||
|
||||
@ -207,43 +207,43 @@ impl CORSCache for CORSCacheSender {
|
||||
fn clear (&mut self, request: CacheRequestDetails) {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::Clear(request, tx));
|
||||
let _ = rx.recv_opt();
|
||||
let _ = rx.recv();
|
||||
}
|
||||
|
||||
fn cleanup(&mut self) {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::Cleanup(tx));
|
||||
let _ = rx.recv_opt();
|
||||
let _ = rx.recv();
|
||||
}
|
||||
|
||||
fn match_header(&mut self, request: CacheRequestDetails, header_name: &str) -> bool {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::MatchHeader(request, header_name.to_string(), tx));
|
||||
rx.recv_opt().unwrap_or(false)
|
||||
rx.recv().unwrap_or(false)
|
||||
}
|
||||
|
||||
fn match_header_and_update(&mut self, request: CacheRequestDetails, header_name: &str, new_max_age: uint) -> bool {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::MatchHeaderUpdate(request, header_name.to_string(), new_max_age, tx));
|
||||
rx.recv_opt().unwrap_or(false)
|
||||
rx.recv().unwrap_or(false)
|
||||
}
|
||||
|
||||
fn match_method(&mut self, request: CacheRequestDetails, method: Method) -> bool {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::MatchMethod(request, method, tx));
|
||||
rx.recv_opt().unwrap_or(false)
|
||||
rx.recv().unwrap_or(false)
|
||||
}
|
||||
|
||||
fn match_method_and_update(&mut self, request: CacheRequestDetails, method: Method, new_max_age: uint) -> bool {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::MatchMethodUpdate(request, method, new_max_age, tx));
|
||||
rx.recv_opt().unwrap_or(false)
|
||||
rx.recv().unwrap_or(false)
|
||||
}
|
||||
|
||||
fn insert(&mut self, entry: CORSCacheEntry) {
|
||||
let (tx, rx) = channel();
|
||||
self.send(CORSCacheTaskMsg::Insert(entry, tx));
|
||||
let _ = rx.recv_opt();
|
||||
let _ = rx.recv();
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ impl CORSCache for CORSCacheSender {
|
||||
/// let task = CORSCacheTask::new();
|
||||
/// let builder = TaskBuilder::new().named("XHRTask");
|
||||
/// let mut sender = task.get_sender();
|
||||
/// builder.spawn(proc() { task.run() });
|
||||
/// builder.spawn(move || { task.run() });
|
||||
/// sender.insert(CORSCacheEntry::new(/* parameters here */));
|
||||
/// ```
|
||||
pub struct CORSCacheTask {
|
||||
@ -284,7 +284,7 @@ impl CORSCacheTask {
|
||||
/// Send ExitMsg to the associated Sender to exit
|
||||
pub fn run(&mut self) {
|
||||
loop {
|
||||
match self.receiver.recv() {
|
||||
match self.receiver.recv().unwrap() {
|
||||
CORSCacheTaskMsg::Clear(request, tx) => {
|
||||
self.cache.clear(request);
|
||||
tx.send(());
|
||||
|
@ -11,7 +11,7 @@ use fetch::cors_cache::CORSCache;
|
||||
use fetch::response::Response;
|
||||
|
||||
/// A [request context](http://fetch.spec.whatwg.org/#concept-request-context)
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum Context {
|
||||
Audio, Beacon, CSPreport, Download, Embed, Eventsource,
|
||||
Favicon, Fetch, Font, Form, Frame, Hyperlink, IFrame, Image,
|
||||
@ -21,7 +21,7 @@ pub enum Context {
|
||||
}
|
||||
|
||||
/// A [request context frame type](http://fetch.spec.whatwg.org/#concept-request-context-frame-type)
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum ContextFrameType {
|
||||
Auxiliary,
|
||||
TopLevel,
|
||||
@ -37,7 +37,7 @@ pub enum Referer {
|
||||
}
|
||||
|
||||
/// A [request mode](http://fetch.spec.whatwg.org/#concept-request-mode)
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum RequestMode {
|
||||
SameOrigin,
|
||||
NoCORS,
|
||||
@ -46,7 +46,7 @@ pub enum RequestMode {
|
||||
}
|
||||
|
||||
/// Request [credentials mode](http://fetch.spec.whatwg.org/#concept-request-credentials-mode)
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum CredentialsMode {
|
||||
Omit,
|
||||
CredentialsSameOrigin,
|
||||
@ -54,7 +54,7 @@ pub enum CredentialsMode {
|
||||
}
|
||||
|
||||
/// [Response tainting](http://fetch.spec.whatwg.org/#concept-request-response-tainting)
|
||||
#[deriving(Copy)]
|
||||
#[derive(Copy)]
|
||||
pub enum ResponseTainting {
|
||||
Basic,
|
||||
CORSTainting,
|
||||
|
@ -6,10 +6,10 @@ use url::Url;
|
||||
use hyper::status::StatusCode;
|
||||
use hyper::header::Headers;
|
||||
use std::ascii::AsciiExt;
|
||||
use std::comm::Receiver;
|
||||
use std::sync::mpsc::Receiver;
|
||||
|
||||
/// [Response type](http://fetch.spec.whatwg.org/#concept-response-type)
|
||||
#[deriving(Clone, PartialEq, Copy)]
|
||||
#[derive(Clone, PartialEq, Copy)]
|
||||
pub enum ResponseType {
|
||||
Basic,
|
||||
CORS,
|
||||
@ -19,7 +19,7 @@ pub enum ResponseType {
|
||||
}
|
||||
|
||||
/// [Response termination reason](http://fetch.spec.whatwg.org/#concept-response-termination-reason)
|
||||
#[deriving(Clone, Copy)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum TerminationReason {
|
||||
EndUserAbort,
|
||||
Fatal,
|
||||
@ -29,7 +29,7 @@ pub enum TerminationReason {
|
||||
/// The response body can still be pushed to after fetch
|
||||
/// This provides a way to store unfinished response bodies
|
||||
#[unstable = "I haven't yet decided exactly how the interface for this will be"]
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum ResponseBody {
|
||||
Empty, // XXXManishearth is this necessary, or is Done(vec![]) enough?
|
||||
Receiving(Vec<u8>),
|
||||
@ -50,7 +50,7 @@ pub struct ResponseLoader {
|
||||
}
|
||||
|
||||
/// A [Response](http://fetch.spec.whatwg.org/#concept-response) as defined by the Fetch spec
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct Response {
|
||||
pub response_type: ResponseType,
|
||||
pub termination_reason: Option<TerminationReason>,
|
||||
@ -110,7 +110,7 @@ impl Response {
|
||||
ResponseType::Default | ResponseType::Error => unreachable!(),
|
||||
ResponseType::Basic => {
|
||||
let headers = old_headers.iter().filter(|header| {
|
||||
match header.name().to_ascii_lower().as_slice() {
|
||||
match header.name().to_ascii_lowercase().as_slice() {
|
||||
"set-cookie" | "set-cookie2" => false,
|
||||
_ => true
|
||||
}
|
||||
@ -120,7 +120,7 @@ impl Response {
|
||||
},
|
||||
ResponseType::CORS => {
|
||||
let headers = old_headers.iter().filter(|header| {
|
||||
match header.name().to_ascii_lower().as_slice() {
|
||||
match header.name().to_ascii_lowercase().as_slice() {
|
||||
"cache-control" | "content-language" |
|
||||
"content-type" | "expires" | "last-modified" | "Pragma" => false,
|
||||
// XXXManishearth handle Access-Control-Expose-Headers
|
||||
|
@ -8,6 +8,7 @@ use resource_task::ProgressMsg::{Payload, Done};
|
||||
use std::borrow::ToOwned;
|
||||
use std::io;
|
||||
use std::io::File;
|
||||
use std::sync::mpsc::Sender;
|
||||
use servo_util::task::spawn_named;
|
||||
|
||||
static READ_SIZE: uint = 8192;
|
||||
@ -17,11 +18,11 @@ fn read_all(reader: &mut io::Stream, progress_chan: &Sender<ProgressMsg>)
|
||||
loop {
|
||||
let mut buf = vec!();
|
||||
match reader.push_at_least(READ_SIZE, READ_SIZE, &mut buf) {
|
||||
Ok(_) => progress_chan.send(Payload(buf)),
|
||||
Ok(_) => progress_chan.send(Payload(buf)).unwrap(),
|
||||
Err(e) => match e.kind {
|
||||
io::EndOfFile => {
|
||||
if buf.len() > 0 {
|
||||
progress_chan.send(Payload(buf));
|
||||
progress_chan.send(Payload(buf)).unwrap();
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@ -39,7 +40,7 @@ pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
eventual_consumer: load_data.consumer,
|
||||
};
|
||||
let progress_chan = start_sending(senders, Metadata::default(url.clone()));
|
||||
spawn_named("file_loader".to_owned(), proc() {
|
||||
spawn_named("file_loader".to_owned(), move || {
|
||||
let file_path: Result<Path, ()> = url.to_file_path();
|
||||
match file_path {
|
||||
Ok(file_path) => {
|
||||
|
@ -11,14 +11,16 @@ use hyper::client::Request;
|
||||
use hyper::header::common::{ContentLength, ContentType, Host, Location};
|
||||
use hyper::method::Method;
|
||||
use hyper::status::StatusClass;
|
||||
use std::error::Error;
|
||||
use std::io::Reader;
|
||||
use std::sync::mpsc::Sender;
|
||||
use servo_util::task::spawn_named;
|
||||
use url::{Url, UrlParser};
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
|
||||
pub fn factory(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
spawn_named("http_loader".to_owned(), proc() load(load_data, start_chan))
|
||||
spawn_named("http_loader".to_owned(), move || load(load_data, start_chan))
|
||||
}
|
||||
|
||||
fn send_error(url: Url, err: String, senders: ResponseSenders) {
|
||||
@ -26,7 +28,7 @@ fn send_error(url: Url, err: String, senders: ResponseSenders) {
|
||||
metadata.status = None;
|
||||
|
||||
match start_sending_opt(senders, metadata) {
|
||||
Ok(p) => p.send(Done(Err(err))),
|
||||
Ok(p) => p.send(Done(Err(err))).unwrap(),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
@ -75,7 +77,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
let mut req = match Request::new(load_data.method.clone(), url.clone()) {
|
||||
Ok(req) => req,
|
||||
Err(e) => {
|
||||
send_error(url, e.to_string(), senders);
|
||||
send_error(url, e.description().to_string(), senders);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -91,11 +93,11 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
//}
|
||||
let writer = match load_data.data {
|
||||
Some(ref data) => {
|
||||
req.headers_mut().set(ContentLength(data.len()));
|
||||
req.headers_mut().set(ContentLength(data.len() as u64));
|
||||
let mut writer = match req.start() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
send_error(url, e.to_string(), senders);
|
||||
send_error(url, e.description().to_string(), senders);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -116,7 +118,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
match req.start() {
|
||||
Ok(w) => w,
|
||||
Err(e) => {
|
||||
send_error(url, e.to_string(), senders);
|
||||
send_error(url, e.description().to_string(), senders);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -125,7 +127,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
let mut response = match writer.send() {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
send_error(url, e.to_string(), senders);
|
||||
send_error(url, e.description().to_string(), senders);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -189,7 +191,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
match response.read(buf.as_mut_slice()) {
|
||||
Ok(len) => {
|
||||
unsafe { buf.set_len(len); }
|
||||
if progress_chan.send_opt(Payload(buf)).is_err() {
|
||||
if progress_chan.send(Payload(buf)).is_err() {
|
||||
// The send errors when the receiver is out of scope,
|
||||
// which will happen if the fetch has timed out (or has been aborted)
|
||||
// so we don't need to continue with the loading of the file here.
|
||||
@ -197,7 +199,7 @@ fn load(load_data: LoadData, start_chan: Sender<TargetedLoadResponse>) {
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
let _ = progress_chan.send_opt(Done(Ok(())));
|
||||
let _ = progress_chan.send(Done(Ok(())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use png;
|
||||
pub type Image = png::Image;
|
||||
|
||||
|
||||
static TEST_IMAGE: &'static [u8] = include_bin!("test.jpeg");
|
||||
static TEST_IMAGE: &'static [u8] = include_bytes!("test.jpeg");
|
||||
|
||||
pub fn test_image_bin() -> Vec<u8> {
|
||||
TEST_IMAGE.iter().map(|&x| x).collect()
|
||||
|
@ -16,7 +16,7 @@ use url::Url;
|
||||
|
||||
/// A struct to store image data. The image will be loaded once the first time it is requested,
|
||||
/// and an Arc will be stored. Clones of this Arc are given out on demand.
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ImageHolder<NodeAddress> {
|
||||
url: Url,
|
||||
image: Option<Arc<Box<Image>>>,
|
||||
@ -41,7 +41,7 @@ impl<NodeAddress: Send> ImageHolder<NodeAddress> {
|
||||
// should be done as early as possible and decode only once we
|
||||
// are sure that the image will be used.
|
||||
{
|
||||
let val = holder.local_image_cache.lock();
|
||||
let val = holder.local_image_cache.lock().unwrap();
|
||||
let mut local_image_cache = val;
|
||||
local_image_cache.prefetch(&holder.url);
|
||||
local_image_cache.decode(&holder.url);
|
||||
@ -81,11 +81,11 @@ impl<NodeAddress: Send> ImageHolder<NodeAddress> {
|
||||
// the image and store it for the future
|
||||
if self.image.is_none() {
|
||||
let port = {
|
||||
let val = self.local_image_cache.lock();
|
||||
let val = self.local_image_cache.lock().unwrap();
|
||||
let mut local_image_cache = val;
|
||||
local_image_cache.get_image(node_address, &self.url)
|
||||
};
|
||||
match port.recv() {
|
||||
match port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageReady(image) => self.image = Some(image),
|
||||
ImageResponseMsg::ImageNotReady => debug!("image not ready for {}", self.url.serialize()),
|
||||
ImageResponseMsg::ImageFailed => debug!("image decoding failed for {}", self.url.serialize()),
|
||||
|
@ -10,12 +10,11 @@ use resource_task::ProgressMsg::{Payload, Done};
|
||||
use servo_util::task::spawn_named;
|
||||
use servo_util::taskpool::TaskPool;
|
||||
use std::borrow::ToOwned;
|
||||
use std::comm::{channel, Receiver, Sender};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::{Occupied, Vacant};
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::mem::replace;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use serialize::{Encoder, Encodable};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use url::Url;
|
||||
|
||||
pub enum Msg {
|
||||
@ -49,7 +48,7 @@ pub enum Msg {
|
||||
WaitForStorePrefetched(Sender<()>),
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum ImageResponseMsg {
|
||||
ImageReady(Arc<Box<Image>>),
|
||||
ImageNotReady,
|
||||
@ -68,25 +67,17 @@ impl PartialEq for ImageResponseMsg {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ImageCacheTask {
|
||||
chan: Sender<Msg>,
|
||||
}
|
||||
|
||||
impl<E, S: Encoder<E>> Encodable<S, E> for ImageCacheTask {
|
||||
fn encode(&self, _: &mut S) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
type DecoderFactory = fn() -> (proc(&[u8]) : 'static -> Option<Image>);
|
||||
|
||||
impl ImageCacheTask {
|
||||
pub fn new(resource_task: ResourceTask, task_pool: TaskPool) -> ImageCacheTask {
|
||||
let (chan, port) = channel();
|
||||
let chan_clone = chan.clone();
|
||||
|
||||
spawn_named("ImageCacheTask".to_owned(), proc() {
|
||||
spawn_named("ImageCacheTask".to_owned(), move || {
|
||||
let mut cache = ImageCache {
|
||||
resource_task: resource_task,
|
||||
port: port,
|
||||
@ -107,11 +98,11 @@ impl ImageCacheTask {
|
||||
pub fn new_sync(resource_task: ResourceTask, task_pool: TaskPool) -> ImageCacheTask {
|
||||
let (chan, port) = channel();
|
||||
|
||||
spawn_named("ImageCacheTask (sync)".to_owned(), proc() {
|
||||
spawn_named("ImageCacheTask (sync)".to_owned(), move || {
|
||||
let inner_cache = ImageCacheTask::new(resource_task, task_pool);
|
||||
|
||||
loop {
|
||||
let msg: Msg = port.recv();
|
||||
let msg: Msg = port.recv().unwrap();
|
||||
|
||||
match msg {
|
||||
Msg::GetImage(url, response) => {
|
||||
@ -147,7 +138,7 @@ struct ImageCache {
|
||||
task_pool: TaskPool,
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
enum ImageState {
|
||||
Init,
|
||||
Prefetching(AfterPrefetch),
|
||||
@ -157,7 +148,7 @@ enum ImageState {
|
||||
Failed
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
enum AfterPrefetch {
|
||||
DoDecode,
|
||||
DoNotDecode
|
||||
@ -169,7 +160,7 @@ impl ImageCache {
|
||||
let mut store_prefetched_chan: Option<Sender<()>> = None;
|
||||
|
||||
loop {
|
||||
let msg = self.port.recv();
|
||||
let msg = self.port.recv().unwrap();
|
||||
|
||||
match msg {
|
||||
Msg::Prefetch(url) => self.prefetch(url),
|
||||
@ -249,7 +240,7 @@ impl ImageCache {
|
||||
let resource_task = self.resource_task.clone();
|
||||
let url_clone = url.clone();
|
||||
|
||||
spawn_named("ImageCacheTask (prefetch)".to_owned(), proc() {
|
||||
spawn_named("ImageCacheTask (prefetch)".to_owned(), move || {
|
||||
let url = url_clone;
|
||||
debug!("image_cache_task: started fetch for {}", url.serialize());
|
||||
|
||||
@ -313,7 +304,7 @@ impl ImageCache {
|
||||
let to_cache = self.chan.clone();
|
||||
let url_clone = url.clone();
|
||||
|
||||
self.task_pool.execute(proc() {
|
||||
self.task_pool.execute(move || {
|
||||
let url = url_clone;
|
||||
debug!("image_cache_task: started image decode for {}", url.serialize());
|
||||
let image = load_from_memory(data.as_slice());
|
||||
@ -358,10 +349,10 @@ impl ImageCache {
|
||||
|
||||
}
|
||||
|
||||
fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) {
|
||||
fn purge_waiters<F>(&mut self, url: Url, f: F) where F: Fn() -> ImageResponseMsg {
|
||||
match self.wait_map.remove(&url) {
|
||||
Some(waiters) => {
|
||||
let items = waiters.lock();
|
||||
let items = waiters.lock().unwrap();
|
||||
for response in items.iter() {
|
||||
response.send(f());
|
||||
}
|
||||
@ -373,11 +364,11 @@ impl ImageCache {
|
||||
fn get_image(&self, url: Url, response: Sender<ImageResponseMsg>) {
|
||||
match self.get_state(&url) {
|
||||
ImageState::Init => panic!("request for image before prefetch"),
|
||||
ImageState::Prefetching(AfterPrefetch::DoDecode) => response.send(ImageResponseMsg::ImageNotReady),
|
||||
ImageState::Prefetching(AfterPrefetch::DoDecode) => response.send(ImageResponseMsg::ImageNotReady).unwrap(),
|
||||
ImageState::Prefetching(AfterPrefetch::DoNotDecode) | ImageState::Prefetched(..) => panic!("request for image before decode"),
|
||||
ImageState::Decoding => response.send(ImageResponseMsg::ImageNotReady),
|
||||
ImageState::Decoded(image) => response.send(ImageResponseMsg::ImageReady(image)),
|
||||
ImageState::Failed => response.send(ImageResponseMsg::ImageFailed),
|
||||
ImageState::Decoding => response.send(ImageResponseMsg::ImageNotReady).unwrap(),
|
||||
ImageState::Decoded(image) => response.send(ImageResponseMsg::ImageReady(image)).unwrap(),
|
||||
ImageState::Failed => response.send(ImageResponseMsg::ImageFailed).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,10 +382,10 @@ impl ImageCache {
|
||||
// We don't have this image yet
|
||||
match self.wait_map.entry(url) {
|
||||
Occupied(mut entry) => {
|
||||
entry.get_mut().lock().push(response);
|
||||
entry.get_mut().lock().unwrap().push(response);
|
||||
}
|
||||
Vacant(entry) => {
|
||||
entry.set(Arc::new(Mutex::new(vec!(response))));
|
||||
entry.insert(Arc::new(Mutex::new(vec!(response))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -420,7 +411,7 @@ impl ImageCacheTaskClient for ImageCacheTask {
|
||||
fn exit(&self) {
|
||||
let (response_chan, response_port) = channel();
|
||||
self.send(Msg::Exit(response_chan));
|
||||
response_port.recv();
|
||||
response_port.recv().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,9 +441,9 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<Vec<u8>, ()>
|
||||
|
||||
let mut image_data = vec!();
|
||||
|
||||
let progress_port = response_port.recv().progress_port;
|
||||
let progress_port = response_port.recv().unwrap().progress_port;
|
||||
loop {
|
||||
match progress_port.recv() {
|
||||
match progress_port.recv().unwrap() {
|
||||
Payload(data) => {
|
||||
image_data.push_all(data.as_slice());
|
||||
}
|
||||
@ -467,15 +458,18 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<Vec<u8>, ()>
|
||||
}
|
||||
|
||||
|
||||
pub fn spawn_listener<A: Send>(f: proc(Receiver<A>):Send) -> Sender<A> {
|
||||
pub fn spawn_listener<F, A>(f: F) -> Sender<A>
|
||||
where F: FnOnce(Receiver<A>) + Send,
|
||||
A: Send
|
||||
{
|
||||
let (setup_chan, setup_port) = channel();
|
||||
|
||||
spawn_named("ImageCacheTask (listener)".to_owned(), proc() {
|
||||
spawn_named("ImageCacheTask (listener)".to_owned(), move || {
|
||||
let (chan, port) = channel();
|
||||
setup_chan.send(chan);
|
||||
f(port);
|
||||
});
|
||||
setup_port.recv()
|
||||
setup_port.recv().unwrap()
|
||||
}
|
||||
|
||||
|
||||
@ -491,7 +485,7 @@ mod tests {
|
||||
use sniffer_task;
|
||||
use image::base::test_image_bin;
|
||||
use servo_util::taskpool::TaskPool;
|
||||
use std::comm;
|
||||
use std::sync::mpsc::{Sender, channel, Receiver};
|
||||
use url::Url;
|
||||
|
||||
trait Closure {
|
||||
@ -541,7 +535,7 @@ mod tests {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
// Don't send the data until after the client requests
|
||||
// the image
|
||||
self.wait_port.recv();
|
||||
self.wait_port.recv().unwrap();
|
||||
response.send(Payload(test_image_bin()));
|
||||
response.send(Done(Ok(())));
|
||||
}
|
||||
@ -554,16 +548,16 @@ mod tests {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
// Don't send the data until after the client requests
|
||||
// the image
|
||||
self.wait_port.recv();
|
||||
self.wait_port.recv().unwrap();
|
||||
response.send(Payload(test_image_bin()));
|
||||
response.send(Done(Err("".to_string())));
|
||||
}
|
||||
}
|
||||
|
||||
fn mock_resource_task<T: Closure+Send>(on_load: Box<T>) -> ResourceTask {
|
||||
spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) {
|
||||
spawn_listener(move |port: Receiver<resource_task::ControlMsg>| {
|
||||
loop {
|
||||
match port.recv() {
|
||||
match port.recv().unwrap() {
|
||||
resource_task::ControlMsg::Load(response) => {
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
let senders = ResponseSenders {
|
||||
@ -600,7 +594,7 @@ mod tests {
|
||||
|
||||
let (chan, port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, chan));
|
||||
port.recv();
|
||||
port.recv().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -613,14 +607,14 @@ mod tests {
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url));
|
||||
url_requested.recv();
|
||||
url_requested.recv().unwrap();
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_request_url_from_resource_task_on_multiple_prefetches() {
|
||||
let (url_requested_chan, url_requested) = comm::channel();
|
||||
let (url_requested_chan, url_requested) = channel();
|
||||
|
||||
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
||||
|
||||
@ -629,7 +623,7 @@ mod tests {
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Prefetch(url));
|
||||
url_requested.recv();
|
||||
url_requested.recv().unwrap();
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
match url_requested.try_recv() {
|
||||
@ -640,7 +634,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_return_image_not_ready_if_data_has_not_arrived() {
|
||||
let (wait_chan, wait_port) = comm::channel();
|
||||
let (wait_chan, wait_port) = channel();
|
||||
|
||||
let mock_resource_task = mock_resource_task(box WaitSendTestImage{wait_port: wait_port});
|
||||
|
||||
@ -649,9 +643,9 @@ mod tests {
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, response_chan));
|
||||
assert!(response_port.recv() == ImageResponseMsg::ImageNotReady);
|
||||
assert!(response_port.recv().unwrap() == ImageResponseMsg::ImageNotReady);
|
||||
wait_chan.send(());
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
@ -670,11 +664,11 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
join_port.recv();
|
||||
join_port.recv().unwrap();
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageReady(_) => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -696,12 +690,12 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
join_port.recv();
|
||||
join_port.recv().unwrap();
|
||||
|
||||
for _ in range(0u32, 2u32) {
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url.clone(), response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageReady(_) => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -713,13 +707,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_not_request_image_from_resource_task_if_image_is_already_available() {
|
||||
let (image_bin_sent_chan, image_bin_sent) = comm::channel();
|
||||
let (image_bin_sent_chan, image_bin_sent) = channel();
|
||||
|
||||
let (resource_task_exited_chan, resource_task_exited) = comm::channel();
|
||||
let (resource_task_exited_chan, resource_task_exited) = channel();
|
||||
|
||||
let mock_resource_task = spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) {
|
||||
let mock_resource_task = spawn_listener(move |port: Receiver<resource_task::ControlMsg>| {
|
||||
loop {
|
||||
match port.recv() {
|
||||
match port.recv().unwrap() {
|
||||
resource_task::ControlMsg::Load(response) => {
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
let senders = ResponseSenders {
|
||||
@ -746,14 +740,14 @@ mod tests {
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
image_bin_sent.recv();
|
||||
image_bin_sent.recv().unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
|
||||
resource_task_exited.recv();
|
||||
resource_task_exited.recv().unwrap();
|
||||
|
||||
// Our resource task should not have received another request for the image
|
||||
// because it's already cached
|
||||
@ -765,13 +759,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_not_request_image_from_resource_task_if_image_fetch_already_failed() {
|
||||
let (image_bin_sent_chan, image_bin_sent) = comm::channel();
|
||||
let (image_bin_sent_chan, image_bin_sent) = channel();
|
||||
|
||||
let (resource_task_exited_chan, resource_task_exited) = comm::channel();
|
||||
let (resource_task_exited_chan, resource_task_exited) = channel();
|
||||
|
||||
let mock_resource_task = spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) {
|
||||
let mock_resource_task = spawn_listener(move |port: Receiver<resource_task::ControlMsg>| {
|
||||
loop {
|
||||
match port.recv() {
|
||||
match port.recv().unwrap() {
|
||||
resource_task::ControlMsg::Load(response) => {
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
let senders = ResponseSenders {
|
||||
@ -799,7 +793,7 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
image_bin_sent.recv();
|
||||
image_bin_sent.recv().unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
@ -807,7 +801,7 @@ mod tests {
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
|
||||
resource_task_exited.recv();
|
||||
resource_task_exited.recv().unwrap();
|
||||
|
||||
// Our resource task should not have received another request for the image
|
||||
// because it's already cached
|
||||
@ -830,11 +824,11 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
join_port.recv();
|
||||
join_port.recv().unwrap();
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageFailed => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -856,19 +850,19 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
join_port.recv();
|
||||
join_port.recv().unwrap();
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url.clone(), response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageFailed => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
|
||||
// And ask again, we should get the same response
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageFailed => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -890,13 +884,13 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
join_port.recv();
|
||||
join_port.recv().unwrap();
|
||||
|
||||
// Make the request
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, response_chan));
|
||||
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageFailed => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -918,11 +912,11 @@ mod tests {
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
// Wait until our mock resource task has sent the image to the image cache
|
||||
join_port.recv();
|
||||
join_port.recv().unwrap();
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::WaitForImage(url, response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageReady(..) => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -933,7 +927,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_return_image_on_wait_if_image_is_not_yet_loaded() {
|
||||
let (wait_chan, wait_port) = comm::channel();
|
||||
let (wait_chan, wait_port) = channel();
|
||||
|
||||
let mock_resource_task = mock_resource_task(box WaitSendTestImage {wait_port: wait_port});
|
||||
|
||||
@ -943,12 +937,12 @@ mod tests {
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::WaitForImage(url, response_chan));
|
||||
|
||||
wait_chan.send(());
|
||||
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageReady(..) => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -959,7 +953,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_return_image_failed_on_wait_if_image_fails_to_load() {
|
||||
let (wait_chan, wait_port) = comm::channel();
|
||||
let (wait_chan, wait_port) = channel();
|
||||
|
||||
let mock_resource_task = mock_resource_task(box WaitSendTestImageErr{wait_port: wait_port});
|
||||
|
||||
@ -969,12 +963,12 @@ mod tests {
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::WaitForImage(url, response_chan));
|
||||
|
||||
wait_chan.send(());
|
||||
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageFailed => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
@ -993,9 +987,9 @@ mod tests {
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
let (response_chan, response_port) = comm::channel();
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::GetImage(url, response_chan));
|
||||
match response_port.recv() {
|
||||
match response_port.recv().unwrap() {
|
||||
ImageResponseMsg::ImageReady(_) => (),
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
|
@ -2,17 +2,20 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![feature(default_type_params, globs, phase)]
|
||||
#![feature(int_uint)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(box_syntax)]
|
||||
|
||||
#![deny(unused_imports)]
|
||||
#![deny(unused_variables)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(unstable)]
|
||||
|
||||
extern crate collections;
|
||||
extern crate geom;
|
||||
extern crate hyper;
|
||||
extern crate png;
|
||||
#[phase(plugin, link)]
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate serialize;
|
||||
extern crate "util" as servo_util;
|
||||
|
@ -11,14 +11,14 @@ multiple times and thus triggering reflows multiple times.
|
||||
use image_cache_task::{ImageCacheTask, ImageResponseMsg, Msg};
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::comm::{Receiver, channel};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::{Occupied, Vacant};
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::sync::mpsc::{Receiver, channel};
|
||||
use servo_util::task::spawn_named;
|
||||
use url::Url;
|
||||
|
||||
pub trait ImageResponder<NodeAddress: Send> {
|
||||
fn respond(&self) -> proc(ImageResponseMsg, NodeAddress):Send;
|
||||
fn respond(&self) -> Box<Fn(ImageResponseMsg, NodeAddress)+Send>;
|
||||
}
|
||||
|
||||
pub struct LocalImageCache<NodeAddress> {
|
||||
@ -39,7 +39,7 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
struct ImageState {
|
||||
prefetched: bool,
|
||||
decoded: bool,
|
||||
@ -118,7 +118,7 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> {
|
||||
let (response_chan, response_port) = channel();
|
||||
self.image_cache_task.send(Msg::GetImage((*url).clone(), response_chan));
|
||||
|
||||
let response = response_port.recv();
|
||||
let response = response_port.recv().unwrap();
|
||||
match response {
|
||||
ImageResponseMsg::ImageNotReady => {
|
||||
// Need to reflow when the image is available
|
||||
@ -128,13 +128,13 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> {
|
||||
// on the image to load and triggering layout
|
||||
let image_cache_task = self.image_cache_task.clone();
|
||||
assert!(self.on_image_available.is_some());
|
||||
let on_image_available: proc(ImageResponseMsg, NodeAddress):Send =
|
||||
let on_image_available =
|
||||
self.on_image_available.as_ref().unwrap().respond();
|
||||
let url = (*url).clone();
|
||||
spawn_named("LocalImageCache".to_owned(), proc() {
|
||||
spawn_named("LocalImageCache".to_owned(), move || {
|
||||
let (response_chan, response_port) = channel();
|
||||
image_cache_task.send(Msg::WaitForImage(url, response_chan));
|
||||
on_image_available(response_port.recv(), node_address);
|
||||
on_image_available(response_port.recv().unwrap(), node_address);
|
||||
});
|
||||
}
|
||||
_ => ()
|
||||
@ -157,7 +157,7 @@ impl<NodeAddress: Send> LocalImageCache<NodeAddress> {
|
||||
match self.state_map.entry((*url).clone()) {
|
||||
Occupied(entry) => entry.into_mut(),
|
||||
Vacant(entry) =>
|
||||
entry.set(ImageState {
|
||||
entry.insert(ImageState {
|
||||
prefetched: false,
|
||||
decoded: false,
|
||||
last_request_round: 0,
|
||||
|
@ -21,7 +21,7 @@ use hyper::mime::{Mime, Attr};
|
||||
use url::Url;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::comm::{channel, Receiver, Sender};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
|
||||
pub enum ControlMsg {
|
||||
/// Request the data associated with a particular URL
|
||||
@ -29,7 +29,7 @@ pub enum ControlMsg {
|
||||
Exit
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct LoadData {
|
||||
pub url: Url,
|
||||
pub method: Method,
|
||||
@ -52,7 +52,7 @@ impl LoadData {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct ResourceCORSData {
|
||||
/// CORS Preflight flag
|
||||
pub preflight: bool,
|
||||
@ -131,7 +131,7 @@ pub struct ResponseSenders {
|
||||
}
|
||||
|
||||
/// Messages sent in response to a `Load` message
|
||||
#[deriving(PartialEq,Show)]
|
||||
#[derive(PartialEq,Show)]
|
||||
pub enum ProgressMsg {
|
||||
/// Binary data - there may be multiple of these
|
||||
Payload(Vec<u8>),
|
||||
@ -147,7 +147,7 @@ pub fn start_sending(senders: ResponseSenders, metadata: Metadata) -> Sender<Pro
|
||||
/// For use by loaders in responding to a Load message.
|
||||
pub fn start_sending_opt(senders: ResponseSenders, metadata: Metadata) -> Result<Sender<ProgressMsg>, ()> {
|
||||
let (progress_chan, progress_port) = channel();
|
||||
let result = senders.immediate_consumer.send_opt(TargetedLoadResponse {
|
||||
let result = senders.immediate_consumer.send(TargetedLoadResponse {
|
||||
load_response: LoadResponse {
|
||||
metadata: metadata,
|
||||
progress_port: progress_port,
|
||||
@ -165,11 +165,11 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||
-> Result<(Metadata, Vec<u8>), String> {
|
||||
let (start_chan, start_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan)));
|
||||
let response = start_port.recv();
|
||||
let response = start_port.recv().unwrap();
|
||||
|
||||
let mut buf = vec!();
|
||||
loop {
|
||||
match response.progress_port.recv() {
|
||||
match response.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => buf.push_all(data.as_slice()),
|
||||
ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)),
|
||||
ProgressMsg::Done(Err(e)) => return Err(e)
|
||||
@ -184,7 +184,7 @@ pub type ResourceTask = Sender<ControlMsg>;
|
||||
pub fn new_resource_task(user_agent: Option<String>) -> ResourceTask {
|
||||
let (setup_chan, setup_port) = channel();
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
spawn_named("ResourceManager".to_owned(), proc() {
|
||||
spawn_named("ResourceManager".to_owned(), move || {
|
||||
ResourceManager::new(setup_port, user_agent, sniffer_task).start();
|
||||
});
|
||||
setup_chan
|
||||
@ -210,7 +210,7 @@ impl ResourceManager {
|
||||
impl ResourceManager {
|
||||
fn start(&self) {
|
||||
loop {
|
||||
match self.from_client.recv() {
|
||||
match self.from_client.recv().unwrap() {
|
||||
ControlMsg::Load(load_data) => {
|
||||
self.load(load_data)
|
||||
}
|
||||
@ -229,21 +229,19 @@ impl ResourceManager {
|
||||
eventual_consumer: load_data.consumer.clone(),
|
||||
};
|
||||
|
||||
let loader = match load_data.url.scheme.as_slice() {
|
||||
"file" => file_loader::factory,
|
||||
"http" | "https" => http_loader::factory,
|
||||
"data" => data_loader::factory,
|
||||
"about" => about_loader::factory,
|
||||
debug!("resource_task: loading url: {}", load_data.url.serialize());
|
||||
match load_data.url.scheme.as_slice() {
|
||||
"file" => file_loader::factory(load_data, self.sniffer_task.clone()),
|
||||
"http" | "https" => http_loader::factory(load_data, self.sniffer_task.clone()),
|
||||
"data" => data_loader::factory(load_data, self.sniffer_task.clone()),
|
||||
"about" => about_loader::factory(load_data, self.sniffer_task.clone()),
|
||||
_ => {
|
||||
debug!("resource_task: no loader for scheme {}", load_data.url.scheme);
|
||||
start_sending(senders, Metadata::default(load_data.url))
|
||||
.send(ProgressMsg::Done(Err("no loader for scheme".to_string())));
|
||||
return
|
||||
}
|
||||
};
|
||||
debug!("resource_task: loading url: {}", load_data.url.serialize());
|
||||
|
||||
loader(load_data, self.sniffer_task.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +250,7 @@ pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, Pro
|
||||
let (input_chan, input_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, input_chan)));
|
||||
|
||||
let response = input_port.recv();
|
||||
let response = input_port.recv().unwrap();
|
||||
let iter = ProgressMsgPortIterator { progress_port: response.progress_port };
|
||||
(response.metadata, iter)
|
||||
}
|
||||
@ -262,9 +260,11 @@ pub struct ProgressMsgPortIterator {
|
||||
progress_port: Receiver<ProgressMsg>
|
||||
}
|
||||
|
||||
impl Iterator<Vec<u8>> for ProgressMsgPortIterator {
|
||||
impl Iterator for ProgressMsgPortIterator {
|
||||
type Item = Vec<u8>;
|
||||
|
||||
fn next(&mut self) -> Option<Vec<u8>> {
|
||||
match self.progress_port.recv() {
|
||||
match self.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => Some(data),
|
||||
ProgressMsg::Done(Ok(())) => None,
|
||||
ProgressMsg::Done(Err(e)) => {
|
||||
@ -287,8 +287,8 @@ fn test_bad_scheme() {
|
||||
let (start_chan, start) = channel();
|
||||
let url = Url::parse("bogus://whatever").unwrap();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan)));
|
||||
let response = start.recv();
|
||||
match response.progress_port.recv() {
|
||||
let response = start.recv().unwrap();
|
||||
match response.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Done(result) => { assert!(result.is_err()) }
|
||||
_ => panic!("bleh")
|
||||
}
|
||||
|
@ -3,16 +3,16 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! A task that sniffs data
|
||||
use std::comm::{channel, Receiver, Sender};
|
||||
use std::task::TaskBuilder;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::thread::Builder;
|
||||
use resource_task::{TargetedLoadResponse};
|
||||
|
||||
pub type SnifferTask = Sender<TargetedLoadResponse>;
|
||||
|
||||
pub fn new_sniffer_task() -> SnifferTask {
|
||||
let(sen, rec) = channel();
|
||||
let builder = TaskBuilder::new().named("SnifferManager");
|
||||
builder.spawn(proc() {
|
||||
let builder = Builder::new().name("SnifferManager".to_string());
|
||||
builder.spawn(move || {
|
||||
SnifferManager::new(rec).start();
|
||||
});
|
||||
sen
|
||||
@ -33,9 +33,9 @@ impl SnifferManager {
|
||||
impl SnifferManager {
|
||||
fn start(self) {
|
||||
loop {
|
||||
match self.data_receiver.recv_opt() {
|
||||
match self.data_receiver.recv() {
|
||||
Ok(snif_data) => {
|
||||
let _ = snif_data.consumer.send_opt(snif_data.load_response);
|
||||
let _ = snif_data.consumer.send(snif_data.load_response);
|
||||
}
|
||||
Err(_) => break,
|
||||
}
|
||||
|
@ -3,9 +3,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::comm::{channel, Receiver, Sender};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::TreeMap;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use url::Url;
|
||||
|
||||
use servo_util::str::DOMString;
|
||||
@ -40,14 +40,14 @@ pub enum StorageTaskMsg {
|
||||
pub type StorageTask = Sender<StorageTaskMsg>;
|
||||
|
||||
pub trait StorageTaskFactory {
|
||||
fn new() -> StorageTask;
|
||||
fn new() -> Self;
|
||||
}
|
||||
|
||||
impl StorageTaskFactory for StorageTask {
|
||||
/// Create a StorageTask
|
||||
fn new() -> StorageTask {
|
||||
let (chan, port) = channel();
|
||||
spawn_named("StorageManager".to_owned(), proc() {
|
||||
spawn_named("StorageManager".to_owned(), move || {
|
||||
StorageManager::new(port).start();
|
||||
});
|
||||
chan
|
||||
@ -56,7 +56,7 @@ impl StorageTaskFactory for StorageTask {
|
||||
|
||||
struct StorageManager {
|
||||
port: Receiver<StorageTaskMsg>,
|
||||
data: HashMap<String, TreeMap<DOMString, DOMString>>,
|
||||
data: HashMap<String, BTreeMap<DOMString, DOMString>>,
|
||||
}
|
||||
|
||||
impl StorageManager {
|
||||
@ -71,7 +71,7 @@ impl StorageManager {
|
||||
impl StorageManager {
|
||||
fn start(&mut self) {
|
||||
loop {
|
||||
match self.port.recv() {
|
||||
match self.port.recv().unwrap() {
|
||||
StorageTaskMsg::Length(sender, url) => {
|
||||
self.length(sender, url)
|
||||
}
|
||||
@ -112,7 +112,7 @@ impl StorageManager {
|
||||
fn set_item(&mut self, sender: Sender<bool>, url: Url, name: DOMString, value: DOMString) {
|
||||
let origin = self.get_origin_as_string(url);
|
||||
if !self.data.contains_key(&origin) {
|
||||
self.data.insert(origin.clone(), TreeMap::new());
|
||||
self.data.insert(origin.clone(), BTreeMap::new());
|
||||
}
|
||||
|
||||
let updated = self.data.get_mut(&origin).map(|entry| {
|
||||
|
@ -15,7 +15,7 @@ use syntax::parse::token::InternedString;
|
||||
pub fn expand_dom_struct(_: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) -> P<Item> {
|
||||
let mut item2 = (*item).clone();
|
||||
{
|
||||
let add_attr = |s| {
|
||||
let mut add_attr = |&mut :s| {
|
||||
item2.attrs.push(attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(InternedString::new(s))));
|
||||
};
|
||||
add_attr("must_root");
|
||||
@ -34,7 +34,7 @@ pub fn expand_dom_struct(_: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>)
|
||||
/// Provides the hook to expand `#[jstraceable]` into an implementation of `JSTraceable`
|
||||
///
|
||||
/// The expansion basically calls `trace()` on all of the fields of the struct/enum, erroring if they do not implement the method.
|
||||
pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Item, push: |P<Item>|) {
|
||||
pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Item, mut push: Box<FnMut(P<Item>)>) {
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
@ -51,13 +51,11 @@ pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item:
|
||||
attributes: vec!(attr::mk_attr_outer(attr::mk_attr_id(),
|
||||
attr::mk_name_value_item_str(InternedString::new("inline"),
|
||||
InternedString::new("always")))),
|
||||
combine_substructure: combine_substructure(|a, b, c| {
|
||||
jstraceable_substructure(a, b, c)
|
||||
})
|
||||
combine_substructure: combine_substructure(box jstraceable_substructure)
|
||||
}
|
||||
)
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
trait_def.expand(cx, mitem, item, |:a| push(a))
|
||||
}
|
||||
|
||||
// Mostly copied from syntax::ext::deriving::hash
|
||||
@ -68,7 +66,7 @@ fn jstraceable_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substru
|
||||
_ => cx.span_bug(trait_span, "incorrect number of arguments in `jstraceable`")
|
||||
};
|
||||
let trace_ident = substr.method_ident;
|
||||
let call_trace = |span, thing_expr| {
|
||||
let call_trace = |&:span, thing_expr| {
|
||||
let expr = cx.expr_method_call(span, thing_expr, trace_ident, vec!(state_expr.clone()));
|
||||
cx.stmt_expr(expr)
|
||||
};
|
||||
|
@ -12,15 +12,18 @@
|
||||
//! - `#[dom_struct]` : Implies `#[privatize]`,`#[jstraceable]`, and `#[must_root]`.
|
||||
//! Use this for structs that correspond to a DOM type
|
||||
|
||||
#![feature(macro_rules, plugin_registrar, quote, phase)]
|
||||
#![feature(plugin_registrar, quote, plugin, box_syntax)]
|
||||
|
||||
#![deny(unused_imports)]
|
||||
#![deny(unused_variables)]
|
||||
#![allow(missing_copy_implementations)]
|
||||
#![allow(unstable)]
|
||||
|
||||
#[phase(plugin,link)]
|
||||
#[plugin]
|
||||
#[macro_use]
|
||||
extern crate syntax;
|
||||
#[phase(plugin, link)]
|
||||
#[plugin]
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
|
||||
use rustc::lint::LintPassObject;
|
||||
@ -50,23 +53,3 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_lint_pass(box lints::str_to_string::StrToStringPass as LintPassObject);
|
||||
reg.register_lint_pass(box lints::ban::BanPass as LintPassObject);
|
||||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! match_ignore_ascii_case {
|
||||
( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr, ) => {
|
||||
match_ignore_ascii_case! { $value:
|
||||
$( $string => $result ),+
|
||||
_ => $fallback
|
||||
}
|
||||
};
|
||||
( $value: expr: $( $string: expr => $result: expr ),+ _ => $fallback: expr ) => {
|
||||
{
|
||||
use std::ascii::AsciiExt;
|
||||
match $value.as_slice() {
|
||||
$( s if s.eq_ignore_ascii_case($string) => $result, )+
|
||||
_ => $fallback
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use rustc::lint::{Context, LintPass, LintArray};
|
||||
use utils::match_ty_unwrap;
|
||||
|
||||
declare_lint!(BANNED_TYPE, Deny,
|
||||
"Ban various unsafe type combinations")
|
||||
"Ban various unsafe type combinations");
|
||||
|
||||
/// Lint for banning various unsafe types
|
||||
///
|
||||
|
@ -9,7 +9,7 @@ use rustc::middle::{ty, def};
|
||||
use utils::match_lang_ty;
|
||||
|
||||
declare_lint!(INHERITANCE_INTEGRITY, Deny,
|
||||
"Ensures that struct fields are properly laid out for inheritance to work")
|
||||
"Ensures that struct fields are properly laid out for inheritance to work");
|
||||
|
||||
/// Lint for ensuring proper layout of DOM structs
|
||||
///
|
||||
|
@ -9,7 +9,7 @@ use rustc::lint::{Context, LintPass, LintArray};
|
||||
use rustc::middle::ty;
|
||||
|
||||
declare_lint!(PRIVATIZE, Deny,
|
||||
"Allows to enforce private fields for struct definitions")
|
||||
"Allows to enforce private fields for struct definitions");
|
||||
|
||||
/// Lint for keeping DOM fields private
|
||||
///
|
||||
|
@ -8,7 +8,7 @@ use rustc::middle::ty::expr_ty;
|
||||
use rustc::middle::ty;
|
||||
|
||||
declare_lint!(STR_TO_STRING, Deny,
|
||||
"Warn when a String could use to_owned() instead of to_string()")
|
||||
"Warn when a String could use to_owned() instead of to_string()");
|
||||
|
||||
/// Prefer str.to_owned() over str.to_string()
|
||||
///
|
||||
|
@ -9,7 +9,7 @@ use rustc::middle::ty::expr_ty;
|
||||
use rustc::util::ppaux::Repr;
|
||||
|
||||
declare_lint!(TRANSMUTE_TYPE_LINT, Allow,
|
||||
"Warn and report types being transmuted")
|
||||
"Warn and report types being transmuted");
|
||||
|
||||
/// Lint for auditing transmutes
|
||||
///
|
||||
|
@ -11,7 +11,7 @@ use rustc::util::ppaux::Repr;
|
||||
use utils::unsafe_context;
|
||||
|
||||
declare_lint!(UNROOTED_MUST_ROOT, Deny,
|
||||
"Warn and report usage of unrooted jsmanaged objects")
|
||||
"Warn and report usage of unrooted jsmanaged objects");
|
||||
|
||||
/// Lint for ensuring safe usage of unrooted pointers
|
||||
///
|
||||
@ -84,7 +84,7 @@ impl LintPass for UnrootedPass {
|
||||
return;
|
||||
},
|
||||
visit::FkItemFn(_, _, style, _) => match style {
|
||||
ast::UnsafeFn => return,
|
||||
ast::Unsafety::Unsafe => return,
|
||||
_ => ()
|
||||
},
|
||||
_ => ()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user