gfx: Implement window resizing

This commit is contained in:
Patrick Walton 2012-10-11 18:56:57 -07:00
parent e270a48694
commit 411ccaf220
6 changed files with 39 additions and 21 deletions

View file

@ -17,6 +17,7 @@ use dom::document::Document;
use dom::node::{Node, NodeScope, define_bindings};
use dom::event::{Event, ResizeEvent, ReflowEvent};
use dom::window::Window;
use geom::size::Size2D;
use gfx::compositor::Compositor;
use layout::layout_task;
use layout_task::{LayoutTask, BuildMsg};
@ -84,6 +85,7 @@ struct Content {
mut document: Option<@Document>,
mut window: Option<@Window>,
mut doc_url: Option<Url>,
mut window_size: Size2D<uint>,
resource_task: ResourceTask,
@ -117,9 +119,10 @@ fn Content(layout_task: LayoutTask,
jsrt : jsrt,
cx : cx,
document : None,
window : None,
doc_url : None,
document : None,
window : None,
doc_url : None,
window_size : Size2D(800u, 600u),
resource_task : resource_task,
compartment : compartment
@ -259,7 +262,8 @@ impl Content {
// Send new document and relevant styles to layout
// FIXME: Put CSS rules in an arc or something.
self.layout_task.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url, self.event_port.chan()));
self.layout_task.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url,
self.event_port.chan(), self.window_size));
// Indicate that reader was forked so any further
// changes will be isolated.
@ -282,7 +286,8 @@ impl Content {
fn handle_event(event: Event) -> bool {
match event {
ResizeEvent(new_width, new_height) => {
debug!("content got resize event: %d, %d", new_width, new_height);
debug!("content got resize event: %u, %u", new_width, new_height);
self.window_size = Size2D(new_width, new_height);
match copy self.document {
None => {
// Nothing to do.

View file

@ -1,5 +1,5 @@
enum Event {
ResizeEvent(int, int),
ResizeEvent(uint, uint),
ReflowEvent
}

View file

@ -22,7 +22,6 @@ pub fn render_layers(layer: &RenderLayer,
let mut buffer = buffer;
if buffer.size != layer.size {
// Create a new buffer.
io::println("making new buffer size!");
let cairo_surface = ImageSurface(CAIRO_FORMAT_RGB24,
layer.size.width as c_int,
layer.size.height as c_int);

View file

@ -289,6 +289,7 @@ fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t {
fn clear(ctx: &RenderContext) {
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat));
let rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat), Size2D(800 as AzFloat, 600 as AzFloat));
let rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
Size2D(ctx.canvas.size.width as AzFloat, ctx.canvas.size.height as AzFloat));
ctx.canvas.draw_target.fill_rect(&rect, &pattern);
}

View file

@ -44,7 +44,7 @@ enum LayoutQueryResponse_ {
}
pub enum Msg {
BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>),
BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>, Size2D<uint>),
PingMsg(comm::Chan<content_task::PingMsg>),
QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
ExitMsg
@ -128,18 +128,20 @@ impl Layout {
debug!("layout: ExitMsg received");
return false
},
BuildMsg(node, styles, doc_url, to_content) => {
BuildMsg(node, styles, doc_url, to_content, window_size) => {
debug!("layout: received layout request for: %s", doc_url.to_str());
debug!("layout: parsed Node tree");
node.dump();
let screen_size = Size2D(au::from_px(window_size.width as int),
au::from_px(window_size.height as int));
let layout_ctx = LayoutContext {
image_cache: self.image_cache_task,
font_cache: self.font_cache,
doc_url: doc_url,
reflow_cb: || to_content.send(ReflowEvent),
// TODO: obtain screen size from a real data source
screen_size: Rect(Point2D(au(0), au(0)), Size2D(au::from_px(800), au::from_px(600)))
screen_size: Rect(Point2D(au(0), au(0)), screen_size)
};
do util::time::time(~"layout") {
@ -150,7 +152,8 @@ impl Layout {
apply_style(&layout_ctx, node, copy layout_ctx.reflow_cb);
let builder = LayoutTreeBuilder();
let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx, node) {
let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
node) {
Ok(root) => root,
Err(*) => fail ~"Root flow should always exist"
};
@ -169,7 +172,8 @@ impl Layout {
};
let render_layer = RenderLayer {
display_list: move dlist,
size: Size2D(800u, 600u)
size: Size2D(au::to_px(screen_size.width) as uint,
au::to_px(screen_size.height) as uint)
};
// TODO: set options on the builder before building

View file

@ -79,8 +79,8 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>) {
let image = @layers::layers::Image(0, 0, layers::layers::RGB24Format, ~[]);
let image_layer = @layers::layers::ImageLayer(image);
image_layer.common.set_transform
(image_layer.common.transform.scale(&800.0f32, &600.0f32, &1.0f32));
let original_layer_transform = image_layer.common.transform;
image_layer.common.set_transform(original_layer_transform.scale(&800.0f32, &600.0f32, &1f32));
let scene = @layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
Size2D(800.0f32, 600.0f32));
@ -105,10 +105,21 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>) {
return_surface(surfaces, dt);
lend_surface(surfaces, sender);
let width = surfaces.front.layer_buffer.size.width as uint;
let height = surfaces.front.layer_buffer.size.height as uint;
let buffer = surfaces.front.layer_buffer.cairo_surface.data();
let image = @layers::layers::Image(800, 600, layers::layers::ARGB32Format,
let image = @layers::layers::Image(width, height, layers::layers::ARGB32Format,
buffer);
image_layer.set_image(image);
image_layer.common.set_transform(original_layer_transform.scale(&(width as f32),
&(height as f32),
&1.0f32));
// FIXME: Cross-crate struct mutability is broken.
let size: &mut Size2D<f32>;
unsafe { size = cast::transmute(&scene.size); }
*size = Size2D(width as f32, height as f32);
}
Exit => {
*done = true;
@ -124,7 +135,7 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>) {
#debug("osmain: window resized to %d,%d", width as int, height as int);
for event_listeners.each |event_listener| {
event_listener.send(ResizeEvent(width as int, height as int));
event_listener.send(ResizeEvent(width as uint, height as uint));
}
}
@ -206,9 +217,7 @@ fn return_surface(surfaces: &SurfaceSet, layer_buffer: LayerBuffer) {
assert surfaces.front.have;
assert !surfaces.back.have;
// FIXME: This is incompatible with page resizing.
assert surfaces.back.layer_buffer.draw_target.azure_draw_target ==
layer_buffer.draw_target.azure_draw_target;
surfaces.back.layer_buffer = move layer_buffer;
// Now we have it again
surfaces.back.have = true;