Bug 1550582 - Ensure the overlap is filled correctly when opposite border edges overlap. r=gw, a=pascalc
authorJamie Nicol <jnicol@mozilla.com>
Wed, 15 May 2019 10:43:25 +0000
changeset 526552 5f21e6f900c825223c2c076cb7cf7f928074ed05
parent 526551 fa5b6a15761ce4d81f730b756ff595eb91148376
child 526553 499809263177f7886716575b172501aa986a5b91
push id2041
push userjcristau@mozilla.com
push dateThu, 16 May 2019 17:34:45 +0000
treeherdermozilla-release@499809263177 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw, pascalc
bugs1550582, 1496540
milestone67.0
Bug 1550582 - Ensure the overlap is filled correctly when opposite border edges overlap. r=gw, a=pascalc To fix bug 1496540 it was made so that webrender clips border corner segments so that they do not overlap with their opposing edges. However, cases where opposing _edges_ both overlap with eachother (rather than just a corner overlapping with an edge), the corners are clipped too far and a gap is left in the middle. Additionally, no clipping was added to the edge segments. So rather than there be a gap there is an area that is painted twice, which is apparent if the colour is semi-transparent. This fixes these issues by identifying when opposing edges overlap and calculating the midpoint, then clipping the edges and corners to that midpoint instead. Differential Revision: https://phabricator.services.mozilla.com/D30814
gfx/wr/webrender/src/border.rs
--- a/gfx/wr/webrender/src/border.rs
+++ b/gfx/wr/webrender/src/border.rs
@@ -648,16 +648,27 @@ pub fn create_border_segments(
     border_segments: &mut Vec<BorderSegmentInfo>,
     brush_segments: &mut Vec<BrushSegment>,
 ) {
     let rect = LayoutRect::new(
         LayoutPoint::zero(),
         size,
     );
 
+    let overlap = LayoutSize::new(
+        (widths.left + widths.right - size.width).max(0.0),
+        (widths.top + widths.bottom - size.height).max(0.0),
+    );
+    let non_overlapping_widths = LayoutSideOffsets::new(
+        widths.top - overlap.height / 2.0,
+        widths.right - overlap.width / 2.0,
+        widths.bottom - overlap.height / 2.0,
+        widths.left - overlap.width / 2.0,
+    );
+
     let local_size_tl = LayoutSize::new(
         border.radius.top_left.width.max(widths.left),
         border.radius.top_left.height.max(widths.top),
     );
     let local_size_tr = LayoutSize::new(
         border.radius.top_right.width.max(widths.right),
         border.radius.top_right.height.max(widths.top),
     );
@@ -691,70 +702,70 @@ pub fn create_border_segments(
         widths.right,
         rect.size.height - local_size_tr.height - local_size_br.height,
     );
 
     add_edge_segment(
         LayoutRect::from_floats(
             rect.origin.x,
             rect.origin.y + local_size_tl.height + left_edge_info.local_offset,
-            rect.origin.x + widths.left,
+            rect.origin.x + non_overlapping_widths.left,
             rect.origin.y + local_size_tl.height + left_edge_info.local_offset + left_edge_info.local_size,
         ),
         &left_edge_info,
         border.left,
-        widths.left,
+        non_overlapping_widths.left,
         BorderSegment::Left,
         EdgeAaSegmentMask::LEFT | EdgeAaSegmentMask::RIGHT,
         brush_segments,
         border_segments,
         border.do_aa,
     );
     add_edge_segment(
         LayoutRect::from_floats(
             rect.origin.x + local_size_tl.width + top_edge_info.local_offset,
             rect.origin.y,
             rect.origin.x + local_size_tl.width + top_edge_info.local_offset + top_edge_info.local_size,
-            rect.origin.y + widths.top,
+            rect.origin.y + non_overlapping_widths.top,
         ),
         &top_edge_info,
         border.top,
-        widths.top,
+        non_overlapping_widths.top,
         BorderSegment::Top,
         EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::BOTTOM,
         brush_segments,
         border_segments,
         border.do_aa,
     );
     add_edge_segment(
         LayoutRect::from_floats(
-            rect.origin.x + rect.size.width - widths.right,
+            rect.origin.x + rect.size.width - non_overlapping_widths.right,
             rect.origin.y + local_size_tr.height + right_edge_info.local_offset,
             rect.origin.x + rect.size.width,
             rect.origin.y + local_size_tr.height + right_edge_info.local_offset + right_edge_info.local_size,
         ),
         &right_edge_info,
         border.right,
-        widths.right,
+        non_overlapping_widths.right,
         BorderSegment::Right,
         EdgeAaSegmentMask::RIGHT | EdgeAaSegmentMask::LEFT,
         brush_segments,
         border_segments,
         border.do_aa,
     );
     add_edge_segment(
         LayoutRect::from_floats(
             rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset,
-            rect.origin.y + rect.size.height - widths.bottom,
+            rect.origin.y + rect.size.height - non_overlapping_widths.bottom,
             rect.origin.x + local_size_bl.width + bottom_edge_info.local_offset + bottom_edge_info.local_size,
             rect.origin.y + rect.size.height,
         ),
         &bottom_edge_info,
         border.bottom,
-        widths.bottom,
+        non_overlapping_widths.bottom,
         BorderSegment::Bottom,
         EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::TOP,
         brush_segments,
         border_segments,
         border.do_aa,
     );
 
     add_corner_segment(
@@ -762,18 +773,18 @@ pub fn create_border_segments(
             rect.origin.x,
             rect.origin.y,
             rect.origin.x + local_size_tl.width,
             rect.origin.y + local_size_tl.height,
         ),
         LayoutRect::from_floats(
             rect.origin.x,
             rect.origin.y,
-            rect.max_x() - widths.right,
-            rect.max_y() - widths.bottom
+            rect.max_x() - non_overlapping_widths.right,
+            rect.max_y() - non_overlapping_widths.bottom
         ),
         border.left,
         border.top,
         LayoutSize::new(widths.left, widths.top),
         border.radius.top_left,
         BorderSegment::TopLeft,
         EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::LEFT,
         rect.top_right(),
@@ -787,20 +798,20 @@ pub fn create_border_segments(
     add_corner_segment(
         LayoutRect::from_floats(
             rect.origin.x + rect.size.width - local_size_tr.width,
             rect.origin.y,
             rect.origin.x + rect.size.width,
             rect.origin.y + local_size_tr.height,
         ),
         LayoutRect::from_floats(
-            rect.origin.x + widths.left,
+            rect.origin.x + non_overlapping_widths.left,
             rect.origin.y,
             rect.max_x(),
-            rect.max_y() - widths.bottom,
+            rect.max_y() - non_overlapping_widths.bottom,
         ),
         border.top,
         border.right,
         LayoutSize::new(widths.right, widths.top),
         border.radius.top_right,
         BorderSegment::TopRight,
         EdgeAaSegmentMask::TOP | EdgeAaSegmentMask::RIGHT,
         rect.origin,
@@ -814,18 +825,18 @@ pub fn create_border_segments(
     add_corner_segment(
         LayoutRect::from_floats(
             rect.origin.x + rect.size.width - local_size_br.width,
             rect.origin.y + rect.size.height - local_size_br.height,
             rect.origin.x + rect.size.width,
             rect.origin.y + rect.size.height,
         ),
         LayoutRect::from_floats(
-            rect.origin.x + widths.left,
-            rect.origin.y + widths.top,
+            rect.origin.x + non_overlapping_widths.left,
+            rect.origin.y + non_overlapping_widths.top,
             rect.max_x(),
             rect.max_y(),
         ),
         border.right,
         border.bottom,
         LayoutSize::new(widths.right, widths.bottom),
         border.radius.bottom_right,
         BorderSegment::BottomRight,
@@ -842,18 +853,18 @@ pub fn create_border_segments(
         LayoutRect::from_floats(
             rect.origin.x,
             rect.origin.y + rect.size.height - local_size_bl.height,
             rect.origin.x + local_size_bl.width,
             rect.origin.y + rect.size.height,
         ),
         LayoutRect::from_floats(
             rect.origin.x,
-            rect.origin.y + widths.top,
-            rect.max_x() - widths.right,
+            rect.origin.y + non_overlapping_widths.top,
+            rect.max_x() - non_overlapping_widths.right,
             rect.max_y(),
         ),
         border.bottom,
         border.left,
         LayoutSize::new(widths.left, widths.bottom),
         border.radius.bottom_left,
         BorderSegment::BottomLeft,
         EdgeAaSegmentMask::BOTTOM | EdgeAaSegmentMask::LEFT,