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 sun.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 {
2091 revalidateAll();
2092 doCopyArea(x, y, w, h, dx, dy);
2093 } catch (InvalidPipeException e2) {
2094 // Still catching the exception; we are not yet ready to
2095 // validate the surfaceData correctly. Fail for now and
2096 // try again next time around.
2097 }
2098 } finally {
2099 surfaceData.markDirty();
2100 }
2101 }
2102
2103 private void doCopyArea(int x, int y, int w, int h, int dx, int dy) {
2104 if (w <= 0 || h <= 0) {
2105 return;
2106 }
2107 SurfaceData theData = surfaceData;
2108 if (theData.copyArea(this, x, y, w, h, dx, dy)) {
2109 return;
2110 }
2111 if (transformState >= TRANSFORM_TRANSLATESCALE) {
2112 throw new InternalError("transformed copyArea not implemented yet");
2113 }
2114 // REMIND: This method does not deal with missing data from the
2115 // source object (i.e. it does not send exposure events...)
2116
2117 Region clip = getCompClip();
2118
2119 Composite comp = composite;
2120 if (lastCAcomp != comp) {
2121 SurfaceType dsttype = theData.getSurfaceType();
2122 CompositeType comptype = imageComp;
2123 if (CompositeType.SrcOverNoEa.equals(comptype) &&
2124 theData.getTransparency() == Transparency.OPAQUE)
2125 {
2126 comptype = CompositeType.SrcNoEa;
2127 }
2128 lastCAblit = Blit.locate(dsttype, comptype, dsttype);
2129 lastCAcomp = comp;
2130 }
2131
2132 x += transX;
2133 y += transY;
2134
2135 Blit ob = lastCAblit;
2136 if (dy == 0 && dx > 0 && dx < w) {
2137 while (w > 0) {
2138 int partW = Math.min(w, dx);
2139 w -= partW;
2140 int sx = x + w;
2141 ob.Blit(theData, theData, comp, clip,
2142 sx, y, sx+dx, y+dy, partW, h);
2143 }
2144 return;
2145 }
2146 if (dy > 0 && dy < h && dx > -w && dx < w) {
2147 while (h > 0) {
2148 int partH = Math.min(h, dy);
2149 h -= partH;
2150 int sy = y + h;
2151 ob.Blit(theData, theData, comp, clip,
2152 x, sy, x+dx, sy+dy, w, partH);
2153 }
3056 }
3057
3058 try {
3059 textpipe.drawChars(this, chData, 0, length, x, y);
3060 } catch (InvalidPipeException e) {
3061 try {
3062 revalidateAll();
3063 textpipe.drawChars(this, chData, 0, length, x, y);
3064 } catch (InvalidPipeException e2) {
3065 // Still catching the exception; we are not yet ready to
3066 // validate the surfaceData correctly. Fail for now and
3067 // try again next time around.
3068 }
3069 } finally {
3070 surfaceData.markDirty();
3071 }
3072 }
3073 // end of text rendering methods
3074
3075 private boolean isHiDPIImage(final Image img) {
3076 return (SurfaceManager.getImageScale(img) != 1) ||
3077 (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_OFF
3078 && img instanceof MultiResolutionImage);
3079 }
3080
3081 private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
3082 int dy2, int sx1, int sy1, int sx2, int sy2,
3083 Color bgcolor, ImageObserver observer) {
3084
3085 if (SurfaceManager.getImageScale(img) != 1) { // Volatile Image
3086 final int scale = SurfaceManager.getImageScale(img);
3087 sx1 = Region.clipScale(sx1, scale);
3088 sx2 = Region.clipScale(sx2, scale);
3089 sy1 = Region.clipScale(sy1, scale);
3090 sy2 = Region.clipScale(sy2, scale);
3091 } else if (img instanceof MultiResolutionImage) {
3092 // get scaled destination image size
3093
3094 int width = img.getWidth(observer);
3095 int height = img.getHeight(observer);
3174 destRegionWidth = dw * Math.hypot(
3175 transform.getScaleX(), transform.getShearY());
3176 destRegionHeight = dh * Math.hypot(
3177 transform.getShearX(), transform.getScaleY());
3178 }
3179
3180 int destImageWidth = (int) Math.abs(srcWidth * destRegionWidth / sw);
3181 int destImageHeight = (int) Math.abs(srcHeight * destRegionHeight / sh);
3182
3183 Image resolutionVariant
3184 = img.getResolutionVariant(destImageWidth, destImageHeight);
3185
3186 if (resolutionVariant instanceof ToolkitImage
3187 && ((ToolkitImage) resolutionVariant).hasError()) {
3188 return null;
3189 }
3190
3191 return resolutionVariant;
3192 }
3193
3194 /**
3195 * Draws an image scaled to x,y,w,h in nonblocking mode with a
3196 * callback object.
3197 */
3198 public boolean drawImage(Image img, int x, int y, int width, int height,
3199 ImageObserver observer) {
3200 return drawImage(img, x, y, width, height, null, observer);
3201 }
3202
3203 /**
3204 * Not part of the advertised API but a useful utility method
3205 * to call internally. This is for the case where we are
3206 * drawing to/from given coordinates using a given width/height,
3207 * but we guarantee that the surfaceData's width/height of the src and dest
3208 * areas are equal (no scale needed). Note that this method intentionally
3209 * ignore scale factor of the source image, and copy it as is.
3210 */
3211 public boolean copyImage(Image img, int dx, int dy, int sx, int sy,
3212 int width, int height, Color bgcolor,
3213 ImageObserver observer) {
3451 return imagepipe.transformImage(this, img, xform, observer);
3452 } catch (InvalidPipeException e2) {
3453 // Still catching the exception; we are not yet ready to
3454 // validate the surfaceData correctly. Fail for now and
3455 // try again next time around.
3456 return false;
3457 }
3458 } finally {
3459 surfaceData.markDirty();
3460 }
3461 }
3462
3463 public void drawImage(BufferedImage bImg,
3464 BufferedImageOp op,
3465 int x,
3466 int y) {
3467
3468 if (bImg == null) {
3469 return;
3470 }
3471
3472 try {
3473 imagepipe.transformImage(this, bImg, op, x, y);
3474 } catch (InvalidPipeException e) {
3475 try {
3476 revalidateAll();
3477 imagepipe.transformImage(this, bImg, op, x, y);
3478 } catch (InvalidPipeException e2) {
3479 // Still catching the exception; we are not yet ready to
3480 // validate the surfaceData correctly. Fail for now and
3481 // try again next time around.
3482 }
3483 } finally {
3484 surfaceData.markDirty();
3485 }
3486 }
3487
3488 /**
3489 * Get the rendering context of the font
3490 * within this Graphics2D context.
3491 */
|
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 sun.awt.image.MultiResolutionImage;
98 import sun.awt.image.OffScreenImage;
99
100 import static java.awt.geom.AffineTransform.TYPE_FLIP;
101 import static java.awt.geom.AffineTransform.TYPE_MASK_SCALE;
102 import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;
103 import sun.awt.image.MultiResolutionToolkitImage;
104 import sun.awt.image.ToolkitImage;
105
106 /**
107 * This is a the master Graphics2D superclass for all of the Sun
108 * Graphics implementations. This class relies on subclasses to
109 * manage the various device information, but provides an overall
110 * general framework for performing all of the requests in the
111 * Graphics and Graphics2D APIs.
112 *
113 * @author Jim Graham
114 */
115 public final class SunGraphics2D
116 extends Graphics2D
117 implements ConstrainableGraphics, Cloneable, DestSurfaceProvider
118 {
2092 revalidateAll();
2093 doCopyArea(x, y, w, h, dx, dy);
2094 } catch (InvalidPipeException e2) {
2095 // Still catching the exception; we are not yet ready to
2096 // validate the surfaceData correctly. Fail for now and
2097 // try again next time around.
2098 }
2099 } finally {
2100 surfaceData.markDirty();
2101 }
2102 }
2103
2104 private void doCopyArea(int x, int y, int w, int h, int dx, int dy) {
2105 if (w <= 0 || h <= 0) {
2106 return;
2107 }
2108 SurfaceData theData = surfaceData;
2109 if (theData.copyArea(this, x, y, w, h, dx, dy)) {
2110 return;
2111 }
2112 if (transformState > TRANSFORM_TRANSLATESCALE) {
2113 throw new InternalError("transformed copyArea not implemented yet");
2114 }
2115 // REMIND: This method does not deal with missing data from the
2116 // source object (i.e. it does not send exposure events...)
2117
2118 Region clip = getCompClip();
2119
2120 Composite comp = composite;
2121 if (lastCAcomp != comp) {
2122 SurfaceType dsttype = theData.getSurfaceType();
2123 CompositeType comptype = imageComp;
2124 if (CompositeType.SrcOverNoEa.equals(comptype) &&
2125 theData.getTransparency() == Transparency.OPAQUE)
2126 {
2127 comptype = CompositeType.SrcNoEa;
2128 }
2129 lastCAblit = Blit.locate(dsttype, comptype, dsttype);
2130 lastCAcomp = comp;
2131 }
2132
2133 double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
2134 transform.transform(coords, 0, coords, 0, 3);
2135
2136 x = (int)Math.ceil(coords[0] - 0.5);
2137 y = (int)Math.ceil(coords[1] - 0.5);
2138 w = ((int)Math.ceil(coords[2] - 0.5)) - x;
2139 h = ((int)Math.ceil(coords[3] - 0.5)) - y;
2140 dx = ((int)Math.ceil(coords[4] - 0.5)) - x;
2141 dy = ((int)Math.ceil(coords[5] - 0.5)) - y;
2142
2143 // In case of negative scale transform, reflect the rect coords.
2144 if (w < 0) {
2145 w *= -1;
2146 x -= w;
2147 }
2148 if (h < 0) {
2149 h *= -1;
2150 y -= h;
2151 }
2152
2153 Blit ob = lastCAblit;
2154 if (dy == 0 && dx > 0 && dx < w) {
2155 while (w > 0) {
2156 int partW = Math.min(w, dx);
2157 w -= partW;
2158 int sx = x + w;
2159 ob.Blit(theData, theData, comp, clip,
2160 sx, y, sx+dx, y+dy, partW, h);
2161 }
2162 return;
2163 }
2164 if (dy > 0 && dy < h && dx > -w && dx < w) {
2165 while (h > 0) {
2166 int partH = Math.min(h, dy);
2167 h -= partH;
2168 int sy = y + h;
2169 ob.Blit(theData, theData, comp, clip,
2170 x, sy, x+dx, sy+dy, w, partH);
2171 }
3074 }
3075
3076 try {
3077 textpipe.drawChars(this, chData, 0, length, x, y);
3078 } catch (InvalidPipeException e) {
3079 try {
3080 revalidateAll();
3081 textpipe.drawChars(this, chData, 0, length, x, y);
3082 } catch (InvalidPipeException e2) {
3083 // Still catching the exception; we are not yet ready to
3084 // validate the surfaceData correctly. Fail for now and
3085 // try again next time around.
3086 }
3087 } finally {
3088 surfaceData.markDirty();
3089 }
3090 }
3091 // end of text rendering methods
3092
3093 private boolean isHiDPIImage(final Image img) {
3094 if (img instanceof OffScreenImage &&
3095 !((OffScreenImage)img).isReturnLayoutSize())
3096 {
3097 return false;
3098 }
3099 return (SurfaceManager.getImageScale(img) != 1) ||
3100 (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_OFF
3101 && img instanceof MultiResolutionImage);
3102 }
3103
3104 private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
3105 int dy2, int sx1, int sy1, int sx2, int sy2,
3106 Color bgcolor, ImageObserver observer) {
3107
3108 if (SurfaceManager.getImageScale(img) != 1) { // Volatile Image
3109 final int scale = SurfaceManager.getImageScale(img);
3110 sx1 = Region.clipScale(sx1, scale);
3111 sx2 = Region.clipScale(sx2, scale);
3112 sy1 = Region.clipScale(sy1, scale);
3113 sy2 = Region.clipScale(sy2, scale);
3114 } else if (img instanceof MultiResolutionImage) {
3115 // get scaled destination image size
3116
3117 int width = img.getWidth(observer);
3118 int height = img.getHeight(observer);
3197 destRegionWidth = dw * Math.hypot(
3198 transform.getScaleX(), transform.getShearY());
3199 destRegionHeight = dh * Math.hypot(
3200 transform.getShearX(), transform.getScaleY());
3201 }
3202
3203 int destImageWidth = (int) Math.abs(srcWidth * destRegionWidth / sw);
3204 int destImageHeight = (int) Math.abs(srcHeight * destRegionHeight / sh);
3205
3206 Image resolutionVariant
3207 = img.getResolutionVariant(destImageWidth, destImageHeight);
3208
3209 if (resolutionVariant instanceof ToolkitImage
3210 && ((ToolkitImage) resolutionVariant).hasError()) {
3211 return null;
3212 }
3213
3214 return resolutionVariant;
3215 }
3216
3217 private boolean drawHiDPIImage(BufferedImage img, BufferedImageOp op,
3218 int x, int y)
3219 {
3220 final int scale = SurfaceManager.getImageScale(img);
3221 if (op != null) {
3222 if (op instanceof AffineTransformOp) {
3223 AffineTransformOp atop = (AffineTransformOp)op;
3224 AffineTransform at = atop.getTransform();
3225 try {
3226 // The "atop" transform may move the bounding rect of the image,
3227 // so the scale transform should be applied before.
3228 at.concatenate(AffineTransform.getScaleInstance(scale, scale).createInverse());
3229 } catch (Exception e) {
3230 // the inverse is always possible
3231 }
3232 atop = new AffineTransformOp(at, atop.getInterpolationType());
3233 imagepipe.transformImage(this, img, atop, x, y);
3234 return true;
3235 }
3236 img = op.filter(img, null);
3237 }
3238 int w = img.getWidth();
3239 int h = img.getHeight();
3240 return drawHiDPIImage(img,
3241 x, y, x + w, y + h,
3242 0, 0, w, h,
3243 backgroundColor, null);
3244 }
3245
3246 /**
3247 * Draws an image scaled to x,y,w,h in nonblocking mode with a
3248 * callback object.
3249 */
3250 public boolean drawImage(Image img, int x, int y, int width, int height,
3251 ImageObserver observer) {
3252 return drawImage(img, x, y, width, height, null, observer);
3253 }
3254
3255 /**
3256 * Not part of the advertised API but a useful utility method
3257 * to call internally. This is for the case where we are
3258 * drawing to/from given coordinates using a given width/height,
3259 * but we guarantee that the surfaceData's width/height of the src and dest
3260 * areas are equal (no scale needed). Note that this method intentionally
3261 * ignore scale factor of the source image, and copy it as is.
3262 */
3263 public boolean copyImage(Image img, int dx, int dy, int sx, int sy,
3264 int width, int height, Color bgcolor,
3265 ImageObserver observer) {
3503 return imagepipe.transformImage(this, img, xform, observer);
3504 } catch (InvalidPipeException e2) {
3505 // Still catching the exception; we are not yet ready to
3506 // validate the surfaceData correctly. Fail for now and
3507 // try again next time around.
3508 return false;
3509 }
3510 } finally {
3511 surfaceData.markDirty();
3512 }
3513 }
3514
3515 public void drawImage(BufferedImage bImg,
3516 BufferedImageOp op,
3517 int x,
3518 int y) {
3519
3520 if (bImg == null) {
3521 return;
3522 }
3523 if (isHiDPIImage(bImg)) {
3524 drawHiDPIImage(bImg, op, x, y);
3525 return;
3526 }
3527 try {
3528 imagepipe.transformImage(this, bImg, op, x, y);
3529 } catch (InvalidPipeException e) {
3530 try {
3531 revalidateAll();
3532 imagepipe.transformImage(this, bImg, op, x, y);
3533 } catch (InvalidPipeException e2) {
3534 // Still catching the exception; we are not yet ready to
3535 // validate the surfaceData correctly. Fail for now and
3536 // try again next time around.
3537 }
3538 } finally {
3539 surfaceData.markDirty();
3540 }
3541 }
3542
3543 /**
3544 * Get the rendering context of the font
3545 * within this Graphics2D context.
3546 */
|