<AWT Dev> [OpenJDK 2D-Dev] Review request for 8029339 Custom MultiResolution image support on HiDPI displays
Alexander Scherbatiy
alexandr.scherbatiy at oracle.com
Tue Jul 21 14:41:38 UTC 2015
Hello Jim,
Thank your for the review.
Could you review the updated fix there the suggested comments are updated:
http://cr.openjdk.java.net/~alexsch/8029339/webrev.09/
On 7/14/2015 2:36 AM, Jim Graham wrote:
> Hi Alexandr,
>
> Sorry that this fell into the cracks. Here are some fairly minor
> updates:
>
> AbstractMRI - getGraphics() should include "getGraphics() not
> supported on Multi-Resolution Images" as the exception description text.
>
> AbstractMRI - getBaseImage() should have doc comments:
> /**
> * Return the base image representing the best version of the image
> * for rendering at the default width and height.
> * @return the base image of the set of multi-resolution images
> */
> (Does it need an @since given that the entire interface is @since 1.9?)
>
> BaseMRI - the doc comments (both the class comment and the constructor
> comments) don't start with "/**" so they aren't really doc comments,
> but they look good so make them so.
>
> BaseMRI - class comment - "The implementation will return the first
> ... satisfy the rendering request." Add another sentence right there
> "The last image in the array will be returned if no suitable image is
> found that is larger than the rendering request."
>
> BaseMRI - move "For best effect ..." should be moved to a new
> paragraph and mention that no exception will be thrown if the images
> are not sorted as suggested.
>
> RenderingHints - comments:
> DEFAULT, SIZE_FIT, DPI_FIT - "an image resolution variant is chosen
> ..." (add "an")
> DEFAULT - "... which may depend on the policies of the platform"
> SIZE_FIT, DPI_FIT "... on the DPI of ..." (add "the")
>
> SunHints - descriptor texts:
> SIZE_FIT, DPI_FIT "based on the DPI" (add "the")
>
> MRCachedImage - remind me what this is used for?
It is used by AquaLookAndFeel for images and icons rendering
requested from the native system.
> MRCachedImage.getResolutionVariant - use ceil or round instead of
> (int) cast? ceil() would match the actions of MRToolkitImage better.
> Also note following comment about precision with SG2D.
>
> SG2D/MRI - the interface declares the values as float, the usage in
> SG2D computes values in double and then truncates them to int to pass
> to the interface - should we upgrade the interface to double for
> completeness? If not, then the usage in SG2D should at least pass in
> float precision.
I changed the argument types to double in the
MRI.getResolutionVariant(...).
>
> SG2D.getResolutionVariant - using destRegionWH to calculate
> destImageWH can involve a lot of "do some math and then later have
> additional code undo it". Would it be faster to just compute
> destImageWH directly, as in:
>
> float destImageWidth, destImageHeight;
>
> if (BASE) {
> destImageWH = srcWH;
> } else if (DPI) {
> destImageWH = (float) abs(srcWH * devScale);
> } else {
> double destRegionWidth, destRegionHeight;
> if (type) {
> ...
> }
> destImageWH = (float) abs(srcWH * destRegionWH / swh);
> }
> Image rv = img.getRV(destImageWH);
>
> On the other hand, the last "else" is probably the most common case so
> this doesn't save anything in the common case, but it avoids a bunch
> of math that could introduce rounding error for the BASE/DPI cases
> (even though it is done in doubles).
>
> Is there intent to have the default case be mapped to DPI_FIT for
> Windows?
I think yes.
>
> MultiResolutionRenderinHints.java - should have "Test" appended to the
> name
>
> MRRHTest - why not render to a BufferedImage and avoid Robot? Could it
> tap into internal APIs to create a BImg/compatibleImage with a given
> devScale?
The DPI_FIT test includes case there a graphics transform is
identity but the device configuration transform has scale 2.
There should be a way to set scale for the device configuration
transform;
>
> MRRHTest - why allow up to delta=50 on the comparison?
It is just for monitors that are calibrated on Mac OS X and they
colors are different from that which was set. The test uses colors which
have at least one color component differ by 255.
>
> MRRHTest - since the scale factor comes from a dialog, we depend on
> running this on a HiDPI display to fully test the hints? Could using
> "scaled compatible images" allow testing this more definitively?
Could you explain more what does it mean "scaled compatible images"?
Thanks,
Alexandr.
>
> MRRHTest - remove println before pushing?
>
> MRRHTest - probably shouldn't have a "right answer" for DEFAULT - it
> should probably just pass if the operation doesn't throw an exception?
>
> ...jim
>
>
> On 4/15/15 7:04 AM, Alexander Scherbatiy wrote:
>>
>> Hello,
>>
>> Could you review the updated fix:
>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.08/
>>
>> - SunGraphics2D is updated to calculate the resolution variant size
>> according to the _BASE, _DPI_FIT, and _SIZE_FIT resolution rendering
>> hint
>> - MultiResolutionRenderingHints test is added
>>
>> Thanks,
>> Alexandr.
>>
>>
>> On 4/7/2015 1:02 PM, Jim Graham wrote:
>>> This is an interesting suggestion that would let us keep the
>>> implementation of the various hints centralized and simplify the
>>> interface to the part of the mechanism that is most tied in to the
>>> implementation specifics of the database of media variants - which is
>>> housed in the MRI-implementing object.
>>>
>>> I'm not sure we ever identified any need to customize the logic of
>>> "what size is needed for this render operation" beyond what we
>>> expressed in the hints, and given that the platform defaults may not
>>> be easy to express to an arbitrary implementation, it is probably
>>> better to put that part of the logic in SG2D, controlled by the easy
>>> to express hints and keep the current API both simple to implement and
>>> flexible to use. Even if there was a need to customize that part of
>>> the operation (the "what size is relevant to this rendering operation"
>>> decision) beyond what the hints suggest, it would be inappropriate to
>>> tie that in to the "find me media" aspect of the MRI interface
>>> anyway. So, best to keep them separate and have the hints affect what
>>> SG2D does and have the MRI focused on just storing (possibly creating)
>>> and managing/finding the variants.
>>>
>>> ...jim
>>>
>>> On 4/1/15 6:46 AM, Alexander Scherbatiy wrote:
>>>> On 3/27/2015 12:48 AM, Jim Graham wrote:
>>>>> Hi Alexander,
>>>>
>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.07/
>>>> I have updated the fix according to the comments except
>>>> RenderingHints.
>>>>
>>>> RenderingHints are supposed to be set on Graphics2D and they have
>>>> keys/values which are not relevant to the getResolutionVariant()
>>>> method.
>>>> Graphics objects chooses an alternative according to the set
>>>> rendering hints.
>>>> May be what SG2D should do just calculate dest image size for the
>>>> given resolution variant hint (_BASE - base image size, _SIZE_FIT -
>>>> including scale factor and graphics transform (Mac algorithm),
>>>> _DPI_FIT - scaled according to the system DPI) and then pass them to
>>>> the getResolutionVariant() method?
>>>>
>>>> Thanks,
>>>> Alexandr.
>>>>
>>>>>
>>>>> MRI.java:
>>>>>
>>>>> Who is the intended audience for the recommendation in the interface
>>>>> to cache image variants? Are we asking the developers who call the
>>>>> methods on the interface to cache the answers? That would be unwise
>>>>> because the list of variants may change over time for some MRIs. Are
>>>>> we speaking to the implementer? If so, then I think that it is
>>>>> unnecessary to remind implementers of basic implementation
>>>>> strategies like "cache complicated objects".
>>>>>
>>>>> How about this wording for the getRV() method? - "Gets a specific
>>>>> image that is the best variant to represent this logical image at
>>>>> the indicated size and screen resolution."
>>>>>
>>>>> Perhaps we should clarify in the doc comments for the dimension
>>>>> arguments in getRV() that the dimensions are measured in pixels?
>>>>>
>>>>> line 56 - delete blank line between doc comment and method
>>>>> declaration
>>>>>
>>>>> Also, it is probably overkill to document that the interface
>>>>> getVariants() method returns an unmodifiable list. Responsible
>>>>> implementations would probably use an unmodifiable list, but I don't
>>>>> think it should be required by the interface. We do need to specify
>>>>> that it isn't required to be modifiable so that a caller doesn't
>>>>> expect to be able to modify it, but that is a looser spec. How
>>>>> about "Gets a readable list of all resolution variants. Note that
>>>>> many implementations might return an unmodifiable list."?
>>>>>
>>>>> AbstractMIR.java:
>>>>>
>>>>> "provides a default implementation for the MRI" or "provides default
>>>>> implementations of several methods in the <MRI> interface and the
>>>>> <Image> class"? Actually, I'll note that it provides none of the
>>>>> implementations of the MRI methods so maybe it should be "provides
>>>>> default implementations of several <Image> methods for classes that
>>>>> want to implement the <MRI> interface"?
>>>>>
>>>>> In the doc example - wrap the list to make it unmodifiable
>>>>>
>>>>> The doc example could be made 2 or 3 lines shorter by simply
>>>>> assuming the base image is in index 0 (it's just an example so I'm
>>>>> not sure the flexibility needs to be a part of the example).
>>>>>
>>>>> getGraphics is allowed by the Image interface to return null.
>>>>> Actually, the exact wording is that it can only be called for
>>>>> "offscreen images" and a MRI is technically not "an offscreen
>>>>> image". Perhaps we should return null here since modifying the base
>>>>> image is unlikely to modify the variants and arguably it would be
>>>>> required by the wording in the method docs (even if the base image
>>>>> was an offscreen, the MRI produced from it stops being an offscreen)?
>>>>>
>>>>> Are all of the empty "@Inherit" comments needed? I thought
>>>>> inheritance was the default?
>>>>>
>>>>> BaseMRI.java:
>>>>>
>>>>> "This class is [an] array-based implementation of the {AMRI} class"
>>>>> (missing "an" and "the")
>>>>>
>>>>> We should probably include the comment about the sorting of the
>>>>> images in the class comments as well as document that the algorithm
>>>>> is a simple scan from the beginning for the first image large enough
>>>>> (and default == last image). The algorithm also might not work very
>>>>> well if the images are not monotonically both wider and taller. How
>>>>> about adding this to the class comments:
>>>>>
>>>>> "The implementation will return the first image variant in the array
>>>>> that is large enough to satisfy the rendering request. For best
>>>>> effect the array of images should be sorted with each image being
>>>>> both wider and taller than the previous image. The base image need
>>>>> not be the first image in the array."
>>>>>
>>>>> getVariants() - you need to return an unmodifiable list. asList()
>>>>> returns a list that "writes back" to the array. You need to use
>>>>> Collections.unmodifiableList(Arrays.asList(array)).
>>>>>
>>>>> RenderingHints.java:
>>>>>
>>>>> Where do we process this hint? Don't we need to pass it to the
>>>>> getVariant() method?
>>>>>
>>>>> I don't understand the hint values other than the one that always
>>>>> uses the base image. Default I guess gives us the ability to use
>>>>> the Mac algorithm of "next larger size" on Mac and "based on Screen
>>>>> DPI" on Windows, but the 3rd value "ON" is so vague as to not have
>>>>> any meaning. Perhaps we should just delete it, but then do we just
>>>>> always do the Mac method? Or do we vaguely have our internal images
>>>>> have a platform-specific method and the Abstract/Base classes just
>>>>> do what they want with no control from the user? In FX we are also
>>>>> still struggling with this issue and we may likely just do what the
>>>>> Mac does in all cases, but perhaps AWT needs to "behave like the
>>>>> platform" more? If we are going to have actual values, then we need
>>>>> to have them do something, which means:
>>>>>
>>>>> - SG2D needs to track the hint just like we do the other hints that
>>>>> affect our processing
>>>>> - MRI.getVariant() needs to have the hint as an argument
>>>>> - BaseMRI should probably do something with that hint
>>>>> - hint values should include:
>>>>> - ..._DEFAULT - implementation gets to decide
>>>>> - ..._BASE - always use the base image
>>>>> - ..._SIZE_FIT - Mac algorithm of smallest image that is big
>>>>> enough
>>>>> - ..._DPI_FIT - choose based on DPI of the screen, ignoring
>>>>> transform
>>>>>
>>>>> line 978 - missing blank line between fields
>>>>>
>>>>> SG2D.java:
>>>>>
>>>>> - The interface says that you will be passing in the "logical DPI"
>>>>> of the display, but here you are actually passing in the screen's
>>>>> scale factor.
>>>>>
>>>>> BaseMRITest.java:
>>>>>
>>>>> - testBaseMRI also passes in a scale rather than a DPI to the MRI
>>>>> method.
>>>>>
>>>>> - How does the modification test pass when the implementation
>>>>> doesn't use unmodifiable lists?
>>>>>
>>>>> MRITest.java:
>>>>>
>>>>> - also uses scale rather than DPI in several places
>>>>>
>>>>> ...jim
>>>>>
>>>>> On 3/13/15 6:34 AM, Alexander Scherbatiy wrote:
>>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> Could you review the proposed API based on MultiresolutionImage
>>>>>> interface:
>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.06/
>>>>>>
>>>>>> - return unmodifiable list comment is added to the
>>>>>> getResolutionVariants() method javadoc in MultiresolutionImage
>>>>>> interface
>>>>>> - base image size arguments are removed form the
>>>>>> getResolutionVariant(...) method in MultiresolutionImage interface
>>>>>> - BaseMultiResolutionImage class that allows to create a
>>>>>> multi-resolution image based on resolution variant array is added
>>>>>> - the test for the BaseMultiResolutionImage is added
>>>>>>
>>>>>> Thanks,
>>>>>> Alexandr.
>>>>>>
>>>>>> On 2/14/2015 3:23 AM, Jim Graham wrote:
>>>>>>> The second solution looks good. I'd make it standard practice
>>>>>>> (perhaps even mentioned in the documentation) to return
>>>>>>> unmodifiable
>>>>>>> lists from the getVariants() method. The Collections class
>>>>>>> provides
>>>>>>> easy methods to create these lists, and it sends a clear message to
>>>>>>> the caller that the list was provided for them to read, but not
>>>>>>> write
>>>>>>> to. Otherwise they may add a new image to the list you provided
>>>>>>> them
>>>>>>> and wonder why it wasn't showing up. Also, an unmodifiable list
>>>>>>> can
>>>>>>> be cached and reused for subsequent calls without having to
>>>>>>> create a
>>>>>>> new list every time.
>>>>>>>
>>>>>>> In getResolutionVariant() was there a reason why the base
>>>>>>> dimensions
>>>>>>> were provided as float? The destination dimensions make sense as
>>>>>>> float since they could be the result of a scale, but the source
>>>>>>> dimensions are typically getWidth/getHeight() on the base image. A
>>>>>>> related question would be if they are needed at all, since the
>>>>>>> implementation should probably already be aware of what the base
>>>>>>> image
>>>>>>> is and what its dimensions are. I'm guessing they are provided
>>>>>>> because the implementation in SG2D already knows them and it
>>>>>>> makes it
>>>>>>> easier to forward the implementation on to a shared (static?)
>>>>>>> method?
>>>>>>>
>>>>>>> With respect to default implementations, I take it that the
>>>>>>> BaseMRI is
>>>>>>> along the pattern that we see in Swing for Base classes. Would
>>>>>>> it be
>>>>>>> helpful to provide an implementation (in addition or instead) that
>>>>>>> allows a developer to take a bunch of images and quickly make an
>>>>>>> MRI
>>>>>>> without having to override anything? The implementations of
>>>>>>> getBaseImage() and getResolutionVariants() are pretty
>>>>>>> straightforward
>>>>>>> and a fairly reasonable default algorithm can be provided for
>>>>>>> getRV(dimensions). This question is more of an idle question
>>>>>>> for my
>>>>>>> own curiosity than a stumbling block...
>>>>>>>
>>>>>>> ...jim
>>>>>>>
>>>>>>> On 1/22/2015 6:49 AM, Alexander Scherbatiy wrote:
>>>>>>>>
>>>>>>>> Hi Phil,
>>>>>>>>
>>>>>>>> I have prepared two versions of the proposed API:
>>>>>>>>
>>>>>>>> I) Resolution variants are added directly to the Image:
>>>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/list/webrev.00
>>>>>>>>
>>>>>>>> II) MultiResolutionImage interface is used:
>>>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.05
>>>>>>>>
>>>>>>>> It could help to decide which way should be chosen for the the
>>>>>>>> multi-resolution image support.
>>>>>>>>
>>>>>>>> Below are some comments:
>>>>>>>>
>>>>>>>> 1. High level goal:
>>>>>>>> Introduce an API that allows to create and handle an image
>>>>>>>> with
>>>>>>>> resolution variants.
>>>>>>>>
>>>>>>>> 2. What is not subject of the provided API
>>>>>>>> - Scale naming convention for high-resolution images
>>>>>>>> - Providing pixel scale factor for the screen/window
>>>>>>>>
>>>>>>>> 3. Use cases
>>>>>>>> 3.1 Loading and drawing high-resolution icons in IntelliJ IDEA
>>>>>>>> A high-resolution image is loaded from resources and
>>>>>>>> stored in
>>>>>>>> JBHiDPIScaledImage class which is a subclass of the buffered
>>>>>>>> image.
>>>>>>>> The high-resolution image is used to create a disabled icon
>>>>>>>> in the
>>>>>>>> IconLoader.getDisabledIcon(icon) method.
>>>>>>>> https://github.com/JetBrains/intellij-community/blob/master/platform/util/src/com/intellij/openapi/util/IconLoader.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 3.2 Loading and drawing high-resolution icons in NetBeans
>>>>>>>> NetBeans does not have support for the high-resolution icons
>>>>>>>> loading.
>>>>>>>> It loads an icon from the file system using
>>>>>>>> Toolkit.getDefaultToolkit().getImage(url) method or from resources
>>>>>>>> by ImageReader and store it in ToolTipImage class which is
>>>>>>>> subclass of the buffered image.
>>>>>>>> ImageUtilities.createDisabledIcon(icon) method creates a
>>>>>>>> disabled
>>>>>>>> icon by applying RGBImageFilter to the icon.
>>>>>>>> http://hg.netbeans.org/main/file/97dcf49eb4a7/openide.util/src/org/openide/util/ImageUtilities.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 3.3 Loading system icons in JDK 1.8
>>>>>>>> JDK requests icons from the native system for system L&Fs
>>>>>>>> and
>>>>>>>> applies filters for them.
>>>>>>>> See for example AquaUtils.generateLightenedImage() method:
>>>>>>>> http://hg.openjdk.java.net/jdk9/client/jdk/file/e6f48c4fad38/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 4. HiDPI support for Images on different OSes
>>>>>>>>
>>>>>>>> 4.1 Mac OS X
>>>>>>>> Cocoa API contains NSImage that allows to work with image
>>>>>>>> representations: add/remove/get all representations.
>>>>>>>> It picks up an image with necessary resolution based on the
>>>>>>>> screen backing store pixel scale factor and applied transforms.
>>>>>>>> https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSImage_Class/Reference/Reference.html
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 4.2 Linux
>>>>>>>> GTK+ 3 API has gtkcssimagescaled lib (it seems that it
>>>>>>>> is not
>>>>>>>> public/stable)
>>>>>>>> that parses the -gtk-scaled css property and draws a
>>>>>>>> GtkCssImage
>>>>>>>> according to the given scale factor.
>>>>>>>>
>>>>>>>> I have not found information about the HiDPI support in
>>>>>>>> Xlib.
>>>>>>>>
>>>>>>>> 4.3 Windows
>>>>>>>> I have only found the tutorial that suggests to select and
>>>>>>>> draw a
>>>>>>>> bitmap using the queried DPI
>>>>>>>> and scale the coordinates for drawing a rectangular frame
>>>>>>>> http://msdn.microsoft.com/en-us/library/dd464659%28v=vs.85%29.aspx
>>>>>>>>
>>>>>>>> Windows also provides the horizontal and vertical DPI of
>>>>>>>> the
>>>>>>>> desktop
>>>>>>>> http://msdn.microsoft.com/en-us/library/windows/apps/dd371316
>>>>>>>>
>>>>>>>> 5. Pseudo API
>>>>>>>> Below are some ways which illustrates how multi-resolution
>>>>>>>> images
>>>>>>>> can be created and used.
>>>>>>>>
>>>>>>>> 5.1 Resolution variants are stored directly in Image class.
>>>>>>>> To query a resolution variant it needs to compare the
>>>>>>>> resolution
>>>>>>>> variant width/height
>>>>>>>> with the requested high-resolution size.
>>>>>>>> ------------
>>>>>>>> public abstract class Image {
>>>>>>>>
>>>>>>>> public void addResolutionVariant(Image image) {...}
>>>>>>>> public List<Image> getResolutionVariants() {...}
>>>>>>>> }
>>>>>>>> ------------
>>>>>>>> // create a disabled image with resolution variants
>>>>>>>>
>>>>>>>> Image disabledImage = getDisabledImage(image);
>>>>>>>>
>>>>>>>> for (Image rv : image.getResolutionVariants()) {
>>>>>>>> disabledImage.addResolutionVariant(getDisabledImage(rv));
>>>>>>>> }
>>>>>>>> ------------
>>>>>>>> This approach requires that all resolution variants have been
>>>>>>>> created even not of them are really used.
>>>>>>>>
>>>>>>>> 5.2 Resolution variants are stored in a separate object that
>>>>>>>> allows to create them by demand.
>>>>>>>> To query a resolution variant it needs to compare the
>>>>>>>> resolution
>>>>>>>> variant scale factor
>>>>>>>> with the requested scale (that can include both screen DPI
>>>>>>>> scale
>>>>>>>> and applied transforms).
>>>>>>>> ------------
>>>>>>>> public abstract class Image {
>>>>>>>>
>>>>>>>> public static interface ResolutionVariant {
>>>>>>>> Image getImage();
>>>>>>>> float getScaleFactor();
>>>>>>>> }
>>>>>>>>
>>>>>>>> public void addResolutionVariant(ResolutionVariant
>>>>>>>> resolutionVariant) {...}
>>>>>>>> public List<ResolutionVariant> getResolutionVariants()
>>>>>>>> {...}
>>>>>>>> }
>>>>>>>> ------------
>>>>>>>> // create a disabled image with resolution variants
>>>>>>>> Image disabledImage = getDisabledImage(image);
>>>>>>>>
>>>>>>>> for (Image.ResolutionVariant rv :
>>>>>>>> image.getResolutionVariants()) {
>>>>>>>> disabledImage.addResolutionVariant(new
>>>>>>>> Image.ResolutionVariant() {
>>>>>>>>
>>>>>>>> public Image getImage() {
>>>>>>>> return getDisabledImage(rv.getImage());
>>>>>>>> }
>>>>>>>>
>>>>>>>> public float getScaleFactor() {
>>>>>>>> return rv.getScaleFactor();
>>>>>>>> }
>>>>>>>> });
>>>>>>>> }
>>>>>>>> ------------
>>>>>>>>
>>>>>>>> It does not have problem if a predefined set of images is
>>>>>>>> provided
>>>>>>>> (like image.png and image at 2x.png on the file system).
>>>>>>>> This does not cover cases where a resolution variant can be
>>>>>>>> created
>>>>>>>> using the exact requested size (like loading icons from the native
>>>>>>>> system).
>>>>>>>> A resolution variant can be queried based on a scale
>>>>>>>> factor and
>>>>>>>> applied transforms.
>>>>>>>>
>>>>>>>> 5.3 The provided example allows to create a resolution
>>>>>>>> variant
>>>>>>>> using the requested high-resolution image size.
>>>>>>>> ------------
>>>>>>>> public interface MultiResolutionImage {
>>>>>>>> Image getResolutionVariant(float width, float height);
>>>>>>>> }
>>>>>>>> ------------
>>>>>>>> // create a multi-resolution image
>>>>>>>> Image mrImage = new AbstractMultiResolutionImage() {
>>>>>>>>
>>>>>>>> public Image getResolutionVariant(float width, float
>>>>>>>> height) {
>>>>>>>> // create and return a resolution variant with
>>>>>>>> exact
>>>>>>>> requested width/height size
>>>>>>>> }
>>>>>>>>
>>>>>>>> protected Image getBaseImage() {
>>>>>>>> return baseImage;
>>>>>>>> }
>>>>>>>> };
>>>>>>>> ------------
>>>>>>>> // create a disabled image with resolution variants
>>>>>>>> Image disabledImage = null;
>>>>>>>> if (image instanceof MultiResolutionImage) {
>>>>>>>> final MultiResolutionImage mrImage =
>>>>>>>> (MultiResolutionImage)
>>>>>>>> image;
>>>>>>>> disabledImage = new AbstractMultiResolutionImage(){
>>>>>>>>
>>>>>>>> public Image getResolutionVariant(float width, float
>>>>>>>> height) {
>>>>>>>> return
>>>>>>>> getDisabledImage(mrImage.getResolutionVariant(width, height));
>>>>>>>> }
>>>>>>>>
>>>>>>>> protected Image getBaseImage() {
>>>>>>>> return getDisabledImage(mrImage);
>>>>>>>> }
>>>>>>>> };
>>>>>>>> } else {
>>>>>>>> disabledImage = getDisabledImage(image);
>>>>>>>> }
>>>>>>>> ------------
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Alexandr.
>>>>>>
>>>>
>>>
>>
More information about the awt-dev
mailing list