LMMS
Loading...
Searching...
No Matches
juce_EdgeTable.cpp
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
30
32 : bounds (area),
33 // this is a very vague heuristic to make a rough guess at a good table size
34 // for a given path, such that it's big enough to mostly avoid remapping, but also
35 // not so big that it's wasteful for simple paths.
37 4 * (int) std::sqrt (path.data.size()))),
39{
40 allocate();
41 int* t = table;
42
43 for (int i = bounds.getHeight(); --i >= 0;)
44 {
45 *t = 0;
47 }
48
49 auto leftLimit = scale * bounds.getX();
50 auto topLimit = scale * bounds.getY();
51 auto rightLimit = scale * bounds.getRight();
52 auto heightLimit = scale * bounds.getHeight();
53
54 PathFlatteningIterator iter (path, transform);
55
56 while (iter.next())
57 {
58 auto y1 = roundToInt (iter.y1 * 256.0f);
59 auto y2 = roundToInt (iter.y2 * 256.0f);
60
61 if (y1 != y2)
62 {
63 y1 -= topLimit;
64 y2 -= topLimit;
65
66 auto startY = y1;
67 int direction = -1;
68
69 if (y1 > y2)
70 {
71 std::swap (y1, y2);
72 direction = 1;
73 }
74
75 if (y1 < 0)
76 y1 = 0;
77
78 if (y2 > heightLimit)
79 y2 = heightLimit;
80
81 if (y1 < y2)
82 {
83 const double startX = 256.0f * iter.x1;
84 const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1);
85 auto stepSize = jlimit (1, 256, 256 / (1 + (int) std::abs (multiplier)));
86
87 do
88 {
89 auto step = jmin (stepSize, y2 - y1, 256 - (y1 & 255));
90 auto x = roundToInt (startX + multiplier * ((y1 + (step >> 1)) - startY));
91
92 if (x < leftLimit)
93 x = leftLimit;
94 else if (x >= rightLimit)
95 x = rightLimit - 1;
96
97 addEdgePoint (x, y1 / scale, direction * step);
98 y1 += step;
99 }
100 while (y1 < y2);
101 }
102 }
103 }
104
105 sanitiseLevels (path.isUsingNonZeroWinding());
106}
107
109 : bounds (rectangleToAdd),
112{
113 allocate();
114 table[0] = 0;
115
116 auto x1 = scale * rectangleToAdd.getX();
117 auto x2 = scale * rectangleToAdd.getRight();
118 int* t = table;
119
120 for (int i = rectangleToAdd.getHeight(); --i >= 0;)
121 {
122 t[0] = 2;
123 t[1] = x1;
124 t[2] = 255;
125 t[3] = x2;
126 t[4] = 0;
128 }
129}
130
132 : bounds (rectanglesToAdd.getBounds()),
136{
137 allocate();
139
140 for (auto& r : rectanglesToAdd)
141 {
142 auto x1 = scale * r.getX();
143 auto x2 = scale * r.getRight();
144 auto y = r.getY() - bounds.getY();
145
146 for (int j = r.getHeight(); --j >= 0;)
147 addEdgePointPair (x1, x2, y++, 255);
148 }
149
150 sanitiseLevels (true);
151}
152
154 : bounds (rectanglesToAdd.getBounds().getSmallestIntegerContainer()),
155 maxEdgesPerLine (rectanglesToAdd.getNumRectangles() * 2),
156 lineStrideElements (rectanglesToAdd.getNumRectangles() * 4 + 1)
157{
158 bounds.setHeight (bounds.getHeight() + 1);
159 allocate();
161
162 for (auto& r : rectanglesToAdd)
163 {
164 auto x1 = roundToInt ((float) scale * r.getX());
165 auto x2 = roundToInt ((float) scale * r.getRight());
166
167 auto y1 = roundToInt ((float) scale * r.getY()) - (bounds.getY() * scale);
168 auto y2 = roundToInt ((float) scale * r.getBottom()) - (bounds.getY() * scale);
169
170 if (x2 <= x1 || y2 <= y1)
171 continue;
172
173 auto y = y1 / scale;
174 auto lastLine = y2 / scale;
175
176 if (y == lastLine)
177 {
178 addEdgePointPair (x1, x2, y, y2 - y1);
179 }
180 else
181 {
182 addEdgePointPair (x1, x2, y++, 255 - (y1 & 255));
183
184 while (y < lastLine)
185 addEdgePointPair (x1, x2, y++, 255);
186
187 jassert (y < bounds.getHeight());
188 addEdgePointPair (x1, x2, y, y2 & 255);
189 }
190 }
191
192 sanitiseLevels (true);
193}
194
196 : bounds ((int) std::floor (rectangleToAdd.getX()),
197 roundToInt (rectangleToAdd.getY() * 256.0f) / scale,
198 2 + (int) rectangleToAdd.getWidth(),
199 2 + (int) rectangleToAdd.getHeight()),
202{
203 jassert (! rectangleToAdd.isEmpty());
204 allocate();
205 table[0] = 0;
206
207 auto x1 = roundToInt ((float) scale * rectangleToAdd.getX());
208 auto x2 = roundToInt ((float) scale * rectangleToAdd.getRight());
209 auto y1 = roundToInt ((float) scale * rectangleToAdd.getY()) - (bounds.getY() * scale);
210 auto y2 = roundToInt ((float) scale * rectangleToAdd.getBottom()) - (bounds.getY() * scale);
211 jassert (y1 < 256);
212
213 if (x2 <= x1 || y2 <= y1)
214 {
215 bounds.setHeight (0);
216 return;
217 }
218
219 int lineY = 0;
220 int* t = table;
221
222 if ((y1 / scale) == (y2 / scale))
223 {
224 t[0] = 2;
225 t[1] = x1;
226 t[2] = y2 - y1;
227 t[3] = x2;
228 t[4] = 0;
229 ++lineY;
231 }
232 else
233 {
234 t[0] = 2;
235 t[1] = x1;
236 t[2] = 255 - (y1 & 255);
237 t[3] = x2;
238 t[4] = 0;
239 ++lineY;
241
242 while (lineY < (y2 / scale))
243 {
244 t[0] = 2;
245 t[1] = x1;
246 t[2] = 255;
247 t[3] = x2;
248 t[4] = 0;
249 ++lineY;
251 }
252
253 jassert (lineY < bounds.getHeight());
254 t[0] = 2;
255 t[1] = x1;
256 t[2] = y2 & 255;
257 t[3] = x2;
258 t[4] = 0;
259 ++lineY;
261 }
262
263 while (lineY < bounds.getHeight())
264 {
265 t[0] = 0;
267 ++lineY;
268 }
269}
270
272{
273 operator= (other);
274}
275
276EdgeTable& EdgeTable::operator= (const EdgeTable& other)
277{
278 bounds = other.bounds;
282
283 allocate();
285 return *this;
286}
287
291
292//==============================================================================
293static size_t getEdgeTableAllocationSize (int lineStride, int height) noexcept
294{
295 // (leave an extra line at the end for use as scratch space)
296 return (size_t) (lineStride * (2 + jmax (0, height)));
297}
298
303
305{
306 int* t = table;
307
308 for (int i = bounds.getHeight(); --i >= 0;)
309 {
310 *t = 0;
312 }
313}
314
315void EdgeTable::copyEdgeTableData (int* dest, int destLineStride, const int* src, int srcLineStride, int numLines) noexcept
316{
317 while (--numLines >= 0)
318 {
319 memcpy (dest, src, (size_t) (src[0] * 2 + 1) * sizeof (int));
320 src += srcLineStride;
321 dest += destLineStride;
322 }
323}
324
325void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept
326{
327 // Convert the table from relative windings to absolute levels..
328 int* lineStart = table;
329
330 for (int y = bounds.getHeight(); --y >= 0;)
331 {
332 auto num = lineStart[0];
333
334 if (num > 0)
335 {
336 auto* items = reinterpret_cast<LineItem*> (lineStart + 1);
337 auto* itemsEnd = items + num;
338
339 // sort the X coords
340 std::sort (items, itemsEnd);
341
342 auto* src = items;
343 auto correctedNum = num;
344 int level = 0;
345
346 while (src < itemsEnd)
347 {
348 level += src->level;
349 auto x = src->x;
350 ++src;
351
352 while (src < itemsEnd && src->x == x)
353 {
354 level += src->level;
355 ++src;
356 --correctedNum;
357 }
358
359 auto corrected = std::abs (level);
360
361 if (corrected / scale)
362 {
363 if (useNonZeroWinding)
364 {
365 corrected = 255;
366 }
367 else
368 {
369 corrected &= 511;
370
371 if (corrected / scale)
372 corrected = 511 - corrected;
373 }
374 }
375
376 items->x = x;
377 items->level = corrected;
378 ++items;
379 }
380
381 lineStart[0] = correctedNum;
382 (items - 1)->level = 0; // force the last level to 0, just in case something went wrong in creating the table
383 }
384
385 lineStart += lineStrideElements;
386 }
387}
388
389void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine)
390{
391 if (newNumEdgesPerLine != maxEdgesPerLine)
392 {
393 maxEdgesPerLine = newNumEdgesPerLine;
394
395 jassert (bounds.getHeight() > 0);
396 auto newLineStrideElements = maxEdgesPerLine * 2 + 1;
397
398 HeapBlock<int> newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight()));
399
400 copyEdgeTableData (newTable, newLineStrideElements, table, lineStrideElements, bounds.getHeight());
401
402 table.swapWith (newTable);
403 lineStrideElements = newLineStrideElements;
404 }
405}
406
407inline void EdgeTable::remapWithExtraSpace (int numPoints)
408{
409 remapTableForNumEdges (numPoints * 2);
410 jassert (numPoints < maxEdgesPerLine);
411}
412
414{
415 int maxLineElements = 0;
416
417 for (int i = bounds.getHeight(); --i >= 0;)
418 maxLineElements = jmax (maxLineElements, table[i * lineStrideElements]);
419
420 remapTableForNumEdges (maxLineElements);
421}
422
423void EdgeTable::addEdgePoint (const int x, const int y, const int winding)
424{
425 jassert (y >= 0 && y < bounds.getHeight());
426
427 auto* line = table + lineStrideElements * y;
428 auto numPoints = line[0];
429
430 if (numPoints >= maxEdgesPerLine)
431 {
432 remapWithExtraSpace (numPoints);
433 line = table + lineStrideElements * y;
434 }
435
436 line[0] = numPoints + 1;
437 line += numPoints * 2;
438 line[1] = x;
439 line[2] = winding;
440}
441
442void EdgeTable::addEdgePointPair (int x1, int x2, int y, int winding)
443{
444 jassert (y >= 0 && y < bounds.getHeight());
445
446 auto* line = table + lineStrideElements * y;
447 auto numPoints = line[0];
448
449 if (numPoints + 1 >= maxEdgesPerLine)
450 {
451 remapWithExtraSpace (numPoints + 1);
452 line = table + lineStrideElements * y;
453 }
454
455 line[0] = numPoints + 2;
456 line += numPoints * 2;
457 line[1] = x1;
458 line[2] = winding;
459 line[3] = x2;
460 line[4] = -winding;
461}
462
463void EdgeTable::translate (float dx, int dy) noexcept
464{
465 bounds.translate ((int) std::floor (dx), dy);
466
467 int* lineStart = table;
468 auto intDx = (int) (dx * 256.0f);
469
470 for (int i = bounds.getHeight(); --i >= 0;)
471 {
472 auto* line = lineStart;
473 lineStart += lineStrideElements;
474 auto num = *line++;
475
476 while (--num >= 0)
477 {
478 *line += intDx;
479 line += 2;
480 }
481 }
482}
483
484void EdgeTable::multiplyLevels (float amount)
485{
486 int* lineStart = table;
487 auto multiplier = (int) (amount * 256.0f);
488
489 for (int y = 0; y < bounds.getHeight(); ++y)
490 {
491 auto numPoints = lineStart[0];
492 auto* item = reinterpret_cast<LineItem*> (lineStart + 1);
493 lineStart += lineStrideElements;
494
495 while (--numPoints > 0)
496 {
497 item->level = jmin (255, (item->level * multiplier) / scale);
498 ++item;
499 }
500 }
501}
502
503void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherLine)
504{
505 jassert (y >= 0 && y < bounds.getHeight());
506
507 auto* srcLine = table + lineStrideElements * y;
508 auto srcNum1 = *srcLine;
509
510 if (srcNum1 == 0)
511 return;
512
513 auto srcNum2 = *otherLine;
514
515 if (srcNum2 == 0)
516 {
517 *srcLine = 0;
518 return;
519 }
520
521 auto right = bounds.getRight() * scale;
522
523 // optimise for the common case where our line lies entirely within a
524 // single pair of points, as happens when clipping to a simple rect.
525 if (srcNum2 == 2 && otherLine[2] >= 255)
526 {
527 clipEdgeTableLineToRange (srcLine, otherLine[1], jmin (right, otherLine[3]));
528 return;
529 }
530
531 bool isUsingTempSpace = false;
532
533 const int* src1 = srcLine + 1;
534 auto x1 = *src1++;
535
536 const int* src2 = otherLine + 1;
537 auto x2 = *src2++;
538
539 int destIndex = 0, destTotal = 0;
540 int level1 = 0, level2 = 0;
541 int lastX = std::numeric_limits<int>::min(), lastLevel = 0;
542
543 while (srcNum1 > 0 && srcNum2 > 0)
544 {
545 int nextX;
546
547 if (x1 <= x2)
548 {
549 if (x1 == x2)
550 {
551 level2 = *src2++;
552 x2 = *src2++;
553 --srcNum2;
554 }
555
556 nextX = x1;
557 level1 = *src1++;
558 x1 = *src1++;
559 --srcNum1;
560 }
561 else
562 {
563 nextX = x2;
564 level2 = *src2++;
565 x2 = *src2++;
566 --srcNum2;
567 }
568
569 if (nextX > lastX)
570 {
571 if (nextX >= right)
572 break;
573
574 lastX = nextX;
575
576 auto nextLevel = (level1 * (level2 + 1)) / scale;
577 jassert (isPositiveAndBelow (nextLevel, 256));
578
579 if (nextLevel != lastLevel)
580 {
581 if (destTotal >= maxEdgesPerLine)
582 {
583 srcLine[0] = destTotal;
584
585 if (isUsingTempSpace)
586 {
587 auto tempSize = (size_t) srcNum1 * 2 * sizeof (int);
588 auto oldTemp = static_cast<int*> (alloca (tempSize));
589 memcpy (oldTemp, src1, tempSize);
590
591 remapTableForNumEdges (jmax (256, destTotal * 2));
592 srcLine = table + lineStrideElements * y;
593
594 auto* newTemp = table + lineStrideElements * bounds.getHeight();
595 memcpy (newTemp, oldTemp, tempSize);
596 src1 = newTemp;
597 }
598 else
599 {
600 remapTableForNumEdges (jmax (256, destTotal * 2));
601 srcLine = table + lineStrideElements * y;
602 }
603 }
604
605 ++destTotal;
606 lastLevel = nextLevel;
607
608 if (! isUsingTempSpace)
609 {
610 isUsingTempSpace = true;
611 auto* temp = table + lineStrideElements * bounds.getHeight();
612 memcpy (temp, src1, (size_t) srcNum1 * 2 * sizeof (int));
613 src1 = temp;
614 }
615
616 srcLine[++destIndex] = nextX;
617 srcLine[++destIndex] = nextLevel;
618 }
619 }
620 }
621
622 if (lastLevel > 0)
623 {
624 if (destTotal >= maxEdgesPerLine)
625 {
626 srcLine[0] = destTotal;
627 remapTableForNumEdges (jmax (256, destTotal * 2));
628 srcLine = table + lineStrideElements * y;
629 }
630
631 ++destTotal;
632 srcLine[++destIndex] = right;
633 srcLine[++destIndex] = 0;
634 }
635
636 srcLine[0] = destTotal;
637}
638
639void EdgeTable::clipEdgeTableLineToRange (int* dest, const int x1, const int x2) noexcept
640{
641 int* lastItem = dest + (dest[0] * 2 - 1);
642
643 if (x2 < lastItem[0])
644 {
645 if (x2 <= dest[1])
646 {
647 dest[0] = 0;
648 return;
649 }
650
651 while (x2 < lastItem[-2])
652 {
653 --(dest[0]);
654 lastItem -= 2;
655 }
656
657 lastItem[0] = x2;
658 lastItem[1] = 0;
659 }
660
661 if (x1 > dest[1])
662 {
663 while (lastItem[0] > x1)
664 lastItem -= 2;
665
666 auto itemsRemoved = (int) (lastItem - (dest + 1)) / 2;
667
668 if (itemsRemoved > 0)
669 {
670 dest[0] -= itemsRemoved;
671 memmove (dest + 1, lastItem, (size_t) dest[0] * (sizeof (int) * 2));
672 }
673
674 dest[1] = x1;
675 }
676}
677
678
679//==============================================================================
681{
682 auto clipped = r.getIntersection (bounds);
683
684 if (clipped.isEmpty())
685 {
686 needToCheckEmptiness = false;
687 bounds.setHeight (0);
688 }
689 else
690 {
691 auto top = clipped.getY() - bounds.getY();
692 auto bottom = clipped.getBottom() - bounds.getY();
693
694 if (bottom < bounds.getHeight())
695 bounds.setHeight (bottom);
696
697 for (int i = 0; i < top; ++i)
699
700 if (clipped.getX() > bounds.getX() || clipped.getRight() < bounds.getRight())
701 {
702 auto x1 = scale * clipped.getX();
703 auto x2 = scale * jmin (bounds.getRight(), clipped.getRight());
704 int* line = table + lineStrideElements * top;
705
706 for (int i = bottom - top; --i >= 0;)
707 {
708 if (line[0] != 0)
709 clipEdgeTableLineToRange (line, x1, x2);
710
711 line += lineStrideElements;
712 }
713 }
714
716 }
717}
718
720{
721 auto clipped = r.getIntersection (bounds);
722
723 if (! clipped.isEmpty())
724 {
725 auto top = clipped.getY() - bounds.getY();
726 auto bottom = clipped.getBottom() - bounds.getY();
727
728 const int rectLine[] = { 4, std::numeric_limits<int>::min(), 255,
729 scale * clipped.getX(), 0,
730 scale * clipped.getRight(), 255,
731 std::numeric_limits<int>::max(), 0 };
732
733 for (int i = top; i < bottom; ++i)
734 intersectWithEdgeTableLine (i, rectLine);
735
737 }
738}
739
741{
742 auto clipped = other.bounds.getIntersection (bounds);
743
744 if (clipped.isEmpty())
745 {
746 needToCheckEmptiness = false;
747 bounds.setHeight (0);
748 }
749 else
750 {
751 auto top = clipped.getY() - bounds.getY();
752 auto bottom = clipped.getBottom() - bounds.getY();
753
754 if (bottom < bounds.getHeight())
755 bounds.setHeight (bottom);
756
757 if (clipped.getRight() < bounds.getRight())
758 bounds.setRight (clipped.getRight());
759
760 for (int i = 0; i < top; ++i)
762
763 auto* otherLine = other.table + other.lineStrideElements * (clipped.getY() - other.bounds.getY());
764
765 for (int i = top; i < bottom; ++i)
766 {
767 intersectWithEdgeTableLine (i, otherLine);
768 otherLine += other.lineStrideElements;
769 }
770
772 }
773}
774
775void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, int numPixels)
776{
777 y -= bounds.getY();
778
779 if (y < 0 || y >= bounds.getHeight())
780 return;
781
783
784 if (numPixels <= 0)
785 {
787 return;
788 }
789
790 auto* tempLine = static_cast<int*> (alloca ((size_t) (numPixels * 2 + 4) * sizeof (int)));
791 int destIndex = 0, lastLevel = 0;
792
793 while (--numPixels >= 0)
794 {
795 auto alpha = *mask;
796 mask += maskStride;
797
798 if (alpha != lastLevel)
799 {
800 tempLine[++destIndex] = (x * scale);
801 tempLine[++destIndex] = alpha;
802 lastLevel = alpha;
803 }
804
805 ++x;
806 }
807
808 if (lastLevel > 0)
809 {
810 tempLine[++destIndex] = (x * scale);
811 tempLine[++destIndex] = 0;
812 }
813
814 tempLine[0] = destIndex >> 1;
815
816 intersectWithEdgeTableLine (y, tempLine);
817}
818
820{
822 {
823 needToCheckEmptiness = false;
824 int* t = table;
825
826 for (int i = bounds.getHeight(); --i >= 0;)
827 {
828 if (t[0] > 1)
829 return false;
830
832 }
833
834 bounds.setHeight (0);
835 }
836
837 return bounds.getHeight() == 0;
838}
839
841
842} // 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
static const unsigned long mask[]
Definition bitwise.c:31
Definition juce_AffineTransform.h:43
bool isEmpty() noexcept
Definition juce_EdgeTable.cpp:819
~EdgeTable()
Definition juce_EdgeTable.cpp:288
int maxEdgesPerLine
Definition juce_EdgeTable.h:209
static constexpr auto defaultEdgesPerLine
Definition juce_EdgeTable.h:195
static constexpr auto scale
Definition juce_EdgeTable.h:196
EdgeTable(Rectangle< int > clipLimits, const Path &pathToAdd, const AffineTransform &transform)
Definition juce_EdgeTable.cpp:31
void excludeRectangle(Rectangle< int > r)
Definition juce_EdgeTable.cpp:719
HeapBlock< int > table
Definition juce_EdgeTable.h:207
void optimiseTable()
Definition juce_EdgeTable.cpp:413
void clipToEdgeTable(const EdgeTable &)
Definition juce_EdgeTable.cpp:740
void multiplyLevels(float factor)
Definition juce_EdgeTable.cpp:484
void clipLineToMask(int x, int y, const uint8 *mask, int maskStride, int numPixels)
Definition juce_EdgeTable.cpp:775
void translate(float dx, int dy) noexcept
Definition juce_EdgeTable.cpp:463
void remapTableForNumEdges(int newNumEdgesPerLine)
Definition juce_EdgeTable.cpp:389
bool needToCheckEmptiness
Definition juce_EdgeTable.h:210
void clearLineSizes() noexcept
Definition juce_EdgeTable.cpp:304
static void copyEdgeTableData(int *dest, int destLineStride, const int *src, int srcLineStride, int numLines) noexcept
Definition juce_EdgeTable.cpp:315
void remapWithExtraSpace(int numPointsNeeded)
Definition juce_EdgeTable.cpp:407
int lineStrideElements
Definition juce_EdgeTable.h:209
void intersectWithEdgeTableLine(int y, const int *otherLine)
Definition juce_EdgeTable.cpp:503
void clipToRectangle(Rectangle< int > r)
Definition juce_EdgeTable.cpp:680
void allocate()
Definition juce_EdgeTable.cpp:299
Rectangle< int > bounds
Definition juce_EdgeTable.h:208
void sanitiseLevels(bool useNonZeroWinding) noexcept
Definition juce_EdgeTable.cpp:325
void addEdgePointPair(int x1, int x2, int y, int winding)
Definition juce_EdgeTable.cpp:442
void clipEdgeTableLineToRange(int *line, int x1, int x2) noexcept
Definition juce_EdgeTable.cpp:639
void addEdgePoint(int x, int y, int winding)
Definition juce_EdgeTable.cpp:423
Definition juce_HeapBlock.h:87
Definition juce_PathIterator.h:42
bool next()
Definition juce_PathIterator.cpp:60
float y2
Definition juce_PathIterator.h:76
float x2
Definition juce_PathIterator.h:75
float y1
Definition juce_PathIterator.h:74
float x1
Definition juce_PathIterator.h:73
Definition juce_Path.h:65
Definition juce_Rectangle.h:67
ValueType getRight() const noexcept
Definition juce_Rectangle.h:139
Rectangle getIntersection(Rectangle other) const noexcept
Definition juce_Rectangle.h:664
ValueType getHeight() const noexcept
Definition juce_Rectangle.h:136
ValueType getBottom() const noexcept
Definition juce_Rectangle.h:142
ValueType getX() const noexcept
Definition juce_Rectangle.h:127
bool isEmpty() const noexcept
Definition juce_Rectangle.h:121
ValueType getY() const noexcept
Definition juce_Rectangle.h:130
Definition juce_RectangleList.h:43
struct huft * t
Definition inflate.c:943
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
struct @113205115357366127300225113341150224053346037032::@137033172036070230260373056156374243321245367362 right
static int int height
Definition pugl.h:1594
JSAMPIMAGE data
Definition jpeglib.h:945
#define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)
Definition juce_CompilerWarnings.h:198
#define JUCE_END_IGNORE_WARNINGS_MSVC
Definition juce_CompilerWarnings.h:199
#define jassert(expression)
Definition carla_juce.cpp:31
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
constexpr Type jmax(Type a, Type b)
Definition juce_MathsFunctions.h:94
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
static size_t getEdgeTableAllocationSize(int lineStride, int height) noexcept
Definition juce_EdgeTable.cpp:293
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Definition juce_MathsFunctions.h:279
unsigned char uint8
Definition juce_MathsFunctions.h:37
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
Definition juce_Uuid.h:141
#define true
Definition ordinals.h:82
Definition juce_EdgeTable.h:201
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
ulg size
Definition extract.c:2350
typedef int(UZ_EXP MsgFn)()
dy
Definition zipinfo.c:2288
#define const
Definition zconf.h:137