< prev index next >

src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java

Print this page




  44 import java.awt.image.WritableRaster;
  45 import java.awt.Image;
  46 import java.awt.Composite;
  47 import java.awt.Color;
  48 import java.awt.image.ColorModel;
  49 import java.awt.GraphicsConfiguration;
  50 import java.awt.Paint;
  51 import java.awt.GradientPaint;
  52 import java.awt.LinearGradientPaint;
  53 import java.awt.RadialGradientPaint;
  54 import java.awt.TexturePaint;
  55 import java.awt.geom.Rectangle2D;
  56 import java.awt.geom.PathIterator;
  57 import java.awt.geom.GeneralPath;
  58 import java.awt.Shape;
  59 import java.awt.Stroke;
  60 import java.awt.FontMetrics;
  61 import java.awt.Rectangle;
  62 import java.text.AttributedCharacterIterator;
  63 import java.awt.Font;
  64 import java.awt.Point;
  65 import java.awt.image.ImageObserver;
  66 import java.awt.Transparency;
  67 import java.awt.font.GlyphVector;
  68 import java.awt.font.TextLayout;
  69 
  70 import sun.awt.image.SurfaceManager;
  71 import sun.font.FontDesignMetrics;
  72 import sun.font.FontUtilities;
  73 import sun.java2d.pipe.PixelDrawPipe;
  74 import sun.java2d.pipe.PixelFillPipe;
  75 import sun.java2d.pipe.ShapeDrawPipe;
  76 import sun.java2d.pipe.ValidatePipe;
  77 import sun.java2d.pipe.ShapeSpanIterator;
  78 import sun.java2d.pipe.Region;
  79 import sun.java2d.pipe.TextPipe;
  80 import sun.java2d.pipe.DrawImagePipe;
  81 import sun.java2d.pipe.LoopPipe;
  82 import sun.java2d.loops.FontInfo;
  83 import sun.java2d.loops.RenderLoops;
  84 import sun.java2d.loops.CompositeType;
  85 import sun.java2d.loops.SurfaceType;
  86 import sun.java2d.loops.Blit;
  87 import sun.java2d.loops.MaskFill;
  88 import java.awt.font.FontRenderContext;
  89 import sun.java2d.loops.XORComposite;
  90 import sun.awt.ConstrainableGraphics;
  91 import sun.awt.SunHints;
  92 import java.util.Map;
  93 import java.util.Iterator;
  94 import sun.misc.PerformanceLogger;
  95 
  96 import java.lang.annotation.Native;
  97 import java.awt.image.MultiResolutionImage;
  98 
  99 import static java.awt.geom.AffineTransform.TYPE_FLIP;
 100 import static java.awt.geom.AffineTransform.TYPE_MASK_SCALE;
 101 import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;

 102 import sun.awt.image.MultiResolutionToolkitImage;
 103 import sun.awt.image.ToolkitImage;
 104 
 105 /**
 106  * This is a the master Graphics2D superclass for all of the Sun
 107  * Graphics implementations.  This class relies on subclasses to
 108  * manage the various device information, but provides an overall
 109  * general framework for performing all of the requests in the
 110  * Graphics and Graphics2D APIs.
 111  *
 112  * @author Jim Graham
 113  */
 114 public final class SunGraphics2D
 115     extends Graphics2D
 116     implements ConstrainableGraphics, Cloneable, DestSurfaceProvider
 117 {
 118     /*
 119      * Attribute States
 120      */
 121     /* Paint */


3069             return;
3070         }
3071 
3072         try {
3073             textpipe.drawChars(this, chData, 0, length, x, y);
3074         } catch (InvalidPipeException e) {
3075             try {
3076                 revalidateAll();
3077                 textpipe.drawChars(this, chData, 0, length, x, y);
3078             } catch (InvalidPipeException e2) {
3079                 // Still catching the exception; we are not yet ready to
3080                 // validate the surfaceData correctly.  Fail for now and
3081                 // try again next time around.
3082             }
3083         } finally {
3084             surfaceData.markDirty();
3085         }
3086     }
3087 // end of text rendering methods
3088 
3089     private boolean isHiDPIImage(final Image img) {
3090         return (SurfaceManager.getImageScale(img) != 1)
3091                 || img instanceof MultiResolutionImage;
3092     }
3093 
3094     private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
3095                                    int dy2, int sx1, int sy1, int sx2, int sy2,
3096                                    Color bgcolor, ImageObserver observer) {
3097 
3098         if (SurfaceManager.getImageScale(img) != 1) {  // Volatile Image
3099             final int scale = SurfaceManager.getImageScale(img);
3100             sx1 = Region.clipScale(sx1, scale);
3101             sx2 = Region.clipScale(sx2, scale);
3102             sy1 = Region.clipScale(sy1, scale);
3103             sy2 = Region.clipScale(sy2, scale);
3104         } else if (img instanceof MultiResolutionImage) {





















3105             // get scaled destination image size
3106 
3107             int width = img.getWidth(observer);
3108             int height = img.getHeight(observer);
3109 
3110             Image resolutionVariant = getResolutionVariant(
3111                     (MultiResolutionImage) img, width, height,
3112                     dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);


3113 
3114             if (resolutionVariant != img && resolutionVariant != null) {
3115                 // recalculate source region for the resolution variant
3116 
3117                 ImageObserver rvObserver = MultiResolutionToolkitImage.
3118                         getResolutionVariantObserver(img, observer,
3119                                 width, height, -1, -1);
3120 
3121                 int rvWidth = resolutionVariant.getWidth(rvObserver);
3122                 int rvHeight = resolutionVariant.getHeight(rvObserver);
3123 
3124                 if (0 < width && 0 < height && 0 < rvWidth && 0 < rvHeight) {
3125 
3126                     float widthScale = ((float) rvWidth) / width;
3127                     float heightScale = ((float) rvHeight) / height;
3128 
3129                     sx1 = Region.clipScale(sx1, widthScale);
3130                     sy1 = Region.clipScale(sy1, heightScale);
3131                     sx2 = Region.clipScale(sx2, widthScale);
3132                     sy2 = Region.clipScale(sy2, heightScale);
3133 
3134                     observer = rvObserver;
3135                     img = resolutionVariant;














3136                 }
3137             }

3138         }
3139 




3140         try {
3141             return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
3142                                         sx2, sy2, bgcolor, observer);
3143         } catch (InvalidPipeException e) {
3144             try {
3145                 revalidateAll();
3146                 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1,
3147                                             sy1, sx2, sy2, bgcolor, observer);
3148             } catch (InvalidPipeException e2) {
3149                 // Still catching the exception; we are not yet ready to
3150                 // validate the surfaceData correctly.  Fail for now and
3151                 // try again next time around.
3152                 return false;
3153             }
3154         } finally {
3155             surfaceData.markDirty();
3156         }
3157     }
3158 





















3159     private Image getResolutionVariant(MultiResolutionImage img,
3160             int srcWidth, int srcHeight, int dx1, int dy1, int dx2, int dy2,
3161             int sx1, int sy1, int sx2, int sy2) {
3162 
3163         if (srcWidth <= 0 || srcHeight <= 0) {
3164             return null;
3165         }
3166 
3167         int sw = sx2 - sx1;
3168         int sh = sy2 - sy1;
3169 
3170         if (sw == 0 || sh == 0) {
3171             return null;
3172         }
3173 
3174         int type = transform.getType();









3175         int dw = dx2 - dx1;
3176         int dh = dy2 - dy1;
3177 
3178         double destImageWidth;
3179         double destImageHeight;
3180 
3181         if (resolutionVariantHint == SunHints.INTVAL_RESOLUTION_VARIANT_BASE) {
3182             destImageWidth = srcWidth;
3183             destImageHeight = srcHeight;
3184         } else if (resolutionVariantHint == SunHints.INTVAL_RESOLUTION_VARIANT_DPI_FIT) {
3185             AffineTransform configTransform = getDefaultTransform();
3186             if (configTransform.isIdentity()) {
3187                 destImageWidth = srcWidth;
3188                 destImageHeight = srcHeight;
3189             } else {
3190                 destImageWidth = srcWidth * configTransform.getScaleX();
3191                 destImageHeight = srcHeight * configTransform.getScaleY();
3192             }
3193         } else {
3194             double destRegionWidth;
3195             double destRegionHeight;
3196 
3197             if ((type & ~(TYPE_TRANSLATION | TYPE_FLIP)) == 0) {
3198                 destRegionWidth = dw;
3199                 destRegionHeight = dh;
3200             } else if ((type & ~(TYPE_TRANSLATION | TYPE_FLIP | TYPE_MASK_SCALE)) == 0) {
3201                 destRegionWidth = dw * transform.getScaleX();
3202                 destRegionHeight = dh * transform.getScaleY();
3203             } else {
3204                 destRegionWidth = dw * Math.hypot(
3205                         transform.getScaleX(), transform.getShearY());
3206                 destRegionHeight = dh * Math.hypot(
3207                         transform.getShearX(), transform.getScaleY());
3208             }
3209             destImageWidth = Math.abs(srcWidth * destRegionWidth / sw);
3210             destImageHeight = Math.abs(srcHeight * destRegionHeight / sh);
3211         }
3212 
3213         Image resolutionVariant
3214                 = img.getResolutionVariant(destImageWidth, destImageHeight);
3215 
3216         if (resolutionVariant instanceof ToolkitImage
3217                 && ((ToolkitImage) resolutionVariant).hasError()) {
3218             return null;
3219         }
3220 
3221         return resolutionVariant;
3222     }
3223 
3224     /**
3225      * Draws an image scaled to x,y,w,h in nonblocking mode with a
3226      * callback object.
3227      */


3260         }
3261     }
3262 
3263     /**
3264      * Draws an image scaled to x,y,w,h in nonblocking mode with a
3265      * solid background color and a callback object.
3266      */
3267     public boolean drawImage(Image img, int x, int y, int width, int height,
3268                              Color bg, ImageObserver observer) {
3269 
3270         if (img == null) {
3271             return true;
3272         }
3273 
3274         if ((width == 0) || (height == 0)) {
3275             return true;
3276         }
3277 
3278         final int imgW = img.getWidth(null);
3279         final int imgH = img.getHeight(null);
3280         if (isHiDPIImage(img)) {
3281             return drawHiDPIImage(img, x, y, x + width, y + height, 0, 0, imgW,
3282                                   imgH, bg, observer);


3283         }
3284 
3285         if (width == imgW && height == imgH) {
3286             return copyImage(img, x, y, 0, 0, width, height, bg, observer);
3287         }
3288 
3289         try {
3290             return imagepipe.scaleImage(this, img, x, y, width, height,
3291                                         bg, observer);
3292         } catch (InvalidPipeException e) {
3293             try {
3294                 revalidateAll();
3295                 return imagepipe.scaleImage(this, img, x, y, width, height,
3296                                             bg, observer);
3297             } catch (InvalidPipeException e2) {
3298                 // Still catching the exception; we are not yet ready to
3299                 // validate the surfaceData correctly.  Fail for now and
3300                 // try again next time around.
3301                 return false;
3302             }


3306     }
3307 
3308     /**
3309      * Draws an image at x,y in nonblocking mode.
3310      */
3311     public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
3312         return drawImage(img, x, y, null, observer);
3313     }
3314 
3315     /**
3316      * Draws an image at x,y in nonblocking mode with a solid background
3317      * color and a callback object.
3318      */
3319     public boolean drawImage(Image img, int x, int y, Color bg,
3320                              ImageObserver observer) {
3321 
3322         if (img == null) {
3323             return true;
3324         }
3325 
3326         if (isHiDPIImage(img)) {
3327             final int imgW = img.getWidth(null);
3328             final int imgH = img.getHeight(null);
3329             return drawHiDPIImage(img, x, y, x + imgW, y + imgH, 0, 0, imgW,
3330                                   imgH, bg, observer);



3331         }
3332 
3333         try {
3334             return imagepipe.copyImage(this, img, x, y, bg, observer);
3335         } catch (InvalidPipeException e) {
3336             try {
3337                 revalidateAll();
3338                 return imagepipe.copyImage(this, img, x, y, bg, observer);
3339             } catch (InvalidPipeException e2) {
3340                 // Still catching the exception; we are not yet ready to
3341                 // validate the surfaceData correctly.  Fail for now and
3342                 // try again next time around.
3343                 return false;
3344             }
3345         } finally {
3346             surfaceData.markDirty();
3347         }
3348     }
3349 
3350     /**


3361 
3362     /**
3363      * Draws a subrectangle of an image scaled to a destination rectangle in
3364      * nonblocking mode with a solid background color and a callback object.
3365      */
3366     public boolean drawImage(Image img,
3367                              int dx1, int dy1, int dx2, int dy2,
3368                              int sx1, int sy1, int sx2, int sy2,
3369                              Color bgcolor, ImageObserver observer) {
3370 
3371         if (img == null) {
3372             return true;
3373         }
3374 
3375         if (dx1 == dx2 || dy1 == dy2 ||
3376             sx1 == sx2 || sy1 == sy2)
3377         {
3378             return true;
3379         }
3380 
3381         if (isHiDPIImage(img)) {
3382             return drawHiDPIImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
3383                                   bgcolor, observer);



3384         }
3385 
3386         if (((sx2 - sx1) == (dx2 - dx1)) &&
3387             ((sy2 - sy1) == (dy2 - dy1)))
3388         {
3389             // Not a scale - forward it to a copy routine
3390             int srcX, srcY, dstX, dstY, width, height;
3391             if (sx2 > sx1) {
3392                 width = sx2 - sx1;
3393                 srcX = sx1;
3394                 dstX = dx1;
3395             } else {
3396                 width = sx1 - sx2;
3397                 srcX = sx2;
3398                 dstX = dx2;
3399             }
3400             if (sy2 > sy1) {
3401                 height = sy2-sy1;
3402                 srcY = sy1;
3403                 dstY = dy1;


3444      * @param img The image to be drawn.
3445      * @param xform The transformation from image space into user space.
3446      * @param observer The image observer to be notified on the image producing
3447      * progress.
3448      * @see #transform
3449      * @see #setComposite
3450      * @see #setClip
3451      */
3452     public boolean drawImage(Image img,
3453                              AffineTransform xform,
3454                              ImageObserver observer) {
3455 
3456         if (img == null) {
3457             return true;
3458         }
3459 
3460         if (xform == null || xform.isIdentity()) {
3461             return drawImage(img, 0, 0, null, observer);
3462         }
3463 
3464         if (isHiDPIImage(img)) {
3465             final int w = img.getWidth(null);
3466             final int h = img.getHeight(null);
3467             final AffineTransform tx = new AffineTransform(transform);
3468             transform(xform);
3469             boolean result = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h, null,
3470                                             observer);
3471             transform.setTransform(tx);
3472             invalidateTransform();
3473             return result;
3474         }
3475 
3476         try {
3477             return imagepipe.transformImage(this, img, xform, observer);
3478         } catch (InvalidPipeException e) {
3479             try {
3480                 revalidateAll();
3481                 return imagepipe.transformImage(this, img, xform, observer);
3482             } catch (InvalidPipeException e2) {
3483                 // Still catching the exception; we are not yet ready to
3484                 // validate the surfaceData correctly.  Fail for now and
3485                 // try again next time around.
3486                 return false;
3487             }
3488         } finally {
3489             surfaceData.markDirty();
3490         }


3491     }
3492 
3493     public void drawImage(BufferedImage bImg,
3494                           BufferedImageOp op,
3495                           int x,
3496                           int y)  {
3497 
3498         if (bImg == null) {
3499             return;
3500         }
3501 
3502         try {
3503             imagepipe.transformImage(this, bImg, op, x, y);
3504         } catch (InvalidPipeException e) {
3505             try {
3506                 revalidateAll();
3507                 imagepipe.transformImage(this, bImg, op, x, y);
3508             } catch (InvalidPipeException e2) {
3509                 // Still catching the exception; we are not yet ready to
3510                 // validate the surfaceData correctly.  Fail for now and




  44 import java.awt.image.WritableRaster;
  45 import java.awt.Image;
  46 import java.awt.Composite;
  47 import java.awt.Color;
  48 import java.awt.image.ColorModel;
  49 import java.awt.GraphicsConfiguration;
  50 import java.awt.Paint;
  51 import java.awt.GradientPaint;
  52 import java.awt.LinearGradientPaint;
  53 import java.awt.RadialGradientPaint;
  54 import java.awt.TexturePaint;
  55 import java.awt.geom.Rectangle2D;
  56 import java.awt.geom.PathIterator;
  57 import java.awt.geom.GeneralPath;
  58 import java.awt.Shape;
  59 import java.awt.Stroke;
  60 import java.awt.FontMetrics;
  61 import java.awt.Rectangle;
  62 import java.text.AttributedCharacterIterator;
  63 import java.awt.Font;

  64 import java.awt.image.ImageObserver;
  65 import java.awt.Transparency;
  66 import java.awt.font.GlyphVector;
  67 import java.awt.font.TextLayout;
  68 
  69 import sun.awt.image.SurfaceManager;
  70 import sun.font.FontDesignMetrics;
  71 import sun.font.FontUtilities;
  72 import sun.java2d.pipe.PixelDrawPipe;
  73 import sun.java2d.pipe.PixelFillPipe;
  74 import sun.java2d.pipe.ShapeDrawPipe;
  75 import sun.java2d.pipe.ValidatePipe;
  76 import sun.java2d.pipe.ShapeSpanIterator;
  77 import sun.java2d.pipe.Region;
  78 import sun.java2d.pipe.TextPipe;
  79 import sun.java2d.pipe.DrawImagePipe;
  80 import sun.java2d.pipe.LoopPipe;
  81 import sun.java2d.loops.FontInfo;
  82 import sun.java2d.loops.RenderLoops;
  83 import sun.java2d.loops.CompositeType;
  84 import sun.java2d.loops.SurfaceType;
  85 import sun.java2d.loops.Blit;
  86 import sun.java2d.loops.MaskFill;
  87 import java.awt.font.FontRenderContext;
  88 import sun.java2d.loops.XORComposite;
  89 import sun.awt.ConstrainableGraphics;
  90 import sun.awt.SunHints;
  91 import java.util.Map;
  92 import java.util.Iterator;
  93 import sun.misc.PerformanceLogger;
  94 
  95 import java.lang.annotation.Native;
  96 import java.awt.image.MultiResolutionImage;
  97 
  98 import static java.awt.geom.AffineTransform.TYPE_FLIP;
  99 import static java.awt.geom.AffineTransform.TYPE_MASK_SCALE;
 100 import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;
 101 import java.awt.image.VolatileImage;
 102 import sun.awt.image.MultiResolutionToolkitImage;
 103 import sun.awt.image.ToolkitImage;
 104 
 105 /**
 106  * This is a the master Graphics2D superclass for all of the Sun
 107  * Graphics implementations.  This class relies on subclasses to
 108  * manage the various device information, but provides an overall
 109  * general framework for performing all of the requests in the
 110  * Graphics and Graphics2D APIs.
 111  *
 112  * @author Jim Graham
 113  */
 114 public final class SunGraphics2D
 115     extends Graphics2D
 116     implements ConstrainableGraphics, Cloneable, DestSurfaceProvider
 117 {
 118     /*
 119      * Attribute States
 120      */
 121     /* Paint */


3069             return;
3070         }
3071 
3072         try {
3073             textpipe.drawChars(this, chData, 0, length, x, y);
3074         } catch (InvalidPipeException e) {
3075             try {
3076                 revalidateAll();
3077                 textpipe.drawChars(this, chData, 0, length, x, y);
3078             } catch (InvalidPipeException e2) {
3079                 // Still catching the exception; we are not yet ready to
3080                 // validate the surfaceData correctly.  Fail for now and
3081                 // try again next time around.
3082             }
3083         } finally {
3084             surfaceData.markDirty();
3085         }
3086     }
3087 // end of text rendering methods
3088 
3089     private Boolean drawHiDPIImage(Image img,
3090                                    int dx1, int dy1, int dx2, int dy2,
3091                                    int sx1, int sy1, int sx2, int sy2,
3092                                    Color bgcolor, ImageObserver observer,
3093                                    AffineTransform xform) {



3094 
3095         if (img instanceof VolatileImage) {
3096             final SurfaceData sd = SurfaceManager.getManager(img)
3097                     .getPrimarySurfaceData();
3098             final double scaleX = sd.getDefaultScaleX();
3099             final double scaleY = sd.getDefaultScaleY();
3100             if (scaleX == 1 && scaleY == 1) {
3101                 return null;
3102             }
3103             sx1 = Region.clipScale(sx1, scaleX);
3104             sx2 = Region.clipScale(sx2, scaleX);
3105             sy1 = Region.clipScale(sy1, scaleY);
3106             sy2 = Region.clipScale(sy2, scaleY);
3107 
3108             AffineTransform tx = null;
3109             if (xform != null) {
3110                 tx = new AffineTransform(transform);
3111                 transform(xform);
3112             }
3113             boolean result = scaleImage(img, dx1, dy1, dx2, dy2,
3114                                         sx1, sy1, sx2, sy2,
3115                                         bgcolor, observer);
3116             if (tx != null) {
3117                 transform.setTransform(tx);
3118                 invalidateTransform();
3119             }
3120             return result;
3121         } else if (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_BASE
3122                    && (img instanceof MultiResolutionImage)) {
3123             // get scaled destination image size
3124 
3125             int width = img.getWidth(observer);
3126             int height = img.getHeight(observer);
3127 
3128             MultiResolutionImage mrImage = (MultiResolutionImage) img;
3129             Image resolutionVariant = getResolutionVariant(mrImage, width, height,
3130                                                            dx1, dy1, dx2, dy2,
3131                                                            sx1, sy1, sx2, sy2,
3132                                                            xform);
3133 
3134             if (resolutionVariant != img && resolutionVariant != null) {
3135                 // recalculate source region for the resolution variant
3136 
3137                 ImageObserver rvObserver = MultiResolutionToolkitImage.
3138                         getResolutionVariantObserver(img, observer,
3139                                 width, height, -1, -1);
3140 
3141                 int rvWidth = resolutionVariant.getWidth(rvObserver);
3142                 int rvHeight = resolutionVariant.getHeight(rvObserver);
3143 
3144                 if (0 < width && 0 < height && 0 < rvWidth && 0 < rvHeight) {
3145 
3146                     double widthScale = ((double) rvWidth) / width;
3147                     double heightScale = ((double) rvHeight) / height;
3148 
3149                     sx1 = Region.clipScale(sx1, widthScale);
3150                     sy1 = Region.clipScale(sy1, heightScale);
3151                     sx2 = Region.clipScale(sx2, widthScale);
3152                     sy2 = Region.clipScale(sy2, heightScale);
3153 
3154                     observer = rvObserver;
3155                     img = resolutionVariant;
3156 
3157                     if (xform != null) {
3158                         assert dx1 == 0 && dy1 == 0;
3159                         assert dx2 == img.getWidth(observer);
3160                         assert dy2 == img.getHeight(observer);
3161                         AffineTransform renderTX = new AffineTransform(xform);
3162                         renderTX.scale(1 / widthScale, 1 / heightScale);
3163                         return transformImage(img, renderTX, observer);
3164                     }
3165 
3166                     return scaleImage(img, dx1, dy1, dx2, dy2,
3167                                       sx1, sy1, sx2, sy2,
3168                                       bgcolor, observer);
3169                 }
3170             }
3171         }
3172         return null;
3173     }
3174 
3175     private boolean scaleImage(Image img, int dx1, int dy1, int dx2, int dy2,
3176                                int sx1, int sy1, int sx2, int sy2,
3177                                Color bgcolor, ImageObserver observer)
3178     {
3179         try {
3180             return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
3181                                         sx2, sy2, bgcolor, observer);
3182         } catch (InvalidPipeException e) {
3183             try {
3184                 revalidateAll();
3185                 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1,
3186                                             sy1, sx2, sy2, bgcolor, observer);
3187             } catch (InvalidPipeException e2) {
3188                 // Still catching the exception; we are not yet ready to
3189                 // validate the surfaceData correctly.  Fail for now and
3190                 // try again next time around.
3191                 return false;
3192             }
3193         } finally {
3194             surfaceData.markDirty();
3195         }
3196     }
3197 
3198     private boolean transformImage(Image img,
3199                                    AffineTransform xform,
3200                                    ImageObserver observer)
3201     {
3202         try {
3203             return imagepipe.transformImage(this, img, xform, observer);
3204         } catch (InvalidPipeException e) {
3205             try {
3206                 revalidateAll();
3207                 return imagepipe.transformImage(this, img, xform, observer);
3208             } catch (InvalidPipeException e2) {
3209                 // Still catching the exception; we are not yet ready to
3210                 // validate the surfaceData correctly.  Fail for now and
3211                 // try again next time around.
3212                 return false;
3213             }
3214         } finally {
3215             surfaceData.markDirty();
3216         }
3217     }
3218 
3219     private Image getResolutionVariant(MultiResolutionImage img,
3220             int srcWidth, int srcHeight, int dx1, int dy1, int dx2, int dy2,
3221             int sx1, int sy1, int sx2, int sy2, AffineTransform xform) {
3222 
3223         if (srcWidth <= 0 || srcHeight <= 0) {
3224             return null;
3225         }
3226 
3227         int sw = sx2 - sx1;
3228         int sh = sy2 - sy1;
3229 
3230         if (sw == 0 || sh == 0) {
3231             return null;
3232         }
3233 
3234         AffineTransform tx;
3235 
3236         if (xform == null) {
3237             tx = transform;
3238         } else {
3239             tx = new AffineTransform(transform);
3240             tx.concatenate(xform);
3241         }
3242 
3243         int type = tx.getType();
3244         int dw = dx2 - dx1;
3245         int dh = dy2 - dy1;
3246 
3247         double destImageWidth;
3248         double destImageHeight;
3249 
3250         if (resolutionVariantHint == SunHints.INTVAL_RESOLUTION_VARIANT_BASE) {
3251             destImageWidth = srcWidth;
3252             destImageHeight = srcHeight;
3253         } else if (resolutionVariantHint == SunHints.INTVAL_RESOLUTION_VARIANT_DPI_FIT) {
3254             AffineTransform configTransform = getDefaultTransform();
3255             if (configTransform.isIdentity()) {
3256                 destImageWidth = srcWidth;
3257                 destImageHeight = srcHeight;
3258             } else {
3259                 destImageWidth = srcWidth * configTransform.getScaleX();
3260                 destImageHeight = srcHeight * configTransform.getScaleY();
3261             }
3262         } else {
3263             double destRegionWidth;
3264             double destRegionHeight;
3265 
3266             if ((type & ~(TYPE_TRANSLATION | TYPE_FLIP)) == 0) {
3267                 destRegionWidth = dw;
3268                 destRegionHeight = dh;
3269             } else if ((type & ~(TYPE_TRANSLATION | TYPE_FLIP | TYPE_MASK_SCALE)) == 0) {
3270                 destRegionWidth = dw * tx.getScaleX();
3271                 destRegionHeight = dh * tx.getScaleY();
3272             } else {
3273                 destRegionWidth = dw * Math.hypot(
3274                         tx.getScaleX(), tx.getShearY());
3275                 destRegionHeight = dh * Math.hypot(
3276                         tx.getShearX(), tx.getScaleY());
3277             }
3278             destImageWidth = Math.abs(srcWidth * destRegionWidth / sw);
3279             destImageHeight = Math.abs(srcHeight * destRegionHeight / sh);
3280         }
3281 
3282         Image resolutionVariant
3283                 = img.getResolutionVariant(destImageWidth, destImageHeight);
3284 
3285         if (resolutionVariant instanceof ToolkitImage
3286                 && ((ToolkitImage) resolutionVariant).hasError()) {
3287             return null;
3288         }
3289 
3290         return resolutionVariant;
3291     }
3292 
3293     /**
3294      * Draws an image scaled to x,y,w,h in nonblocking mode with a
3295      * callback object.
3296      */


3329         }
3330     }
3331 
3332     /**
3333      * Draws an image scaled to x,y,w,h in nonblocking mode with a
3334      * solid background color and a callback object.
3335      */
3336     public boolean drawImage(Image img, int x, int y, int width, int height,
3337                              Color bg, ImageObserver observer) {
3338 
3339         if (img == null) {
3340             return true;
3341         }
3342 
3343         if ((width == 0) || (height == 0)) {
3344             return true;
3345         }
3346 
3347         final int imgW = img.getWidth(null);
3348         final int imgH = img.getHeight(null);
3349         Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + width, y + height,
3350                                                  0, 0, imgW, imgH, bg, observer,
3351                                                  null);
3352         if (hidpiImageDrawn != null) {
3353             return hidpiImageDrawn;
3354         }
3355 
3356         if (width == imgW && height == imgH) {
3357             return copyImage(img, x, y, 0, 0, width, height, bg, observer);
3358         }
3359 
3360         try {
3361             return imagepipe.scaleImage(this, img, x, y, width, height,
3362                                         bg, observer);
3363         } catch (InvalidPipeException e) {
3364             try {
3365                 revalidateAll();
3366                 return imagepipe.scaleImage(this, img, x, y, width, height,
3367                                             bg, observer);
3368             } catch (InvalidPipeException e2) {
3369                 // Still catching the exception; we are not yet ready to
3370                 // validate the surfaceData correctly.  Fail for now and
3371                 // try again next time around.
3372                 return false;
3373             }


3377     }
3378 
3379     /**
3380      * Draws an image at x,y in nonblocking mode.
3381      */
3382     public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
3383         return drawImage(img, x, y, null, observer);
3384     }
3385 
3386     /**
3387      * Draws an image at x,y in nonblocking mode with a solid background
3388      * color and a callback object.
3389      */
3390     public boolean drawImage(Image img, int x, int y, Color bg,
3391                              ImageObserver observer) {
3392 
3393         if (img == null) {
3394             return true;
3395         }
3396 

3397         final int imgW = img.getWidth(null);
3398         final int imgH = img.getHeight(null);
3399         Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + imgW, y + imgH,
3400                                                  0, 0, imgW, imgH, bg, observer,
3401                                                  null);
3402         if (hidpiImageDrawn != null) {
3403             return hidpiImageDrawn;
3404         }
3405 
3406         try {
3407             return imagepipe.copyImage(this, img, x, y, bg, observer);
3408         } catch (InvalidPipeException e) {
3409             try {
3410                 revalidateAll();
3411                 return imagepipe.copyImage(this, img, x, y, bg, observer);
3412             } catch (InvalidPipeException e2) {
3413                 // Still catching the exception; we are not yet ready to
3414                 // validate the surfaceData correctly.  Fail for now and
3415                 // try again next time around.
3416                 return false;
3417             }
3418         } finally {
3419             surfaceData.markDirty();
3420         }
3421     }
3422 
3423     /**


3434 
3435     /**
3436      * Draws a subrectangle of an image scaled to a destination rectangle in
3437      * nonblocking mode with a solid background color and a callback object.
3438      */
3439     public boolean drawImage(Image img,
3440                              int dx1, int dy1, int dx2, int dy2,
3441                              int sx1, int sy1, int sx2, int sy2,
3442                              Color bgcolor, ImageObserver observer) {
3443 
3444         if (img == null) {
3445             return true;
3446         }
3447 
3448         if (dx1 == dx2 || dy1 == dy2 ||
3449             sx1 == sx2 || sy1 == sy2)
3450         {
3451             return true;
3452         }
3453 
3454         Boolean hidpiImageDrawn = drawHiDPIImage(img, dx1, dy1, dx2, dy2,
3455                                                  sx1, sy1, sx2, sy2,
3456                                                  bgcolor, observer, null);
3457 
3458         if (hidpiImageDrawn != null) {
3459             return hidpiImageDrawn;
3460         }
3461 
3462         if (((sx2 - sx1) == (dx2 - dx1)) &&
3463             ((sy2 - sy1) == (dy2 - dy1)))
3464         {
3465             // Not a scale - forward it to a copy routine
3466             int srcX, srcY, dstX, dstY, width, height;
3467             if (sx2 > sx1) {
3468                 width = sx2 - sx1;
3469                 srcX = sx1;
3470                 dstX = dx1;
3471             } else {
3472                 width = sx1 - sx2;
3473                 srcX = sx2;
3474                 dstX = dx2;
3475             }
3476             if (sy2 > sy1) {
3477                 height = sy2-sy1;
3478                 srcY = sy1;
3479                 dstY = dy1;


3520      * @param img The image to be drawn.
3521      * @param xform The transformation from image space into user space.
3522      * @param observer The image observer to be notified on the image producing
3523      * progress.
3524      * @see #transform
3525      * @see #setComposite
3526      * @see #setClip
3527      */
3528     public boolean drawImage(Image img,
3529                              AffineTransform xform,
3530                              ImageObserver observer) {
3531 
3532         if (img == null) {
3533             return true;
3534         }
3535 
3536         if (xform == null || xform.isIdentity()) {
3537             return drawImage(img, 0, 0, null, observer);
3538         }
3539 

3540         final int w = img.getWidth(null);
3541         final int h = img.getHeight(null);
3542         Boolean hidpiImageDrawn = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h,
3543                                                  null, observer, xform);






3544 
3545         if (hidpiImageDrawn != null) {
3546             return hidpiImageDrawn;












3547         }
3548 
3549         return transformImage(img, xform, observer);
3550     }
3551 
3552     public void drawImage(BufferedImage bImg,
3553                           BufferedImageOp op,
3554                           int x,
3555                           int y)  {
3556 
3557         if (bImg == null) {
3558             return;
3559         }
3560 
3561         try {
3562             imagepipe.transformImage(this, bImg, op, x, y);
3563         } catch (InvalidPipeException e) {
3564             try {
3565                 revalidateAll();
3566                 imagepipe.transformImage(this, bImg, op, x, y);
3567             } catch (InvalidPipeException e2) {
3568                 // Still catching the exception; we are not yet ready to
3569                 // validate the surfaceData correctly.  Fail for now and


< prev index next >