Skip to content

Commit 30de644

Browse files
author
bors-servo
authored
Auto merge of #1769 - glennw:fix-border-panic, r=nical
Fix a panic in border image segment creation. Fixes servo/servo#18633 Fixes servo/servo#18615 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/1769) <!-- Reviewable:end -->
2 parents e4c846a + e0da68b commit 30de644

File tree

5 files changed

+137
-77
lines changed

5 files changed

+137
-77
lines changed

webrender/src/frame_builder.rs

Lines changed: 97 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -801,15 +801,15 @@ impl FrameBuilder {
801801
let rect = LayerRect::new(origin, size);
802802

803803
// Calculate the local texel coords of the slices.
804-
let px0 = 0;
805-
let px1 = border.patch.slice.left;
806-
let px2 = border.patch.width - border.patch.slice.right;
807-
let px3 = border.patch.width;
804+
let px0 = 0.0;
805+
let px1 = border.patch.slice.left as f32;
806+
let px2 = border.patch.width as f32 - border.patch.slice.right as f32;
807+
let px3 = border.patch.width as f32;
808808

809-
let py0 = 0;
810-
let py1 = border.patch.slice.top;
811-
let py2 = border.patch.height - border.patch.slice.bottom;
812-
let py3 = border.patch.height;
809+
let py0 = 0.0;
810+
let py1 = border.patch.slice.top as f32;
811+
let py2 = border.patch.height as f32 - border.patch.slice.bottom as f32;
812+
let py3 = border.patch.height as f32;
813813

814814
let tl_outer = LayerPoint::new(rect.origin.x, rect.origin.y);
815815
let tl_inner = tl_outer + vec2(border_item.widths.left, border_item.widths.top);
@@ -826,81 +826,104 @@ impl FrameBuilder {
826826
);
827827
let br_inner = br_outer - vec2(border_item.widths.right, border_item.widths.bottom);
828828

829+
fn add_segment(
830+
segments: &mut Vec<ImageBorderSegment>,
831+
rect: LayerRect,
832+
uv_rect: TexelRect,
833+
repeat_horizontal: RepeatMode,
834+
repeat_vertical: RepeatMode) {
835+
if uv_rect.uv1.x > uv_rect.uv0.x &&
836+
uv_rect.uv1.y > uv_rect.uv0.y {
837+
segments.push(ImageBorderSegment::new(
838+
rect,
839+
uv_rect,
840+
repeat_horizontal,
841+
repeat_vertical,
842+
));
843+
}
844+
}
845+
829846
// Build the list of image segments
830-
let mut segments = vec![
831-
// Top left
832-
ImageBorderSegment::new(
833-
LayerRect::from_floats(tl_outer.x, tl_outer.y, tl_inner.x, tl_inner.y),
834-
TexelRect::new(px0, py0, px1, py1),
835-
RepeatMode::Stretch,
836-
RepeatMode::Stretch,
837-
),
838-
// Top right
839-
ImageBorderSegment::new(
840-
LayerRect::from_floats(tr_inner.x, tr_outer.y, tr_outer.x, tr_inner.y),
841-
TexelRect::new(px2, py0, px3, py1),
842-
RepeatMode::Stretch,
843-
RepeatMode::Stretch,
844-
),
845-
// Bottom right
846-
ImageBorderSegment::new(
847-
LayerRect::from_floats(br_inner.x, br_inner.y, br_outer.x, br_outer.y),
848-
TexelRect::new(px2, py2, px3, py3),
849-
RepeatMode::Stretch,
850-
RepeatMode::Stretch,
851-
),
852-
// Bottom left
853-
ImageBorderSegment::new(
854-
LayerRect::from_floats(bl_outer.x, bl_inner.y, bl_inner.x, bl_outer.y),
855-
TexelRect::new(px0, py2, px1, py3),
856-
RepeatMode::Stretch,
857-
RepeatMode::Stretch,
858-
),
859-
];
847+
let mut segments = vec![];
848+
849+
// Top left
850+
add_segment(
851+
&mut segments,
852+
LayerRect::from_floats(tl_outer.x, tl_outer.y, tl_inner.x, tl_inner.y),
853+
TexelRect::new(px0, py0, px1, py1),
854+
RepeatMode::Stretch,
855+
RepeatMode::Stretch
856+
);
857+
// Top right
858+
add_segment(
859+
&mut segments,
860+
LayerRect::from_floats(tr_inner.x, tr_outer.y, tr_outer.x, tr_inner.y),
861+
TexelRect::new(px2, py0, px3, py1),
862+
RepeatMode::Stretch,
863+
RepeatMode::Stretch
864+
);
865+
// Bottom right
866+
add_segment(
867+
&mut segments,
868+
LayerRect::from_floats(br_inner.x, br_inner.y, br_outer.x, br_outer.y),
869+
TexelRect::new(px2, py2, px3, py3),
870+
RepeatMode::Stretch,
871+
RepeatMode::Stretch
872+
);
873+
// Bottom left
874+
add_segment(
875+
&mut segments,
876+
LayerRect::from_floats(bl_outer.x, bl_inner.y, bl_inner.x, bl_outer.y),
877+
TexelRect::new(px0, py2, px1, py3),
878+
RepeatMode::Stretch,
879+
RepeatMode::Stretch
880+
);
860881

861882
// Center
862883
if border.fill {
863-
segments.push(ImageBorderSegment::new(
884+
add_segment(
885+
&mut segments,
864886
LayerRect::from_floats(tl_inner.x, tl_inner.y, tr_inner.x, bl_inner.y),
865887
TexelRect::new(px1, py1, px2, py2),
866888
border.repeat_horizontal,
867-
border.repeat_vertical,
868-
))
889+
border.repeat_vertical
890+
);
869891
}
870892

871-
// Add edge segments if valid size.
872-
if px1 < px2 && py1 < py2 {
873-
segments.extend_from_slice(&[
874-
// Top
875-
ImageBorderSegment::new(
876-
LayerRect::from_floats(tl_inner.x, tl_outer.y, tr_inner.x, tl_inner.y),
877-
TexelRect::new(px1, py0, px2, py1),
878-
border.repeat_horizontal,
879-
RepeatMode::Stretch,
880-
),
881-
// Bottom
882-
ImageBorderSegment::new(
883-
LayerRect::from_floats(bl_inner.x, bl_inner.y, br_inner.x, bl_outer.y),
884-
TexelRect::new(px1, py2, px2, py3),
885-
border.repeat_horizontal,
886-
RepeatMode::Stretch,
887-
),
888-
// Left
889-
ImageBorderSegment::new(
890-
LayerRect::from_floats(tl_outer.x, tl_inner.y, tl_inner.x, bl_inner.y),
891-
TexelRect::new(px0, py1, px1, py2),
892-
RepeatMode::Stretch,
893-
border.repeat_vertical,
894-
),
895-
// Right
896-
ImageBorderSegment::new(
897-
LayerRect::from_floats(tr_inner.x, tr_inner.y, br_outer.x, br_inner.y),
898-
TexelRect::new(px2, py1, px3, py2),
899-
RepeatMode::Stretch,
900-
border.repeat_vertical,
901-
),
902-
]);
903-
}
893+
// Add edge segments.
894+
895+
// Top
896+
add_segment(
897+
&mut segments,
898+
LayerRect::from_floats(tl_inner.x, tl_outer.y, tr_inner.x, tl_inner.y),
899+
TexelRect::new(px1, py0, px2, py1),
900+
border.repeat_horizontal,
901+
RepeatMode::Stretch,
902+
);
903+
// Bottom
904+
add_segment(
905+
&mut segments,
906+
LayerRect::from_floats(bl_inner.x, bl_inner.y, br_inner.x, bl_outer.y),
907+
TexelRect::new(px1, py2, px2, py3),
908+
border.repeat_horizontal,
909+
RepeatMode::Stretch,
910+
);
911+
// Left
912+
add_segment(
913+
&mut segments,
914+
LayerRect::from_floats(tl_outer.x, tl_inner.y, tl_inner.x, bl_inner.y),
915+
TexelRect::new(px0, py1, px1, py2),
916+
RepeatMode::Stretch,
917+
border.repeat_vertical,
918+
);
919+
// Right
920+
add_segment(
921+
&mut segments,
922+
LayerRect::from_floats(tr_inner.x, tr_inner.y, br_outer.x, br_inner.y),
923+
TexelRect::new(px2, py1, px3, py2),
924+
RepeatMode::Stretch,
925+
border.repeat_vertical,
926+
);
904927

905928
for segment in segments {
906929
let mut info = info.clone();

webrender/src/prim_store.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ pub struct TexelRect {
5757
}
5858

5959
impl TexelRect {
60-
pub fn new(u0: u32, v0: u32, u1: u32, v1: u32) -> TexelRect {
60+
pub fn new(u0: f32, v0: f32, u1: f32, v1: f32) -> TexelRect {
6161
TexelRect {
62-
uv0: DevicePoint::new(u0 as f32, v0 as f32),
63-
uv1: DevicePoint::new(u1 as f32, v1 as f32),
62+
uv0: DevicePoint::new(u0, v0),
63+
uv1: DevicePoint::new(u1, v1),
6464
}
6565
}
6666

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
root:
3+
items:
4+
- type: stacking-context
5+
bounds: [0, 0, 500, 500]
6+
items:
7+
- type: border
8+
bounds: [ 100, 100, 192, 192 ]
9+
width: 32
10+
border-type: image
11+
image-source: "border-image-src.png"
12+
image-width: 32
13+
image-height: 32
14+
slice: [ 3, 0, 1, 36 ]
15+
outset: 0
16+
repeat-vertical: stretch
17+
repeat-horizontal: stretch
18+
fill: true
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
root:
3+
items:
4+
- type: stacking-context
5+
bounds: [0, 0, 500, 500]
6+
items:
7+
- type: border
8+
bounds: [ 100, 100, 192, 192 ]
9+
width: 32
10+
border-type: image
11+
image-source: "border-image-src.png"
12+
image-width: 32
13+
image-height: 32
14+
slice: [ 3, 0, 1, 36 ]
15+
outset: 0
16+
repeat-vertical: stretch
17+
repeat-horizontal: stretch
18+
fill: true

wrench/reftests/border/reftest.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ fuzzy(255,24) == border-groove-simple.yaml border-groove-simple-ref.yaml
99
fuzzy(255,24) == border-ridge-simple.yaml border-ridge-simple-ref.yaml
1010
== degenerate-curve.yaml degenerate-curve.png
1111
== border-image.yaml border-image-ref.png
12+
== border-image-crash.yaml border-image-crash-ref.yaml
1213
== border-image-fill.yaml border-image-fill-ref.png
1314

0 commit comments

Comments
 (0)