Fixed scaling artefacts in paint worklets caused by zoom and hidpi.

This commit is contained in:
Alan Jeffrey 2017-06-23 11:07:02 -05:00
parent e19fefcb47
commit caa3585219
24 changed files with 160 additions and 77 deletions

1
Cargo.lock generated
View file

@ -2558,7 +2558,6 @@ dependencies = [
name = "script_traits" name = "script_traits"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1", "bluetooth_traits 0.0.1",
"canvas_traits 0.0.1", "canvas_traits 0.0.1",
"cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -16,7 +16,7 @@ use msg::constellation_msg::{PipelineId, PipelineIndex, PipelineNamespaceId, Tra
use net_traits::image::base::{Image, PixelFormat}; use net_traits::image::base::{Image, PixelFormat};
use profile_traits::time::{self, ProfilerCategory, profile}; use profile_traits::time::{self, ProfilerCategory, profile};
use script_traits::{AnimationState, AnimationTickType, ConstellationControlMsg}; use script_traits::{AnimationState, AnimationTickType, ConstellationControlMsg};
use script_traits::{ConstellationMsg, DevicePixel, LayoutControlMsg, LoadData, MouseButton}; use script_traits::{ConstellationMsg, LayoutControlMsg, LoadData, MouseButton};
use script_traits::{MouseEventType, ScrollState}; use script_traits::{MouseEventType, ScrollState};
use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId, WindowSizeData, WindowSizeType}; use script_traits::{TouchpadPressurePhase, TouchEventType, TouchId, WindowSizeData, WindowSizeType};
use script_traits::CompositorEvent::{self, MouseMoveEvent, MouseButtonEvent, TouchEvent, TouchpadPressureEvent}; use script_traits::CompositorEvent::{self, MouseMoveEvent, MouseButtonEvent, TouchEvent, TouchpadPressureEvent};
@ -29,7 +29,7 @@ use std::fs::File;
use std::rc::Rc; use std::rc::Rc;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use style_traits::{CSSPixel, PinchZoomFactor}; use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use time::{precise_time_ns, precise_time_s}; use time::{precise_time_ns, precise_time_s};
use touch::{TouchHandler, TouchAction}; use touch::{TouchHandler, TouchAction};

View file

@ -4,8 +4,9 @@
use euclid::{TypedPoint2D, TypedVector2D}; use euclid::{TypedPoint2D, TypedVector2D};
use euclid::ScaleFactor; use euclid::ScaleFactor;
use script_traits::{DevicePixel, EventResult, TouchId}; use script_traits::{EventResult, TouchId};
use self::TouchState::*; use self::TouchState::*;
use style_traits::DevicePixel;
/// Minimum number of `DeviceIndependentPixel` to begin touch scrolling. /// Minimum number of `DeviceIndependentPixel` to begin touch scrolling.
const TOUCH_PAN_MIN_SCREEN_PX: f32 = 20.0; const TOUCH_PAN_MIN_SCREEN_PX: f32 = 20.0;

View file

@ -11,11 +11,12 @@ use gleam::gl;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::{Key, KeyModifiers, KeyState, TraversalDirection}; use msg::constellation_msg::{Key, KeyModifiers, KeyState, TraversalDirection};
use net_traits::net_error_list::NetError; use net_traits::net_error_list::NetError;
use script_traits::{DevicePixel, LoadData, MouseButton, TouchEventType, TouchId, TouchpadPressurePhase}; use script_traits::{LoadData, MouseButton, TouchEventType, TouchId, TouchpadPressurePhase};
use servo_geometry::DeviceIndependentPixel; use servo_geometry::DeviceIndependentPixel;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::fmt::{Debug, Error, Formatter}; use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc; use std::rc::Rc;
use style_traits::DevicePixel;
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use webrender_api::ScrollLocation; use webrender_api::ScrollLocation;

View file

@ -21,7 +21,7 @@ use net_traits::{IpcSend, ResourceThreads};
use net_traits::image_cache::ImageCache; use net_traits::image_cache::ImageCache;
use profile_traits::mem as profile_mem; use profile_traits::mem as profile_mem;
use profile_traits::time; use profile_traits::time;
use script_traits::{ConstellationControlMsg, DevicePixel, DiscardBrowsingContext}; use script_traits::{ConstellationControlMsg, DiscardBrowsingContext};
use script_traits::{DocumentActivity, InitialScriptState}; use script_traits::{DocumentActivity, InitialScriptState};
use script_traits::{LayoutControlMsg, LayoutMsg, LoadData, MozBrowserEvent}; use script_traits::{LayoutControlMsg, LayoutMsg, LoadData, MozBrowserEvent};
use script_traits::{NewLayoutInfo, SWManagerMsg, SWManagerSenders, ScriptMsg}; use script_traits::{NewLayoutInfo, SWManagerMsg, SWManagerSenders, ScriptMsg};
@ -38,6 +38,7 @@ use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use style_traits::CSSPixel; use style_traits::CSSPixel;
use style_traits::DevicePixel;
use webrender_api; use webrender_api;
use webvr_traits::WebVRMsg; use webvr_traits::WebVRMsg;

View file

@ -1170,7 +1170,10 @@ impl FragmentDisplayListBuilding for Fragment {
// including padding, but not border or margin, so we follow suit. // including padding, but not border or margin, so we follow suit.
// https://github.com/w3c/css-houdini-drafts/issues/417 // https://github.com/w3c/css-houdini-drafts/issues/417
let unbordered_box = self.border_box - style.logical_border_width(); let unbordered_box = self.border_box - style.logical_border_width();
let size = unbordered_box.size.to_physical(style.writing_mode); let device_pixel_ratio = state.layout_context.style_context.device_pixel_ratio();
let size_in_au = unbordered_box.size.to_physical(style.writing_mode);
let size_in_px = TypedSize2D::new(size_in_au.width.to_f32_px(), size_in_au.height.to_f32_px());
let size_in_dpx = size_in_px * device_pixel_ratio;
let name = paint_worklet.name.clone(); let name = paint_worklet.name.clone();
// Get the painter, and the computed values for its properties. // Get the painter, and the computed values for its properties.
@ -1188,17 +1191,17 @@ impl FragmentDisplayListBuilding for Fragment {
// TODO: add a one-place cache to avoid drawing the paint image every time. // TODO: add a one-place cache to avoid drawing the paint image every time.
// https://github.com/servo/servo/issues/17369 // https://github.com/servo/servo/issues/17369
debug!("Drawing a paint image {}({},{}).", name, size.width.to_px(), size.height.to_px()); debug!("Drawing a paint image {}({},{}).", name, size_in_px.width, size_in_px.height);
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap();
painter.draw_a_paint_image(size, properties, sender); painter.draw_a_paint_image(size_in_px, device_pixel_ratio, properties, sender);
// TODO: timeout // TODO: timeout
let webrender_image = match receiver.recv() { let webrender_image = match receiver.recv() {
Ok(CanvasData::Image(canvas_data)) => { Ok(CanvasData::Image(canvas_data)) => {
WebRenderImageInfo { WebRenderImageInfo {
// TODO: it would be nice to get this data back from the canvas // TODO: it would be nice to get this data back from the canvas
width: size.width.to_px().abs() as u32, width: size_in_dpx.width as u32,
height: size.height.to_px().abs() as u32, height: size_in_dpx.height as u32,
format: PixelFormat::BGRA8, format: PixelFormat::BGRA8,
key: Some(canvas_data.image_key), key: Some(canvas_data.image_key),
} }

View file

@ -462,9 +462,12 @@ impl LayoutThread {
layout_threads: usize, layout_threads: usize,
paint_time_metrics: PaintTimeMetrics) paint_time_metrics: PaintTimeMetrics)
-> LayoutThread { -> LayoutThread {
// The device pixel ratio is incorrect (it does not have the hidpi value),
// but it will be set correctly when the initial reflow takes place.
let device = Device::new( let device = Device::new(
MediaType::Screen, MediaType::Screen,
opts::get().initial_window_size.to_f32() * ScaleFactor::new(1.0)); opts::get().initial_window_size.to_f32() * ScaleFactor::new(1.0),
ScaleFactor::new(opts::get().device_pixels_per_px.unwrap_or(1.0)));
let configuration = let configuration =
rayon::Configuration::new().num_threads(layout_threads); rayon::Configuration::new().num_threads(layout_threads);
@ -1125,6 +1128,7 @@ impl LayoutThread {
trace!("{:?}", ShowSubtree(element.as_node())); trace!("{:?}", ShowSubtree(element.as_node()));
let initial_viewport = data.window_size.initial_viewport; let initial_viewport = data.window_size.initial_viewport;
let device_pixel_ratio = data.window_size.device_pixel_ratio;
let old_viewport_size = self.viewport_size; let old_viewport_size = self.viewport_size;
let current_screen_size = Size2D::new(Au::from_f32_px(initial_viewport.width), let current_screen_size = Size2D::new(Au::from_f32_px(initial_viewport.width),
Au::from_f32_px(initial_viewport.height)); Au::from_f32_px(initial_viewport.height));
@ -1134,7 +1138,7 @@ impl LayoutThread {
let document_shared_lock = document.style_shared_lock(); let document_shared_lock = document.style_shared_lock();
self.document_shared_lock = Some(document_shared_lock.clone()); self.document_shared_lock = Some(document_shared_lock.clone());
let author_guard = document_shared_lock.read(); let author_guard = document_shared_lock.read();
let device = Device::new(MediaType::Screen, initial_viewport); let device = Device::new(MediaType::Screen, initial_viewport, device_pixel_ratio);
self.stylist.set_device(device, &author_guard, &data.document_stylesheets); self.stylist.set_device(device, &author_guard, &data.document_stylesheets);
self.viewport_size = self.viewport_size =

View file

@ -43,7 +43,7 @@ use dom::bindings::str::{DOMString, USVString};
use dom::bindings::utils::WindowProxyHandler; use dom::bindings::utils::WindowProxyHandler;
use dom::document::PendingRestyle; use dom::document::PendingRestyle;
use encoding::types::EncodingRef; use encoding::types::EncodingRef;
use euclid::{Transform2D, Transform3D, Point2D, Vector2D, Rect, Size2D}; use euclid::{Transform2D, Transform3D, Point2D, Vector2D, Rect, Size2D, ScaleFactor};
use euclid::Length as EuclidLength; use euclid::Length as EuclidLength;
use html5ever::{Prefix, LocalName, Namespace, QualName}; use html5ever::{Prefix, LocalName, Namespace, QualName};
use html5ever::buffer_queue::BufferQueue; use html5ever::buffer_queue::BufferQueue;
@ -484,6 +484,13 @@ unsafe impl JSTraceable for Point2D<f32> {
} }
} }
unsafe impl<T, U> JSTraceable for ScaleFactor<f32, T, U> {
#[inline]
unsafe fn trace(&self, _trc: *mut JSTracer) {
// Do nothing
}
}
unsafe impl JSTraceable for Vector2D<f32> { unsafe impl JSTraceable for Vector2D<f32> {
#[inline] #[inline]
unsafe fn trace(&self, _trc: *mut JSTracer) { unsafe fn trace(&self, _trc: *mut JSTracer) {

View file

@ -76,7 +76,8 @@ impl MediaQueryList {
pub fn evaluate(&self) -> bool { pub fn evaluate(&self) -> bool {
if let Some(window_size) = self.document.window().window_size() { if let Some(window_size) = self.document.window().window_size() {
let viewport_size = window_size.initial_viewport; let viewport_size = window_size.initial_viewport;
let device = Device::new(MediaType::Screen, viewport_size); let device_pixel_ratio = window_size.device_pixel_ratio;
let device = Device::new(MediaType::Screen, viewport_size, device_pixel_ratio);
self.media_query_list.evaluate(&device, self.document.quirks_mode()) self.media_query_list.evaluate(&device, self.document.quirks_mode())
} else { } else {
false false

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use canvas_traits::CanvasData; use canvas_traits::CanvasData;
use canvas_traits::CanvasMsg; use canvas_traits::CanvasMsg;
use canvas_traits::FromLayoutMsg; use canvas_traits::FromLayoutMsg;
@ -26,12 +25,18 @@ use dom::canvaspattern::CanvasPattern;
use dom::canvasrenderingcontext2d::CanvasRenderingContext2D; use dom::canvasrenderingcontext2d::CanvasRenderingContext2D;
use dom::paintworkletglobalscope::PaintWorkletGlobalScope; use dom::paintworkletglobalscope::PaintWorkletGlobalScope;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::ScaleFactor;
use euclid::Size2D; use euclid::Size2D;
use euclid::TypedSize2D;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use std::cell::Cell;
use style_traits::CSSPixel;
use style_traits::DevicePixel;
#[dom_struct] #[dom_struct]
pub struct PaintRenderingContext2D { pub struct PaintRenderingContext2D {
context: CanvasRenderingContext2D, context: CanvasRenderingContext2D,
device_pixel_ratio: Cell<ScaleFactor<f32, CSSPixel, DevicePixel>>,
} }
impl PaintRenderingContext2D { impl PaintRenderingContext2D {
@ -39,6 +44,7 @@ impl PaintRenderingContext2D {
let size = Size2D::zero(); let size = Size2D::zero();
PaintRenderingContext2D { PaintRenderingContext2D {
context: CanvasRenderingContext2D::new_inherited(global.upcast(), None, size), context: CanvasRenderingContext2D::new_inherited(global.upcast(), None, size),
device_pixel_ratio: Cell::new(ScaleFactor::new(1.0)),
} }
} }
@ -53,9 +59,21 @@ impl PaintRenderingContext2D {
let _ = self.context.ipc_renderer().send(msg); let _ = self.context.ipc_renderer().send(msg);
} }
pub fn set_bitmap_dimensions(&self, size: Size2D<Au>) { pub fn set_bitmap_dimensions(&self,
let size = Size2D::new(size.width.to_px(), size.height.to_px()); size: TypedSize2D<f32, CSSPixel>,
self.context.set_bitmap_dimensions(size); device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>)
{
let size = size * device_pixel_ratio;
self.device_pixel_ratio.set(device_pixel_ratio);
self.context.set_bitmap_dimensions(size.to_untyped().to_i32());
self.scale_by_device_pixel_ratio();
}
fn scale_by_device_pixel_ratio(&self) {
let device_pixel_ratio = self.device_pixel_ratio.get().get() as f64;
if device_pixel_ratio != 1.0 {
self.Scale(device_pixel_ratio, device_pixel_ratio);
}
} }
} }
@ -92,12 +110,14 @@ impl PaintRenderingContext2DMethods for PaintRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform // https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform
fn SetTransform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) { fn SetTransform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
self.context.SetTransform(a, b, c, d, e, f) self.context.SetTransform(a, b, c, d, e, f);
self.scale_by_device_pixel_ratio();
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-resettransform // https://html.spec.whatwg.org/multipage/#dom-context-2d-resettransform
fn ResetTransform(&self) { fn ResetTransform(&self) {
self.context.ResetTransform() self.context.ResetTransform();
self.scale_by_device_pixel_ratio();
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use dom::bindings::codegen::Bindings::PaintSizeBinding; use dom::bindings::codegen::Bindings::PaintSizeBinding;
use dom::bindings::codegen::Bindings::PaintSizeBinding::PaintSizeMethods; use dom::bindings::codegen::Bindings::PaintSizeBinding::PaintSizeMethods;
use dom::bindings::js::Root; use dom::bindings::js::Root;
@ -11,7 +10,8 @@ use dom::bindings::reflector::Reflector;
use dom::bindings::reflector::reflect_dom_object; use dom::bindings::reflector::reflect_dom_object;
use dom::paintworkletglobalscope::PaintWorkletGlobalScope; use dom::paintworkletglobalscope::PaintWorkletGlobalScope;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::Size2D; use euclid::TypedSize2D;
use style_traits::CSSPixel;
#[dom_struct] #[dom_struct]
pub struct PaintSize { pub struct PaintSize {
@ -21,15 +21,15 @@ pub struct PaintSize {
} }
impl PaintSize { impl PaintSize {
fn new_inherited(size: Size2D<Au>) -> PaintSize { fn new_inherited(size: TypedSize2D<f32, CSSPixel>) -> PaintSize {
PaintSize { PaintSize {
reflector: Reflector::new(), reflector: Reflector::new(),
width: Finite::wrap(size.width.to_px().abs() as f64), width: Finite::wrap(size.width as f64),
height: Finite::wrap(size.height.to_px().abs() as f64), height: Finite::wrap(size.height as f64),
} }
} }
pub fn new(global: &PaintWorkletGlobalScope, size: Size2D<Au>) -> Root<PaintSize> { pub fn new(global: &PaintWorkletGlobalScope, size: TypedSize2D<f32, CSSPixel>) -> Root<PaintSize> {
reflect_dom_object(box PaintSize::new_inherited(size), global, PaintSizeBinding::Wrap) reflect_dom_object(box PaintSize::new_inherited(size), global, PaintSizeBinding::Wrap)
} }
} }

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use canvas_traits::CanvasData; use canvas_traits::CanvasData;
use canvas_traits::CanvasImageData; use canvas_traits::CanvasImageData;
use dom::bindings::callback::CallbackContainer; use dom::bindings::callback::CallbackContainer;
@ -27,7 +26,8 @@ use dom::workletglobalscope::WorkletGlobalScope;
use dom::workletglobalscope::WorkletGlobalScopeInit; use dom::workletglobalscope::WorkletGlobalScopeInit;
use dom::workletglobalscope::WorkletTask; use dom::workletglobalscope::WorkletTask;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::Size2D; use euclid::ScaleFactor;
use euclid::TypedSize2D;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use ipc_channel::ipc::IpcSharedMemory; use ipc_channel::ipc::IpcSharedMemory;
use js::jsapi::Call; use js::jsapi::Call;
@ -59,6 +59,8 @@ use std::ptr::null_mut;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use style_traits::CSSPixel;
use style_traits::DevicePixel;
/// https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope /// https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope
#[dom_struct] #[dom_struct]
@ -94,9 +96,9 @@ impl PaintWorkletGlobalScope {
pub fn perform_a_worklet_task(&self, task: PaintWorkletTask) { pub fn perform_a_worklet_task(&self, task: PaintWorkletTask) {
match task { match task {
PaintWorkletTask::DrawAPaintImage(name, size, properties, sender) => { PaintWorkletTask::DrawAPaintImage(name, size, device_pixel_ratio, properties, sender) => {
let properties = StylePropertyMapReadOnly::from_iter(self.upcast(), properties); let properties = StylePropertyMapReadOnly::from_iter(self.upcast(), properties);
self.draw_a_paint_image(name, size, &*properties, sender); self.draw_a_paint_image(name, size, device_pixel_ratio, &*properties, sender);
} }
} }
} }
@ -104,25 +106,28 @@ impl PaintWorkletGlobalScope {
/// https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image /// https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image
fn draw_a_paint_image(&self, fn draw_a_paint_image(&self,
name: Atom, name: Atom,
size: Size2D<Au>, size_in_px: TypedSize2D<f32, CSSPixel>,
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
properties: &StylePropertyMapReadOnly, properties: &StylePropertyMapReadOnly,
sender: IpcSender<CanvasData>) sender: IpcSender<CanvasData>)
{ {
// TODO: document paint definitions. // TODO: document paint definitions.
self.invoke_a_paint_callback(name, size, properties, sender); self.invoke_a_paint_callback(name, size_in_px, device_pixel_ratio, properties, sender);
} }
/// https://drafts.css-houdini.org/css-paint-api/#invoke-a-paint-callback /// https://drafts.css-houdini.org/css-paint-api/#invoke-a-paint-callback
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn invoke_a_paint_callback(&self, fn invoke_a_paint_callback(&self,
name: Atom, name: Atom,
size: Size2D<Au>, size_in_px: TypedSize2D<f32, CSSPixel>,
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
properties: &StylePropertyMapReadOnly, properties: &StylePropertyMapReadOnly,
sender: IpcSender<CanvasData>) sender: IpcSender<CanvasData>)
{ {
let width = size.width.to_px().abs() as u32; let size_in_dpx = size_in_px * device_pixel_ratio;
let height = size.height.to_px().abs() as u32; let size_in_dpx = TypedSize2D::new(size_in_dpx.width.abs() as u32, size_in_dpx.height.abs() as u32);
debug!("Invoking a paint callback {}({},{}).", name, width, height); debug!("Invoking a paint callback {}({},{}) at {}.",
name, size_in_px.width, size_in_px.height, device_pixel_ratio);
let cx = self.worklet_global.get_cx(); let cx = self.worklet_global.get_cx();
let _ac = JSAutoCompartment::new(cx, self.worklet_global.reflector().get_jsobject().get()); let _ac = JSAutoCompartment::new(cx, self.worklet_global.reflector().get_jsobject().get());
@ -135,13 +140,13 @@ impl PaintWorkletGlobalScope {
None => { None => {
// Step 2.2. // Step 2.2.
warn!("Drawing un-registered paint definition {}.", name); warn!("Drawing un-registered paint definition {}.", name);
return self.send_invalid_image(size, sender); return self.send_invalid_image(size_in_dpx, sender);
} }
Some(definition) => { Some(definition) => {
// Step 5.1 // Step 5.1
if !definition.constructor_valid_flag.get() { if !definition.constructor_valid_flag.get() {
debug!("Drawing invalid paint definition {}.", name); debug!("Drawing invalid paint definition {}.", name);
return self.send_invalid_image(size, sender); return self.send_invalid_image(size_in_dpx, sender);
} }
class_constructor.set(definition.class_constructor.get()); class_constructor.set(definition.class_constructor.get());
paint_function.set(definition.paint_function.get()); paint_function.set(definition.paint_function.get());
@ -169,7 +174,7 @@ impl PaintWorkletGlobalScope {
self.paint_definitions.borrow_mut().get_mut(&name) self.paint_definitions.borrow_mut().get_mut(&name)
.expect("Vanishing paint definition.") .expect("Vanishing paint definition.")
.constructor_valid_flag.set(false); .constructor_valid_flag.set(false);
return self.send_invalid_image(size, sender); return self.send_invalid_image(size_in_dpx, sender);
} }
// Step 5.4 // Step 5.4
entry.insert(Box::new(Heap::default())).set(paint_instance.get()); entry.insert(Box::new(Heap::default())).set(paint_instance.get());
@ -180,10 +185,10 @@ impl PaintWorkletGlobalScope {
// Step 8 // Step 8
// TODO: the spec requires creating a new paint rendering context each time, // TODO: the spec requires creating a new paint rendering context each time,
// this code recycles the same one. // this code recycles the same one.
rendering_context.set_bitmap_dimensions(size); rendering_context.set_bitmap_dimensions(size_in_px, device_pixel_ratio);
// Step 9 // Step 9
let paint_size = PaintSize::new(self, size); let paint_size = PaintSize::new(self, size_in_px);
// TODO: Step 10 // TODO: Step 10
// Steps 11-12 // Steps 11-12
@ -202,17 +207,19 @@ impl PaintWorkletGlobalScope {
if unsafe { JS_IsExceptionPending(cx) } { if unsafe { JS_IsExceptionPending(cx) } {
debug!("Paint function threw an exception {}.", name); debug!("Paint function threw an exception {}.", name);
unsafe { JS_ClearPendingException(cx); } unsafe { JS_ClearPendingException(cx); }
return self.send_invalid_image(size, sender); return self.send_invalid_image(size_in_dpx, sender);
} }
rendering_context.send_data(sender); rendering_context.send_data(sender);
} }
// https://drafts.csswg.org/css-images-4/#invalid-image fn send_invalid_image(&self,
fn send_invalid_image(&self, size: Size2D<Au>, sender: IpcSender<CanvasData>) { size: TypedSize2D<u32, DevicePixel>,
sender: IpcSender<CanvasData>)
{
debug!("Sending an invalid image."); debug!("Sending an invalid image.");
let width = size.width.to_px().abs() as u32; let width = size.width as u32;
let height = size.height.to_px().abs() as u32; let height = size.height as u32;
let len = (width as usize) * (height as usize) * 4; let len = (width as usize) * (height as usize) * 4;
let pixel = [0x00, 0x00, 0x00, 0x00]; let pixel = [0x00, 0x00, 0x00, 0x00];
let bytes: Vec<u8> = pixel.iter().cloned().cycle().take(len).collect(); let bytes: Vec<u8> = pixel.iter().cloned().cycle().take(len).collect();
@ -235,12 +242,13 @@ impl PaintWorkletGlobalScope {
struct WorkletPainter(Atom, Mutex<WorkletExecutor>); struct WorkletPainter(Atom, Mutex<WorkletExecutor>);
impl Painter for WorkletPainter { impl Painter for WorkletPainter {
fn draw_a_paint_image(&self, fn draw_a_paint_image(&self,
size: Size2D<Au>, size: TypedSize2D<f32, CSSPixel>,
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
properties: Vec<(Atom, String)>, properties: Vec<(Atom, String)>,
sender: IpcSender<CanvasData>) sender: IpcSender<CanvasData>)
{ {
let name = self.0.clone(); let name = self.0.clone();
let task = PaintWorkletTask::DrawAPaintImage(name, size, properties, sender); let task = PaintWorkletTask::DrawAPaintImage(name, size, device_pixel_ratio, properties, sender);
self.1.lock().expect("Locking a painter.") self.1.lock().expect("Locking a painter.")
.schedule_a_worklet_task(WorkletTask::Paint(task)); .schedule_a_worklet_task(WorkletTask::Paint(task));
} }
@ -334,7 +342,11 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope {
/// Tasks which can be peformed by a paint worklet /// Tasks which can be peformed by a paint worklet
pub enum PaintWorkletTask { pub enum PaintWorkletTask {
DrawAPaintImage(Atom, Size2D<Au>, Vec<(Atom, String)>, IpcSender<CanvasData>) DrawAPaintImage(Atom,
TypedSize2D<f32, CSSPixel>,
ScaleFactor<f32, CSSPixel, DevicePixel>,
Vec<(Atom, String)>,
IpcSender<CanvasData>)
} }
/// A paint definition /// A paint definition

View file

@ -10,7 +10,6 @@ name = "script_traits"
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
app_units = "0.5"
bluetooth_traits = {path = "../bluetooth_traits"} bluetooth_traits = {path = "../bluetooth_traits"}
canvas_traits = {path = "../canvas_traits"} canvas_traits = {path = "../canvas_traits"}
cookie = "0.6" cookie = "0.6"

View file

@ -9,7 +9,6 @@
#![deny(missing_docs)] #![deny(missing_docs)]
#![deny(unsafe_code)] #![deny(unsafe_code)]
extern crate app_units;
extern crate bluetooth_traits; extern crate bluetooth_traits;
extern crate canvas_traits; extern crate canvas_traits;
extern crate cookie as cookie_rs; extern crate cookie as cookie_rs;
@ -39,7 +38,6 @@ extern crate webvr_traits;
mod script_msg; mod script_msg;
pub mod webdriver_msg; pub mod webdriver_msg;
use app_units::Au;
use bluetooth_traits::BluetoothRequest; use bluetooth_traits::BluetoothRequest;
use canvas_traits::CanvasData; use canvas_traits::CanvasData;
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId}; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
@ -68,6 +66,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender, RecvTimeoutError}; use std::sync::mpsc::{Receiver, Sender, RecvTimeoutError};
use style_traits::CSSPixel; use style_traits::CSSPixel;
use style_traits::DevicePixel;
use webdriver_msg::{LoadStatus, WebDriverScriptCommand}; use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
use webrender_api::ClipId; use webrender_api::ClipId;
use webvr_traits::{WebVREvent, WebVRMsg}; use webvr_traits::{WebVREvent, WebVRMsg};
@ -687,12 +686,6 @@ pub struct ScrollState {
pub scroll_offset: Vector2D<f32>, pub scroll_offset: Vector2D<f32>,
} }
/// One hardware pixel.
///
/// This unit corresponds to the smallest addressable element of the display hardware.
#[derive(Copy, Clone, Debug)]
pub enum DevicePixel {}
/// Data about the window size. /// Data about the window size.
#[derive(Copy, Clone, Deserialize, Serialize, HeapSizeOf)] #[derive(Copy, Clone, Deserialize, Serialize, HeapSizeOf)]
pub struct WindowSizeData { pub struct WindowSizeData {
@ -828,7 +821,8 @@ impl From<RecvTimeoutError> for PaintWorkletError {
pub trait Painter: Sync + Send { pub trait Painter: Sync + Send {
/// https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image /// https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image
fn draw_a_paint_image(&self, fn draw_a_paint_image(&self,
concrete_object_size: Size2D<Au>, size: TypedSize2D<f32, CSSPixel>,
zoom: ScaleFactor<f32, CSSPixel, DevicePixel>,
properties: Vec<(Atom, String)>, properties: Vec<(Atom, String)>,
sender: IpcSender<CanvasData>); sender: IpcSender<CanvasData>);
} }

View file

@ -11,6 +11,7 @@ use bloom::StyleBloom;
use cache::LRUCache; use cache::LRUCache;
use data::{EagerPseudoStyles, ElementData}; use data::{EagerPseudoStyles, ElementData};
use dom::{OpaqueNode, TNode, TElement, SendElement}; use dom::{OpaqueNode, TNode, TElement, SendElement};
use euclid::ScaleFactor;
use euclid::Size2D; use euclid::Size2D;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use font_metrics::FontMetricsProvider; use font_metrics::FontMetricsProvider;
@ -27,6 +28,8 @@ use std::fmt;
use std::ops; use std::ops;
#[cfg(feature = "servo")] use std::sync::Mutex; #[cfg(feature = "servo")] use std::sync::Mutex;
#[cfg(feature = "servo")] use std::sync::mpsc::Sender; #[cfg(feature = "servo")] use std::sync::mpsc::Sender;
use style_traits::CSSPixel;
use style_traits::DevicePixel;
use stylist::Stylist; use stylist::Stylist;
use thread_state; use thread_state;
use time; use time;
@ -152,6 +155,11 @@ impl<'a> SharedStyleContext<'a> {
pub fn viewport_size(&self) -> Size2D<Au> { pub fn viewport_size(&self) -> Size2D<Au> {
self.stylist.device().au_viewport_size() self.stylist.device().au_viewport_size()
} }
/// The device pixel ratio
pub fn device_pixel_ratio(&self) -> ScaleFactor<f32, CSSPixel, DevicePixel> {
self.stylist.device().device_pixel_ratio()
}
} }
/// The structure holds various intermediate inputs that are eventually used by /// The structure holds various intermediate inputs that are eventually used by

View file

@ -4,9 +4,11 @@
//! Gecko's media-query device and expression representation. //! Gecko's media-query device and expression representation.
use app_units::AU_PER_PX;
use app_units::Au; use app_units::Au;
use context::QuirksMode; use context::QuirksMode;
use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError}; use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError};
use euclid::ScaleFactor;
use euclid::Size2D; use euclid::Size2D;
use font_metrics::get_metrics_provider_for_product; use font_metrics::get_metrics_provider_for_product;
use gecko::values::convert_nscolor_to_rgba; use gecko::values::convert_nscolor_to_rgba;
@ -25,6 +27,7 @@ use std::fmt::{self, Write};
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
use str::starts_with_ignore_ascii_case; use str::starts_with_ignore_ascii_case;
use string_cache::Atom; use string_cache::Atom;
use style_traits::{CSSPixel, DevicePixel};
use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::{ToCss, ParseError, StyleParseError};
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use values::{CSSFloat, specified}; use values::{CSSFloat, specified};
@ -153,6 +156,15 @@ impl Device {
}) })
} }
/// Returns the device pixel ratio.
pub fn device_pixel_ratio(&self) -> ScaleFactor<f32, CSSPixel, DevicePixel> {
let override_dppx = self.pres_context().mOverrideDPPX;
if override_dppx > 0.0 { return ScaleFactor::new(override_dppx); }
let au_per_dpx = self.pres_context().mCurAppUnitsPerDevPixel as f32;
let au_per_px = AU_PER_PX as f32;
ScaleFactor::new(au_per_px / au_per_dpx)
}
/// Returns whether document colors are enabled. /// Returns whether document colors are enabled.
pub fn use_document_colors(&self) -> bool { pub fn use_document_colors(&self) -> bool {
self.pres_context().mUseDocumentColors() != 0 self.pres_context().mUseDocumentColors() != 0

View file

@ -7,7 +7,7 @@
use app_units::Au; use app_units::Au;
use context::QuirksMode; use context::QuirksMode;
use cssparser::{Parser, RGBA}; use cssparser::{Parser, RGBA};
use euclid::{Size2D, TypedSize2D}; use euclid::{ScaleFactor, Size2D, TypedSize2D};
use font_metrics::ServoMetricsProvider; use font_metrics::ServoMetricsProvider;
use media_queries::MediaType; use media_queries::MediaType;
use parser::ParserContext; use parser::ParserContext;
@ -16,7 +16,7 @@ use properties::longhands::font_size;
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use std::fmt; use std::fmt;
use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
use style_traits::{CSSPixel, ToCss, ParseError}; use style_traits::{CSSPixel, DevicePixel, ToCss, ParseError};
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use values::computed::{self, ToComputedValue}; use values::computed::{self, ToComputedValue};
use values::specified; use values::specified;
@ -31,6 +31,8 @@ pub struct Device {
media_type: MediaType, media_type: MediaType,
/// The current viewport size, in CSS pixels. /// The current viewport size, in CSS pixels.
viewport_size: TypedSize2D<f32, CSSPixel>, viewport_size: TypedSize2D<f32, CSSPixel>,
/// The current device pixel ratio, from CSS pixels to device pixels.
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
/// The font size of the root element /// The font size of the root element
/// This is set when computing the style of the root /// This is set when computing the style of the root
@ -51,11 +53,13 @@ pub struct Device {
impl Device { impl Device {
/// Trivially construct a new `Device`. /// Trivially construct a new `Device`.
pub fn new(media_type: MediaType, pub fn new(media_type: MediaType,
viewport_size: TypedSize2D<f32, CSSPixel>) viewport_size: TypedSize2D<f32, CSSPixel>,
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>)
-> Device { -> Device {
Device { Device {
media_type: media_type, media_type: media_type,
viewport_size: viewport_size, viewport_size: viewport_size,
device_pixel_ratio: device_pixel_ratio,
root_font_size: AtomicIsize::new(font_size::get_initial_value().0 as isize), // FIXME(bz): Seems dubious? root_font_size: AtomicIsize::new(font_size::get_initial_value().0 as isize), // FIXME(bz): Seems dubious?
used_root_font_size: AtomicBool::new(false), used_root_font_size: AtomicBool::new(false),
} }
@ -99,6 +103,11 @@ impl Device {
self.viewport_size self.viewport_size
} }
/// Returns the device pixel ratio.
pub fn device_pixel_ratio(&self) -> ScaleFactor<f32, CSSPixel, DevicePixel> {
self.device_pixel_ratio
}
/// Take into account a viewport rule taken from the stylesheets. /// Take into account a viewport rule taken from the stylesheets.
pub fn account_for_viewport_rule(&mut self, constraints: &ViewportConstraints) { pub fn account_for_viewport_rule(&mut self, constraints: &ViewportConstraints) {
self.viewport_size = constraints.size; self.viewport_size = constraints.size;

View file

@ -59,6 +59,12 @@ impl PinchZoomFactor {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum CSSPixel {} pub enum CSSPixel {}
/// One hardware pixel.
///
/// This unit corresponds to the smallest addressable element of the display hardware.
#[derive(Copy, Clone, Debug)]
pub enum DevicePixel {}
// In summary, the hierarchy of pixel units and the factors to convert from one to the next: // In summary, the hierarchy of pixel units and the factors to convert from one to the next:
// //
// DevicePixel // DevicePixel

View file

@ -23,7 +23,7 @@ use euclid::{Point2D, TypedPoint2D, TypedRect, Size2D, TypedSize2D, ScaleFactor}
use gleam::gl; use gleam::gl;
use msg::constellation_msg::{Key, KeyModifiers}; use msg::constellation_msg::{Key, KeyModifiers};
use net_traits::net_error_list::NetError; use net_traits::net_error_list::NetError;
use script_traits::{DevicePixel, LoadData}; use script_traits::LoadData;
use servo::ipc_channel::ipc::IpcSender; use servo::ipc_channel::ipc::IpcSender;
use servo_geometry::DeviceIndependentPixel; use servo_geometry::DeviceIndependentPixel;
use std::cell::RefCell; use std::cell::RefCell;
@ -34,6 +34,7 @@ use std::rc::Rc;
use std::sync::mpsc::{Sender, channel}; use std::sync::mpsc::{Sender, channel};
use servo_url::ServoUrl; use servo_url::ServoUrl;
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use style_traits::DevicePixel;
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
extern crate x11; extern crate x11;
#[cfg(target_os="linux")] #[cfg(target_os="linux")]

View file

@ -24,7 +24,7 @@ use msg::constellation_msg::{ALT, CONTROL, KeyState, NONE, SHIFT, SUPER, Travers
use net_traits::net_error_list::NetError; use net_traits::net_error_list::NetError;
#[cfg(any(target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "linux", target_os = "macos"))]
use osmesa_sys; use osmesa_sys;
use script_traits::{DevicePixel, LoadData, TouchEventType, TouchpadPressurePhase}; use script_traits::{LoadData, TouchEventType, TouchpadPressurePhase};
use servo::ipc_channel::ipc::IpcSender; use servo::ipc_channel::ipc::IpcSender;
use servo_config::opts; use servo_config::opts;
use servo_config::prefs::PREFS; use servo_config::prefs::PREFS;
@ -39,6 +39,7 @@ use std::mem;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use style_traits::DevicePixel;
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use user32; use user32;

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::{Parser, SourcePosition}; use cssparser::{Parser, SourcePosition};
use euclid::ScaleFactor;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use servo_arc::Arc; use servo_arc::Arc;
use servo_url::ServoUrl; use servo_url::ServoUrl;
@ -39,7 +40,7 @@ fn test_media_rule<F>(css: &str, callback: F)
let stylesheet = Stylesheet::from_str( let stylesheet = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock, css, url, Origin::Author, media_list, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0u64); None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0u64);
let dummy = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0)); let dummy = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0));
let mut rule_count = 0; let mut rule_count = 0;
let guard = stylesheet.shared_lock.read(); let guard = stylesheet.shared_lock.read();
for rule in stylesheet.iter_rules::<AllRules>(&dummy, &guard) { for rule in stylesheet.iter_rules::<AllRules>(&dummy, &guard) {
@ -342,7 +343,7 @@ fn test_mq_malformed_expressions() {
#[test] #[test]
fn test_matching_simple() { fn test_matching_simple() {
let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0)); let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0));
media_query_test(&device, "@media not all { a { color: red; } }", 0); media_query_test(&device, "@media not all { a { color: red; } }", 0);
media_query_test(&device, "@media not screen { a { color: red; } }", 0); media_query_test(&device, "@media not screen { a { color: red; } }", 0);
@ -358,7 +359,7 @@ fn test_matching_simple() {
#[test] #[test]
fn test_matching_width() { fn test_matching_width() {
let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0)); let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0));
media_query_test(&device, "@media { a { color: red; } }", 1); media_query_test(&device, "@media { a { color: red; } }", 1);
@ -399,7 +400,7 @@ fn test_matching_width() {
#[test] #[test]
fn test_matching_invalid() { fn test_matching_invalid() {
let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0)); let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0));
media_query_test(&device, "@media fridge { a { color: red; } }", 0); media_query_test(&device, "@media fridge { a { color: red; } }", 0);
media_query_test(&device, "@media screen and (height: 100px) { a { color: red; } }", 0); media_query_test(&device, "@media screen and (height: 100px) { a { color: red; } }", 0);

View file

@ -5,6 +5,7 @@
//! Tests for parsing and serialization of values/properties //! Tests for parsing and serialization of values/properties
use cssparser::{Parser, ParserInput}; use cssparser::{Parser, ParserInput};
use euclid::ScaleFactor;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use media_queries::CSSErrorReporterTest; use media_queries::CSSErrorReporterTest;
use style::context::QuirksMode; use style::context::QuirksMode;
@ -50,7 +51,7 @@ fn assert_computed_serialization<C, F, T>(f: F, input: &'static str, output: &st
{ {
let viewport_size = TypedSize2D::new(0., 0.); let viewport_size = TypedSize2D::new(0., 0.);
let initial_style = ComputedValues::initial_values(); let initial_style = ComputedValues::initial_values();
let device = Device::new(MediaType::Screen, viewport_size); let device = Device::new(MediaType::Screen, viewport_size, ScaleFactor::new(1.0));
let context = Context { let context = Context {
is_root_element: true, is_root_element: true,

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::SourceLocation; use cssparser::SourceLocation;
use euclid::ScaleFactor;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use html5ever::LocalName; use html5ever::LocalName;
use selectors::parser::{AncestorHashes, Selector}; use selectors::parser::{AncestorHashes, Selector};
@ -235,7 +236,7 @@ fn test_get_universal_rules() {
} }
fn mock_stylist() -> Stylist { fn mock_stylist() -> Stylist {
let device = Device::new(MediaType::Screen, TypedSize2D::new(0f32, 0f32)); let device = Device::new(MediaType::Screen, TypedSize2D::new(0f32, 0f32), ScaleFactor::new(1.0));
Stylist::new(device, QuirksMode::NoQuirks) Stylist::new(device, QuirksMode::NoQuirks)
} }

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::{Parser, ParserInput}; use cssparser::{Parser, ParserInput};
use euclid::ScaleFactor;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use media_queries::CSSErrorReporterTest; use media_queries::CSSErrorReporterTest;
use servo_arc::Arc; use servo_arc::Arc;
@ -96,7 +97,7 @@ macro_rules! viewport_length {
#[test] #[test]
fn empty_viewport_rule() { fn empty_viewport_rule() {
let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.)); let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0));
test_viewport_rule("@viewport {}", &device, |declarations, css| { test_viewport_rule("@viewport {}", &device, |declarations, css| {
println!("{}", css); println!("{}", css);
@ -119,7 +120,7 @@ macro_rules! assert_decl_eq {
#[test] #[test]
fn simple_viewport_rules() { fn simple_viewport_rules() {
let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.)); let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0));
test_viewport_rule("@viewport { width: auto; height: auto;\ test_viewport_rule("@viewport { width: auto; height: auto;\
zoom: auto; min-zoom: 0; max-zoom: 200%;\ zoom: auto; min-zoom: 0; max-zoom: 200%;\
@ -191,7 +192,7 @@ fn simple_meta_viewport_contents() {
#[test] #[test]
fn cascading_within_viewport_rule() { fn cascading_within_viewport_rule() {
let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.)); let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0));
// normal order of appearance // normal order of appearance
test_viewport_rule("@viewport { min-width: 200px; min-width: auto; }", test_viewport_rule("@viewport { min-width: 200px; min-width: auto; }",
@ -257,7 +258,7 @@ fn cascading_within_viewport_rule() {
#[test] #[test]
fn multiple_stylesheets_cascading() { fn multiple_stylesheets_cascading() {
PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true)); PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true));
let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.)); let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0));
let error_reporter = CSSErrorReporterTest; let error_reporter = CSSErrorReporterTest;
let shared_lock = SharedRwLock::new(); let shared_lock = SharedRwLock::new();
let stylesheets = vec![ let stylesheets = vec![
@ -313,7 +314,7 @@ fn constrain_viewport() {
} }
let initial_viewport = TypedSize2D::new(800., 600.); let initial_viewport = TypedSize2D::new(800., 600.);
let device = Device::new(MediaType::Screen, initial_viewport); let device = Device::new(MediaType::Screen, initial_viewport, ScaleFactor::new(1.0));
let mut input = ParserInput::new(""); let mut input = ParserInput::new("");
assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks), None); assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks), None);
@ -362,7 +363,7 @@ fn constrain_viewport() {
})); }));
let initial_viewport = TypedSize2D::new(200., 150.); let initial_viewport = TypedSize2D::new(200., 150.);
let device = Device::new(MediaType::Screen, initial_viewport); let device = Device::new(MediaType::Screen, initial_viewport, ScaleFactor::new(1.0));
let mut input = ParserInput::new("width: 320px auto"); let mut input = ParserInput::new("width: 320px auto");
assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks), assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks),
Some(ViewportConstraints { Some(ViewportConstraints {