LMMS
Loading...
Searching...
No Matches
juce_RectangleList.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29//==============================================================================
41template <typename ValueType>
43{
44public:
46
47 //==============================================================================
49 RectangleList() = default;
50
52 RectangleList (const RectangleList& other) : rects (other.rects)
53 {
54 }
55
58 {
59 addWithoutMerging (rect);
60 }
61
63 RectangleList& operator= (const RectangleList& other)
64 {
65 rects = other.rects;
66 return *this;
67 }
68
71 : rects (std::move (other.rects))
72 {
73 }
74
76 RectangleList& operator= (RectangleList&& other) noexcept
77 {
78 rects = std::move (other.rects);
79 return *this;
80 }
81
82 //==============================================================================
84 bool isEmpty() const noexcept { return rects.isEmpty(); }
85
87 int getNumRectangles() const noexcept { return rects.size(); }
88
92 RectangleType getRectangle (int index) const noexcept { return rects[index]; }
93
94 //==============================================================================
96 void clear()
97 {
98 rects.clearQuick();
99 }
100
110 void add (RectangleType rect)
111 {
112 jassert (rect.isFinite()); // You must provide a valid rectangle to this method!
113
114 if (! rect.isEmpty())
115 {
116 if (isEmpty())
117 {
118 rects.add (rect);
119 }
120 else
121 {
122 bool anyOverlaps = false;
123
124 for (int j = rects.size(); --j >= 0;)
125 {
126 auto& ourRect = rects.getReference (j);
127
128 if (rect.intersects (ourRect))
129 {
130 if (rect.contains (ourRect))
131 rects.remove (j);
132 else if (! ourRect.reduceIfPartlyContainedIn (rect))
133 anyOverlaps = true;
134 }
135 }
136
137 if (anyOverlaps && ! isEmpty())
138 {
139 RectangleList r (rect);
140
141 for (auto& ourRect : rects)
142 {
143 if (rect.intersects (ourRect))
144 {
145 r.subtract (ourRect);
146
147 if (r.isEmpty())
148 return;
149 }
150 }
151
152 rects.addArray (r.rects);
153 }
154 else
155 {
156 rects.add (rect);
157 }
158 }
159 }
160 }
161
167 void add (ValueType x, ValueType y, ValueType width, ValueType height)
168 {
170 }
171
181 {
182 jassert (rect.isFinite()); // You must provide a valid rectangle to this method!
183
184 if (! rect.isEmpty())
185 rects.add (rect);
186 }
187
193 void add (const RectangleList& other)
194 {
195 for (auto& r : other)
196 add (r);
197 }
198
205 {
206 if (auto numRects = rects.size())
207 {
208 auto x1 = rect.getX();
209 auto y1 = rect.getY();
210 auto x2 = x1 + rect.getWidth();
211 auto y2 = y1 + rect.getHeight();
212
213 for (int i = numRects; --i >= 0;)
214 {
215 auto& r = rects.getReference (i);
216
217 auto rx1 = r.getX();
218 auto ry1 = r.getY();
219 auto rx2 = rx1 + r.getWidth();
220 auto ry2 = ry1 + r.getHeight();
221
222 if (! (x2 <= rx1 || x1 >= rx2 || y2 <= ry1 || y1 >= ry2))
223 {
224 if (x1 > rx1 && x1 < rx2)
225 {
226 if (y1 <= ry1 && y2 >= ry2 && x2 >= rx2)
227 {
228 r.setWidth (x1 - rx1);
229 }
230 else
231 {
232 r.setX (x1);
233 r.setWidth (rx2 - x1);
234
235 rects.insert (++i, RectangleType (rx1, ry1, x1 - rx1, ry2 - ry1));
236 ++i;
237 }
238 }
239 else if (x2 > rx1 && x2 < rx2)
240 {
241 r.setX (x2);
242 r.setWidth (rx2 - x2);
243
244 if (y1 > ry1 || y2 < ry2 || x1 > rx1)
245 {
246 rects.insert (++i, RectangleType (rx1, ry1, x2 - rx1, ry2 - ry1));
247 ++i;
248 }
249 }
250 else if (y1 > ry1 && y1 < ry2)
251 {
252 if (x1 <= rx1 && x2 >= rx2 && y2 >= ry2)
253 {
254 r.setHeight (y1 - ry1);
255 }
256 else
257 {
258 r.setY (y1);
259 r.setHeight (ry2 - y1);
260
261 rects.insert (++i, RectangleType (rx1, ry1, rx2 - rx1, y1 - ry1));
262 ++i;
263 }
264 }
265 else if (y2 > ry1 && y2 < ry2)
266 {
267 r.setY (y2);
268 r.setHeight (ry2 - y2);
269
270 if (x1 > rx1 || x2 < rx2 || y1 > ry1)
271 {
272 rects.insert (++i, RectangleType (rx1, ry1, rx2 - rx1, y2 - ry1));
273 ++i;
274 }
275 }
276 else
277 {
278 rects.remove (i);
279 }
280 }
281 }
282 }
283 }
284
292 bool subtract (const RectangleList& otherList)
293 {
294 for (auto& r : otherList)
295 {
296 if (isEmpty())
297 return false;
298
299 subtract (r);
300 }
301
302 return ! isEmpty();
303 }
304
315 {
316 jassert (rect.isFinite()); // You must provide a valid rectangle to this method!
317
318 bool notEmpty = false;
319
320 if (rect.isEmpty())
321 {
322 clear();
323 }
324 else
325 {
326 for (int i = rects.size(); --i >= 0;)
327 {
328 auto& r = rects.getReference (i);
329
330 if (! rect.intersectRectangle (r))
331 rects.remove (i);
332 else
333 notEmpty = true;
334 }
335 }
336
337 return notEmpty;
338 }
339
349 template <typename OtherValueType>
351 {
352 if (isEmpty())
353 return false;
354
356
357 for (auto& rect : rects)
358 {
359 for (auto& r : other)
360 {
361 auto clipped = r.template toType<ValueType>();
362
363 if (rect.intersectRectangle (clipped))
364 result.rects.add (clipped);
365 }
366 }
367
369 return ! isEmpty();
370 }
371
381 bool getIntersectionWith (RectangleType rect, RectangleList& destRegion) const
382 {
383 jassert (rect.isFinite()); // You must provide a valid rectangle to this method!
384
385 destRegion.clear();
386
387 if (! rect.isEmpty())
388 for (auto r : rects)
389 if (rect.intersectRectangle (r))
390 destRegion.rects.add (r);
391
392 return ! destRegion.isEmpty();
393 }
394
400 void swapWith (RectangleList& otherList) noexcept
401 {
402 rects.swapWith (otherList.rects);
403 }
404
405 //==============================================================================
409 bool containsPoint (Point<ValueType> point) const noexcept
410 {
411 for (auto& r : rects)
412 if (r.contains (point))
413 return true;
414
415 return false;
416 }
417
421 bool containsPoint (ValueType x, ValueType y) const noexcept
422 {
423 return containsPoint (Point<ValueType> (x, y));
424 }
425
432 bool containsRectangle (RectangleType rectangleToCheck) const
433 {
434 if (rects.size() > 1)
435 {
436 RectangleList r (rectangleToCheck);
437
438 for (auto& rect : rects)
439 {
440 r.subtract (rect);
441
442 if (r.isEmpty())
443 return true;
444 }
445 }
446 else if (! isEmpty())
447 {
448 return rects.getReference (0).contains (rectangleToCheck);
449 }
450
451 return false;
452 }
453
460 bool intersectsRectangle (RectangleType rectangleToCheck) const noexcept
461 {
462 for (auto& r : rects)
463 if (r.intersects (rectangleToCheck))
464 return true;
465
466 return false;
467 }
468
472 bool intersects (const RectangleList& other) const noexcept
473 {
474 for (auto& r : rects)
475 if (other.intersectsRectangle (r))
476 return true;
477
478 return false;
479 }
480
481 //==============================================================================
484 {
485 if (isEmpty())
486 return {};
487
488 auto& r = rects.getReference (0);
489
490 if (rects.size() == 1)
491 return r;
492
493 auto minX = r.getX();
494 auto minY = r.getY();
495 auto maxX = minX + r.getWidth();
496 auto maxY = minY + r.getHeight();
497
498 for (int i = rects.size(); --i > 0;)
499 {
500 auto& r2 = rects.getReference (i);
501
502 minX = jmin (minX, r2.getX());
503 minY = jmin (minY, r2.getY());
504 maxX = jmax (maxX, r2.getRight());
505 maxY = jmax (maxY, r2.getBottom());
506 }
507
508 return { minX, minY, maxX - minX, maxY - minY };
509 }
510
518 {
519 for (int i = 0; i < rects.size() - 1; ++i)
520 {
521 auto& r = rects.getReference (i);
522 auto rx1 = r.getX();
523 auto ry1 = r.getY();
524 auto rx2 = rx1 + r.getWidth();
525 auto ry2 = ry1 + r.getHeight();
526
527 for (int j = rects.size(); --j > i;)
528 {
529 auto& r2 = rects.getReference (j);
530 auto jrx1 = r2.getX();
531 auto jry1 = r2.getY();
532 auto jrx2 = jrx1 + r2.getWidth();
533 auto jry2 = jry1 + r2.getHeight();
534
535 // if the vertical edges of any blocks are touching and their horizontals don't
536 // line up, split them horizontally..
537 if (jrx1 == rx2 || jrx2 == rx1)
538 {
539 if (jry1 > ry1 && jry1 < ry2)
540 {
541 r.setHeight (jry1 - ry1);
542 rects.add (RectangleType (rx1, jry1, rx2 - rx1, ry2 - jry1));
543 i = -1;
544 break;
545 }
546
547 if (jry2 > ry1 && jry2 < ry2)
548 {
549 r.setHeight (jry2 - ry1);
550 rects.add (RectangleType (rx1, jry2, rx2 - rx1, ry2 - jry2));
551 i = -1;
552 break;
553 }
554 else if (ry1 > jry1 && ry1 < jry2)
555 {
556 r2.setHeight (ry1 - jry1);
557 rects.add (RectangleType (jrx1, ry1, jrx2 - jrx1, jry2 - ry1));
558 i = -1;
559 break;
560 }
561 else if (ry2 > jry1 && ry2 < jry2)
562 {
563 r2.setHeight (ry2 - jry1);
564 rects.add (RectangleType (jrx1, ry2, jrx2 - jrx1, jry2 - ry2));
565 i = -1;
566 break;
567 }
568 }
569 }
570 }
571
572 for (int i = 0; i < rects.size() - 1; ++i)
573 {
574 auto& r = rects.getReference (i);
575
576 for (int j = rects.size(); --j > i;)
577 {
578 if (r.enlargeIfAdjacent (rects.getReference (j)))
579 {
580 rects.remove (j);
581 i = -1;
582 break;
583 }
584 }
585 }
586 }
587
589 void offsetAll (Point<ValueType> offset) noexcept
590 {
591 for (auto& r : rects)
592 r += offset;
593 }
594
596 void offsetAll (ValueType dx, ValueType dy) noexcept
597 {
599 }
600
602 template <typename ScaleType>
603 void scaleAll (ScaleType scaleFactor) noexcept
604 {
605 for (auto& r : rects)
606 r *= scaleFactor;
607 }
608
613 void transformAll (const AffineTransform& transform) noexcept
614 {
615 for (auto& r : rects)
616 r = r.transformedBy (transform);
617 }
618
619 //==============================================================================
621 Path toPath() const
622 {
623 Path p;
624
625 for (auto& r : rects)
626 p.addRectangle (r);
627
628 return p;
629 }
630
631 //==============================================================================
633 const RectangleType* begin() const noexcept { return rects.begin(); }
635 const RectangleType* end() const noexcept { return rects.end(); }
636
643 void ensureStorageAllocated (int minNumRectangles)
644 {
645 rects.ensureStorageAllocated (minNumRectangles);
646 }
647
648private:
649 //==============================================================================
651};
652
653} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
#define noexcept
Definition DistrhoDefines.h:72
#define final
Definition DistrhoDefines.h:74
Definition juce_AffineTransform.h:43
Definition juce_Array.h:56
Definition juce_Path.h:65
Definition juce_Point.h:42
Definition juce_Rectangle.h:67
bool intersects(Rectangle other) const noexcept
Definition juce_Rectangle.h:641
bool contains(ValueType xCoord, ValueType yCoord) const noexcept
Definition juce_Rectangle.h:622
ValueType getHeight() const noexcept
Definition juce_Rectangle.h:136
ValueType getX() const noexcept
Definition juce_Rectangle.h:127
ValueType getWidth() const noexcept
Definition juce_Rectangle.h:133
bool isFinite() const noexcept
Definition juce_Rectangle.h:124
bool isEmpty() const noexcept
Definition juce_Rectangle.h:121
ValueType getY() const noexcept
Definition juce_Rectangle.h:130
bool intersectRectangle(ValueType &otherX, ValueType &otherY, ValueType &otherW, ValueType &otherH) const noexcept
Definition juce_Rectangle.h:685
bool containsPoint(ValueType x, ValueType y) const noexcept
Definition juce_RectangleList.h:421
RectangleType getRectangle(int index) const noexcept
Definition juce_RectangleList.h:92
bool clipTo(const RectangleList< OtherValueType > &other)
Definition juce_RectangleList.h:350
void clear()
Definition juce_RectangleList.h:96
RectangleType getBounds() const noexcept
Definition juce_RectangleList.h:483
void add(ValueType x, ValueType y, ValueType width, ValueType height)
Definition juce_RectangleList.h:167
RectangleList(RectangleList &&other) noexcept
Definition juce_RectangleList.h:70
void addWithoutMerging(RectangleType rect)
Definition juce_RectangleList.h:180
void subtract(RectangleType rect)
Definition juce_RectangleList.h:204
void offsetAll(ValueType dx, ValueType dy) noexcept
Definition juce_RectangleList.h:596
void add(const RectangleList &other)
Definition juce_RectangleList.h:193
Path toPath() const
Definition juce_RectangleList.h:621
bool subtract(const RectangleList &otherList)
Definition juce_RectangleList.h:292
void offsetAll(Point< ValueType > offset) noexcept
Definition juce_RectangleList.h:589
bool intersectsRectangle(RectangleType rectangleToCheck) const noexcept
Definition juce_RectangleList.h:460
bool containsRectangle(RectangleType rectangleToCheck) const
Definition juce_RectangleList.h:432
void scaleAll(ScaleType scaleFactor) noexcept
Definition juce_RectangleList.h:603
RectangleList()=default
bool intersects(const RectangleList &other) const noexcept
Definition juce_RectangleList.h:472
Rectangle< ValueType > RectangleType
Definition juce_RectangleList.h:45
bool clipTo(RectangleType rect)
Definition juce_RectangleList.h:314
const RectangleType * begin() const noexcept
Definition juce_RectangleList.h:633
bool containsPoint(Point< ValueType > point) const noexcept
Definition juce_RectangleList.h:409
const RectangleType * end() const noexcept
Definition juce_RectangleList.h:635
RectangleList(const RectangleList &other)
Definition juce_RectangleList.h:52
RectangleList(RectangleType rect)
Definition juce_RectangleList.h:57
void add(RectangleType rect)
Definition juce_RectangleList.h:110
int getNumRectangles() const noexcept
Definition juce_RectangleList.h:87
bool isEmpty() const noexcept
Definition juce_RectangleList.h:84
void swapWith(RectangleList &otherList) noexcept
Definition juce_RectangleList.h:400
void ensureStorageAllocated(int minNumRectangles)
Definition juce_RectangleList.h:643
void consolidate()
Definition juce_RectangleList.h:517
bool getIntersectionWith(RectangleType rect, RectangleList &destRegion) const
Definition juce_RectangleList.h:381
void transformAll(const AffineTransform &transform) noexcept
Definition juce_RectangleList.h:613
Array< RectangleType > rects
Definition juce_RectangleList.h:650
register unsigned j
Definition inflate.c:1576
int y
Definition inflate.c:1588
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
static void r2(register WDL_FFT_REAL *a)
Definition fft.c:1089
static int int minY
Definition pugl.h:1627
static int minX
Definition pugl.h:1626
static int int height
Definition pugl.h:1594
static int int int int maxY
Definition pugl.h:1630
static int width
Definition pugl.h:1593
static int int int maxX
Definition pugl.h:1628
#define jassert(expression)
Definition carla_juce.cpp:31
uch * p
Definition crypt.c:594
int r
Definition crypt.c:458
int result
Definition process.c:1455
dy
Definition zipinfo.c:2288
#define const
Definition zconf.h:137