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 * <p> 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 * <p> 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 * <pre> 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 <code>AffineTransform</code> to be applied to the 172 * coordinates as they are returned in the iteration, or 173 * <code>null</code> 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 * <p> 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 * <p> 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 * <p> 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 * <p> 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 * <pre> 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 <code>AffineTransform</code> to be applied to the 183 * coordinates as they are returned in the iteration, or 184 * <code>null</code> 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 * <p> 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 * <p> 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 * <p> 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 } |