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;
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,
|
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 return scaleImage(img, dx1, dy1, dx2, dy2,
3109 sx1, sy1, sx2, sy2,
3110 bgcolor, observer, xform);
3111 } else if (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_BASE
3112 && (img instanceof MultiResolutionImage)) {
3113 // get scaled destination image size
3114
3115 int width = img.getWidth(observer);
3116 int height = img.getHeight(observer);
3117
3118 Image resolutionVariant = getResolutionVariant(
3119 (MultiResolutionImage) img, width, height,
3120 dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
3121
3122 if (resolutionVariant != img && resolutionVariant != null) {
3123 // recalculate source region for the resolution variant
3124
3125 ImageObserver rvObserver = MultiResolutionToolkitImage.
3126 getResolutionVariantObserver(img, observer,
3127 width, height, -1, -1);
3128
3129 int rvWidth = resolutionVariant.getWidth(rvObserver);
3130 int rvHeight = resolutionVariant.getHeight(rvObserver);
3131
3132 if (0 < width && 0 < height && 0 < rvWidth && 0 < rvHeight) {
3133
3134 float widthScale = ((float) rvWidth) / width;
3135 float heightScale = ((float) rvHeight) / height;
3136
3137 sx1 = Region.clipScale(sx1, widthScale);
3138 sy1 = Region.clipScale(sy1, heightScale);
3139 sx2 = Region.clipScale(sx2, widthScale);
3140 sy2 = Region.clipScale(sy2, heightScale);
3141
3142 observer = rvObserver;
3143 img = resolutionVariant;
3144 return scaleImage(img, dx1, dy1, dx2, dy2,
3145 sx1, sy1, sx2, sy2,
3146 bgcolor, observer, xform);
3147 }
3148 }
3149 }
3150 return null;
3151 }
3152
3153 private boolean scaleImage(Image img, int dx1, int dy1, int dx2, int dy2,
3154 int sx1, int sy1, int sx2, int sy2,
3155 Color bgcolor, ImageObserver observer,
3156 AffineTransform xform) {
3157
3158 AffineTransform tx = null;
3159
3160 if (xform != null) {
3161 tx = new AffineTransform(transform);
3162 transform(xform);
3163 }
3164
3165 try {
3166 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
3167 sx2, sy2, bgcolor, observer);
3168 } catch (InvalidPipeException e) {
3169 try {
3170 revalidateAll();
3171 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1,
3172 sy1, sx2, sy2, bgcolor, observer);
3173 } catch (InvalidPipeException e2) {
3174 // Still catching the exception; we are not yet ready to
3175 // validate the surfaceData correctly. Fail for now and
3176 // try again next time around.
3177 return false;
3178 }
3179 } finally {
3180 surfaceData.markDirty();
3181
3182 if (tx != null) {
3183 transform.setTransform(tx);
3184 invalidateTransform();
3185 }
3186 }
3187 }
3188
3189 private Image getResolutionVariant(MultiResolutionImage img,
3190 int srcWidth, int srcHeight, int dx1, int dy1, int dx2, int dy2,
3191 int sx1, int sy1, int sx2, int sy2) {
3192
3193 if (srcWidth <= 0 || srcHeight <= 0) {
3194 return null;
3195 }
3196
3197 int sw = sx2 - sx1;
3198 int sh = sy2 - sy1;
3199
3200 if (sw == 0 || sh == 0) {
3201 return null;
3202 }
3203
3204 int type = transform.getType();
3205 int dw = dx2 - dx1;
3290 }
3291 }
3292
3293 /**
3294 * Draws an image scaled to x,y,w,h in nonblocking mode with a
3295 * solid background color and a callback object.
3296 */
3297 public boolean drawImage(Image img, int x, int y, int width, int height,
3298 Color bg, ImageObserver observer) {
3299
3300 if (img == null) {
3301 return true;
3302 }
3303
3304 if ((width == 0) || (height == 0)) {
3305 return true;
3306 }
3307
3308 final int imgW = img.getWidth(null);
3309 final int imgH = img.getHeight(null);
3310 Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + width, y + height,
3311 0, 0, imgW, imgH, bg, observer,
3312 null);
3313 if (hidpiImageDrawn != null) {
3314 return hidpiImageDrawn;
3315 }
3316
3317 if (width == imgW && height == imgH) {
3318 return copyImage(img, x, y, 0, 0, width, height, bg, observer);
3319 }
3320
3321 try {
3322 return imagepipe.scaleImage(this, img, x, y, width, height,
3323 bg, observer);
3324 } catch (InvalidPipeException e) {
3325 try {
3326 revalidateAll();
3327 return imagepipe.scaleImage(this, img, x, y, width, height,
3328 bg, observer);
3329 } catch (InvalidPipeException e2) {
3330 // Still catching the exception; we are not yet ready to
3331 // validate the surfaceData correctly. Fail for now and
3332 // try again next time around.
3333 return false;
3334 }
3338 }
3339
3340 /**
3341 * Draws an image at x,y in nonblocking mode.
3342 */
3343 public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
3344 return drawImage(img, x, y, null, observer);
3345 }
3346
3347 /**
3348 * Draws an image at x,y in nonblocking mode with a solid background
3349 * color and a callback object.
3350 */
3351 public boolean drawImage(Image img, int x, int y, Color bg,
3352 ImageObserver observer) {
3353
3354 if (img == null) {
3355 return true;
3356 }
3357
3358 final int imgW = img.getWidth(null);
3359 final int imgH = img.getHeight(null);
3360 Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + imgW, y + imgH,
3361 0, 0, imgW, imgH, bg, observer,
3362 null);
3363 if (hidpiImageDrawn != null) {
3364 return hidpiImageDrawn;
3365 }
3366
3367 try {
3368 return imagepipe.copyImage(this, img, x, y, bg, observer);
3369 } catch (InvalidPipeException e) {
3370 try {
3371 revalidateAll();
3372 return imagepipe.copyImage(this, img, x, y, bg, observer);
3373 } catch (InvalidPipeException e2) {
3374 // Still catching the exception; we are not yet ready to
3375 // validate the surfaceData correctly. Fail for now and
3376 // try again next time around.
3377 return false;
3378 }
3379 } finally {
3380 surfaceData.markDirty();
3381 }
3382 }
3383
3384 /**
3395
3396 /**
3397 * Draws a subrectangle of an image scaled to a destination rectangle in
3398 * nonblocking mode with a solid background color and a callback object.
3399 */
3400 public boolean drawImage(Image img,
3401 int dx1, int dy1, int dx2, int dy2,
3402 int sx1, int sy1, int sx2, int sy2,
3403 Color bgcolor, ImageObserver observer) {
3404
3405 if (img == null) {
3406 return true;
3407 }
3408
3409 if (dx1 == dx2 || dy1 == dy2 ||
3410 sx1 == sx2 || sy1 == sy2)
3411 {
3412 return true;
3413 }
3414
3415 Boolean hidpiImageDrawn = drawHiDPIImage(img, dx1, dy1, dx2, dy2,
3416 sx1, sy1, sx2, sy2,
3417 bgcolor, observer, null);
3418
3419 if (hidpiImageDrawn != null) {
3420 return hidpiImageDrawn;
3421 }
3422
3423 if (((sx2 - sx1) == (dx2 - dx1)) &&
3424 ((sy2 - sy1) == (dy2 - dy1)))
3425 {
3426 // Not a scale - forward it to a copy routine
3427 int srcX, srcY, dstX, dstY, width, height;
3428 if (sx2 > sx1) {
3429 width = sx2 - sx1;
3430 srcX = sx1;
3431 dstX = dx1;
3432 } else {
3433 width = sx1 - sx2;
3434 srcX = sx2;
3435 dstX = dx2;
3436 }
3437 if (sy2 > sy1) {
3438 height = sy2-sy1;
3439 srcY = sy1;
3440 dstY = dy1;
3481 * @param img The image to be drawn.
3482 * @param xform The transformation from image space into user space.
3483 * @param observer The image observer to be notified on the image producing
3484 * progress.
3485 * @see #transform
3486 * @see #setComposite
3487 * @see #setClip
3488 */
3489 public boolean drawImage(Image img,
3490 AffineTransform xform,
3491 ImageObserver observer) {
3492
3493 if (img == null) {
3494 return true;
3495 }
3496
3497 if (xform == null || xform.isIdentity()) {
3498 return drawImage(img, 0, 0, null, observer);
3499 }
3500
3501 final int w = img.getWidth(null);
3502 final int h = img.getHeight(null);
3503 Boolean hidpiImageDrawn = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h,
3504 null, observer, xform);
3505
3506 if (hidpiImageDrawn != null) {
3507 return hidpiImageDrawn;
3508 }
3509
3510 try {
3511 return imagepipe.transformImage(this, img, xform, observer);
3512 } catch (InvalidPipeException e) {
3513 try {
3514 revalidateAll();
3515 return imagepipe.transformImage(this, img, xform, observer);
3516 } catch (InvalidPipeException e2) {
3517 // Still catching the exception; we are not yet ready to
3518 // validate the surfaceData correctly. Fail for now and
3519 // try again next time around.
3520 return false;
3521 }
3522 } finally {
3523 surfaceData.markDirty();
3524 }
3525 }
3526
3527 public void drawImage(BufferedImage bImg,
|