1 package com.atlassian.selenium.visualcomparison.utils;
2
3 import com.atlassian.annotations.Internal;
4
5 import java.util.ArrayList;
6 import java.util.List;
7
8 @Internal
9 public class BoundingBox
10 {
11 private int left;
12 private int top;
13 private int right;
14 private int bottom;
15
16 private int leftMargin;
17 private int topMargin;
18 private int rightMargin;
19 private int bottomMargin;
20 private static final int MARGIN = 25;
21
22 public BoundingBox(int x, int y)
23 {
24 this(x, y, x, y);
25 }
26
27 public BoundingBox(int left, int top, int right, int bottom)
28 {
29 setLeft(left);
30 setTop(top);
31 setRight(right);
32 setBottom(bottom);
33 }
34
35
36
37 private void setLeft(int left)
38 {
39 this.left = left;
40 this.leftMargin = left - MARGIN;
41 }
42
43 private void setRight(int right)
44 {
45 this.right = right;
46 this.rightMargin = right + MARGIN;
47 }
48
49 private void setTop(int top)
50 {
51 this.top = top;
52 this.topMargin = top - MARGIN;
53 }
54
55 private void setBottom(int bottom)
56 {
57 this.bottom = bottom;
58 this.bottomMargin = bottom + MARGIN;
59 }
60
61 public int getLeft()
62 {
63 return left;
64 }
65
66 public int getTop()
67 {
68 return top;
69 }
70
71 public int getRight()
72 {
73 return right;
74 }
75
76 public int getBottom()
77 {
78 return bottom;
79 }
80
81 public int getWidth()
82 {
83 return right - left + 1;
84 }
85
86 public int getHeight()
87 {
88 return bottom - top + 1;
89 }
90
91
92 public int getMarginLeft()
93 {
94 return Math.max(left - MARGIN, 0);
95 }
96
97 public int getMarginTop()
98 {
99 return Math.max(top - MARGIN, 0);
100 }
101
102 public int getMarginRight(int maxX)
103 {
104 return Math.min(right + MARGIN, maxX);
105 }
106
107 public int getMarginBottom(int maxY)
108 {
109 return Math.min(bottom + MARGIN, maxY);
110 }
111
112 public int getMarginWidth(int maxX)
113 {
114 return getMarginRight(maxX) - getMarginLeft() + 1;
115 }
116
117 public int getMarginHeight(int maxY)
118 {
119 return getMarginBottom(maxY) - getMarginTop() + 1;
120 }
121
122 public boolean contains (int x, int y)
123 {
124
125 return ((x >= left) && (x <= right) &&
126 (y >= top) && (y <= bottom));
127 }
128
129 public boolean isNear(int x, int y)
130 {
131
132 return ((x >= leftMargin) && (x <= rightMargin) &&
133 (y >= topMargin) && (y <= bottomMargin));
134 }
135
136 public boolean isNear(BoundingBox box)
137 {
138
139
140 return (box.isNear(left, top) || box.isNear(right, top) ||
141 box.isNear(left, bottom) || box.isNear(right, bottom) ||
142 isNear(box.left, box.top) || isNear(box.right, box.top) ||
143 isNear(box.left, box.bottom) || isNear(box.right, box.bottom));
144 }
145
146 public void merge(int x, int y)
147 {
148
149 if (x < left)
150 {
151 setLeft(x);
152 }
153 if (x > right)
154 {
155 setRight(x);
156 }
157 if (y < top)
158 {
159 setTop(y);
160 }
161 if (y > bottom)
162 {
163 setBottom(y);
164 }
165 }
166
167 public void merge(BoundingBox box)
168 {
169
170 merge(box.left, box.top);
171 merge(box.right, box.bottom);
172 }
173
174 public static void mergeOverlappingBoxes(ArrayList<BoundingBox> boxes)
175 {
176
177
178
179
180
181
182 boolean mergePerformedThisLoop;
183 do
184 {
185 mergePerformedThisLoop = false;
186 for (int iCurrent = 0; iCurrent < boxes.size(); iCurrent++)
187 {
188 BoundingBox current = boxes.get(iCurrent);
189 for (int iOther = iCurrent + 1; iOther < boxes.size();)
190 {
191 if (current.isNear(boxes.get(iOther)))
192 {
193 current.merge(boxes.get(iOther));
194 boxes.remove(iOther);
195 mergePerformedThisLoop = true;
196 }
197 else
198 {
199 iOther++;
200 }
201 }
202 }
203 }
204 while (mergePerformedThisLoop);
205 }
206
207 public static void deleteSingleLineBoxes(List<BoundingBox> boxes)
208 {
209
210 for (int i = 0; i < boxes.size(); )
211 {
212 BoundingBox box = boxes.get(i);
213 if (box.getWidth() == 1 || box.getHeight() == 1)
214 {
215 boxes.remove(i);
216 }
217 else
218 {
219 i++;
220 }
221 }
222 }
223 }