diff --git a/webrender/src/border.rs b/webrender/src/border.rs index a0e627a060..c602dca110 100644 --- a/webrender/src/border.rs +++ b/webrender/src/border.rs @@ -2,7 +2,7 @@ * 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/. */ -use api::{BorderSide, BorderStyle, BorderWidths, ClipAndScrollInfo, ColorF}; +use api::{BorderRadius, BorderSide, BorderStyle, BorderWidths, ClipAndScrollInfo, ColorF}; use api::{LayerPoint, LayerRect}; use api::{LayerPrimitiveInfo, LayerSize, NormalBorder, RepeatMode}; use clip::ClipSource; @@ -227,6 +227,48 @@ impl NormalBorderHelpers for NormalBorder { } } +fn ensure_no_corner_overlap(radius: &mut BorderRadius, info: &LayerPrimitiveInfo) { + let mut ratio = 1.0; + let top_left_radius = &mut radius.top_left; + let top_right_radius = &mut radius.top_right; + let bottom_right_radius = &mut radius.bottom_right; + let bottom_left_radius = &mut radius.bottom_left; + + let sum = top_left_radius.width + bottom_left_radius.width; + if info.rect.size.width < sum { + ratio = f32::min(ratio, info.rect.size.width / sum); + } + + let sum = top_right_radius.width + bottom_right_radius.width; + if info.rect.size.width < sum { + ratio = f32::min(ratio, info.rect.size.width / sum); + } + + let sum = top_left_radius.height + bottom_left_radius.height; + if info.rect.size.height < sum { + ratio = f32::min(ratio, info.rect.size.height / sum); + } + + let sum = top_right_radius.height + bottom_right_radius.height; + if info.rect.size.height < sum { + ratio = f32::min(ratio, info.rect.size.height / sum); + } + + if ratio < 1. { + top_left_radius.width *= ratio; + top_left_radius.height *= ratio; + + top_right_radius.width *= ratio; + top_right_radius.height *= ratio; + + bottom_left_radius.width *= ratio; + bottom_left_radius.height *= ratio; + + bottom_right_radius.width *= ratio; + bottom_right_radius.height *= ratio; + } +} + impl FrameBuilder { fn add_normal_border_primitive( &mut self, @@ -310,6 +352,9 @@ impl FrameBuilder { // out more often on CI (the actual cause is simply too many Servo processes and // threads being run on CI at once). + let mut border = *border; + ensure_no_corner_overlap(&mut border.radius, &info); + let radius = &border.radius; let left = &border.left; let right = &border.right; @@ -478,7 +523,7 @@ impl FrameBuilder { self.add_normal_border_primitive( info, - border, + &border, widths, clip_and_scroll, corner_instances, @@ -880,4 +925,4 @@ impl ImageBorderSegment { tile_spacing, } } -} +} \ No newline at end of file diff --git a/wrench/reftests/border/border-clamp-corner-radius-ref.png b/wrench/reftests/border/border-clamp-corner-radius-ref.png new file mode 100644 index 0000000000..e87d5873e2 Binary files /dev/null and b/wrench/reftests/border/border-clamp-corner-radius-ref.png differ diff --git a/wrench/reftests/border/border-clamp-corner-radius.yaml b/wrench/reftests/border/border-clamp-corner-radius.yaml new file mode 100644 index 0000000000..10859274c7 --- /dev/null +++ b/wrench/reftests/border/border-clamp-corner-radius.yaml @@ -0,0 +1,24 @@ +--- +root: + items: + - type: stacking-context + bounds: [0, 0, 420, 250] + items: + - type: border + bounds: [ 0, 0, 200, 200 ] + width: 10 + border-type: normal + style: solid + radius: 180 + color: blue + - type: border + bounds: [ 200, 0, 200, 200 ] + width: 10 + border-type: normal + style: solid + radius: + top-left: [180, 180] + top-right: [0, 0] + bottom-left: [0, 0] + bottom-right: [180, 180] + color: blue \ No newline at end of file diff --git a/wrench/reftests/border/border-no-bogus-line-ref.png b/wrench/reftests/border/border-no-bogus-line-ref.png index 52344a03fe..64c7a3afe5 100644 Binary files a/wrench/reftests/border/border-no-bogus-line-ref.png and b/wrench/reftests/border/border-no-bogus-line-ref.png differ diff --git a/wrench/reftests/border/reftest.list b/wrench/reftests/border/reftest.list index a8e95cc59d..883176536d 100644 --- a/wrench/reftests/border/reftest.list +++ b/wrench/reftests/border/reftest.list @@ -1,3 +1,4 @@ +== border-clamp-corner-radius.yaml border-clamp-corner-radius-ref.png == border-gradient-simple.yaml border-gradient-simple-ref.yaml == border-radial-gradient-simple.yaml border-radial-gradient-simple-ref.yaml == border-radii.yaml border-radii.png