mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Reflow when images become available
This commit is contained in:
parent
5e379067e6
commit
7bf10c8e06
6 changed files with 55 additions and 16 deletions
|
@ -88,7 +88,8 @@ struct Content<S:Sink send copy> {
|
|||
|
||||
let resource_task: ResourceTask;
|
||||
|
||||
new(layout: Layout, sink: S, from_master: Port<ControlMsg>, resource_task: ResourceTask) {
|
||||
new(layout: Layout, sink: S, from_master: Port<ControlMsg>,
|
||||
resource_task: ResourceTask) {
|
||||
self.layout = layout;
|
||||
self.sink = sink;
|
||||
self.from_master = from_master;
|
||||
|
@ -193,7 +194,7 @@ struct Content<S:Sink send copy> {
|
|||
|
||||
// Send new document and relevant styles to layout
|
||||
// FIXME: Put CSS rules in an arc or something.
|
||||
self.layout.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url));
|
||||
self.layout.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url, self.event_port.chan()));
|
||||
|
||||
// Indicate that reader was forked so any further
|
||||
// changes will be isolated.
|
||||
|
@ -215,6 +216,19 @@ struct Content<S:Sink send copy> {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
ReflowEvent => {
|
||||
#debug("content got reflow event");
|
||||
match copy self.document {
|
||||
none => {
|
||||
// Nothing to do.
|
||||
}
|
||||
some(document) => {
|
||||
assert self.doc_url.is_some();
|
||||
self.relayout(*document, &self.doc_url.get());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
enum Event {
|
||||
ResizeEvent(int, int)
|
||||
ResizeEvent(int, int),
|
||||
ReflowEvent
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import resource::image_cache_task;
|
|||
import image_cache_task::ImageCacheTask;
|
||||
import core::to_str::ToStr;
|
||||
import std::arc::{arc, clone};
|
||||
import task::spawn;
|
||||
|
||||
enum BoxKind {
|
||||
BlockBox,
|
||||
|
@ -87,11 +88,13 @@ struct ImageHolder {
|
|||
let mut url : option<url>;
|
||||
let mut image : option<arc<~Image>>;
|
||||
let image_cache_task: ImageCacheTask;
|
||||
let reflow: fn~();
|
||||
|
||||
new(-url : url, image_cache_task: ImageCacheTask) {
|
||||
new(-url : url, image_cache_task: ImageCacheTask, reflow: fn~()) {
|
||||
self.url = some(copy url);
|
||||
self.image = none;
|
||||
self.image_cache_task = image_cache_task;
|
||||
self.reflow = copy reflow;
|
||||
|
||||
// Tell the image cache we're going to be interested in this url
|
||||
// FIXME: These two messages must be sent to prep an image for use
|
||||
|
@ -117,8 +120,22 @@ struct ImageHolder {
|
|||
self.image_cache_task.send(image_cache_task::GetImage(copy url, response_port.chan()));
|
||||
self.image = match response_port.recv() {
|
||||
image_cache_task::ImageReady(image) => some(clone(&image)),
|
||||
image_cache_task::ImageNotReady
|
||||
| image_cache_task::ImageFailed => {
|
||||
image_cache_task::ImageNotReady => {
|
||||
// Need to reflow when the image is available
|
||||
let image_cache_task = self.image_cache_task;
|
||||
let reflow = copy self.reflow;
|
||||
do spawn |copy url, move reflow| {
|
||||
let response_port = port();
|
||||
image_cache_task.send(image_cache_task::WaitForImage(copy url, response_port.chan()));
|
||||
match response_port.recv() {
|
||||
image_cache_task::ImageReady(*) => reflow(),
|
||||
image_cache_task::ImageNotReady => fail /*not possible*/,
|
||||
image_cache_task::ImageFailed => ()
|
||||
}
|
||||
}
|
||||
none
|
||||
}
|
||||
image_cache_task::ImageFailed => {
|
||||
#info("image was not ready for %s", url.to_str());
|
||||
// FIXME: Need to schedule another layout when the image is ready
|
||||
none
|
||||
|
|
|
@ -12,6 +12,7 @@ import gfx::renderer::Renderer;
|
|||
import resource::image_cache_task::ImageCacheTask;
|
||||
import std::net::url::url;
|
||||
import style::apply::apply_style;
|
||||
import dom::event::{Event, ReflowEvent};
|
||||
|
||||
import task::*;
|
||||
import comm::*;
|
||||
|
@ -19,7 +20,7 @@ import comm::*;
|
|||
type Layout = Chan<Msg>;
|
||||
|
||||
enum Msg {
|
||||
BuildMsg(Node, arc<Stylesheet>, url),
|
||||
BuildMsg(Node, arc<Stylesheet>, url, Chan<Event>),
|
||||
PingMsg(Chan<content::PingMsg>),
|
||||
ExitMsg
|
||||
}
|
||||
|
@ -33,7 +34,7 @@ fn Layout(renderer: Renderer, image_cache_task: ImageCacheTask) -> Layout {
|
|||
#debug("layout: ExitMsg received");
|
||||
break;
|
||||
}
|
||||
BuildMsg(node, styles, doc_url) => {
|
||||
BuildMsg(node, styles, doc_url, event_chan) => {
|
||||
#debug("layout: received layout request for:");
|
||||
node.dump();
|
||||
|
||||
|
@ -44,7 +45,9 @@ fn Layout(renderer: Renderer, image_cache_task: ImageCacheTask) -> Layout {
|
|||
let this_box = node.construct_boxes();
|
||||
this_box.dump();
|
||||
|
||||
apply_style(this_box, &doc_url, image_cache_task);
|
||||
let reflow: fn~() = || event_chan.send(ReflowEvent);
|
||||
|
||||
apply_style(this_box, &doc_url, image_cache_task, reflow);
|
||||
|
||||
this_box.reflow_subtree(px_to_au(800));
|
||||
|
||||
|
|
|
@ -14,13 +14,15 @@ struct StyleApplicator {
|
|||
box: @Box;
|
||||
doc_url: &url;
|
||||
image_cache_task: ImageCacheTask;
|
||||
reflow: fn~();
|
||||
}
|
||||
|
||||
fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask) {
|
||||
fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask, reflow: fn~()) {
|
||||
let applicator = StyleApplicator {
|
||||
box: box,
|
||||
doc_url: doc_url,
|
||||
image_cache_task: image_cache_task
|
||||
image_cache_task: image_cache_task,
|
||||
reflow: reflow
|
||||
};
|
||||
|
||||
applicator.apply_css_style();
|
||||
|
@ -28,11 +30,12 @@ fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask) {
|
|||
|
||||
#[doc="A wrapper around a set of functions that can be applied as a top-down traversal of layout
|
||||
boxes."]
|
||||
fn inheritance_wrapper(box : @Box, doc_url: &url, image_cache_task: ImageCacheTask) {
|
||||
fn inheritance_wrapper(box : @Box, doc_url: &url, image_cache_task: ImageCacheTask, reflow: fn~()) {
|
||||
let applicator = StyleApplicator {
|
||||
box: box,
|
||||
doc_url: doc_url,
|
||||
image_cache_task: image_cache_task
|
||||
image_cache_task: image_cache_task,
|
||||
reflow: reflow
|
||||
};
|
||||
applicator.apply_style();
|
||||
inhereit_height(box);
|
||||
|
@ -103,8 +106,9 @@ impl StyleApplicator {
|
|||
fn apply_css_style() {
|
||||
let doc_url = copy *self.doc_url;
|
||||
let image_cache_task = self.image_cache_task;
|
||||
let reflow = copy self.reflow;
|
||||
do top_down_traversal(self.box) |box, move doc_url| {
|
||||
inheritance_wrapper(box, &doc_url, image_cache_task);
|
||||
inheritance_wrapper(box, &doc_url, image_cache_task, reflow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +140,7 @@ impl StyleApplicator {
|
|||
// FIXME: Some sort of BASE HREF support!
|
||||
// FIXME: Parse URLs!
|
||||
let new_url = make_url(option::unwrap(url), some(copy *self.doc_url));
|
||||
self.box.appearance.background_image = some(ImageHolder(new_url, self.image_cache_task))
|
||||
self.box.appearance.background_image = some(ImageHolder(new_url, self.image_cache_task, self.reflow))
|
||||
};
|
||||
}
|
||||
_ => { /* Ignore. */ }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export Msg, Prefetch, Decode, GetImage, Exit;
|
||||
export Msg, Prefetch, Decode, GetImage, WaitForImage, Exit;
|
||||
export ImageResponseMsg, ImageReady, ImageNotReady, ImageFailed;
|
||||
export ImageCacheTask;
|
||||
export image_cache_task;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue