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

Elements with a combination of 'border' and 'border-radius' are drawn incorrectly #20922

Closed
MartinRogalla opened this issue Jun 5, 2018 · 21 comments

Comments

@MartinRogalla
Copy link

@MartinRogalla MartinRogalla commented Jun 5, 2018

Excuse my narcism here for posting my own profile picture, but I was checking out my own website in servo. What I noticed is that my profile picture that is supposed to be round, get's drawn incorrectly:

Google Chrome:
chrome

Servo:
servo

When I try to create a 'circular' element with the following attributes:

border: 3px solid #fff;
border-radius: 100px; /* note, border-radius >= 75px for the element do be 'circular' */
width: 150px;
height: 150px;

To me it looks like the image gets square borders and then is rounded, instead of the other way around. I'm interested in contributing to servo and would love to pick this issue up if you think it's doable.

@MartinRogalla MartinRogalla changed the title Elements with border and border-radius causes draw incorrectly Elements with a combination of 'border' and 'border-radius' are drawn incorrectly Jun 5, 2018
@jdm
Copy link
Member

@jdm jdm commented Jun 5, 2018

pub fn build_border_radius(
is the code that is responsible for creating a border radius value that is added to display list items. It would be worth creating a minimal testcase so it's easier to trace the code that ends up reaching there.

@MartinRogalla
Copy link
Author

@MartinRogalla MartinRogalla commented Jun 5, 2018

Perfect, will do. Thanks!

@MartinRogalla
Copy link
Author

@MartinRogalla MartinRogalla commented Jun 6, 2018

The following document should render a purple circle with a pink border:

<html>
<head>
    <link rel=match href=border_radius_border_solid_combination.html>
</head>
<body>
    <div style="background: #1f1f2e; border-radius: 50%; border: 10px solid #ff3399; width: 250px; height: 250px;"></div>
</body>
</html>

Expected output:
correct
Actual output:
actual

This is only happening when the border is greater than 3px. If it is 3px or less, it renders as expected.

Display-list Dump

Nothing in the display-lists caught my eye that would explain why it's incorrectly rendering. I will keep looking.

@jdm
Copy link
Member

@jdm jdm commented Jun 6, 2018

It may be that our display list is correct and webrender is interpreting it incorrectly. @gw3583 does this ring any bells?

@MartinRogalla
Copy link
Author

@MartinRogalla MartinRogalla commented Jun 6, 2018

I think the issue might be here: webrender/src/util.rs extract_inner_rect_impl. I'll have another look in a bit and if needed will try to build the webrenderer and use that to find where it's going wrong.

@gw3583
Copy link
Contributor

@gw3583 gw3583 commented Jun 6, 2018

It doesn't ring any bells. It's certainly possible it could be a bug in WR, although I don't think we've seen anything like this in Gecko thus far. One option would be to build wrench (the standalone WR reftest tool) and see if you can reproduce it in wrench by modifying some of the border reftests (for example https://github.com/servo/webrender/tree/master/wrench/reftests/border).

@gw3583
Copy link
Contributor

@gw3583 gw3583 commented Jun 6, 2018

If you can reproduce it there, that would rule out Servo being the issue.

@MartinRogalla
Copy link
Author

@MartinRogalla MartinRogalla commented Jun 6, 2018

Perfect, I'll try that. Thanks!

@MartinRogalla
Copy link
Author

@MartinRogalla MartinRogalla commented Jun 7, 2018

Running the border-tests using:

cd wrench && cargo run -- reftest reftests/border/

in WebRender outputs failing tests (both on 'master' & on 'auto'):

REFTEST INFO | 15 passing, 5 failing
Reftests with unexpected results:
        reftests/border/border-clamp-corner-radius.yaml == reftests/border/border-clamp-corner-radius.png
        reftests/border/border-suite.yaml == reftests/border/border-suite.png
        reftests/border/border-suite-2.yaml == reftests/border/border-suite-2.png
        reftests/border/border-suite-3.yaml == reftests/border/border-suite-3.png
        reftests/border/degenerate-curve.yaml == reftests/border/degenerate-curve.png

Is this to be expected (as in tests written but not yet implemented), or should these reftests always pass?

I think this is indeed a WR issue. See servo/webrender/issues/2754

@gw3583
Copy link
Contributor

@gw3583 gw3583 commented Jun 7, 2018

For the reftests, you'll need to use the headless script to run them - this will ensure that they are drawn with a software rasterizer for consistency between machines:

./script/headless.py reftest reftests/border/

@dralley
Copy link
Contributor

@dralley dralley commented Apr 6, 2020

The test snippet from #20922 (comment) is fixed, but the original website link still renders incorrectly.

@jdm
Copy link
Member

@jdm jdm commented Apr 6, 2020

<style>
#avatar {
        border: 3px solid #000;
        border-radius: 100px;
        width: 150px;
        height: 150px;
}
</style>
<img id="avatar" src="https://martinrogalla.com/img/martin-rogalla-bw.jpg">

Firefox:
Screen Shot 2020-04-06 at 2 24 16 PM
Servo:
Screen Shot 2020-04-06 at 2 24 30 PM

@jdm
Copy link
Member

@jdm jdm commented Apr 6, 2020

Switching the img to a div shows the expected circular background color with the borders appearing over top as expected.

@dralley
Copy link
Contributor

@dralley dralley commented Apr 8, 2020

Do you have idea where the code that controls this would be located?

@dralley
Copy link
Contributor

@dralley dralley commented Apr 9, 2020

@jdm ^

@jdm
Copy link
Member

@jdm jdm commented Apr 13, 2020

Of course, it's not clear to me if ultimately the problem is that:

  1. we're drawing the image over the borders
  2. our border calculation code is incorrect
  3. our border-radius calculation code is incorrect
  4. something else??
@dralley
Copy link
Contributor

@dralley dralley commented Apr 13, 2020

Screenshot from 2020-04-13 18-12-34

So, 2 things:

  • It looks like the size is exactly the same and the border width is the same.
  • If you look closely, the visible parts of the border have completely straight edges. It kinda looks like the picture + border is being drawn square and then the whole thing clipped to fit a circle, rather than the image clipped into a circle and then a round border applied. (edit: which I'm somehow just noticing is exactly what the original reporter said...)

Does that help pin down the problem?

Other differences, irrelevant to the current problem but might be worthwhile to think about:

  • Firefox seems to add a tiny white edge between the border and the image so that you can distinguish the two when they have very similar colors
  • The Servo-rendered image has a lot more pixelation
@dralley
Copy link
Contributor

@dralley dralley commented Apr 14, 2020

Found a duplicate (well, probably duplicate) issue, it's a lot more obvious with the example they use: #22818

@dralley
Copy link
Contributor

@dralley dralley commented Apr 14, 2020

Layout 2020, meanwhile, looks like this:

Screenshot from 2020-04-14 10-58-27
Screenshot from 2020-04-14 10-58-43

@jdm jdm added the A-layout/2020 label Apr 14, 2020
@dralley
Copy link
Contributor

@dralley dralley commented Apr 17, 2020

Ignore #20922 (comment), I'm wrong, it's definitely drawing a round border and then drawing the rectangular image on top of that. It's obvious if you toss a panic in before the image gets drawn.

All the dimensions are correct when I measure with GIMP (as far as I know, I have very little web dev experience). It seems like the image stops drawing at the outer edge of the border rather than the inner edge, or it's on top when it should not be.

I assume the issue is probably somewhere in here? https://github.com/servo/servo/blob/master/components/layout/display_list/builder.rs#L1720

@jdm
Copy link
Member

@jdm jdm commented Apr 17, 2020

The CSS specification defines an order in which elements are painted in https://www.w3.org/TR/CSS2/zindex.html#painting-order. Given this, I believe that painting borders before the image content is correct. Since changing the border-radius to 0 in the testcase shows the border correctly, this suggests to me that the calculations for border-radius interact poorly with the calculations for where to draw the border, which suggests that the error is in https://github.com/servo/servo/blob/master/components/layout/display_list/builder.rs#L1731-L1739 or https://github.com/servo/servo/blob/master/components/layout/display_list/builder.rs#L574-L590

bors-servo added a commit that referenced this issue Apr 17, 2020
Fix combination of border and border-radius being drawn incorrectly

fixes #20922

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #20922

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because ___
bors-servo added a commit that referenced this issue Apr 30, 2020
Fix combination of border and border-radius being drawn incorrectly

fixes #20922

Manual testcase in the attached issue

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #20922

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because ___
bors-servo added a commit that referenced this issue May 1, 2020
Fix combination of border and border-radius being drawn incorrectly

fixes #20922

Manual testcase in the attached issue

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #20922

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because ___
bors-servo added a commit that referenced this issue May 2, 2020
Fix combination of border and border-radius being drawn incorrectly

fixes #20922

Manual testcase in the attached issue

- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #20922

<!-- Either: -->
- [x] There are tests for these changes OR
- [ ] These changes do not require tests because ___
@bors-servo bors-servo closed this in 232df23 May 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

4 participants
You can’t perform that action at this time.