Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gfx: Simplify complex clipping regions as we construct them. #10331

Merged
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -32,7 +32,7 @@ use range::Range;
use serde::de::{self, Deserialize, Deserializer, MapVisitor, Visitor};
use serde::ser::impls::MapIteratorVisitor;
use serde::ser::{Serialize, Serializer};
use std::cmp::Ordering;
use std::cmp::{self, Ordering};
use std::collections::HashMap;
use std::fmt;
use std::hash::{BuildHasherDefault, Hash};
@@ -887,6 +887,27 @@ impl ClippingRegion {
/// Intersects this clipping region with the given rounded rectangle.
#[inline]
pub fn intersect_with_rounded_rect(&mut self, rect: &Rect<Au>, radii: &BorderRadii<Au>) {
let new_complex_region = ComplexClippingRegion {
rect: *rect,
radii: *radii,
};

// FIXME(pcwalton): This is O(n²) worst case for disjoint clipping regions. Is that OK?
// They're slow anyway…
//
// Possibly relevant if we want to do better:
//
// http://www.inrg.csie.ntu.edu.tw/algorithm2014/presentation/D&C%20Lee-84.pdf
for existing_complex_region in &mut self.complex {
if existing_complex_region.completely_encloses(&new_complex_region) {
*existing_complex_region = new_complex_region;
return
}
if new_complex_region.completely_encloses(existing_complex_region) {
return
}
}

self.complex.push(ComplexClippingRegion {
rect: *rect,
radii: *radii,
@@ -908,6 +929,21 @@ impl ClippingRegion {
}
}

impl ComplexClippingRegion {
// TODO(pcwalton): This could be more aggressive by considering points that touch the inside of
// the border radius ellipse.
fn completely_encloses(&self, other: &ComplexClippingRegion) -> bool {
let left = cmp::max(self.radii.top_left.width, self.radii.bottom_left.width);
let top = cmp::max(self.radii.top_left.height, self.radii.top_right.height);
let right = cmp::max(self.radii.top_right.width, self.radii.bottom_right.width);
let bottom = cmp::max(self.radii.bottom_left.height, self.radii.bottom_right.height);
let interior = Rect::new(Point2D::new(self.rect.origin.x + left, self.rect.origin.y + top),
Size2D::new(self.rect.size.width - left - right,
self.rect.size.height - top - bottom));
interior.origin.x <= other.rect.origin.x && interior.origin.y <= other.rect.origin.y &&
interior.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y()
}
}

/// Metadata attached to each display item. This is useful for performing auxiliary threads with
/// the display list involving hit testing: finding the originating DOM node and determining the
@@ -836,6 +836,18 @@
"url": "/_mozilla/css/border_radius_elliptical_a.html"
}
],
"css/border_radius_in_border_radius_a.html": [
{
"path": "css/border_radius_in_border_radius_a.html",
"references": [
[
"/_mozilla/css/border_radius_in_border_radius_ref.html",
"=="
]
],
"url": "/_mozilla/css/border_radius_in_border_radius_a.html"
}
],
"css/border_radius_overlapping_a.html": [
{
"path": "css/border_radius_overlapping_a.html",
@@ -7246,6 +7258,18 @@
"url": "/_mozilla/css/border_radius_elliptical_a.html"
}
],
"css/border_radius_in_border_radius_a.html": [
{
"path": "css/border_radius_in_border_radius_a.html",
"references": [
[
"/_mozilla/css/border_radius_in_border_radius_ref.html",
"=="
]
],
"url": "/_mozilla/css/border_radius_in_border_radius_a.html"
}
],
"css/border_radius_overlapping_a.html": [
{
"path": "css/border_radius_overlapping_a.html",
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="match" href="border_radius_in_border_radius_ref.html">
<style>
html, body {
margin: 0;
padding: 0;
}

.green {
overflow: hidden;
border-radius: 50px;
background: green;
padding: 50px;
width: 100px;
}

.red {
background: red;
border-radius: 50%;
width: 100px;
height: 100px
}
</style>
<div class="green"><div class="red"></div></div>

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
html, body {
margin: 0;
padding: 0;
}

.green {
position: absolute;
border-radius: 50px;
background: green;
padding: 50px;
width: 100px;
height: 100px;
}

.red {
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
background: red;
border-radius: 50%;
}
</style>
<div class="green"></div><div class="red"></div>

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.