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 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
101 }
102
103 /**
104 * Adds the delta {@code dv} to the value {@code v} with
105 * appropriate clipping to the bounds of Integer resolution.
106 * If the answer would be greater than {@code Integer.MAX_VALUE}
107 * then {@code Integer.MAX_VALUE} is returned.
108 * If the answer would be less than {@code Integer.MIN_VALUE}
109 * then {@code Integer.MIN_VALUE} is returned.
110 * Otherwise the sum is returned.
111 */
112 public static int clipAdd(int v, int dv) {
113 int newv = v + dv;
114 if ((newv > v) != (dv > 0)) {
115 newv = (dv < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
116 }
117 return newv;
118 }
119
120 /**
121 * Multiply the scale factor {@code sv} and the value {@code v} with
122 * appropriate clipping to the bounds of Integer resolution. If the answer
123 * would be greater than {@code Integer.MAX_VALUE} then {@code
124 * Integer.MAX_VALUE} is returned. If the answer would be less than {@code
125 * Integer.MIN_VALUE} then {@code Integer.MIN_VALUE} is returned. Otherwise
126 * the multiplication is returned.
127 */
128 public static int clipScale(final int v, final double sv) {
129 if (sv == 1.0) {
130 return v;
131 }
132 final double newv = v * sv;
133 if (newv < Integer.MIN_VALUE) {
134 return Integer.MIN_VALUE;
135 }
136 if (newv > Integer.MAX_VALUE) {
137 return Integer.MAX_VALUE;
138 }
139 return (int) Math.round(newv);
140 }
542 /**
543 * Returns a Region object that represents the intersection of
544 * this object with the specified Rectangle. The return value
545 * may be this same object if no clipping occurs.
546 */
547 public Region getIntersection(Rectangle r) {
548 return getIntersectionXYWH(r.x, r.y, r.width, r.height);
549 }
550
551 /**
552 * Returns a Region object that represents the intersection of
553 * this object with the specified rectangular area. The return
554 * value may be this same object if no clipping occurs.
555 */
556 public Region getIntersectionXYWH(int x, int y, int w, int h) {
557 return getIntersectionXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
558 }
559
560 /**
561 * Returns a Region object that represents the intersection of
562 * this object with the specified rectangular area. The return
563 * value may be this same object if no clipping occurs.
564 */
565 public Region getIntersectionXYXY(int lox, int loy, int hix, int hiy) {
566 if (isInsideXYXY(lox, loy, hix, hiy)) {
567 return this;
568 }
569 Region ret = new Region((lox < this.lox) ? this.lox : lox,
570 (loy < this.loy) ? this.loy : loy,
571 (hix > this.hix) ? this.hix : hix,
572 (hiy > this.hiy) ? this.hiy : hiy);
573 if (bands != null) {
574 ret.appendSpans(this.getSpanIterator());
575 }
576 return ret;
577 }
578
579 /**
580 * Returns a Region object that represents the intersection of this
581 * object with the specified Region object.
|
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 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.Rectangle2D;
32 import java.awt.geom.RectangularShape;
33
34 import sun.java2d.loops.TransformHelper;
35
36 /**
37 * This class encapsulates a definition of a two dimensional region which
38 * consists of a number of Y ranges each containing multiple X bands.
39 * <p>
40 * A rectangular Region is allowed to have a null band list in which
41 * case the rectangular shape is defined by the bounding box parameters
42 * (lox, loy, hix, hiy).
43 * <p>
44 * The band list, if present, consists of a list of rows in ascending Y
45 * order, ending at endIndex which is the index beyond the end of the
46 * last row. Each row consists of at least 3 + 2n entries (n >= 1)
47 * where the first 3 entries specify the Y range as start, end, and
48 * the number of X ranges in that Y range. These 3 entries are
49 * followed by pairs of X coordinates in ascending order:
50 * <pre>
51 * bands[rowstart+0] = Y0; // starting Y coordinate
102 }
103
104 /**
105 * Adds the delta {@code dv} to the value {@code v} with
106 * appropriate clipping to the bounds of Integer resolution.
107 * If the answer would be greater than {@code Integer.MAX_VALUE}
108 * then {@code Integer.MAX_VALUE} is returned.
109 * If the answer would be less than {@code Integer.MIN_VALUE}
110 * then {@code Integer.MIN_VALUE} is returned.
111 * Otherwise the sum is returned.
112 */
113 public static int clipAdd(int v, int dv) {
114 int newv = v + dv;
115 if ((newv > v) != (dv > 0)) {
116 newv = (dv < 0) ? Integer.MIN_VALUE : Integer.MAX_VALUE;
117 }
118 return newv;
119 }
120
121 /**
122 * Returns the closest {@code int} to the argument, with ties rounding to
123 * negative infinity.
124 * <p>
125 * Special cases:
126 * <ul><li>If the argument is NaN, the result is 0.
127 * <li>If the argument is negative infinity or any value less than or
128 * equal to the value of {@code Integer.MIN_VALUE}, the result is
129 * equal to the value of {@code Integer.MIN_VALUE}.
130 * <li>If the argument is positive infinity or any value greater than or
131 * equal to the value of {@code Integer.MAX_VALUE}, the result is
132 * equal to the value of {@code Integer.MAX_VALUE}.</ul>
133 *
134 * @param coordinate a floating-point value to be rounded to an integer
135 * @return the value of the argument rounded to the nearest
136 * {@code int} value.
137 */
138 public static int clipRound(final double coordinate) {
139 final double newv = coordinate - 0.5;
140 if (newv < Integer.MIN_VALUE) {
141 return Integer.MIN_VALUE;
142 }
143 if (newv > Integer.MAX_VALUE) {
144 return Integer.MAX_VALUE;
145 }
146 return (int) Math.ceil(newv);
147 }
148
149 /**
150 * Multiply the scale factor {@code sv} and the value {@code v} with
151 * appropriate clipping to the bounds of Integer resolution. If the answer
152 * would be greater than {@code Integer.MAX_VALUE} then {@code
153 * Integer.MAX_VALUE} is returned. If the answer would be less than {@code
154 * Integer.MIN_VALUE} then {@code Integer.MIN_VALUE} is returned. Otherwise
155 * the multiplication is returned.
156 */
157 public static int clipScale(final int v, final double sv) {
158 if (sv == 1.0) {
159 return v;
160 }
161 final double newv = v * sv;
162 if (newv < Integer.MIN_VALUE) {
163 return Integer.MIN_VALUE;
164 }
165 if (newv > Integer.MAX_VALUE) {
166 return Integer.MAX_VALUE;
167 }
168 return (int) Math.round(newv);
169 }
571 /**
572 * Returns a Region object that represents the intersection of
573 * this object with the specified Rectangle. The return value
574 * may be this same object if no clipping occurs.
575 */
576 public Region getIntersection(Rectangle r) {
577 return getIntersectionXYWH(r.x, r.y, r.width, r.height);
578 }
579
580 /**
581 * Returns a Region object that represents the intersection of
582 * this object with the specified rectangular area. The return
583 * value may be this same object if no clipping occurs.
584 */
585 public Region getIntersectionXYWH(int x, int y, int w, int h) {
586 return getIntersectionXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
587 }
588
589 /**
590 * Returns a Region object that represents the intersection of
591 * this object with the specified Rectangle2D. The return value
592 * may be this same object if no clipping occurs.
593 */
594 public Region getIntersection(Rectangle2D r) {
595 return getIntersectionXYXY(r.getMinX(), r.getMinY(), r.getMaxX(),
596 r.getMaxY());
597 }
598
599 /**
600 * Returns a Region object that represents the intersection of
601 * this object with the specified rectangular area. The return
602 * value may be this same object if no clipping occurs.
603 */
604 public Region getIntersectionXYXY(double lox, double loy, double hix,
605 double hiy) {
606 return getIntersectionXYXY(clipRound(lox), clipRound(loy),
607 clipRound(hix), clipRound(hiy));
608 }
609
610 /**
611 * Returns a Region object that represents the intersection of
612 * this object with the specified rectangular area. The return
613 * value may be this same object if no clipping occurs.
614 */
615 public Region getIntersectionXYXY(int lox, int loy, int hix, int hiy) {
616 if (isInsideXYXY(lox, loy, hix, hiy)) {
617 return this;
618 }
619 Region ret = new Region((lox < this.lox) ? this.lox : lox,
620 (loy < this.loy) ? this.loy : loy,
621 (hix > this.hix) ? this.hix : hix,
622 (hiy > this.hiy) ? this.hiy : hiy);
623 if (bands != null) {
624 ret.appendSpans(this.getSpanIterator());
625 }
626 return ret;
627 }
628
629 /**
630 * Returns a Region object that represents the intersection of this
631 * object with the specified Region object.
|