[cc'ing to j2d]
On 12.12.2013 1:54, Jim Graham wrote:
On 12/11/13 5:13 AM, Anton V. Tarasov wrote:
On 11.12.2013 13:14, Jim Graham wrote:
With the new support for scaled BufferedImages we now have a situation
where some images return their logical dimensions from
getWidth/Height(null) and some return physical dimensions. That's a
little dicey as the method now has two meanings depending on how the
images were created. We're sort of between a rock and a hard place in
that BufferedImage objects have a historical context for how their
values relate to the pixels you can access, but we also have a
relationship between how the return values of
getWidth/Height(observer) relate to the size the image is drawn on the
screen. Is this only ever done for the backing store objects? Do we
ever expose them to developers?
Well, this is the question I was waiting for... The methods
getWidth/Height will continue to return the physical size of an image,
regardless of was it scaled or not. However, for a scaled image the
physical size, and so the returned values will be auto-scaled. This is
applicable to the following "factory" methods I've overriden:
1) BufferedImageGraphicsConfig.createCompatibleImage(...)
2) CGLGraphicsConfig.createCompatibleImage(...)
3) LWLightweightFramePeer.createImage(...)
The 1st depend on the scale factor of the GC instance the method is
called on. The scale factor of BufferedImageGraphicsConfig is taken from
the BI instance passed to its ctor. So, this won't affect any third
party code, as the BI.scale field has a private access.
The 2nd depend on the scale factor of the device, which is set either by
the platform or by me (in case when I set it to the default device in
CPlatformLWView.java). So, theoretically it is possible for a user to
call this method on a Retina display and get a scaled image.
We are subtly changing the meaning of createCompatibleImage() in both of those circumstances.
It's hard to understand the impact of that subtle change. It looks like this fix is targeted at
JDK9 so we have time to vet it, but my initial gut feel on this is that we are going to confuse
some developers here unless we create a special "createCompatibleImage()" method variant (with
perhaps a different name) that specifically requests an image with an appropriate scale. If we
are then going to service those requests with BufferedImage return values then we add an
additional issue in that we have conflicting needs for the various methods on BI in that case.
I rather agree with you. Another problem is that we need a solution for jdk8u20
as well...
The 3rd depend on the scale factor taken from the JLightweightFrame
instance. This affects only the code run inside the JLF, however a user
is able to call this method (on any of a component from the JLF's
hierarchy) and get a scaled image.
So, we have situations when a user might create a BufferedImage with w*h
Are they specifically creating a BufferedImage, or an Image that happens to be an instance of BI
in most current cases?
Component.createImage(..) is currently used by Swing in only two cases: as a double buffer factory
method (by JViewport and RepaintManager). The javadoc for the method says just that: "an Image for
double buffering". I don't know if this method is used by a third party code... Still, it is public.
GraphicsConfiguration.createCompatibleImage(..) returns BufferedImage. It's used 1) as a fallback
for a createCompatibleVolatileImage when acceleration is not supported 2) directly from a number of
places: d&d, custom cursor, tray icon, printing, 2/3 more minor cases.
Again, I don't know what's the rating of these methods among developers...
size but get back an image with w*h*4 size (on a Retina display). And
this might be unexpected. However, this image will produce a "context"
with the same scale factor. A BufferedImageGraphicsConfig will be
created with the same scale (see its ctor), a BufImgSurfaceData will be
created with the same scale (see its getDefaultScale() method), and a
SunGraphics2D will be created with the same scale ("devScale =
sd.getDefaultScale();" in its ctor). In this case, all drawings into the
image will take the scale into account, and should be correct. The only
concern is the size of the image itself. At least, this is not
documented...
My big worry here is that we currently have 2 consumers of BI.getWidth(null) - one group that
expects the answer to relate to layout, and another that expects the answer to relate to pixel
access.
Here is where someone dons their "genius hat" and comes up with a creative solution that works for
both groups. Mine is unfortunately at the cleaners right now and they don't know when they'll
have it done... :(
But, I feel there is a good common ground to be found there once we wrap our heads around the
problem the right way (and with the right "genius hat"). Also, perhaps we need to engage the
2d-dev list as well here, since the results will affect them as well?
Well, let's find that right way :)
Thanks,
Anton.
...jim