style: Make media queries and viewport units in print be evaluated against the default page size minus margins.

For that, move the default page margin computation to nsPresContext.

See https://github.com/w3c/csswg-drafts/issues/5437 as to why doing this
and other alternatives.

Differential Revision: https://phabricator.services.mozilla.com/D87311
This commit is contained in:
Emilio Cobos Álvarez 2020-08-19 10:32:16 +00:00
parent 9fd3d9a5e9
commit c200b67395
2 changed files with 27 additions and 18 deletions

View file

@ -17,18 +17,6 @@ use crate::Atom;
use app_units::Au;
use euclid::default::Size2D;
fn viewport_size(device: &Device) -> Size2D<Au> {
if let Some(pc) = device.pres_context() {
if pc.mIsRootPaginatedDocument() != 0 {
// We want the page size, including unprintable areas and margins.
// FIXME(emilio, bug 1414600): Not quite!
let area = &pc.mPageSize;
return Size2D::new(Au(area.width), Au(area.height));
}
}
device.au_viewport_size()
}
fn device_size(device: &Device) -> Size2D<Au> {
let mut width = 0;
let mut height = 0;
@ -47,7 +35,7 @@ fn eval_width(
RangeOrOperator::evaluate(
range_or_operator,
value.map(Au::from),
viewport_size(device).width,
device.au_viewport_size().width,
)
}
@ -73,7 +61,7 @@ fn eval_height(
RangeOrOperator::evaluate(
range_or_operator,
value.map(Au::from),
viewport_size(device).height,
device.au_viewport_size().height,
)
}
@ -115,7 +103,7 @@ fn eval_aspect_ratio(
query_value: Option<Ratio>,
range_or_operator: Option<RangeOrOperator>,
) -> bool {
eval_aspect_ratio_for(device, query_value, range_or_operator, viewport_size)
eval_aspect_ratio_for(device, query_value, range_or_operator, Device::au_viewport_size)
}
/// https://drafts.csswg.org/mediaqueries-4/#device-aspect-ratio
@ -168,7 +156,7 @@ where
/// https://drafts.csswg.org/mediaqueries-4/#orientation
fn eval_orientation(device: &Device, value: Option<Orientation>) -> bool {
eval_orientation_for(device, value, viewport_size)
eval_orientation_for(device, value, Device::au_viewport_size)
}
/// FIXME: There's no spec for `-moz-device-orientation`.

View file

@ -19,7 +19,7 @@ use cssparser::RGBA;
use euclid::default::Size2D;
use euclid::{Scale, SideOffsets2D};
use servo_arc::Arc;
use std::fmt;
use std::{cmp, fmt};
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
use style_traits::viewport::ViewportConstraints;
use style_traits::{CSSPixel, DevicePixel};
@ -223,12 +223,29 @@ impl Device {
MediaType(CustomIdent(unsafe { Atom::from_raw(medium_to_use) }))
}
// It may make sense to account for @page rule margins here somehow, however
// it's not clear how that'd work, see:
// https://github.com/w3c/csswg-drafts/issues/5437
fn page_size_minus_default_margin(&self, pc: &structs::nsPresContext) -> Size2D<Au> {
debug_assert!(pc.mIsRootPaginatedDocument() != 0);
let area = &pc.mPageSize;
let margin = &pc.mDefaultPageMargin;
let width = area.width - margin.left - margin.right;
let height = area.height - margin.top - margin.bottom;
Size2D::new(Au(cmp::max(width, 0)), Au(cmp::max(height, 0)))
}
/// Returns the current viewport size in app units.
pub fn au_viewport_size(&self) -> Size2D<Au> {
let pc = match self.pres_context() {
Some(pc) => pc,
None => return Size2D::new(Au(0), Au(0)),
};
if pc.mIsRootPaginatedDocument() != 0 {
return self.page_size_minus_default_margin(pc);
}
let area = &pc.mVisibleArea;
Size2D::new(Au(area.width), Au(area.height))
}
@ -237,11 +254,15 @@ impl Device {
/// used for viewport unit resolution.
pub fn au_viewport_size_for_viewport_unit_resolution(&self) -> Size2D<Au> {
self.used_viewport_size.store(true, Ordering::Relaxed);
let pc = match self.pres_context() {
Some(pc) => pc,
None => return Size2D::new(Au(0), Au(0)),
};
if pc.mIsRootPaginatedDocument() != 0 {
return self.page_size_minus_default_margin(pc)
}
let size = &pc.mSizeForViewportUnits;
Size2D::new(Au(size.width), Au(size.height))
}