📄 region.java
字号:
*/ private void updateExtent() { if (nRectangles_ == 0) extent_.set (0, 0, 0, 0); else { // Y values extent_.y1 = rectangles_[0]; extent_.y2 = rectangles_[(nRectangles_ << 2) - 3]; // X values initialize extent_.x1 = rectangles_[2]; extent_.x2 = rectangles_[3]; // Scan all rectangles for extreme X values for (int i = 4; i < nRectangles_ << 2; i += 4) { if (rectangles_[i+2] < extent_.x1) extent_.x1 = rectangles_[i+2]; if (rectangles_[i+3] > extent_.x2) extent_.x2 = rectangles_[i+3]; } } } /** * Union this region with the specified region. * Corresponds to XUnionRegion in X11. * * @param region Region to union this with. */ public void union (Region region) { // Trivial case #1. Region is this or empty if (this == region || region.isEmpty()) return; // Trivial case #2. This is empty if (isEmpty()) { set (region); return; } // Trivial case #3. This region covers the specified one if (rectangles_.length == 1 && region.extent_.isInsideOf (extent_)) return; // Trivial case #4. The specified region covers this one if (region.rectangles_.length == 1 && extent_.isInsideOf (region.extent_)) { set (region); return; } // Ceneral case combine (region, OPERATION_UNION); // Update extent extent_.x1 = Math.min (extent_.x1, region.extent_.x1); extent_.y1 = Math.min (extent_.y1, region.extent_.y1); extent_.x2 = Math.max (extent_.x2, region.extent_.x2); extent_.y2 = Math.max (extent_.y2, region.extent_.y2); } /** * Union this region with the specified rectangle. * Corresponds to XUnionRectWithRegion in X11. * * @param rectangle Rectangle to union this with. */ public void union (Rect rectangle) { if (rectangle.isEmpty()) return; union (new Region (rectangle)); } /** * Create a new region as the union between two specified regions. * * @param r1 First region to union. * @param r2 Second region to union. * @return Union of the two specified regions. */ public static Region union (Region r1, Region r2) { Region region = new Region (r1); region.union (r2); return region; } /** * Create a new region as the union between a region and a rectangle. * * @param region Region to union. * @param rectangle Rectangle to intersect with. * @return Union of the region and the rectangle. */ public static Region union (Region region, Rect rectangle) { if (rectangle.isEmpty()) return new Region (region); else return union (region, new Region (rectangle)); } /** * Leave this region as the intersection between this region and the * specified region. * Corresponds to XIntersectRegion in X11. * * @param region Region to intersect this with. */ public void intersect (Region region) { // Trivial case which results in an empty region if (isEmpty() || region.isEmpty() || !extent_.isOverlapping (region.extent_)) { clear(); return; } // General case combine (region, OPERATION_INTERSECTION); // Update extent updateExtent(); } /** * Leave this region as the intersection between this region and the * specified rectangle. * * @param region Region to intersect this with. */ public void intersect (Rect rectangle) { if (rectangle.isEmpty()) clear(); else intersect (new Region (rectangle)); } /** * Create a new region as the intersection between two specified regions. * * @param r1 First region to intersect. * @param r2 Second region to intersect. * @return Intersection between the two specified regions. */ public static Region intersect (Region r1, Region r2) { Region region = new Region (r1); region.intersect (r2); return region; } /** * Create a new region as the intersection between a region and a rectangle. * * @param region Region to intersect. * @param rectangle Rectangle to intersect with. * @return Intersection between the region and the rectangle. */ public static Region intersect (Region region, Rect rectangle) { if (rectangle.isEmpty()) return new Region(); else return intersect (region, new Region (rectangle)); } /** * Subtract the specified region from this region. * Corresponds to XSubtractRegion in X11. * * @param region Region to subtract from this region. */ public void subtract (Region region) { // Trivial check for non-op if (isEmpty() || region.isEmpty() || !extent_.isOverlapping (region.extent_)) return; // General case combine (region, OPERATION_SUBTRACTION); // Update extent updateExtent(); } /** * Subtract the specified rectangle from this region. * * @param rectangle Rectangle to subtract from this region. */ public void subtract (Rect rectangle) { if (rectangle.isEmpty()) return; subtract (new Region (rectangle)); } /** * Create a new region as the subtraction of one region from another. * * @param r1 Region to subtract from. * @param r2 Region to subtract. * @return Subtraction of the two specified regions. */ public static Region subtract (Region r1, Region r2) { Region region = new Region (r1); region.subtract (r2); return region; } /** * Create a new region as the subtraction of a rectangle from * a region. * * @param region Region to subtract from. * @param rectangle Ractangle to subtract. * @return Subtraction of the two specified regions. */ public static Region subtract (Region region, Rect rectangle) { if (rectangle.isEmpty()) return new Region (region); else return subtract (region, new Region (rectangle)); } /** * Leave the exclusive-or between this and the specified region in * this region. Corresponds to the XXorRegion in X11. * * @param region Region to xor this region with. */ public void xor (Region region) { Region r = (Region) region.clone(); r.subtract (this); subtract (region); union (r); } /** * Leave the exclusive-or between this and the specified rectangle in * this region. * * @param rectangle Rectangle to xor this region with. */ public void xor (Rect rectangle) { if (rectangle.isEmpty()) clear(); else xor (new Region (rectangle)); } /** * Do an exlusive-or operation between two regions and return * the result. * * @param r1 First region to xor. * @param r2 Second region to xor. * @return Result of operation. */ public static Region xor (Region r1, Region r2) { Region region = new Region (r1); region.xor (r2); return region; } /** * Do an exlusive-or operation between a regions and a rectangle * and return the result. * * @param region Region to xor. * @param rectangle Rectangle to xor with. * @return Result of operation. */ public static Region xor (Region region, Rect rectangle) { if (rectangle.isEmpty()) return new Region(); else return xor (region, new Region (rectangle)); } // DEBUG private boolean isExtentCorrect() { int yMin = 0; int yMax = 0; int xMin = 0; int xMax = 0; if (nRectangles_ > 0) { yMin = rectangles_[0]; yMax = rectangles_[1]; xMin = rectangles_[2]; xMax = rectangles_[3]; for (int i = 4; i < nRectangles_ << 2; i+= 4) { if (rectangles_[i+0] < yMin) yMin = rectangles_[i+0]; if (rectangles_[i+1] > yMax) yMax = rectangles_[i+1]; if (rectangles_[i+2] < xMin) xMin = rectangles_[i+2]; if (rectangles_[i+3] > xMax) xMax = rectangles_[i+3]; } } if (extent_.x1 != xMin) { System.out.println ("Extent error x1"); return false; } if (extent_.x2 != xMax) { System.out.println ("Extent error x2"); return false; } if (extent_.y1 != yMin) { System.out.println ("Extent error y1"); return false; } if (extent_.y2 != yMax) { System.out.println ("Extent error y2"); return false; } return true; } // DEBUG private boolean isCoalesced() { if (nRectangles_ < 2) return true; int rEnd = nRectangles_ << 2; int thisBand = 0; while (thisBand != rEnd) { // Find start of next band int nextBand = thisBand; while (nextBand != rEnd && rectangles_[nextBand] == rectangles_[thisBand]) nextBand += 4; if (nextBand == rEnd) return true; // Now we have two consecutive bands. See if they touch. if (rectangles_[thisBand+1] == rectangles_[nextBand+1]) { // Check the x values int thisY = rectangles_[thisBand]; int nextY = rectangles_[nextBand]; int i = thisBand; int j = nextBand; while (j != rEnd && rectangles_[i] == thisY && rectangles_[j] == nextY) { if (rectangles_[i+2] != rectangles_[j+2] || rectangles_[i+3] != rectangles_[j+3]) break; i += 4; j += 4; } if (rectangles_[i] != thisY && (rectangles_[j] != nextY || j == rEnd)) System.out.println ("Coalesce error at Y=" + thisY); } thisBand = nextBand; } return true; } // DEBUG private boolean isConsistent() { boolean isExtentCorrect = isExtentCorrect(); if (!isExtentCorrect) return false; if (nRectangles_ == 0) return true; for (int i = 0; i < nRectangles_; i += 4) { int y1 = rectangles_[i+0]; int y2 = rectangles_[i+1]; int x1 = rectangles_[i+2]; int x2 = rectangles_[i+3]; if (y2 <= y1) { System.out.println ("Rectangle error y2 > y1"); return false; } if (x2 <= x1) { System.out.println ("Rectangle error x2 > x1"); return false; } if (i+4 < nRectangles_) { int y1next = rectangles_[i+4]; int y2next = rectangles_[i+5]; int x1next = rectangles_[i+6]; int x2next = rectangles_[i+7]; if (y1next < y1) { System.out.println ("Band alignment top error"); return false; } if (y1next == y1) { if (y2next != y2) { System.out.println ("Band alignment bottom error"); return false; } if (x1next < x2) { System.out.println ("X bands intersect error"); return false; } if (x1next == x2) { System.out.println ("X bands touch error"); return false; } } } } if (!isCoalesced()) return false; return true; } // DEBUG private void print() { System.out.println ("-------------------------------"); System.out.println (extent_); System.out.println ("nRectangles = " + nRectangles_); for (int i = 0; i < nRectangles_; i++) { System.out.print ("y1=" + rectangles_[i*4 + 0] + ", "); System.out.print ("y2=" + rectangles_[i*4 + 1] + ", "); System.out.print ("x1=" + rectangles_[i*4 + 2] + ", "); System.out.println ("x2=" + rectangles_[i*4 + 3]); } } // DEBUG private void printRects() { for (int i = 0; i < nRectangles_ << 2; i++) { if (i % 4 == 0 && i != 0) System.out.print (" "); System.out.print (rectangles_[i]); if ((i+1) % 4 != 0) System.out.print (','); } System.out.println (); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -