Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]
    1   /*
    2    * Copyright (c) 1997, 2007, 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
   23    * questions.
   24    */
   25   
   26   package java.awt;
   27   
   28   import java.awt.image.BufferedImage;
   29   import java.awt.image.Raster;
   30   import java.awt.image.WritableRaster;
   31   import java.awt.image.ColorModel;
   32   import java.awt.image.DirectColorModel;
   33   import java.awt.image.IndexColorModel;
   34   import java.awt.geom.AffineTransform;
   35   import java.awt.geom.NoninvertibleTransformException;
   36   import java.lang.ref.WeakReference;
   37   import sun.awt.image.SunWritableRaster;
   38   import sun.awt.image.IntegerInterleavedRaster;
   39   import sun.awt.image.ByteInterleavedRaster;
   40   
   41   abstract class TexturePaintContext implements PaintContext {
   42       public static ColorModel xrgbmodel =
   43           new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
   44       public static ColorModel argbmodel = ColorModel.getRGBdefault();
   45   
   46       ColorModel colorModel;
   47       int bWidth;
   48       int bHeight;
   49       int maxWidth;
   50   
   51       WritableRaster outRas;
   52   
   53       double xOrg;
   54       double yOrg;
   55       double incXAcross;
   56       double incYAcross;
   57       double incXDown;
   58       double incYDown;
   59   
   60       int colincx;
   61       int colincy;
   62       int colincxerr;
   63       int colincyerr;
   64       int rowincx;
   65       int rowincy;
   66       int rowincxerr;
   67       int rowincyerr;
   68   
   69       public static PaintContext getContext(BufferedImage bufImg,
   70                                             AffineTransform xform,
   71                                             RenderingHints hints,
   72                                             Rectangle devBounds) {
   73           WritableRaster raster = bufImg.getRaster();
   74           ColorModel cm = bufImg.getColorModel();
   75           int maxw = devBounds.width;
   76           Object val = hints.get(hints.KEY_INTERPOLATION);
   77           boolean filter =
   78               (val == null
   79                ? (hints.get(hints.KEY_RENDERING) == hints.VALUE_RENDER_QUALITY)
   80                : (val != hints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR));
   81           if (raster instanceof IntegerInterleavedRaster &&
   82               (!filter || isFilterableDCM(cm)))
   83           {
   84               IntegerInterleavedRaster iir = (IntegerInterleavedRaster) raster;
   85               if (iir.getNumDataElements() == 1 && iir.getPixelStride() == 1) {
   86                   return new Int(iir, cm, xform, maxw, filter);
   87               }
   88           } else if (raster instanceof ByteInterleavedRaster) {
   89               ByteInterleavedRaster bir = (ByteInterleavedRaster) raster;
   90               if (bir.getNumDataElements() == 1 && bir.getPixelStride() == 1) {
   91                   if (filter) {
   92                       if (isFilterableICM(cm)) {
   93                           return new ByteFilter(bir, cm, xform, maxw);
   94                       }
   95                   } else {
   96                       return new Byte(bir, cm, xform, maxw);
   97                   }
   98               }
   99           }
  100           return new Any(raster, cm, xform, maxw, filter);
  101       }
  102   
  103       public static boolean isFilterableICM(ColorModel cm) {
  104           if (cm instanceof IndexColorModel) {
  105               IndexColorModel icm = (IndexColorModel) cm;
  106               if (icm.getMapSize() <= 256) {
  107                   return true;
  108               }
  109           }
  110           return false;
  111       }
  112   
  113       public static boolean isFilterableDCM(ColorModel cm) {
  114           if (cm instanceof DirectColorModel) {
  115               DirectColorModel dcm = (DirectColorModel) cm;
  116               return (isMaskOK(dcm.getAlphaMask(), true) &&
  117                       isMaskOK(dcm.getRedMask(), false) &&
  118                       isMaskOK(dcm.getGreenMask(), false) &&
  119                       isMaskOK(dcm.getBlueMask(), false));
  120           }
  121           return false;
  122       }
  123   
  124       public static boolean isMaskOK(int mask, boolean canbezero) {
  125           if (canbezero && mask == 0) {
  126               return true;
  127           }
  128           return (mask == 0xff ||
  129                   mask == 0xff00 ||
  130                   mask == 0xff0000 ||
  131                   mask == 0xff000000);
  132       }
  133   
  134       public static ColorModel getInternedColorModel(ColorModel cm) {
  135           if (xrgbmodel == cm || xrgbmodel.equals(cm)) {
  136               return xrgbmodel;
  137           }
  138           if (argbmodel == cm || argbmodel.equals(cm)) {
  139               return argbmodel;
  140           }
  141           return cm;
  142       }
  143   
  144       TexturePaintContext(ColorModel cm, AffineTransform xform,
  145                           int bWidth, int bHeight, int maxw) {
  146           this.colorModel = getInternedColorModel(cm);
  147           this.bWidth = bWidth;
  148           this.bHeight = bHeight;
  149           this.maxWidth = maxw;
  150   
  151           try {
  152               xform = xform.createInverse();
  153           } catch (NoninvertibleTransformException e) {
  154               xform.setToScale(0, 0);
  155           }
  156           this.incXAcross = mod(xform.getScaleX(), bWidth);
  157           this.incYAcross = mod(xform.getShearY(), bHeight);
  158           this.incXDown = mod(xform.getShearX(), bWidth);
  159           this.incYDown = mod(xform.getScaleY(), bHeight);
  160           this.xOrg = xform.getTranslateX();
  161           this.yOrg = xform.getTranslateY();
  162           this.colincx = (int) incXAcross;
  163           this.colincy = (int) incYAcross;
  164           this.colincxerr = fractAsInt(incXAcross);
  165           this.colincyerr = fractAsInt(incYAcross);
  166           this.rowincx = (int) incXDown;
  167           this.rowincy = (int) incYDown;
  168           this.rowincxerr = fractAsInt(incXDown);
  169           this.rowincyerr = fractAsInt(incYDown);
  170   
  171       }
  172   
  173       static int fractAsInt(double d) {
  174           return (int) ((d % 1.0) * Integer.MAX_VALUE);
  175       }
  176   
  177       static double mod(double num, double den) {
  178           num = num % den;
  179           if (num < 0) {
  180               num += den;
  181               if (num >= den) {
  182                   // For very small negative numerators, the answer might
  183                   // be such a tiny bit less than den that the difference
  184                   // is smaller than the mantissa of a double allows and
  185                   // the result would then be rounded to den.  If that is
  186                   // the case then we map that number to 0 as the nearest
  187                   // modulus representation.
  188                   num = 0;
  189               }
  190           }
  191           return num;
  192       }
  193   
  194       /**
  195        * Release the resources allocated for the operation.
  196        */
  197       public void dispose() {
  198           dropRaster(colorModel, outRas);
  199       }
  200   
  201       /**
  202        * Return the ColorModel of the output.
  203        */
  204       public ColorModel getColorModel() {
  205           return colorModel;
  206       }
  207   
  208       /**
  209        * Return a Raster containing the colors generated for the graphics
  210        * operation.
  211        * @param x,y,w,h The area in device space for which colors are
  212        * generated.
  213        */
  214       public Raster getRaster(int x, int y, int w, int h) {
  215           if (outRas == null ||
  216               outRas.getWidth() < w ||
  217               outRas.getHeight() < h)
  218           {
  219               // If h==1, we will probably get lots of "scanline" rects
  220               outRas = makeRaster((h == 1 ? Math.max(w, maxWidth) : w), h);
  221           }
  222           double X = mod(xOrg + x * incXAcross + y * incXDown, bWidth);
  223           double Y = mod(yOrg + x * incYAcross + y * incYDown, bHeight);
  224   
  225           setRaster((int) X, (int) Y, fractAsInt(X), fractAsInt(Y),
  226                     w, h, bWidth, bHeight,
  227                     colincx, colincxerr,
  228                     colincy, colincyerr,
  229                     rowincx, rowincxerr,
  230                     rowincy, rowincyerr);
  231   
  232           SunWritableRaster.markDirty(outRas);
  233   
  234           return outRas;
  235       }
  236   
  237       private static WeakReference xrgbRasRef;
  238       private static WeakReference argbRasRef;
  239   
  240       synchronized static WritableRaster makeRaster(ColorModel cm,
  241                                                     Raster srcRas,
  242                                                     int w, int h)
  243       {
  244           if (xrgbmodel == cm) {
  245               if (xrgbRasRef != null) {
  246                   WritableRaster wr = (WritableRaster) xrgbRasRef.get();
  247                   if (wr != null && wr.getWidth() >= w && wr.getHeight() >= h) {
  248                       xrgbRasRef = null;
  249                       return wr;
  250                   }
  251               }
  252               // If we are going to cache this Raster, make it non-tiny
  253               if (w <= 32 && h <= 32) {
  254                   w = h = 32;
  255               }
  256           } else if (argbmodel == cm) {
  257               if (argbRasRef != null) {
  258                   WritableRaster wr = (WritableRaster) argbRasRef.get();
  259                   if (wr != null && wr.getWidth() >= w && wr.getHeight() >= h) {
  260                       argbRasRef = null;
  261                       return wr;
  262                   }
  263               }
  264               // If we are going to cache this Raster, make it non-tiny
  265               if (w <= 32 && h <= 32) {
  266                   w = h = 32;
  267               }
  268           }
  269           if (srcRas != null) {
  270               return srcRas.createCompatibleWritableRaster(w, h);
  271           } else {
  272               return cm.createCompatibleWritableRaster(w, h);
  273           }
  274       }
  275   
  276       synchronized static void dropRaster(ColorModel cm, Raster outRas) {
  277           if (outRas == null) {
  278               return;
  279           }
  280           if (xrgbmodel == cm) {
  281               xrgbRasRef = new WeakReference(outRas);
  282           } else if (argbmodel == cm) {
  283               argbRasRef = new WeakReference(outRas);
  284           }
  285       }
  286   
  287       private static WeakReference byteRasRef;
  288   
  289       synchronized static WritableRaster makeByteRaster(Raster srcRas,
  290                                                         int w, int h)
  291       {
  292           if (byteRasRef != null) {
  293               WritableRaster wr = (WritableRaster) byteRasRef.get();
  294               if (wr != null && wr.getWidth() >= w && wr.getHeight() >= h) {
  295                   byteRasRef = null;
  296                   return wr;
  297               }
  298           }
  299           // If we are going to cache this Raster, make it non-tiny
  300           if (w <= 32 && h <= 32) {
  301               w = h = 32;
  302           }
  303           return srcRas.createCompatibleWritableRaster(w, h);
  304       }
  305   
  306       synchronized static void dropByteRaster(Raster outRas) {
  307           if (outRas == null) {
  308               return;
  309           }
  310           byteRasRef = new WeakReference(outRas);
  311       }
  312   
  313       public abstract WritableRaster makeRaster(int w, int h);
  314       public abstract void setRaster(int x, int y, int xerr, int yerr,
  315                                      int w, int h, int bWidth, int bHeight,
  316                                      int colincx, int colincxerr,
  317                                      int colincy, int colincyerr,
  318                                      int rowincx, int rowincxerr,
  319                                      int rowincy, int rowincyerr);
  320   
  321       /*
  322        * Blends the four ARGB values in the rgbs array using the factors
  323        * described by xmul and ymul in the following ratio:
  324        *
  325        *     rgbs[0] * (1-xmul) * (1-ymul) +
  326        *     rgbs[1] * (  xmul) * (1-ymul) +
  327        *     rgbs[2] * (1-xmul) * (  ymul) +
  328        *     rgbs[3] * (  xmul) * (  ymul)
  329        *
  330        * xmul and ymul are integer values in the half-open range [0, 2^31)
  331        * where 0 == 0.0 and 2^31 == 1.0.
  332        *
  333        * Note that since the range is half-open, the values are always
  334        * logically less than 1.0.  This makes sense because while choosing
  335        * pixels to blend, when the error values reach 1.0 we move to the
  336        * next pixel and reset them to 0.0.
  337        */
  338       public static int blend(int rgbs[], int xmul, int ymul) {
  339           // xmul/ymul are 31 bits wide, (0 => 2^31-1)
  340           // shift them to 12 bits wide, (0 => 2^12-1)
  341           xmul = (xmul >>> 19);
  342           ymul = (ymul >>> 19);
  343           int accumA, accumR, accumG, accumB;
  344           accumA = accumR = accumG = accumB = 0;
  345           for (int i = 0; i < 4; i++) {
  346               int rgb = rgbs[i];
  347               // The complement of the [xy]mul values (1-[xy]mul) can result
  348               // in new values in the range (1 => 2^12).  Thus for any given
  349               // loop iteration, the values could be anywhere in (0 => 2^12).
  350               xmul = (1<<12) - xmul;
  351               if ((i & 1) == 0) {
  352                   ymul = (1<<12) - ymul;
  353               }
  354               // xmul and ymul are each 12 bits (0 => 2^12)
  355               // factor is thus 24 bits (0 => 2^24)
  356               int factor = xmul * ymul;
  357               if (factor != 0) {
  358                   // accum variables will accumulate 32 bits
  359                   // bytes extracted from rgb fit in 8 bits (0 => 255)
  360                   // byte * factor thus fits in 32 bits (0 => 255 * 2^24)
  361                   accumA += (((rgb >>> 24)       ) * factor);
  362                   accumR += (((rgb >>> 16) & 0xff) * factor);
  363                   accumG += (((rgb >>>  8) & 0xff) * factor);
  364                   accumB += (((rgb       ) & 0xff) * factor);
  365               }
  366           }
  367           return ((((accumA + (1<<23)) >>> 24) << 24) |
  368                   (((accumR + (1<<23)) >>> 24) << 16) |
  369                   (((accumG + (1<<23)) >>> 24) <<  8) |
  370                   (((accumB + (1<<23)) >>> 24)      ));
  371       }
  372   
  373       static class Int extends TexturePaintContext {
  374           IntegerInterleavedRaster srcRas;
  375           int inData[];
  376           int inOff;
  377           int inSpan;
  378           int outData[];
  379           int outOff;
  380           int outSpan;
  381           boolean filter;
  382   
  383           public Int(IntegerInterleavedRaster srcRas, ColorModel cm,
  384                      AffineTransform xform, int maxw, boolean filter)
  385           {
  386               super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  387               this.srcRas = srcRas;
  388               this.inData = srcRas.getDataStorage();
  389               this.inSpan = srcRas.getScanlineStride();
  390               this.inOff = srcRas.getDataOffset(0);
  391               this.filter = filter;
  392           }
  393   
  394           public WritableRaster makeRaster(int w, int h) {
  395               WritableRaster ras = makeRaster(colorModel, srcRas, w, h);
  396               IntegerInterleavedRaster iiRas = (IntegerInterleavedRaster) ras;
  397               outData = iiRas.getDataStorage();
  398               outSpan = iiRas.getScanlineStride();
  399               outOff = iiRas.getDataOffset(0);
  400               return ras;
  401           }
  402   
  403           public void setRaster(int x, int y, int xerr, int yerr,
  404                                 int w, int h, int bWidth, int bHeight,
  405                                 int colincx, int colincxerr,
  406                                 int colincy, int colincyerr,
  407                                 int rowincx, int rowincxerr,
  408                                 int rowincy, int rowincyerr) {
  409               int[] inData = this.inData;
  410               int[] outData = this.outData;
  411               int out = outOff;
  412               int inSpan = this.inSpan;
  413               int inOff = this.inOff;
  414               int outSpan = this.outSpan;
  415               boolean filter = this.filter;
  416               boolean normalx = (colincx == 1 && colincxerr == 0 &&
  417                                  colincy == 0 && colincyerr == 0) && !filter;
  418               int rowx = x;
  419               int rowy = y;
  420               int rowxerr = xerr;
  421               int rowyerr = yerr;
  422               if (normalx) {
  423                   outSpan -= w;
  424               }
  425               int rgbs[] = filter ? new int[4] : null;
  426               for (int j = 0; j < h; j++) {
  427                   if (normalx) {
  428                       int in = inOff + rowy * inSpan + bWidth;
  429                       x = bWidth - rowx;
  430                       out += w;
  431                       if (bWidth >= 32) {
  432                           int i = w;
  433                           while (i > 0) {
  434                               int copyw = (i < x) ? i : x;
  435                               System.arraycopy(inData, in - x,
  436                                                outData, out - i,
  437                                                copyw);
  438                               i -= copyw;
  439                               if ((x -= copyw) == 0) {
  440                                   x = bWidth;
  441                               }
  442                           }
  443                       } else {
  444                           for (int i = w; i > 0; i--) {
  445                               outData[out - i] = inData[in - x];
  446                               if (--x == 0) {
  447                                   x = bWidth;
  448                               }
  449                           }
  450                       }
  451                   } else {
  452                       x = rowx;
  453                       y = rowy;
  454                       xerr = rowxerr;
  455                       yerr = rowyerr;
  456                       for (int i = 0; i < w; i++) {
  457                           if (filter) {
  458                               int nextx, nexty;
  459                               if ((nextx = x + 1) >= bWidth) {
  460                                   nextx = 0;
  461                               }
  462                               if ((nexty = y + 1) >= bHeight) {
  463                                   nexty = 0;
  464                               }
  465                               rgbs[0] = inData[inOff + y * inSpan + x];
  466                               rgbs[1] = inData[inOff + y * inSpan + nextx];
  467                               rgbs[2] = inData[inOff + nexty * inSpan + x];
  468                               rgbs[3] = inData[inOff + nexty * inSpan + nextx];
  469                               outData[out + i] =
  470                                   TexturePaintContext.blend(rgbs, xerr, yerr);
  471                           } else {
  472                               outData[out + i] = inData[inOff + y * inSpan + x];
  473                           }
  474                           if ((xerr += colincxerr) < 0) {
  475                               xerr &= Integer.MAX_VALUE;
  476                               x++;
  477                           }
  478                           if ((x += colincx) >= bWidth) {
  479                               x -= bWidth;
  480                           }
  481                           if ((yerr += colincyerr) < 0) {
  482                               yerr &= Integer.MAX_VALUE;
  483                               y++;
  484                           }
  485                           if ((y += colincy) >= bHeight) {
  486                               y -= bHeight;
  487                           }
  488                       }
  489                   }
  490                   if ((rowxerr += rowincxerr) < 0) {
  491                       rowxerr &= Integer.MAX_VALUE;
  492                       rowx++;
  493                   }
  494                   if ((rowx += rowincx) >= bWidth) {
  495                       rowx -= bWidth;
  496                   }
  497                   if ((rowyerr += rowincyerr) < 0) {
  498                       rowyerr &= Integer.MAX_VALUE;
  499                       rowy++;
  500                   }
  501                   if ((rowy += rowincy) >= bHeight) {
  502                       rowy -= bHeight;
  503                   }
  504                   out += outSpan;
  505               }
  506           }
  507       }
  508   
  509       static class Byte extends TexturePaintContext {
  510           ByteInterleavedRaster srcRas;
  511           byte inData[];
  512           int inOff;
  513           int inSpan;
  514           byte outData[];
  515           int outOff;
  516           int outSpan;
  517   
  518           public Byte(ByteInterleavedRaster srcRas, ColorModel cm,
  519                       AffineTransform xform, int maxw)
  520           {
  521               super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  522               this.srcRas = srcRas;
  523               this.inData = srcRas.getDataStorage();
  524               this.inSpan = srcRas.getScanlineStride();
  525               this.inOff = srcRas.getDataOffset(0);
  526           }
  527   
  528           public WritableRaster makeRaster(int w, int h) {
  529               WritableRaster ras = makeByteRaster(srcRas, w, h);
  530               ByteInterleavedRaster biRas = (ByteInterleavedRaster) ras;
  531               outData = biRas.getDataStorage();
  532               outSpan = biRas.getScanlineStride();
  533               outOff = biRas.getDataOffset(0);
  534               return ras;
  535           }
  536   
  537           public void dispose() {
  538               dropByteRaster(outRas);
  539           }
  540   
  541           public void setRaster(int x, int y, int xerr, int yerr,
  542                                 int w, int h, int bWidth, int bHeight,
  543                                 int colincx, int colincxerr,
  544                                 int colincy, int colincyerr,
  545                                 int rowincx, int rowincxerr,
  546                                 int rowincy, int rowincyerr) {
  547               byte[] inData = this.inData;
  548               byte[] outData = this.outData;
  549               int out = outOff;
  550               int inSpan = this.inSpan;
  551               int inOff = this.inOff;
  552               int outSpan = this.outSpan;
  553               boolean normalx = (colincx == 1 && colincxerr == 0 &&
  554                                  colincy == 0 && colincyerr == 0);
  555               int rowx = x;
  556               int rowy = y;
  557               int rowxerr = xerr;
  558               int rowyerr = yerr;
  559               if (normalx) {
  560                   outSpan -= w;
  561               }
  562               for (int j = 0; j < h; j++) {
  563                   if (normalx) {
  564                       int in = inOff + rowy * inSpan + bWidth;
  565                       x = bWidth - rowx;
  566                       out += w;
  567                       if (bWidth >= 32) {
  568                           int i = w;
  569                           while (i > 0) {
  570                               int copyw = (i < x) ? i : x;
  571                               System.arraycopy(inData, in - x,
  572                                                outData, out - i,
  573                                                copyw);
  574                               i -= copyw;
  575                               if ((x -= copyw) == 0) {
  576                                   x = bWidth;
  577                               }
  578                           }
  579                       } else {
  580                           for (int i = w; i > 0; i--) {
  581                               outData[out - i] = inData[in - x];
  582                               if (--x == 0) {
  583                                   x = bWidth;
  584                               }
  585                           }
  586                       }
  587                   } else {
  588                       x = rowx;
  589                       y = rowy;
  590                       xerr = rowxerr;
  591                       yerr = rowyerr;
  592                       for (int i = 0; i < w; i++) {
  593                           outData[out + i] = inData[inOff + y * inSpan + x];
  594                           if ((xerr += colincxerr) < 0) {
  595                               xerr &= Integer.MAX_VALUE;
  596                               x++;
  597                           }
  598                           if ((x += colincx) >= bWidth) {
  599                               x -= bWidth;
  600                           }
  601                           if ((yerr += colincyerr) < 0) {
  602                               yerr &= Integer.MAX_VALUE;
  603                               y++;
  604                           }
  605                           if ((y += colincy) >= bHeight) {
  606                               y -= bHeight;
  607                           }
  608                       }
  609                   }
  610                   if ((rowxerr += rowincxerr) < 0) {
  611                       rowxerr &= Integer.MAX_VALUE;
  612                       rowx++;
  613                   }
  614                   if ((rowx += rowincx) >= bWidth) {
  615                       rowx -= bWidth;
  616                   }
  617                   if ((rowyerr += rowincyerr) < 0) {
  618                       rowyerr &= Integer.MAX_VALUE;
  619                       rowy++;
  620                   }
  621                   if ((rowy += rowincy) >= bHeight) {
  622                       rowy -= bHeight;
  623                   }
  624                   out += outSpan;
  625               }
  626           }
  627       }
  628   
  629       static class ByteFilter extends TexturePaintContext {
  630           ByteInterleavedRaster srcRas;
  631           int inPalette[];
  632           byte inData[];
  633           int inOff;
  634           int inSpan;
  635           int outData[];
  636           int outOff;
  637           int outSpan;
  638   
  639           public ByteFilter(ByteInterleavedRaster srcRas, ColorModel cm,
  640                             AffineTransform xform, int maxw)
  641           {
  642               super((cm.getTransparency() == Transparency.OPAQUE
  643                      ? xrgbmodel : argbmodel),
  644                     xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  645               this.inPalette = new int[256];
  646               ((IndexColorModel) cm).getRGBs(this.inPalette);
  647               this.srcRas = srcRas;
  648               this.inData = srcRas.getDataStorage();
  649               this.inSpan = srcRas.getScanlineStride();
  650               this.inOff = srcRas.getDataOffset(0);
  651           }
  652   
  653           public WritableRaster makeRaster(int w, int h) {
  654               // Note that we do not pass srcRas to makeRaster since it
  655               // is a Byte Raster and this colorModel needs an Int Raster
  656               WritableRaster ras = makeRaster(colorModel, null, w, h);
  657               IntegerInterleavedRaster iiRas = (IntegerInterleavedRaster) ras;
  658               outData = iiRas.getDataStorage();
  659               outSpan = iiRas.getScanlineStride();
  660               outOff = iiRas.getDataOffset(0);
  661               return ras;
  662           }
  663   
  664           public void setRaster(int x, int y, int xerr, int yerr,
  665                                 int w, int h, int bWidth, int bHeight,
  666                                 int colincx, int colincxerr,
  667                                 int colincy, int colincyerr,
  668                                 int rowincx, int rowincxerr,
  669                                 int rowincy, int rowincyerr) {
  670               byte[] inData = this.inData;
  671               int[] outData = this.outData;
  672               int out = outOff;
  673               int inSpan = this.inSpan;
  674               int inOff = this.inOff;
  675               int outSpan = this.outSpan;
  676               int rowx = x;
  677               int rowy = y;
  678               int rowxerr = xerr;
  679               int rowyerr = yerr;
  680               int rgbs[] = new int[4];
  681               for (int j = 0; j < h; j++) {
  682                   x = rowx;
  683                   y = rowy;
  684                   xerr = rowxerr;
  685                   yerr = rowyerr;
  686                   for (int i = 0; i < w; i++) {
  687                       int nextx, nexty;
  688                       if ((nextx = x + 1) >= bWidth) {
  689                           nextx = 0;
  690                       }
  691                       if ((nexty = y + 1) >= bHeight) {
  692                           nexty = 0;
  693                       }
  694                       rgbs[0] = inPalette[0xff & inData[inOff + x +
  695                                                         inSpan * y]];
  696                       rgbs[1] = inPalette[0xff & inData[inOff + nextx +
  697                                                         inSpan * y]];
  698                       rgbs[2] = inPalette[0xff & inData[inOff + x +
  699                                                         inSpan * nexty]];
  700                       rgbs[3] = inPalette[0xff & inData[inOff + nextx +
  701                                                         inSpan * nexty]];
  702                       outData[out + i] =
  703                           TexturePaintContext.blend(rgbs, xerr, yerr);
  704                       if ((xerr += colincxerr) < 0) {
  705                           xerr &= Integer.MAX_VALUE;
  706                           x++;
  707                       }
  708                       if ((x += colincx) >= bWidth) {
  709                           x -= bWidth;
  710                       }
  711                       if ((yerr += colincyerr) < 0) {
  712                           yerr &= Integer.MAX_VALUE;
  713                           y++;
  714                       }
  715                       if ((y += colincy) >= bHeight) {
  716                           y -= bHeight;
  717                       }
  718                   }
  719                   if ((rowxerr += rowincxerr) < 0) {
  720                       rowxerr &= Integer.MAX_VALUE;
  721                       rowx++;
  722                   }
  723                   if ((rowx += rowincx) >= bWidth) {
  724                       rowx -= bWidth;
  725                   }
  726                   if ((rowyerr += rowincyerr) < 0) {
  727                       rowyerr &= Integer.MAX_VALUE;
  728                       rowy++;
  729                   }
  730                   if ((rowy += rowincy) >= bHeight) {
  731                       rowy -= bHeight;
  732                   }
  733                   out += outSpan;
  734               }
  735           }
  736       }
  737   
  738       static class Any extends TexturePaintContext {
  739           WritableRaster srcRas;
  740           boolean filter;
  741   
  742           public Any(WritableRaster srcRas, ColorModel cm,
  743                      AffineTransform xform, int maxw, boolean filter)
  744           {
  745               super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  746               this.srcRas = srcRas;
  747               this.filter = filter;
  748           }
  749   
  750           public WritableRaster makeRaster(int w, int h) {
  751               return makeRaster(colorModel, srcRas, w, h);
  752           }
  753   
  754           public void setRaster(int x, int y, int xerr, int yerr,
  755                                 int w, int h, int bWidth, int bHeight,
  756                                 int colincx, int colincxerr,
  757                                 int colincy, int colincyerr,
  758                                 int rowincx, int rowincxerr,
  759                                 int rowincy, int rowincyerr) {
  760               Object data = null;
  761               int rowx = x;
  762               int rowy = y;
  763               int rowxerr = xerr;
  764               int rowyerr = yerr;
  765               WritableRaster srcRas = this.srcRas;
  766               WritableRaster outRas = this.outRas;
  767               int rgbs[] = filter ? new int[4] : null;
  768               for (int j = 0; j < h; j++) {
  769                   x = rowx;
  770                   y = rowy;
  771                   xerr = rowxerr;
  772                   yerr = rowyerr;
  773                   for (int i = 0; i < w; i++) {
  774                       data = srcRas.getDataElements(x, y, data);
  775                       if (filter) {
  776                           int nextx, nexty;
  777                           if ((nextx = x + 1) >= bWidth) {
  778                               nextx = 0;
  779                           }
  780                           if ((nexty = y + 1) >= bHeight) {
  781                               nexty = 0;
  782                           }
  783                           rgbs[0] = colorModel.getRGB(data);
  784                           data = srcRas.getDataElements(nextx, y, data);
  785                           rgbs[1] = colorModel.getRGB(data);
  786                           data = srcRas.getDataElements(x, nexty, data);
  787                           rgbs[2] = colorModel.getRGB(data);
  788                           data = srcRas.getDataElements(nextx, nexty, data);
  789                           rgbs[3] = colorModel.getRGB(data);
  790                           int rgb =
  791                               TexturePaintContext.blend(rgbs, xerr, yerr);
  792                           data = colorModel.getDataElements(rgb, data);
  793                       }
  794                       outRas.setDataElements(i, j, data);
  795                       if ((xerr += colincxerr) < 0) {
  796                           xerr &= Integer.MAX_VALUE;
  797                           x++;
  798                       }
  799                       if ((x += colincx) >= bWidth) {
  800                           x -= bWidth;
  801                       }
  802                       if ((yerr += colincyerr) < 0) {
  803                           yerr &= Integer.MAX_VALUE;
  804                           y++;
  805                       }
  806                       if ((y += colincy) >= bHeight) {
  807                           y -= bHeight;
  808                       }
  809                   }
  810                   if ((rowxerr += rowincxerr) < 0) {
  811                       rowxerr &= Integer.MAX_VALUE;
  812                       rowx++;
  813                   }
  814                   if ((rowx += rowincx) >= bWidth) {
  815                       rowx -= bWidth;
  816                   }
  817                   if ((rowyerr += rowincyerr) < 0) {
  818                       rowyerr &= Integer.MAX_VALUE;
  819                       rowy++;
  820                   }
  821                   if ((rowy += rowincy) >= bHeight) {
  822                       rowy -= bHeight;
  823                   }
  824               }
  825           }
  826       }
  827   }

Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]