|
Replies:
14
-
Last Post:
Jul 9, 2007 9:32 PM
by: Dmitri Trembove...
|
Threads:
[
Previous
|
Next
]
|
|
|
|
|
|
Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 3:56 AM
|
|
|
I'm writing some nice looking components, or I'm trying to at least.. Is there any way to affect the anti aliasing "weight" on normal draws, like lines and the rounded corners of a RoundRectangle2D?
They are to heavy in general. You can see this for instance in the roundness of the buttons in the Numbus L&F:
http://galbraiths.org/blog/wp-content/uploads/2007/03/controls_regular.png
Look at the third "Close" button from the left in the top row. The top corners are too thick. This happens only for darker colors though.
While we are on the subject of gfx and Nimbus. Run the webstart app and look at the buttons. You'll see the problem with differently sized corners of RoundeRectangles that I've mentioned several times. Check the top four buttons in the "Color Chooser" tab and you'll see what I mean (the corners have different radius).
http://javadesktop.org/swinglabs/demos/nimbus/nimbus.jnlp
I hope these glitches gets fixed soon as it is hard to create high fidelity stuff that looks as posh as Apples' stuff when the above problems are present.
Btw, this was tested on Windows with Java 1.6.0_01 with the normal pipeline. And I do off course know about PURE strokes, fractional metrics and all those kind of rendering hints...
Cheers, Mikael Grev
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 9:00 AM
in response to: mikaelgrev
|
|
|
On Jun 29, 2007, at 3:56 AM, java2d@javadesktop.org wrote: > I'm writing some nice looking components, or I'm trying to at > least.. Is there any way to affect the anti aliasing "weight" on > normal draws, like lines and the rounded corners of a > RoundRectangle2D? >
As far as I know, there is no way to tweak the way our (current) antialiasing rasterizer produces coverage values.
> They are to heavy in general. You can see this for instance in the > roundness of the buttons in the Numbus L&F: > > http://galbraiths.org/blog/wp-content/uploads/2007/03/ > controls_regular.png > > Look at the third "Close" button from the left in the top row. The > top corners are too thick. This happens only for darker colors though. >
Not a very good example, considering that image comes from the Nimbus spec, which was produced entirely in Photoshop 
If you show us a simple, pure Java 2D testcase that illustrates your concerns, we might be able to offer more assistance.
> > While we are on the subject of gfx and Nimbus. Run the webstart app > and look at the buttons. You'll see the problem with differently > sized corners of RoundeRectangles that I've mentioned several > times. Check the top four buttons in the "Color Chooser" tab and > you'll see what I mean (the corners have different radius). > > http://javadesktop.org/swinglabs/demos/nimbus/nimbus.jnlp > > > I hope these glitches gets fixed soon as it is hard to create high > fidelity stuff that looks as posh as Apples' stuff when the above > problems are present. >
That is an older demo; there is plenty more ongoing work with Nimbus. If you have specific complaints about Nimbus itself, I suggest you bring them up on the Nimbus mailing list.
Chris
> Btw, this was tested on Windows with Java 1.6.0_01 with the normal > pipeline. And I do off course know about PURE strokes, fractional > metrics and all those kind of rendering hints... > Cheers, > Mikael Grev > [Message sent by forum member 'mikaelgrev' (mikaelgrev)] > > http://forums.java.net/jive/thread.jspa?messageID=224661 > > ====================================================================== > ===== > To unsubscribe, send email to listserv@java.sun.com and include in > the body > of the message "signoff JAVA2D-INTEREST". For general help, send > email to > listserv@java.sun.com and include in the body of the message "help".
=========================================================================== To unsubscribe, send email to listserv@java.sun.com and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to listserv@java.sun.com and include in the body of the message "help".
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 12:29 PM
in response to: Chris Campbell
|
|
|
Hi Chris,
I'll leave the AA thickness as explained in the reply to Kirill above.
What bothers me a tad more is the flat circles that still haunts us. I think this is what is the problem with the Webstart app as well. It's solvable by using non-even sizes only though..
I'll try to post a screen shot of the problem here (and I have checked this in Photoshop, there're round..) :
Cheers,
Mikael
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 1:02 PM
in response to: Jim Graham
|
|
|
Yes, sure have. That solves the roundness but brings on a whole slew of other visual problems (not bugs), especially with RoundedRectangles. Like simple lines being two pixels wide, in gray.
Cheers, Mikael
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 1:44 PM
in response to: mikaelgrev
|
|
|
The double wide gray lines are due to the fact that lines straddle the border between pixels and so extend halfway into each pixel on either side.
Adding .5 to the coordinates should help with that...
...jim
java2d@javadesktop.org wrote: > Yes, sure have. That solves the roundness but brings on a whole slew of other visual problems (not bugs), especially with RoundedRectangles. Like simple lines being two pixels wide, in gray. > > Cheers, > Mikael > [Message sent by forum member 'mikaelgrev' (mikaelgrev)] > > http://forums.java.net/jive/thread.jspa?messageID=224739 > > =========================================================================== > To unsubscribe, send email to listserv@java.sun.com and include in the body > of the message "signoff JAVA2D-INTEREST". For general help, send email to > listserv@java.sun.com and include in the body of the message "help".
=========================================================================== To unsubscribe, send email to listserv@java.sun.com and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to listserv@java.sun.com and include in the body of the message "help".
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 3:12 PM
in response to: Jim Graham
|
|
|
Yes, I know.
Given any exact case I can solve that using those kind of tricks. The problem is that I'm creating a generic shape painting framework and I don't want a lot of "if this, then that" if you know what I mean. For instance I should only use the pure if aa is on. Which Shape is painted, what rendering hints are used, what Composite are to be used are all configurable by the user of our API. That's why I need stuff to just work and not fiddle around with specific workarounds for specific problems...
I actually don't understand. As I see it the normal aa routine draws non-round circles when they should be round. That must be a bug. Why not just fix it?
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 4:19 PM
in response to: mikaelgrev
|
|
|
java2d@javadesktop.org wrote: > I actually don't understand. As I see it the normal aa routine draws non-round circles when they should be round. That must be a bug. Why not just fix it? > [Message sent by forum member 'mikaelgrev' (mikaelgrev)]
While I can imagine this is frustrating, let me point out why things behave the way that they do.
The circles are off because we have to massage the paths to meet some basic rasterization expectations. STROKE_PURE turns off that massaging so that you can manage the problems yourself if you so wish.
If you use PURE, then as you've discovered the lines become fuzzy unless you adjust them. As you've already pointed out, the adjustment can get tricky when dealing with arbitrary paths.
If we were to stop massaging the paths, then we'd have fuzzy lines like you see with STROKE_PURE, but the circles would get rounder.
We could stop massaging them and then also bias all paths and then you can choose whether you want fuzzy lines or fuzzy rectangles or both. No bias can have both sharp lines and sharp rectangles.
The massaging we apply under STROKE_NORMALIZE does manage to get basic primitives like lines and rectangles to both be crisp, but it does so with a more complicated adjustment than a simple bias that, unfortunately, disturbs the aesthetics of some circles.
We can fix our massaging to work better, but such an algorithm that both maintains the crispness of lines and rectangles and also preserves nicely rounded curves has yet to be created. You've already noted that some sizes of circles are both crisp and round with AA and NORMALIZE - I imagine that the other sizes have a basic mathematical conflict between trying to look crisp and trying to be round that might not be solvable. And, if there is a normalization technique that might make circles both round and crisp at all sizes, it might not work for the case of a quarter circle connecting to a horizontal and a vertical line on either side of it...all TBD...
Until then "fixing this bug" would mean creating some other condition that would appear to be a bug to someone else. Is a flat circle a worse bug than a fuzzy horizontal or vertical line?
Hopefully with the magic of OpenJDK someone out there might be able to come up with a better system...
...jim
=========================================================================== To unsubscribe, send email to listserv@java.sun.com and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to listserv@java.sun.com and include in the body of the message "help".
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jun 30, 2007 2:41 AM
in response to: Jim Graham
|
|
|
Thanks for the explanation.
I don't know what to say. You go to great length explaining why circles aren't round and why the corner radius on rounded rectangles are different on the different sides, and why you will not fix it. I guess other platforms (Flash, .NET and similar) also have these problems since they aren't fixable?
It turns out that it is too hard to do Java2D graphics in a high fidelity way, at least without resorting to hacks.
Another problem I have is that one can not in Java2D in a generic way outline and fill a Shape and make it look good. The outline will plot outside and inside the shape depending on the direction of the vector (in degrees). This is since you don't provide an INSIDE and OUTSIDE stroke. You have the hanging right/left stroke and the pure stroke.
The pure stroke isn't usable since you either get the lines sharing two pixels for vertical and horizontal lines or you do as you suggest and translate 0.5, in which case you get good lines but shapes that are one pixel too big.
One CAN solve the one-pixel-too-big-shapes-when-using-PURE-and-translate.5-problem by scaling the output with ((width - 1.0)/width) but that only works for rectangles (shapes with equal but mirrored quadrants actually, so also for circles) but fails for general paths, polygons and composite shapes of all kinds.
This problem has shown to unsolvable in a generic way. Only if one has prior knowledge about what type of shape to paint and are in full control of the rendering hints can one get good results for some types of shapes. You can not create an API that takes a Shape, a fill and stroke color and do a decent job painting those at some coordinates.
If you (as in Sun) are sincere in your efforts to take on Flash and Silverlight these kinds of rendering issues must be solved IMO. Given your stance as explained above I guess they won't be until it's too late though. 
Cheers, Mikael
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jul 3, 2007 5:38 PM
in response to: mikaelgrev
|
|
|
Hi Mikael,
java2d@javadesktop.org wrote: > I don't know what to say. You go to great length explaining why circles aren't round and why the corner radius on rounded rectangles are different on the different sides, and why you will not fix it. I guess other platforms (Flash, .NET and similar) also have these problems since they aren't fixable?
Actually, I wasn't sure - I just know that the rendering models that we use are fairly industry standard and there are well-known techniques for working around them, some can be implemented as heuristics within the rendering engine (along with a way to turn them off since they aren't always right) and we've done that, and others have to be implemented as "care in how one constructs rendering requests".
I know that we've exercised about as much "magic" as we know how to exercise internally here in the implementation in the heuristics we created for path normalization, but I believe there could be more "magic", it just isn't something we have sitting in our back pocket and it can't be summoned up on command like a "bug fix" normally can. This isn't a case of "whoops, we forgot to increment that variable" or "we should probably keep more bits of resolution here", this is a limitation of how advanced a set of heuristics we know how to create.
And, like I said, I wasn't totally sure about Flash - but I went and downloaded it and played around with it for a few hours and discovered that, basically, they use a rendering model that is fairly close to what we've implemented - very close to the industry standard. If you render small circles with Flash you get fuzzy outlines on the circles. If you enable their form of "stroke hinting" then you get lopsided un-round (but still fuzzy) circles. At least in our case I believe the circles tend to be crisp (or at least our heuristics try to keep them crisp) even though they are lop-sided. The "hinted" circles I saw with Flash were neither crisp nor were they round.
I then tried a few more experiments and found that many of the issues that people complain about with respect to Java2D rendering are exactly the behaviors that Flash produces (and they have some problems that we don't as well).
I haven't done the same experiment with .NET, but in either case - if you have output from some other rendering engine that does what you want then please share a real-world example, rather than "guessing" about the other platforms.
> It turns out that it is too hard to do Java2D graphics in a high fidelity way, at least without resorting to hacks.
And are you sure that it is possible with other systems? I'd like to see some examples.
> Another problem I have is that one can not in Java2D in a generic way outline and fill a Shape and make it look good. The outline will plot outside and inside the shape depending on the direction of the vector (in degrees). This is since you don't provide an INSIDE and OUTSIDE stroke. You have the hanging right/left stroke and the pure stroke.
Flash provides a very similar rendering model. When you draw 1 pixel wide strokes at 1:1 scales you get the same "hanging pen" strokes that we render.
> The pure stroke isn't usable since you either get the lines sharing two pixels for vertical and horizontal lines or you do as you suggest and translate 0.5, in which case you get good lines but shapes that are one pixel too big.
You get the "one pixel too big" problem with Flash too. The stroke follows the outline and straddles the path - therefore the stroked version will always be "linewidth" larger than the filled stroke.
> One CAN solve the one-pixel-too-big-shapes-when-using-PURE-and-translate.5-problem by scaling the output with ((width - 1.0)/width) but that only works for rectangles (shapes with equal but mirrored quadrants actually, so also for circles) but fails for general paths, polygons and composite shapes of all kinds.
Scaling the output isn't a very general solution and can be tricky to get right with oblong shapes - even if they are convex - as you say.
Other techniques for handling stroking involve things like:
- stroke then fill (even widths == symmetric border) (odd widths and STROKE_NORMAL == uneven border) (odd widths and PURE == fuzzy symmetric border in AA) - fill then stroke (misalignment of stroke at odd sizes is hidden behind the stroke) - use linewidth=2x and stroke then fill (gives a 1 pixel "outer/halo stroke", but needs a fill to carve out the stroke) - use linewidth=2x and compute [strokeShape SUB Shape] (gives a 1 pixel "outer stroke shape") - use linewidth=2x and intersect strokeShape and Shape (gives a 1 pixel "inner stroke shape")
> This problem has shown to unsolvable in a generic way. Only if one has prior knowledge about what type of shape to paint and are in full control of the rendering hints can one get good results for some types of shapes. You can not create an API that takes a Shape, a fill and stroke color and do a decent job painting those at some coordinates.
This is exactly why it is hard to come up with a heuristic that we can implement for you. It seems that you understand the complexity of the problem, but somehow perceive that what is "unsolvable" for you is "just a bug fix" for us. I'm sorry to say that it isn't true. When you use the PURE stroke hint you are getting the mathematically ideal rendering and if it doesn't hit the pixels you want then change the geometry you are using. You'd have to do this with most rendering systems - professional or free - that I am familiar with.
Problems like these have appeared with tools like Illustrator for a long time and the community has built up "strategies" and "techniques" for creating artwork that agrees with the rendering models. The "hinting" heuristics help in some common cases so that most programmers/designers don't have to get involved in these strategies, but eventually everyone outgrows the heuristics and needs more control.
> If you (as in Sun) are sincere in your efforts to take on Flash and Silverlight these kinds of rendering issues must be solved IMO. Given your stance as explained above I guess they won't be until it's too late though. 
We are sincere. You seem to feel that we lag Flash, but it seems to use the same rendering model that we do so I'm not sure how we are lagging there...? Do you have specific issues and examples?
...jim
=========================================================================== To unsubscribe, send email to listserv@java.sun.com and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to listserv@java.sun.com and include in the body of the message "help".
|
|
|
|
|
|
|
|
Re: [JAVA2D] Java2D anti alias rounded corner fidelity problems
Posted:
Jul 4, 2007 6:36 AM
in response to: Jim Graham
|
|
|
Thanks for you great answer Jim!
My frustration comes from creating a middle layer API (a Component structure with advanced shape construction and painting). When I create end user things I haven't generally got any problems with these kind of things, as I can compensate on an issue for issue basis. It's just when I try to guarantee a certain quality of the visuals of my API that I do get these problems.
As you rightfully point out your implementation isn't flawed or buggy when looking at the details. Yet, looking at the specification above the details (the API contract), a circle should be round and a drawn box should be the same size as a filled box. At least IMO. One could say that we are both right, but on different levels.
Would it be possible to have a new STROKE_INSIDE (and possibly STROKE_OUTSIDE)? This is how you can specify the stroke in for instance Photoshop. That would solve everything in a good way.
How much work would it be to implement that kind of stroke? Does OpenGL and DirectDraw have these kind of strokes or would you have to punt to the Java software rendering pipeline if you implemented such a stroke?
Also, would it be much trouble to expose a setting of contrast for anti aliased draws just like you do for LCD text? That way it would be possible to tweak hi fidelity graphics creation in a quite important way (again, IMO).
Note that my intention here is just to get as good rendering with Java2D as possible. I think Java2D is a tremendous API and as I've heard better than any of the competing APIs out there. That doesn't mean that one should try to make it even better since the other APIs are doing their best to catch up! 
Cheers,
|
|
|
|
|
|
|
|
Question about recommended render loop for BufferStrategy...
Posted:
Jul 9, 2007 8:23 PM
in response to: mikaelgrev
|
|
|
According to the documentation on: http://java.sun.com/javase/6/docs/api/java/awt/image/BufferStrategy.html
One is supposed to do { Graphics graphics = strategy.getDrawGraphics(); //render here graphics.dispose(); } while (strategy.contentsRestored());
So I did that where I render: do { do { bg = (Graphics2D)bs.getDrawGraphics(); mis.newPixels(pixels, cm, 0, thisW); bg.drawImage(canvasImage, 0, 0, thisW, thisH, this); drawAttribution(); bg.dispose(); } while (bs.contentsRestored()); bs.show(); } while (bs.contentsLost());
So I'm disposing of bg -- the BufferStrategy graphics after I render.
The question is -- how come I can still use the buffer graphics (bg) at other times to draw stuff. My applet draws onto the BufferStrategy (bs) in many other places at various times. And it works and all the while I have dispose()'ed of the buffergraphics (bg) and the loop above is the only place I getDrawGraphics();
For example -- here's my paint() method -- no problem -- no drawGraphics.
public void paint(Graphics g) { //System.err.println("paint()"); bg.drawImage(canvasImage, 0, 0, thisW, thisH, this); if(DRAWATT) drawAttribution(); bs.show(); }
I don't understand that...
Ken
=========================================================================== To unsubscribe, send email to listserv@java.sun.com and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to listserv@java.sun.com and include in the body of the message "help".
|
|
|
|
|
|
|
|
Re: [JAVA2D] Question about recommended render loop for BufferStrategy...
Posted:
Jul 9, 2007 9:32 PM
in response to: Ken Warner
|
|
|
Hi Ken,
first of all, rendering to the same graphics context from multiple thread is not a good idea. Java2D does not guarantee thread safety, and doing so could lead to unpredictable results (and even crashes due to bugs in our code). So, please don't do that.
As to your question why it "works" - you just got lucky and the paint on EDT executed while another thread was in between the getDrawGraphics() and dispose().
After the dispose() all rendering operations to a graphics context become no-ops, so by definition you would only see something rendered the paint event happened to be while the graphics was still valid.
Thank you, Dmitri Java2D Team
Ken Warner wrote: > According to the documentation on: > http://java.sun.com/javase/6/docs/api/java/awt/image/BufferStrategy.html > > One is supposed to > do { > Graphics graphics = strategy.getDrawGraphics(); > //render here > graphics.dispose(); > } while (strategy.contentsRestored()); > > So I did that where I render: > do { > do { > bg = (Graphics2D)bs.getDrawGraphics(); > mis.newPixels(pixels, cm, 0, thisW); > bg.drawImage(canvasImage, 0, 0, thisW, thisH, this); > drawAttribution(); > bg.dispose(); > } while (bs.contentsRestored()); > bs.show(); > } while (bs.contentsLost()); > > So I'm disposing of bg -- the BufferStrategy graphics after I render. > > The question is -- how come I can still use the buffer graphics (bg) > at other times to draw stuff. My applet draws onto the BufferStrategy (bs) > in many other places at various times. And it works and all the while > I have dispose()'ed of the buffergraphics (bg) and the loop above is the > only > place I getDrawGraphics(); > > For example -- here's my paint() method -- no problem -- no drawGraphics. > > public void paint(Graphics g) > { > //System.err.println("paint()"); > bg.drawImage(canvasImage, 0, 0, thisW, thisH, this); > if(DRAWATT) > drawAttribution(); > bs.show(); > } > > I don't understand that... > > Ken > > =========================================================================== > To unsubscribe, send email to listserv@java.sun.com and include in the body > of the message "signoff JAVA2D-INTEREST". For general help, send email to > listserv@java.sun.com and include in the body of the message "help".
=========================================================================== To unsubscribe, send email to listserv@java.sun.com and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to listserv@java.sun.com and include in the body of the message "help".
|
|
|
|
|
|
|
|
Re: Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 9:06 AM
in response to: mikaelgrev
|
|
|
I thought that all those screenshots were done by a professional design company, and Jasper's task is to "translate" these into Java2D. Wouldn't this mean that the corners you are pointing were not implemented with Java2D (at least in the design screenshots)?
|
|
|
|
|
|
|
|
Re: Java2D anti alias rounded corner fidelity problems
Posted:
Jun 29, 2007 12:19 PM
in response to: kirillcool
|
|
|
You are correct. I thought the process was already completed and this was the Java2D version (which looks similar). Since Java2D does the same as Photoshop I guess one can't really complain. I just thought that since one can set the contrast on LCD AA text that maybe one could do the same for normal AA.
I think the corners look "too fat" (IMO) because the gray scale isn't linear when viewed but treated like that when calculated. new Color(128, 128, 128) isn't viewed by the brain as half way between white and black (it looks darker). Having the AA rasterizer compensate for this could be very costly I guess.
Cheers, Mikael
|
|
|
|
|