diff options
Diffstat (limited to 'awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java')
-rw-r--r-- | awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java | 837 |
1 files changed, 0 insertions, 837 deletions
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java b/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java deleted file mode 100644 index c75e203..0000000 --- a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @author Denis M. Kishenko - * @version $Revision$ - */ -package org.apache.harmony.awt.gl; - -import java.awt.Rectangle; - -public class MultiRectAreaOp { - - /** - * Rectangle buffer capacity - */ - public static final int RECT_CAPACITY = 16; - - /** - * If number of rectangle in MultiRectArea object less than MAX_SIMPLE simple algorithm applies - */ - private static final int MAX_SIMPLE = 8; - - /** - * Create buffer - */ - public static int[] createBuf(int capacity) { - if (capacity == 0) { - capacity = RECT_CAPACITY; - } - int[] buf = new int[capacity]; - buf[0] = 1; - return buf; - } - - /** - * Checks buffer size and reallocate if necessary - */ - public static int[] checkBufSize(int[] buf, int capacity) { - if (buf[0] + capacity >= buf.length) { - int length = buf[0] + (capacity > RECT_CAPACITY ? capacity : RECT_CAPACITY); - int[] tmp = new int[length]; - System.arraycopy(buf, 0, tmp, 0, buf[0]); - buf = tmp; - } - buf[0] += capacity; - return buf; - } - - /** - * Region class provides basic functionlity for MultiRectArea objects to make logical operations - */ - static class Region { - - int[] region; - int[] active; - int[] bottom; - int index; - - public Region(int[] region) { - this.region = region; - active = new int[RECT_CAPACITY]; - bottom = new int[RECT_CAPACITY]; - active[0] = 1; - bottom[0] = 1; - index = 1; - } - - void addActive(int index) { - int length = active[0]; - active = checkBufSize(active, 4); - int i = 1; - - while(i < length) { - if (region[index] < active[i]) { - // Insert - System.arraycopy(active, i, active, i + 4, length - i); - length = i; - break; - } - i += 4; - } - System.arraycopy(region, index, active, length, 4); - - } - - void findActive(int top, int bottom) { - while(index < region[0]) { - if (region[index + 1] > bottom) { // y1 > bottom - return; - } - if (region[index + 3] >= top) { // y2 >= top - addActive(index); - } - index += 4; - } - } - - void deleteActive(int bottom) { - int length = active[0]; - for(int i = 1; i < length;) { - if (active[i + 3] == bottom) { - length -= 4; - if (i < length) { - System.arraycopy(active, i + 4, active, i, length - i); - } - } else { - i += 4; - } - } - active[0] = length; - } - - void deleteActive() { - int length = active[0]; - for(int i = length - 4; i > 0; i -= 4) { - if (active[i + 1] > active[i + 3]) { - length -= 4; - if (i < length) { - System.arraycopy(active, i + 4, active, i, length - i); - } - } - } - active[0] = length; - } - - void createLevel(int[] level) { - int levelCount = 1; - int topIndex = 1; - int i = 1; - while(i < region[0]) { - - int top = region[i + 1]; - int bottom = region[i + 3] + 1; - int j = topIndex; - - addTop: { - while(j < levelCount) { - if (level[j] == top) { - break addTop; - } - if (level[j] > top) { - System.arraycopy(level, j, level, j + 1, levelCount - j); - break; - } - j++; - } - - level[j] = top; - levelCount++; - topIndex = j; - } - - addBottom: { - while(j < levelCount) { - if (level[j] == bottom) { - break addBottom; - } - if (level[j] > bottom) { - System.arraycopy(level, j, level, j + 1, levelCount - j); - break; - } - j++; - }; - - level[j] = bottom; - levelCount++; - } - - i += 4; - } - level[0] = levelCount; - } - - static void sortOrdered(int[] src1, int[] src2, int[] dst) { - int length1 = src1[0]; - int length2 = src2[0]; - int count = 1; - int i1 = 1; - int i2 = 1; - int v1 = src1[1]; - int v2 = src2[1]; - while(true) { - - LEFT: { - while(i1 < length1) { - v1 = src1[i1]; - if (v1 >= v2) { - break LEFT; - } - dst[count++] = v1; - i1++; - } - while(i2 < length2) { - dst[count++] = src2[i2++]; - } - dst[0] = count; - return; - } - - RIGHT: { - while(i2 < length2) { - v2 = src2[i2]; - if (v2 >= v1) { - break RIGHT; - } - dst[count++] = v2; - i2++; - } - while(i1 < length1) { - dst[count++] = src1[i1++]; - } - dst[0] = count; - return; - } - - if (v1 == v2) { - dst[count++] = v1; - i1++; - i2++; - if (i1 < length1) { - v1 = src1[i1]; - } - if (i2 < length2 - 1) { - v2 = src2[i2]; - } - } - } - // UNREACHABLE - } - - } - - /** - * Intersection class provides intersection of two MultiRectAre aobjects - */ - static class Intersection { - - static void intersectRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) { - - Region d1 = new Region(reg1); - Region d2 = new Region(reg2); - - int[] level = new int[height1 + height2]; - int[] level1 = new int[height1]; - int[] level2 = new int[height2]; - d1.createLevel(level1); - d2.createLevel(level2); - Region.sortOrdered(level1, level2, level); - - int top; - int bottom = level[1] - 1; - for(int i = 2; i < level[0]; i++) { - - top = bottom + 1; - bottom = level[i] - 1; - - d1.findActive(top, bottom); - d2.findActive(top, bottom); - - int i1 = 1; - int i2 = 1; - - while(i1 < d1.active[0] && i2 < d2.active[0]) { - - int x11 = d1.active[i1]; - int x12 = d1.active[i1 + 2]; - int x21 = d2.active[i2]; - int x22 = d2.active[i2 + 2]; - - if (x11 <= x21) { - if (x12 >= x21) { - if (x12 <= x22) { - dst.addRectCashed(x21, top, x12, bottom); - i1 += 4; - } else { - dst.addRectCashed(x21, top, x22, bottom); - i2 += 4; - } - } else { - i1 += 4; - } - } else { - if (x22 >= x11) { - if (x22 <= x12) { - dst.addRectCashed(x11, top, x22, bottom); - i2 += 4; - } else { - dst.addRectCashed(x11, top, x12, bottom); - i1 += 4; - } - } else { - i2 += 4; - } - } - } - - d1.deleteActive(bottom); - d2.deleteActive(bottom); - } - } - - static int[] simpleIntersect(MultiRectArea src1, MultiRectArea src2) { - int[] rect1 = src1.rect; - int[] rect2 = src2.rect; - int[] rect = createBuf(0); - - int k = 1; - for(int i = 1; i < rect1[0];) { - - int x11 = rect1[i++]; - int y11 = rect1[i++]; - int x12 = rect1[i++]; - int y12 = rect1[i++]; - - for(int j = 1; j < rect2[0];) { - - int x21 = rect2[j++]; - int y21 = rect2[j++]; - int x22 = rect2[j++]; - int y22 = rect2[j++]; - - if (x11 <= x22 && x12 >= x21 && - y11 <= y22 && y12 >= y21) - { - rect = checkBufSize(rect, 4); - rect[k++] = x11 > x21 ? x11 : x21; - rect[k++] = y11 > y21 ? y11 : y21; - rect[k++] = x12 > x22 ? x22 : x12; - rect[k++] = y12 > y22 ? y22 : y12; - } - } - } - - rect[0] = k; - return rect; - } - - public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) { - - if (src1 == null || src2 == null || src1.isEmpty() || src2.isEmpty()) { - return new MultiRectArea(); - } - - MultiRectArea.RectCash dst = new MultiRectArea.RectCash(); - - if (!src1.sorted || !src2.sorted || - src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) - { - dst.setRect(simpleIntersect(src1, src2), false); - } else { - Rectangle bounds1 = src1.getBounds(); - Rectangle bounds2 = src2.getBounds(); - Rectangle bounds3 = bounds1.intersection(bounds2); - if (bounds3.width > 0 && bounds3.height > 0) { - intersectRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2); - } - } - - return dst; - } - - } - - /** - * Union class provides union of two MultiRectAre aobjects - */ - static class Union { - - int rx1, rx2; - int top, bottom; - MultiRectArea.RectCash dst; - - boolean next(Region d, int index) { - int x1 = d.active[index]; - int x2 = d.active[index + 2]; - boolean res = false; - - if (x2 < rx1 - 1) { - res = true; - dst.addRectCashed(x1, top, x2, bottom); - } else - if (x1 > rx2 + 1) { - res = false; - dst.addRectCashed(rx1, top, rx2, bottom); - rx1 = x1; - rx2 = x2; - } else { - res = x2 <= rx2; - rx1 = Math.min(x1, rx1); - rx2 = Math.max(x2, rx2); - } - - // Top - if (d.active[index + 1] < top) { - dst.addRectCashed(x1, d.active[index + 1], x2, top - 1); - } - // Bottom - if (d.active[index + 3] > bottom) { - d.active[index + 1] = bottom + 1; - } - return res; - } - - void check(Region d, int index, boolean t) { - int x1 = d.active[index]; - int x2 = d.active[index + 2]; - // Top - if (d.active[index + 1] < top) { - dst.addRectCashed(x1, d.active[index + 1], x2, top - 1); - } - if (t) { - dst.addRectCashed(x1, top, x2, bottom); - } - // Bottom - if (d.active[index + 3] > bottom) { - d.active[index + 1] = bottom + 1; - } - } - - void unionRegions(int[] reg1, int[] reg2, int height1, int height2) { - Region d1 = new Region(reg1); - Region d2 = new Region(reg2); - - int[] level = new int[height1 + height2]; - int[] level1 = new int[height1]; - int[] level2 = new int[height2]; - d1.createLevel(level1); - d2.createLevel(level2); - Region.sortOrdered(level1, level2, level); - - bottom = level[1] - 1; - for(int i = 2; i < level[0]; i++) { - - top = bottom + 1; - bottom = level[i] - 1; - - d1.findActive(top, bottom); - d2.findActive(top, bottom); - - int i1 = 1; - int i2 = 1; - boolean res1, res2; - - if (d1.active[0] > 1) { - check(d1, 1, false); - rx1 = d1.active[1]; - rx2 = d1.active[3]; - i1 += 4; - res1 = false; - res2 = true; - } else - if (d2.active[0] > 1) { - check(d2, 1, false); - rx1 = d2.active[1]; - rx2 = d2.active[3]; - i2 += 4; - res1 = true; - res2 = false; - } else { - continue; - } - - outer: - while(true) { - - while (res1) { - if (i1 >= d1.active[0]) { - dst.addRectCashed(rx1, top, rx2, bottom); - while(i2 < d2.active[0]) { - check(d2, i2, true); - i2 += 4; - } - break outer; - } - res1 = next(d1, i1); - i1 += 4; - } - - while (res2) { - if (i2 >= d2.active[0]) { - dst.addRectCashed(rx1, top, rx2, bottom); - while(i1 < d1.active[0]) { - check(d1, i1, true); - i1 += 4; - } - break outer; - } - res2 = next(d2, i2); - i2 += 4; - } - - res1 = true; - res2 = true; - } // while - - d1.deleteActive(bottom); - d2.deleteActive(bottom); - - } - } - - static void simpleUnion(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) { - if (src1.getRectCount() < src2.getRectCount()) { - simpleUnion(src2, src1, dst); - } else { - Subtraction.simpleSubtract(src1, src2, dst); - int pos = dst.rect[0]; - int size = src2.rect[0] - 1; - dst.rect = checkBufSize(dst.rect, size); - System.arraycopy(src2.rect,1, dst.rect, pos, size); - dst.resort(); - } - } - - MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) { - - if (src1 == null || src1.isEmpty()) { - return new MultiRectArea(src2); - } - - if (src2 == null || src2.isEmpty()) { - return new MultiRectArea(src1); - } - - dst = new MultiRectArea.RectCash(); - - if (!src1.sorted || !src2.sorted || - src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) - { - simpleUnion(src1, src2, dst); - } else { - Rectangle bounds1 = src1.getBounds(); - Rectangle bounds2 = src2.getBounds(); - Rectangle bounds3 = bounds1.intersection(bounds2); - - if (bounds3.width < 0 || bounds3.height < 0) { - if (bounds1.y + bounds1.height < bounds2.y) { - dst.setRect(addVerRegion(src1.rect, src2.rect), false); - } else - if (bounds2.y + bounds2.height < bounds1.y) { - dst.setRect(addVerRegion(src2.rect, src1.rect), false); - } else - if (bounds1.x < bounds2.x) { - dst.setRect(addHorRegion(src1.rect, src2.rect), false); - } else { - dst.setRect(addHorRegion(src2.rect, src1.rect), false); - } - } else { - unionRegions(src1.rect, src2.rect, bounds1.height + 2, bounds2.height + 2); - } - } - - return dst; - } - - int[] addVerRegion(int[] top, int[] bottom) { - int length = top[0] + bottom[0] - 1; - int[] dst = new int[length]; - dst[0] = length; - System.arraycopy(top, 1, dst, 1, top[0] - 1); - System.arraycopy(bottom, 1, dst, top[0], bottom[0] - 1); - return dst; - } - - int[] addHorRegion(int[] left, int[] right) { - int count1 = left[0]; - int count2 = right[0]; - int[] dst = new int[count1 + count2 + 1]; - int count = 1; - int index1 = 1; - int index2 = 1; - - int top1 = left[2]; - int top2 = right[2]; - int pos1, pos2; - - while(true) { - - if (index1 >= count1) { - System.arraycopy(right, index2, dst, count, count2 - index2); - count += count2 - index2; - break; - } - if (index2 >= count2) { - System.arraycopy(left, index1, dst, count, count1 - index1); - count += count1 - index1; - break; - } - - if (top1 < top2) { - pos1 = index1; - do { - index1 += 4; - } while (index1 < count1 && (top1 = left[index1 + 1]) < top2); - System.arraycopy(left, pos1, dst, count, index1 - pos1); - count += index1 - pos1; - continue; - } - - if (top1 > top2) { - pos2 = index2; - do { - index2 += 4; - } while (index2 < count2 && (top2 = right[index2 + 1]) < top1); - System.arraycopy(right, pos2, dst, count, index2 - pos2); - count += index2 - pos2; - continue; - } - - int top = top1; - pos1 = index1; - pos2 = index2; - do { - index1 += 4; - } while(index1 < count1 && (top1 = left[index1 + 1]) == top); - do { - index2 += 4; - } while(index2 < count2 && (top2 = right[index2 + 1]) == top); - - System.arraycopy(left, pos1, dst, count, index1 - pos1); - count += index1 - pos1; - System.arraycopy(right, pos2, dst, count, index2 - pos2); - count += index2 - pos2; - } - - dst[0] = count; - return dst; - } - - } - - /** - * Subtraction class provides subtraction of two MultiRectAre aobjects - */ - static class Subtraction { - - static void subtractRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) { - Region d1 = new Region(reg1); - Region d2 = new Region(reg2); - - int[] level = new int[height1 + height2]; - int[] level1 = new int[height1]; - int[] level2 = new int[height2]; - d1.createLevel(level1); - d2.createLevel(level2); - Region.sortOrdered(level1, level2, level); - - int top; - int bottom = level[1] - 1; - for(int i = 2; i < level[0]; i++) { - - top = bottom + 1; - bottom = level[i] - 1; - - d1.findActive(top, bottom); - if (d1.active[0] == 1) { - d2.deleteActive(bottom); - continue; - } - - d2.findActive(top, bottom); - - int i1 = 1; - int i2 = 1; - - int rx1 = 0; - int rx2 = 0; - - boolean next = true; - - while(true) { - - if (next) { - next = false; - if (i1 >= d1.active[0]) { - break; - } - // Bottom - d1.active[i1 + 1] = bottom + 1; - rx1 = d1.active[i1]; - rx2 = d1.active[i1 + 2]; - i1 += 4; - } - - if (i2 >= d2.active[0]) { - dst.addRectCashed(rx1, top, rx2, bottom); - for(int j = i1; j < d1.active[0]; j += 4) { - dst.addRectCashed(d1.active[j], top, d1.active[j + 2], bottom); - d1.active[j + 1] = bottom + 1; - } - break; - } - - int x1 = d2.active[i2]; - int x2 = d2.active[i2 + 2]; - - if (rx1 < x1) { - if (rx2 >= x1) { - if (rx2 <= x2) { - // [-----------] - // [-------------] - dst.addRectCashed(rx1, top, x1 - 1, bottom); - next = true; - } else { - // [-----------------] - // [------] - dst.addRectCashed(rx1, top, x1 - 1, bottom); - rx1 = x2 + 1; - i2 += 4; - } - } else { - // [-----] - // [----] - dst.addRectCashed(rx1, top, rx2, bottom); - next = true; - } - } else { - if (rx1 <= x2) { - if (rx2 <= x2) { - // [------] - // [-----------] - next = true; - } else { - // [------------] - // [---------] - rx1 = x2 + 1; - i2 += 4; - } - } else { - // [----] - // [-----] - i2 += 4; - } - } - - } - d1.deleteActive(); - d2.deleteActive(bottom); - } - } - - static void subtractRect(int x11, int y11, int x12, int y12, int[] rect, int index, MultiRectArea dst) { - - for(int i = index; i < rect[0]; i += 4) { - int x21 = rect[i + 0]; - int y21 = rect[i + 1]; - int x22 = rect[i + 2]; - int y22 = rect[i + 3]; - - if (x11 <= x22 && x12 >= x21 && y11 <= y22 && y12 >= y21) { - int top, bottom; - if (y11 < y21) { - subtractRect(x11, y11, x12, y21 - 1, rect, i + 4, dst); - top = y21; - } else { - top = y11; - } - if (y12 > y22) { - subtractRect(x11, y22 + 1, x12, y12, rect, i + 4, dst); - bottom = y22; - } else { - bottom = y12; - } - if (x11 < x21) { - subtractRect(x11, top, x21 - 1, bottom, rect, i + 4, dst); - } - if (x12 > x22) { - subtractRect(x22 + 1, top, x12, bottom, rect, i + 4, dst); - } - return; - } - } - dst.addRect(x11, y11, x12, y12); - } - - static void simpleSubtract(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) { - for(int i = 1; i < src1.rect[0]; i += 4) { - subtractRect( - src1.rect[i + 0], - src1.rect[i + 1], - src1.rect[i + 2], - src1.rect[i + 3], - src2.rect, - 1, - dst); - } - dst.resort(); - } - - public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) { - - if (src1 == null || src1.isEmpty()) { - return new MultiRectArea(); - } - - if (src2 == null || src2.isEmpty()) { - return new MultiRectArea(src1); - } - - MultiRectArea.RectCash dst = new MultiRectArea.RectCash(); - - if (!src1.sorted || !src2.sorted || - src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) - { - simpleSubtract(src1, src2, dst); - } else { - Rectangle bounds1 = src1.getBounds(); - Rectangle bounds2 = src2.getBounds(); - Rectangle bounds3 = bounds1.intersection(bounds2); - - if (bounds3.width > 0 && bounds3.height > 0) { - subtractRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2); - } else { - dst.setRect(src1.rect, true); - } - } - - return dst; - } - - } - -} |