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