aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/gfx/display_list/mod.rs43
-rw-r--r--components/gfx/paint_context.rs20
-rw-r--r--tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-017.htm.ini4
-rw-r--r--tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-018.htm.ini4
-rw-r--r--tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini4
5 files changed, 40 insertions, 35 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 0073b1b0a69..c7143457db9 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -18,7 +18,7 @@ use app_units::Au;
use azure::azure::AzFloat;
use azure::azure_hl::Color;
use euclid::approxeq::ApproxEq;
-use euclid::num::Zero;
+use euclid::num::{One, Zero};
use euclid::rect::TypedRect;
use euclid::side_offsets::SideOffsets2D;
use euclid::{Matrix2D, Matrix4D, Point2D, Rect, Size2D};
@@ -457,20 +457,18 @@ impl DisplayList {
let transform = transform.translate(pixel_snapped_origin.x as AzFloat,
pixel_snapped_origin.y as AzFloat,
0.0).mul(&stacking_context.transform);
- let inverse_transform = transform.invert();
-
- // Here we are trying to accumulate any subpixel distances across transformed
- // stacking contexts. This allows us transform stacking context with a
- // pixel-snapped transform, but continue to propagate any subpixels from stacking
- // context origins to children.
- let subpixel_offset = Point2D::new(origin.x.to_f32_px() - pixel_snapped_origin.x,
- origin.y.to_f32_px() - pixel_snapped_origin.y);
- let subpixel_offset = inverse_transform.transform_point(&subpixel_offset) -
- inverse_transform.transform_point(&Point2D::zero());;
- let subpixel_offset = Point2D::new(Au::from_f32_px(subpixel_offset.x),
- Au::from_f32_px(subpixel_offset.y));
-
- (transform, subpixel_offset)
+
+ if transform.is_identity_or_simple_translation() {
+ let pixel_snapped_origin = Point2D::new(Au::from_f32_px(pixel_snapped_origin.x),
+ Au::from_f32_px(pixel_snapped_origin.y));
+ (transform, origin - pixel_snapped_origin)
+ } else {
+ // In the case of a more complicated transformation, don't attempt to
+ // preserve subpixel offsets. This causes problems with reference tests
+ // that do scaling and rotation and it's unclear if we even want to be doing
+ // this.
+ (transform, Point2D::zero())
+ }
}
};
@@ -1462,3 +1460,18 @@ impl WebRenderImageInfo {
/// The type of the scroll offset list. This is only populated if WebRender is in use.
pub type ScrollOffsetMap = HashMap<StackingContextId, Point2D<f32>>;
+
+pub trait SimpleMatrixDetection {
+ fn is_identity_or_simple_translation(&self) -> bool;
+}
+
+impl SimpleMatrixDetection for Matrix4D<f32> {
+ #[inline]
+ fn is_identity_or_simple_translation(&self) -> bool {
+ let (_0, _1) = (Zero::zero(), One::one());
+ self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 &&
+ self.m21 == _0 && self.m22 == _1 && self.m23 == _0 && self.m24 == _0 &&
+ self.m31 == _0 && self.m32 == _0 && self.m33 == _1 && self.m34 == _0 &&
+ self.m44 == _1
+ }
+}
diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs
index 15c4b169ba4..acfa5186fe1 100644
--- a/components/gfx/paint_context.rs
+++ b/components/gfx/paint_context.rs
@@ -122,6 +122,10 @@ struct CornerOrigin {
}
impl<'a> PaintContext<'a> {
+ pub fn to_nearest_azure_rect(&self, rect: &Rect<Au>) -> Rect<AzFloat> {
+ rect.translate(&self.subpixel_offset).to_nearest_azure_rect(self.screen_pixels_per_px())
+ }
+
pub fn screen_pixels_per_px(&self) -> ScaleFactor<PagePx, ScreenPx, f32> {
self.screen_rect.as_f32().size.width / self.page_rect.size.width
}
@@ -132,7 +136,7 @@ impl<'a> PaintContext<'a> {
pub fn draw_solid_color(&self, bounds: &Rect<Au>, color: Color) {
self.draw_target.make_current();
- self.draw_target.fill_rect(&bounds.to_nearest_azure_rect(self.screen_pixels_per_px()),
+ self.draw_target.fill_rect(&self.to_nearest_azure_rect(&bounds),
PatternRef::Color(&ColorPattern::new(color)),
None);
}
@@ -160,7 +164,7 @@ impl<'a> PaintContext<'a> {
}
pub fn draw_push_clip(&self, bounds: &Rect<Au>) {
- let rect = bounds.to_nearest_azure_rect(self.screen_pixels_per_px());
+ let rect = self.to_nearest_azure_rect(bounds);
let path_builder = self.draw_target.create_path_builder();
let left_top = Point2D::new(rect.origin.x, rect.origin.y);
@@ -211,7 +215,7 @@ impl<'a> PaintContext<'a> {
let source_rect = Rect::new(Point2D::new(0.0, 0.0),
Size2D::new(image_info.width as AzFloat,
image_info.height as AzFloat));
- let dest_rect = bounds.to_nearest_azure_rect(scale);
+ let dest_rect = self.to_nearest_azure_rect(bounds);
// TODO(pcwalton): According to CSS-IMAGES-3 § 5.3, nearest-neighbor interpolation is a
// conforming implementation of `crisp-edges`, but it is not the best we could do.
@@ -1127,7 +1131,7 @@ impl<'a> PaintContext<'a> {
radius: &BorderRadii<AzFloat>,
color: Color,
dash_size: DashSize) {
- let rect = bounds.to_nearest_azure_rect(self.screen_pixels_per_px());
+ let rect = self.to_nearest_azure_rect(bounds);
let draw_opts = DrawOptions::new(1.0, CompositionOp::Over, AntialiasMode::None);
let border_width = match direction {
Direction::Top => border.top,
@@ -1195,7 +1199,7 @@ impl<'a> PaintContext<'a> {
border: &SideOffsets2D<f32>,
radius: &BorderRadii<AzFloat>,
color: Color) {
- let rect = bounds.to_nearest_azure_rect(self.screen_pixels_per_px());
+ let rect = self.to_nearest_azure_rect(bounds);
self.draw_border_path(&rect, direction, border, radius, color);
}
@@ -1203,7 +1207,7 @@ impl<'a> PaintContext<'a> {
bounds: &Rect<Au>,
border: &SideOffsets2D<f32>,
shrink_factor: f32) -> Rect<f32> {
- let rect = bounds.to_nearest_azure_rect(self.screen_pixels_per_px());
+ let rect = self.to_nearest_azure_rect(bounds);
let scaled_border = SideOffsets2D::new(shrink_factor * border.top,
shrink_factor * border.right,
shrink_factor * border.bottom,
@@ -1406,7 +1410,7 @@ impl<'a> PaintContext<'a> {
&end_point.to_nearest_azure_point(scale),
stops,
&Matrix2D::identity());
- self.draw_target.fill_rect(&bounds.to_nearest_azure_rect(scale),
+ self.draw_target.fill_rect(&self.to_nearest_azure_rect(&bounds),
PatternRef::LinearGradient(&pattern),
None);
}
@@ -1632,7 +1636,7 @@ impl<'a> PaintContext<'a> {
self.draw_push_clip(&clip_region.main);
for complex_region in &clip_region.complex {
// FIXME(pcwalton): Actually draw a rounded rect.
- self.push_rounded_rect_clip(&complex_region.rect.to_nearest_azure_rect(scale),
+ self.push_rounded_rect_clip(&self.to_nearest_azure_rect(&complex_region.rect),
&complex_region.radii.to_radii_pixels(scale))
}
self.transient_clip = Some(clip_region)
diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-017.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-017.htm.ini
deleted file mode 100644
index 4dc53b8f843..00000000000
--- a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-017.htm.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[transform-input-017.htm]
- type: reftest
- expected: FAIL
- bug: https://github.com/servo/servo/issues/10881
diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-018.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-018.htm.ini
deleted file mode 100644
index 69c5b778d30..00000000000
--- a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-018.htm.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[transform-input-018.htm]
- type: reftest
- expected: FAIL
- bug: https://github.com/servo/servo/issues/10881
diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini
deleted file mode 100644
index 8e2a7b49f90..00000000000
--- a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-input-019.htm.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[transform-input-019.htm]
- type: reftest
- expected:
- if os == "linux": FAIL