home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / TexturePaintContext.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  12.2 KB  |  469 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)TexturePaintContext.java    1.20 98/08/17
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt;
  16.  
  17. import java.awt.image.BufferedImage;
  18. import java.awt.image.Raster;
  19. import java.awt.image.WritableRaster;
  20. import java.awt.image.ColorModel;
  21. import java.awt.geom.AffineTransform;
  22. import java.awt.geom.NoninvertibleTransformException;
  23. import sun.awt.image.IntegerInterleavedRaster;
  24. import sun.awt.image.ByteInterleavedRaster;
  25.  
  26. abstract class TexturePaintContext implements PaintContext {
  27.     ColorModel colorModel;
  28.     int bWidth;
  29.     int bHeight;
  30.     int maxWidth;
  31.  
  32.     WritableRaster outRas;
  33.  
  34.     double xOrg;
  35.     double yOrg;
  36.     double incXAcross;
  37.     double incYAcross;
  38.     double incXDown;
  39.     double incYDown;
  40.  
  41.     int colincx;
  42.     int colincy;
  43.     int colincxerr;
  44.     int colincyerr;
  45.     int rowincx;
  46.     int rowincy;
  47.     int rowincxerr;
  48.     int rowincyerr;
  49.  
  50.     public static PaintContext getContext(BufferedImage bufImg,
  51.                       AffineTransform xform,
  52.                       RenderingHints hints,
  53.                       Rectangle devBounds) {
  54.         WritableRaster raster = bufImg.getRaster();
  55.     ColorModel cm = bufImg.getColorModel();
  56.     int maxw = devBounds.width;
  57.     if (raster instanceof IntegerInterleavedRaster) {
  58.         IntegerInterleavedRaster iir = (IntegerInterleavedRaster) raster;
  59.         if (iir.getNumDataElements() == 1 && iir.getPixelStride() == 1) {
  60.         return new Int(iir, cm, xform, maxw);
  61.         }
  62.     } else if (raster instanceof ByteInterleavedRaster) {
  63.         ByteInterleavedRaster bir = (ByteInterleavedRaster) raster;
  64.         if (bir.getNumDataElements() == 1 && bir.getPixelStride() == 1) {
  65.         return new Byte(bir, cm, xform, maxw);
  66.         }
  67.     }
  68.     return new Any(raster, cm, xform, maxw);
  69.     }
  70.  
  71.     TexturePaintContext(ColorModel cm, AffineTransform xform,
  72.             int bWidth, int bHeight, int maxw) {
  73.     this.colorModel = cm;
  74.     this.bWidth = bWidth;
  75.     this.bHeight = bHeight;
  76.     this.maxWidth = maxw;
  77.  
  78.     try {
  79.         xform = xform.createInverse();
  80.         } catch (NoninvertibleTransformException e) {
  81.         xform.setToScale(0, 0);
  82.     }
  83.     this.incXAcross = mod(xform.getScaleX(), bWidth);
  84.     this.incYAcross = mod(xform.getShearY(), bHeight);
  85.     this.incXDown = mod(xform.getShearX(), bWidth);
  86.     this.incYDown = mod(xform.getScaleY(), bHeight);
  87.         this.xOrg = xform.getTranslateX();
  88.         this.yOrg = xform.getTranslateY();
  89.     this.colincx = (int) incXAcross;
  90.     this.colincy = (int) incYAcross;
  91.     this.colincxerr = fractAsInt(incXAcross);
  92.     this.colincyerr = fractAsInt(incYAcross);
  93.     this.rowincx = (int) incXDown;
  94.     this.rowincy = (int) incYDown;
  95.     this.rowincxerr = fractAsInt(incXDown);
  96.     this.rowincyerr = fractAsInt(incYDown);
  97.  
  98.     }
  99.  
  100.     static int fractAsInt(double d) {
  101.     return (int) ((d % 1.0) * Integer.MAX_VALUE);
  102.     }
  103.  
  104.     static double mod(double num, double den) {
  105.     num = num % den;
  106.     if (num < 0) {
  107.         num += den;
  108.         if (num >= den) {
  109.         // For very small negative numerators, the answer might
  110.         // be such a tiny bit less than den that the difference
  111.         // is smaller than the mantissa of a double allows and
  112.         // the result would then be rounded to den.  If that is
  113.         // the case then we map that number to 0 as the nearest
  114.         // modulus representation.
  115.         num = 0;
  116.         }
  117.     }
  118.     return num;
  119.     }
  120.     
  121.     /**
  122.      * Release the resources allocated for the operation.
  123.      */
  124.     public void dispose() {
  125.         // Nothing to dispose
  126.     }
  127.  
  128.     /**
  129.      * Return the ColorModel of the output.
  130.      */
  131.     public ColorModel getColorModel() {
  132.         return colorModel;
  133.     }
  134.  
  135.     /**
  136.      * Return a Raster containing the colors generated for the graphics
  137.      * operation.
  138.      * @param x,y,w,h The area in device space for which colors are
  139.      * generated.
  140.      */
  141.     public Raster getRaster(int x, int y, int w, int h) {
  142.     if (outRas == null ||
  143.         outRas.getWidth() < w ||
  144.         outRas.getHeight() < h)
  145.     {
  146.         // If h==1, we will probably get lots of "scanline" rects
  147.         outRas = makeRaster((h == 1 ? Math.max(w, maxWidth) : w), h);
  148.     }
  149.     double X = mod(xOrg + x * incXAcross + y * incXDown, bWidth);
  150.     double Y = mod(yOrg + x * incYAcross + y * incYDown, bHeight);
  151.  
  152.     setRaster((int) X, (int) Y,
  153.           (int) ((X % 1.0) * Integer.MAX_VALUE),
  154.           (int) ((Y % 1.0) * Integer.MAX_VALUE),
  155.           w, h, bWidth, bHeight,
  156.           colincx, colincxerr,
  157.           colincy, colincyerr,
  158.           rowincx, rowincxerr,
  159.           rowincy, rowincyerr);
  160.  
  161.     return outRas;
  162.     }
  163.  
  164.     public abstract WritableRaster makeRaster(int w, int h);
  165.     public abstract void setRaster(int x, int y, int xerr, int yerr,
  166.                    int w, int h, int bWidth, int bHeight,
  167.                    int colincx, int colincxerr,
  168.                    int colincy, int colincyerr,
  169.                    int rowincx, int rowincxerr,
  170.                    int rowincy, int rowincyerr);
  171.  
  172.     static class Int extends TexturePaintContext {
  173.     IntegerInterleavedRaster srcRas;
  174.     int inData[];
  175.     int inOff;
  176.     int inSpan;
  177.     int outData[];
  178.     int outOff;
  179.     int outSpan;
  180.  
  181.     public Int(IntegerInterleavedRaster srcRas,
  182.            ColorModel cm, AffineTransform xform, int maxw) {
  183.         super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  184.         this.srcRas = srcRas;
  185.         this.inData = srcRas.getDataStorage();
  186.         this.inSpan = srcRas.getScanlineStride();
  187.         this.inOff = srcRas.getDataOffset(0);
  188.     }
  189.  
  190.     public WritableRaster makeRaster(int w, int h) {
  191.         WritableRaster ras = srcRas.createCompatibleWritableRaster(w, h);
  192.         IntegerInterleavedRaster iiRas = (IntegerInterleavedRaster) ras;
  193.         outData = iiRas.getDataStorage();
  194.         outSpan = iiRas.getScanlineStride();
  195.         outOff = iiRas.getDataOffset(0);
  196.         return ras;
  197.     }
  198.  
  199.     public void setRaster(int x, int y, int xerr, int yerr,
  200.                   int w, int h, int bWidth, int bHeight,
  201.                   int colincx, int colincxerr,
  202.                   int colincy, int colincyerr,
  203.                   int rowincx, int rowincxerr,
  204.                   int rowincy, int rowincyerr) {
  205.         int[] inData = this.inData;
  206.         int[] outData = this.outData;
  207.         int out = outOff;
  208.         int inSpan = this.inSpan;
  209.         int inOff = this.inOff;
  210.         int outSpan = this.outSpan;
  211.         boolean normalx = (colincx == 1 && colincxerr == 0 &&
  212.                    colincy == 0 && colincyerr == 0);
  213.         int rowx = x;
  214.         int rowy = y;
  215.         int rowxerr = xerr;
  216.         int rowyerr = yerr;
  217.         if (normalx) {
  218.         outSpan -= w;
  219.         }
  220.         for (int j = 0; j < h; j++) {
  221.         if (normalx) {
  222.             int in = inOff + rowy * inSpan + bWidth;
  223.             x = bWidth - rowx;
  224.             out += w;
  225.             if (bWidth >= 32) {
  226.             int i = w;
  227.             while (i > 0) {
  228.                 int copyw = (i < x) ? i : x;
  229.                 System.arraycopy(inData, in - x,
  230.                          outData, out - i,
  231.                          copyw);
  232.                 i -= copyw;
  233.                 if ((x -= copyw) == 0) {
  234.                 x = bWidth;
  235.                 }
  236.             }
  237.             } else {
  238.             for (int i = w; i > 0; i--) {
  239.                 outData[out - i] = inData[in - x];
  240.                 if (--x == 0) {
  241.                 x = bWidth;
  242.                 }
  243.             }
  244.             }
  245.         } else {
  246.             x = rowx;
  247.             y = rowy;
  248.             xerr = rowxerr;
  249.             yerr = rowyerr;
  250.             for (int i = 0; i < w; i++) {
  251.             outData[out + i] = inData[inOff + y * inSpan + x];
  252.             if ((xerr += colincxerr) < 0) {
  253.                 xerr &= Integer.MAX_VALUE;
  254.                 x++;
  255.             }
  256.             if ((x += colincx) >= bWidth) {
  257.                 x -= bWidth;
  258.             }
  259.             if ((yerr += colincyerr) < 0) {
  260.                 yerr &= Integer.MAX_VALUE;
  261.                 y++;
  262.             }
  263.             if ((y += colincy) >= bHeight) {
  264.                 y -= bHeight;
  265.             }
  266.             }
  267.         }
  268.         if ((rowxerr += rowincxerr) < 0) {
  269.             rowxerr &= Integer.MAX_VALUE;
  270.             rowx++;
  271.         }
  272.         if ((rowx += rowincx) >= bWidth) {
  273.             rowx -= bWidth;
  274.         }
  275.         if ((rowyerr += rowincyerr) < 0) {
  276.             rowyerr &= Integer.MAX_VALUE;
  277.             rowy++;
  278.         }
  279.         if ((rowy += rowincy) >= bHeight) {
  280.             rowy -= bHeight;
  281.         }
  282.         out += outSpan;
  283.         }
  284.     }
  285.     }
  286.  
  287.     static class Byte extends TexturePaintContext {
  288.     ByteInterleavedRaster srcRas;
  289.     byte inData[];
  290.     int inOff;
  291.     int inSpan;
  292.     byte outData[];
  293.     int outOff;
  294.     int outSpan;
  295.  
  296.     public Byte(ByteInterleavedRaster srcRas,
  297.             ColorModel cm, AffineTransform xform, int maxw) {
  298.         super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  299.         this.srcRas = srcRas;
  300.         this.inData = srcRas.getDataStorage();
  301.         this.inSpan = srcRas.getScanlineStride();
  302.         this.inOff = srcRas.getDataOffset(0);
  303.     }
  304.  
  305.     public WritableRaster makeRaster(int w, int h) {
  306.         WritableRaster ras = srcRas.createCompatibleWritableRaster(w, h);
  307.         ByteInterleavedRaster biRas = (ByteInterleavedRaster) ras;
  308.         outData = biRas.getDataStorage();
  309.         outSpan = biRas.getScanlineStride();
  310.         outOff = biRas.getDataOffset(0);
  311.         return ras;
  312.     }
  313.  
  314.     public 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.         byte[] inData = this.inData;
  321.         byte[] outData = this.outData;
  322.         int out = outOff;
  323.         int inSpan = this.inSpan;
  324.         int inOff = this.inOff;
  325.         int outSpan = this.outSpan;
  326.         boolean normalx = (colincx == 1 && colincxerr == 0 &&
  327.                    colincy == 0 && colincyerr == 0);
  328.         int rowx = x;
  329.         int rowy = y;
  330.         int rowxerr = xerr;
  331.         int rowyerr = yerr;
  332.         if (normalx) {
  333.         outSpan -= w;
  334.         }
  335.         for (int j = 0; j < h; j++) {
  336.         if (normalx) {
  337.             int in = inOff + rowy * inSpan + bWidth;
  338.             x = bWidth - rowx;
  339.             out += w;
  340.             if (bWidth >= 32) {
  341.             int i = w;
  342.             while (i > 0) {
  343.                 int copyw = (i < x) ? i : x;
  344.                 System.arraycopy(inData, in - x,
  345.                          outData, out - i,
  346.                          copyw);
  347.                 i -= copyw;
  348.                 if ((x -= copyw) == 0) {
  349.                 x = bWidth;
  350.                 }
  351.             }
  352.             } else {
  353.             for (int i = w; i > 0; i--) {
  354.                 outData[out - i] = inData[in - x];
  355.                 if (--x == 0) {
  356.                 x = bWidth;
  357.                 }
  358.             }
  359.             }
  360.         } else {
  361.             x = rowx;
  362.             y = rowy;
  363.             xerr = rowxerr;
  364.             yerr = rowyerr;
  365.             for (int i = 0; i < w; i++) {
  366.             outData[out + i] = inData[inOff + y * inSpan + x];
  367.             if ((xerr += colincxerr) < 0) {
  368.                 xerr &= Integer.MAX_VALUE;
  369.                 x++;
  370.             }
  371.             if ((x += colincx) >= bWidth) {
  372.                 x -= bWidth;
  373.             }
  374.             if ((yerr += colincyerr) < 0) {
  375.                 yerr &= Integer.MAX_VALUE;
  376.                 y++;
  377.             }
  378.             if ((y += colincy) >= bHeight) {
  379.                 y -= bHeight;
  380.             }
  381.             }
  382.         }
  383.         if ((rowxerr += rowincxerr) < 0) {
  384.             rowxerr &= Integer.MAX_VALUE;
  385.             rowx++;
  386.         }
  387.         if ((rowx += rowincx) >= bWidth) {
  388.             rowx -= bWidth;
  389.         }
  390.         if ((rowyerr += rowincyerr) < 0) {
  391.             rowyerr &= Integer.MAX_VALUE;
  392.             rowy++;
  393.         }
  394.         if ((rowy += rowincy) >= bHeight) {
  395.             rowy -= bHeight;
  396.         }
  397.         out += outSpan;
  398.         }
  399.     }
  400.     }
  401.  
  402.     static class Any extends TexturePaintContext {
  403.     WritableRaster srcRas;
  404.  
  405.     public Any(WritableRaster srcRas,
  406.            ColorModel cm, AffineTransform xform, int maxw) {
  407.         super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
  408.         this.srcRas = srcRas;
  409.     }
  410.  
  411.     public WritableRaster makeRaster(int w, int h) {
  412.         return srcRas.createCompatibleWritableRaster(w, h);
  413.     }
  414.  
  415.     public void setRaster(int x, int y, int xerr, int yerr,
  416.                   int w, int h, int bWidth, int bHeight,
  417.                   int colincx, int colincxerr,
  418.                   int colincy, int colincyerr,
  419.                   int rowincx, int rowincxerr,
  420.                   int rowincy, int rowincyerr) {
  421.         Object data = null;
  422.         int rowx = x;
  423.         int rowy = y;
  424.         int rowxerr = xerr;
  425.         int rowyerr = yerr;
  426.         WritableRaster srcRas = this.srcRas;
  427.         WritableRaster outRas = this.outRas;
  428.         for (int j = 0; j < h; j++) {
  429.         x = rowx;
  430.         y = rowy;
  431.         xerr = rowxerr;
  432.         yerr = rowyerr;
  433.         for (int i = 0; i < w; i++) {
  434.             data = srcRas.getDataElements(x, y, data);
  435.             outRas.setDataElements(i, j, data);
  436.             if ((xerr += colincxerr) < 0) {
  437.             xerr &= Integer.MAX_VALUE;
  438.             x++;
  439.             }
  440.             if ((x += colincx) >= bWidth) {
  441.             x -= bWidth;
  442.             }
  443.             if ((yerr += colincyerr) < 0) {
  444.             yerr &= Integer.MAX_VALUE;
  445.             y++;
  446.             }
  447.             if ((y += colincy) >= bHeight) {
  448.             y -= bHeight;
  449.             }
  450.         }
  451.         if ((rowxerr += rowincxerr) < 0) {
  452.             rowxerr &= Integer.MAX_VALUE;
  453.             rowx++;
  454.         }
  455.         if ((rowx += rowincx) >= bWidth) {
  456.             rowx -= bWidth;
  457.         }
  458.         if ((rowyerr += rowincyerr) < 0) {
  459.             rowyerr &= Integer.MAX_VALUE;
  460.             rowy++;
  461.         }
  462.         if ((rowy += rowincy) >= bHeight) {
  463.             rowy -= bHeight;
  464.         }
  465.         }
  466.     }
  467.     }
  468. }
  469.