19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this work for additional information regarding copyright ownership. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (the "License"); you may not use this file except in compliance with 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @author Denis M. Kishenko 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @version $Revision$ 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage org.apache.harmony.awt.gl; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.Rectangle; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MultiRectAreaOp { 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Rectangle buffer capacity 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RECT_CAPACITY = 16; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If number of rectangle in MultiRectArea object less than MAX_SIMPLE simple algorithm applies 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SIMPLE = 8; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create buffer 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int[] createBuf(int capacity) { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (capacity == 0) { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project capacity = RECT_CAPACITY; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] buf = new int[capacity]; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[0] = 1; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return buf; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Checks buffer size and reallocate if necessary 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int[] checkBufSize(int[] buf, int capacity) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (buf[0] + capacity >= buf.length) { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = buf[0] + (capacity > RECT_CAPACITY ? capacity : RECT_CAPACITY); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] tmp = new int[length]; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(buf, 0, tmp, 0, buf[0]); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = tmp; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[0] += capacity; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return buf; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Region class provides basic functionlity for MultiRectArea objects to make logical operations 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class Region { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] region; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] active; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] bottom; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Region(int[] region) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.region = region; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project active = new int[RECT_CAPACITY]; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = new int[RECT_CAPACITY]; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project active[0] = 1; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom[0] = 1; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = 1; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addActive(int index) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = active[0]; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project active = checkBufSize(active, 4); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 1; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i < length) { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (region[index] < active[i]) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Insert 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(active, i, active, i + 4, length - i); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = i; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i += 4; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(region, index, active, length, 4); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void findActive(int top, int bottom) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(index < region[0]) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (region[index + 1] > bottom) { // y1 > bottom 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (region[index + 3] >= top) { // y2 >= top 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addActive(index); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 4; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void deleteActive(int bottom) { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = active[0]; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 1; i < length;) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (active[i + 3] == bottom) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length -= 4; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i < length) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(active, i + 4, active, i, length - i); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i += 4; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project active[0] = length; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void deleteActive() { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = active[0]; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = length - 4; i > 0; i -= 4) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (active[i + 1] > active[i + 3]) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length -= 4; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i < length) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(active, i + 4, active, i, length - i); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project active[0] = length; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void createLevel(int[] level) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int levelCount = 1; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topIndex = 1; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 1; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i < region[0]) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top = region[i + 1]; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottom = region[i + 3] + 1; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int j = topIndex; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addTop: { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(j < levelCount) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (level[j] == top) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break addTop; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (level[j] > top) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(level, j, level, j + 1, levelCount - j); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j++; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project level[j] = top; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project levelCount++; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project topIndex = j; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addBottom: { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(j < levelCount) { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (level[j] == bottom) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break addBottom; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (level[j] > bottom) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(level, j, level, j + 1, levelCount - j); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j++; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project level[j] = bottom; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project levelCount++; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i += 4; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project level[0] = levelCount; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void sortOrdered(int[] src1, int[] src2, int[] dst) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length1 = src1[0]; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length2 = src2[0]; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = 1; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i1 = 1; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i2 = 1; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int v1 = src1[1]; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int v2 = src2[1]; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(true) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LEFT: { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i1 < length1) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v1 = src1[i1]; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v1 >= v2) { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break LEFT; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[count++] = v1; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1++; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i2 < length2) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[count++] = src2[i2++]; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[0] = count; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RIGHT: { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i2 < length2) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v2 = src2[i2]; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v2 >= v1) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break RIGHT; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[count++] = v2; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2++; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i1 < length1) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[count++] = src1[i1++]; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[0] = count; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v1 == v2) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[count++] = v1; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1++; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2++; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i1 < length1) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v1 = src1[i1]; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i2 < length2 - 1) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v2 = src2[i2]; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // UNREACHABLE 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Intersection class provides intersection of two MultiRectAre aobjects 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class Intersection { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void intersectRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region d1 = new Region(reg1); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region d2 = new Region(reg2); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level = new int[height1 + height2]; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level1 = new int[height1]; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level2 = new int[height2]; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.createLevel(level1); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.createLevel(level2); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region.sortOrdered(level1, level2, level); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottom = level[1] - 1; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 2; i < level[0]; i++) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project top = bottom + 1; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = level[i] - 1; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.findActive(top, bottom); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.findActive(top, bottom); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i1 = 1; 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i2 = 1; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i1 < d1.active[0] && i2 < d2.active[0]) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x11 = d1.active[i1]; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x12 = d1.active[i1 + 2]; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x21 = d2.active[i2]; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x22 = d2.active[i2 + 2]; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x11 <= x21) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x12 >= x21) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x12 <= x22) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x21, top, x12, bottom); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x21, top, x22, bottom); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x22 >= x11) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x22 <= x12) { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x11, top, x22, bottom); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x11, top, x12, bottom); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.deleteActive(bottom); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.deleteActive(bottom); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int[] simpleIntersect(MultiRectArea src1, MultiRectArea src2) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] rect1 = src1.rect; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] rect2 = src2.rect; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] rect = createBuf(0); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int k = 1; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 1; i < rect1[0];) { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x11 = rect1[i++]; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y11 = rect1[i++]; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x12 = rect1[i++]; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y12 = rect1[i++]; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int j = 1; j < rect2[0];) { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x21 = rect2[j++]; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y21 = rect2[j++]; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x22 = rect2[j++]; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y22 = rect2[j++]; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x11 <= x22 && x12 >= x21 && 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y11 <= y22 && y12 >= y21) 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect = checkBufSize(rect, 4); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect[k++] = x11 > x21 ? x11 : x21; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect[k++] = y11 > y21 ? y11 : y21; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect[k++] = x12 > x22 ? x22 : x12; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect[k++] = y12 > y22 ? y22 : y12; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rect[0] = k; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rect; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) { 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (src1 == null || src2 == null || src1.isEmpty() || src2.isEmpty()) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MultiRectArea(); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MultiRectArea.RectCash dst = new MultiRectArea.RectCash(); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!src1.sorted || !src2.sorted || 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.setRect(simpleIntersect(src1, src2), false); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds1 = src1.getBounds(); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds2 = src2.getBounds(); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds3 = bounds1.intersection(bounds2); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds3.width > 0 && bounds3.height > 0) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intersectRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dst; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Union class provides union of two MultiRectAre aobjects 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class Union { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rx1, rx2; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top, bottom; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MultiRectArea.RectCash dst; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean next(Region d, int index) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x1 = d.active[index]; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x2 = d.active[index + 2]; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean res = false; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x2 < rx1 - 1) { 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res = true; 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x1, top, x2, bottom); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x1 > rx2 + 1) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res = false; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, rx2, bottom); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = x1; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx2 = x2; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res = x2 <= rx2; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = Math.min(x1, rx1); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx2 = Math.max(x2, rx2); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Top 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d.active[index + 1] < top) { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x1, d.active[index + 1], x2, top - 1); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bottom 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d.active[index + 3] > bottom) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.active[index + 1] = bottom + 1; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void check(Region d, int index, boolean t) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x1 = d.active[index]; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x2 = d.active[index + 2]; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Top 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d.active[index + 1] < top) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x1, d.active[index + 1], x2, top - 1); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(x1, top, x2, bottom); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bottom 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d.active[index + 3] > bottom) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d.active[index + 1] = bottom + 1; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void unionRegions(int[] reg1, int[] reg2, int height1, int height2) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region d1 = new Region(reg1); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region d2 = new Region(reg2); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level = new int[height1 + height2]; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level1 = new int[height1]; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level2 = new int[height2]; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.createLevel(level1); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.createLevel(level2); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region.sortOrdered(level1, level2, level); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = level[1] - 1; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 2; i < level[0]; i++) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project top = bottom + 1; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = level[i] - 1; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.findActive(top, bottom); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.findActive(top, bottom); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i1 = 1; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i2 = 1; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean res1, res2; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d1.active[0] > 1) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project check(d1, 1, false); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = d1.active[1]; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx2 = d1.active[3]; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res1 = false; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res2 = true; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d2.active[0] > 1) { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project check(d2, 1, false); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = d2.active[1]; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx2 = d2.active[3]; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res1 = true; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res2 = false; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outer: 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(true) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (res1) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i1 >= d1.active[0]) { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, rx2, bottom); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i2 < d2.active[0]) { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project check(d2, i2, true); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break outer; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res1 = next(d1, i1); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (res2) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i2 >= d2.active[0]) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, rx2, bottom); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(i1 < d1.active[0]) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project check(d1, i1, true); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break outer; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res2 = next(d2, i2); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res1 = true; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res2 = true; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } // while 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.deleteActive(bottom); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.deleteActive(bottom); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void simpleUnion(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (src1.getRectCount() < src2.getRectCount()) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project simpleUnion(src2, src1, dst); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Subtraction.simpleSubtract(src1, src2, dst); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos = dst.rect[0]; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = src2.rect[0] - 1; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.rect = checkBufSize(dst.rect, size); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(src2.rect,1, dst.rect, pos, size); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.resort(); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (src1 == null || src1.isEmpty()) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MultiRectArea(src2); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (src2 == null || src2.isEmpty()) { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MultiRectArea(src1); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst = new MultiRectArea.RectCash(); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!src1.sorted || !src2.sorted || 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project simpleUnion(src1, src2, dst); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds1 = src1.getBounds(); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds2 = src2.getBounds(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds3 = bounds1.intersection(bounds2); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds3.width < 0 || bounds3.height < 0) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds1.y + bounds1.height < bounds2.y) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.setRect(addVerRegion(src1.rect, src2.rect), false); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds2.y + bounds2.height < bounds1.y) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.setRect(addVerRegion(src2.rect, src1.rect), false); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds1.x < bounds2.x) { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.setRect(addHorRegion(src1.rect, src2.rect), false); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.setRect(addHorRegion(src2.rect, src1.rect), false); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unionRegions(src1.rect, src2.rect, bounds1.height + 2, bounds2.height + 2); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dst; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] addVerRegion(int[] top, int[] bottom) { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = top[0] + bottom[0] - 1; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] dst = new int[length]; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[0] = length; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(top, 1, dst, 1, top[0] - 1); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(bottom, 1, dst, top[0], bottom[0] - 1); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dst; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] addHorRegion(int[] left, int[] right) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count1 = left[0]; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count2 = right[0]; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] dst = new int[count1 + count2 + 1]; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = 1; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index1 = 1; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index2 = 1; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top1 = left[2]; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top2 = right[2]; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int pos1, pos2; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(true) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index1 >= count1) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(right, index2, dst, count, count2 - index2); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += count2 - index2; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index2 >= count2) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(left, index1, dst, count, count1 - index1); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += count1 - index1; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (top1 < top2) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos1 = index1; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index1 += 4; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (index1 < count1 && (top1 = left[index1 + 1]) < top2); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(left, pos1, dst, count, index1 - pos1); 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += index1 - pos1; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (top1 > top2) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos2 = index2; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index2 += 4; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (index2 < count2 && (top2 = right[index2 + 1]) < top1); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(right, pos2, dst, count, index2 - pos2); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += index2 - pos2; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top = top1; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos1 = index1; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos2 = index2; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index1 += 4; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while(index1 < count1 && (top1 = left[index1 + 1]) == top); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index2 += 4; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while(index2 < count2 && (top2 = right[index2 + 1]) == top); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(left, pos1, dst, count, index1 - pos1); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += index1 - pos1; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(right, pos2, dst, count, index2 - pos2); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count += index2 - pos2; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst[0] = count; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dst; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Subtraction class provides subtraction of two MultiRectAre aobjects 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class Subtraction { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void subtractRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region d1 = new Region(reg1); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region d2 = new Region(reg2); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level = new int[height1 + height2]; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level1 = new int[height1]; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] level2 = new int[height2]; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.createLevel(level1); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.createLevel(level2); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Region.sortOrdered(level1, level2, level); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottom = level[1] - 1; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 2; i < level[0]; i++) { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project top = bottom + 1; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = level[i] - 1; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.findActive(top, bottom); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (d1.active[0] == 1) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.deleteActive(bottom); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.findActive(top, bottom); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i1 = 1; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i2 = 1; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rx1 = 0; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rx2 = 0; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean next = true; 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while(true) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (next) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = false; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i1 >= d1.active[0]) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bottom 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.active[i1 + 1] = bottom + 1; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = d1.active[i1]; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx2 = d1.active[i1 + 2]; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i1 += 4; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i2 >= d2.active[0]) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, rx2, bottom); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int j = i1; j < d1.active[0]; j += 4) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(d1.active[j], top, d1.active[j + 2], bottom); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.active[j + 1] = bottom + 1; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x1 = d2.active[i2]; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x2 = d2.active[i2 + 2]; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rx1 < x1) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rx2 >= x1) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rx2 <= x2) { 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [-----------] 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [-------------] 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, x1 - 1, bottom); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = true; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [-----------------] 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [------] 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, x1 - 1, bottom); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = x2 + 1; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [-----] 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [----] 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRectCashed(rx1, top, rx2, bottom); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = true; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rx1 <= x2) { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rx2 <= x2) { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [------] 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [-----------] 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = true; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [------------] 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [---------] 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rx1 = x2 + 1; 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [----] 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [-----] 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i2 += 4; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d1.deleteActive(); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project d2.deleteActive(bottom); 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void subtractRect(int x11, int y11, int x12, int y12, int[] rect, int index, MultiRectArea dst) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = index; i < rect[0]; i += 4) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x21 = rect[i + 0]; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y21 = rect[i + 1]; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x22 = rect[i + 2]; 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y22 = rect[i + 3]; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x11 <= x22 && x12 >= x21 && y11 <= y22 && y12 >= y21) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int top, bottom; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y11 < y21) { 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project subtractRect(x11, y11, x12, y21 - 1, rect, i + 4, dst); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project top = y21; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project top = y11; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y12 > y22) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project subtractRect(x11, y22 + 1, x12, y12, rect, i + 4, dst); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = y22; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottom = y12; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x11 < x21) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project subtractRect(x11, top, x21 - 1, bottom, rect, i + 4, dst); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x12 > x22) { 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project subtractRect(x22 + 1, top, x12, bottom, rect, i + 4, dst); 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.addRect(x11, y11, x12, y12); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void simpleSubtract(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for(int i = 1; i < src1.rect[0]; i += 4) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project subtractRect( 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.rect[i + 0], 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.rect[i + 1], 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.rect[i + 2], 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.rect[i + 3], 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src2.rect, 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1, 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.resort(); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) { 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (src1 == null || src1.isEmpty()) { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MultiRectArea(); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (src2 == null || src2.isEmpty()) { 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MultiRectArea(src1); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MultiRectArea.RectCash dst = new MultiRectArea.RectCash(); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!src1.sorted || !src2.sorted || 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project simpleSubtract(src1, src2, dst); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds1 = src1.getBounds(); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds2 = src2.getBounds(); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rectangle bounds3 = bounds1.intersection(bounds2); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bounds3.width > 0 && bounds3.height > 0) { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project subtractRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dst.setRect(src1.rect, true); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dst; 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 838