jdk/src/share/classes/sun/java2d/pipe/DrawImage.java
author ohair
Tue, 25 May 2010 15:58:33 -0700
changeset 5506 202f599c92aa
parent 888 c7009cf0001f
child 9830 692619a439fc
permissions -rw-r--r--
6943119: Rebrand source copyright notices Reviewed-by: darcy, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 888
diff changeset
     2
 * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 888
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 888
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 888
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 888
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 888
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.java2d.pipe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.AlphaComposite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Color;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.Graphics2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.Image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.Transparency;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.geom.AffineTransform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.geom.NoninvertibleTransformException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.image.AffineTransformOp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.image.BufferedImageOp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.awt.image.ColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.image.DataBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.awt.image.DirectColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.awt.image.ImageObserver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.image.IndexColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.image.Raster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.awt.image.VolatileImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.awt.image.WritableRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.awt.image.ImagingOpException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import sun.awt.SunHints;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import sun.awt.image.ImageRepresentation;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import sun.awt.image.ToolkitImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import sun.java2d.InvalidPipeException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import sun.java2d.SunGraphics2D;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import sun.java2d.SurfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import sun.java2d.loops.Blit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
import sun.java2d.loops.BlitBg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import sun.java2d.loops.TransformHelper;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import sun.java2d.loops.MaskBlit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
import sun.java2d.loops.CompositeType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import sun.java2d.loops.ScaledBlit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
import sun.java2d.loops.SurfaceType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
public class DrawImage implements DrawImagePipe
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    public boolean copyImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
                             int x, int y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
                             Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        int imgw = img.getWidth(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        int imgh = img.getHeight(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        if (isSimpleTranslate(sg)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
            return renderImageCopy(sg, img, bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
                                   x + sg.transX, y + sg.transY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
                                   0, 0, imgw, imgh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        AffineTransform atfm = sg.transform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        if ((x | y) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
            atfm = new AffineTransform(atfm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            atfm.translate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        transformImage(sg, img, atfm, sg.interpolationType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
                       0, 0, imgw, imgh, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    public boolean copyImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
                             int dx, int dy, int sx, int sy, int w, int h,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
                             Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        if (isSimpleTranslate(sg)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            return renderImageCopy(sg, img, bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
                                   dx + sg.transX, dy + sg.transY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
                                   sx, sy, w, h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        scaleImage(sg, img, dx, dy, (dx + w), (dy + h),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                   sx, sy, (sx + w), (sy + h), bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    public boolean scaleImage(SunGraphics2D sg, Image img, int x, int y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                              int width, int height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                              Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        int imgw = img.getWidth(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        int imgh = img.getHeight(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        // Only accelerate scale if:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        //          - w/h positive values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        //          - sg transform integer translate/identity only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        //          - no bgColor in operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        if ((width > 0) && (height > 0) && isSimpleTranslate(sg)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            double dx1 = x + sg.transX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            double dy1 = y + sg.transY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            double dx2 = dx1 + width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
            double dy2 = dy1 + height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
            if (renderImageScale(sg, img, bgColor, sg.interpolationType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                                 0, 0, imgw, imgh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                                 dx1, dy1, dx2, dy2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        AffineTransform atfm = sg.transform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        if ((x | y) != 0 || width != imgw || height != imgh) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            atfm = new AffineTransform(atfm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            atfm.translate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            atfm.scale(((double)width)/imgw, ((double)height)/imgh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        transformImage(sg, img, atfm, sg.interpolationType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                       0, 0, imgw, imgh, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * This method is only called in those circumstances where the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * operation has a non-null secondary transform specfied.  Its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * role is to check for various optimizations based on the types
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * of both the secondary and SG2D transforms and to do some
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * quick calculations to avoid having to combine the transforms
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * and/or to call a more generalized method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    protected void transformImage(SunGraphics2D sg, Image img, int x, int y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                  AffineTransform extraAT, int interpType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        int txtype = extraAT.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        int imgw = img.getWidth(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        int imgh = img.getHeight(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        boolean checkfinalxform;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        if (sg.transformState <= sg.TRANSFORM_ANY_TRANSLATE &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            (txtype == AffineTransform.TYPE_IDENTITY ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
             txtype == AffineTransform.TYPE_TRANSLATION))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            // First optimization - both are some kind of translate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            // Combine the translations and check if interpolation is necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            double tx = extraAT.getTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            double ty = extraAT.getTranslateY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            tx += sg.transform.getTranslateX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            ty += sg.transform.getTranslateY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            int itx = (int) Math.floor(tx + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            int ity = (int) Math.floor(ty + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                (closeToInteger(itx, tx) && closeToInteger(ity, ty)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                renderImageCopy(sg, img, null, x+itx, y+ity, 0, 0, imgw, imgh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            checkfinalxform = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        } else if (sg.transformState <= sg.TRANSFORM_TRANSLATESCALE &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                   ((txtype & (AffineTransform.TYPE_FLIP |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                               AffineTransform.TYPE_MASK_ROTATION |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                               AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            // Second optimization - both are some kind of translate or scale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            // Combine the scales and check if interpolation is necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            // Transform source bounds by extraAT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            // then translate the bounds again by x, y
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            // then transform the bounds again by sg.transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            double coords[] = new double[] {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                0, 0, imgw, imgh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            extraAT.transform(coords, 0, coords, 0, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            coords[0] += x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            coords[1] += y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            coords[2] += x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            coords[3] += y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            sg.transform.transform(coords, 0, coords, 0, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                               null, interpType, coords))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            checkfinalxform = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            checkfinalxform = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        // Begin Transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        AffineTransform tx = new AffineTransform(sg.transform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        tx.translate(x, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        tx.concatenate(extraAT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        // Do not try any more optimizations if either of the cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        // above was tried as we have already verified that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        // resulting transform will not simplify.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        if (checkfinalxform) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            // In this case neither of the above simple transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            // pairs was found so we will do some final tests on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            // the final rendering transform which may be the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            // simple product of two complex transforms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            transformImage(sg, img, tx, interpType, 0, 0, imgw, imgh, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            renderImageXform(sg, img, tx, interpType, 0, 0, imgw, imgh, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * This method is called with a final rendering transform that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     * has combined all of the information about the Graphics2D
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * transform attribute with the transformations specified by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * the arguments to the drawImage call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * Its role is to see if the combined transform ends up being
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * acceleratable by either a renderImageCopy or renderImageScale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * once all of the math is done.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * Note: The transform supplied here has an origin that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * already adjusted to point to the device location where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * the (sx1, sy1) location of the source image should be placed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    protected void transformImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                                  AffineTransform tx, int interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                                  int sx1, int sy1, int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                                  Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        // Transform 3 source corners by tx and analyze them
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        // for simplified operations (Copy or Scale).  Using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        // 3 points lets us analyze any kind of transform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        // even transforms that involve very tiny amounts of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        // rotation or skew to see if they degenerate to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        // simple scale or copy operation within the allowable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        // error bounds.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        // because the transform is already translated such that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        // the origin is where sx1, sy1 should go.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        double coords[] = new double[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        /* index:  0  1    2  3    4  5  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        /* coord: (0, 0), (w, h), (0, h) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        coords[2] = sx2 - sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        coords[3] = coords[5] = sy2 - sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        tx.transform(coords, 0, coords, 0, 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        // First test if the X coords of the transformed UL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        // and LL points match and that the Y coords of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        // transformed LR and LL points also match.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        // If they do then it is a "rectilinear" transform and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        // tryCopyOrScale will make sure it is upright and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        // integer-based.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                           bgColor, interpType, coords))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * Check the bounding coordinates of the transformed source
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * image to see if they fall on integer coordinates such
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * that they will cause no interpolation anomalies if we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * use our simplified Blit or ScaledBlit operations instead
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * of a full transform operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    protected boolean tryCopyOrScale(SunGraphics2D sg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                                     Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                                     int sx1, int sy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                                     int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                                     Color bgColor, int interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                                     double coords[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        double dx = coords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        double dy = coords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        double dw = coords[2] - dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        double dh = coords[3] - dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        // First check if width and height are very close to img w&h.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        if (closeToInteger(sx2-sx1, dw) && closeToInteger(sy2-sy1, dh)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            // Round location to nearest pixel and then test
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            // if it will cause interpolation anomalies.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            int idx = (int) Math.floor(dx + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            int idy = (int) Math.floor(dy + 0.5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                (closeToInteger(idx, dx) && closeToInteger(idy, dy)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                renderImageCopy(sg, img, bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                                idx, idy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                                sx1, sy1, sx2-sx1, sy2-sy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        // (For now) We can only use our ScaledBlits if the image
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        // is upright (i.e. dw & dh both > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        if (dw > 0 && dh > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            if (renderImageScale(sg, img, bgColor, interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                                 sx1, sy1, sx2, sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                                 coords[0], coords[1], coords[2], coords[3]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * Return a BufferedImage of the requested type with the indicated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * subimage of the original image located at 0,0 in the new image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * If a bgColor is supplied, composite the original image over that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * color with a SrcOver operation, otherwise make a SrcNoEa copy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    BufferedImage makeBufferedImage(Image img, Color bgColor, int type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                                    int sx1, int sy1, int sx2, int sy2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        BufferedImage bimg = new BufferedImage(sx2-sx1, sy2-sy1, type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        Graphics2D g2d = bimg.createGraphics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        g2d.setComposite(AlphaComposite.Src);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        if (bgColor != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            g2d.setColor(bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            g2d.fillRect(0, 0, sx2-sx1, sy2-sy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            g2d.setComposite(AlphaComposite.SrcOver);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        g2d.drawImage(img, -sx1, -sy1, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        g2d.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        return bimg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    protected void renderImageXform(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                                    AffineTransform tx, int interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                                    int sx1, int sy1, int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                                    Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        Region clip = sg.getCompClip();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        SurfaceData dstData = sg.surfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        SurfaceData srcData = dstData.getSourceSurfaceData(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                                                           sg.TRANSFORM_GENERIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                                                           sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                                                           bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        if (srcData == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            img = getBufferedImage(img);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            srcData = dstData.getSourceSurfaceData(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                                                   sg.TRANSFORM_GENERIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                                                   sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                                                   bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            if (srcData == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                // REMIND: Is this correct?  Can this happen?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        if (isBgOperation(srcData, bgColor)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            // We cannot perform bg operations during transform so make
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
            // an opaque temp image with the appropriate background
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            // and work from there.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            img = makeBufferedImage(img, bgColor, BufferedImage.TYPE_INT_RGB,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                                    sx1, sy1, sx2, sy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            // Temp image has appropriate subimage at 0,0 now.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            sx2 -= sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            sy2 -= sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            sx1 = sy1 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            srcData = dstData.getSourceSurfaceData(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                                                   sg.TRANSFORM_GENERIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                                                   sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                                                   bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        SurfaceType srcType = srcData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        TransformHelper helper = TransformHelper.getFromCache(srcType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        if (helper == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            /* We have no helper for this source image type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
             * But we know that we do have helpers for both RGB and ARGB,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
             * so convert to one of those types depending on transparency.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
             * ARGB_PRE might be a better choice if the source image has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
             * alpha, but it may cause some recursion here since we only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
             * tend to have converters that convert to ARGB.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            int type = ((srcData.getTransparency() == Transparency.OPAQUE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                        ? BufferedImage.TYPE_INT_RGB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                        : BufferedImage.TYPE_INT_ARGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
            img = makeBufferedImage(img, null, type, sx1, sy1, sx2, sy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            // Temp image has appropriate subimage at 0,0 now.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            sx2 -= sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            sy2 -= sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            sx1 = sy1 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            srcData = dstData.getSourceSurfaceData(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                                                   sg.TRANSFORM_GENERIC,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                                                   sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                                                   null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            srcType = srcData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            helper = TransformHelper.getFromCache(srcType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            // assert(helper != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        AffineTransform itx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            itx = tx.createInverse();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        } catch (NoninvertibleTransformException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            // Non-invertible transform means no output
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
         * Find the maximum bounds on the destination that will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
         * affected by the transformed source.  First, transform all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
         * four corners of the source and then min and max the resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
         * destination coordinates of the transformed corners.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
         * Note that tx already has the offset to sx1,sy1 accounted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
         * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
         * source coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        double coords[] = new double[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        /* corner:  UL      UR      LL      LR   */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        /* index:  0  1    2  3    4  5    6  7  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        /* coord: (0, 0), (w, 0), (0, h), (w, h) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        coords[2] = coords[6] = sx2 - sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        coords[5] = coords[7] = sy2 - sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        tx.transform(coords, 0, coords, 0, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        double ddx1, ddy1, ddx2, ddy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        ddx1 = ddx2 = coords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        ddy1 = ddy2 = coords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        for (int i = 2; i < coords.length; i += 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            double d = coords[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            if (ddx1 > d) ddx1 = d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            else if (ddx2 < d) ddx2 = d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            d = coords[i+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            if (ddy1 > d) ddy1 = d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            else if (ddy2 < d) ddy2 = d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        int dx1 = (int) Math.floor(ddx1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        int dy1 = (int) Math.floor(ddy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        int dx2 = (int) Math.ceil(ddx2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        int dy2 = (int) Math.ceil(ddy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        SurfaceType dstType = dstData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        MaskBlit maskblit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        Blit blit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        if (sg.compositeState <= sg.COMP_ALPHA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            /* NOTE: We either have, or we can make,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
             * a MaskBlit for any alpha composite type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                                             sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                                             dstType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            /* NOTE: We can only use the native TransformHelper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
             * func to go directly to the dest if both the helper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
             * and the MaskBlit are native.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
             * All helpers are native at this point, but some MaskBlit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
             * objects are implemented in Java, so we need to check.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
            if (maskblit.getNativePrim() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                // We can render directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                helper.Transform(maskblit, srcData, dstData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                                 sg.composite, clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                                 itx, interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                                 sx1, sy1, sx2, sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                                 dx1, dy1, dx2, dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                                 null, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            blit = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            /* NOTE: We either have, or we can make,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
             * a Blit for any composite type, even Custom
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            maskblit = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            blit = Blit.getFromCache(SurfaceType.IntArgbPre,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                                     sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                                     dstType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        // We need to transform to a temp image and then copy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        // just the pieces that are valid data to the dest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                                                 BufferedImage.TYPE_INT_ARGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        SurfaceType tmpType = tmpData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        MaskBlit tmpmaskblit =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            MaskBlit.getFromCache(SurfaceType.IntArgbPre,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                                  CompositeType.SrcNoEa,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                                  tmpType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
         * The helper function fills a temporary edges buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
         * for us with the bounding coordinates of each scanline
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
         * in the following format:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
         * edges[0, 1] = [top y, bottom y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
         * edges[2, 3] = [left x, right x) of top row
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
         * ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
         * edges[h*2, h*2+1] = [left x, right x) of bottom row
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
         * all coordinates in the edges array will be relative to dx1, dy1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
         * edges thus has to be h*2+2 in length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        int edges[] = new int[(dy2-dy1)*2+2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        helper.Transform(tmpmaskblit, srcData, tmpData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                         AlphaComposite.Src, null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                         itx, interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                         sx1, sy1, sx2, sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                         0, 0, dx2-dx1, dy2-dy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                         edges, dx1, dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
         * Now copy the results, scanline by scanline, into the dest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
         * The edges array helps us minimize the work.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        int index = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        for (int y = edges[0]; y < edges[1]; y++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            int relx1 = edges[index++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            int relx2 = edges[index++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            if (relx1 >= relx2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            if (maskblit != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                maskblit.MaskBlit(tmpData, dstData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                                  sg.composite, clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                                  relx1, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                                  dx1+relx1, dy1+y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                                  relx2 - relx1, 1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                                  null, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                blit.Blit(tmpData, dstData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                          sg.composite, clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                          relx1, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                          dx1+relx1, dy1+y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                          relx2 - relx1, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    // Render an image using only integer translation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
    // (no scale or transform or sub-pixel interpolated translations).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    protected boolean renderImageCopy(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                                      Color bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                                      int dx, int dy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                                      int sx, int sy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                                      int w, int h)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        Region clip = sg.getCompClip();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        SurfaceData dstData = sg.surfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        int attempts = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        // Loop up to twice through; this gives us a chance to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        // revalidate the surfaceData objects in case of an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        // and try it once more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            SurfaceData srcData =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                dstData.getSourceSurfaceData(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                                             sg.TRANSFORM_ISIDENT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                                             sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                                             bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            if (srcData == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                SurfaceType srcType = srcData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                SurfaceType dstType = dstData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                blitSurfaceData(sg, clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                                srcData, dstData, srcType, dstType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                                sx, sy, dx, dy, w, h, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            } catch (NullPointerException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                if (!(SurfaceData.isNull(dstData) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                      SurfaceData.isNull(srcData)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                    // Something else caused the exception, throw it...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                    throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                // NOP if we have been disposed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            } catch (InvalidPipeException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                // Always catch the exception; try this a couple of times
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                // and fail silently if the system is not yet ready to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                // revalidate the source or dest surfaceData objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                ++attempts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                clip = sg.getCompClip();   // ensures sg.surfaceData is valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                dstData = sg.surfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                if (SurfaceData.isNull(dstData) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                    SurfaceData.isNull(srcData) || (attempts > 1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    // Render an image using only integer scaling (no transform).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    protected boolean renderImageScale(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                                       Color bgColor, int interpType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                                       int sx1, int sy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                                       int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                                       double dx1, double dy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                                       double dx2, double dy2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        // Currently only NEAREST_NEIGHBOR interpolation is implemented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        // for ScaledBlit operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        if (interpType != AffineTransformOp.TYPE_NEAREST_NEIGHBOR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        Region clip = sg.getCompClip();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        SurfaceData dstData = sg.surfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        int attempts = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        // Loop up to twice through; this gives us a chance to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        // revalidate the surfaceData objects in case of an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        // and try it once more
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            SurfaceData srcData =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                dstData.getSourceSurfaceData(img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                                             sg.TRANSFORM_TRANSLATESCALE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                                             sg.imageComp,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                                             bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            if (srcData == null || isBgOperation(srcData, bgColor)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                SurfaceType srcType = srcData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                SurfaceType dstType = dstData.getSurfaceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                return scaleSurfaceData(sg, clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                                        srcData, dstData, srcType, dstType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                                        sx1, sy1, sx2, sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                                        dx1, dy1, dx2, dy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            } catch (NullPointerException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                if (!SurfaceData.isNull(dstData)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                    // Something else caused the exception, throw it...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                    throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                // NOP if we have been disposed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            } catch (InvalidPipeException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                // Always catch the exception; try this a couple of times
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                // and fail silently if the system is not yet ready to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                // revalidate the source or dest surfaceData objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                ++attempts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                clip = sg.getCompClip();  // ensures sg.surfaceData is valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                dstData = sg.surfaceData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                if (SurfaceData.isNull(dstData) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                    SurfaceData.isNull(srcData) || (attempts > 1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    public boolean scaleImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                              int dx1, int dy1, int dx2, int dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                              int sx1, int sy1, int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                              Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        int srcW, srcH, dstW, dstH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        int srcX, srcY, dstX, dstY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        boolean srcWidthFlip = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        boolean srcHeightFlip = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        boolean dstWidthFlip = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        boolean dstHeightFlip = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        if (sx2 > sx1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            srcW = sx2 - sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            srcX = sx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            srcWidthFlip = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            srcW = sx1 - sx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            srcX = sx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        if (sy2 > sy1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            srcH = sy2-sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            srcY = sy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            srcHeightFlip = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
            srcH = sy1-sy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
            srcY = sy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        if (dx2 > dx1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            dstW = dx2 - dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            dstX = dx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            dstW = dx1 - dx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            dstWidthFlip = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            dstX = dx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        if (dy2 > dy1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            dstH = dy2 - dy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            dstY = dy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            dstH = dy1 - dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            dstHeightFlip = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            dstY = dy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        if (srcW <= 0 || srcH <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        // Only accelerate scale if it does not involve a flip or transform
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        if ((srcWidthFlip == dstWidthFlip) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
            (srcHeightFlip == dstHeightFlip) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            isSimpleTranslate(sg))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            double ddx1 = dstX + sg.transX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            double ddy1 = dstY + sg.transY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
            double ddx2 = ddx1 + dstW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            double ddy2 = ddy1 + dstH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            if (renderImageScale(sg, img, bgColor, sg.interpolationType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                                 srcX, srcY, srcX+srcW, srcY+srcH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                                 ddx1, ddy1, ddx2, ddy2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        AffineTransform atfm = new AffineTransform(sg.transform);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        atfm.translate(dx1, dy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        double m00 = (double)(dx2-dx1)/(sx2-sx1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        double m11 = (double)(dy2-dy1)/(sy2-sy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
        atfm.scale(m00, m11);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        atfm.translate(srcX-sx1, srcY-sy1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        int imgW = img.getWidth(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        int imgH = img.getHeight(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        srcW += srcX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        srcH += srcY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        // Make sure we are not out of bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        if (srcW > imgW) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            srcW = imgW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        if (srcH > imgH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
            srcH = imgH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        if (srcX < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
            atfm.translate(-srcX, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            srcX = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        if (srcY < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            atfm.translate(0, -srcY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
            srcY = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        if (srcX >= srcW || srcY >= srcH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        // Note: src[WH] are currently the right and bottom coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        // The following two lines would adjust src[WH] back to being
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        // dimensions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        //     srcW -= srcX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        //     srcH -= srcY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        // Since transformImage needs right and bottom coords we will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        // omit this adjustment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        transformImage(sg, img, atfm, sg.interpolationType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                       srcX, srcY, srcW, srcH, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     ** Utilities
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     ** The following methods are used by the public methods above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     ** for performing various operations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     * This constant represents a tradeoff between the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
     * need to make sure that image transformations are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * "very close" to integer device coordinates before
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     * we decide to use an integer scale or copy operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
     * as a substitute and the fact that roundoff errors
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     * in AffineTransforms are frequently introduced by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     * performing multiple sequential operations on them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
     * The evaluation of bug 4990624 details the potential
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     * for this error cutoff to result in display anomalies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
     * in different types of image operations and how this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * value represents a good compromise here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    private static final double MAX_TX_ERROR = .0001;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    public static boolean closeToInteger(int i, double d) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        return (Math.abs(d-i) < MAX_TX_ERROR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    public static boolean isSimpleTranslate(SunGraphics2D sg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        int ts = sg.transformState;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        if (ts <= sg.TRANSFORM_INT_TRANSLATE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
            // Integer translates are always "simple"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        if (ts >= sg.TRANSFORM_TRANSLATESCALE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            // Scales and beyond are always "not simple"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        // non-integer translates are only simple when not interpolating
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        if (sg.interpolationType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    protected static boolean isBgOperation(SurfaceData srcData, Color bgColor) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        // If we cannot get the srcData, then cannot assume anything about
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        // the image
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        return ((srcData == null) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                ((bgColor != null) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                 (srcData.getTransparency() != Transparency.OPAQUE)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    protected BufferedImage getBufferedImage(Image img) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        if (img instanceof BufferedImage) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            return (BufferedImage)img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        // Must be VolatileImage; get BufferedImage representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        return ((VolatileImage)img).getSnapshot();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
     * Return the color model to be used with this BufferedImage and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
     * transform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    private ColorModel getTransformColorModel(SunGraphics2D sg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                                              BufferedImage bImg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                                              AffineTransform tx) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
        ColorModel cm = bImg.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
        ColorModel dstCM = cm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        if (tx.isIdentity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            return dstCM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        int type = tx.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        boolean needTrans =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            ((type&(tx.TYPE_MASK_ROTATION|tx.TYPE_GENERAL_TRANSFORM)) != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        if (! needTrans && type != tx.TYPE_TRANSLATION && type != tx.TYPE_IDENTITY)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            double[] mtx = new double[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            tx.getMatrix(mtx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
            // Check out the matrix.  A non-integral scale will force ARGB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            // since the edge conditions cannot be guaranteed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        if (sg.renderHint != SunHints.INTVAL_RENDER_QUALITY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            if (cm instanceof IndexColorModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                Raster raster = bImg.getRaster();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                IndexColorModel icm = (IndexColorModel) cm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                // Just need to make sure that we have a transparent pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                if (needTrans && cm.getTransparency() == cm.OPAQUE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    // Fix 4221407
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    if (raster instanceof sun.awt.image.BytePackedRaster) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                        dstCM = ColorModel.getRGBdefault();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                        double[] matrix = new double[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                        tx.getMatrix(matrix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                        if (matrix[1] == 0. && matrix[2] ==0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                            && matrix[4] == 0. && matrix[5] == 0.) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                            // Only scaling so do not need to create
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                            int mapSize = icm.getMapSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                            if (mapSize < 256) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                                int[] cmap = new int[mapSize+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                                icm.getRGBs(cmap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                                cmap[mapSize] = 0x0000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                                dstCM = new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                                    IndexColorModel(icm.getPixelSize(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                                                    mapSize+1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                                                    cmap, 0, true, mapSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                                                    DataBuffer.TYPE_BYTE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                                dstCM = ColorModel.getRGBdefault();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                        }  /* if (matrix[0] < 1.f ...) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                    }   /* raster instanceof sun.awt.image.BytePackedRaster */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                } /* if (cm.getTransparency() == cm.OPAQUE) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            } /* if (cm instanceof IndexColorModel) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            else if (needTrans && cm.getTransparency() == cm.OPAQUE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                // Need a bitmask transparency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
                // REMIND: for now, use full transparency since no loops
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                // for bitmask
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                dstCM = ColorModel.getRGBdefault();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        } /* if (sg.renderHint == RENDER_QUALITY) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
            if (cm instanceof IndexColorModel ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                (needTrans && cm.getTransparency() == cm.OPAQUE))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
                // Need a bitmask transparency
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
                // REMIND: for now, use full transparency since no loops
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
                // for bitmask
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
                dstCM = ColorModel.getRGBdefault();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
        return dstCM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
    protected void blitSurfaceData(SunGraphics2D sg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
                                   Region clipRegion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                                   SurfaceData srcData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                                   SurfaceData dstData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
                                   SurfaceType srcType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
                                   SurfaceType dstType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
                                   int sx, int sy, int dx, int dy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
                                   int w, int h,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                                   Color bgColor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        if (w <= 0 || h <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
             * Fix for bugid 4783274 - BlitBg throws an exception for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
             * a particular set of anomalous parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
             * REMIND: The native loops do proper clipping and would
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
             * detect this situation themselves, but the Java loops
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
             * all seem to trust their parameters a little too well
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
             * to the point where they will try to process a negative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
             * area of pixels and throw exceptions.  The real fix is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
             * to modify the Java loops to do proper clipping so that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
             * they can deal with negative dimensions as well as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
             * improperly large dimensions, but that fix is too risky
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
             * to integrate for Mantis at this point.  In the meantime
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
             * eliminating the negative or zero dimensions here is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
             * "correct" and saves them from some nasty exceptional
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
             * conditions, one of which is the test case of 4783274.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
        CompositeType comp = sg.imageComp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        if (CompositeType.SrcOverNoEa.equals(comp) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            (srcData.getTransparency() == Transparency.OPAQUE ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
             (bgColor != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
              bgColor.getTransparency() == Transparency.OPAQUE)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
            comp = CompositeType.SrcNoEa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
        if (!isBgOperation(srcData, bgColor)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
            Blit blit = Blit.getFromCache(srcType, comp, dstType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            blit.Blit(srcData, dstData, sg.composite, clipRegion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
                      sx, sy, dx, dy, w, h);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
            blit.BlitBg(srcData, dstData, sg.composite, clipRegion,
887
0aab8d3fa11a 6725214: D3D: forward-port the new pipeline from 6u10
tdv
parents: 2
diff changeset
   958
                        bgColor.getRGB(), sx, sy, dx, dy, w, h);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
    protected boolean scaleSurfaceData(SunGraphics2D sg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
                                       Region clipRegion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
                                       SurfaceData srcData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
                                       SurfaceData dstData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
                                       SurfaceType srcType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                                       SurfaceType dstType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
                                       int sx1, int sy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
                                       int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
                                       double dx1, double dy1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
                                       double dx2, double dy2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
        CompositeType comp = sg.imageComp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        if (CompositeType.SrcOverNoEa.equals(comp) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
            (srcData.getTransparency() == Transparency.OPAQUE))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            comp = CompositeType.SrcNoEa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        ScaledBlit blit = ScaledBlit.getFromCache(srcType, comp, dstType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        if (blit != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            blit.Scale(srcData, dstData, sg.composite, clipRegion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                       sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
    protected static boolean imageReady(ToolkitImage sunimg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                                        ImageObserver observer)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
        if (sunimg.hasError()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            if (observer != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                observer.imageUpdate(sunimg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                                     ImageObserver.ERROR|ImageObserver.ABORT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
                                     -1, -1, -1, -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
    public boolean copyImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                             int x, int y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                             Color bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                             ImageObserver observer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        if (!(img instanceof ToolkitImage)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
            return copyImage(sg, img, x, y, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            ToolkitImage sunimg = (ToolkitImage)img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            if (!imageReady(sunimg, observer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
            ImageRepresentation ir = sunimg.getImageRep();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
            return ir.drawToBufImage(sg, sunimg, x, y, bgColor, observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    public boolean copyImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                             int dx, int dy, int sx, int sy, int w, int h,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                             Color bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                             ImageObserver observer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
        if (!(img instanceof ToolkitImage)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
            return copyImage(sg, img, dx, dy, sx, sy, w, h, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            ToolkitImage sunimg = (ToolkitImage)img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            if (!imageReady(sunimg, observer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
            ImageRepresentation ir = sunimg.getImageRep();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            return ir.drawToBufImage(sg, sunimg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                                     dx, dy, (dx + w), (dy + h),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
                                     sx, sy, (sx + w), (sy + h),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
                                     bgColor, observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
    public boolean scaleImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                                int x, int y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                                int width, int height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
                                Color bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                                ImageObserver observer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
        if (!(img instanceof ToolkitImage)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            return scaleImage(sg, img, x, y, width, height, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            ToolkitImage sunimg = (ToolkitImage)img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
            if (!imageReady(sunimg, observer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            ImageRepresentation ir = sunimg.getImageRep();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
            return ir.drawToBufImage(sg, sunimg, x, y, width, height, bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                                     observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
    public boolean scaleImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                              int dx1, int dy1, int dx2, int dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                              int sx1, int sy1, int sx2, int sy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                              Color bgColor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                              ImageObserver observer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        if (!(img instanceof ToolkitImage)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            return scaleImage(sg, img, dx1, dy1, dx2, dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
                              sx1, sy1, sx2, sy2, bgColor);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
            ToolkitImage sunimg = (ToolkitImage)img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            if (!imageReady(sunimg, observer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
            ImageRepresentation ir = sunimg.getImageRep();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            return ir.drawToBufImage(sg, sunimg, dx1, dy1, dx2, dy2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                                     sx1, sy1, sx2, sy2, bgColor, observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    public boolean transformImage(SunGraphics2D sg, Image img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
                                  AffineTransform atfm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
                                  ImageObserver observer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
        if (!(img instanceof ToolkitImage)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
            transformImage(sg, img, 0, 0, atfm, sg.interpolationType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            ToolkitImage sunimg = (ToolkitImage)img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
            if (!imageReady(sunimg, observer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
            ImageRepresentation ir = sunimg.getImageRep();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            return ir.drawToBufImage(sg, sunimg, atfm, observer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
    public void transformImage(SunGraphics2D sg, BufferedImage img,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                               BufferedImageOp op, int x, int y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        if (op != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
            if (op instanceof AffineTransformOp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
                AffineTransformOp atop = (AffineTransformOp) op;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
                transformImage(sg, img, x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
                               atop.getTransform(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
                               atop.getInterpolationType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
                img = op.filter(img, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
        copyImage(sg, img, x, y, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
}