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

Alexander Scherbatiy alexandr.scherbatiy at oracle.com
Wed Jun 4 14:29:42 UTC 2014


   Hi Phil,

   Could you review the fix where only new MultiResolutionImage 
interface and AbstractMultiResolutionImage class are added:
      http://cr.openjdk.java.net/~alexsch/8029339/webrev.05/

   Thanks,
   Alexandr.


On 5/19/2014 2:46 PM, Alexander Scherbatiy wrote:
>
>   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 2d-dev mailing list