< prev index next >

src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java

Print this page


   1 /*
   2  * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 157             int ity = (int) Math.floor(ty + 0.5);
 158             if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
 159                 (closeToInteger(itx, tx) && closeToInteger(ity, ty)))
 160             {
 161                 renderImageCopy(sg, img, null, x+itx, y+ity, 0, 0, imgw, imgh);
 162                 return;
 163             }
 164             checkfinalxform = false;
 165         } else if (sg.transformState <= SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
 166                    ((txtype & (AffineTransform.TYPE_FLIP |
 167                                AffineTransform.TYPE_MASK_ROTATION |
 168                                AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0))
 169         {
 170             // Second optimization - both are some kind of translate or scale
 171 
 172             // Combine the scales and check if interpolation is necessary.
 173 
 174             // Transform source bounds by extraAT,
 175             // then translate the bounds again by x, y
 176             // then transform the bounds again by sg.transform
 177             double coords[] = new double[] {
 178                 0, 0, imgw, imgh,
 179             };
 180             extraAT.transform(coords, 0, coords, 0, 2);
 181             coords[0] += x;
 182             coords[1] += y;
 183             coords[2] += x;
 184             coords[3] += y;
 185             sg.transform.transform(coords, 0, coords, 0, 2);
 186 
 187             if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh,
 188                                null, interpType, coords))
 189             {
 190                 return;
 191             }
 192             checkfinalxform = false;
 193         } else {
 194             checkfinalxform = true;
 195         }
 196 
 197         // Begin Transform


 224      *
 225      * Note: The transform supplied here has an origin that is
 226      * already adjusted to point to the device location where
 227      * the (sx1, sy1) location of the source image should be placed.
 228      */
 229     protected void transformImage(SunGraphics2D sg, Image img,
 230                                   AffineTransform tx, int interpType,
 231                                   int sx1, int sy1, int sx2, int sy2,
 232                                   Color bgColor)
 233     {
 234         // Transform 3 source corners by tx and analyze them
 235         // for simplified operations (Copy or Scale).  Using
 236         // 3 points lets us analyze any kind of transform,
 237         // even transforms that involve very tiny amounts of
 238         // rotation or skew to see if they degenerate to a
 239         // simple scale or copy operation within the allowable
 240         // error bounds.
 241         // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
 242         // because the transform is already translated such that
 243         // the origin is where sx1, sy1 should go.
 244         double coords[] = new double[6];
 245         /* index:  0  1    2  3    4  5  */
 246         /* coord: (0, 0), (w, h), (0, h) */
 247         coords[2] = sx2 - sx1;
 248         coords[3] = coords[5] = sy2 - sy1;
 249         tx.transform(coords, 0, coords, 0, 3);
 250         // First test if the X coords of the transformed UL
 251         // and LL points match and that the Y coords of the
 252         // transformed LR and LL points also match.
 253         // If they do then it is a "rectilinear" transform and
 254         // tryCopyOrScale will make sure it is upright and
 255         // integer-based.
 256         if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR &&
 257             Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR &&
 258             tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2,
 259                            bgColor, interpType, coords))
 260         {
 261             return;
 262         }
 263 
 264         renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor);
 265     }
 266 
 267     /*
 268      * Check the bounding coordinates of the transformed source
 269      * image to see if they fall on integer coordinates such
 270      * that they will cause no interpolation anomalies if we
 271      * use our simplified Blit or ScaledBlit operations instead
 272      * of a full transform operation.
 273      */
 274     protected boolean tryCopyOrScale(SunGraphics2D sg,
 275                                      Image img,
 276                                      int sx1, int sy1,
 277                                      int sx2, int sy2,
 278                                      Color bgColor, int interpType,
 279                                      double coords[])
 280     {
 281         double dx1 = coords[0];
 282         double dy1 = coords[1];
 283         double dx2 = coords[2];
 284         double dy2 = coords[3];
 285         double dw = dx2 - dx1;
 286         double dh = dy2 - dy1;
 287 
 288         /* If any of the destination coordinates exceed the integer range,
 289          * then the calculations performed in calls made here cannot be
 290          * guaranteed to be correct, or to converge (terminate).
 291          * So return out of here, deferring to code that can handle this.
 292          */
 293         if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
 294             dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
 295             dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
 296             dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
 297         {
 298             return false;
 299         }


   1 /*
   2  * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 157             int ity = (int) Math.floor(ty + 0.5);
 158             if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
 159                 (closeToInteger(itx, tx) && closeToInteger(ity, ty)))
 160             {
 161                 renderImageCopy(sg, img, null, x+itx, y+ity, 0, 0, imgw, imgh);
 162                 return;
 163             }
 164             checkfinalxform = false;
 165         } else if (sg.transformState <= SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
 166                    ((txtype & (AffineTransform.TYPE_FLIP |
 167                                AffineTransform.TYPE_MASK_ROTATION |
 168                                AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0))
 169         {
 170             // Second optimization - both are some kind of translate or scale
 171 
 172             // Combine the scales and check if interpolation is necessary.
 173 
 174             // Transform source bounds by extraAT,
 175             // then translate the bounds again by x, y
 176             // then transform the bounds again by sg.transform
 177             double[] coords = new double[] {
 178                 0, 0, imgw, imgh,
 179             };
 180             extraAT.transform(coords, 0, coords, 0, 2);
 181             coords[0] += x;
 182             coords[1] += y;
 183             coords[2] += x;
 184             coords[3] += y;
 185             sg.transform.transform(coords, 0, coords, 0, 2);
 186 
 187             if (tryCopyOrScale(sg, img, 0, 0, imgw, imgh,
 188                                null, interpType, coords))
 189             {
 190                 return;
 191             }
 192             checkfinalxform = false;
 193         } else {
 194             checkfinalxform = true;
 195         }
 196 
 197         // Begin Transform


 224      *
 225      * Note: The transform supplied here has an origin that is
 226      * already adjusted to point to the device location where
 227      * the (sx1, sy1) location of the source image should be placed.
 228      */
 229     protected void transformImage(SunGraphics2D sg, Image img,
 230                                   AffineTransform tx, int interpType,
 231                                   int sx1, int sy1, int sx2, int sy2,
 232                                   Color bgColor)
 233     {
 234         // Transform 3 source corners by tx and analyze them
 235         // for simplified operations (Copy or Scale).  Using
 236         // 3 points lets us analyze any kind of transform,
 237         // even transforms that involve very tiny amounts of
 238         // rotation or skew to see if they degenerate to a
 239         // simple scale or copy operation within the allowable
 240         // error bounds.
 241         // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2)
 242         // because the transform is already translated such that
 243         // the origin is where sx1, sy1 should go.
 244         double[] coords = new double[6];
 245         /* index:  0  1    2  3    4  5  */
 246         /* coord: (0, 0), (w, h), (0, h) */
 247         coords[2] = sx2 - sx1;
 248         coords[3] = coords[5] = sy2 - sy1;
 249         tx.transform(coords, 0, coords, 0, 3);
 250         // First test if the X coords of the transformed UL
 251         // and LL points match and that the Y coords of the
 252         // transformed LR and LL points also match.
 253         // If they do then it is a "rectilinear" transform and
 254         // tryCopyOrScale will make sure it is upright and
 255         // integer-based.
 256         if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR &&
 257             Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR &&
 258             tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2,
 259                            bgColor, interpType, coords))
 260         {
 261             return;
 262         }
 263 
 264         renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor);
 265     }
 266 
 267     /*
 268      * Check the bounding coordinates of the transformed source
 269      * image to see if they fall on integer coordinates such
 270      * that they will cause no interpolation anomalies if we
 271      * use our simplified Blit or ScaledBlit operations instead
 272      * of a full transform operation.
 273      */
 274     protected boolean tryCopyOrScale(SunGraphics2D sg,
 275                                      Image img,
 276                                      int sx1, int sy1,
 277                                      int sx2, int sy2,
 278                                      Color bgColor, int interpType,
 279                                      double[] coords)
 280     {
 281         double dx1 = coords[0];
 282         double dy1 = coords[1];
 283         double dx2 = coords[2];
 284         double dy2 = coords[3];
 285         double dw = dx2 - dx1;
 286         double dh = dy2 - dy1;
 287 
 288         /* If any of the destination coordinates exceed the integer range,
 289          * then the calculations performed in calls made here cannot be
 290          * guaranteed to be correct, or to converge (terminate).
 291          * So return out of here, deferring to code that can handle this.
 292          */
 293         if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
 294             dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
 295             dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
 296             dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
 297         {
 298             return false;
 299         }


< prev index next >