<AWT Dev> [OpenJDK 2D-Dev] [9] Review request for 8029339 Custom MultiResolution image support on HiDPI displays

Alexander Scherbatiy alexandr.scherbatiy at oracle.com
Mon May 19 10:46:47 UTC 2014


   Hi Phil,

On 5/16/2014 9:12 PM, Phil Race wrote:
> I think Jim was looking at this. I am not sure if you yet answered all 
> his questions/concerns.
>
> There's a lot of API here and it will take more time than I have right 
> now just to get
> my head around it so do not expect a quick answer.
>
> 1. Why is there no javadoc on the new API on Toolkit ?
   It was decided to split the original issue on two parts:
        - this fix adds only MultiResolutionImage interface and 
AbstractMultiResolutionImage class.
            Here is the webrev for it: 
http://cr.openjdk.java.net/~alexsch/8029339/webrev.05/
       - the Toolkit related API is moved to the separate issue

   Could you review the current fix:
      http://cr.openjdk.java.net/~alexsch/8029339/webrev.05/

> 2. What kinds of classes are expected to implement MultiResolutionImage
> Application ones or platform ones ?
     Both.
     - Application: A developer can provide a set of images with 
different resolutions to create a multi-resolution image. An image with 
best-fitting resolution
         will be drawn on HiDPI display.
     - Platform: we used it to support Aqua L&F on HiDPI displays.

> 3. can you better explain all these parameters :
>
>   49      * @param logicalDPIX the logical horizontal DPI of the desktop.
>   50      * @param logicalDPIY the logical vertical DPI of the desktop.
>   51      * @param baseImageWidth the width of the base image.
>   52      * @param baseImageHeight the height of the base image.
>   53      * @param destImageWidth the width of the destination image.
>   54      * @param destImageHeight the height of the destination image.
>   55      * @return image resolution variant.

     Could we postpone it to the CCC request?

>
> 4.    public List<Image> getResolutionVariants();
>
> So this implies a fixed, known ahead of time set of images ?
> Why is it required to have this API ? How will anyone be able to
> tell which is which and use the list ?

    Here are some usages from the JDK code:
     - AquaImagefactory.getAppIconCompositedOn(final Image background)
        The original multi-resolution image is used to create another 
multi-resolution image with the background
     - AquaUtils.generateLightenedImage(Image image, ImageFilter filter)
       The original multi-resolution image is used to create lightening 
multi-resolution image
     - CImage.createFromImage(final Image image)
         Resolution variants from a multi-resolution image are used to 
create an NSImage
     - CCustomCursor:  it is possible set a custom cursor which contains 
resolution variants to the native system

     Usually the getResolutionVariants() method is used to create one 
multi-resolution image based on the another multi-resolution image.

> 5. Why is the rendering hint needed ?
       Someone can manually switch off the multi-resolution image 
drawing from graphics so only the base image will be drawn.
       It is useful for the performance reason. There is a choice to 
draw the high-resolution image slowly or the low-resolution image faster.

    Thanks,
    Alexandr.
> -phil.
>
>
> On 5/16/2014 9:16 AM, Alexander Scherbatiy wrote:
>>
>>   Hi Phil,
>>
>>   I need a reviewer from the 2d group for the fix. Could you take a 
>> look at the fix and review it?
>>
>>   Thanks,
>>   Alexandr.
>>
>>
>> On 5/12/2014 6:35 PM, Alexander Scherbatiy wrote:
>>>
>>>   There was a long thread about the image with sub-pixel resolution 
>>> drawing  on Mac OS X:
>>> http://mail.openjdk.java.net/pipermail/macosx-port-dev/2013-April/005559.html 
>>>
>>>
>>>  It was pointed out that Icon images that can be programmatically 
>>> generated also need to have HiDPI support:
>>> http://mail.openjdk.java.net/pipermail/macosx-port-dev/2013-April/005566.html 
>>>
>>> http://mail.openjdk.java.net/pipermail/macosx-port-dev/2013-April/005569.html 
>>>
>>>
>>>  All requests about Mac OS X HiDPI support were included to the 
>>> umbrella issue:
>>>    7124410 [macosx] Lion HiDPI support
>>>    https://bugs.openjdk.java.net/browse/JDK-7124410
>>>
>>>  Thanks,
>>>  Alexandr.
>>>
>>> On 4/25/2014 6:45 PM, Alexander Scherbatiy wrote:
>>>> On 4/25/2014 2:17 AM, Jim Graham wrote:
>>>>> Hi Alexandr,
>>>>>
>>>>> I asked for who was requesting these facilities and you responded 
>>>>> with the solution you are planning to provide.
>>>>>
>>>>> I don't care what the solution looks like if we have nobody asking 
>>>>> for the feature - I am asking who is asking for these capabilities?
>>>>
>>>>    This is the request from the AWT team for the HiDPI support.
>>>>
>>>>    Thanks,
>>>>    Alexandr.
>>>>>
>>>>>             ...jim
>>>>>
>>>>> On 4/4/14 4:53 AM, Alexander Scherbatiy wrote:
>>>>>> On 4/3/2014 2:23 AM, Jim Graham wrote:
>>>>>>> Hi Alexandr,
>>>>>>>
>>>>>>> The back and forth is getting confusing here, so I thought I'd 
>>>>>>> try to
>>>>>>> summarize and start fresh(ish):
>>>>>>>
>>>>>>> 1. We need to support @2x internally for MacOS compatibility 
>>>>>>> (done).
>>>>>>>
>>>>>>> 2. We will need to support _DPI images for Win-DPI compatibility 
>>>>>>> (TBD).
>>>>>>>
>>>>>>> 3. Customers may have their own collection of images to bundle
>>>>>>> together into an MR image (working on that here). What is the push
>>>>>>> for this?  Is this simply parity with Mac interfaces?
>>>>>>
>>>>>>          ----------
>>>>>>          Image[] resolutionVariants = // get sorted by sizes 
>>>>>> array of
>>>>>> resolution variants;
>>>>>>          Image mrImage =
>>>>>> Toolkit.getDefaultToolkit().createMRImage(baseImageIndex,
>>>>>> resolutionVariants);
>>>>>>          ----------
>>>>>>
>>>>>>       Here is the proposed patch:
>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.04/
>>>>>>
>>>>>>> 4. Customers may want to synthetically generate images at arbitrary
>>>>>>> resolutions (a variation that is impacting this solution). What is
>>>>>>> the push for this?
>>>>>>          ----------
>>>>>>          Image mrImage =
>>>>>> Toolkit.getDefaultToolkit().createMRImage(baseImageWidth, 
>>>>>> baseImageHeight,
>>>>>>                  new float[][]{{100, 100}, {150, 150}, {200, 
>>>>>> 200}}, //
>>>>>> resolution variants sizes
>>>>>>                  (rvWidth, rvHeight) -> {  /* generate a resolution
>>>>>> variant */  });
>>>>>>         ----------
>>>>>>
>>>>>>>
>>>>>>> 5. I'm guessing that customers might want to override the logic to
>>>>>>> choose from among multiple resolutions.  That came from me based on
>>>>>>> seeing Mac and Win using different selection logic and our 
>>>>>>> history of
>>>>>>> developers split between those wanting cross-platform 
>>>>>>> consistency and
>>>>>>> those wanting consistency with native apps on each platform. Also,
>>>>>>> the needs of an animator may differ from the needs of a
>>>>>>> resolution-settable-document editor as to how dynamically the 
>>>>>>> images
>>>>>>> shift between resolution variants.
>>>>>>         ----------
>>>>>>          Image[] resolutionVariants = // get sorted by sizes 
>>>>>> array of
>>>>>> resolution variants;
>>>>>>          Image mrImage = ImageResolutionHelper.createMRImage(
>>>>>>                  (rvWidth, rvHeight, resolutionVariants) -> { 
>>>>>> /*use a
>>>>>> custom logic to choose a resolution variant from an array of 
>>>>>> images*/},
>>>>>>                  (logicalDPI, baseImageSize, destImageSize) ->
>>>>>> destImageSize, // calculate the custom aware resolution variant size
>>>>>>                  baseImageIndex, resolutionVariants);
>>>>>>         ----------
>>>>>>
>>>>>>     or just extend the CustomMultiResolutionImage which has Image 
>>>>>> as the
>>>>>> parent class:
>>>>>>
>>>>>> --------------------
>>>>>>   public class CustomMultiResolutionImage extends
>>>>>> AbstractMultiResolutionImage {
>>>>>>
>>>>>>      @Override
>>>>>>      public Image getResolutionVariant(float logicalDPIX, float
>>>>>> logicalDPIY,
>>>>>>              float baseImageWidth, float baseImageHeight,
>>>>>>              float destImageWidth, float destImageHeight) {
>>>>>>          // return a resolution variant based on the given 
>>>>>> logical DPI,
>>>>>>          // base image size, or destination image size
>>>>>>      }
>>>>>>
>>>>>>      @Override
>>>>>>      public List<Image> getResolutionVariants() {
>>>>>>          // return a list of resolution variants
>>>>>>      }
>>>>>>
>>>>>>      @Override
>>>>>>      protected Image getBaseImage() {
>>>>>>          // return the base image
>>>>>>      }
>>>>>> }
>>>>>> --------------------
>>>>>>>
>>>>>>> Is that a fair summary of all of the considerations so far, or 
>>>>>>> did I
>>>>>>> miss something?
>>>>>>     I think it should cover the main needs.
>>>>>>
>>>>>>      Thanks,
>>>>>>      Alexandr.
>>>>>>>
>>>>>>>             ...jim
>>>>>>>
>>>>>>> On 3/27/14 7:43 AM, Alexander Scherbatiy wrote:
>>>>>>>>
>>>>>>>>   Below are some thoughts about TK.createMRImage(...) method
>>>>>>>>
>>>>>>>> On 3/24/2014 4:52 PM, Alexander Scherbatiy wrote:
>>>>>>>>> Hello,
>>>>>>>>>
>>>>>>>>>   Could you review the updated fix:
>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.03/
>>>>>>>>>
>>>>>>>>>   - baseImageWidth/Height arguments are added to the
>>>>>>>>> getResolutionVariant(...) method
>>>>>>>>>   - dest image sizes are reverted to included DPI scale
>>>>>>>>>   - AbstractMultiResolutionImage is added. It needs only to 
>>>>>>>>> implement
>>>>>>>>> only 3 methods from the AbstractMultiResolutionImage class
>>>>>>>>>     to create a custom multi-resolution image. For example:
>>>>>>>>>
>>>>>>>>> On 3/22/2014 3:57 AM, Jim Graham wrote:
>>>>>>>>>>
>>>>>>>>>> Your code example below can be expressed as an implementation 
>>>>>>>>>> of the
>>>>>>>>>> single-method, lambda-compatible interface that expresses 
>>>>>>>>>> just the
>>>>>>>>>> getRV() method. They could easily do:
>>>>>>>>>>
>>>>>>>>>> final Image baseImage = ...;
>>>>>>>>>> TK.createMRImage(new RVInterface() {
>>>>>>>>>>     public Image getRV(...) {
>>>>>>>>>>         // calculate rvWidth and rvHeight
>>>>>>>>>>         // look up rvWidth/rvHeight in a database of images
>>>>>>>>>>         // possibly contruct a new image
>>>>>>>>>>         return rvImage;
>>>>>>>>>>     }
>>>>>>>>>> }, baseImage);
>>>>>>>>>>
>>>>>>>>       The RVInterface mixes the logic that construct an image and
>>>>>>>> chooses the necessary resolution variant.
>>>>>>>>       It is ok if a developer always implements this interface. 
>>>>>>>> If it
>>>>>>>> needs to have DPI/Transform/Platform aware RVInterface the image
>>>>>>>> construction logic should be separated.
>>>>>>>>
>>>>>>>>      Does  TK.createMRImage() method implies that Platform 
>>>>>>>> aware logic
>>>>>>>> should be used for a resolution-variant choosing?
>>>>>>>>      If so, may be general createMRImage() can be placed in the
>>>>>>>> ImageResolutionHelper.
>>>>>>>>>> The main issue I see is if you might want the newly constructed
>>>>>>>>>> variants to appear in the List returned from the getVariants()
>>>>>>>>>> method.  I'm not sure what value that would have beyond simply
>>>>>>>>>> returning the base media that the object uses from which to 
>>>>>>>>>> construct
>>>>>>>>>> its variants...?
>>>>>>>>
>>>>>>>>    It can be solved by using something like array of image 
>>>>>>>> sizes or
>>>>>>>> other seeds and a mapper that can create an image from the 
>>>>>>>> given seed.
>>>>>>>>
>>>>>>>>   It can look like:
>>>>>>>> -------------------------
>>>>>>>> public class ImageResolutionHelper {
>>>>>>>>      public interface RVChooser {
>>>>>>>>
>>>>>>>>          public Image getRV(
>>>>>>>>                  float logicalDPIX, float logicalDPIY,
>>>>>>>>                  float baseImageWidth, float baseImageHeight,
>>>>>>>>                  float destImageWidth, float destImageHeight,
>>>>>>>>                  final Image... resolutionVariants);
>>>>>>>>      }
>>>>>>>>
>>>>>>>>      public static final RVChooser DPI_AWARE = ...;
>>>>>>>>      public static final RVChooser TRANSFORM_AWARE = ...;
>>>>>>>>
>>>>>>>>      // resolutionVariants is an array of  sorted by 
>>>>>>>> width/height images
>>>>>>>>      static Image createMRImage(final RVChooser rvChooser,
>>>>>>>>              final int baseImageIndex, final Image...
>>>>>>>> resolutionVariants) { ... }
>>>>>>>>
>>>>>>>>      // sorted by width/height images should be generated from 
>>>>>>>> seeds
>>>>>>>>      static <Type> Image createMRImage(final RVChooser rvChooser,
>>>>>>>>              final Type baseImageSeed, final Function<Type, Image>
>>>>>>>> mapper, final Type... rvSeeds) {...}
>>>>>>>> }
>>>>>>>>
>>>>>>>> public abstract class Toolkit {
>>>>>>>>      public abstract Image createMRImage(int baseImageIndex, 
>>>>>>>> Image...
>>>>>>>> resolutionVariants); // Platform aware rv chooser is used
>>>>>>>>      public abstract RVChooser getPlatformRVChooser() ;
>>>>>>>> }
>>>>>>>> --------------------------
>>>>>>>> Thanks,
>>>>>>>> Alexandr.
>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>>      I think it is better to provide both the 
>>>>>>>>>>> MultiResolutionImage
>>>>>>>>>>> and
>>>>>>>>>>> its implementation based on the given resolution variants 
>>>>>>>>>>> array.
>>>>>>>>>>
>>>>>>>>>> It occurs to me that even if we don't go with a 
>>>>>>>>>> lambda-factory-based
>>>>>>>>>> approach like what I'm describing, it might make sense to 
>>>>>>>>>> provide a
>>>>>>>>>> baseMR implementation that they can subclass to keep them 
>>>>>>>>>> from trying
>>>>>>>>>> to subclass off of BufferedImage instead.  I really would 
>>>>>>>>>> like to
>>>>>>>>>> avoid "custom MR images are subclasses of BufImg" if we can as I
>>>>>>>>>> think the mix of concepts is a little jarring...
>>>>>>>>>>
>>>>>>>>>>             ...jim
>>>>>>>>>>
>>>>>>>>>>>     The implementation could look like:
>>>>>>>>>>> ---------------------------------
>>>>>>>>>>> public class CustomMultiResolutionImage extends Image 
>>>>>>>>>>> implements
>>>>>>>>>>> MultiResolutionImage {
>>>>>>>>>>>
>>>>>>>>>>>      int baseImageIndex;
>>>>>>>>>>>      Image[] resolutionVariants;
>>>>>>>>>>>
>>>>>>>>>>>      public CustomMultiResolutionImage(int baseImageIndex,
>>>>>>>>>>>              Image... resolutionVariants) {
>>>>>>>>>>>          this.baseImageIndex = baseImageIndex;
>>>>>>>>>>>          this.resolutionVariants = resolutionVariants;
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public int getWidth(ImageObserver observer) {
>>>>>>>>>>>          return getBaseImage().getWidth(null);
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public int getHeight(ImageObserver observer) {
>>>>>>>>>>>          return getBaseImage().getHeight(null);
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public ImageProducer getSource() {
>>>>>>>>>>>          return getBaseImage().getSource();
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public Graphics getGraphics() {
>>>>>>>>>>>          return getBaseImage().getGraphics();
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public Object getProperty(String name, ImageObserver 
>>>>>>>>>>> observer) {
>>>>>>>>>>>          return getBaseImage().getProperty(name, observer);
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public Image getResolutionVariant(float logicalDPIX, float
>>>>>>>>>>> logicalDPIY,
>>>>>>>>>>>              float destinationImageWidth, float
>>>>>>>>>>> destinationImageHeight) {
>>>>>>>>>>>              // calculate resolution variant width/height
>>>>>>>>>>>          return getResolutionVariant(rvWidth, rvHeight);
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      @Override
>>>>>>>>>>>      public List<Image> getResolutionVariants() {
>>>>>>>>>>>          return Arrays.asList(resolutionVariants);
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      private Image getResolutionVariant(float rvWidth, float
>>>>>>>>>>> rvHeight) {
>>>>>>>>>>>          // return a resolution variant based on the given 
>>>>>>>>>>> width and
>>>>>>>>>>> height
>>>>>>>>>>>      }
>>>>>>>>>>>
>>>>>>>>>>>      private Image getBaseImage() {
>>>>>>>>>>>          return resolutionVariants[baseImageIndex];
>>>>>>>>>>>      }
>>>>>>>>>>> }
>>>>>>>>>>> ---------------------------------
>>>>>>>>>>>
>>>>>>>>>>>    Thanks,
>>>>>>>>>>>    Alexandr.
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Then we provide one of these from TK.get/createImage() when 
>>>>>>>>>>>> the
>>>>>>>>>>>> platform detects @2x, or Win8-style variants.
>>>>>>>>>>>>
>>>>>>>>>>>> For custom images we provide TK.createMRImage(lambda getRV, 
>>>>>>>>>>>> Image
>>>>>>>>>>>> variants...) and TK.createMRImage(Image variants...);
>>>>>>>>>>>>
>>>>>>>>>>>> Since the get<List> method is just bookkeeping, I don't see 
>>>>>>>>>>>> them
>>>>>>>>>>>> needing to override it, so the getRV() method is really the 
>>>>>>>>>>>> only
>>>>>>>>>>>> thing
>>>>>>>>>>>> they might want to override, and we can tie into the new 
>>>>>>>>>>>> Lambda
>>>>>>>>>>>> capabilities by making a single-method interface for it 
>>>>>>>>>>>> that they
>>>>>>>>>>>> supply in a factory method.
>>>>>>>>>>>>
>>>>>>>>>>>> I realize that the interface you created is more fundamentally
>>>>>>>>>>>> OO, but
>>>>>>>>>>>> the Image class has always been special in this regard in 
>>>>>>>>>>>> the AWT
>>>>>>>>>>>> ecosystem (in so far as we do not support someone 
>>>>>>>>>>>> implementing their
>>>>>>>>>>>> own Image subclass even though it is technically possible).
>>>>>>>>>>>> Because of
>>>>>>>>>>>> this special nature of Image, we end up with the situation 
>>>>>>>>>>>> that if
>>>>>>>>>>>> someone were given a need to create a subclass of Image, 
>>>>>>>>>>>> then they
>>>>>>>>>>>> would turn to BufImg as their superclass even though BufImg is
>>>>>>>>>>>> essentially an implementation-specific leaf node on the 
>>>>>>>>>>>> Image class
>>>>>>>>>>>> hierarchy.  This approach with a factory method to create an
>>>>>>>>>>>> internal
>>>>>>>>>>>> subclass of the new MRI class mirrors the existing cases of 
>>>>>>>>>>>> Image
>>>>>>>>>>>> objects that come from factories as well.
>>>>>>>>>>>>
>>>>>>>>>>>> Thoughts?
>>>>>>>>>>>>
>>>>>>>>>>>>             ...jim
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On 3/20/14 7:52 AM, Alexander Scherbatiy wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>    Hello,
>>>>>>>>>>>>>
>>>>>>>>>>>>>    Could you review the updated version of the fix:
>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.01/
>>>>>>>>>>>>>
>>>>>>>>>>>>>   - The "getResolutionVariant(int width, int height)" 
>>>>>>>>>>>>> method from
>>>>>>>>>>>>> MultiResolutionImage class is changed to
>>>>>>>>>>>>>     Image getResolutionVariant(float logicalDPIX, float
>>>>>>>>>>>>> logicalDPIY,
>>>>>>>>>>>>> float width, float height, AffineTransform transform);
>>>>>>>>>>>>>
>>>>>>>>>>>>>   - sun.awt.image.ImageResolutionHelper class is added. The
>>>>>>>>>>>>> sun.awt.image.MultiResolutionToolkitImage and
>>>>>>>>>>>>> sun.awt.image.MultiResolutionBufferedImage classes are used
>>>>>>>>>>>>> PLATFORM  ImageResolutionHelper.
>>>>>>>>>>>>>
>>>>>>>>>>>>>   The  MultiResolutionImage interface implementation could 
>>>>>>>>>>>>> look
>>>>>>>>>>>>> like:
>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>> public class CustomMultiResolutionImage extends BufferedImage
>>>>>>>>>>>>> implements
>>>>>>>>>>>>> MultiResolutionImage {
>>>>>>>>>>>>>
>>>>>>>>>>>>>      private final Image[] resolutionVariants;
>>>>>>>>>>>>>
>>>>>>>>>>>>>      public CustomMultiResolutionImage(int baseIndex, 
>>>>>>>>>>>>> Image...
>>>>>>>>>>>>> images) {
>>>>>>>>>>>>> super(images[baseIndex].getWidth(null),
>>>>>>>>>>>>> images[baseIndex].getHeight(null),
>>>>>>>>>>>>> BufferedImage.TYPE_INT_RGB);
>>>>>>>>>>>>>          this.resolutionVariants = images;
>>>>>>>>>>>>>          Graphics g = getGraphics();
>>>>>>>>>>>>>          g.drawImage(images[baseIndex], 0, 0, null);
>>>>>>>>>>>>>          g.dispose();
>>>>>>>>>>>>>      }
>>>>>>>>>>>>>
>>>>>>>>>>>>>      @Override
>>>>>>>>>>>>>      public Image getResolutionVariant(float logicalDPIX, 
>>>>>>>>>>>>> float
>>>>>>>>>>>>> logicalDPIY,
>>>>>>>>>>>>>              float width, float height, AffineTransform
>>>>>>>>>>>>> transform) {
>>>>>>>>>>>>>          return getResolutionVariant(logicalDPIX * width,
>>>>>>>>>>>>> logicalDPIY *
>>>>>>>>>>>>> height);
>>>>>>>>>>>>>      }
>>>>>>>>>>>>>
>>>>>>>>>>>>>      @Override
>>>>>>>>>>>>>      public List<Image> getResolutionVariants() {
>>>>>>>>>>>>>          return Arrays.asList(resolutionVariants);
>>>>>>>>>>>>>      }
>>>>>>>>>>>>>
>>>>>>>>>>>>>      public Image getResolutionVariant(double width, double
>>>>>>>>>>>>> height) {
>>>>>>>>>>>>>          for (Image image : resolutionVariants) {
>>>>>>>>>>>>>              if (width <= image.getWidth(null) && height <=
>>>>>>>>>>>>> image.getHeight(null)) {
>>>>>>>>>>>>>                  return image;
>>>>>>>>>>>>>              }
>>>>>>>>>>>>>          }
>>>>>>>>>>>>>          return this;
>>>>>>>>>>>>>      }
>>>>>>>>>>>>> }
>>>>>>>>>>>>> ------------------------------
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>    Thanks,
>>>>>>>>>>>>>    Alexandr.
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 2/27/2014 4:54 PM, Alexander Scherbatiy wrote:
>>>>>>>>>>>>>> On 2/22/2014 3:54 AM, Jim Graham wrote:
>>>>>>>>>>>>>>> Hi Alexandr,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 2/18/14 7:33 AM, Alexander Scherbatiy wrote:
>>>>>>>>>>>>>>>>   Hi Jim,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   Let's divide the discussion into two part.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   1. Where it is better to hold resolution variants?
>>>>>>>>>>>>>>>>      Putting resolution variants in Image class brings 
>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>> questions like:
>>>>>>>>>>>>>>>>    - Some type of images do not need to have resolution 
>>>>>>>>>>>>>>>> variants
>>>>>>>>>>>>>>>>    - Should resolution variants have the same type as 
>>>>>>>>>>>>>>>> the base
>>>>>>>>>>>>>>>> image?
>>>>>>>>>>>>>>>>    - getResolutionVariants() method can return copy of the
>>>>>>>>>>>>>>>> original
>>>>>>>>>>>>>>>> list
>>>>>>>>>>>>>>>> so add/removeRV methods should be also added.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    There are pros and cons for placing resolution 
>>>>>>>>>>>>>>>> variants to
>>>>>>>>>>>>>>>> Image
>>>>>>>>>>>>>>>> class or to a separate intreface.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I agree that this could be a separate interface. In my 
>>>>>>>>>>>>>>> examples
>>>>>>>>>>>>>>> below I was just sticking them inside an "Image{}" to 
>>>>>>>>>>>>>>> show where
>>>>>>>>>>>>>>> they
>>>>>>>>>>>>>>> lived in the set of involved objects, not a specific
>>>>>>>>>>>>>>> recommendation
>>>>>>>>>>>>>>> that they actually be new methods on the base class 
>>>>>>>>>>>>>>> itself. I
>>>>>>>>>>>>>>> probably should have put a comment there about that.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> With respect to add/remove - that is assuming a need for 
>>>>>>>>>>>>>>> manual
>>>>>>>>>>>>>>> construction of an image set, right? Forgive me if I'm
>>>>>>>>>>>>>>> forgetting
>>>>>>>>>>>>>>> something, but I seem to recall that manual Multi-Res 
>>>>>>>>>>>>>>> images was
>>>>>>>>>>>>>>> proposed as a way for developers to introduce @2x support
>>>>>>>>>>>>>>> themselves,
>>>>>>>>>>>>>>> but if we are internally managing @2x and -DPI variants 
>>>>>>>>>>>>>>> for them,
>>>>>>>>>>>>>>> then I'm not sure if there is actual developer need to 
>>>>>>>>>>>>>>> manually
>>>>>>>>>>>>>>> construct their own.  Am I forgetting something?
>>>>>>>>>>>>>>    The NSImage has addRepresentation/removeRepresentation
>>>>>>>>>>>>>> methods to
>>>>>>>>>>>>>> work with image representations on Mac OS X.
>>>>>>>>>>>>>>    The java.awt.Image class should provide similar
>>>>>>>>>>>>>> functionality to
>>>>>>>>>>>>>> have the possibilities as Cocoa on HiDPI displays.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>   2. Using scale factor/image sizes/scaled image sizes to
>>>>>>>>>>>>>>>> retreive a
>>>>>>>>>>>>>>>> resolution variant.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    May be it is better to have a structure that provide 
>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>> necessary
>>>>>>>>>>>>>>>> information  to query the resolution variant: scale 
>>>>>>>>>>>>>>>> factor,
>>>>>>>>>>>>>>>> draw area
>>>>>>>>>>>>>>>> width/height, transformed area width/height?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    For example:
>>>>>>>>>>>>>>>>    ---------------------
>>>>>>>>>>>>>>>>      public interface MultiResolutionImage {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>          interface DrawAreaInfo {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>              float getScaleFactor();
>>>>>>>>>>>>>>>>              float getAreaWidth();
>>>>>>>>>>>>>>>>              float getAreaHeight();
>>>>>>>>>>>>>>>>              float getTransformedAreaWidth();
>>>>>>>>>>>>>>>>              float getTransformedAreaHeight();
>>>>>>>>>>>>>>>>          }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>          public Image getResolutionVariant(DrawAreaInfo
>>>>>>>>>>>>>>>> drawAreaInfo) ;
>>>>>>>>>>>>>>>>          public List<Image> getResolutionVariants();
>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>    ---------------------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The problem with a constructor is that this is something 
>>>>>>>>>>>>>>> that is
>>>>>>>>>>>>>>> (potentially) done on every drawImage() call, which 
>>>>>>>>>>>>>>> means we are
>>>>>>>>>>>>>>> inviting GC into the equation.  If we can come up with a 
>>>>>>>>>>>>>>> simple
>>>>>>>>>>>>>>> "just
>>>>>>>>>>>>>>> a couple/3/4 numbers" way to embed that data into a 
>>>>>>>>>>>>>>> method call
>>>>>>>>>>>>>>> argument list then we can make this lighter weight.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> What about simply having floating point (double) 
>>>>>>>>>>>>>>> dimensions on
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> rendered size
>>>>>>>>>>>>>>       There should be a way to choose a resolution variant
>>>>>>>>>>>>>> based on
>>>>>>>>>>>>>> requested drawing size or transformed drawing size.
>>>>>>>>>>>>>>       At least a current transformation should be 
>>>>>>>>>>>>>> included too.
>>>>>>>>>>>>>>> plus a single floating point "logical DPI" for the screen?
>>>>>>>>>>>>>>      There is the ID2D1Factory::GetDesktopDpi method 
>>>>>>>>>>>>>> which returns
>>>>>>>>>>>>>> dpiX and dpiY.
>>>>>>>>>>>>>> http://msdn.microsoft.com/en-us/library/windows/apps/dd371316 
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     That means that logicalDPIX/Y can have different values.
>>>>>>>>>>>>>>      At least it is described in the
>>>>>>>>>>>>>> http://msdn.microsoft.com/en-us/library/windows/apps/ff684173 
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>      "To get the DPI setting, call the 
>>>>>>>>>>>>>> ID2D1Factory::GetDesktopDpi
>>>>>>>>>>>>>> method. The DPI is returned as two floating-point values, 
>>>>>>>>>>>>>> one for
>>>>>>>>>>>>>> the
>>>>>>>>>>>>>> x-axis and one for the y-axis. In theory, these values 
>>>>>>>>>>>>>> can differ.
>>>>>>>>>>>>>> Calculate a separate scaling factor for each axis."
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   The getResolutionVariant method could look like:
>>>>>>>>>>>>>> --------------------------------------
>>>>>>>>>>>>>>     public Image getResolutionVariant(float logicalDPIX, 
>>>>>>>>>>>>>> float
>>>>>>>>>>>>>> logicalDPIY,
>>>>>>>>>>>>>>             float widthX, float widthY, AffineTransform
>>>>>>>>>>>>>> transform);
>>>>>>>>>>>>>> --------------------------------------
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  If the image is known (either passed as an argument or the
>>>>>>>>>>>>>>> method is
>>>>>>>>>>>>>>> called on the image), then it can provide the original WH.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>    The MultiResolutionImage default implementation 
>>>>>>>>>>>>>>>> could allow
>>>>>>>>>>>>>>>> to use
>>>>>>>>>>>>>>>> different strategies like scale factor/transfom/OS based
>>>>>>>>>>>>>>>>    to query a resolution variant. The OS based strategy 
>>>>>>>>>>>>>>>> can be
>>>>>>>>>>>>>>>> used by
>>>>>>>>>>>>>>>> default.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> For Mac policy, all we need is the transformed 
>>>>>>>>>>>>>>> dimensions, which
>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>> be passed in as FP for generality. For Windows policy, 
>>>>>>>>>>>>>>> all we
>>>>>>>>>>>>>>> need
>>>>>>>>>>>>>>> is logical DPI for the screen.   What other information 
>>>>>>>>>>>>>>> would we
>>>>>>>>>>>>>>> need, or would an algorithm like to use, that can't be 
>>>>>>>>>>>>>>> computed
>>>>>>>>>>>>>>> from
>>>>>>>>>>>>>>> those 2 pieces?
>>>>>>>>>>>>>>      The aim is to provide a base class that can be used to
>>>>>>>>>>>>>> create a
>>>>>>>>>>>>>> MultiResolutionImage like:
>>>>>>>>>>>>>> http://hg.openjdk.java.net/jdk9/client/jdk/diff/ae53ebce5fa3/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java 
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>      A developer should be able to implement a custom 
>>>>>>>>>>>>>> algorithm to
>>>>>>>>>>>>>> query a resolution variant.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     It can be done by overriding the getResolutionVariant 
>>>>>>>>>>>>>> image:
>>>>>>>>>>>>>>    -----------------------
>>>>>>>>>>>>>>         Image mrImage = new MultiResolutionBufferedImage(){
>>>>>>>>>>>>>>             @Override
>>>>>>>>>>>>>>             public Image getResolutionVariant(...) {
>>>>>>>>>>>>>>                 // Custom logic here
>>>>>>>>>>>>>>             }
>>>>>>>>>>>>>>         };
>>>>>>>>>>>>>>    -----------------------
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>    Or it can be done by using resolution variant choosers 
>>>>>>>>>>>>>> so a
>>>>>>>>>>>>>> developer can implement custom resolution variant query:
>>>>>>>>>>>>>>    -----------------------
>>>>>>>>>>>>>> public class MultiResolutionBufferedImage implements
>>>>>>>>>>>>>> MultiResolutionImage{
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     interface ResolutionVariantChooser{
>>>>>>>>>>>>>>         Image getResolutionVariant(dpi, size,..., 
>>>>>>>>>>>>>> List<Image>
>>>>>>>>>>>>>> resolutionVariants);
>>>>>>>>>>>>>>     }
>>>>>>>>>>>>>>     ResolutionVariantChooser TRANSFORM_BASED = null;
>>>>>>>>>>>>>>     ResolutionVariantChooser DPI_BASED = null;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     ResolutionVariantChooser rvChooser;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     @Override
>>>>>>>>>>>>>>     public Image getResolutionVariant(dpi, size,...,) {
>>>>>>>>>>>>>>         return rvChooser.getResolutionVariant(dpi, size,...,
>>>>>>>>>>>>>> getResolutionVariants());
>>>>>>>>>>>>>>     }
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>    -----------------------
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   Thanks,
>>>>>>>>>>>>>>   Alexandr.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>             ...jim
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Alexandr.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 2/13/2014 4:42 AM, Jim Graham wrote:
>>>>>>>>>>>>>>>>> On 2/12/14 5:59 AM, Alexander Scherbatiy wrote:
>>>>>>>>>>>>>>>>>> On 2/8/2014 4:19 AM, Jim Graham wrote:
>>>>>>>>>>>>>>>>>>> The primary thing that I was concerned about was the
>>>>>>>>>>>>>>>>>>> presence of
>>>>>>>>>>>>>>>>>>> integers in the API when Windows uses non-integer 
>>>>>>>>>>>>>>>>>>> multiples
>>>>>>>>>>>>>>>>>>       It would make sense to pass real numbers to the
>>>>>>>>>>>>>>>>>> getResolutionVariant() method if the difference between
>>>>>>>>>>>>>>>>>> resolution
>>>>>>>>>>>>>>>>>> variants sizes is 1.
>>>>>>>>>>>>>>>>>>       It seems that it is not a common case.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I was thinking of other API that is related to this, 
>>>>>>>>>>>>>>>>> such as
>>>>>>>>>>>>>>>>> the API
>>>>>>>>>>>>>>>>> that queries the scaling factor from a SurfaceManager. I
>>>>>>>>>>>>>>>>> seem to
>>>>>>>>>>>>>>>>> remember some integer return values in that, but 
>>>>>>>>>>>>>>>>> Windows might
>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>> the answer 1.4 or 1.8, depending on the screen scaling 
>>>>>>>>>>>>>>>>> factor
>>>>>>>>>>>>>>>>> that was
>>>>>>>>>>>>>>>>> determined from the UI.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> In terms of the getResolutionVariant() method here, those
>>>>>>>>>>>>>>>>> non-integer
>>>>>>>>>>>>>>>>> screen scaling factors don't directly impact this API. 
>>>>>>>>>>>>>>>>> But, we
>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>> some issues with the use of integers there from other 
>>>>>>>>>>>>>>>>> sources:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - That API assumes that the caller will determine the 
>>>>>>>>>>>>>>>>> pixel
>>>>>>>>>>>>>>>>> size
>>>>>>>>>>>>>>>>> needed, but the actual media choice is determined with
>>>>>>>>>>>>>>>>> different
>>>>>>>>>>>>>>>>> techniques on Mac and Windows so this means that the 
>>>>>>>>>>>>>>>>> caller
>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>> to worry about platform conventions. Is that the right
>>>>>>>>>>>>>>>>> tradeoff?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - The technique recommended for Mac involves computing 
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> precise
>>>>>>>>>>>>>>>>> size desired using the current transform, which may be a
>>>>>>>>>>>>>>>>> floating
>>>>>>>>>>>>>>>>> point value, so the integer values used in this API 
>>>>>>>>>>>>>>>>> are already
>>>>>>>>>>>>>>>>> approximations and there is no documentation on how to
>>>>>>>>>>>>>>>>> generate the
>>>>>>>>>>>>>>>>> proper integer.  In particular, the current code in SG2D
>>>>>>>>>>>>>>>>> naively
>>>>>>>>>>>>>>>>> uses
>>>>>>>>>>>>>>>>> a cast to integer to determine the values to supply which
>>>>>>>>>>>>>>>>> means a
>>>>>>>>>>>>>>>>> transformed size of W+0.5 will be truncated to W and 
>>>>>>>>>>>>>>>>> the lower
>>>>>>>>>>>>>>>>> resolution image will be used. Does that conform to Mac
>>>>>>>>>>>>>>>>> guidelines? Do
>>>>>>>>>>>>>>>>> they require the truncated size to reach W+1 before 
>>>>>>>>>>>>>>>>> the next
>>>>>>>>>>>>>>>>> size is
>>>>>>>>>>>>>>>>> used?  Passing in float or double values would 
>>>>>>>>>>>>>>>>> sidestep all of
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> since then the comparisons would be done with full 
>>>>>>>>>>>>>>>>> precision,
>>>>>>>>>>>>>>>>> but as
>>>>>>>>>>>>>>>>> long as we can determine a "best practices compatible 
>>>>>>>>>>>>>>>>> with all
>>>>>>>>>>>>>>>>> platforms" rule on how to round to integers, then 
>>>>>>>>>>>>>>>>> integers
>>>>>>>>>>>>>>>>> are OK
>>>>>>>>>>>>>>>>> there.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - The Windows document you cite below suggests that the
>>>>>>>>>>>>>>>>> determination
>>>>>>>>>>>>>>>>> should be made by looking at the Screen DPI and 
>>>>>>>>>>>>>>>>> choosing the
>>>>>>>>>>>>>>>>> next
>>>>>>>>>>>>>>>>> higher media variant based on that screen DPI. They do 
>>>>>>>>>>>>>>>>> not
>>>>>>>>>>>>>>>>> specify
>>>>>>>>>>>>>>>>> choosing media based on the current transform as is 
>>>>>>>>>>>>>>>>> done for
>>>>>>>>>>>>>>>>> Mac.  If
>>>>>>>>>>>>>>>>> we stick with supplying values that are used to 
>>>>>>>>>>>>>>>>> determine which
>>>>>>>>>>>>>>>>> media
>>>>>>>>>>>>>>>>> to use, then on Windows we should not take the 
>>>>>>>>>>>>>>>>> transform into
>>>>>>>>>>>>>>>>> account,
>>>>>>>>>>>>>>>>> but instead query the SurfaceManager for the scale 
>>>>>>>>>>>>>>>>> factor and
>>>>>>>>>>>>>>>>> only
>>>>>>>>>>>>>>>>> transform by those values (even if the current 
>>>>>>>>>>>>>>>>> transform was
>>>>>>>>>>>>>>>>> manually
>>>>>>>>>>>>>>>>> overridden to identity).
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> There are pros and cons to both approaches.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Mac ensures that you are always using the best media 
>>>>>>>>>>>>>>>>> for any
>>>>>>>>>>>>>>>>> given
>>>>>>>>>>>>>>>>> render operation.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> But, Windows ensure more consistency in the face of other
>>>>>>>>>>>>>>>>> scaling.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> The thing to consider is that if you have a 500x500 image
>>>>>>>>>>>>>>>>> with a
>>>>>>>>>>>>>>>>> 1000x1000 variant and you rendering it at 500x500 and 
>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>> 501x501,
>>>>>>>>>>>>>>>>> that first jump will be fairly jarring as the scaled 
>>>>>>>>>>>>>>>>> version
>>>>>>>>>>>>>>>>> of the
>>>>>>>>>>>>>>>>> 1000x1000 will not look precisely like the original 
>>>>>>>>>>>>>>>>> 500x500
>>>>>>>>>>>>>>>>> did.
>>>>>>>>>>>>>>>>> With
>>>>>>>>>>>>>>>>> @2x images only, this effect is minimized so the 
>>>>>>>>>>>>>>>>> advantage of
>>>>>>>>>>>>>>>>> always
>>>>>>>>>>>>>>>>> using "the best media for a given render operation" may
>>>>>>>>>>>>>>>>> outweigh the
>>>>>>>>>>>>>>>>> inconsistency issue.  But, on Windows where the media are
>>>>>>>>>>>>>>>>> 1.4x or
>>>>>>>>>>>>>>>>> 1.8x
>>>>>>>>>>>>>>>>> in size, a downscaled image will start to show more
>>>>>>>>>>>>>>>>> interpolation
>>>>>>>>>>>>>>>>> noise and so the balance of the two choices may shift 
>>>>>>>>>>>>>>>>> more
>>>>>>>>>>>>>>>>> towards not
>>>>>>>>>>>>>>>>> wanting a jarring shift.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> We might want one or more of the following:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - Developer chooses policy (TX_AWARE, DPI_AWARE,
>>>>>>>>>>>>>>>>> ALWAYS_LARGEST,
>>>>>>>>>>>>>>>>> NONE,
>>>>>>>>>>>>>>>>> PLATFORM) where the last policy would use TX_AWARE on 
>>>>>>>>>>>>>>>>> Mac and
>>>>>>>>>>>>>>>>> DPI_AWARE on Windows
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - We create our own policy and always use it 
>>>>>>>>>>>>>>>>> (TX_AWARE? or
>>>>>>>>>>>>>>>>> DPI_AWARE?)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - We create our own policy that dynamically chooses 
>>>>>>>>>>>>>>>>> one of the
>>>>>>>>>>>>>>>>> above
>>>>>>>>>>>>>>>>> strategies depending on platform or available media or 
>>>>>>>>>>>>>>>>> ???
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> - We could create an optional interface for them to 
>>>>>>>>>>>>>>>>> install
>>>>>>>>>>>>>>>>> their
>>>>>>>>>>>>>>>>> own
>>>>>>>>>>>>>>>>> algorithm as well.  I think it would work best as a 
>>>>>>>>>>>>>>>>> delegate
>>>>>>>>>>>>>>>>> interface
>>>>>>>>>>>>>>>>> that one installs into Image so that it can be used 
>>>>>>>>>>>>>>>>> with any
>>>>>>>>>>>>>>>>> image
>>>>>>>>>>>>>>>>> without having to subclass (it wouldn't really have 
>>>>>>>>>>>>>>>>> much to do
>>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>>> BufferedImages or VolatileImages, though):
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> class Image {
>>>>>>>>>>>>>>>>>     void setResolutionHelper(ImageResolutionHelper foo);
>>>>>>>>>>>>>>>>>     List<Image> getResolutionVariants();
>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> or:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> class Graphics {
>>>>>>>>>>>>>>>>>      void setResolutionHelper(ImageResolutionHelper foo);
>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> or - anywhere else it could be installed more 
>>>>>>>>>>>>>>>>> centrally (per
>>>>>>>>>>>>>>>>> App
>>>>>>>>>>>>>>>>> context)?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> and the interface would be something like one of these
>>>>>>>>>>>>>>>>> variants:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> interface ImageResolutionHelper {
>>>>>>>>>>>>>>>>>     // This version would prevent substituting a 
>>>>>>>>>>>>>>>>> random image:
>>>>>>>>>>>>>>>>>     // They have to return an index into the 
>>>>>>>>>>>>>>>>> List<Image> for
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> image...
>>>>>>>>>>>>>>>>>     public int chooseVariant(Image img, double dpi, 
>>>>>>>>>>>>>>>>> number w,
>>>>>>>>>>>>>>>>> number h);
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> or:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>     // This version would allow substituting an arbitrary
>>>>>>>>>>>>>>>>> image:
>>>>>>>>>>>>>>>>>     public Image getVariant(Image img, double dpi, 
>>>>>>>>>>>>>>>>> number w,
>>>>>>>>>>>>>>>>> number
>>>>>>>>>>>>>>>>> h);
>>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Since they would be in full control of the policy, 
>>>>>>>>>>>>>>>>> though, we
>>>>>>>>>>>>>>>>> would
>>>>>>>>>>>>>>>>> unfortunately always have to call this, there would be 
>>>>>>>>>>>>>>>>> no more
>>>>>>>>>>>>>>>>> testing
>>>>>>>>>>>>>>>>> in SG2D to see "if" we need to deal with DPI, though 
>>>>>>>>>>>>>>>>> perhaps we
>>>>>>>>>>>>>>>>> could
>>>>>>>>>>>>>>>>> document some internal conditions in which we do not 
>>>>>>>>>>>>>>>>> call it
>>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>>> common cases (but that would have to be well agreed 
>>>>>>>>>>>>>>>>> not to
>>>>>>>>>>>>>>>>> get in
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> way of reasonable uses of the API and well documented)?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Note that we would have to do a security audit to make 
>>>>>>>>>>>>>>>>> sure
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> random image substitution couldn't allow any sort of 
>>>>>>>>>>>>>>>>> "screen
>>>>>>>>>>>>>>>>> phishing"
>>>>>>>>>>>>>>>>> exploit.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>             ...jim
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> and also what policy they use for choosing scaled 
>>>>>>>>>>>>>>>>>>> images.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I don't see a mention of taking the current 
>>>>>>>>>>>>>>>>>>> transform into
>>>>>>>>>>>>>>>>>>> account,
>>>>>>>>>>>>>>>>>>> just physical issues like screen DPI and form 
>>>>>>>>>>>>>>>>>>> factor. They
>>>>>>>>>>>>>>>>>>> talk
>>>>>>>>>>>>>>>>>>> about
>>>>>>>>>>>>>>>>>>> resolution plateaus and in their recommendations 
>>>>>>>>>>>>>>>>>>> section they
>>>>>>>>>>>>>>>>>>> tell the
>>>>>>>>>>>>>>>>>>> developer to use a particular property that tells 
>>>>>>>>>>>>>>>>>>> them the
>>>>>>>>>>>>>>>>>>> screen
>>>>>>>>>>>>>>>>>>> resolution to figure out which image to load if they 
>>>>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>>> loading
>>>>>>>>>>>>>>>>>>> manually.  There is no discussion about dynamically 
>>>>>>>>>>>>>>>>>>> loading
>>>>>>>>>>>>>>>>>>> multiple
>>>>>>>>>>>>>>>>>>> versions of the image based on a dynamic 
>>>>>>>>>>>>>>>>>>> program-applied
>>>>>>>>>>>>>>>>>>> transform
>>>>>>>>>>>>>>>>>>> factor as is done on MacOS.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Also, they tell developers to draw images to a 
>>>>>>>>>>>>>>>>>>> specific size
>>>>>>>>>>>>>>>>>>> rather
>>>>>>>>>>>>>>>>>>> than using auto-sizing.  That begs the question as 
>>>>>>>>>>>>>>>>>>> to how
>>>>>>>>>>>>>>>>>>> they
>>>>>>>>>>>>>>>>>>> interpret a call to draw an image just using a 
>>>>>>>>>>>>>>>>>>> location in
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> presence of various DPI factors.
>>>>>>>>>>>>>>>>>>       There is an interesting doc that describes how 
>>>>>>>>>>>>>>>>>> to write
>>>>>>>>>>>>>>>>>> DPI-aware
>>>>>>>>>>>>>>>>>> Win32 applications:
>>>>>>>>>>>>>>>>>> http://msdn.microsoft.com/en-us/library/dd464646%28v=vs.85%29.aspx 
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>       It is suggested to handle WM_DPICHANGED 
>>>>>>>>>>>>>>>>>> message, load
>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>> graphic
>>>>>>>>>>>>>>>>>> that has slightly greater resolution to the current 
>>>>>>>>>>>>>>>>>> DPI and
>>>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>>>> StretchBlt
>>>>>>>>>>>>>>>>>>       to scale down the image.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>      Thanks,
>>>>>>>>>>>>>>>>>>      Alexandr.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>             ...jim
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On 2/7/14 3:00 AM, Alexander Scherbatiy wrote:
>>>>>>>>>>>>>>>>>>>> On 1/22/2014 6:40 AM, Jim Graham wrote:
>>>>>>>>>>>>>>>>>>>>> Hi Alexander,
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Before we get too far down the road on this API, I 
>>>>>>>>>>>>>>>>>>>>> think we
>>>>>>>>>>>>>>>>>>>>> understand
>>>>>>>>>>>>>>>>>>>>> the way in which MacOS processes multi-resolution 
>>>>>>>>>>>>>>>>>>>>> images
>>>>>>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>>>>>>> HiDPI
>>>>>>>>>>>>>>>>>>>>> screens, but have we investigated the processes that
>>>>>>>>>>>>>>>>>>>>> Windows
>>>>>>>>>>>>>>>>>>>>> uses
>>>>>>>>>>>>>>>>>>>>> under Windows 8?  My impression is that Windows 8 has
>>>>>>>>>>>>>>>>>>>>> included a
>>>>>>>>>>>>>>>>>>>>> number of new techniques for dealing with the high
>>>>>>>>>>>>>>>>>>>>> resolution
>>>>>>>>>>>>>>>>>>>>> displays
>>>>>>>>>>>>>>>>>>>>> that it will run on in the Windows tablet and mobile
>>>>>>>>>>>>>>>>>>>>> industries
>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>> that these will also come into play as 4K displays 
>>>>>>>>>>>>>>>>>>>>> (already
>>>>>>>>>>>>>>>>>>>>> available)
>>>>>>>>>>>>>>>>>>>>> become more common on the desktop.  We should make 
>>>>>>>>>>>>>>>>>>>>> sure
>>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>>> what we
>>>>>>>>>>>>>>>>>>>>> come up with here can provide native compatibility 
>>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>>> either
>>>>>>>>>>>>>>>>>>>>> platform's policies and standard practices.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> If you've investigated the MS policies I'd like to 
>>>>>>>>>>>>>>>>>>>>> see a
>>>>>>>>>>>>>>>>>>>>> summary so
>>>>>>>>>>>>>>>>>>>>> that we can consider them as we review this API...
>>>>>>>>>>>>>>>>>>>>     There is the Windows Guidelines for scaling to 
>>>>>>>>>>>>>>>>>>>> pixel
>>>>>>>>>>>>>>>>>>>> density:
>>>>>>>>>>>>>>>>>>>> http://msdn.microsoft.com/en-us/library/windows/apps/hh465362.aspx 
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>     which says that Windows has automatic resource 
>>>>>>>>>>>>>>>>>>>> loading
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> supports
>>>>>>>>>>>>>>>>>>>> three version of images scaling (100%, 140%, and 180%)
>>>>>>>>>>>>>>>>>>>> --------------------------------
>>>>>>>>>>>>>>>>>>>> Without scaling, as the pixel density of a display 
>>>>>>>>>>>>>>>>>>>> device
>>>>>>>>>>>>>>>>>>>> increases, the
>>>>>>>>>>>>>>>>>>>> physical sizes of objects on screen get smaller.
>>>>>>>>>>>>>>>>>>>> When UI would otherwise be too small to touch and 
>>>>>>>>>>>>>>>>>>>> when text
>>>>>>>>>>>>>>>>>>>> gets
>>>>>>>>>>>>>>>>>>>> too
>>>>>>>>>>>>>>>>>>>> small to read,
>>>>>>>>>>>>>>>>>>>> Windows scales the system and app UI to one of the 
>>>>>>>>>>>>>>>>>>>> following
>>>>>>>>>>>>>>>>>>>> scaling
>>>>>>>>>>>>>>>>>>>> plateaus:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>      1.0 (100%, no scaling is applied)
>>>>>>>>>>>>>>>>>>>>      1.4 (140% scaling)
>>>>>>>>>>>>>>>>>>>>      1.8 (180% scaling)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Windows determines which scaling plateau to use 
>>>>>>>>>>>>>>>>>>>> based on the
>>>>>>>>>>>>>>>>>>>> physical
>>>>>>>>>>>>>>>>>>>> screen size, the screen resolution, the DPI of the
>>>>>>>>>>>>>>>>>>>> screen, and
>>>>>>>>>>>>>>>>>>>> form
>>>>>>>>>>>>>>>>>>>> factor.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Use resource loading for bitmap images in the app 
>>>>>>>>>>>>>>>>>>>> package
>>>>>>>>>>>>>>>>>>>> For
>>>>>>>>>>>>>>>>>>>> bitmap
>>>>>>>>>>>>>>>>>>>> images stored
>>>>>>>>>>>>>>>>>>>> in the app package, provide a separate image for each
>>>>>>>>>>>>>>>>>>>> scaling
>>>>>>>>>>>>>>>>>>>> factor(100%, 140%, and 180%),
>>>>>>>>>>>>>>>>>>>> and name your image files using the "scale" naming
>>>>>>>>>>>>>>>>>>>> convention
>>>>>>>>>>>>>>>>>>>> described
>>>>>>>>>>>>>>>>>>>> below.
>>>>>>>>>>>>>>>>>>>> Windows loads the right image for the current scale
>>>>>>>>>>>>>>>>>>>> automatically.
>>>>>>>>>>>>>>>>>>>> --------------------------------
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>   The image name convention for the various scales is:
>>>>>>>>>>>>>>>>>>>> images/logo.scale-100.png
>>>>>>>>>>>>>>>>>>>> images/logo.scale-140.png
>>>>>>>>>>>>>>>>>>>> images/logo.scale-180.png
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>    The 'ms-appx:///images/logo.png' uri is used to 
>>>>>>>>>>>>>>>>>>>> load the
>>>>>>>>>>>>>>>>>>>> image
>>>>>>>>>>>>>>>>>>>> in an
>>>>>>>>>>>>>>>>>>>> application.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>    If we want to support this in the same way as it 
>>>>>>>>>>>>>>>>>>>> is done
>>>>>>>>>>>>>>>>>>>> for Mac
>>>>>>>>>>>>>>>>>>>> OS X
>>>>>>>>>>>>>>>>>>>>    the WToolkit should return MultiResolution image in
>>>>>>>>>>>>>>>>>>>> case if
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> loaded image has .scale-* qualifiers.
>>>>>>>>>>>>>>>>>>>>    The Graphics class can request an image with 
>>>>>>>>>>>>>>>>>>>> necessary
>>>>>>>>>>>>>>>>>>>> resolution
>>>>>>>>>>>>>>>>>>>> from the MultiResolution image.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>    It seems that nothing should be changed in the
>>>>>>>>>>>>>>>>>>>> MultiResolution
>>>>>>>>>>>>>>>>>>>> interface in this case.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>     Thanks,
>>>>>>>>>>>>>>>>>>>>     Alexandr.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>             ...jim
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On 1/14/14 2:54 AM, Alexander Scherbatiy wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Hello,
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Could you review the fix:
>>>>>>>>>>>>>>>>>>>>>>    bug: 
>>>>>>>>>>>>>>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8029339
>>>>>>>>>>>>>>>>>>>>>>    webrev:
>>>>>>>>>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8029339/webrev.00 
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    This is a proposal to introduce an API that 
>>>>>>>>>>>>>>>>>>>>>> allows to
>>>>>>>>>>>>>>>>>>>>>> create a
>>>>>>>>>>>>>>>>>>>>>> custom
>>>>>>>>>>>>>>>>>>>>>> multi resolution image.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I. It seems reasonable that the API should 
>>>>>>>>>>>>>>>>>>>>>> provide two
>>>>>>>>>>>>>>>>>>>>>> basic
>>>>>>>>>>>>>>>>>>>>>> operations:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   1. Get the resolution variant based on the 
>>>>>>>>>>>>>>>>>>>>>> requested
>>>>>>>>>>>>>>>>>>>>>> image
>>>>>>>>>>>>>>>>>>>>>> width and
>>>>>>>>>>>>>>>>>>>>>> height:
>>>>>>>>>>>>>>>>>>>>>>      - Image getResolutionVariant(int width, int 
>>>>>>>>>>>>>>>>>>>>>> height)
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>     Usually the system provides the scale factor 
>>>>>>>>>>>>>>>>>>>>>> which
>>>>>>>>>>>>>>>>>>>>>> represents
>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>> number of pixels corresponding to each linear 
>>>>>>>>>>>>>>>>>>>>>> unit on the
>>>>>>>>>>>>>>>>>>>>>> display.
>>>>>>>>>>>>>>>>>>>>>>     However, it has sense to combine the scale 
>>>>>>>>>>>>>>>>>>>>>> factor and
>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>> current
>>>>>>>>>>>>>>>>>>>>>> transformations to get the actual image size to be
>>>>>>>>>>>>>>>>>>>>>> displayed.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   2. Get all provided resolution variants:
>>>>>>>>>>>>>>>>>>>>>>     - List<Image> getResolutionVariants()
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    There are several uses cases:
>>>>>>>>>>>>>>>>>>>>>>     - Create a new multi-resolution image based 
>>>>>>>>>>>>>>>>>>>>>> on the
>>>>>>>>>>>>>>>>>>>>>> given
>>>>>>>>>>>>>>>>>>>>>> multi-resolution image.
>>>>>>>>>>>>>>>>>>>>>>     - Pass to the native system the multi-resolution
>>>>>>>>>>>>>>>>>>>>>> image. For
>>>>>>>>>>>>>>>>>>>>>> example,
>>>>>>>>>>>>>>>>>>>>>> a use can set to the system the custom 
>>>>>>>>>>>>>>>>>>>>>> multi-resolution
>>>>>>>>>>>>>>>>>>>>>> cursor.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> II. There are some possible ways where the new 
>>>>>>>>>>>>>>>>>>>>>> API can be
>>>>>>>>>>>>>>>>>>>>>> added
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   1. java.awt.Image.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    The 2 new methods can be added to the Image 
>>>>>>>>>>>>>>>>>>>>>> class. A
>>>>>>>>>>>>>>>>>>>>>> user
>>>>>>>>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>>>>>>>>> override
>>>>>>>>>>>>>>>>>>>>>>    the getResolutionVariant() and 
>>>>>>>>>>>>>>>>>>>>>> getResolutionVariants()
>>>>>>>>>>>>>>>>>>>>>> methods to
>>>>>>>>>>>>>>>>>>>>>> provide the resolution variants
>>>>>>>>>>>>>>>>>>>>>>    or there can be default implementations of these
>>>>>>>>>>>>>>>>>>>>>> methods
>>>>>>>>>>>>>>>>>>>>>> if a
>>>>>>>>>>>>>>>>>>>>>> user
>>>>>>>>>>>>>>>>>>>>>> puts resolution variants
>>>>>>>>>>>>>>>>>>>>>>    to the list in the sorted order.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    To check that the image has resolution 
>>>>>>>>>>>>>>>>>>>>>> variants the
>>>>>>>>>>>>>>>>>>>>>> following
>>>>>>>>>>>>>>>>>>>>>> statement can be used:
>>>>>>>>>>>>>>>>>>>>>> image.getResolutionVariants().size()
>>>>>>>>>>>>>>>>>>>>>> != 1
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    The disadvantage is that there is an overhead 
>>>>>>>>>>>>>>>>>>>>>> that the
>>>>>>>>>>>>>>>>>>>>>> Image
>>>>>>>>>>>>>>>>>>>>>> class
>>>>>>>>>>>>>>>>>>>>>> should contain the List object and not all
>>>>>>>>>>>>>>>>>>>>>>    images can have resolution variants.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   2. Introduce new MultiResolutionImage interface.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    A user should extend Image class and implement 
>>>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>> MultiResolutionImage interface.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>    For example:
>>>>>>>>>>>>>>>>>>>>>>    ---------------------
>>>>>>>>>>>>>>>>>>>>>>      public class CustomMultiResolutionImage extends
>>>>>>>>>>>>>>>>>>>>>> BufferedImage
>>>>>>>>>>>>>>>>>>>>>>              implements MultiResolutionImage {
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>          Image highResolutionImage;
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>          public 
>>>>>>>>>>>>>>>>>>>>>> CustomMultiResolutionImage(BufferedImage
>>>>>>>>>>>>>>>>>>>>>> baseImage,
>>>>>>>>>>>>>>>>>>>>>> BufferedImage highResolutionImage) {
>>>>>>>>>>>>>>>>>>>>>> super(baseImage.getWidth(),
>>>>>>>>>>>>>>>>>>>>>> baseImage.getHeight(),
>>>>>>>>>>>>>>>>>>>>>> baseImage.getType());
>>>>>>>>>>>>>>>>>>>>>> this.highResolutionImage = highResolutionImage;
>>>>>>>>>>>>>>>>>>>>>>              Graphics g = getGraphics();
>>>>>>>>>>>>>>>>>>>>>> g.drawImage(baseImage, 0, 0, null);
>>>>>>>>>>>>>>>>>>>>>> g.dispose();
>>>>>>>>>>>>>>>>>>>>>>          }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>          @Override
>>>>>>>>>>>>>>>>>>>>>>          public Image getResolutionVariant(int 
>>>>>>>>>>>>>>>>>>>>>> width, int
>>>>>>>>>>>>>>>>>>>>>> height) {
>>>>>>>>>>>>>>>>>>>>>>              return ((width <= getWidth() && 
>>>>>>>>>>>>>>>>>>>>>> height <=
>>>>>>>>>>>>>>>>>>>>>> getHeight()))
>>>>>>>>>>>>>>>>>>>>>>                      ? this : highResolutionImage;
>>>>>>>>>>>>>>>>>>>>>>          }
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>          @Override
>>>>>>>>>>>>>>>>>>>>>>          public List<Image> 
>>>>>>>>>>>>>>>>>>>>>> getResolutionVariants() {
>>>>>>>>>>>>>>>>>>>>>>              return Arrays.asList(this,
>>>>>>>>>>>>>>>>>>>>>> highResolutionImage);
>>>>>>>>>>>>>>>>>>>>>>          }
>>>>>>>>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>>>>>>>>    ---------------------
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   The current fix adds the MultiResolutionImage 
>>>>>>>>>>>>>>>>>>>>>> interface
>>>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>>> public
>>>>>>>>>>>>>>>>>>>>>> resolution variant rendering hints.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>>>> Alexandr.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>
>>>
>>
>



More information about the macosx-port-dev mailing list