Source Code Cross Referenced for DrawImage.java in  » 6.0-JDK-Modules-sun » java2d » sun » java2d » pipe » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » java2d » sun.java2d.pipe 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package sun.java2d.pipe;
0027:
0028:        import java.awt.AlphaComposite;
0029:        import java.awt.Color;
0030:        import java.awt.Graphics2D;
0031:        import java.awt.Image;
0032:        import java.awt.Rectangle;
0033:        import java.awt.Transparency;
0034:        import java.awt.geom.AffineTransform;
0035:        import java.awt.geom.NoninvertibleTransformException;
0036:        import java.awt.image.AffineTransformOp;
0037:        import java.awt.image.BufferedImage;
0038:        import java.awt.image.BufferedImageOp;
0039:        import java.awt.image.ColorModel;
0040:        import java.awt.image.DataBuffer;
0041:        import java.awt.image.DirectColorModel;
0042:        import java.awt.image.ImageObserver;
0043:        import java.awt.image.IndexColorModel;
0044:        import java.awt.image.Raster;
0045:        import java.awt.image.VolatileImage;
0046:        import java.awt.image.WritableRaster;
0047:        import java.awt.image.ImagingOpException;
0048:        import sun.awt.SunHints;
0049:        import sun.awt.image.ImageRepresentation;
0050:        import sun.awt.image.ToolkitImage;
0051:        import sun.java2d.InvalidPipeException;
0052:        import sun.java2d.SunGraphics2D;
0053:        import sun.java2d.SurfaceData;
0054:        import sun.java2d.loops.Blit;
0055:        import sun.java2d.loops.BlitBg;
0056:        import sun.java2d.loops.TransformHelper;
0057:        import sun.java2d.loops.MaskBlit;
0058:        import sun.java2d.loops.CompositeType;
0059:        import sun.java2d.loops.ScaledBlit;
0060:        import sun.java2d.loops.SurfaceType;
0061:
0062:        public class DrawImage implements  DrawImagePipe {
0063:            public boolean copyImage(SunGraphics2D sg, Image img, int x, int y,
0064:                    Color bgColor) {
0065:                int imgw = img.getWidth(null);
0066:                int imgh = img.getHeight(null);
0067:                if (isSimpleTranslate(sg)) {
0068:                    return renderImageCopy(sg, img, bgColor, x + sg.transX, y
0069:                            + sg.transY, 0, 0, imgw, imgh);
0070:                }
0071:                AffineTransform atfm = sg.transform;
0072:                if ((x | y) != 0) {
0073:                    atfm = new AffineTransform(atfm);
0074:                    atfm.translate(x, y);
0075:                }
0076:                transformImage(sg, img, atfm, sg.interpolationType, 0, 0, imgw,
0077:                        imgh, bgColor);
0078:                return true;
0079:            }
0080:
0081:            public boolean copyImage(SunGraphics2D sg, Image img, int dx,
0082:                    int dy, int sx, int sy, int w, int h, Color bgColor) {
0083:                if (isSimpleTranslate(sg)) {
0084:                    return renderImageCopy(sg, img, bgColor, dx + sg.transX, dy
0085:                            + sg.transY, sx, sy, w, h);
0086:                }
0087:                scaleImage(sg, img, dx, dy, (dx + w), (dy + h), sx, sy,
0088:                        (sx + w), (sy + h), bgColor);
0089:                return true;
0090:            }
0091:
0092:            public boolean scaleImage(SunGraphics2D sg, Image img, int x,
0093:                    int y, int width, int height, Color bgColor) {
0094:                int imgw = img.getWidth(null);
0095:                int imgh = img.getHeight(null);
0096:                // Only accelerate scale if:
0097:                //	    - w/h positive values
0098:                //	    - sg transform integer translate/identity only
0099:                //	    - no bgColor in operation
0100:                if ((width > 0) && (height > 0) && isSimpleTranslate(sg)) {
0101:                    double dx1 = x + sg.transX;
0102:                    double dy1 = y + sg.transY;
0103:                    double dx2 = dx1 + width;
0104:                    double dy2 = dy1 + height;
0105:                    if (renderImageScale(sg, img, bgColor,
0106:                            sg.interpolationType, 0, 0, imgw, imgh, dx1, dy1,
0107:                            dx2, dy2)) {
0108:                        return true;
0109:                    }
0110:                }
0111:
0112:                AffineTransform atfm = sg.transform;
0113:                if ((x | y) != 0 || width != imgw || height != imgh) {
0114:                    atfm = new AffineTransform(atfm);
0115:                    atfm.translate(x, y);
0116:                    atfm.scale(((double) width) / imgw, ((double) height)
0117:                            / imgh);
0118:                }
0119:                transformImage(sg, img, atfm, sg.interpolationType, 0, 0, imgw,
0120:                        imgh, bgColor);
0121:                return true;
0122:            }
0123:
0124:            /*
0125:             * This method is only called in those circumstances where the
0126:             * operation has a non-null secondary transform specfied.  Its
0127:             * role is to check for various optimizations based on the types
0128:             * of both the secondary and SG2D transforms and to do some
0129:             * quick calculations to avoid having to combine the transforms
0130:             * and/or to call a more generalized method.
0131:             */
0132:            protected void transformImage(SunGraphics2D sg, Image img, int x,
0133:                    int y, AffineTransform extraAT, int interpType) {
0134:                int txtype = extraAT.getType();
0135:                int imgw = img.getWidth(null);
0136:                int imgh = img.getHeight(null);
0137:                boolean checkfinalxform;
0138:
0139:                if (sg.transformState <= sg.TRANSFORM_ANY_TRANSLATE
0140:                        && (txtype == AffineTransform.TYPE_IDENTITY || txtype == AffineTransform.TYPE_TRANSLATION)) {
0141:                    // First optimization - both are some kind of translate
0142:
0143:                    // Combine the translations and check if interpolation is necessary.
0144:                    double tx = extraAT.getTranslateX();
0145:                    double ty = extraAT.getTranslateY();
0146:                    tx += sg.transform.getTranslateX();
0147:                    ty += sg.transform.getTranslateY();
0148:                    int itx = (int) Math.floor(tx + 0.5);
0149:                    int ity = (int) Math.floor(ty + 0.5);
0150:                    if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR
0151:                            || (closeToInteger(itx, tx) && closeToInteger(ity,
0152:                                    ty))) {
0153:                        renderImageCopy(sg, img, null, x + itx, y + ity, 0, 0,
0154:                                imgw, imgh);
0155:                        return;
0156:                    }
0157:                    checkfinalxform = false;
0158:                } else if (sg.transformState <= sg.TRANSFORM_TRANSLATESCALE
0159:                        && ((txtype & (AffineTransform.TYPE_FLIP
0160:                                | AffineTransform.TYPE_MASK_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0)) {
0161:                    // Second optimization - both are some kind of translate or scale
0162:
0163:                    // Combine the scales and check if interpolation is necessary.
0164:
0165:                    // Transform source bounds by extraAT,
0166:                    // then translate the bounds again by x, y
0167:                    // then transform the bounds again by sg.transform
0168:                    double coords[] = new double[] { 0, 0, imgw, imgh, };
0169:                    extraAT.transform(coords, 0, coords, 0, 2);
0170:                    coords[0] += x;
0171:                    coords[1] += y;
0172:                    coords[2] += x;
0173:                    coords[3] += y;
0174:                    sg.transform.transform(coords, 0, coords, 0, 2);
0175:
0176:                    if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh, null,
0177:                            interpType, coords)) {
0178:                        return;
0179:                    }
0180:                    checkfinalxform = false;
0181:                } else {
0182:                    checkfinalxform = true;
0183:                }
0184:
0185:                // Begin Transform
0186:                AffineTransform tx = new AffineTransform(sg.transform);
0187:                tx.translate(x, y);
0188:                tx.concatenate(extraAT);
0189:
0190:                // Do not try any more optimizations if either of the cases
0191:                // above was tried as we have already verified that the
0192:                // resulting transform will not simplify.
0193:                if (checkfinalxform) {
0194:                    // In this case neither of the above simple transform
0195:                    // pairs was found so we will do some final tests on
0196:                    // the final rendering transform which may be the
0197:                    // simple product of two complex transforms.
0198:                    transformImage(sg, img, tx, interpType, 0, 0, imgw, imgh,
0199:                            null);
0200:                } else {
0201:                    renderImageXform(sg, img, tx, interpType, 0, 0, imgw, imgh,
0202:                            null);
0203:                }
0204:            }
0205:
0206:            /*
0207:             * This method is called with a final rendering transform that
0208:             * has combined all of the information about the Graphics2D
0209:             * transform attribute with the transformations specified by
0210:             * the arguments to the drawImage call.
0211:             * Its role is to see if the combined transform ends up being
0212:             * acceleratable by either a renderImageCopy or renderImageScale
0213:             * once all of the math is done.
0214:             *
0215:             * Note: The transform supplied here has an origin that is
0216:             * already adjusted to point to the device location where
0217:             * the (sx1, sy1) location of the source image should be placed.
0218:             */
0219:            protected void transformImage(SunGraphics2D sg, Image img,
0220:                    AffineTransform tx, int interpType, int sx1, int sy1,
0221:                    int sx2, int sy2, Color bgColor) {
0222:                // Transform 3 source corners by tx and analyze them
0223:                // for simplified operations (Copy or Scale).  Using
0224:                // 3 points lets us analyze any kind of transform,
0225:                // even transforms that involve very tiny amounts of
0226:                // rotation or skew to see if they degenerate to a
0227:                // simple scale or copy operation within the allowable
0228:                // error bounds.
0229:                // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
0230:                // because the transform is already translated such that
0231:                // the origin is where sx1, sy1 should go.
0232:                double coords[] = new double[6];
0233:                /* index:  0  1    2  3    4  5  */
0234:                /* coord: (0, 0), (w, h), (0, h) */
0235:                coords[2] = sx2 - sx1;
0236:                coords[3] = coords[5] = sy2 - sy1;
0237:                tx.transform(coords, 0, coords, 0, 3);
0238:                // First test if the X coords of the transformed UL
0239:                // and LL points match and that the Y coords of the
0240:                // transformed LR and LL points also match.
0241:                // If they do then it is a "rectilinear" transform and
0242:                // tryCopyOrScale will make sure it is upright and
0243:                // integer-based.
0244:                if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR
0245:                        && Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR
0246:                        && tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2, bgColor,
0247:                                interpType, coords)) {
0248:                    return;
0249:                }
0250:
0251:                renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2,
0252:                        bgColor);
0253:            }
0254:
0255:            /*
0256:             * Check the bounding coordinates of the transformed source
0257:             * image to see if they fall on integer coordinates such
0258:             * that they will cause no interpolation anomalies if we
0259:             * use our simplified Blit or ScaledBlit operations instead
0260:             * of a full transform operation.
0261:             */
0262:            protected boolean tryCopyOrScale(SunGraphics2D sg, Image img,
0263:                    int sx1, int sy1, int sx2, int sy2, Color bgColor,
0264:                    int interpType, double coords[]) {
0265:                double dx = coords[0];
0266:                double dy = coords[1];
0267:                double dw = coords[2] - dx;
0268:                double dh = coords[3] - dy;
0269:                // First check if width and height are very close to img w&h.
0270:                if (closeToInteger(sx2 - sx1, dw)
0271:                        && closeToInteger(sy2 - sy1, dh)) {
0272:                    // Round location to nearest pixel and then test
0273:                    // if it will cause interpolation anomalies.
0274:                    int idx = (int) Math.floor(dx + 0.5);
0275:                    int idy = (int) Math.floor(dy + 0.5);
0276:                    if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR
0277:                            || (closeToInteger(idx, dx) && closeToInteger(idy,
0278:                                    dy))) {
0279:                        renderImageCopy(sg, img, bgColor, idx, idy, sx1, sy1,
0280:                                sx2 - sx1, sy2 - sy1);
0281:                        return true;
0282:                    }
0283:                }
0284:                // (For now) We can only use our ScaledBlits if the image
0285:                // is upright (i.e. dw & dh both > 0)
0286:                if (dw > 0 && dh > 0) {
0287:                    if (renderImageScale(sg, img, bgColor, interpType, sx1,
0288:                            sy1, sx2, sy2, coords[0], coords[1], coords[2],
0289:                            coords[3])) {
0290:                        return true;
0291:                    }
0292:                }
0293:                return false;
0294:            }
0295:
0296:            /*
0297:             * Return a BufferedImage of the requested type with the indicated
0298:             * subimage of the original image located at 0,0 in the new image.
0299:             * If a bgColor is supplied, composite the original image over that
0300:             * color with a SrcOver operation, otherwise make a SrcNoEa copy.
0301:             */
0302:            BufferedImage makeBufferedImage(Image img, Color bgColor, int type,
0303:                    int sx1, int sy1, int sx2, int sy2) {
0304:                BufferedImage bimg = new BufferedImage(sx2 - sx1, sy2 - sy1,
0305:                        type);
0306:                Graphics2D g2d = bimg.createGraphics();
0307:                g2d.setComposite(AlphaComposite.Src);
0308:                if (bgColor != null) {
0309:                    g2d.setColor(bgColor);
0310:                    g2d.fillRect(0, 0, sx2 - sx1, sy2 - sy1);
0311:                    g2d.setComposite(AlphaComposite.SrcOver);
0312:                }
0313:                g2d.drawImage(img, -sx1, -sy1, null);
0314:                g2d.dispose();
0315:                return bimg;
0316:            }
0317:
0318:            protected void renderImageXform(SunGraphics2D sg, Image img,
0319:                    AffineTransform tx, int interpType, int sx1, int sy1,
0320:                    int sx2, int sy2, Color bgColor) {
0321:                Region clip = sg.getCompClip();
0322:                SurfaceData dstData = sg.surfaceData;
0323:                SurfaceData srcData = dstData.getSourceSurfaceData(img,
0324:                        sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
0325:
0326:                if (srcData == null) {
0327:                    img = getBufferedImage(img);
0328:                    srcData = dstData.getSourceSurfaceData(img,
0329:                            sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
0330:                    if (srcData == null) {
0331:                        // REMIND: Is this correct?  Can this happen?
0332:                        return;
0333:                    }
0334:                }
0335:
0336:                if (isBgOperation(srcData, bgColor)) {
0337:                    // We cannot perform bg operations during transform so make
0338:                    // an opaque temp image with the appropriate background
0339:                    // and work from there.
0340:                    img = makeBufferedImage(img, bgColor,
0341:                            BufferedImage.TYPE_INT_RGB, sx1, sy1, sx2, sy2);
0342:                    // Temp image has appropriate subimage at 0,0 now.
0343:                    sx2 -= sx1;
0344:                    sy2 -= sy1;
0345:                    sx1 = sy1 = 0;
0346:
0347:                    srcData = dstData.getSourceSurfaceData(img,
0348:                            sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
0349:                }
0350:
0351:                SurfaceType srcType = srcData.getSurfaceType();
0352:                TransformHelper helper = TransformHelper.getFromCache(srcType);
0353:
0354:                if (helper == null) {
0355:                    /* We have no helper for this source image type.
0356:                     * But we know that we do have helpers for both RGB and ARGB,
0357:                     * so convert to one of those types depending on transparency.
0358:                     * ARGB_PRE might be a better choice if the source image has
0359:                     * alpha, but it may cause some recursion here since we only
0360:                     * tend to have converters that convert to ARGB.
0361:                     */
0362:                    int type = ((srcData.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
0363:                            : BufferedImage.TYPE_INT_ARGB);
0364:                    img = makeBufferedImage(img, null, type, sx1, sy1, sx2, sy2);
0365:                    // Temp image has appropriate subimage at 0,0 now.
0366:                    sx2 -= sx1;
0367:                    sy2 -= sy1;
0368:                    sx1 = sy1 = 0;
0369:
0370:                    srcData = dstData.getSourceSurfaceData(img,
0371:                            sg.TRANSFORM_GENERIC, sg.imageComp, null);
0372:                    srcType = srcData.getSurfaceType();
0373:                    helper = TransformHelper.getFromCache(srcType);
0374:                    // assert(helper != null);
0375:                }
0376:
0377:                AffineTransform itx;
0378:                try {
0379:                    itx = tx.createInverse();
0380:                } catch (NoninvertibleTransformException e) {
0381:                    // Non-invertible transform means no output
0382:                    return;
0383:                }
0384:
0385:                /*
0386:                 * Find the maximum bounds on the destination that will be
0387:                 * affected by the transformed source.  First, transform all
0388:                 * four corners of the source and then min and max the resulting
0389:                 * destination coordinates of the transformed corners.
0390:                 * Note that tx already has the offset to sx1,sy1 accounted
0391:                 * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
0392:                 * source coordinates.
0393:                 */
0394:                double coords[] = new double[8];
0395:                /* corner:  UL      UR      LL      LR   */
0396:                /* index:  0  1    2  3    4  5    6  7  */
0397:                /* coord: (0, 0), (w, 0), (0, h), (w, h) */
0398:                coords[2] = coords[6] = sx2 - sx1;
0399:                coords[5] = coords[7] = sy2 - sy1;
0400:                tx.transform(coords, 0, coords, 0, 4);
0401:                double ddx1, ddy1, ddx2, ddy2;
0402:                ddx1 = ddx2 = coords[0];
0403:                ddy1 = ddy2 = coords[1];
0404:                for (int i = 2; i < coords.length; i += 2) {
0405:                    double d = coords[i];
0406:                    if (ddx1 > d)
0407:                        ddx1 = d;
0408:                    else if (ddx2 < d)
0409:                        ddx2 = d;
0410:                    d = coords[i + 1];
0411:                    if (ddy1 > d)
0412:                        ddy1 = d;
0413:                    else if (ddy2 < d)
0414:                        ddy2 = d;
0415:                }
0416:                int dx1 = (int) Math.floor(ddx1);
0417:                int dy1 = (int) Math.floor(ddy1);
0418:                int dx2 = (int) Math.ceil(ddx2);
0419:                int dy2 = (int) Math.ceil(ddy2);
0420:
0421:                SurfaceType dstType = dstData.getSurfaceType();
0422:                MaskBlit maskblit;
0423:                Blit blit;
0424:                if (sg.compositeState <= sg.COMP_ALPHA) {
0425:                    /* NOTE: We either have, or we can make,
0426:                     * a MaskBlit for any alpha composite type
0427:                     */
0428:                    maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre,
0429:                            sg.imageComp, dstType);
0430:
0431:                    /* NOTE: We can only use the native TransformHelper
0432:                     * func to go directly to the dest if both the helper
0433:                     * and the MaskBlit are native.
0434:                     * All helpers are native at this point, but some MaskBlit
0435:                     * objects are implemented in Java, so we need to check.
0436:                     */
0437:                    if (maskblit.getNativePrim() != 0) {
0438:                        // We can render directly.
0439:                        helper.Transform(maskblit, srcData, dstData,
0440:                                sg.composite, clip, itx, interpType, sx1, sy1,
0441:                                sx2, sy2, dx1, dy1, dx2, dy2, null, 0, 0);
0442:                        return;
0443:                    }
0444:                    blit = null;
0445:                } else {
0446:                    /* NOTE: We either have, or we can make,
0447:                     * a Blit for any composite type, even Custom
0448:                     */
0449:                    maskblit = null;
0450:                    blit = Blit.getFromCache(SurfaceType.IntArgbPre,
0451:                            sg.imageComp, dstType);
0452:                }
0453:
0454:                // We need to transform to a temp image and then copy
0455:                // just the pieces that are valid data to the dest.
0456:                BufferedImage tmpimg = new BufferedImage(dx2 - dx1, dy2 - dy1,
0457:                        BufferedImage.TYPE_INT_ARGB);
0458:                SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
0459:                SurfaceType tmpType = tmpData.getSurfaceType();
0460:                MaskBlit tmpmaskblit = MaskBlit.getFromCache(
0461:                        SurfaceType.IntArgbPre, CompositeType.SrcNoEa, tmpType);
0462:                /*
0463:                 * The helper function fills a temporary edges buffer
0464:                 * for us with the bounding coordinates of each scanline
0465:                 * in the following format:
0466:                 *
0467:                 * edges[0, 1] = [top y, bottom y)
0468:                 * edges[2, 3] = [left x, right x) of top row
0469:                 * ...
0470:                 * edges[h*2, h*2+1] = [left x, right x) of bottom row
0471:                 *
0472:                 * all coordinates in the edges array will be relative to dx1, dy1
0473:                 *
0474:                 * edges thus has to be h*2+2 in length
0475:                 */
0476:                int edges[] = new int[(dy2 - dy1) * 2 + 2];
0477:                helper.Transform(tmpmaskblit, srcData, tmpData,
0478:                        AlphaComposite.Src, null, itx, interpType, sx1, sy1,
0479:                        sx2, sy2, 0, 0, dx2 - dx1, dy2 - dy1, edges, dx1, dy1);
0480:
0481:                /*
0482:                 * Now copy the results, scanline by scanline, into the dest.
0483:                 * The edges array helps us minimize the work.
0484:                 */
0485:                int index = 2;
0486:                for (int y = edges[0]; y < edges[1]; y++) {
0487:                    int relx1 = edges[index++];
0488:                    int relx2 = edges[index++];
0489:                    if (relx1 >= relx2) {
0490:                        continue;
0491:                    }
0492:                    if (maskblit != null) {
0493:                        maskblit.MaskBlit(tmpData, dstData, sg.composite, clip,
0494:                                relx1, y, dx1 + relx1, dy1 + y, relx2 - relx1,
0495:                                1, null, 0, 0);
0496:                    } else {
0497:                        blit.Blit(tmpData, dstData, sg.composite, clip, relx1,
0498:                                y, dx1 + relx1, dy1 + y, relx2 - relx1, 1);
0499:                    }
0500:                }
0501:            }
0502:
0503:            // Render an image using only integer translation
0504:            // (no scale or transform or sub-pixel interpolated translations).
0505:            protected boolean renderImageCopy(SunGraphics2D sg, Image img,
0506:                    Color bgColor, int dx, int dy, int sx, int sy, int w, int h) {
0507:                Region clip = sg.getCompClip();
0508:                SurfaceData dstData = sg.surfaceData;
0509:
0510:                int attempts = 0;
0511:                // Loop up to twice through; this gives us a chance to
0512:                // revalidate the surfaceData objects in case of an exception
0513:                // and try it once more
0514:                while (true) {
0515:                    SurfaceData srcData = dstData.getSourceSurfaceData(img,
0516:                            sg.TRANSFORM_ISIDENT, sg.imageComp, bgColor);
0517:                    if (srcData == null) {
0518:                        return false;
0519:                    }
0520:
0521:                    try {
0522:                        SurfaceType srcType = srcData.getSurfaceType();
0523:                        SurfaceType dstType = dstData.getSurfaceType();
0524:                        blitSurfaceData(sg, clip, srcData, dstData, srcType,
0525:                                dstType, sx, sy, dx, dy, w, h, bgColor);
0526:                        return true;
0527:                    } catch (NullPointerException e) {
0528:                        if (!(SurfaceData.isNull(dstData) || SurfaceData
0529:                                .isNull(srcData))) {
0530:                            // Something else caused the exception, throw it...
0531:                            throw e;
0532:                        }
0533:                        return false;
0534:                        // NOP if we have been disposed
0535:                    } catch (InvalidPipeException e) {
0536:                        // Always catch the exception; try this a couple of times
0537:                        // and fail silently if the system is not yet ready to
0538:                        // revalidate the source or dest surfaceData objects.
0539:                        ++attempts;
0540:                        clip = sg.getCompClip(); // ensures sg.surfaceData is valid
0541:                        dstData = sg.surfaceData;
0542:                        if (SurfaceData.isNull(dstData)
0543:                                || SurfaceData.isNull(srcData)
0544:                                || (attempts > 1)) {
0545:                            return false;
0546:                        }
0547:                    }
0548:                }
0549:            }
0550:
0551:            // Render an image using only integer scaling (no transform).
0552:            protected boolean renderImageScale(SunGraphics2D sg, Image img,
0553:                    Color bgColor, int interpType, int sx1, int sy1, int sx2,
0554:                    int sy2, double dx1, double dy1, double dx2, double dy2) {
0555:                // Currently only NEAREST_NEIGHBOR interpolation is implemented
0556:                // for ScaledBlit operations.
0557:                if (interpType != AffineTransformOp.TYPE_NEAREST_NEIGHBOR) {
0558:                    return false;
0559:                }
0560:
0561:                Region clip = sg.getCompClip();
0562:                SurfaceData dstData = sg.surfaceData;
0563:
0564:                int attempts = 0;
0565:                // Loop up to twice through; this gives us a chance to
0566:                // revalidate the surfaceData objects in case of an exception
0567:                // and try it once more
0568:                while (true) {
0569:                    SurfaceData srcData = dstData.getSourceSurfaceData(img,
0570:                            sg.TRANSFORM_TRANSLATESCALE, sg.imageComp, bgColor);
0571:
0572:                    if (srcData == null || isBgOperation(srcData, bgColor)) {
0573:                        return false;
0574:                    }
0575:
0576:                    try {
0577:                        SurfaceType srcType = srcData.getSurfaceType();
0578:                        SurfaceType dstType = dstData.getSurfaceType();
0579:                        return scaleSurfaceData(sg, clip, srcData, dstData,
0580:                                srcType, dstType, sx1, sy1, sx2, sy2, dx1, dy1,
0581:                                dx2, dy2);
0582:                    } catch (NullPointerException e) {
0583:                        if (!SurfaceData.isNull(dstData)) {
0584:                            // Something else caused the exception, throw it...
0585:                            throw e;
0586:                        }
0587:                        return false;
0588:                        // NOP if we have been disposed
0589:                    } catch (InvalidPipeException e) {
0590:                        // Always catch the exception; try this a couple of times
0591:                        // and fail silently if the system is not yet ready to
0592:                        // revalidate the source or dest surfaceData objects.
0593:                        ++attempts;
0594:                        clip = sg.getCompClip(); // ensures sg.surfaceData is valid
0595:                        dstData = sg.surfaceData;
0596:                        if (SurfaceData.isNull(dstData)
0597:                                || SurfaceData.isNull(srcData)
0598:                                || (attempts > 1)) {
0599:                            return false;
0600:                        }
0601:                    }
0602:                }
0603:            }
0604:
0605:            public boolean scaleImage(SunGraphics2D sg, Image img, int dx1,
0606:                    int dy1, int dx2, int dy2, int sx1, int sy1, int sx2,
0607:                    int sy2, Color bgColor) {
0608:                int srcW, srcH, dstW, dstH;
0609:                int srcX, srcY, dstX, dstY;
0610:                boolean srcWidthFlip = false;
0611:                boolean srcHeightFlip = false;
0612:                boolean dstWidthFlip = false;
0613:                boolean dstHeightFlip = false;
0614:
0615:                if (sx2 > sx1) {
0616:                    srcW = sx2 - sx1;
0617:                    srcX = sx1;
0618:                } else {
0619:                    srcWidthFlip = true;
0620:                    srcW = sx1 - sx2;
0621:                    srcX = sx2;
0622:                }
0623:                if (sy2 > sy1) {
0624:                    srcH = sy2 - sy1;
0625:                    srcY = sy1;
0626:                } else {
0627:                    srcHeightFlip = true;
0628:                    srcH = sy1 - sy2;
0629:                    srcY = sy2;
0630:                }
0631:                if (dx2 > dx1) {
0632:                    dstW = dx2 - dx1;
0633:                    dstX = dx1;
0634:                } else {
0635:                    dstW = dx1 - dx2;
0636:                    dstWidthFlip = true;
0637:                    dstX = dx2;
0638:                }
0639:                if (dy2 > dy1) {
0640:                    dstH = dy2 - dy1;
0641:                    dstY = dy1;
0642:                } else {
0643:                    dstH = dy1 - dy2;
0644:                    dstHeightFlip = true;
0645:                    dstY = dy2;
0646:                }
0647:                if (srcW <= 0 || srcH <= 0) {
0648:                    return true;
0649:                }
0650:                // Only accelerate scale if it does not involve a flip or transform
0651:                if ((srcWidthFlip == dstWidthFlip)
0652:                        && (srcHeightFlip == dstHeightFlip)
0653:                        && isSimpleTranslate(sg)) {
0654:                    double ddx1 = dstX + sg.transX;
0655:                    double ddy1 = dstY + sg.transY;
0656:                    double ddx2 = ddx1 + dstW;
0657:                    double ddy2 = ddy1 + dstH;
0658:                    if (renderImageScale(sg, img, bgColor,
0659:                            sg.interpolationType, srcX, srcY, srcX + srcW, srcY
0660:                                    + srcH, ddx1, ddy1, ddx2, ddy2)) {
0661:                        return true;
0662:                    }
0663:                }
0664:
0665:                AffineTransform atfm = new AffineTransform(sg.transform);
0666:                atfm.translate(dx1, dy1);
0667:                double m00 = (double) (dx2 - dx1) / (sx2 - sx1);
0668:                double m11 = (double) (dy2 - dy1) / (sy2 - sy1);
0669:                atfm.scale(m00, m11);
0670:                atfm.translate(srcX - sx1, srcY - sy1);
0671:
0672:                int imgW = img.getWidth(null);
0673:                int imgH = img.getHeight(null);
0674:                srcW += srcX;
0675:                srcH += srcY;
0676:                // Make sure we are not out of bounds
0677:                if (srcW > imgW) {
0678:                    srcW = imgW;
0679:                }
0680:                if (srcH > imgH) {
0681:                    srcH = imgH;
0682:                }
0683:                if (srcX < 0) {
0684:                    atfm.translate(-srcX, 0);
0685:                    srcX = 0;
0686:                }
0687:                if (srcY < 0) {
0688:                    atfm.translate(0, -srcY);
0689:                    srcY = 0;
0690:                }
0691:                if (srcX >= srcW || srcY >= srcH) {
0692:                    return true;
0693:                }
0694:                // Note: src[WH] are currently the right and bottom coordinates.
0695:                // The following two lines would adjust src[WH] back to being
0696:                // dimensions.
0697:                //     srcW -= srcX;
0698:                //     srcH -= srcY;
0699:                // Since transformImage needs right and bottom coords we will
0700:                // omit this adjustment.
0701:
0702:                transformImage(sg, img, atfm, sg.interpolationType, srcX, srcY,
0703:                        srcW, srcH, bgColor);
0704:                return true;
0705:            }
0706:
0707:            /**
0708:             ** Utilities
0709:             ** The following methods are used by the public methods above
0710:             ** for performing various operations
0711:             **/
0712:
0713:            /*
0714:             * This constant represents a tradeoff between the
0715:             * need to make sure that image transformations are
0716:             * "very close" to integer device coordinates before
0717:             * we decide to use an integer scale or copy operation
0718:             * as a substitute and the fact that roundoff errors
0719:             * in AffineTransforms are frequently introduced by
0720:             * performing multiple sequential operations on them.
0721:             *
0722:             * The evaluation of bug 4990624 details the potential
0723:             * for this error cutoff to result in display anomalies
0724:             * in different types of image operations and how this
0725:             * value represents a good compromise here.
0726:             */
0727:            private static final double MAX_TX_ERROR = .0001;
0728:
0729:            public static boolean closeToInteger(int i, double d) {
0730:                return (Math.abs(d - i) < MAX_TX_ERROR);
0731:            }
0732:
0733:            public static boolean isSimpleTranslate(SunGraphics2D sg) {
0734:                int ts = sg.transformState;
0735:                if (ts <= sg.TRANSFORM_INT_TRANSLATE) {
0736:                    // Integer translates are always "simple"
0737:                    return true;
0738:                }
0739:                if (ts >= sg.TRANSFORM_TRANSLATESCALE) {
0740:                    // Scales and beyond are always "not simple"
0741:                    return false;
0742:                }
0743:                // non-integer translates are only simple when not interpolating
0744:                if (sg.interpolationType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR) {
0745:                    return true;
0746:                }
0747:                return false;
0748:            }
0749:
0750:            protected static boolean isBgOperation(SurfaceData srcData,
0751:                    Color bgColor) {
0752:                // If we cannot get the srcData, then cannot assume anything about
0753:                // the image
0754:                return ((srcData == null) || ((bgColor != null) && (srcData
0755:                        .getTransparency() != Transparency.OPAQUE)));
0756:            }
0757:
0758:            protected BufferedImage getBufferedImage(Image img) {
0759:                if (img instanceof  BufferedImage) {
0760:                    return (BufferedImage) img;
0761:                }
0762:                // Must be VolatileImage; get BufferedImage representation
0763:                return ((VolatileImage) img).getSnapshot();
0764:            }
0765:
0766:            /*
0767:             * Return the color model to be used with this BufferedImage and
0768:             * transform.
0769:             */
0770:            private ColorModel getTransformColorModel(SunGraphics2D sg,
0771:                    BufferedImage bImg, AffineTransform tx) {
0772:                ColorModel cm = bImg.getColorModel();
0773:                ColorModel dstCM = cm;
0774:
0775:                if (tx.isIdentity()) {
0776:                    return dstCM;
0777:                }
0778:                int type = tx.getType();
0779:                boolean needTrans = ((type & (tx.TYPE_MASK_ROTATION | tx.TYPE_GENERAL_TRANSFORM)) != 0);
0780:                if (!needTrans && type != tx.TYPE_TRANSLATION
0781:                        && type != tx.TYPE_IDENTITY) {
0782:                    double[] mtx = new double[4];
0783:                    tx.getMatrix(mtx);
0784:                    // Check out the matrix.  A non-integral scale will force ARGB
0785:                    // since the edge conditions cannot be guaranteed.
0786:                    needTrans = (mtx[0] != (int) mtx[0] || mtx[3] != (int) mtx[3]);
0787:                }
0788:
0789:                if (sg.renderHint != SunHints.INTVAL_RENDER_QUALITY) {
0790:                    if (cm instanceof  IndexColorModel) {
0791:                        Raster raster = bImg.getRaster();
0792:                        IndexColorModel icm = (IndexColorModel) cm;
0793:                        // Just need to make sure that we have a transparent pixel
0794:                        if (needTrans && cm.getTransparency() == cm.OPAQUE) {
0795:                            // Fix 4221407
0796:                            if (raster instanceof  sun.awt.image.BytePackedRaster) {
0797:                                dstCM = ColorModel.getRGBdefault();
0798:                            } else {
0799:                                double[] matrix = new double[6];
0800:                                tx.getMatrix(matrix);
0801:                                if (matrix[1] == 0. && matrix[2] == 0.
0802:                                        && matrix[4] == 0. && matrix[5] == 0.) {
0803:                                    // Only scaling so do not need to create
0804:                                } else {
0805:                                    int mapSize = icm.getMapSize();
0806:                                    if (mapSize < 256) {
0807:                                        int[] cmap = new int[mapSize + 1];
0808:                                        icm.getRGBs(cmap);
0809:                                        cmap[mapSize] = 0x0000;
0810:                                        dstCM = new IndexColorModel(icm
0811:                                                .getPixelSize(), mapSize + 1,
0812:                                                cmap, 0, true, mapSize,
0813:                                                DataBuffer.TYPE_BYTE);
0814:                                    } else {
0815:                                        dstCM = ColorModel.getRGBdefault();
0816:                                    }
0817:                                } /* if (matrix[0] < 1.f ...) */
0818:                            } /* raster instanceof sun.awt.image.BytePackedRaster */
0819:                        } /* if (cm.getTransparency() == cm.OPAQUE) */
0820:                    } /* if (cm instanceof IndexColorModel) */
0821:                    else if (needTrans && cm.getTransparency() == cm.OPAQUE) {
0822:                        // Need a bitmask transparency
0823:                        // REMIND: for now, use full transparency since no loops
0824:                        // for bitmask
0825:                        dstCM = ColorModel.getRGBdefault();
0826:                    }
0827:                } /* if (sg.renderHint == RENDER_QUALITY) */
0828:                else {
0829:
0830:                    if (cm instanceof  IndexColorModel
0831:                            || (needTrans && cm.getTransparency() == cm.OPAQUE)) {
0832:                        // Need a bitmask transparency
0833:                        // REMIND: for now, use full transparency since no loops
0834:                        // for bitmask
0835:                        dstCM = ColorModel.getRGBdefault();
0836:                    }
0837:                }
0838:
0839:                return dstCM;
0840:            }
0841:
0842:            protected void blitSurfaceData(SunGraphics2D sg, Region clipRegion,
0843:                    SurfaceData srcData, SurfaceData dstData,
0844:                    SurfaceType srcType, SurfaceType dstType, int sx, int sy,
0845:                    int dx, int dy, int w, int h, Color bgColor) {
0846:                if (w <= 0 || h <= 0) {
0847:                    /*
0848:                     * Fix for bugid 4783274 - BlitBg throws an exception for
0849:                     * a particular set of anomalous parameters.
0850:                     * REMIND: The native loops do proper clipping and would
0851:                     * detect this situation themselves, but the Java loops
0852:                     * all seem to trust their parameters a little too well
0853:                     * to the point where they will try to process a negative
0854:                     * area of pixels and throw exceptions.  The real fix is
0855:                     * to modify the Java loops to do proper clipping so that
0856:                     * they can deal with negative dimensions as well as
0857:                     * improperly large dimensions, but that fix is too risky
0858:                     * to integrate for Mantis at this point.  In the meantime
0859:                     * eliminating the negative or zero dimensions here is
0860:                     * "correct" and saves them from some nasty exceptional
0861:                     * conditions, one of which is the test case of 4783274.
0862:                     */
0863:                    return;
0864:                }
0865:                CompositeType comp = sg.imageComp;
0866:                if (CompositeType.SrcOverNoEa.equals(comp)
0867:                        && (srcData.getTransparency() == Transparency.OPAQUE || (bgColor != null && bgColor
0868:                                .getTransparency() == Transparency.OPAQUE))) {
0869:                    comp = CompositeType.SrcNoEa;
0870:                }
0871:                if (!isBgOperation(srcData, bgColor)) {
0872:                    Blit blit = Blit.getFromCache(srcType, comp, dstType);
0873:                    blit.Blit(srcData, dstData, sg.composite, clipRegion, sx,
0874:                            sy, dx, dy, w, h);
0875:                } else {
0876:                    BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType);
0877:                    blit.BlitBg(srcData, dstData, sg.composite, clipRegion,
0878:                            bgColor, sx, sy, dx, dy, w, h);
0879:                }
0880:            }
0881:
0882:            protected boolean scaleSurfaceData(SunGraphics2D sg,
0883:                    Region clipRegion, SurfaceData srcData,
0884:                    SurfaceData dstData, SurfaceType srcType,
0885:                    SurfaceType dstType, int sx1, int sy1, int sx2, int sy2,
0886:                    double dx1, double dy1, double dx2, double dy2) {
0887:                CompositeType comp = sg.imageComp;
0888:                if (CompositeType.SrcOverNoEa.equals(comp)
0889:                        && (srcData.getTransparency() == Transparency.OPAQUE)) {
0890:                    comp = CompositeType.SrcNoEa;
0891:                }
0892:
0893:                ScaledBlit blit = ScaledBlit.getFromCache(srcType, comp,
0894:                        dstType);
0895:                if (blit != null) {
0896:                    blit.Scale(srcData, dstData, sg.composite, clipRegion, sx1,
0897:                            sy1, sx2, sy2, dx1, dy1, dx2, dy2);
0898:                    return true;
0899:                }
0900:                return false;
0901:            }
0902:
0903:            protected static boolean imageReady(ToolkitImage sunimg,
0904:                    ImageObserver observer) {
0905:                if (sunimg.hasError()) {
0906:                    if (observer != null) {
0907:                        observer.imageUpdate(sunimg, ImageObserver.ERROR
0908:                                | ImageObserver.ABORT, -1, -1, -1, -1);
0909:                    }
0910:                    return false;
0911:                }
0912:                return true;
0913:            }
0914:
0915:            public boolean copyImage(SunGraphics2D sg, Image img, int x, int y,
0916:                    Color bgColor, ImageObserver observer) {
0917:                if (!(img instanceof  ToolkitImage)) {
0918:                    return copyImage(sg, img, x, y, bgColor);
0919:                } else {
0920:                    ToolkitImage sunimg = (ToolkitImage) img;
0921:                    if (!imageReady(sunimg, observer)) {
0922:                        return false;
0923:                    }
0924:                    ImageRepresentation ir = sunimg.getImageRep();
0925:                    return ir.drawToBufImage(sg, sunimg, x, y, bgColor,
0926:                            observer);
0927:                }
0928:            }
0929:
0930:            public boolean copyImage(SunGraphics2D sg, Image img, int dx,
0931:                    int dy, int sx, int sy, int w, int h, Color bgColor,
0932:                    ImageObserver observer) {
0933:                if (!(img instanceof  ToolkitImage)) {
0934:                    return copyImage(sg, img, dx, dy, sx, sy, w, h, bgColor);
0935:                } else {
0936:                    ToolkitImage sunimg = (ToolkitImage) img;
0937:                    if (!imageReady(sunimg, observer)) {
0938:                        return false;
0939:                    }
0940:                    ImageRepresentation ir = sunimg.getImageRep();
0941:                    return ir.drawToBufImage(sg, sunimg, dx, dy, (dx + w),
0942:                            (dy + h), sx, sy, (sx + w), (sy + h), bgColor,
0943:                            observer);
0944:                }
0945:            }
0946:
0947:            public boolean scaleImage(SunGraphics2D sg, Image img, int x,
0948:                    int y, int width, int height, Color bgColor,
0949:                    ImageObserver observer) {
0950:                if (!(img instanceof  ToolkitImage)) {
0951:                    return scaleImage(sg, img, x, y, width, height, bgColor);
0952:                } else {
0953:                    ToolkitImage sunimg = (ToolkitImage) img;
0954:                    if (!imageReady(sunimg, observer)) {
0955:                        return false;
0956:                    }
0957:                    ImageRepresentation ir = sunimg.getImageRep();
0958:                    return ir.drawToBufImage(sg, sunimg, x, y, width, height,
0959:                            bgColor, observer);
0960:                }
0961:            }
0962:
0963:            public boolean scaleImage(SunGraphics2D sg, Image img, int dx1,
0964:                    int dy1, int dx2, int dy2, int sx1, int sy1, int sx2,
0965:                    int sy2, Color bgColor, ImageObserver observer) {
0966:                if (!(img instanceof  ToolkitImage)) {
0967:                    return scaleImage(sg, img, dx1, dy1, dx2, dy2, sx1, sy1,
0968:                            sx2, sy2, bgColor);
0969:                } else {
0970:                    ToolkitImage sunimg = (ToolkitImage) img;
0971:                    if (!imageReady(sunimg, observer)) {
0972:                        return false;
0973:                    }
0974:                    ImageRepresentation ir = sunimg.getImageRep();
0975:                    return ir.drawToBufImage(sg, sunimg, dx1, dy1, dx2, dy2,
0976:                            sx1, sy1, sx2, sy2, bgColor, observer);
0977:                }
0978:            }
0979:
0980:            public boolean transformImage(SunGraphics2D sg, Image img,
0981:                    AffineTransform atfm, ImageObserver observer) {
0982:                if (!(img instanceof  ToolkitImage)) {
0983:                    transformImage(sg, img, 0, 0, atfm, sg.interpolationType);
0984:                    return true;
0985:                } else {
0986:                    ToolkitImage sunimg = (ToolkitImage) img;
0987:                    if (!imageReady(sunimg, observer)) {
0988:                        return false;
0989:                    }
0990:                    ImageRepresentation ir = sunimg.getImageRep();
0991:                    return ir.drawToBufImage(sg, sunimg, atfm, observer);
0992:                }
0993:            }
0994:
0995:            public void transformImage(SunGraphics2D sg, BufferedImage img,
0996:                    BufferedImageOp op, int x, int y) {
0997:                if (op != null) {
0998:                    if (op instanceof  AffineTransformOp) {
0999:                        AffineTransformOp atop = (AffineTransformOp) op;
1000:                        transformImage(sg, img, x, y, atop.getTransform(), atop
1001:                                .getInterpolationType());
1002:                        return;
1003:                    } else {
1004:                        img = op.filter(img, null);
1005:                    }
1006:                }
1007:                copyImage(sg, img, x, y, null);
1008:            }
1009:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.