From jesmith at kaon.com Thu May 1 20:09:15 2014 From: jesmith at kaon.com (Joshua Smith) Date: Thu, 1 May 2014 16:09:15 -0400 Subject: Handling Opening Files Message-ID: <534D4473-AFBA-40B9-943C-067D310CE136@kaon.com> I?ve finally bitten the bullet and moved over to Java 7 on Mac. The only thing I?m stuck on is handling opening files when they are double-clicked in the Finder or dropped on my program in the Dock. Are there any changes required to the file handling stuff in Info.plist for Java 7, or should one that worked with the previous Java still work? Previously, I had this to handle the files: com.apple.mrj.MRJApplicationUtils.registerOpenDocumentHandler(m); Some googling revealed that now I need this: com.apple.eawt.Application.getApplication().setOpenFileHandler(m); Double-clicking the file is opening my app, but the OpenFileHandler is never called. (Note that Application.getApplication().addApplicationListener(m) *is* working; I?m able to intercept Quit like I used to.) If my program was not running, it opens. But no handler call. If my program was already running, it pops to the foreground. But no handler call. What?s the trick? -Joshua From mik3hall at gmail.com Thu May 1 20:59:01 2014 From: mik3hall at gmail.com (Michael Hall) Date: Thu, 1 May 2014 15:59:01 -0500 Subject: Handling Opening Files In-Reply-To: <534D4473-AFBA-40B9-943C-067D310CE136@kaon.com> References: <534D4473-AFBA-40B9-943C-067D310CE136@kaon.com> Message-ID: <217F053A-0B56-4761-A3FC-5CDED5AAE1CE@gmail.com> On May 1, 2014, at 3:09 PM, Joshua Smith wrote: > I?ve finally bitten the bullet and moved over to Java 7 on Mac. > > The only thing I?m stuck on is handling opening files when they are double-clicked in the Finder or dropped on my program in the Dock. > > Are there any changes required to the file handling stuff in Info.plist for Java 7, or should one that worked with the previous Java still work? This used to work for my AppConverter application. I haven't tried it lately. If you still have a Apple JVM application just try dragging it to the application. That should tell you if it works. If it doesn't something maybe is broke now. If it does you can check the source, I believe OSXApplication was the class. Not sure I tested dragging to the Dock though, I usually tested dragging to the app itself. Michael Hall trz nio.2 for OS X http://www195.pair.com/mik3hall/index.html#trz HalfPipe Java 6/7 shell app http://www195.pair.com/mik3hall/index.html#halfpipe AppConverter convert Apple jvm to openjdk apps http://www195.pair.com/mik3hall/index.html#appconverter From ivan at nikitin.io Mon May 5 07:13:56 2014 From: ivan at nikitin.io (Ivan Nikitin) Date: Mon, 05 May 2014 11:13:56 +0400 Subject: Handling Opening Files In-Reply-To: <534D4473-AFBA-40B9-943C-067D310CE136@kaon.com> References: <534D4473-AFBA-40B9-943C-067D310CE136@kaon.com> Message-ID: <53673A34.2090505@nikitin.io> Hi Joshua, We also have Document types record in the Info.plist file of our bundle: CFBundleTypeName Images CFBundleTypeRole Viewer LSHandlerRank Alternate LSItemContentTypes public.image NSExportableTypes public.image CFBundleTypeName Folders CFBundleTypeRole Viewer LSHandlerRank None LSItemContentTypes public.folder This is a list of file types the app can handle. With it open file handler is called correctly. We're using OpenJDK 7u45. Joshua Smith wrote: > I?ve finally bitten the bullet and moved over to Java 7 on Mac. > > The only thing I?m stuck on is handling opening files when they are double-clicked in the Finder or dropped on my program in the Dock. > > Are there any changes required to the file handling stuff in Info.plist for Java 7, or should one that worked with the previous Java still work? > > Previously, I had this to handle the files: > > com.apple.mrj.MRJApplicationUtils.registerOpenDocumentHandler(m); > > Some googling revealed that now I need this: > > com.apple.eawt.Application.getApplication().setOpenFileHandler(m); > > Double-clicking the file is opening my app, but the OpenFileHandler is never called. > > (Note that Application.getApplication().addApplicationListener(m) *is* working; I?m able to intercept Quit like I used to.) > > If my program was not running, it opens. But no handler call. > > If my program was already running, it pops to the foreground. But no handler call. > > What?s the trick? > > -Joshua > > -- Ivan Nikitin From mik3hall at gmail.com Mon May 5 09:03:26 2014 From: mik3hall at gmail.com (Michael Hall) Date: Mon, 5 May 2014 04:03:26 -0500 Subject: Handling Opening Files In-Reply-To: <53673A34.2090505@nikitin.io> References: <534D4473-AFBA-40B9-943C-067D310CE136@kaon.com> <53673A34.2090505@nikitin.io> Message-ID: > Joshua Smith wrote: >> I?ve finally bitten the bullet and moved over to Java 7 on Mac. >> >> The only thing I?m stuck on is handling opening files when they are double-clicked in the Finder or dropped on my program in the Dock. >> >> Are there any changes required to the file handling stuff in Info.plist for Java 7, or should one that worked with the previous Java still work? >> >> Previously, I had this to handle the files: >> >> com.apple.mrj.MRJApplicationUtils.registerOpenDocumentHandler(m); On May 5, 2014, at 2:13 AM, Ivan Nikitin wrote: > Hi Joshua, > > We also have Document types record in the Info.plist file of our bundle: > Unchanged from Java 6 to Java 7. There should be no plist differences. No other differences either really, the Java 7 is as far as I know the Apple Java 6 contributed code. Michael Hall trz nio.2 for OS X http://www195.pair.com/mik3hall/index.html#trz HalfPipe Java 6/7 shell app http://www195.pair.com/mik3hall/index.html#halfpipe AppConverter convert Apple jvm to openjdk apps http://www195.pair.com/mik3hall/index.html#appconverter From alexandr.scherbatiy at oracle.com Mon May 12 14:35:45 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Mon, 12 May 2014 18:35:45 +0400 Subject: [OpenJDK 2D-Dev] [9] Review request for 8029339 Custom MultiResolution image support on HiDPI displays In-Reply-To: <535A7509.6050802@oracle.com> References: <52D51764.8020103@oracle.com> <52DF2F98.3030503@oracle.com> <52F4BCEB.9040702@oracle.com> <52F5782A.9060300@oracle.com> <52FB7E3E.6050000@oracle.com> <52FC14EC.9080503@oracle.com> <53037D3D.80709@oracle.com> <5307E71E.50607@oracle.com> <530F3592.40600@oracle.com> <532B00AD.1000704@oracle.com> <532B7EC5.9000206@oracle.com> <532C4DD7.1080804@oracle.com> <532CD202.5070508@oracle.com> <53302A8E.6090107@oracle.com> <53343914.6090004@oracle.com> <533C8DDB.5000406@oracle.com> <533E9D42.10409@oracle.com> <53598D86.5020607@oracle.com> <535A7509.6050802@oracle.com> Message-ID: <5370DC41.5080608@oracle.com> 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 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 Image createMRImage(final RVChooser rvChooser, >>>>> final Type baseImageSeed, final Function >>>>> 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 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 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 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 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 >>>>>>>>>>> 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 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 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 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 getResolutionVariants() { >>>>>>>>>>>>>>>>>>> return Arrays.asList(this, >>>>>>>>>>>>>>>>>>> highResolutionImage); >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> --------------------- >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> The current fix adds the MultiResolutionImage >>>>>>>>>>>>>>>>>>> interface >>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>> public >>>>>>>>>>>>>>>>>>> resolution variant rendering hints. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>> Alexandr. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>> >>>>>> >>>>> >>> > From alexandr.scherbatiy at oracle.com Fri May 16 16:16:21 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Fri, 16 May 2014 20:16:21 +0400 Subject: [OpenJDK 2D-Dev] [9] Review request for 8029339 Custom MultiResolution image support on HiDPI displays In-Reply-To: <5370DC41.5080608@oracle.com> References: <52D51764.8020103@oracle.com> <52DF2F98.3030503@oracle.com> <52F4BCEB.9040702@oracle.com> <52F5782A.9060300@oracle.com> <52FB7E3E.6050000@oracle.com> <52FC14EC.9080503@oracle.com> <53037D3D.80709@oracle.com> <5307E71E.50607@oracle.com> <530F3592.40600@oracle.com> <532B00AD.1000704@oracle.com> <532B7EC5.9000206@oracle.com> <532C4DD7.1080804@oracle.com> <532CD202.5070508@oracle.com> <53302A8E.6090107@oracle.com> <53343914.6090004@oracle.com> <533C8DDB.5000406@oracle.com> <533E9D42.10409@oracle.com> <53598D86.5020607@oracle.com> <535A7509.6050802@oracle.com> <5370DC41.5080608@oracle.com> Message-ID: <537639D5.9000206@oracle.com> 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 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 Image createMRImage(final RVChooser rvChooser, >>>>>> final Type baseImageSeed, final Function >>>>>> 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 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 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 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 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 >>>>>>>>>>>> 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 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 >>>>>>>>>>>>>>> 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 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 getResolutionVariants() { >>>>>>>>>>>>>>>>>>>> return Arrays.asList(this, >>>>>>>>>>>>>>>>>>>> highResolutionImage); >>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>> --------------------- >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> The current fix adds the MultiResolutionImage >>>>>>>>>>>>>>>>>>>> interface >>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>> public >>>>>>>>>>>>>>>>>>>> resolution variant rendering hints. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>> Alexandr. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>> >>>>>>> >>>>>> >>>> >> > From philip.race at oracle.com Fri May 16 17:12:32 2014 From: philip.race at oracle.com (Phil Race) Date: Fri, 16 May 2014 10:12:32 -0700 Subject: [OpenJDK 2D-Dev] [9] Review request for 8029339 Custom MultiResolution image support on HiDPI displays In-Reply-To: <537639D5.9000206@oracle.com> References: <52D51764.8020103@oracle.com> <52DF2F98.3030503@oracle.com> <52F4BCEB.9040702@oracle.com> <52F5782A.9060300@oracle.com> <52FB7E3E.6050000@oracle.com> <52FC14EC.9080503@oracle.com> <53037D3D.80709@oracle.com> <5307E71E.50607@oracle.com> <530F3592.40600@oracle.com> <532B00AD.1000704@oracle.com> <532B7EC5.9000206@oracle.com> <532C4DD7.1080804@oracle.com> <532CD202.5070508@oracle.com> <53302A8E.6090107@oracle.com> <53343914.6090004@oracle.com> <533C8DDB.5000406@oracle.com> <533E9D42.10409@oracle.com> <53598D86.5020607@oracle.com> <535A7509.6050802@oracle.com> <5370DC41.5080608@oracle.com> <537639D5.9000206@oracle.com> Message-ID: <53764700.2060309@oracle.com> 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 ? 2. What kinds of classes are expected to implement MultiResolutionImage Application ones or platform ones ? 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. 4. public List 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 ? 5. Why is the rendering hint needed ? -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 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 Image createMRImage(final RVChooser rvChooser, >>>>>>> final Type baseImageSeed, final Function >>>>>>> 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 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 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 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 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 >>>>>>>>>>>>> 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 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 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 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 getResolutionVariants() { >>>>>>>>>>>>>>>>>>>>> return Arrays.asList(this, >>>>>>>>>>>>>>>>>>>>> highResolutionImage); >>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>> --------------------- >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> The current fix adds the MultiResolutionImage >>>>>>>>>>>>>>>>>>>>> interface >>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>> public >>>>>>>>>>>>>>>>>>>>> resolution variant rendering hints. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>>> Alexandr. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>> >>>>>>>> >>>>>>> >>>>> >>> >> > From alexandr.scherbatiy at oracle.com Mon May 19 10:46:47 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Mon, 19 May 2014 14:46:47 +0400 Subject: [OpenJDK 2D-Dev] [9] Review request for 8029339 Custom MultiResolution image support on HiDPI displays In-Reply-To: <53764700.2060309@oracle.com> References: <52D51764.8020103@oracle.com> <52DF2F98.3030503@oracle.com> <52F4BCEB.9040702@oracle.com> <52F5782A.9060300@oracle.com> <52FB7E3E.6050000@oracle.com> <52FC14EC.9080503@oracle.com> <53037D3D.80709@oracle.com> <5307E71E.50607@oracle.com> <530F3592.40600@oracle.com> <532B00AD.1000704@oracle.com> <532B7EC5.9000206@oracle.com> <532C4DD7.1080804@oracle.com> <532CD202.5070508@oracle.com> <53302A8E.6090107@oracle.com> <53343914.6090004@oracle.com> <533C8DDB.5000406@oracle.com> <533E9D42.10409@oracle.com> <53598D86.5020607@oracle.com> <535A7509.6050802@oracle.com> <5370DC41.5080608@oracle.com> <537639D5.9000206@oracle.com> <53764700.2060309@oracle.com> Message-ID: <5379E117.6010202@oracle.com> 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 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 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 Image createMRImage(final RVChooser rvChooser, >>>>>>>> final Type baseImageSeed, final Function >>>>>>>> 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 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 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 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 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 >>>>>>>>>>>>>> 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 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 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 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 >>>>>>>>>>>>>>>>>>>>>> getResolutionVariants() { >>>>>>>>>>>>>>>>>>>>>> return Arrays.asList(this, >>>>>>>>>>>>>>>>>>>>>> highResolutionImage); >>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>>>>> --------------------- >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> The current fix adds the MultiResolutionImage >>>>>>>>>>>>>>>>>>>>>> interface >>>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>> public >>>>>>>>>>>>>>>>>>>>>> resolution variant rendering hints. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>>>> Alexandr. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>> >>>> >>> >> > From puybaret at eteks.com Tue May 20 14:26:39 2014 From: puybaret at eteks.com (Emmanuel Puybaret) Date: Tue, 20 May 2014 16:26:39 +0200 Subject: Shape filled with a pattern not printed Message-ID: <2E1D156C-3D9C-48FE-A932-C3C79D9E1574@eteks.com> Hi, Are there any news about the bug in Java 7u40 and 7u60 beta versions that prevents to print a shape filled with a pattern? Here'a simple simple example to let you test this issue: import java.awt.*; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.print.*; public class PatternFillBug { public static void main(String [] args) throws PrinterException { PrinterJob printerJob = PrinterJob.getPrinterJob(); printerJob.setPrintable(new Printable() { public int print(Graphics g, PageFormat pageFormat, int index) throws PrinterException { if (index == 1) { return NO_SUCH_PAGE; } // Create a simple pattern BufferedImage patternImage = new BufferedImage(2, 2, BufferedImage.TYPE_INT_ARGB); Graphics gImage = patternImage.getGraphics(); gImage.setColor(Color.WHITE); gImage.drawLine(0, 1, 1, 0); gImage.setColor(Color.BLACK); gImage.drawLine(0, 0, 1, 1); gImage.dispose(); Graphics2D g2D = (Graphics2D)g; // Fill a part of the page with pattern Rectangle2D.Double shape = new Rectangle2D.Double(pageFormat.getImageableX(), pageFormat.getImageableY(), pageFormat.getImageableWidth() / 5, pageFormat.getImageableHeight() / 5); g2D.setPaint(new TexturePaint(patternImage, new Rectangle2D.Double(0, 0, pageFormat.getImageableWidth() / 50, pageFormat.getImageableHeight() / 50))); g2D.fill(shape); // Surround it with a rectangle g2D.setPaint(Color.BLACK); g2D.draw(shape); return PAGE_EXISTS; } }); // Show print dialog and print if (printerJob.printDialog()) { printerJob.print(); } } } The bug happens also when you choose to print to PDF in OSX print dialog box. I reported this bug to Oracle in september 2013, but the URL keeps saying that the bug is not available: http://bugs.sun.com/view_bug.do?bug_id=9007022 It would be nice to make submitted bugs public again when they are not related to a security issue. It's so frustrating to wonder if someone else posted the same bug. :-( Regards, -- Emmanuel PUYBARET Email : puybaret at eteks.com Web : http://www.eteks.com http://www.sweethome3d.com From roger.lewis at oracle.com Tue May 20 14:30:08 2014 From: roger.lewis at oracle.com (Roger Lewis) Date: Tue, 20 May 2014 07:30:08 -0700 Subject: Shape filled with a pattern not printed In-Reply-To: <2E1D156C-3D9C-48FE-A932-C3C79D9E1574@eteks.com> References: <2E1D156C-3D9C-48FE-A932-C3C79D9E1574@eteks.com> Message-ID: <537B66F0.4090101@oracle.com> Hello Emmanuel, Your bug report can be seen here: https://bugs.openjdk.java.net/browse/JDK-8040635 -Roger On 5/20/14, 7:26 AM, Emmanuel Puybaret wrote: > Hi, > > Are there any news about the bug in Java 7u40 and 7u60 beta versions that prevents to print a shape filled with a pattern? > Here'a simple simple example to let you test this issue: > > import java.awt.*; > import java.awt.geom.Rectangle2D; > import java.awt.image.BufferedImage; > import java.awt.print.*; > > public class PatternFillBug { > public static void main(String [] args) throws PrinterException { > PrinterJob printerJob = PrinterJob.getPrinterJob(); > printerJob.setPrintable(new Printable() { > public int print(Graphics g, PageFormat pageFormat, > int index) throws PrinterException { > if (index == 1) { > return NO_SUCH_PAGE; > } > // Create a simple pattern > BufferedImage patternImage = new BufferedImage(2, 2, BufferedImage.TYPE_INT_ARGB); > Graphics gImage = patternImage.getGraphics(); > gImage.setColor(Color.WHITE); > gImage.drawLine(0, 1, 1, 0); > gImage.setColor(Color.BLACK); > gImage.drawLine(0, 0, 1, 1); > gImage.dispose(); > > Graphics2D g2D = (Graphics2D)g; > // Fill a part of the page with pattern > Rectangle2D.Double shape = new Rectangle2D.Double(pageFormat.getImageableX(), pageFormat.getImageableY(), > pageFormat.getImageableWidth() / 5, pageFormat.getImageableHeight() / 5); > g2D.setPaint(new TexturePaint(patternImage, new Rectangle2D.Double(0, 0, > pageFormat.getImageableWidth() / 50, pageFormat.getImageableHeight() / 50))); > g2D.fill(shape); > // Surround it with a rectangle > g2D.setPaint(Color.BLACK); > g2D.draw(shape); > return PAGE_EXISTS; > } > }); > > // Show print dialog and print > if (printerJob.printDialog()) { > printerJob.print(); > } > } > } > > > The bug happens also when you choose to print to PDF in OSX print dialog box. > > I reported this bug to Oracle in september 2013, but the URL keeps saying that the bug is not available: > http://bugs.sun.com/view_bug.do?bug_id=9007022 > It would be nice to make submitted bugs public again when they are not related to a security issue. > It's so frustrating to wonder if someone else posted the same bug. :-( > > Regards, > -- > Emmanuel PUYBARET > Email : puybaret at eteks.com > Web : http://www.eteks.com > http://www.sweethome3d.com > From alexandr.scherbatiy at oracle.com Tue May 20 14:32:28 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Tue, 20 May 2014 18:32:28 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <536109EE.1020303@oracle.com> References: <536109EE.1020303@oracle.com> Message-ID: <537B677C.7000302@oracle.com> Hello, Could you look at the fix? Thanks, Alexandr. On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: > > Hello, > > Could you review the fix: > bug: https://bugs.openjdk.java.net/browse/JDK-8040291 > webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 > > > The SunToolkit.prepareResolutionVariant() method wraps the base > image observer and > passes it to the resolution variant. It leads that the resolution > variant notifies > the base image about info changing. > > When the base image is loaded by the MediaTracker and the resolution > variant is loaded > first it calls the base image observer and wrongly finishes the base > image loading. > > > The fix passes the reduced resolution variant info flags to the base > image > so the base image loading is finished only after notifiing by the > original base image observer. > > > Thanks, > Alexandr. > From petr.pchelko at oracle.com Tue May 20 14:46:54 2014 From: petr.pchelko at oracle.com (Petr Pchelko) Date: Tue, 20 May 2014 18:46:54 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <537B677C.7000302@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> Message-ID: <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> Hello, Alexander. SunToolkit:876 size == -1 ? -1 : size What?s going on here? Isn?t this equal to just size? I believe is?t wrong and the size should be multiplied by 2 somewhere? If the method is wrong how does the test pass? With best regards. Petr. On May 20, 2014, at 6:32 PM, Alexander Scherbatiy wrote: > > Hello, > > Could you look at the fix? > > Thanks, > Alexandr. > > On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >> >> Hello, >> >> Could you review the fix: >> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >> >> >> The SunToolkit.prepareResolutionVariant() method wraps the base image observer and >> passes it to the resolution variant. It leads that the resolution variant notifies >> the base image about info changing. >> >> When the base image is loaded by the MediaTracker and the resolution variant is loaded >> first it calls the base image observer and wrongly finishes the base image loading. >> >> >> The fix passes the reduced resolution variant info flags to the base image >> so the base image loading is finished only after notifiing by the original base image observer. >> >> >> Thanks, >> Alexandr. >> > From puybaret at eteks.com Tue May 20 15:04:10 2014 From: puybaret at eteks.com (Emmanuel Puybaret) Date: Tue, 20 May 2014 17:04:10 +0200 Subject: Shape filled with a pattern not printed In-Reply-To: <537B66F0.4090101@oracle.com> References: <2E1D156C-3D9C-48FE-A932-C3C79D9E1574@eteks.com> <537B66F0.4090101@oracle.com> Message-ID: Thanks Roger for pointing to the bug report. It's reassuring to see the bug wasn't forgotten. :-) 7u80 seems very far but as long as I can provide some kind of workaround, users will be able to live with it. For more information, see http://www.sweethome3d.com/support/forum/viewthread_thread,4991 Regards, -- Emmanuel Le 20 mai 2014 ? 16:30, Roger Lewis a ?crit : > Hello Emmanuel, > Your bug report can be seen here: https://bugs.openjdk.java.net/browse/JDK-8040635 > > -Roger > > On 5/20/14, 7:26 AM, Emmanuel Puybaret wrote: >> Hi, >> >> Are there any news about the bug in Java 7u40 and 7u60 beta versions that prevents to print a shape filled with a pattern? >> >> [...] >> >> I reported this bug to Oracle in september 2013, but the URL keeps saying that the bug is not available: >> http://bugs.sun.com/view_bug.do?bug_id=9007022 >> It would be nice to make submitted bugs public again when they are not related to a security issue. >> It's so frustrating to wonder if someone else posted the same bug. :-( >> >> Regards, >> -- >> Emmanuel PUYBARET >> Email : puybaret at eteks.com >> Web : http://www.eteks.com >> http://www.sweethome3d.com From alexandr.scherbatiy at oracle.com Tue May 20 15:07:14 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Tue, 20 May 2014 19:07:14 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> Message-ID: <537B6FA2.1090903@oracle.com> Could you review the updated fix: http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 - The getRVSize() method from the SunToolkit is fixed On 5/20/2014 6:46 PM, Petr Pchelko wrote: > Hello, Alexander. > > SunToolkit:876 size == -1 ? -1 : size > > What?s going on here? Isn?t this equal to just size? > I believe is?t wrong and the size should be multiplied by 2 somewhere? > If the method is wrong how does the test pass? The test passes because it uses SunToolkit.prepareImage() method with the -1 size. It also uses the image observer that requires to load all image bits. Thanks, Alexandr. > > > With best regards. Petr. > > On May 20, 2014, at 6:32 PM, Alexander Scherbatiy wrote: > >> Hello, >> >> Could you look at the fix? >> >> Thanks, >> Alexandr. >> >> On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >>> Hello, >>> >>> Could you review the fix: >>> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >>> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >>> >>> >>> The SunToolkit.prepareResolutionVariant() method wraps the base image observer and >>> passes it to the resolution variant. It leads that the resolution variant notifies >>> the base image about info changing. >>> >>> When the base image is loaded by the MediaTracker and the resolution variant is loaded >>> first it calls the base image observer and wrongly finishes the base image loading. >>> >>> >>> The fix passes the reduced resolution variant info flags to the base image >>> so the base image loading is finished only after notifiing by the original base image observer. >>> >>> >>> Thanks, >>> Alexandr. >>> From petr.pchelko at oracle.com Tue May 20 15:32:56 2014 From: petr.pchelko at oracle.com (Petr Pchelko) Date: Tue, 20 May 2014 19:32:56 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <537B6FA2.1090903@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> <537B6FA2.1090903@oracle.com> Message-ID: <614D8A0A-435D-46C8-9688-3A4ED1AF2F41@oracle.com> > Could you review the updated fix: > http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 > > - The getRVSize() method from the SunToolkit is fixed Thank you for the update, but I still have questions about the test: 1. There?s a typo in isRVObserevr. 2. Do we need the isRVObserevr method? How could it be that this method return false in this test and it?s a correct behavior and not a bug? I see it?s only possible from SunToolkit.prepareImage if bits are ERROR | ABORT. Couldn?t we get rid of this method? Walking up the stack doesn?t look like the most reliable solution.. With best regards. Petr. On May 20, 2014, at 7:07 PM, Alexander Scherbatiy wrote: > > Could you review the updated fix: > http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 > > - The getRVSize() method from the SunToolkit is fixed > > On 5/20/2014 6:46 PM, Petr Pchelko wrote: >> Hello, Alexander. >> >> SunToolkit:876 size == -1 ? -1 : size >> >> What?s going on here? Isn?t this equal to just size? >> I believe is?t wrong and the size should be multiplied by 2 somewhere? >> If the method is wrong how does the test pass? > The test passes because it uses SunToolkit.prepareImage() method with the -1 size. > It also uses the image observer that requires to load all image bits. > > Thanks, > Alexandr. > >> >> With best regards. Petr. >> >> On May 20, 2014, at 6:32 PM, Alexander Scherbatiy wrote: >> >>> Hello, >>> >>> Could you look at the fix? >>> >>> Thanks, >>> Alexandr. >>> >>> On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >>>> Hello, >>>> >>>> Could you review the fix: >>>> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >>>> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >>>> >>>> >>>> The SunToolkit.prepareResolutionVariant() method wraps the base image observer and >>>> passes it to the resolution variant. It leads that the resolution variant notifies >>>> the base image about info changing. >>>> >>>> When the base image is loaded by the MediaTracker and the resolution variant is loaded >>>> first it calls the base image observer and wrongly finishes the base image loading. >>>> >>>> >>>> The fix passes the reduced resolution variant info flags to the base image >>>> so the base image loading is finished only after notifiing by the original base image observer. >>>> >>>> >>>> Thanks, >>>> Alexandr. >>>> > From alexandr.scherbatiy at oracle.com Wed May 21 10:50:54 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Wed, 21 May 2014 14:50:54 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <614D8A0A-435D-46C8-9688-3A4ED1AF2F41@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> <537B6FA2.1090903@oracle.com> <614D8A0A-435D-46C8-9688-3A4ED1AF2F41@oracle.com> Message-ID: <537C850E.3020704@oracle.com> Could you review the updated fix: http://cr.openjdk.java.net/~alexsch/8040291/webrev.02/ - The isRVObserevr typo is fixed On 5/20/2014 7:32 PM, Petr Pchelko wrote: >> Could you review the updated fix: >> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >> >> - The getRVSize() method from the SunToolkit is fixed > Thank you for the update, but I still have questions about the test: > 1. There?s a typo in isRVObserevr. > 2. Do we need the isRVObserevr method? How could it be that this > method return false in this test and it?s a correct behavior and not a bug? > I see it?s only possible from SunToolkit.prepareImage if bits are ERROR | ABORT. > Couldn?t we get rid of this method? Walking up the stack doesn?t look like the most > reliable solution.. The ImageObserver is used for two purposes in the Toolkit prepareImage() method: - to query which part of the image should be loaded - to notify an object about which image information is available To prepare a multi-resolution image it needs to prepare its resolution variant as well. The only way to know which part of the resolution variant should be loaded is requesting the base image observer. It leads that there will be a notification for the object that contains the resolution variant instead of the base image. To improve it the MultiResolutionToolkitImage wraps the base image observer for the resolution variant. The object gets notification which contains only the base image and updated sizes after that. The another case which is fixed in this issue is that the resolution variant can be loaded first and it notifies the object that the image is loaded. The fix reduces the resolution variant info flags so the object should wait for image loading notification from the base image. The test needs to check that the wrapped observer from the resolution variant does not send more info than the original image has already had. The isRVObserver() just checks that the observer is called from the resolution variant and not is from the base image. Thanks, Alexandr. > > With best regards. Petr. > > On May 20, 2014, at 7:07 PM, Alexander Scherbatiy wrote: > >> Could you review the updated fix: >> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >> >> - The getRVSize() method from the SunToolkit is fixed >> >> On 5/20/2014 6:46 PM, Petr Pchelko wrote: >>> Hello, Alexander. >>> >>> SunToolkit:876 size == -1 ? -1 : size >>> >>> What?s going on here? Isn?t this equal to just size? >>> I believe is?t wrong and the size should be multiplied by 2 somewhere? >>> If the method is wrong how does the test pass? >> The test passes because it uses SunToolkit.prepareImage() method with the -1 size. >> It also uses the image observer that requires to load all image bits. >> >> Thanks, >> Alexandr. >> >>> >>> With best regards. Petr. >>> >>> On May 20, 2014, at 6:32 PM, Alexander Scherbatiy wrote: >>> >>>> Hello, >>>> >>>> Could you look at the fix? >>>> >>>> Thanks, >>>> Alexandr. >>>> >>>> On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >>>>> Hello, >>>>> >>>>> Could you review the fix: >>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >>>>> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >>>>> >>>>> >>>>> The SunToolkit.prepareResolutionVariant() method wraps the base image observer and >>>>> passes it to the resolution variant. It leads that the resolution variant notifies >>>>> the base image about info changing. >>>>> >>>>> When the base image is loaded by the MediaTracker and the resolution variant is loaded >>>>> first it calls the base image observer and wrongly finishes the base image loading. >>>>> >>>>> >>>>> The fix passes the reduced resolution variant info flags to the base image >>>>> so the base image loading is finished only after notifiing by the original base image observer. >>>>> >>>>> >>>>> Thanks, >>>>> Alexandr. >>>>> From alexandr.scherbatiy at oracle.com Wed May 21 13:47:37 2014 From: alexandr.scherbatiy at oracle.com (Alexander Scherbatiy) Date: Wed, 21 May 2014 17:47:37 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <537C850E.3020704@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> <537B6FA2.1090903@oracle.com> <614D8A0A-435D-46C8-9688-3A4ED1AF2F41@oracle.com> <537C850E.3020704@oracle.com> Message-ID: <537CAE79.3040801@oracle.com> Could you review the updated fix: http://cr.openjdk.java.net/~alexsch/8040291/webrev.03/ - The test checks that the resolution-variant observer is called at least once. Thanks, Alexandr. On 5/21/2014 2:50 PM, Alexander Scherbatiy wrote: > > Could you review the updated fix: > http://cr.openjdk.java.net/~alexsch/8040291/webrev.02/ > > - The isRVObserevr typo is fixed > > On 5/20/2014 7:32 PM, Petr Pchelko wrote: >>> Could you review the updated fix: >>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >>> >>> - The getRVSize() method from the SunToolkit is fixed >> Thank you for the update, but I still have questions about the test: >> 1. There?s a typo in isRVObserevr. >> 2. Do we need the isRVObserevr method? How could it be that this >> method return false in this test and it?s a correct behavior and not >> a bug? >> I see it?s only possible from SunToolkit.prepareImage if bits are >> ERROR | ABORT. >> Couldn?t we get rid of this method? Walking up the stack doesn?t look >> like the most >> reliable solution.. > > The ImageObserver is used for two purposes in the Toolkit > prepareImage() method: > - to query which part of the image should be loaded > - to notify an object about which image information is available > > To prepare a multi-resolution image it needs to prepare its > resolution variant as well. > The only way to know which part of the resolution variant should be > loaded is requesting > the base image observer. It leads that there will be a notification > for the object that contains > the resolution variant instead of the base image. To improve it the > MultiResolutionToolkitImage > wraps the base image observer for the resolution variant. The object > gets notification > which contains only the base image and updated sizes after that. > > The another case which is fixed in this issue is that the > resolution variant can be loaded first > and it notifies the object that the image is loaded. The fix reduces > the resolution variant info > flags so the object should wait for image loading notification from > the base image. > > The test needs to check that the wrapped observer from the > resolution variant does not send > more info than the original image has already had. The > isRVObserver() just checks > that the observer is called from the resolution variant and not is > from the base image. > > Thanks, > Alexandr. > >> >> With best regards. Petr. >> >> On May 20, 2014, at 7:07 PM, Alexander Scherbatiy >> wrote: >> >>> Could you review the updated fix: >>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >>> >>> - The getRVSize() method from the SunToolkit is fixed >>> >>> On 5/20/2014 6:46 PM, Petr Pchelko wrote: >>>> Hello, Alexander. >>>> >>>> SunToolkit:876 size == -1 ? -1 : size >>>> >>>> What?s going on here? Isn?t this equal to just size? >>>> I believe is?t wrong and the size should be multiplied by 2 somewhere? >>>> If the method is wrong how does the test pass? >>> The test passes because it uses SunToolkit.prepareImage() method >>> with the -1 size. >>> It also uses the image observer that requires to load all image >>> bits. >>> >>> Thanks, >>> Alexandr. >>> >>>> With best regards. Petr. >>>> >>>> On May 20, 2014, at 6:32 PM, Alexander Scherbatiy >>>> wrote: >>>> >>>>> Hello, >>>>> >>>>> Could you look at the fix? >>>>> >>>>> Thanks, >>>>> Alexandr. >>>>> >>>>> On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >>>>>> Hello, >>>>>> >>>>>> Could you review the fix: >>>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >>>>>> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >>>>>> >>>>>> >>>>>> The SunToolkit.prepareResolutionVariant() method wraps the base >>>>>> image observer and >>>>>> passes it to the resolution variant. It leads that the >>>>>> resolution variant notifies >>>>>> the base image about info changing. >>>>>> >>>>>> When the base image is loaded by the MediaTracker and the >>>>>> resolution variant is loaded >>>>>> first it calls the base image observer and wrongly finishes the >>>>>> base image loading. >>>>>> >>>>>> >>>>>> The fix passes the reduced resolution variant info flags to the >>>>>> base image >>>>>> so the base image loading is finished only after notifiing by >>>>>> the original base image observer. >>>>>> >>>>>> >>>>>> Thanks, >>>>>> Alexandr. >>>>>> > From petr.pchelko at oracle.com Wed May 21 14:00:37 2014 From: petr.pchelko at oracle.com (Petr Pchelko) Date: Wed, 21 May 2014 18:00:37 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <537CAE79.3040801@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> <537B6FA2.1090903@oracle.com> <614D8A0A-435D-46C8-9688-3A4ED1AF2F41@oracle.com> <537C850E.3020704@oracle.com> <537CAE79.3040801@oracle.com> Message-ID: <1AB17DF9-543B-4284-8C47-CBD679F83DAC@oracle.com> Hello, Alexander. The fix looks good. With best regards. Petr. On 21 ??? 2014 ?., at 17:47, Alexander Scherbatiy wrote: > > Could you review the updated fix: > http://cr.openjdk.java.net/~alexsch/8040291/webrev.03/ > > - The test checks that the resolution-variant observer is called at least once. > > Thanks, > Alexandr. > > On 5/21/2014 2:50 PM, Alexander Scherbatiy wrote: >> >> Could you review the updated fix: >> http://cr.openjdk.java.net/~alexsch/8040291/webrev.02/ >> >> - The isRVObserevr typo is fixed >> >> On 5/20/2014 7:32 PM, Petr Pchelko wrote: >>>> Could you review the updated fix: >>>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >>>> >>>> - The getRVSize() method from the SunToolkit is fixed >>> Thank you for the update, but I still have questions about the test: >>> 1. There?s a typo in isRVObserevr. >>> 2. Do we need the isRVObserevr method? How could it be that this >>> method return false in this test and it?s a correct behavior and not a bug? >>> I see it?s only possible from SunToolkit.prepareImage if bits are ERROR | ABORT. >>> Couldn?t we get rid of this method? Walking up the stack doesn?t look like the most >>> reliable solution.. >> >> The ImageObserver is used for two purposes in the Toolkit prepareImage() method: >> - to query which part of the image should be loaded >> - to notify an object about which image information is available >> >> To prepare a multi-resolution image it needs to prepare its resolution variant as well. >> The only way to know which part of the resolution variant should be loaded is requesting >> the base image observer. It leads that there will be a notification for the object that contains >> the resolution variant instead of the base image. To improve it the MultiResolutionToolkitImage >> wraps the base image observer for the resolution variant. The object gets notification >> which contains only the base image and updated sizes after that. >> >> The another case which is fixed in this issue is that the resolution variant can be loaded first >> and it notifies the object that the image is loaded. The fix reduces the resolution variant info >> flags so the object should wait for image loading notification from the base image. >> >> The test needs to check that the wrapped observer from the resolution variant does not send >> more info than the original image has already had. The isRVObserver() just checks >> that the observer is called from the resolution variant and not is from the base image. >> >> Thanks, >> Alexandr. >> >>> >>> With best regards. Petr. >>> >>> On May 20, 2014, at 7:07 PM, Alexander Scherbatiy wrote: >>> >>>> Could you review the updated fix: >>>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >>>> >>>> - The getRVSize() method from the SunToolkit is fixed >>>> >>>> On 5/20/2014 6:46 PM, Petr Pchelko wrote: >>>>> Hello, Alexander. >>>>> >>>>> SunToolkit:876 size == -1 ? -1 : size >>>>> >>>>> What?s going on here? Isn?t this equal to just size? >>>>> I believe is?t wrong and the size should be multiplied by 2 somewhere? >>>>> If the method is wrong how does the test pass? >>>> The test passes because it uses SunToolkit.prepareImage() method with the -1 size. >>>> It also uses the image observer that requires to load all image bits. >>>> >>>> Thanks, >>>> Alexandr. >>>> >>>>> With best regards. Petr. >>>>> >>>>> On May 20, 2014, at 6:32 PM, Alexander Scherbatiy wrote: >>>>> >>>>>> Hello, >>>>>> >>>>>> Could you look at the fix? >>>>>> >>>>>> Thanks, >>>>>> Alexandr. >>>>>> >>>>>> On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >>>>>>> Hello, >>>>>>> >>>>>>> Could you review the fix: >>>>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >>>>>>> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >>>>>>> >>>>>>> >>>>>>> The SunToolkit.prepareResolutionVariant() method wraps the base image observer and >>>>>>> passes it to the resolution variant. It leads that the resolution variant notifies >>>>>>> the base image about info changing. >>>>>>> >>>>>>> When the base image is loaded by the MediaTracker and the resolution variant is loaded >>>>>>> first it calls the base image observer and wrongly finishes the base image loading. >>>>>>> >>>>>>> >>>>>>> The fix passes the reduced resolution variant info flags to the base image >>>>>>> so the base image loading is finished only after notifiing by the original base image observer. >>>>>>> >>>>>>> >>>>>>> Thanks, >>>>>>> Alexandr. >>>>>>> >> > From rengels at ix.netcom.com Thu May 22 02:01:37 2014 From: rengels at ix.netcom.com (robert engels) Date: Thu, 22 May 2014 02:01:37 +0000 (UTC) Subject: Crash on startup in SnowLeopard =?utf-8?b?MS43LjBfNDU=?= References: <5266BD29.4090305@oracle.com> Message-ID: Johannes Schindelin writes: > I have to admit that this makes me very sad. I work in an academic > environment (read: financially restricted unless you happen to work on the > NIH campus in DC) where upgrading is often simply not an option. Yes, this is very sad. The whole premise of "WORA" is being forgotten. There is no technical reason not to support the prior APIs in minor release updates and 7u25 works fine ! We might expect this from Apple builds in order to force OS/equipment upgrades, but from an "open jdk" community it is just sad, very sad. From hs at tagtraum.com Thu May 22 19:05:38 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Thu, 22 May 2014 21:05:38 +0200 Subject: HiDPI/Retina support for -splash option Message-ID: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> Hi, I'm under the impression that the VM option -splash does not honor the @2x notation for HiDPI images. Am I missing something, is that being worked on, or is there a bug report for this (I couldn't find one)? It's a little disappointing when you spend so much time on getting Retina right and then you realize that the very first impression the user gets when starting your app is a bad one, i.e. a blurry splash screen. Thanks! -hendrik From Sergey.Bylokhov at oracle.com Thu May 22 19:16:14 2014 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 22 May 2014 23:16:14 +0400 Subject: HiDPI/Retina support for -splash option In-Reply-To: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> Message-ID: <537E4CFE.6050804@oracle.com> Hi, Hendrik. I think it was overlooked. Please file a new bug at http://bugreport.sun.com/bugreport , don't forget to add a steps to reproduce your issue. Thanks for report! On 5/22/14 11:05 PM, Hendrik Schreiber wrote: > Hi, > > I'm under the impression that the VM option -splash does not honor the @2x notation for HiDPI images. > Am I missing something, is that being worked on, or is there a bug report for this (I couldn't find one)? > > It's a little disappointing when you spend so much time on getting Retina right and then you realize that the very first impression the user gets when starting your app is a bad one, i.e. a blurry splash screen. > > Thanks! > > -hendrik -- Best regards, Sergey. From hs at tagtraum.com Fri May 23 08:59:41 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Fri, 23 May 2014 10:59:41 +0200 Subject: HiDPI/Retina support for -splash option In-Reply-To: <537E4CFE.6050804@oracle.com> References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> <537E4CFE.6050804@oracle.com> Message-ID: <653B3279-EF76-40B7-B388-CA83E172F608@tagtraum.com> On May 22, 2014, at 21:16, Sergey Bylokhov wrote: > I think it was overlooked. Please file a new bug at http://bugreport.sun.com/bugreport , don't forget to add a steps to reproduce your issue. > Thanks for report! Filed the report. The Oracle review id is: JI-9012489 Cheers, -hendrik From paul_t100 at fastmail.fm Fri May 23 10:32:17 2014 From: paul_t100 at fastmail.fm (Paul Taylor) Date: Fri, 23 May 2014 11:32:17 +0100 Subject: HiDPI/Retina support for -splash option In-Reply-To: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> Message-ID: <537F23B1.2010102@fastmail.fm> On 22/05/2014 20:05, Hendrik Schreiber wrote: > Hi, > > I'm under the impression that the VM option -splash does not honor the @2x notation for HiDPI images. > Am I missing something, is that being worked on, or is there a bug report for this (I couldn't find one)? > > It's a little disappointing when you spend so much time on getting Retina right and then you realize that the very first impression the user gets when starting your app is a bad one, i.e. a blurry splash screen. > > Thanks! > > -hendrik But isnt there a much larger problem, the -splash option still broken only to be fixed in https://bugs.openjdk.java.net/browse/JDK-8024185. To clarify using the splash option will prevent my main application from working. Paul From petr.pchelko at oracle.com Fri May 23 10:38:10 2014 From: petr.pchelko at oracle.com (Petr Pchelko) Date: Fri, 23 May 2014 14:38:10 +0400 Subject: HiDPI/Retina support for -splash option In-Reply-To: <537F23B1.2010102@fastmail.fm> References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> <537F23B1.2010102@fastmail.fm> Message-ID: > But isnt there a much larger problem, the -splash option still broken only to be fixed in https://bugs.openjdk.java.net/browse/JDK-8024185. To clarify using the splash option will prevent my main application from working. This fix was integrated in JDK-9 long time ago and didn?t cause any regressions. I think it is safe to back port this to jdk8u20 which I will do right now. With best regards. Petr. On May 23, 2014, at 2:32 PM, Paul Taylor wrote: > On 22/05/2014 20:05, Hendrik Schreiber wrote: >> Hi, >> >> I'm under the impression that the VM option -splash does not honor the @2x notation for HiDPI images. >> Am I missing something, is that being worked on, or is there a bug report for this (I couldn't find one)? >> >> It's a little disappointing when you spend so much time on getting Retina right and then you realize that the very first impression the user gets when starting your app is a bad one, i.e. a blurry splash screen. >> >> Thanks! >> >> -hendrik > But isnt there a much larger problem, the -splash option still broken only to be fixed in https://bugs.openjdk.java.net/browse/JDK-8024185. To clarify using the splash option will prevent my main application from working. > > Paul From hs at tagtraum.com Fri May 23 10:40:19 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Fri, 23 May 2014 12:40:19 +0200 Subject: HiDPI/Retina support for -splash option In-Reply-To: <537F23B1.2010102@fastmail.fm> References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> <537F23B1.2010102@fastmail.fm> Message-ID: <96B27FE3-F243-4E75-92DB-8EB9E68D7AA1@tagtraum.com> On May 23, 2014, at 12:32, Paul Taylor wrote: > On 22/05/2014 20:05, Hendrik Schreiber wrote: >> Hi, >> >> I'm under the impression that the VM option -splash does not honor the @2x notation for HiDPI images. >> Am I missing something, is that being worked on, or is there a bug report for this (I couldn't find one)? >> >> It's a little disappointing when you spend so much time on getting Retina right and then you realize that the very first impression the user gets when starting your app is a bad one, i.e. a blurry splash screen. >> >> Thanks! >> >> -hendrik > But isnt there a much larger problem, the -splash option still broken only to be fixed in https://bugs.openjdk.java.net/browse/JDK-8024185. To clarify using the splash option will prevent my main application from working. The bug is marked as "Fixed" for 9. Do you still see this problem in 8u20? And if it is only fixed for 9, will it be backported to 8u20? Thanks, -hendrik From paul_t100 at fastmail.fm Fri May 23 10:44:23 2014 From: paul_t100 at fastmail.fm (Paul Taylor) Date: Fri, 23 May 2014 11:44:23 +0100 Subject: HiDPI/Retina support for -splash option In-Reply-To: References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> <537F23B1.2010102@fastmail.fm> Message-ID: <537F2687.10501@fastmail.fm> On 23/05/2014 11:38, Petr Pchelko wrote: >> But isnt there a much larger problem, the -splash option still broken only to be fixed in https://bugs.openjdk.java.net/browse/JDK-8024185. To clarify using the splash option will prevent my main application from working. > This fix was integrated in JDK-9 long time ago and didn?t cause any regressions. I think it is safe to back port this to jdk8u20 which I will do right now. > > With best regards. Petr. > > Okay, great thanks. From krueger at lesspain.de Fri May 23 11:57:47 2014 From: krueger at lesspain.de (=?UTF-8?Q?Robert_Kr=C3=BCger?=) Date: Fri, 23 May 2014 13:57:47 +0200 Subject: HiDPI/Retina support for -splash option In-Reply-To: <537F23B1.2010102@fastmail.fm> References: <24FD14E7-F364-4641-88ED-EEB1EF7655B5@tagtraum.com> <537F23B1.2010102@fastmail.fm> Message-ID: On Fri, May 23, 2014 at 12:32 PM, Paul Taylor wrote: > On 22/05/2014 20:05, Hendrik Schreiber wrote: >> >> Hi, >> >> I'm under the impression that the VM option -splash does not honor the @2x >> notation for HiDPI images. >> Am I missing something, is that being worked on, or is there a bug report >> for this (I couldn't find one)? >> >> It's a little disappointing when you spend so much time on getting Retina >> right and then you realize that the very first impression the user gets when >> starting your app is a bad one, i.e. a blurry splash screen. >> >> Thanks! >> >> -hendrik > > But isnt there a much larger problem, the -splash option still broken only > to be fixed in https://bugs.openjdk.java.net/browse/JDK-8024185. To clarify > using the splash option will prevent my main application from working. Same here. -- Robert Kr?ger Managing Partner Lesspain GmbH & Co. KG www.lesspain-software.com From Sergey.Bylokhov at oracle.com Fri May 23 14:09:53 2014 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Fri, 23 May 2014 18:09:53 +0400 Subject: [9] Review request for 8040291 [macosx] Http-Images are not fully loaded when using ImageIcon In-Reply-To: <1AB17DF9-543B-4284-8C47-CBD679F83DAC@oracle.com> References: <536109EE.1020303@oracle.com> <537B677C.7000302@oracle.com> <9F404942-A83E-48BC-B5E1-C2582D59B9D8@oracle.com> <537B6FA2.1090903@oracle.com> <614D8A0A-435D-46C8-9688-3A4ED1AF2F41@oracle.com> <537C850E.3020704@oracle.com> <537CAE79.3040801@oracle.com> <1AB17DF9-543B-4284-8C47-CBD679F83DAC@oracle.com> Message-ID: <537F56B1.3040705@oracle.com> Hi, Alexander. The fix looks good. On 5/21/14 6:00 PM, Petr Pchelko wrote: > Hello, Alexander. > > The fix looks good. > > With best regards. Petr. > > On 21 ??? 2014 ?., at 17:47, Alexander Scherbatiy wrote: > >> Could you review the updated fix: >> http://cr.openjdk.java.net/~alexsch/8040291/webrev.03/ >> >> - The test checks that the resolution-variant observer is called at least once. >> >> Thanks, >> Alexandr. >> >> On 5/21/2014 2:50 PM, Alexander Scherbatiy wrote: >>> Could you review the updated fix: >>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.02/ >>> >>> - The isRVObserevr typo is fixed >>> >>> On 5/20/2014 7:32 PM, Petr Pchelko wrote: >>>>> Could you review the updated fix: >>>>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >>>>> >>>>> - The getRVSize() method from the SunToolkit is fixed >>>> Thank you for the update, but I still have questions about the test: >>>> 1. There?s a typo in isRVObserevr. >>>> 2. Do we need the isRVObserevr method? How could it be that this >>>> method return false in this test and it?s a correct behavior and not a bug? >>>> I see it?s only possible from SunToolkit.prepareImage if bits are ERROR | ABORT. >>>> Couldn?t we get rid of this method? Walking up the stack doesn?t look like the most >>>> reliable solution.. >>> The ImageObserver is used for two purposes in the Toolkit prepareImage() method: >>> - to query which part of the image should be loaded >>> - to notify an object about which image information is available >>> >>> To prepare a multi-resolution image it needs to prepare its resolution variant as well. >>> The only way to know which part of the resolution variant should be loaded is requesting >>> the base image observer. It leads that there will be a notification for the object that contains >>> the resolution variant instead of the base image. To improve it the MultiResolutionToolkitImage >>> wraps the base image observer for the resolution variant. The object gets notification >>> which contains only the base image and updated sizes after that. >>> >>> The another case which is fixed in this issue is that the resolution variant can be loaded first >>> and it notifies the object that the image is loaded. The fix reduces the resolution variant info >>> flags so the object should wait for image loading notification from the base image. >>> >>> The test needs to check that the wrapped observer from the resolution variant does not send >>> more info than the original image has already had. The isRVObserver() just checks >>> that the observer is called from the resolution variant and not is from the base image. >>> >>> Thanks, >>> Alexandr. >>> >>>> With best regards. Petr. >>>> >>>> On May 20, 2014, at 7:07 PM, Alexander Scherbatiy wrote: >>>> >>>>> Could you review the updated fix: >>>>> http://cr.openjdk.java.net/~alexsch/8040291/webrev.01 >>>>> >>>>> - The getRVSize() method from the SunToolkit is fixed >>>>> >>>>> On 5/20/2014 6:46 PM, Petr Pchelko wrote: >>>>>> Hello, Alexander. >>>>>> >>>>>> SunToolkit:876 size == -1 ? -1 : size >>>>>> >>>>>> What?s going on here? Isn?t this equal to just size? >>>>>> I believe is?t wrong and the size should be multiplied by 2 somewhere? >>>>>> If the method is wrong how does the test pass? >>>>> The test passes because it uses SunToolkit.prepareImage() method with the -1 size. >>>>> It also uses the image observer that requires to load all image bits. >>>>> >>>>> Thanks, >>>>> Alexandr. >>>>> >>>>>> With best regards. Petr. >>>>>> >>>>>> On May 20, 2014, at 6:32 PM, Alexander Scherbatiy wrote: >>>>>> >>>>>>> Hello, >>>>>>> >>>>>>> Could you look at the fix? >>>>>>> >>>>>>> Thanks, >>>>>>> Alexandr. >>>>>>> >>>>>>> On 4/30/2014 6:34 PM, Alexander Scherbatiy wrote: >>>>>>>> Hello, >>>>>>>> >>>>>>>> Could you review the fix: >>>>>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8040291 >>>>>>>> webrev: http://cr.openjdk.java.net/~alexsch/8040291/webrev.00 >>>>>>>> >>>>>>>> >>>>>>>> The SunToolkit.prepareResolutionVariant() method wraps the base image observer and >>>>>>>> passes it to the resolution variant. It leads that the resolution variant notifies >>>>>>>> the base image about info changing. >>>>>>>> >>>>>>>> When the base image is loaded by the MediaTracker and the resolution variant is loaded >>>>>>>> first it calls the base image observer and wrongly finishes the base image loading. >>>>>>>> >>>>>>>> >>>>>>>> The fix passes the reduced resolution variant info flags to the base image >>>>>>>> so the base image loading is finished only after notifiing by the original base image observer. >>>>>>>> >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Alexandr. >>>>>>>> -- Best regards, Sergey. From hs at tagtraum.com Fri May 23 14:22:55 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Fri, 23 May 2014 16:22:55 +0200 Subject: HiDPI Scaling - OSX vs Windows Message-ID: <19B10D36-F5CA-43A7-8E30-9D8D2E4DF118@tagtraum.com> Hey Guys, about half a year ago I filed https://bugs.openjdk.java.net/browse/JDK-8029087, stating basically that the HiDPI logic on Windows and on OS X is fundamentally different and therefore WORA is violated (don't know what the Linux situation is). I was wondering whether anybody at Oracle discusses this and what your conclusions are? Or is this being ignored as not important enough? I'm writing mainly, because a hint in which direction this will go, will help me to write my code accordingly. I would hate having to re-code all retina related stuff with extra workarounds for Windows... Thanks, -hendrik From hs at tagtraum.com Fri May 23 17:26:58 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Fri, 23 May 2014 19:26:58 +0200 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app Message-ID: Hey, I'm under the impression that the java.awt.FileDialog in mode FileDialog.LOAD does not work properly when invoked from an app bundle. As in: It always assumes a sandbox and does not give me access to all files anymore. It does not matter, if the bundle was signed or not. The bundle was created with https://bitbucket.org/infinitekind/appbundler Note that AppBundler passes in a system property -DSandboxEnabled=true, if it finds *any* Containers folder. Meaning, it's only an indication for whether sandboxing is possible at all, *not* whether this particular app is sandboxed. There is no problem, when launching the same app via the regular java launcher. Does anybody else have this problem? Cheers, -hendrik From richard at biomatters.com Wed May 28 01:48:06 2014 From: richard at biomatters.com (Richard Moir) Date: Wed, 28 May 2014 13:48:06 +1200 Subject: HiDPI Scaling - OSX vs Windows In-Reply-To: <19B10D36-F5CA-43A7-8E30-9D8D2E4DF118@tagtraum.com> References: <19B10D36-F5CA-43A7-8E30-9D8D2E4DF118@tagtraum.com> Message-ID: Hi All, I would also like to hear about the status of this, High DPI PC's are now hitting the mainstream and our customers are starting to ask why everything is messed up. For now I guess we have to introduce lots of Windows specific hacks :-( Regards, Richard On Sat, May 24, 2014 at 2:22 AM, Hendrik Schreiber wrote: > Hey Guys, > > about half a year ago I filed > https://bugs.openjdk.java.net/browse/JDK-8029087, stating basically that > the HiDPI logic on Windows and on OS X is fundamentally different and > therefore WORA is violated (don't know what the Linux situation is). > > I was wondering whether anybody at Oracle discusses this and what your > conclusions are? Or is this being ignored as not important enough? > > I'm writing mainly, because a hint in which direction this will go, will > help me to write my code accordingly. I would hate having to re-code all > retina related stuff with extra workarounds for Windows... > > Thanks, > > -hendrik -- Richard Moir Product Manager www.geneious.com From hs at tagtraum.com Wed May 28 14:58:38 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Wed, 28 May 2014 16:58:38 +0200 Subject: HiDPI Scaling - OSX vs Windows In-Reply-To: References: <19B10D36-F5CA-43A7-8E30-9D8D2E4DF118@tagtraum.com> Message-ID: <3355A408-1349-4912-A174-AEB38E7286AA@tagtraum.com> On May 28, 2014, at 3:48, Richard Moir wrote: > I would also like to hear about the status of this, High DPI PC's are now hitting the mainstream and our customers are starting to ask why everything is messed up. For now I guess we have to introduce lots of Windows specific hacks :-( Thanks for supporting my request, Richard. @oracle people: Any insights? State of affairs? Thank you! -hendrik From Sergey.Bylokhov at oracle.com Wed May 28 16:09:56 2014 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Wed, 28 May 2014 20:09:56 +0400 Subject: HiDPI Scaling - OSX vs Windows In-Reply-To: <3355A408-1349-4912-A174-AEB38E7286AA@tagtraum.com> References: <19B10D36-F5CA-43A7-8E30-9D8D2E4DF118@tagtraum.com> <3355A408-1349-4912-A174-AEB38E7286AA@tagtraum.com> Message-ID: <53860A54.5040003@oracle.com> Hi, Hendrik. The logic of how it should be implemented/updated still under discussion. So if you have some broken use-cases or you have to use some hacks, I suggest to file a new bugs. On 5/28/14 6:58 PM, Hendrik Schreiber wrote: > On May 28, 2014, at 3:48, Richard Moir wrote: > >> I would also like to hear about the status of this, High DPI PC's are now hitting the mainstream and our customers are starting to ask why everything is messed up. For now I guess we have to introduce lots of Windows specific hacks :-( > Thanks for supporting my request, Richard. > @oracle people: Any insights? State of affairs? > > Thank you! > > -hendrik -- Best regards, Sergey. From hs at tagtraum.com Wed May 28 18:31:29 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Wed, 28 May 2014 20:31:29 +0200 Subject: HiDPI Scaling - OSX vs Windows In-Reply-To: <53860A54.5040003@oracle.com> References: <19B10D36-F5CA-43A7-8E30-9D8D2E4DF118@tagtraum.com> <3355A408-1349-4912-A174-AEB38E7286AA@tagtraum.com> <53860A54.5040003@oracle.com> Message-ID: <834F3D1A-D882-4BB5-83B1-256E5CAF002B@tagtraum.com> On May 28, 2014, at 18:09, Sergey Bylokhov wrote: > Hi, Hendrik. > The logic of how it should be implemented/updated still under discussion. So if you have some broken use-cases or you have to use some hacks, I suggest to file a new bugs. Thanks, Sergey. I actually think the already filed bug summarizes pretty nicely that WORA is violated, especially in the comments section. Currently there is no good way to support both OS X Retina and Windows HiDPI using the same code, which smells like a huge bug to me. So for good measure I files another bug (review id JI-9012585). Hope this helps. Cheers, -hendrik From hs at tagtraum.com Wed May 28 18:32:12 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Wed, 28 May 2014 20:32:12 +0200 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app In-Reply-To: References: Message-ID: On May 23, 2014, at 19:26, Hendrik Schreiber wrote: > I'm under the impression that the java.awt.FileDialog in mode FileDialog.LOAD does not work properly when invoked from an app bundle. > As in: It always assumes a sandbox and does not give me access to all files anymore. > It does not matter, if the bundle was signed or not. > The bundle was created with https://bitbucket.org/infinitekind/appbundler > Note that AppBundler passes in a system property -DSandboxEnabled=true, if it finds *any* Containers folder. Meaning, it's only an indication for whether sandboxing is possible at all, *not* whether this particular app is sandboxed. > > There is no problem, when launching the same app via the regular java launcher. > > Does anybody else have this problem? Really, no one else is having problems with this? -hendrik From krueger at lesspain.de Thu May 29 10:27:17 2014 From: krueger at lesspain.de (=?UTF-8?Q?Robert_Kr=C3=BCger?=) Date: Thu, 29 May 2014 12:27:17 +0200 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app In-Reply-To: References: Message-ID: Hi, I am not really sure I understand your posting correctly. Are you saying that your impression is that java.awt.FileDialog in mode FileDialog.LOAD does not work properly in an app bundle, regardless of sandboxing? If that is so, then I can confirm that this is not the case. You are not by any chance starting the app with a splash screen with -splash? If so that is likely to be the reason for your problems as java.awt.FileDialog is completely broken then (see https://bugs.openjdk.java.net/browse/JDK-8009203, https://bugs.openjdk.java.net/browse/JDK-8006420). If I understand the feedback of an Oracle dev a few days ago on this list correctly, this is fixed in J9 and will be backported for the next J8 update. We even implemented our own splash screen because of this. Cheers, Robert On Wed, May 28, 2014 at 8:32 PM, Hendrik Schreiber wrote: > On May 23, 2014, at 19:26, Hendrik Schreiber wrote: >> I'm under the impression that the java.awt.FileDialog in mode FileDialog.LOAD does not work properly when invoked from an app bundle. >> As in: It always assumes a sandbox and does not give me access to all files anymore. >> It does not matter, if the bundle was signed or not. >> The bundle was created with https://bitbucket.org/infinitekind/appbundler >> Note that AppBundler passes in a system property -DSandboxEnabled=true, if it finds *any* Containers folder. Meaning, it's only an indication for whether sandboxing is possible at all, *not* whether this particular app is sandboxed. >> >> There is no problem, when launching the same app via the regular java launcher. >> >> Does anybody else have this problem? > > Really, no one else is having problems with this? > > -hendrik -- Robert Kr?ger Managing Partner Lesspain GmbH & Co. KG www.lesspain-software.com From paul_t100 at fastmail.fm Thu May 29 15:18:15 2014 From: paul_t100 at fastmail.fm (Paul Taylor) Date: Thu, 29 May 2014 16:18:15 +0100 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app In-Reply-To: References: Message-ID: <53874FB7.3060404@fastmail.fm> On 29/05/2014 11:27, Robert Kr?ger wrote: > Hi, > > I am not really sure I understand your posting correctly. Are you > saying that your impression is that java.awt.FileDialog in mode > FileDialog.LOAD does not work properly in an app bundle, regardless of > sandboxing? If that is so, then I can confirm that this is not the > case. > > You are not by any chance starting the app with a splash screen with > -splash? If so that is likely to be the reason for your problems as > java.awt.FileDialog is completely broken then (see > https://bugs.openjdk.java.net/browse/JDK-8009203, > https://bugs.openjdk.java.net/browse/JDK-8006420). If I understand the > feedback of an Oracle dev a few days ago on this list correctly, this > is fixed in J9 and will be backported for the next J8 update. We even > implemented our own splash screen because of this. > > Cheers, > > Robert > > > +1 this is what I was saying about splashscreen completely screwing up a gui application. Using Appbundler and without splash screen I use java.awt.FIleDialog fine ( see http://jthink.net/songkong, and select File/Open Folder ) Paul From hs at tagtraum.com Thu May 29 20:39:07 2014 From: hs at tagtraum.com (Hendrik Schreiber) Date: Thu, 29 May 2014 22:39:07 +0200 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app In-Reply-To: References: Message-ID: On May 29, 2014, at 12:27, Robert Kr?ger wrote: > I am not really sure I understand your posting correctly. Are you > saying that your impression is that java.awt.FileDialog in mode > FileDialog.LOAD does not work properly in an app bundle, regardless of > sandboxing? If that is so, then I can confirm that this is not the > case. > > You are not by any chance starting the app with a splash screen with > -splash? If so that is likely to be the reason for your problems as > java.awt.FileDialog is completely broken then (see > https://bugs.openjdk.java.net/browse/JDK-8009203, > https://bugs.openjdk.java.net/browse/JDK-8006420). If I understand the > feedback of an Oracle dev a few days ago on this list correctly, this > is fixed in J9 and will be backported for the next J8 update. We even > implemented our own splash screen because of this. Thank you, Robert for pointing out the (not quite so obvious) connection between the FileDialog and the splash screen. Indeed, I was attempting to use the splash screen option.. once I removed it, things were working as expected. Looking forward to the backported fix! -hendrik From krueger at lesspain.de Fri May 30 07:33:29 2014 From: krueger at lesspain.de (=?UTF-8?Q?Robert_Kr=C3=BCger?=) Date: Fri, 30 May 2014 09:33:29 +0200 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app In-Reply-To: References: Message-ID: On Thu, May 29, 2014 at 10:39 PM, Hendrik Schreiber wrote: > On May 29, 2014, at 12:27, Robert Kr?ger wrote: > >> I am not really sure I understand your posting correctly. Are you >> saying that your impression is that java.awt.FileDialog in mode >> FileDialog.LOAD does not work properly in an app bundle, regardless of >> sandboxing? If that is so, then I can confirm that this is not the >> case. >> >> You are not by any chance starting the app with a splash screen with >> -splash? If so that is likely to be the reason for your problems as >> java.awt.FileDialog is completely broken then (see >> https://bugs.openjdk.java.net/browse/JDK-8009203, >> https://bugs.openjdk.java.net/browse/JDK-8006420). If I understand the >> feedback of an Oracle dev a few days ago on this list correctly, this >> is fixed in J9 and will be backported for the next J8 update. We even >> implemented our own splash screen because of this. > > Thank you, Robert for pointing out the (not quite so obvious) connection between the FileDialog and the splash screen. > Indeed, I was attempting to use the splash screen option.. once I removed it, things were working as expected. I know the feeling :-). I ran into this a few months ago and didn't have a clue what was causing it until a colleague of mine somehow stumbled over another bug (full-screen mode screwed up by splash screen, I think) with a similar non-obvious connection. Cheers, Robert From steve at weblite.ca Fri May 30 16:49:34 2014 From: steve at weblite.ca (Steve Hannah) Date: Fri, 30 May 2014 09:49:34 -0700 Subject: java.awt.FileDialog does not work properly bundled but not sandboxed app In-Reply-To: References: Message-ID: For my OS X apps, I generally use a wrapper of NSOpenPanel and NSSavePanel that I created rather than java.awt.FileDialog. That way I have access to the full gamut of what Cocoa provides in file dialogs. It also won't be affected by this bug. I have posted the source and some example usage here. https://gist.github.com/shannah/65007754c2b0f8add4f7 Feel free to use it. Steve On Fri, May 30, 2014 at 12:33 AM, Robert Kr?ger wrote: > On Thu, May 29, 2014 at 10:39 PM, Hendrik Schreiber > wrote: > > On May 29, 2014, at 12:27, Robert Kr?ger wrote: > > > >> I am not really sure I understand your posting correctly. Are you > >> saying that your impression is that java.awt.FileDialog in mode > >> FileDialog.LOAD does not work properly in an app bundle, regardless of > >> sandboxing? If that is so, then I can confirm that this is not the > >> case. > >> > >> You are not by any chance starting the app with a splash screen with > >> -splash? If so that is likely to be the reason for your problems as > >> java.awt.FileDialog is completely broken then (see > >> https://bugs.openjdk.java.net/browse/JDK-8009203, > >> https://bugs.openjdk.java.net/browse/JDK-8006420). If I understand the > >> feedback of an Oracle dev a few days ago on this list correctly, this > >> is fixed in J9 and will be backported for the next J8 update. We even > >> implemented our own splash screen because of this. > > > > Thank you, Robert for pointing out the (not quite so obvious) connection > between the FileDialog and the splash screen. > > Indeed, I was attempting to use the splash screen option.. once I > removed it, things were working as expected. > > I know the feeling :-). I ran into this a few months ago and didn't > have a clue what was causing it until a colleague of mine somehow > stumbled over another bug (full-screen mode screwed up by splash > screen, I think) with a similar non-obvious connection. > > Cheers, > > Robert > -- Steve Hannah Web Lite Solutions Corp.