21#include <osl/diagnose.h>
34#define SUBDIVIDE_FOR_CUT_TEST_COUNT (50)
48 temporaryPoint(
const B2DPoint& rNewPoint, sal_uInt32 nIndex,
double fCut)
55 bool operator<(
const temporaryPoint& rComp)
const
59 return (
mfCut < rComp.mfCut);
62 return (
mnIndex < rComp.mnIndex);
65 const B2DPoint& getPoint()
const {
return maPoint; }
66 sal_uInt32 getIndex()
const {
return mnIndex; }
67 double getCut()
const {
return mfCut; }
70 typedef std::vector< temporaryPoint > temporaryPointVector;
72 class temporaryPolygonData
79 const B2DPolygon& getPolygon()
const {
return maPolygon; }
82 temporaryPointVector& getTemporaryPointVector() {
return maPoints; }
85 B2DPolygon mergeTemporaryPointsAndPolygon(
const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints)
90 const sal_uInt32 nTempPointCount(rTempPoints.size());
95 const sal_uInt32
nCount(rCandidate.count());
100 std::sort(rTempPoints.begin(), rTempPoints.end());
103 B2DCubicBezier aEdge;
104 sal_uInt32 nNewInd(0);
107 aRetval.append(rCandidate.getB2DPoint(0));
112 rCandidate.getBezierSegment(a, aEdge);
117 double fLeftStart(0.0);
120 while (nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a && fLeftStart < 1.0)
122 const temporaryPoint& rTempPoint = rTempPoints[nNewInd++];
127 B2DCubicBezier aLeftPart;
128 const double fRelativeSplitPoint((rTempPoint.getCut() - fLeftStart) / (1.0 - fLeftStart));
129 aEdge.split(fRelativeSplitPoint, &aLeftPart, &aEdge);
130 fLeftStart = rTempPoint.getCut();
133 aRetval.appendBezierSegment(aLeftPart.getControlPointA(), aLeftPart.getControlPointB(), rTempPoint.getPoint());
137 aRetval.appendBezierSegment(aEdge.getControlPointA(), aEdge.getControlPointB(), aEdge.getEndPoint());
142 while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a)
144 const temporaryPoint& rTempPoint = rTempPoints[nNewInd++];
145 const B2DPoint& aNewPoint(rTempPoint.getPoint());
148 if(!aRetval.getB2DPoint(aRetval.count() - 1).equal(aNewPoint))
150 aRetval.append(aNewPoint);
155 aRetval.append(aEdge.getEndPoint());
160 if(rCandidate.isClosed())
174 void adaptAndTransferCutsWithBezierSegment(
175 const temporaryPointVector& rPointVector,
const B2DPolygon& rPolygon,
176 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
182 const sal_uInt32 nTempPointCount(rPointVector.size());
183 const sal_uInt32 nEdgeCount(rPolygon.count() ? rPolygon.count() - 1 : 0);
185 if(nTempPointCount && nEdgeCount)
187 for(sal_uInt32
a(0);
a < nTempPointCount;
a++)
189 const temporaryPoint& rTempPoint = rPointVector[
a];
190 const double fCutPosInPolygon(
static_cast<double>(rTempPoint.getIndex()) + rTempPoint.getCut());
191 const double fRelativeCutPos(fCutPosInPolygon /
static_cast<double>(nEdgeCount));
192 rTempPoints.emplace_back(rTempPoint.getPoint(), nInd, fRelativeCutPos);
207 void findCuts(
const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints,
size_t* pPointLimit =
nullptr);
208 void findTouches(
const B2DPolygon& rEdgePolygon,
const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints);
209 void findCuts(
const B2DPolygon& rCandidateA,
const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB);
211 void findEdgeCutsTwoEdges(
212 const B2DPoint& rCurrA,
const B2DPoint& rNextA,
213 const B2DPoint& rCurrB,
const B2DPoint& rNextB,
214 sal_uInt32 nIndA, sal_uInt32 nIndB,
215 temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
218 if(rCurrA.equal(rNextA) || rCurrB.equal(rNextB))
222 if(rCurrB.equal(rCurrA) || rCurrB.equal(rNextA) || rNextB.equal(rCurrA) || rNextB.equal(rNextA))
225 const B2DVector aVecA(rNextA - rCurrA);
226 const B2DVector aVecB(rNextB - rCurrB);
227 double fCut(aVecA.cross(aVecB));
232 const double fZero(0.0);
233 const double fOne(1.0);
234 fCut = (aVecB.getY() * (rCurrB.getX() - rCurrA.getX()) + aVecB.getX() * (rCurrA.getY() - rCurrB.getY())) / fCut;
243 if(fabs(aVecB.getX()) > fabs(aVecB.getY()))
245 fCut2 = (rCurrA.getX() + (fCut * aVecA.getX()) - rCurrB.getX()) / aVecB.getX();
249 fCut2 = (rCurrA.getY() + (fCut * aVecA.getY()) - rCurrB.getY()) / aVecB.getY();
257 const B2DPoint aCutPoint(
interpolate(rCurrA, rNextA, fCut));
258 rTempPointsA.emplace_back(aCutPoint, nIndA, fCut);
259 rTempPointsB.emplace_back(aCutPoint, nIndB, fCut2);
263 void findCutsAndTouchesAndCommonForBezier(
const B2DPolygon& rCandidateA,
const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
277 OSL_ENSURE(!rCandidateA.areControlPointsUsed() && !rCandidateB.areControlPointsUsed(),
"findCutsAndTouchesAndCommonForBezier only works with subdivided polygons (!)");
278 OSL_ENSURE(!rCandidateA.isClosed() && !rCandidateB.isClosed(),
"findCutsAndTouchesAndCommonForBezier only works with opened polygons (!)");
279 const sal_uInt32 nPointCountA(rCandidateA.count());
280 const sal_uInt32 nPointCountB(rCandidateB.count());
282 if(nPointCountA <= 1 || nPointCountB <= 1)
285 const sal_uInt32 nEdgeCountA(nPointCountA - 1);
286 const sal_uInt32 nEdgeCountB(nPointCountB - 1);
287 B2DPoint aCurrA(rCandidateA.getB2DPoint(0));
289 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
291 const B2DPoint aNextA(rCandidateA.getB2DPoint(a + 1));
292 const B2DRange aRangeA(aCurrA, aNextA);
293 B2DPoint aCurrB(rCandidateB.getB2DPoint(0));
295 for(sal_uInt32 b(0); b < nEdgeCountB; b++)
297 const B2DPoint aNextB(rCandidateB.getB2DPoint(b + 1));
298 const B2DRange aRangeB(aCurrB, aNextB);
300 if(aRangeA.overlaps(aRangeB))
303 if(!(aCurrA.equal(aNextA) || aCurrB.equal(aNextB)))
305 const B2DVector aVecA(aNextA - aCurrA);
306 const B2DVector aVecB(aNextB - aCurrB);
307 double fCutA(aVecA.cross(aVecB));
311 const double fZero(0.0);
312 const double fOne(1.0);
313 fCutA = (aVecB.getY() * (aCurrB.getX() - aCurrA.getX()) + aVecB.getX() * (aCurrA.getY() - aCurrB.getY())) / fCutA;
323 if(fabs(aVecB.getX()) > fabs(aVecB.getY()))
325 fCutB = (aCurrA.getX() + (fCutA * aVecA.getX()) - aCurrB.getX()) / aVecB.getX();
329 fCutB = (aCurrA.getY() + (fCutA * aVecA.getY()) - aCurrB.getY()) / aVecB.getY();
344 rTempPointsA.emplace_back(aCurrA, a, 0.0);
349 const B2DPoint aCutPoint(
interpolate(aCurrA, aNextA, fCutA));
350 rTempPointsA.emplace_back(aCutPoint, a, fCutA);
360 rTempPointsB.emplace_back(aCurrB, b, 0.0);
365 const B2DPoint aCutPoint(
interpolate(aCurrB, aNextB, fCutB));
366 rTempPointsB.emplace_back(aCutPoint, b, fCutB);
383 void findEdgeCutsBezierAndEdge(
384 const B2DCubicBezier& rCubicA,
385 const B2DPoint& rCurrB,
const B2DPoint& rNextB,
386 sal_uInt32 nIndA, sal_uInt32 nIndB,
387 temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
392 B2DPolygon aTempPolygonA;
393 B2DPolygon aTempPolygonEdge;
394 temporaryPointVector aTempPointVectorA;
395 temporaryPointVector aTempPointVectorEdge;
400 aTempPolygonA.append(rCubicA.getStartPoint());
402 aTempPolygonEdge.append(rCurrB);
403 aTempPolygonEdge.append(rNextB);
406 findCutsAndTouchesAndCommonForBezier(aTempPolygonA, aTempPolygonEdge, aTempPointVectorA, aTempPointVectorEdge);
408 if(!aTempPointVectorA.empty())
411 adaptAndTransferCutsWithBezierSegment(aTempPointVectorA, aTempPolygonA, nIndA, rTempPointsA);
415 for(
const temporaryPoint & rTempPoint : aTempPointVectorEdge)
417 rTempPointsB.emplace_back(rTempPoint.getPoint(), nIndB, rTempPoint.getCut());
421 void findEdgeCutsTwoBeziers(
422 const B2DCubicBezier& rCubicA,
423 const B2DCubicBezier& rCubicB,
424 sal_uInt32 nIndA, sal_uInt32 nIndB,
425 temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
430 B2DPolygon aTempPolygonA;
431 B2DPolygon aTempPolygonB;
432 temporaryPointVector aTempPointVectorA;
433 temporaryPointVector aTempPointVectorB;
438 aTempPolygonA.append(rCubicA.getStartPoint());
441 aTempPolygonB.append(rCubicB.getStartPoint());
445 findCutsAndTouchesAndCommonForBezier(aTempPolygonA, aTempPolygonB, aTempPointVectorA, aTempPointVectorB);
447 if(!aTempPointVectorA.empty())
450 adaptAndTransferCutsWithBezierSegment(aTempPointVectorA, aTempPolygonA, nIndA, rTempPointsA);
453 if(!aTempPointVectorB.empty())
456 adaptAndTransferCutsWithBezierSegment(aTempPointVectorB, aTempPolygonB, nIndB, rTempPointsB);
460 void findEdgeCutsOneBezier(
461 const B2DCubicBezier& rCubicA,
462 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
467 const bool bHasAnyExtremum = rCubicA.getMinimumExtremumPosition( fDummy );
468 if( !bHasAnyExtremum )
474 B2DPolygon aTempPolygon;
475 temporaryPointVector aTempPointVector;
480 aTempPolygon.append(rCubicA.getStartPoint());
482 findCuts(aTempPolygon, aTempPointVector);
484 if(!aTempPointVector.empty())
487 adaptAndTransferCutsWithBezierSegment(aTempPointVector, aTempPolygon, nInd, rTempPoints);
491 void findCuts(
const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints,
size_t* pPointLimit)
495 const sal_uInt32 nPointCount(rCandidate.count());
500 const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
505 const bool bCurvesInvolved(rCandidate.areControlPointsUsed());
509 B2DCubicBezier aCubicA;
510 B2DCubicBezier aCubicB;
512 for(sal_uInt32
a(0);
a < nEdgeCount - 1;
a++)
514 rCandidate.getBezierSegment(a, aCubicA);
515 aCubicA.testAndSolveTrivialBezier();
516 const bool bEdgeAIsCurve(aCubicA.isBezier());
517 const B2DRange aRangeA(aCubicA.getRange());
522 findEdgeCutsOneBezier(aCubicA, a, rTempPoints);
525 for(sal_uInt32 b(a + 1); b < nEdgeCount; b++)
527 rCandidate.getBezierSegment(b, aCubicB);
528 aCubicB.testAndSolveTrivialBezier();
529 const B2DRange aRangeB(aCubicB.getRange());
533 bool bOverlap =
false;
535 bOverlap = aRangeA.overlaps(aRangeB);
537 bOverlap = aRangeA.overlapsMore(aRangeB);
540 const bool bEdgeBIsCurve(aCubicB.isBezier());
541 if(bEdgeAIsCurve && bEdgeBIsCurve)
544 findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, rTempPoints, rTempPoints);
546 else if(bEdgeAIsCurve)
549 findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, rTempPoints, rTempPoints);
551 else if(bEdgeBIsCurve)
554 findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, rTempPoints, rTempPoints);
559 findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(),
560 a, b, rTempPoints, rTempPoints);
568 B2DPoint aCurrA(rCandidate.getB2DPoint(0));
570 for(sal_uInt32
a(0);
a < nEdgeCount - 1;
a++)
572 const B2DPoint aNextA(rCandidate.getB2DPoint(a + 1 == nPointCount ? 0 : a + 1));
573 const B2DRange aRangeA(aCurrA, aNextA);
574 B2DPoint aCurrB(rCandidate.getB2DPoint(a + 1));
576 for(sal_uInt32 b(a + 1); b < nEdgeCount; b++)
578 const B2DPoint aNextB(rCandidate.getB2DPoint(b + 1 == nPointCount ? 0 : b + 1));
579 const B2DRange aRangeB(aCurrB, aNextB);
582 bool bOverlap =
false;
584 bOverlap = aRangeA.overlaps(aRangeB);
586 bOverlap = aRangeA.overlapsMore(aRangeB);
589 findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPoints, rTempPoints);
592 if (pPointLimit && rTempPoints.size() > *pPointLimit)
606 if (rTempPoints.size() > *pPointLimit)
609 *pPointLimit -= rTempPoints.size();
621 void findTouchesOnEdge(
622 const B2DPoint& rCurr,
const B2DPoint& rNext,
const B2DPolygon& rPointPolygon,
623 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
627 const sal_uInt32 nPointCount(rPointPolygon.count());
632 const B2DRange aRange(rCurr, rNext);
633 const B2DVector aEdgeVector(rNext - rCurr);
634 bool bTestUsingX(fabs(aEdgeVector.getX()) > fabs(aEdgeVector.getY()));
636 for(sal_uInt32
a(0);
a < nPointCount;
a++)
638 const B2DPoint aTestPoint(rPointPolygon.getB2DPoint(a));
640 if(aRange.isInside(aTestPoint))
642 if(!aTestPoint.equal(rCurr) && !aTestPoint.equal(rNext))
644 const B2DVector aTestVector(aTestPoint - rCurr);
648 const double fCut(bTestUsingX
649 ? aTestVector.getX() / aEdgeVector.getX()
650 : aTestVector.getY() / aEdgeVector.getY());
651 const double fZero(0.0);
652 const double fOne(1.0);
656 rTempPoints.emplace_back(aTestPoint, nInd, fCut);
664 void findTouchesOnCurve(
665 const B2DCubicBezier& rCubicA,
const B2DPolygon& rPointPolygon,
666 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
671 B2DPolygon aTempPolygon;
672 temporaryPointVector aTempPointVector;
677 aTempPolygon.append(rCubicA.getStartPoint());
679 findTouches(aTempPolygon, rPointPolygon, aTempPointVector);
681 if(!aTempPointVector.empty())
684 adaptAndTransferCutsWithBezierSegment(aTempPointVector, aTempPolygon, nInd, rTempPoints);
688 void findTouches(
const B2DPolygon& rEdgePolygon,
const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints)
692 const sal_uInt32 nPointCount(rPointPolygon.count());
693 const sal_uInt32 nEdgePointCount(rEdgePolygon.count());
695 if(!(nPointCount && nEdgePointCount))
698 const sal_uInt32 nEdgeCount(rEdgePolygon.isClosed() ? nEdgePointCount : nEdgePointCount - 1);
699 B2DPoint aCurr(rEdgePolygon.getB2DPoint(0));
701 for(sal_uInt32
a(0);
a < nEdgeCount;
a++)
703 const sal_uInt32 nNextIndex((a + 1) % nEdgePointCount);
704 const B2DPoint aNext(rEdgePolygon.getB2DPoint(nNextIndex));
706 if(!aCurr.equal(aNext))
708 bool bHandleAsSimpleEdge(
true);
710 if(rEdgePolygon.areControlPointsUsed())
712 const B2DPoint aNextControlPoint(rEdgePolygon.getNextControlPoint(a));
713 const B2DPoint aPrevControlPoint(rEdgePolygon.getPrevControlPoint(nNextIndex));
714 const bool bEdgeIsCurve(!aNextControlPoint.equal(aCurr) || !aPrevControlPoint.equal(aNext));
718 bHandleAsSimpleEdge =
false;
719 const B2DCubicBezier aCubicA(aCurr, aNextControlPoint, aPrevControlPoint, aNext);
720 findTouchesOnCurve(aCubicA, rPointPolygon, a, rTempPoints);
724 if(bHandleAsSimpleEdge)
726 findTouchesOnEdge(aCurr, aNext, rPointPolygon, a, rTempPoints);
743 void findCuts(
const B2DPolygon& rCandidateA,
const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
747 const sal_uInt32 nPointCountA(rCandidateA.count());
748 const sal_uInt32 nPointCountB(rCandidateB.count());
750 if(!(nPointCountA && nPointCountB))
753 const sal_uInt32 nEdgeCountA(rCandidateA.isClosed() ? nPointCountA : nPointCountA - 1);
754 const sal_uInt32 nEdgeCountB(rCandidateB.isClosed() ? nPointCountB : nPointCountB - 1);
756 if(!(nEdgeCountA && nEdgeCountB))
759 const bool bCurvesInvolved(rCandidateA.areControlPointsUsed() || rCandidateB.areControlPointsUsed());
763 B2DCubicBezier aCubicA;
764 B2DCubicBezier aCubicB;
766 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
768 rCandidateA.getBezierSegment(a, aCubicA);
769 aCubicA.testAndSolveTrivialBezier();
770 const bool bEdgeAIsCurve(aCubicA.isBezier());
771 const B2DRange aRangeA(aCubicA.getRange());
773 for(sal_uInt32 b(0); b < nEdgeCountB; b++)
775 rCandidateB.getBezierSegment(b, aCubicB);
776 aCubicB.testAndSolveTrivialBezier();
777 const B2DRange aRangeB(aCubicB.getRange());
780 bool bOverlap =
false;
782 bOverlap = aRangeA.overlaps(aRangeB);
784 bOverlap = aRangeA.overlapsMore(aRangeB);
787 const bool bEdgeBIsCurve(aCubicB.isBezier());
788 if(bEdgeAIsCurve && bEdgeBIsCurve)
791 findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, rTempPointsA, rTempPointsB);
793 else if(bEdgeAIsCurve)
796 findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, rTempPointsA, rTempPointsB);
798 else if(bEdgeBIsCurve)
801 findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, rTempPointsB, rTempPointsA);
806 findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(),
807 a, b, rTempPointsA, rTempPointsB);
815 B2DPoint aCurrA(rCandidateA.getB2DPoint(0));
817 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
819 const B2DPoint aNextA(rCandidateA.getB2DPoint(a + 1 == nPointCountA ? 0 : a + 1));
820 const B2DRange aRangeA(aCurrA, aNextA);
821 B2DPoint aCurrB(rCandidateB.getB2DPoint(0));
823 for(sal_uInt32 b(0); b < nEdgeCountB; b++)
825 const B2DPoint aNextB(rCandidateB.getB2DPoint(b + 1 == nPointCountB ? 0 : b + 1));
826 const B2DRange aRangeB(aCurrB, aNextB);
829 bool bOverlap =
false;
831 bOverlap = aRangeA.overlaps(aRangeB);
833 bOverlap = aRangeA.overlapsMore(aRangeB);
837 findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPointsA, rTempPointsB);
858 if(rCandidate.
count())
860 temporaryPointVector aTempPoints;
862 findTouches(rCandidate, rCandidate, aTempPoints);
863 findCuts(rCandidate, aTempPoints, pPointLimit);
864 if (pPointLimit && !*pPointLimit)
866 SAL_WARN(
"basegfx",
"addPointsAtCutsAndTouches hit point limit");
870 return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
894 std::unique_ptr<temporaryPolygonData[]> pTempData(
new temporaryPolygonData[
nCount]);
903 if (pPointLimit && !*pPointLimit)
905 SAL_WARN(
"basegfx",
"addPointsAtCutsAndTouches hit point limit");
912 for(b = 0; b <
nCount; b++)
919 findTouches(pTempData[
a].getPolygon(), pTempData[b].getPolygon(), pTempData[
a].getTemporaryPointVector());
928 findCuts(pTempData[
a].getPolygon(), pTempData[b].getPolygon(), pTempData[
a].getTemporaryPointVector(), pTempData[b].getTemporaryPointVector());
937 aRetval.
append(mergeTemporaryPointsAndPolygon(pTempData[
a].getPolygon(), pTempData[
a].getTemporaryPointVector()));
956 const B2DRange aEdgeRange(rStart, rEnd);
958 if(aPolygonRange.
overlaps(aEdgeRange))
961 temporaryPointVector aTempPoints;
962 temporaryPointVector aUnusedTempPoints;
965 for(sal_uInt32
a(0);
a < nEdgeCount;
a++)
975 if(aCubicRange.
overlaps(aEdgeRange))
977 findEdgeCutsBezierAndEdge(aCubic, rStart, rEnd,
a, 0, aTempPoints, aUnusedTempPoints);
982 if(aCubicRange.
overlaps(aEdgeRange))
989 return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
998 const sal_uInt32 nCountA(rCandidate.
count());
999 const sal_uInt32 nCountM(rPolyMask.
count());
1001 if(nCountA && nCountM)
1008 const sal_uInt32 nEdgeCountA(rCandidate.
isClosed() ? nCountA : nCountA - 1);
1009 temporaryPointVector aTempPointsA;
1010 temporaryPointVector aUnusedTempPointsB;
1012 for(sal_uInt32
m(0);
m < nCountM;
m++)
1015 const sal_uInt32 nCountB(aMask.
count());
1022 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
1025 const bool bCubicAIsCurve(aCubicA.
isBezier());
1034 for(sal_uInt32 b(0); b < nCountB; b++)
1037 const bool bCubicBIsCurve(aCubicB.
isBezier());
1046 if(aCubicRangeA.
overlaps(aCubicRangeB))
1048 if(bCubicAIsCurve && bCubicBIsCurve)
1050 findEdgeCutsTwoBeziers(aCubicA, aCubicB,
a, b, aTempPointsA, aUnusedTempPointsB);
1052 else if(bCubicAIsCurve)
1054 findEdgeCutsBezierAndEdge(aCubicA, aCubicB.
getStartPoint(), aCubicB.
getEndPoint(),
a, b, aTempPointsA, aUnusedTempPointsB);
1056 else if(bCubicBIsCurve)
1058 findEdgeCutsBezierAndEdge(aCubicB, aCubicA.
getStartPoint(), aCubicA.
getEndPoint(), b,
a, aUnusedTempPointsB, aTempPointsA);
1070 return mergeTemporaryPointsAndPolygon(rCandidate, aTempPointsA);
temporaryPointVector maPoints
#define SUBDIVIDE_FOR_CUT_TEST_COUNT
const B2DPoint & getStartPoint() const
const B2DPoint & getControlPointB() const
const B2DPoint & getEndPoint() const
const B2DPoint & getControlPointA() const
Base Point class with two double values.
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
B2DRange getB2DRange() const
Get the B2DRange (Rectangle dimensions) of this B2DPolyPolygon.
bool isClosed() const
closed state interface
void getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier &rTarget) const
bezier segment access
B2DRange const & getB2DRange() const
Get the B2DRange (Rectangle dimensions) of this B2DPolygon.
sal_uInt32 count() const
member count
A two-dimensional interval over doubles.
void expand(const Tuple2D< TYPE > &rTuple)
add point to the set, expanding as necessary
bool overlaps(const Range2D &rRange) const
yields true if rRange at least partly inside set
bool equal(const Tuple2D< TYPE > &rTup) const
#define SAL_WARN(area, stream)
B2DPolygon addPointsAtCuts(const B2DPolygon &rCandidate, const B2DPoint &rStart, const B2DPoint &rEnd)
void closeWithGeometryChange(B2DPolygon &rCandidate)
B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon &rCandidate, size_t *pPointLimit)
B2DRange getRange(const B2DPolygon &rCandidate)
Get the range of a polygon.
B2DTuple interpolate(const B2DTuple &rOld1, const B2DTuple &rOld2, double t)
bool areParallel(const B2DVector &rVecA, const B2DVector &rVecB)
Test two vectors which need not to be normalized for parallelism.
bool operator<(const wwFont &r1, const wwFont &r2)