Store content offset in unscaled pixels

Content offset is now stored in unscaled pixels, so that it can be
applied to tile positions during compositor rendering without unscaling
it. This means that when using it in calculations of layer size (stored
in device pixels), we need to scale it. Scene scale is now stored as a
scale rather than a transformation.

Fixes #3269.
Fixes #3042.
This commit is contained in:
Martin Robinson 2014-09-12 11:37:41 -07:00
parent 13ae369dec
commit ea14fca1dc
5 changed files with 89 additions and 100 deletions

View file

@ -22,7 +22,6 @@ use windowing::PinchZoomWindowEvent;
use azure::azure_hl::SourceSurfaceMethods;
use azure::azure_hl;
use std::cmp;
use geom::matrix::identity;
use geom::point::{Point2D, TypedPoint2D};
use geom::rect::Rect;
use geom::size::TypedSize2D;
@ -159,7 +158,7 @@ impl IOCompositor {
context: rendergl::RenderContext::new(CompositorTask::create_graphics_context(),
show_debug_borders),
root_pipeline: None,
scene: Scene::new(window_size.as_f32().to_untyped(), identity()),
scene: Scene::new(window_size.as_f32().to_untyped()),
window_size: window_size,
hidpi_factor: hidpi_factor,
composite_ready: false,
@ -543,26 +542,41 @@ impl IOCompositor {
}));
}
pub fn move_layer(&self,
pipeline_id: PipelineId,
layer_id: LayerId,
origin: TypedPoint2D<DevicePixel, f32>)
-> bool {
match self.find_layer_with_pipeline_and_layer_id(pipeline_id, layer_id) {
Some(ref layer) => {
if layer.extra_data.borrow().wants_scroll_events == WantsScrollEvents {
events::clamp_scroll_offset_and_scroll_layer(layer.clone(),
TypedPoint2D(0f32, 0f32) - origin,
self.window_size.as_f32(),
self.device_pixels_per_page_px());
}
true
}
None => false,
}
}
fn scroll_layer_to_fragment_point_if_necessary(&mut self,
pipeline_id: PipelineId,
layer_id: LayerId) {
let device_pixels_per_page_px = self.device_pixels_per_page_px();
let window_size = self.window_size.as_f32();
let needs_recomposite = match self.scene.root {
Some(ref mut root_layer) => {
self.fragment_point.take().map_or(false, |fragment_point| {
let fragment_point = fragment_point * device_pixels_per_page_px.get();
events::move(root_layer.clone(),
pipeline_id,
layer_id,
Point2D::from_untyped(&fragment_point),
window_size)
})
}
None => fail!("Compositor: Tried to scroll to fragment without root layer."),
};
match self.fragment_point.take() {
Some(point) => {
let point = point * device_pixels_per_page_px.get();
if !self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&point)) {
fail!("Compositor: Tried to scroll to fragment with unknown layer.");
}
self.recomposite_if(needs_recomposite);
self.recomposite = true;
}
None => {}
};
}
fn set_layer_origin(&mut self,
@ -610,30 +624,13 @@ impl IOCompositor {
pipeline_id: PipelineId,
layer_id: LayerId,
point: Point2D<f32>) {
let device_pixels_per_page_px = self.device_pixels_per_page_px();
let device_point = point * device_pixels_per_page_px.get();
let window_size = self.window_size.as_f32();
let (ask, move): (bool, bool) = match self.scene.root {
Some(ref layer) if layer.extra_data.borrow().pipeline.id == pipeline_id => {
(true,
events::move(layer.clone(),
pipeline_id,
layer_id,
Point2D::from_untyped(&device_point),
window_size))
}
Some(_) | None => {
self.fragment_point = Some(point);
(false, false)
}
};
if ask {
self.recomposite_if(move);
if self.move_layer(pipeline_id, layer_id, Point2D::from_untyped(&device_point)) {
self.recomposite = true;
self.send_buffer_requests_for_all_layers();
} else {
self.fragment_point = Some(point);
}
}
@ -750,12 +747,14 @@ impl IOCompositor {
cursor: TypedPoint2D<DevicePixel, i32>) {
let mut scroll = false;
let window_size = self.window_size.as_f32();
let scene_scale = self.device_pixels_per_page_px();
match self.scene.root {
Some(ref mut layer) => {
scroll = events::handle_scroll_event(layer.clone(),
delta,
cursor.as_f32(),
window_size) || scroll;
window_size,
scene_scale) || scroll;
}
None => { }
}
@ -779,7 +778,7 @@ impl IOCompositor {
fn update_zoom_transform(&mut self) {
let scale = self.device_pixels_per_page_px();
self.scene.transform = identity().scale(scale.get(), scale.get(), 1f32);
self.scene.scale = scale.get();
}
fn on_zoom_window_event(&mut self, magnification: f32) {
@ -806,12 +805,14 @@ impl IOCompositor {
let delta = page_delta * self.device_pixels_per_page_px();
let cursor = TypedPoint2D(-1f32, -1f32); // Make sure this hits the base layer.
let scene_scale = self.device_pixels_per_page_px();
match self.scene.root {
Some(ref mut layer) => {
events::handle_scroll_event(layer.clone(),
delta,
cursor,
window_size);
window_size,
scene_scale);
}
None => { }
}