Closed
Bug 328241
Opened 19 years ago
Closed 18 years ago
Anti-aliasing problem with joining borders
Categories
(Core :: Graphics, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: maikelkrause, Assigned: vlad)
References
Details
(Keywords: regression, testcase)
Attachments
(5 files, 1 obsolete file)
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060222 Firefox/1.6a1
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) Gecko/20060222 Firefox/1.6a1
There seems to be an anti-aliasing problem between borders. This can be easily seen on the Acid2 test for instance, which uses such techniques to form squares.
Reproducible: Always
Steps to Reproduce:
1. Open attached testcase
Actual Results:
Lines are visible where borders join.
Expected Results:
Should see a perfect black square.
Reporter | ||
Comment 1•19 years ago
|
||
Should see a perfect square.
Reporter | ||
Comment 2•19 years ago
|
||
Comment 4•19 years ago
|
||
Here the bug is more visible than in the first testcase.
Comment 5•19 years ago
|
||
Testcase with doctype (to compare with Opera's rendering)
Attachment #213309 -
Attachment is obsolete: true
Comment 6•19 years ago
|
||
According to bug 289480 (comment 289480#93) this bug created a regression in acid2 test rendering.
Comment 7•19 years ago
|
||
...which is what comment #0 already says...
Comment 8•19 years ago
|
||
Ryan, I'm not the QA contact for this bug. Therefore I do not need to read it all. I just wanted to be helpful.
Thanks for spamming the bug (with your comment and my compulsory reply).
Updated•19 years ago
|
Keywords: regression,
testcase
Comment 9•19 years ago
|
||
Might be a good information that the bug is caused by a check-in that happened between 2006-01-24 and 2006-02-10. Anybody having builds from that timeframe should run either Acid2 or one of these testcases to identify the real time of the buggy check-in.
Comment 10•19 years ago
|
||
Correction: This bug has appeared in the Cairo branch with build 2005-11-09-13, much before its appearance in the trunk. It's invisible in build 2005-11-09-08. Maybe we should check what changes were made to the Cairo branch in that timeframe to find the check-in causing this bug.
Comment 11•19 years ago
|
||
What's the branch tag for the brach referenced in comment 10?
Blocks: acid2
Flags: blocking1.9a1?
Assignee | ||
Comment 12•19 years ago
|
||
This isn't a css rendering issue, sorry that I didn't see the bug sooner -- it has to do with how borders are rendered through gfx. Lines and polygon edges were not antialiased before, now they are; this is causing this boundary issue. There are a few potential fixes, but I'd need to talk to dbaron/bz/someone to figure out what the right way to do it is.
Ideally, the border rendering code would combine same-color border pieces into a single polygon to render instead of rendering them as 4 separate polygons always. Also, that code can probably be simplified quite a bit; it goes through great pains (if I remember right) to do things like rendering width-2 borders as 2 lines instead of doing a polygon render.
Comment 13•19 years ago
|
||
Well, it's not that simple, since the borders can be different colors, but we don't want an approximation of the background in the middle even if they are. Given anti-aliasing, cairo really needs an api for filling multiple polygons at once, in different colors, that avoids this issue. I can't think off the top of my head how one would implement such an API, actually, but I'm not a graphics expert. (And given dashed and dotted borders, it may be a lot of polygons.)
Comment 14•19 years ago
|
||
> Ideally, the border rendering code would combine same-color border pieces into
> a single polygon to render
I'm not sure the simple case of 4 borders all of the same color (as here) can be expressed as a single polygon without running into this bug somewhere. I'd love to be proved wrong, of course. ;)
Assignee | ||
Comment 15•19 years ago
|
||
(In reply to comment #14)
> > Ideally, the border rendering code would combine same-color border pieces into
> > a single polygon to render
>
> I'm not sure the simple case of 4 borders all of the same color (as here) can
> be expressed as a single polygon without running into this bug somewhere. I'd
> love to be proved wrong, of course. ;)
Hmm, I'm not sure why not (I guess I should have said path, not necessarily polygon.. as I'm thinking of a polygon with holes :).. as dbaron points out though, we'd have a similar problem at different-color border joins, it would just be less visible (but no less wrong).
Comment 16•19 years ago
|
||
There's not much here that attachment 213310 [details] doesn't cover (just the dashed border, really), but attaching another one anyway.
Assignee | ||
Comment 17•19 years ago
|
||
Actually, I /think/ this may also be caused by us offsetting the coordinates of one side of each border side by 1, to get no overlap, whereas in this case we do want overlap. That will give us overdraw in the case of translucent colors, though, but there's another way we can draw borders with translucency. (Assuming they all have the same opacity -- if you have 4 borders with different opacities... that's just pain, I think.)
I think this is just an example of the generic seams problem that occurs when rendering using coverage-based antialiasing. It's popping up elsewhere, like when you render a rotated HTML page that contains a mosaic of images or elements (e.g. Google Maps).
The only solution IMHO is to turn off coverage-based antialiasing wherever it causes such problems, and use supersampling instead when resources are available.
Comment 19•19 years ago
|
||
I'd agree with that; this type of antialiasing would be really annoying for Web designers.
Comment 20•19 years ago
|
||
I would also vote at removing this type of antialiasing, as it only causes problems.
Comment 21•19 years ago
|
||
Some more pages showing this bug:
http://www.hixie.ch/tests/evil/css/css21/tests/t100304-c43-rpl-bbx-01-d-g.xht
http://www.hixie.ch/tests/evil/css/css21/tests/t1005-c5524-width-00-b-g.xht (notice the border of the blue square)
http://www.hixie.ch/tests/evil/css/css21/tests/t100304-c43-rpl-bbx-00-d-g.xht (the smaller square shouldn't be blurred)
http://www.hixie.ch/tests/evil/css/css21/tests/t1008-c44-ln-box-01-d-ag.xht (I suspect that it's related, something is also visible on the border)
http://www.hixie.ch/tests/evil/css/css21/tests/t100801-c42-ibx-ht-00-d-a.xht (there is no red, but diagonal lines are seen)
http://www.hixie.ch/tests/evil/css/css21/tests/t100801-c544-valgn-03-d-agi.xht (blue rectangles sometimes blurred)
http://www.hixie.ch/tests/evil/css/css21/tests/t140201-c537-bgfxps-00-c-ag.xht (yellow lines in the green block)
http://www.hixie.ch/tests/evil/css/css21/tests/t0805-c5518-ibrdr-t-00-a.htm (blue lines blurred)
Reporter | ||
Comment 22•19 years ago
|
||
Stefanik, most of those testcases have nothing to do with this bug. The blurryness is caused by bug 324698.
Comment 23•19 years ago
|
||
The green border of http://www.hixie.ch/tests/evil/css/css21/tests/t1008-c44-ln-box-02-d-ag.xht really shows this bug, though. (Look at the corners of the frame!)
Comment 24•19 years ago
|
||
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a1) Gecko/20060407 Firefox/3.0a1
Using the testcases in this bug, I can confirm this on Linux.
OS: Windows XP → All
Assignee | ||
Comment 25•19 years ago
|
||
So here's an easy patch to fix this for the interim, until we can come up with a better solution. This will disable AA for square borders (not for -moz-border-radius).
Some of the future solutions dbaron and I talked about:
1) For the common case where all sides of the border either have the same color (or are not present), render the entire border as one path.
2) If the borders have different colors but are at 100% opacity, then we need to adjust the generated polygons such that they truly overlap at the corners -- right now the border rendering code explicitly makes sure that they don't overlap, and tightly controls which side gets the extra pixel. For the antialiasing to look right, the diagonal line from each border side should be drawn in the same location, not adjacant to eachother.
3) If the borders have different colors and are all at the same opacity (but not 100%), we render the borders at 100% opacity in a subsurface and then paint that in at whatever the desired opacity is (giving us the same output as #2, with a constant opacity).
4) If the borders have different colors and different opacities, then we've got some trouble. What should the joinining line look like between a 30% opacity red left border and 50% opacity blue top border? My initial thought is a 40% opacity red-blue join, so that there is a smooth progression for the 30% to the 50%. Alternatively, in this non-common case, we could fall back to just not doing antialiasing here.
Assignee | ||
Updated•19 years ago
|
Attachment #219188 -
Flags: review? → review?(dbaron)
Comment 26•19 years ago
|
||
Comment on attachment 219188 [details] [diff] [review]
disable antialiasing for borders, for now
This patch looks fine. (It reminds me that I really need to fix dashed/dotted border drawing at some point to do the right thing, but that's bug 19963.)
5) I think there's also a fifth possibility. I think it *should* be possible to do additional drawing on top that will fix up the edge. In particular, I'd think you could implement a function that took a path and two colors (where the first color was painted first, and on the left side of the path, and the second color was painted afterwards, and on the right side of the path) and do additional drawing on all pixels that are crossed by the path to get them to the correct color, modulo a small amount of rounding error accumulation. (Of course, such a function would have problems at pixels that were both crossed by the path and not completely covered by the two regions -- but that shouldn't be an issue in this case.)
Attachment #219188 -
Flags: review?(dbaron) → review+
Assignee | ||
Comment 27•19 years ago
|
||
(In reply to comment #26)
> (From update of attachment 219188 [details] [diff] [review] [edit])
> This patch looks fine. (It reminds me that I really need to fix dashed/dotted
> border drawing at some point to do the right thing, but that's bug 19963.)
Checked in.
> 5) I think there's also a fifth possibility. I think it *should* be possible
> to do additional drawing on top that will fix up the edge. In particular, I'd
> think you could implement a function that took a path and two colors (where the
> first color was painted first, and on the left side of the path, and the second
> color was painted afterwards, and on the right side of the path) and do
> additional drawing on all pixels that are crossed by the path to get them to
> the correct color, modulo a small amount of rounding error accumulation. (Of
> course, such a function would have problems at pixels that were both crossed by
> the path and not completely covered by the two regions -- but that shouldn't be
> an issue in this case.)
Hmm, maybe; this should be doable in the case of opaque borders, but with any sort of translucent borders it becomes hard.. the final result depends on what's underneath, and we would have already drawn a "wrong" antialiased border there already. I'm not sure if it would be possible in that case.
Comment 28•19 years ago
|
||
> the final result depends on
> what's underneath, and we would have already drawn a "wrong" antialiased border
> there already. I'm not sure if it would be possible in that case.
Couldn't you clip the drawing in a way that the wrong stuff won't be drawn?
Comment 29•19 years ago
|
||
In the cases with alpha, however, the issue would be that too little was drawn, not too much, so drawing something else with alpha on top ought to be able to correct the problem unless the math is nonlinear.
Comment 30•19 years ago
|
||
I have not yet had the chance to look into the provided test cases in detail, nor what the geometry and constraints of "borders" even are.
The various proposed workarounds for the problem seem reasonable, but I think there are still some possible fixes for the problem that have not been discussed here. Specifically, between Vlad's #3 (draw opaque to intermediate surface, then blend result) but before #4 (disable antialiasing), there are generalizations of #3 that will support various alpha values of the connecting objects. The trick is to carefully use ADD or SATURATE operators.
Ee've had discussions about seams issues like this on the cairo list before. Here's an example of an SVG file that was provided to the cairo list as a very hard case to avoid the seams problem:
http://cairographics.org/~cworth/images/star_and_ring.svg
This is a particularly challenging figure since the two objects mutually overlap each other and both are translucent. SVG is 2.5-dimensional, so can't actually express mutually overlapping figures directly. So the objects in the SVG file here have been pre-sliced, which is what introduces the seams problem.
Here's a post from me showing an approach that achieves the desired result:
http://lists.freedesktop.org/archives/cairo/2005-March/003457.html
What I did not provide there was an algorithm for taking the original pre-sliced objects and also drawing the correct result. (Owen Taylor did later sketch out something that would be possible to implement, but might require some rather elaborate data structures (BSP say) in order to be efficient:
http://lists.freedesktop.org/archives/cairo/2005-March/003461.html
But, if the problematic edges are "known" to the programmer, then an approach like I show above might be helpful, without requiring anything like Owen described. (Here is where I don't know the constraints of the problem being attempted in this bug report.)
And while we're throwing things out, another general solution is to use the SATURATE operator and drawing objects front-to-back. This is similar to what OpenGL does to avoid seams, and has been demonstrated to be an effective approach with cairo by a gnuplot developer, (modulo some correctness bugs in the X server implementation of SATURATE).
Anyway, I hope some of that might be relevant or helpful.
-Carl
Comment 31•18 years ago
|
||
See also bug 342262, "Antialiasing causes seams in rotated HTML content".
Assignee | ||
Updated•18 years ago
|
Flags: blocking1.9a1? → blocking1.9-
Whiteboard: [wanted-1.9]
Assignee | ||
Comment 32•18 years ago
|
||
Fixed by patch for bug 368247.
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Comment 33•18 years ago
|
||
Shouldn't we back out the no-antialiasing patch now that we got antialiasing right?
Updated•17 years ago
|
Flags: wanted1.9+
Whiteboard: [wanted-1.9]
Comment 34•12 years ago
|
||
I would love to see this re-opened to add antialiasing back in with a real fix instead of just removing it. Joining borders look pretty bad in FireFox at the moment.
Comment 35•12 years ago
|
||
Scott, reopening is generally reserved for when patches get backed out. If you want a followup fix, please file a separate bug.
You need to log in
before you can comment on or make changes to this bug.
Description
•