LMMS
Loading...
Searching...
No Matches
juce_PathStrokeType.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 : thickness (strokeThickness), jointStyle (mitered), endStyle (butt)
31{
32}
33
35 : thickness (strokeThickness), jointStyle (joint), endStyle (end)
36{
37}
38
40 : thickness (other.thickness),
41 jointStyle (other.jointStyle),
42 endStyle (other.endStyle)
43{
44}
45
46PathStrokeType& PathStrokeType::operator= (const PathStrokeType& other) noexcept
47{
48 thickness = other.thickness;
49 jointStyle = other.jointStyle;
50 endStyle = other.endStyle;
51 return *this;
52}
53
57
58bool PathStrokeType::operator== (const PathStrokeType& other) const noexcept
59{
60 return thickness == other.thickness
61 && jointStyle == other.jointStyle
62 && endStyle == other.endStyle;
63}
64
65bool PathStrokeType::operator!= (const PathStrokeType& other) const noexcept
66{
67 return ! operator== (other);
68}
69
70//==============================================================================
72{
73 static bool lineIntersection (const float x1, const float y1,
74 const float x2, const float y2,
75 const float x3, const float y3,
76 const float x4, const float y4,
77 float& intersectionX,
78 float& intersectionY,
79 float& distanceBeyondLine1EndSquared) noexcept
80 {
81 if (x2 != x3 || y2 != y3)
82 {
83 auto dx1 = x2 - x1;
84 auto dy1 = y2 - y1;
85 auto dx2 = x4 - x3;
86 auto dy2 = y4 - y3;
87 auto divisor = dx1 * dy2 - dx2 * dy1;
88
89 if (divisor == 0.0f)
90 {
91 if (! ((dx1 == 0.0f && dy1 == 0.0f) || (dx2 == 0.0f && dy2 == 0.0f)))
92 {
93 if (dy1 == 0.0f && dy2 != 0.0f)
94 {
95 auto along = (y1 - y3) / dy2;
96 intersectionX = x3 + along * dx2;
97 intersectionY = y1;
98
99 distanceBeyondLine1EndSquared = intersectionX - x2;
100 distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
101 if ((x2 > x1) == (intersectionX < x2))
102 distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
103
104 return along >= 0 && along <= 1.0f;
105 }
106
107 if (dy2 == 0.0f && dy1 != 0.0f)
108 {
109 auto along = (y3 - y1) / dy1;
110 intersectionX = x1 + along * dx1;
111 intersectionY = y3;
112
113 distanceBeyondLine1EndSquared = (along - 1.0f) * dx1;
114 distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
115 if (along < 1.0f)
116 distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
117
118 return along >= 0 && along <= 1.0f;
119 }
120
121 if (dx1 == 0.0f && dx2 != 0.0f)
122 {
123 auto along = (x1 - x3) / dx2;
124 intersectionX = x1;
125 intersectionY = y3 + along * dy2;
126
127 distanceBeyondLine1EndSquared = intersectionY - y2;
128 distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
129
130 if ((y2 > y1) == (intersectionY < y2))
131 distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
132
133 return along >= 0 && along <= 1.0f;
134 }
135
136 if (dx2 == 0.0f && dx1 != 0.0f)
137 {
138 auto along = (x3 - x1) / dx1;
139 intersectionX = x3;
140 intersectionY = y1 + along * dy1;
141
142 distanceBeyondLine1EndSquared = (along - 1.0f) * dy1;
143 distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
144 if (along < 1.0f)
145 distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
146
147 return along >= 0 && along <= 1.0f;
148 }
149 }
150
151 intersectionX = 0.5f * (x2 + x3);
152 intersectionY = 0.5f * (y2 + y3);
153
154 distanceBeyondLine1EndSquared = 0.0f;
155 return false;
156 }
157
158 auto along1 = ((y1 - y3) * dx2 - (x1 - x3) * dy2) / divisor;
159
160 intersectionX = x1 + along1 * dx1;
161 intersectionY = y1 + along1 * dy1;
162
163 if (along1 >= 0 && along1 <= 1.0f)
164 {
165 auto along2 = ((y1 - y3) * dx1 - (x1 - x3) * dy1) / divisor;
166
167 if (along2 >= 0 && along2 <= 1.0f)
168 {
169 distanceBeyondLine1EndSquared = 0.0f;
170 return true;
171 }
172 }
173
174 distanceBeyondLine1EndSquared = along1 - 1.0f;
175 distanceBeyondLine1EndSquared *= distanceBeyondLine1EndSquared;
176 distanceBeyondLine1EndSquared *= (dx1 * dx1 + dy1 * dy1);
177
178 if (along1 < 1.0f)
179 distanceBeyondLine1EndSquared = -distanceBeyondLine1EndSquared;
180
181 return false;
182 }
183
184 intersectionX = x2;
185 intersectionY = y2;
186
187 distanceBeyondLine1EndSquared = 0.0f;
188 return true;
189 }
190
191 static void addEdgeAndJoint (Path& destPath,
193 const float maxMiterExtensionSquared, const float width,
194 const float x1, const float y1,
195 const float x2, const float y2,
196 const float x3, const float y3,
197 const float x4, const float y4,
198 const float midX, const float midY)
199 {
201 || (x3 == x4 && y3 == y4)
202 || (x1 == x2 && y1 == y2))
203 {
204 destPath.lineTo (x2, y2);
205 destPath.lineTo (x3, y3);
206 }
207 else
208 {
209 float jx, jy, distanceBeyondLine1EndSquared;
210
211 // if they intersect, use this point..
212 if (lineIntersection (x1, y1, x2, y2,
213 x3, y3, x4, y4,
214 jx, jy, distanceBeyondLine1EndSquared))
215 {
216 destPath.lineTo (jx, jy);
217 }
218 else
219 {
221 {
222 if (distanceBeyondLine1EndSquared < maxMiterExtensionSquared
223 && distanceBeyondLine1EndSquared > 0.0f)
224 {
225 destPath.lineTo (jx, jy);
226 }
227 else
228 {
229 // the end sticks out too far, so just use a blunt joint
230 destPath.lineTo (x2, y2);
231 destPath.lineTo (x3, y3);
232 }
233 }
234 else
235 {
236 // curved joints
237 float angle1 = std::atan2 (x2 - midX, y2 - midY);
238 float angle2 = std::atan2 (x3 - midX, y3 - midY);
239 const float angleIncrement = 0.1f;
240
241 destPath.lineTo (x2, y2);
242
243 if (std::abs (angle1 - angle2) > angleIncrement)
244 {
245 if (angle2 > angle1 + MathConstants<float>::pi
246 || (angle2 < angle1 && angle2 >= angle1 - MathConstants<float>::pi))
247 {
248 if (angle2 > angle1)
250
251 jassert (angle1 <= angle2 + MathConstants<float>::pi);
252
253 angle1 -= angleIncrement;
254 while (angle1 > angle2)
255 {
256 destPath.lineTo (midX + width * std::sin (angle1),
257 midY + width * std::cos (angle1));
258
259 angle1 -= angleIncrement;
260 }
261 }
262 else
263 {
264 if (angle1 > angle2)
266
267 jassert (angle1 >= angle2 - MathConstants<float>::pi);
268
269 angle1 += angleIncrement;
270 while (angle1 < angle2)
271 {
272 destPath.lineTo (midX + width * std::sin (angle1),
273 midY + width * std::cos (angle1));
274
275 angle1 += angleIncrement;
276 }
277 }
278 }
279
280 destPath.lineTo (x3, y3);
281 }
282 }
283 }
284 }
285
286 static void addLineEnd (Path& destPath,
288 const float x1, const float y1,
289 const float x2, const float y2,
290 const float width)
291 {
293 {
294 destPath.lineTo (x2, y2);
295 }
296 else
297 {
298 float offx1, offy1, offx2, offy2;
299
300 auto dx = x2 - x1;
301 auto dy = y2 - y1;
302 auto len = juce_hypot (dx, dy);
303
304 if (len == 0.0f)
305 {
306 offx1 = offx2 = x1;
307 offy1 = offy2 = y1;
308 }
309 else
310 {
311 auto offset = width / len;
312 dx *= offset;
313 dy *= offset;
314
315 offx1 = x1 + dy;
316 offy1 = y1 - dx;
317 offx2 = x2 + dy;
318 offy2 = y2 - dx;
319 }
320
322 {
323 // square ends
324 destPath.lineTo (offx1, offy1);
325 destPath.lineTo (offx2, offy2);
326 destPath.lineTo (x2, y2);
327 }
328 else
329 {
330 // rounded ends
331 auto midx = (offx1 + offx2) * 0.5f;
332 auto midy = (offy1 + offy2) * 0.5f;
333
334 destPath.cubicTo (x1 + (offx1 - x1) * 0.55f, y1 + (offy1 - y1) * 0.55f,
335 offx1 + (midx - offx1) * 0.45f, offy1 + (midy - offy1) * 0.45f,
336 midx, midy);
337
338 destPath.cubicTo (midx + (offx2 - midx) * 0.55f, midy + (offy2 - midy) * 0.55f,
339 offx2 + (x2 - offx2) * 0.45f, offy2 + (y2 - offy2) * 0.45f,
340 x2, y2);
341 }
342 }
343 }
344
346 {
349 };
350
351 static void addArrowhead (Path& destPath,
352 const float x1, const float y1,
353 const float x2, const float y2,
354 const float tipX, const float tipY,
355 const float width,
356 const float arrowheadWidth)
357 {
358 Line<float> line (x1, y1, x2, y2);
359 destPath.lineTo (line.getPointAlongLine (-(arrowheadWidth / 2.0f - width), 0));
360 destPath.lineTo (tipX, tipY);
361 destPath.lineTo (line.getPointAlongLine (arrowheadWidth - (arrowheadWidth / 2.0f - width), 0));
362 destPath.lineTo (x2, y2);
363 }
364
366 {
367 float x1, y1, x2, y2; // original line
368 float lx1, ly1, lx2, ly2; // the left-hand stroke
369 float rx1, ry1, rx2, ry2; // the right-hand stroke
370 };
371
372 static void shortenSubPath (Array<LineSection>& subPath, float amountAtStart, float amountAtEnd)
373 {
374 while (amountAtEnd > 0 && subPath.size() > 0)
375 {
376 auto& l = subPath.getReference (subPath.size() - 1);
377 auto dx = l.rx2 - l.rx1;
378 auto dy = l.ry2 - l.ry1;
379 auto len = juce_hypot (dx, dy);
380
381 if (len <= amountAtEnd && subPath.size() > 1)
382 {
383 LineSection& prev = subPath.getReference (subPath.size() - 2);
384 prev.x2 = l.x2;
385 prev.y2 = l.y2;
386 subPath.removeLast();
387 amountAtEnd -= len;
388 }
389 else
390 {
391 auto prop = jmin (0.9999f, amountAtEnd / len);
392 dx *= prop;
393 dy *= prop;
394 l.rx1 += dx;
395 l.ry1 += dy;
396 l.lx2 += dx;
397 l.ly2 += dy;
398 break;
399 }
400 }
401
402 while (amountAtStart > 0 && subPath.size() > 0)
403 {
404 auto& l = subPath.getReference (0);
405 auto dx = l.rx2 - l.rx1;
406 auto dy = l.ry2 - l.ry1;
407 auto len = juce_hypot (dx, dy);
408
409 if (len <= amountAtStart && subPath.size() > 1)
410 {
411 LineSection& next = subPath.getReference (1);
412 next.x1 = l.x1;
413 next.y1 = l.y1;
414 subPath.remove (0);
415 amountAtStart -= len;
416 }
417 else
418 {
419 auto prop = jmin (0.9999f, amountAtStart / len);
420 dx *= prop;
421 dy *= prop;
422 l.rx2 -= dx;
423 l.ry2 -= dy;
424 l.lx1 -= dx;
425 l.ly1 -= dy;
426 break;
427 }
428 }
429 }
430
431 static void addSubPath (Path& destPath, Array<LineSection>& subPath,
432 const bool isClosed, const float width, const float maxMiterExtensionSquared,
433 const PathStrokeType::JointStyle jointStyle, const PathStrokeType::EndCapStyle endStyle,
434 const Arrowhead* const arrowhead)
435 {
436 jassert (subPath.size() > 0);
437
438 if (arrowhead != nullptr)
439 shortenSubPath (subPath, arrowhead->startLength, arrowhead->endLength);
440
441 auto& firstLine = subPath.getReference (0);
442
443 auto lastX1 = firstLine.lx1;
444 auto lastY1 = firstLine.ly1;
445 auto lastX2 = firstLine.lx2;
446 auto lastY2 = firstLine.ly2;
447
448 if (isClosed)
449 {
450 destPath.startNewSubPath (lastX1, lastY1);
451 }
452 else
453 {
454 destPath.startNewSubPath (firstLine.rx2, firstLine.ry2);
455
456 if (arrowhead != nullptr && arrowhead->startWidth > 0.0f)
457 addArrowhead (destPath, firstLine.rx2, firstLine.ry2, lastX1, lastY1, firstLine.x1, firstLine.y1,
458 width, arrowhead->startWidth);
459 else
460 addLineEnd (destPath, endStyle, firstLine.rx2, firstLine.ry2, lastX1, lastY1, width);
461 }
462
463 for (int i = 1; i < subPath.size(); ++i)
464 {
465 const LineSection& l = subPath.getReference (i);
466
467 addEdgeAndJoint (destPath, jointStyle,
468 maxMiterExtensionSquared, width,
469 lastX1, lastY1, lastX2, lastY2,
470 l.lx1, l.ly1, l.lx2, l.ly2,
471 l.x1, l.y1);
472
473 lastX1 = l.lx1;
474 lastY1 = l.ly1;
475 lastX2 = l.lx2;
476 lastY2 = l.ly2;
477 }
478
479 auto& lastLine = subPath.getReference (subPath.size() - 1);
480
481 if (isClosed)
482 {
483 auto& l = subPath.getReference (0);
484
485 addEdgeAndJoint (destPath, jointStyle,
486 maxMiterExtensionSquared, width,
487 lastX1, lastY1, lastX2, lastY2,
488 l.lx1, l.ly1, l.lx2, l.ly2,
489 l.x1, l.y1);
490
491 destPath.closeSubPath();
492 destPath.startNewSubPath (lastLine.rx1, lastLine.ry1);
493 }
494 else
495 {
496 destPath.lineTo (lastX2, lastY2);
497
498 if (arrowhead != nullptr && arrowhead->endWidth > 0.0f)
499 addArrowhead (destPath, lastX2, lastY2, lastLine.rx1, lastLine.ry1, lastLine.x2, lastLine.y2,
500 width, arrowhead->endWidth);
501 else
502 addLineEnd (destPath, endStyle, lastX2, lastY2, lastLine.rx1, lastLine.ry1, width);
503 }
504
505 lastX1 = lastLine.rx1;
506 lastY1 = lastLine.ry1;
507 lastX2 = lastLine.rx2;
508 lastY2 = lastLine.ry2;
509
510 for (int i = subPath.size() - 1; --i >= 0;)
511 {
512 auto& l = subPath.getReference (i);
513
514 addEdgeAndJoint (destPath, jointStyle,
515 maxMiterExtensionSquared, width,
516 lastX1, lastY1, lastX2, lastY2,
517 l.rx1, l.ry1, l.rx2, l.ry2,
518 l.x2, l.y2);
519
520 lastX1 = l.rx1;
521 lastY1 = l.ry1;
522 lastX2 = l.rx2;
523 lastY2 = l.ry2;
524 }
525
526 if (isClosed)
527 {
528 addEdgeAndJoint (destPath, jointStyle,
529 maxMiterExtensionSquared, width,
530 lastX1, lastY1, lastX2, lastY2,
531 lastLine.rx1, lastLine.ry1, lastLine.rx2, lastLine.ry2,
532 lastLine.x2, lastLine.y2);
533 }
534 else
535 {
536 // do the last line
537 destPath.lineTo (lastX2, lastY2);
538 }
539
540 destPath.closeSubPath();
541 }
542
543 static void createStroke (const float thickness, const PathStrokeType::JointStyle jointStyle,
544 const PathStrokeType::EndCapStyle endStyle,
545 Path& destPath, const Path& source,
546 const AffineTransform& transform,
547 const float extraAccuracy, const Arrowhead* const arrowhead)
548 {
549 jassert (extraAccuracy > 0);
550
551 if (thickness <= 0)
552 {
553 destPath.clear();
554 return;
555 }
556
557 const Path* sourcePath = &source;
558 Path temp;
559
560 if (sourcePath == &destPath)
561 {
562 destPath.swapWithPath (temp);
563 sourcePath = &temp;
564 }
565 else
566 {
567 destPath.clear();
568 }
569
570 destPath.setUsingNonZeroWinding (true);
571
572 const float maxMiterExtensionSquared = 9.0f * thickness * thickness;
573 const float width = 0.5f * thickness;
574
575 // Iterate the path, creating a list of the
576 // left/right-hand lines along either side of it...
577 PathFlatteningIterator it (*sourcePath, transform, Path::defaultToleranceForMeasurement / extraAccuracy);
578
579 Array<LineSection> subPath;
580 subPath.ensureStorageAllocated (512);
582 l.x1 = 0;
583 l.y1 = 0;
584
585 const float minSegmentLength = 0.0001f;
586
587 while (it.next())
588 {
589 if (it.subPathIndex == 0)
590 {
591 if (subPath.size() > 0)
592 {
593 addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead);
594 subPath.clearQuick();
595 }
596
597 l.x1 = it.x1;
598 l.y1 = it.y1;
599 }
600
601 l.x2 = it.x2;
602 l.y2 = it.y2;
603
604 float dx = l.x2 - l.x1;
605 float dy = l.y2 - l.y1;
606
607 auto hypotSquared = dx * dx + dy * dy;
608
609 if (it.closesSubPath || hypotSquared > minSegmentLength || it.isLastInSubpath())
610 {
611 auto len = std::sqrt (hypotSquared);
612
613 if (len == 0.0f)
614 {
615 l.rx1 = l.rx2 = l.lx1 = l.lx2 = l.x1;
616 l.ry1 = l.ry2 = l.ly1 = l.ly2 = l.y1;
617 }
618 else
619 {
620 auto offset = width / len;
621 dx *= offset;
622 dy *= offset;
623
624 l.rx2 = l.x1 - dy;
625 l.ry2 = l.y1 + dx;
626 l.lx1 = l.x1 + dy;
627 l.ly1 = l.y1 - dx;
628
629 l.lx2 = l.x2 + dy;
630 l.ly2 = l.y2 - dx;
631 l.rx1 = l.x2 - dy;
632 l.ry1 = l.y2 + dx;
633 }
634
635 subPath.add (l);
636
637 if (it.closesSubPath)
638 {
639 addSubPath (destPath, subPath, true, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead);
640 subPath.clearQuick();
641 }
642 else
643 {
644 l.x1 = it.x2;
645 l.y1 = it.y2;
646 }
647 }
648 }
649
650 if (subPath.size() > 0)
651 addSubPath (destPath, subPath, false, width, maxMiterExtensionSquared, jointStyle, endStyle, arrowhead);
652 }
653}
654
655void PathStrokeType::createStrokedPath (Path& destPath, const Path& sourcePath,
656 const AffineTransform& transform, float extraAccuracy) const
657{
659 transform, extraAccuracy, nullptr);
660}
661
663 const Path& sourcePath,
664 const float* dashLengths,
665 int numDashLengths,
666 const AffineTransform& transform,
667 float extraAccuracy) const
668{
669 jassert (extraAccuracy > 0);
670
671 if (thickness <= 0)
672 return;
673
674 Path newDestPath;
675 PathFlatteningIterator it (sourcePath, transform, Path::defaultToleranceForMeasurement / extraAccuracy);
676
677 bool first = true;
678 int dashNum = 0;
679 float pos = 0.0f, lineLen = 0.0f, lineEndPos = 0.0f;
680 float dx = 0.0f, dy = 0.0f;
681
682 for (;;)
683 {
684 const bool isSolid = ((dashNum & 1) == 0);
685 const float dashLen = dashLengths [dashNum++ % numDashLengths];
686
687 jassert (dashLen >= 0); // must be a positive increment!
688 if (dashLen <= 0)
689 continue;
690
691 pos += dashLen;
692
693 while (pos > lineEndPos)
694 {
695 if (! it.next())
696 {
697 if (isSolid && ! first)
698 newDestPath.lineTo (it.x2, it.y2);
699
700 createStrokedPath (destPath, newDestPath, AffineTransform(), extraAccuracy);
701 return;
702 }
703
704 if (isSolid && ! first)
705 newDestPath.lineTo (it.x1, it.y1);
706 else
707 newDestPath.startNewSubPath (it.x1, it.y1);
708
709 dx = it.x2 - it.x1;
710 dy = it.y2 - it.y1;
711 lineLen = juce_hypot (dx, dy);
712 lineEndPos += lineLen;
713 first = it.closesSubPath;
714 }
715
716 const float alpha = (pos - (lineEndPos - lineLen)) / lineLen;
717
718 if (isSolid)
719 newDestPath.lineTo (it.x1 + dx * alpha,
720 it.y1 + dy * alpha);
721 else
722 newDestPath.startNewSubPath (it.x1 + dx * alpha,
723 it.y1 + dy * alpha);
724 }
725}
726
728 const Path& sourcePath,
729 const float arrowheadStartWidth, const float arrowheadStartLength,
730 const float arrowheadEndWidth, const float arrowheadEndLength,
731 const AffineTransform& transform,
732 const float extraAccuracy) const
733{
735 head.startWidth = arrowheadStartWidth;
736 head.startLength = arrowheadStartLength;
737 head.endWidth = arrowheadEndWidth;
738 head.endLength = arrowheadEndLength;
739
741 destPath, sourcePath, transform, extraAccuracy, &head);
742}
743
744} // namespace juce
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
#define noexcept
Definition DistrhoDefines.h:72
Definition juce_AffineTransform.h:43
Definition juce_Array.h:56
void removeLast(int howManyToRemove=1)
Definition juce_Array.h:939
void ensureStorageAllocated(int minNumElements)
Definition juce_Array.h:1065
void clearQuick()
Definition juce_Array.h:198
int size() const noexcept
Definition juce_Array.h:215
void remove(int indexToRemove)
Definition juce_Array.h:767
void add(const ElementType &newElement)
Definition juce_Array.h:418
ElementType & getReference(int index) noexcept
Definition juce_Array.h:267
Definition juce_Line.h:47
Point< ValueType > getPointAlongLine(ValueType distanceFromStart) const noexcept
Definition juce_Line.h:204
Definition juce_PathIterator.h:42
bool closesSubPath
Definition juce_PathIterator.h:83
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
int subPathIndex
Definition juce_PathIterator.h:90
bool isLastInSubpath() const noexcept
Definition juce_PathIterator.cpp:54
Definition juce_Path.h:65
static const float defaultToleranceForMeasurement
Definition juce_Path.h:90
void startNewSubPath(float startX, float startY)
Definition juce_Path.cpp:216
void cubicTo(float controlPoint1X, float controlPoint1Y, float controlPoint2X, float controlPoint2Y, float endPointX, float endPointY)
Definition juce_Path.cpp:268
void clear() noexcept
Definition juce_Path.cpp:151
void closeSubPath()
Definition juce_Path.cpp:292
void lineTo(float endX, float endY)
Definition juce_Path.cpp:233
void swapWithPath(Path &) noexcept
Definition juce_Path.cpp:157
void setUsingNonZeroWinding(bool isNonZeroWinding) noexcept
Definition juce_Path.cpp:168
float thickness
Definition juce_PathStrokeType.h:199
JointStyle
Definition juce_PathStrokeType.h:47
@ beveled
Definition juce_PathStrokeType.h:54
@ mitered
Definition juce_PathStrokeType.h:48
void createStrokedPath(Path &destPath, const Path &sourcePath, const AffineTransform &transform=AffineTransform(), float extraAccuracy=1.0f) const
Definition juce_PathStrokeType.cpp:655
PathStrokeType(float strokeThickness) noexcept
Definition juce_PathStrokeType.cpp:29
JointStyle jointStyle
Definition juce_PathStrokeType.h:200
EndCapStyle
Definition juce_PathStrokeType.h:60
@ square
Definition juce_PathStrokeType.h:62
@ butt
Definition juce_PathStrokeType.h:61
void createDashedStroke(Path &destPath, const Path &sourcePath, const float *dashLengths, int numDashLengths, const AffineTransform &transform=AffineTransform(), float extraAccuracy=1.0f) const
Definition juce_PathStrokeType.cpp:662
~PathStrokeType() noexcept
Definition juce_PathStrokeType.cpp:54
EndCapStyle endStyle
Definition juce_PathStrokeType.h:201
void createStrokeWithArrowheads(Path &destPath, const Path &sourcePath, float arrowheadStartWidth, float arrowheadStartLength, float arrowheadEndWidth, float arrowheadEndLength, const AffineTransform &transform=AffineTransform(), float extraAccuracy=1.0f) const
Definition juce_PathStrokeType.cpp:727
int * l
Definition inflate.c:1579
register unsigned i
Definition inflate.c:1575
static int width
Definition pugl.h:1593
#define jassert(expression)
static const SerdStyle style
Definition sratom.c:36
Definition juce_PathStrokeType.cpp:72
static void addEdgeAndJoint(Path &destPath, const PathStrokeType::JointStyle style, const float maxMiterExtensionSquared, const float width, const float x1, const float y1, const float x2, const float y2, const float x3, const float y3, const float x4, const float y4, const float midX, const float midY)
Definition juce_PathStrokeType.cpp:191
static bool lineIntersection(const float x1, const float y1, const float x2, const float y2, const float x3, const float y3, const float x4, const float y4, float &intersectionX, float &intersectionY, float &distanceBeyondLine1EndSquared) noexcept
Definition juce_PathStrokeType.cpp:73
static void createStroke(const float thickness, const PathStrokeType::JointStyle jointStyle, const PathStrokeType::EndCapStyle endStyle, Path &destPath, const Path &source, const AffineTransform &transform, const float extraAccuracy, const Arrowhead *const arrowhead)
Definition juce_PathStrokeType.cpp:543
static void shortenSubPath(Array< LineSection > &subPath, float amountAtStart, float amountAtEnd)
Definition juce_PathStrokeType.cpp:372
static void addArrowhead(Path &destPath, const float x1, const float y1, const float x2, const float y2, const float tipX, const float tipY, const float width, const float arrowheadWidth)
Definition juce_PathStrokeType.cpp:351
static void addLineEnd(Path &destPath, const PathStrokeType::EndCapStyle style, const float x1, const float y1, const float x2, const float y2, const float width)
Definition juce_PathStrokeType.cpp:286
static void addSubPath(Path &destPath, Array< LineSection > &subPath, const bool isClosed, const float width, const float maxMiterExtensionSquared, const PathStrokeType::JointStyle jointStyle, const PathStrokeType::EndCapStyle endStyle, const Arrowhead *const arrowhead)
Definition juce_PathStrokeType.cpp:431
Definition carla_juce.cpp:31
RangedDirectoryIterator end(const RangedDirectoryIterator &)
Definition juce_RangedDirectoryIterator.h:184
Type juce_hypot(Type a, Type b) noexcept
Definition juce_MathsFunctions.h:352
Definition misc.c:36
static constexpr FloatType twoPi
Definition juce_MathsFunctions.h:385
static constexpr FloatType pi
Definition juce_MathsFunctions.h:382
Definition juce_PathStrokeType.cpp:346
float endWidth
Definition juce_PathStrokeType.cpp:348
float endLength
Definition juce_PathStrokeType.cpp:348
float startWidth
Definition juce_PathStrokeType.cpp:347
float startLength
Definition juce_PathStrokeType.cpp:347
Definition juce_PathStrokeType.cpp:366
float ry1
Definition juce_PathStrokeType.cpp:369
float ry2
Definition juce_PathStrokeType.cpp:369
float y2
Definition juce_PathStrokeType.cpp:367
float rx2
Definition juce_PathStrokeType.cpp:369
float rx1
Definition juce_PathStrokeType.cpp:369
float lx1
Definition juce_PathStrokeType.cpp:368
float ly2
Definition juce_PathStrokeType.cpp:368
float lx2
Definition juce_PathStrokeType.cpp:368
float x1
Definition juce_PathStrokeType.cpp:367
float y1
Definition juce_PathStrokeType.cpp:367
float ly1
Definition juce_PathStrokeType.cpp:368
float x2
Definition juce_PathStrokeType.cpp:367
dy
Definition zipinfo.c:2288