## src/java.desktop/share/classes/sun/java2d/pipe/Region.java

 ``` `````` 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 sun.java2d.pipe; 27 28 import java.awt.Rectangle; 29 import java.awt.Shape; 30 import java.awt.geom.AffineTransform; 31 import java.awt.geom.RectangularShape; 32 33 /** 34 * This class encapsulates a definition of a two dimensional region which 35 * consists of a number of Y ranges each containing multiple X bands. 36 *

37 * A rectangular Region is allowed to have a null band list in which 38 * case the rectangular shape is defined by the bounding box parameters 39 * (lox, loy, hix, hiy). 40 *

41 * The band list, if present, consists of a list of rows in ascending Y 42 * order, ending at endIndex which is the index beyond the end of the 43 * last row. Each row consists of at least 3 + 2n entries (n >= 1) 44 * where the first 3 entries specify the Y range as start, end, and 45 * the number of X ranges in that Y range. These 3 entries are 46 * followed by pairs of X coordinates in ascending order: 47 *

48  * bands[rowstart+0] = Y0;        // starting Y coordinate   49  * bands[rowstart+1] = Y1;        // ending Y coordinate - endY > startY   50  * bands[rowstart+2] = N;         // number of X bands - N >= 1   51  *   52  * bands[rowstart+3] = X10;       // starting X coordinate of first band  `````` 143         if (sv == 1.0) {  144             return v;  145         }  146         final double newv = v * sv;  147         if (newv < Integer.MIN_VALUE) {  148             return Integer.MIN_VALUE;  149         }  150         if (newv > Integer.MAX_VALUE) {  151             return Integer.MAX_VALUE;  152         }  153         return (int) Math.round(newv);  154     }  155   156     protected Region(int lox, int loy, int hix, int hiy) {  157         this.lox = lox;  158         this.loy = loy;  159         this.hix = hix;  160         this.hiy = hiy;  161     }  162            163     /**  164      * Returns a Region object covering the pixels which would be  165      * touched by a fill or clip operation on a Graphics implementation  166      * on the specified Shape object under the optionally specified  167      * AffineTransform object.  168      *  169      * @param s a non-null Shape object specifying the geometry enclosing  170      *          the pixels of interest  171      * @param at an optional AffineTransform to be applied to the  172      *          coordinates as they are returned in the iteration, or  173      *          null if untransformed coordinates are desired  174      */  175     public static Region getInstance(Shape s, AffineTransform at) {  176         return getInstance(WHOLE_REGION, false, s, at);  177     }  178   179     /**  180      * Returns a Region object covering the pixels which would be  181      * touched by a fill or clip operation on a Graphics implementation  182      * on the specified Shape object under the optionally specified  `````` 239                 ((RectangularShape)s).isEmpty())  240         {  241             return EMPTY_REGION;  242         }  243   244         int box[] = new int[4];  245         ShapeSpanIterator sr = new ShapeSpanIterator(normalize);  246         try {  247             sr.setOutputArea(devBounds);  248             sr.appendPath(s.getPathIterator(at));  249             sr.getPathBox(box);  250             Region r = Region.getInstance(box);  251             r.appendSpans(sr);  252             return r;  253         } finally {  254             sr.dispose();  255         }  256     }  257   258     /**                                  259      * Returns a Region object with a rectangle of interest specified  260      * by the indicated Rectangle object.  261      *

262 * This method can also be used to create a simple rectangular 263 * region. 264 */ 265 public static Region getInstance(Rectangle r) { 266 return Region.getInstanceXYWH(r.x, r.y, r.width, r.height); 267 } 268 269 /** 270 * Returns a Region object with a rectangle of interest specified 271 * by the indicated rectangular area in x, y, width, height format. 272 *

273 * This method can also be used to create a simple rectangular 274 * region. 275 */ 276 public static Region getInstanceXYWH(int x, int y, int w, int h) { 277 return Region.getInstanceXYXY(x, y, dimAdd(x, w), dimAdd(y, h)); 278 } ``` ``` `````` 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 sun.java2d.pipe; 27 28 import java.awt.Rectangle; 29 import java.awt.Shape; 30 import java.awt.geom.AffineTransform; 31 import java.awt.geom.RectangularShape; 32 33 import sun.java2d.loops.TransformHelper; 34 35 /** 36 * This class encapsulates a definition of a two dimensional region which 37 * consists of a number of Y ranges each containing multiple X bands. 38 *

39 * A rectangular Region is allowed to have a null band list in which 40 * case the rectangular shape is defined by the bounding box parameters 41 * (lox, loy, hix, hiy). 42 *

43 * The band list, if present, consists of a list of rows in ascending Y 44 * order, ending at endIndex which is the index beyond the end of the 45 * last row. Each row consists of at least 3 + 2n entries (n >= 1) 46 * where the first 3 entries specify the Y range as start, end, and 47 * the number of X ranges in that Y range. These 3 entries are 48 * followed by pairs of X coordinates in ascending order: 49 *

50  * bands[rowstart+0] = Y0;        // starting Y coordinate   51  * bands[rowstart+1] = Y1;        // ending Y coordinate - endY > startY   52  * bands[rowstart+2] = N;         // number of X bands - N >= 1   53  *   54  * bands[rowstart+3] = X10;       // starting X coordinate of first band  `````` 145         if (sv == 1.0) {  146             return v;  147         }  148         final double newv = v * sv;  149         if (newv < Integer.MIN_VALUE) {  150             return Integer.MIN_VALUE;  151         }  152         if (newv > Integer.MAX_VALUE) {  153             return Integer.MAX_VALUE;  154         }  155         return (int) Math.round(newv);  156     }  157   158     protected Region(int lox, int loy, int hix, int hiy) {  159         this.lox = lox;  160         this.loy = loy;  161         this.hix = hix;  162         this.hiy = hiy;  163     }  164   165     private Region(int lox, int loy, int hix, int hiy, int[] bands, int end) {  166         this.lox = lox;  167         this.loy = loy;  168         this.hix = hix;  169         this.hiy = hiy;  170         this.bands = bands;  171         this.endIndex = end;  172     }  173   174     /**  175      * Returns a Region object covering the pixels which would be  176      * touched by a fill or clip operation on a Graphics implementation  177      * on the specified Shape object under the optionally specified  178      * AffineTransform object.  179      *  180      * @param s a non-null Shape object specifying the geometry enclosing  181      *          the pixels of interest  182      * @param at an optional AffineTransform to be applied to the  183      *          coordinates as they are returned in the iteration, or  184      *          null if untransformed coordinates are desired  185      */  186     public static Region getInstance(Shape s, AffineTransform at) {  187         return getInstance(WHOLE_REGION, false, s, at);  188     }  189   190     /**  191      * Returns a Region object covering the pixels which would be  192      * touched by a fill or clip operation on a Graphics implementation  193      * on the specified Shape object under the optionally specified  `````` 250                 ((RectangularShape)s).isEmpty())  251         {  252             return EMPTY_REGION;  253         }  254   255         int box[] = new int[4];  256         ShapeSpanIterator sr = new ShapeSpanIterator(normalize);  257         try {  258             sr.setOutputArea(devBounds);  259             sr.appendPath(s.getPathIterator(at));  260             sr.getPathBox(box);  261             Region r = Region.getInstance(box);  262             r.appendSpans(sr);  263             return r;  264         } finally {  265             sr.dispose();  266         }  267     }  268   269     /**  270      * Returns a Region object with a rectangle of interest specified by the  271      * indicated rectangular area in lox, loy, hix, hiy and edges array, which  272      * is located relative to the rectangular area. Edges array - 0,1 are y  273      * range, 2N,2N+1 are x ranges, 1 per y range.  274      *

275 * Note that we trust to the edges array, which means that edges should be: 276 * {@code edges + (lox, loy) < (hix, hiy)}, otherwise result is undefined 277 * 278 * @see TransformHelper 279 */ 280 static Region getInstance(final int lox, final int loy, final int hix, 281 final int hiy, final int edges[]) { 282 // rowsNum * (3 + 1 * 2), plus one byte for endIndex 283 final int[] bands = new int[(edges[1] - edges[0]) * 5 + 1]; 284 int end = 0; 285 int index = 2; 286 for (int y = edges[0]; end < bands.length && y < edges[1]; ++y) { 287 final int x1 = edges[index++]; 288 final int x2 = edges[index++]; 289 if (x1 < x2) { 290 bands[end++] = loy + y; // spanloy 291 bands[end++] = loy + y + 1; // spanhiy 292 bands[end++] = 1; // 1 span per row 293 bands[end++] = lox + x1; // spanlox 294 bands[end++] = lox + x2; // spanhix 295 } 296 } 297 return end != 0 ? new Region(lox, loy, hix, hiy, bands, end) 298 : EMPTY_REGION; 299 } 300 301 /** 302 * Returns a Region object with a rectangle of interest specified 303 * by the indicated Rectangle object. 304 *

305 * This method can also be used to create a simple rectangular 306 * region. 307 */ 308 public static Region getInstance(Rectangle r) { 309 return Region.getInstanceXYWH(r.x, r.y, r.width, r.height); 310 } 311 312 /** 313 * Returns a Region object with a rectangle of interest specified 314 * by the indicated rectangular area in x, y, width, height format. 315 *

316 * This method can also be used to create a simple rectangular 317 * region. 318 */ 319 public static Region getInstanceXYWH(int x, int y, int w, int h) { 320 return Region.getInstanceXYXY(x, y, dimAdd(x, w), dimAdd(y, h)); 321 } ```