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
97 /**
98 * This is a the master Graphics2D superclass for all of the Sun
99 * Graphics implementations. This class relies on subclasses to
100 * manage the various device information, but provides an overall
101 * general framework for performing all of the requests in the
102 * Graphics and Graphics2D APIs.
103 *
104 * @author Jim Graham
105 */
106 public final class SunGraphics2D
107 extends Graphics2D
108 implements ConstrainableGraphics, Cloneable, DestSurfaceProvider
109 {
110 /*
111 * Attribute States
112 */
113 /* Paint */
114 @Native
115 public static final int PAINT_CUSTOM = 6; /* Any other Paint object */
2071 revalidateAll();
2072 doCopyArea(x, y, w, h, dx, dy);
2073 } catch (InvalidPipeException e2) {
2074 // Still catching the exception; we are not yet ready to
2075 // validate the surfaceData correctly. Fail for now and
2076 // try again next time around.
2077 }
2078 } finally {
2079 surfaceData.markDirty();
2080 }
2081 }
2082
2083 private void doCopyArea(int x, int y, int w, int h, int dx, int dy) {
2084 if (w <= 0 || h <= 0) {
2085 return;
2086 }
2087 SurfaceData theData = surfaceData;
2088 if (theData.copyArea(this, x, y, w, h, dx, dy)) {
2089 return;
2090 }
2091 if (transformState >= TRANSFORM_TRANSLATESCALE) {
2092 throw new InternalError("transformed copyArea not implemented yet");
2093 }
2094 // REMIND: This method does not deal with missing data from the
2095 // source object (i.e. it does not send exposure events...)
2096
2097 Region clip = getCompClip();
2098
2099 Composite comp = composite;
2100 if (lastCAcomp != comp) {
2101 SurfaceType dsttype = theData.getSurfaceType();
2102 CompositeType comptype = imageComp;
2103 if (CompositeType.SrcOverNoEa.equals(comptype) &&
2104 theData.getTransparency() == Transparency.OPAQUE)
2105 {
2106 comptype = CompositeType.SrcNoEa;
2107 }
2108 lastCAblit = Blit.locate(dsttype, comptype, dsttype);
2109 lastCAcomp = comp;
2110 }
2111
2112 x += transX;
2113 y += transY;
2114
2115 Blit ob = lastCAblit;
2116 if (dy == 0 && dx > 0 && dx < w) {
2117 while (w > 0) {
2118 int partW = Math.min(w, dx);
2119 w -= partW;
2120 int sx = x + w;
2121 ob.Blit(theData, theData, comp, clip,
2122 sx, y, sx+dx, y+dy, partW, h);
2123 }
2124 return;
2125 }
2126 if (dy > 0 && dy < h && dx > -w && dx < w) {
2127 while (h > 0) {
2128 int partH = Math.min(h, dy);
2129 h -= partH;
2130 int sy = y + h;
2131 ob.Blit(theData, theData, comp, clip,
2132 x, sy, x+dx, sy+dy, w, partH);
2133 }
3034 }
3035
3036 try {
3037 textpipe.drawChars(this, chData, 0, length, x, y);
3038 } catch (InvalidPipeException e) {
3039 try {
3040 revalidateAll();
3041 textpipe.drawChars(this, chData, 0, length, x, y);
3042 } catch (InvalidPipeException e2) {
3043 // Still catching the exception; we are not yet ready to
3044 // validate the surfaceData correctly. Fail for now and
3045 // try again next time around.
3046 }
3047 } finally {
3048 surfaceData.markDirty();
3049 }
3050 }
3051 // end of text rendering methods
3052
3053 private static boolean isHiDPIImage(final Image img) {
3054 return SurfaceManager.getImageScale(img) != 1;
3055 }
3056
3057 private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
3058 int dy2, int sx1, int sy1, int sx2, int sy2,
3059 Color bgcolor, ImageObserver observer) {
3060 final int scale = SurfaceManager.getImageScale(img);
3061 sx1 = Region.clipScale(sx1, scale);
3062 sx2 = Region.clipScale(sx2, scale);
3063 sy1 = Region.clipScale(sy1, scale);
3064 sy2 = Region.clipScale(sy2, scale);
3065 try {
3066 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
3067 sx2, sy2, bgcolor, observer);
3068 } catch (InvalidPipeException e) {
3069 try {
3070 revalidateAll();
3071 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1,
3072 sy1, sx2, sy2, bgcolor, observer);
3073 } catch (InvalidPipeException e2) {
3074 // Still catching the exception; we are not yet ready to
3075 // validate the surfaceData correctly. Fail for now and
3076 // try again next time around.
3077 return false;
3078 }
3079 } finally {
3080 surfaceData.markDirty();
3081 }
3082 }
3083
3084 /**
3085 * Draws an image scaled to x,y,w,h in nonblocking mode with a
3086 * callback object.
3087 */
3088 public boolean drawImage(Image img, int x, int y, int width, int height,
3089 ImageObserver observer) {
3090 return drawImage(img, x, y, width, height, null, observer);
3091 }
3092
3093 /**
3094 * Not part of the advertised API but a useful utility method
3095 * to call internally. This is for the case where we are
3096 * drawing to/from given coordinates using a given width/height,
3097 * but we guarantee that the surfaceData's width/height of the src and dest
3098 * areas are equal (no scale needed). Note that this method intentionally
3099 * ignore scale factor of the source image, and copy it as is.
3100 */
3101 public boolean copyImage(Image img, int dx, int dy, int sx, int sy,
3102 int width, int height, Color bgcolor,
3103 ImageObserver observer) {
3341 return imagepipe.transformImage(this, img, xform, observer);
3342 } catch (InvalidPipeException e2) {
3343 // Still catching the exception; we are not yet ready to
3344 // validate the surfaceData correctly. Fail for now and
3345 // try again next time around.
3346 return false;
3347 }
3348 } finally {
3349 surfaceData.markDirty();
3350 }
3351 }
3352
3353 public void drawImage(BufferedImage bImg,
3354 BufferedImageOp op,
3355 int x,
3356 int y) {
3357
3358 if (bImg == null) {
3359 return;
3360 }
3361
3362 try {
3363 imagepipe.transformImage(this, bImg, op, x, y);
3364 } catch (InvalidPipeException e) {
3365 try {
3366 revalidateAll();
3367 imagepipe.transformImage(this, bImg, op, x, y);
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 }
3373 } finally {
3374 surfaceData.markDirty();
3375 }
3376 }
3377
3378 /**
3379 * Get the rendering context of the font
3380 * within this Graphics2D context.
3381 */
|
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 sun.awt.image.OffScreenImage;
97
98 /**
99 * This is a the master Graphics2D superclass for all of the Sun
100 * Graphics implementations. This class relies on subclasses to
101 * manage the various device information, but provides an overall
102 * general framework for performing all of the requests in the
103 * Graphics and Graphics2D APIs.
104 *
105 * @author Jim Graham
106 */
107 public final class SunGraphics2D
108 extends Graphics2D
109 implements ConstrainableGraphics, Cloneable, DestSurfaceProvider
110 {
111 /*
112 * Attribute States
113 */
114 /* Paint */
115 @Native
116 public static final int PAINT_CUSTOM = 6; /* Any other Paint object */
2072 revalidateAll();
2073 doCopyArea(x, y, w, h, dx, dy);
2074 } catch (InvalidPipeException e2) {
2075 // Still catching the exception; we are not yet ready to
2076 // validate the surfaceData correctly. Fail for now and
2077 // try again next time around.
2078 }
2079 } finally {
2080 surfaceData.markDirty();
2081 }
2082 }
2083
2084 private void doCopyArea(int x, int y, int w, int h, int dx, int dy) {
2085 if (w <= 0 || h <= 0) {
2086 return;
2087 }
2088 SurfaceData theData = surfaceData;
2089 if (theData.copyArea(this, x, y, w, h, dx, dy)) {
2090 return;
2091 }
2092 if (transformState > TRANSFORM_TRANSLATESCALE) {
2093 throw new InternalError("transformed copyArea not implemented yet");
2094 }
2095 // REMIND: This method does not deal with missing data from the
2096 // source object (i.e. it does not send exposure events...)
2097
2098 Region clip = getCompClip();
2099
2100 Composite comp = composite;
2101 if (lastCAcomp != comp) {
2102 SurfaceType dsttype = theData.getSurfaceType();
2103 CompositeType comptype = imageComp;
2104 if (CompositeType.SrcOverNoEa.equals(comptype) &&
2105 theData.getTransparency() == Transparency.OPAQUE)
2106 {
2107 comptype = CompositeType.SrcNoEa;
2108 }
2109 lastCAblit = Blit.locate(dsttype, comptype, dsttype);
2110 lastCAcomp = comp;
2111 }
2112
2113 double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
2114 transform.transform(coords, 0, coords, 0, 3);
2115
2116 x = (int)Math.ceil(coords[0] - 0.5);
2117 y = (int)Math.ceil(coords[1] - 0.5);
2118 w = ((int)Math.ceil(coords[2] - 0.5)) - x;
2119 h = ((int)Math.ceil(coords[3] - 0.5)) - y;
2120 dx = ((int)Math.ceil(coords[4] - 0.5)) - x;
2121 dy = ((int)Math.ceil(coords[5] - 0.5)) - y;
2122
2123 Blit ob = lastCAblit;
2124 if (dy == 0 && dx > 0 && dx < w) {
2125 while (w > 0) {
2126 int partW = Math.min(w, dx);
2127 w -= partW;
2128 int sx = x + w;
2129 ob.Blit(theData, theData, comp, clip,
2130 sx, y, sx+dx, y+dy, partW, h);
2131 }
2132 return;
2133 }
2134 if (dy > 0 && dy < h && dx > -w && dx < w) {
2135 while (h > 0) {
2136 int partH = Math.min(h, dy);
2137 h -= partH;
2138 int sy = y + h;
2139 ob.Blit(theData, theData, comp, clip,
2140 x, sy, x+dx, sy+dy, w, partH);
2141 }
3042 }
3043
3044 try {
3045 textpipe.drawChars(this, chData, 0, length, x, y);
3046 } catch (InvalidPipeException e) {
3047 try {
3048 revalidateAll();
3049 textpipe.drawChars(this, chData, 0, length, x, y);
3050 } catch (InvalidPipeException e2) {
3051 // Still catching the exception; we are not yet ready to
3052 // validate the surfaceData correctly. Fail for now and
3053 // try again next time around.
3054 }
3055 } finally {
3056 surfaceData.markDirty();
3057 }
3058 }
3059 // end of text rendering methods
3060
3061 private static boolean isHiDPIImage(final Image img) {
3062 if (img instanceof OffScreenImage &&
3063 !((OffScreenImage)img).isReturnLayoutSize())
3064 {
3065 return false;
3066 }
3067 return SurfaceManager.getImageScale(img) != 1;
3068 }
3069
3070 private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
3071 int dy2, int sx1, int sy1, int sx2, int sy2,
3072 Color bgcolor, ImageObserver observer) {
3073 final int scale = SurfaceManager.getImageScale(img);
3074 sx1 = Region.clipScale(sx1, scale);
3075 sx2 = Region.clipScale(sx2, scale);
3076 sy1 = Region.clipScale(sy1, scale);
3077 sy2 = Region.clipScale(sy2, scale);
3078 try {
3079 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
3080 sx2, sy2, bgcolor, observer);
3081 } catch (InvalidPipeException e) {
3082 try {
3083 revalidateAll();
3084 return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1,
3085 sy1, sx2, sy2, bgcolor, observer);
3086 } catch (InvalidPipeException e2) {
3087 // Still catching the exception; we are not yet ready to
3088 // validate the surfaceData correctly. Fail for now and
3089 // try again next time around.
3090 return false;
3091 }
3092 } finally {
3093 surfaceData.markDirty();
3094 }
3095 }
3096
3097 private boolean drawHiDPIImage(BufferedImage img, BufferedImageOp op,
3098 int x, int y)
3099 {
3100 final int scale = SurfaceManager.getImageScale(img);
3101 if (op != null) {
3102 if (op instanceof AffineTransformOp) {
3103 AffineTransformOp atop = (AffineTransformOp)op;
3104 AffineTransform at = atop.getTransform();
3105 try {
3106 // The "atop" transform may move the bounding rect of the image,
3107 // so the scale transform should be applied before.
3108 at.concatenate(AffineTransform.getScaleInstance(scale, scale).createInverse());
3109 } catch (Exception e) {
3110 // the inverse is always possible
3111 }
3112 atop = new AffineTransformOp(at, atop.getInterpolationType());
3113 imagepipe.transformImage(this, img, atop, x, y);
3114 return true;
3115 }
3116 img = op.filter(img, null);
3117 }
3118 int w = img.getWidth();
3119 int h = img.getHeight();
3120 return drawHiDPIImage(img,
3121 x, y, x + w, y + h,
3122 0, 0, w, h,
3123 backgroundColor, null);
3124 }
3125
3126 /**
3127 * Draws an image scaled to x,y,w,h in nonblocking mode with a
3128 * callback object.
3129 */
3130 public boolean drawImage(Image img, int x, int y, int width, int height,
3131 ImageObserver observer) {
3132 return drawImage(img, x, y, width, height, null, observer);
3133 }
3134
3135 /**
3136 * Not part of the advertised API but a useful utility method
3137 * to call internally. This is for the case where we are
3138 * drawing to/from given coordinates using a given width/height,
3139 * but we guarantee that the surfaceData's width/height of the src and dest
3140 * areas are equal (no scale needed). Note that this method intentionally
3141 * ignore scale factor of the source image, and copy it as is.
3142 */
3143 public boolean copyImage(Image img, int dx, int dy, int sx, int sy,
3144 int width, int height, Color bgcolor,
3145 ImageObserver observer) {
3383 return imagepipe.transformImage(this, img, xform, observer);
3384 } catch (InvalidPipeException e2) {
3385 // Still catching the exception; we are not yet ready to
3386 // validate the surfaceData correctly. Fail for now and
3387 // try again next time around.
3388 return false;
3389 }
3390 } finally {
3391 surfaceData.markDirty();
3392 }
3393 }
3394
3395 public void drawImage(BufferedImage bImg,
3396 BufferedImageOp op,
3397 int x,
3398 int y) {
3399
3400 if (bImg == null) {
3401 return;
3402 }
3403 if (isHiDPIImage(bImg)) {
3404 drawHiDPIImage(bImg, op, x, y);
3405 return;
3406 }
3407 try {
3408 imagepipe.transformImage(this, bImg, op, x, y);
3409 } catch (InvalidPipeException e) {
3410 try {
3411 revalidateAll();
3412 imagepipe.transformImage(this, bImg, op, x, y);
3413 } catch (InvalidPipeException e2) {
3414 // Still catching the exception; we are not yet ready to
3415 // validate the surfaceData correctly. Fail for now and
3416 // try again next time around.
3417 }
3418 } finally {
3419 surfaceData.markDirty();
3420 }
3421 }
3422
3423 /**
3424 * Get the rendering context of the font
3425 * within this Graphics2D context.
3426 */
|