Skip to main content

What could be preventing sub-pixel antialiasing for text?

13 replies [Last post]
qu0ll
Offline
Joined: 2006-12-09

I am trying to modify a local copy of the Batik framework to make it use sub-pixel antialiasing for text rendering but I cannot get it to work as something seems to be "blocking" it. In a draw() method where the text is actually rendered I have rewritten it just for debugging to setup sub-pixel antialiasing and render some arbitrary text but the text is rendered using a standard greyscale antialiasing. The exact same code produces true sub-pixel antialiasing when run in a separate program.

So, what could be preventing the text from being rendered with true sub-pixel antialiasing? Is there something in the Graphics2D object that might be set that would cause this? Could some form of double buffering be causing this?

This is the code I am using:

<br />
graphics2D.setPaint(new Color(0, 0, 0));<br />
graphics2D.setTransform(new AffineTransform());<br />
graphics2D.setFont(new Font("Segoe UI", Font.PLAIN, 13));<br />
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);<br />
graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);<br />
graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, 120);<br />
graphics2D.drawString("Some test text", 20, 20);<br />

As I said, if I run this code in a separate stand-alone program then the text is rendered properly.

I am using Java 6 Update 10 on Windows Vista.

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
trembovetski
Offline
Joined: 2003-12-31

It depends. What java version are you running?

There are certain conditions under which grayscale aa will be used.
Check out method 'canRenderLCDText':
http://hg.openjdk.java.net/jdk7/2d/jdk/file/9cdababf6179/src/share/class...

In 1.7 and 6u12 these conditions would be
- if your destination has alpha
- if your color has alpha (it doesn't seem to be), or if you have "extra alpha" compositing mode set
- if you have a non-trivial clip

If you're rendering on windows into a volatile image and you have the d3d pipeline enabled, the conditions are slightly different (non-rect clip is allowed).
http://hg.openjdk.java.net/jdk7/2d/jdk/file/9cdababf6179/src/windows/cla...

Dmitri

qu0ll
Offline
Joined: 2006-12-09

Hi Dmitri,

I have tried with JSE 6 Update 10 and JSE 7 b38 with the same results.

Well, the color certainly doesn't have alpha set and I've tried setting the clip to a trivial rectangle but the result is the same. So, from what you have said, this must mean that the destination has alpha set. But the destination's alpha setting is determined by the Graphics2D object isn't it? How can I turn off the alpha in the destination to try it out?

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

trembovetski
Offline
Joined: 2003-12-31

Where does that graphics object come from? Basically, where are you rendering to? If it's Swing back buffer it definitely should be opaque.

Could you post a complete test case reproducing the issue?

Dmitri

qu0ll
Offline
Joined: 2006-12-09

Dmitri,

I am not sure what you mean by "test case" here. As I said, the exact same code works fine in isolation and only fails when used in this context within the Batik framework. Therefore, to provide a test case I would need to provide the entire Batik framework or you won't be able to reproduce the problem.

Is that what you require?

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

trembovetski
Offline
Joined: 2003-12-31

ok. Then run your code with -Dsun.java2d.trace=log and collect the output. It may tell us the type of destination surface.

It helps if you add some printlns at somewhere close your text rendering code so that we know where in the log to look for it.

Dmitri

qu0ll
Offline
Joined: 2006-12-09

Hi Dmitri,

What's the best address to send the output to? I tried what I thought was a logical choice for your Sun email address but it failed. You can reply privately if you prefer.

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

qu0ll
Offline
Joined: 2006-12-09

Nevermind, I had a typo in your surname... you should have the output log now.

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

qu0ll
Offline
Joined: 2006-12-09

I can report that Dmitri analysed the trace log and discovered that the reason for the text not being rendered with sub-pixel antialiasing was that the image buffer being rendered to was not opaque. Apparently LCD antialiasing only works on opaque surfaces.

Thanks for your time Dmitri.

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

trembovetski
Offline
Joined: 2003-12-31

Actually, I'm still not convinced that the destination is the problem. You see, in 6u10 we didn't have that 'disable if destination is translucent' check, it was only added in 7 and 6u11, so in theory it should still use lcd loops in 6u10.

Another possibility is the color you render with - make sure it doesn't have alpha, and the compositing mode is set to SrcOver.

As for the non-opaque destination, a possible work around I mentioned would be to render the text into an opaque image filled with background, and copy that image into the destination. That only works if you know the background color, of course.

Also, for the record, we will be improving the LCD loops to overcome this and perhaps other limiatations, see this bug:
6749069: LCD text loops should support non-opaque destination (and possibly other compositing modes)

Dmitri

trembovetski
Offline
Joined: 2003-12-31

And yet another factor is the clip. Print out the clip shape that you have set. If it's not a simple rect clip we'll switch to non-lcd aa as well.

Dmitri

qu0ll
Offline
Joined: 2006-12-09

Dmitri,

I appreciate your input but none of those additional factors apply in this case. The problem definitely appears to be that the BufferedImage that's being rendered into was created using a ColorModel with alpha values. This is by design in Batik.

I am currently working on some modifications to Batik that will enable the use of opaque BufferedImages in special cases but this is not a trivial task in the context of the complexities of the code.

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]

trembovetski
Offline
Joined: 2003-12-31

> The problem definitely appears to be that the BufferedImage that's being rendered into was created using a ColorModel with alpha values.

I can't see how that can be given that the check for non-opaque destination is not there in 6u10.

Could you run this test on your system:
http://hg.openjdk.java.net/jdk7/2d/jdk/raw-file/3bc4d79d8123/test/sun/ja...

And post a screen shot (in uncompressed png please).

Dmitri

qu0ll
Offline
Joined: 2006-12-09

I have run the test and sent you the output.

--
And loving it,

-Qu0ll (Rare, not extinct)
_________________________________________________
Qu0llSixFour@gmail.com
[Replace the "SixFour" with numbers to email me]