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