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::node::{Node, NodeScope, define_bindings};
use dom::event::{Event, ResizeEvent, ReflowEvent}; use dom::event::{Event, ResizeEvent, ReflowEvent};
use dom::window::Window; use dom::window::Window;
use geom::size::Size2D;
use gfx::compositor::Compositor; use gfx::compositor::Compositor;
use layout::layout_task; use layout::layout_task;
use layout_task::{LayoutTask, BuildMsg}; use layout_task::{LayoutTask, BuildMsg};
@ -84,6 +85,7 @@ struct Content {
mut document: Option<@Document>, mut document: Option<@Document>,
mut window: Option<@Window>, mut window: Option<@Window>,
mut doc_url: Option<Url>, mut doc_url: Option<Url>,
mut window_size: Size2D<uint>,
resource_task: ResourceTask, resource_task: ResourceTask,
@ -120,6 +122,7 @@ fn Content(layout_task: LayoutTask,
document : None, document : None,
window : None, window : None,
doc_url : None, doc_url : None,
window_size : Size2D(800u, 600u),
resource_task : resource_task, resource_task : resource_task,
compartment : compartment compartment : compartment
@ -259,7 +262,8 @@ impl Content {
// 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_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 // Indicate that reader was forked so any further
// changes will be isolated. // changes will be isolated.
@ -282,7 +286,8 @@ impl Content {
fn handle_event(event: Event) -> bool { fn handle_event(event: Event) -> bool {
match event { match event {
ResizeEvent(new_width, new_height) => { 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 { match copy self.document {
None => { None => {
// Nothing to do. // Nothing to do.

View file

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

View file

@ -22,7 +22,6 @@ pub fn render_layers(layer: &RenderLayer,
let mut buffer = buffer; let mut buffer = buffer;
if buffer.size != layer.size { if buffer.size != layer.size {
// Create a new buffer. // Create a new buffer.
io::println("making new buffer size!");
let cairo_surface = ImageSurface(CAIRO_FORMAT_RGB24, let cairo_surface = ImageSurface(CAIRO_FORMAT_RGB24,
layer.size.width as c_int, layer.size.width as c_int,
layer.size.height 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) { fn clear(ctx: &RenderContext) {
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat)); 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); ctx.canvas.draw_target.fill_rect(&rect, &pattern);
} }

View file

@ -44,7 +44,7 @@ enum LayoutQueryResponse_ {
} }
pub enum Msg { 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>), PingMsg(comm::Chan<content_task::PingMsg>),
QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>), QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
ExitMsg ExitMsg
@ -128,18 +128,20 @@ impl Layout {
debug!("layout: ExitMsg received"); debug!("layout: ExitMsg received");
return false 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: received layout request for: %s", doc_url.to_str());
debug!("layout: parsed Node tree"); debug!("layout: parsed Node tree");
node.dump(); 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 { let layout_ctx = LayoutContext {
image_cache: self.image_cache_task, image_cache: self.image_cache_task,
font_cache: self.font_cache, font_cache: self.font_cache,
doc_url: doc_url, doc_url: doc_url,
reflow_cb: || to_content.send(ReflowEvent), reflow_cb: || to_content.send(ReflowEvent),
// TODO: obtain screen size from a real data source screen_size: Rect(Point2D(au(0), au(0)), screen_size)
screen_size: Rect(Point2D(au(0), au(0)), Size2D(au::from_px(800), au::from_px(600)))
}; };
do util::time::time(~"layout") { do util::time::time(~"layout") {
@ -150,7 +152,8 @@ impl Layout {
apply_style(&layout_ctx, node, copy layout_ctx.reflow_cb); apply_style(&layout_ctx, node, copy layout_ctx.reflow_cb);
let builder = LayoutTreeBuilder(); 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, Ok(root) => root,
Err(*) => fail ~"Root flow should always exist" Err(*) => fail ~"Root flow should always exist"
}; };
@ -169,7 +172,8 @@ impl Layout {
}; };
let render_layer = RenderLayer { let render_layer = RenderLayer {
display_list: move dlist, 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 // 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 = @layers::layers::Image(0, 0, layers::layers::RGB24Format, ~[]);
let image_layer = @layers::layers::ImageLayer(image); let image_layer = @layers::layers::ImageLayer(image);
image_layer.common.set_transform let original_layer_transform = image_layer.common.transform;
(image_layer.common.transform.scale(&800.0f32, &600.0f32, &1.0f32)); image_layer.common.set_transform(original_layer_transform.scale(&800.0f32, &600.0f32, &1f32));
let scene = @layers::scene::Scene(layers::layers::ImageLayerKind(image_layer), let scene = @layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
Size2D(800.0f32, 600.0f32)); Size2D(800.0f32, 600.0f32));
@ -105,10 +105,21 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>) {
return_surface(surfaces, dt); return_surface(surfaces, dt);
lend_surface(surfaces, sender); 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 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); buffer);
image_layer.set_image(image); 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 => { Exit => {
*done = true; *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); #debug("osmain: window resized to %d,%d", width as int, height as int);
for event_listeners.each |event_listener| { 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.front.have;
assert !surfaces.back.have; assert !surfaces.back.have;
// FIXME: This is incompatible with page resizing. surfaces.back.layer_buffer = move layer_buffer;
assert surfaces.back.layer_buffer.draw_target.azure_draw_target ==
layer_buffer.draw_target.azure_draw_target;
// Now we have it again // Now we have it again
surfaces.back.have = true; surfaces.back.have = true;