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 nEdgeCount(rPolygon.count() ? rPolygon.count() - 1 : 0);
184 if(!rPointVector.empty() && nEdgeCount)
186 for(
const auto& rTempPoint : rPointVector )
188 const double fCutPosInPolygon(
static_cast<double>(rTempPoint.getIndex()) + rTempPoint.getCut());
189 const double fRelativeCutPos(fCutPosInPolygon /
static_cast<double>(nEdgeCount));
190 rTempPoints.emplace_back(rTempPoint.getPoint(), nInd, fRelativeCutPos);
205 void findCuts(
const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints,
size_t* pPointLimit =
nullptr);
206 void findTouches(
const B2DPolygon& rEdgePolygon,
const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints);
207 void findCuts(
const B2DPolygon& rCandidateA,
const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB);
209 void findEdgeCutsTwoEdges(
210 const B2DPoint& rCurrA,
const B2DPoint& rNextA,
211 const B2DPoint& rCurrB,
const B2DPoint& rNextB,
212 sal_uInt32 nIndA, sal_uInt32 nIndB,
213 temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
216 if(rCurrA.equal(rNextA) || rCurrB.equal(rNextB))
220 if(rCurrB.equal(rCurrA) || rCurrB.equal(rNextA) || rNextB.equal(rCurrA) || rNextB.equal(rNextA))
223 const B2DVector aVecA(rNextA - rCurrA);
224 const B2DVector aVecB(rNextB - rCurrB);
225 double fCut(aVecA.cross(aVecB));
230 const double fZero(0.0);
231 const double fOne(1.0);
232 fCut = (aVecB.getY() * (rCurrB.getX() - rCurrA.getX()) + aVecB.getX() * (rCurrA.getY() - rCurrB.getY())) / fCut;
241 if(fabs(aVecB.getX()) > fabs(aVecB.getY()))
243 fCut2 = (rCurrA.getX() + (fCut * aVecA.getX()) - rCurrB.getX()) / aVecB.getX();
247 fCut2 = (rCurrA.getY() + (fCut * aVecA.getY()) - rCurrB.getY()) / aVecB.getY();
255 const B2DPoint aCutPoint(
interpolate(rCurrA, rNextA, fCut));
256 rTempPointsA.emplace_back(aCutPoint, nIndA, fCut);
257 rTempPointsB.emplace_back(aCutPoint, nIndB, fCut2);
261 void findCutsAndTouchesAndCommonForBezier(
const B2DPolygon& rCandidateA,
const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
275 OSL_ENSURE(!rCandidateA.areControlPointsUsed() && !rCandidateB.areControlPointsUsed(),
"findCutsAndTouchesAndCommonForBezier only works with subdivided polygons (!)");
276 OSL_ENSURE(!rCandidateA.isClosed() && !rCandidateB.isClosed(),
"findCutsAndTouchesAndCommonForBezier only works with opened polygons (!)");
277 const sal_uInt32 nPointCountA(rCandidateA.count());
278 const sal_uInt32 nPointCountB(rCandidateB.count());
280 if(nPointCountA <= 1 || nPointCountB <= 1)
283 const sal_uInt32 nEdgeCountA(nPointCountA - 1);
284 const sal_uInt32 nEdgeCountB(nPointCountB - 1);
285 B2DPoint aCurrA(rCandidateA.getB2DPoint(0));
287 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
289 const B2DPoint aNextA(rCandidateA.getB2DPoint(a + 1));
290 const B2DRange aRangeA(aCurrA, aNextA);
291 B2DPoint aCurrB(rCandidateB.getB2DPoint(0));
293 for(sal_uInt32 b(0); b < nEdgeCountB; b++)
295 const B2DPoint aNextB(rCandidateB.getB2DPoint(b + 1));
296 const B2DRange aRangeB(aCurrB, aNextB);
298 if(aRangeA.overlaps(aRangeB))
301 if(!(aCurrA.equal(aNextA) || aCurrB.equal(aNextB)))
303 const B2DVector aVecA(aNextA - aCurrA);
304 const B2DVector aVecB(aNextB - aCurrB);
305 double fCutA(aVecA.cross(aVecB));
309 const double fZero(0.0);
310 const double fOne(1.0);
311 fCutA = (aVecB.getY() * (aCurrB.getX() - aCurrA.getX()) + aVecB.getX() * (aCurrA.getY() - aCurrB.getY())) / fCutA;
321 if(fabs(aVecB.getX()) > fabs(aVecB.getY()))
323 fCutB = (aCurrA.getX() + (fCutA * aVecA.getX()) - aCurrB.getX()) / aVecB.getX();
327 fCutB = (aCurrA.getY() + (fCutA * aVecA.getY()) - aCurrB.getY()) / aVecB.getY();
342 rTempPointsA.emplace_back(aCurrA, a, 0.0);
347 const B2DPoint aCutPoint(
interpolate(aCurrA, aNextA, fCutA));
348 rTempPointsA.emplace_back(aCutPoint, a, fCutA);
358 rTempPointsB.emplace_back(aCurrB, b, 0.0);
363 const B2DPoint aCutPoint(
interpolate(aCurrB, aNextB, fCutB));
364 rTempPointsB.emplace_back(aCutPoint, b, fCutB);
381 void findEdgeCutsBezierAndEdge(
382 const B2DCubicBezier& rCubicA,
383 const B2DPoint& rCurrB,
const B2DPoint& rNextB,
384 sal_uInt32 nIndA, sal_uInt32 nIndB,
385 temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
390 B2DPolygon aTempPolygonA;
391 B2DPolygon aTempPolygonEdge;
392 temporaryPointVector aTempPointVectorA;
393 temporaryPointVector aTempPointVectorEdge;
398 aTempPolygonA.append(rCubicA.getStartPoint());
400 aTempPolygonEdge.append(rCurrB);
401 aTempPolygonEdge.append(rNextB);
404 findCutsAndTouchesAndCommonForBezier(aTempPolygonA, aTempPolygonEdge, aTempPointVectorA, aTempPointVectorEdge);
406 if(!aTempPointVectorA.empty())
409 adaptAndTransferCutsWithBezierSegment(aTempPointVectorA, aTempPolygonA, nIndA, rTempPointsA);
413 for(
const temporaryPoint & rTempPoint : aTempPointVectorEdge)
415 rTempPointsB.emplace_back(rTempPoint.getPoint(), nIndB, rTempPoint.getCut());
419 void findEdgeCutsTwoBeziers(
420 const B2DCubicBezier& rCubicA,
421 const B2DCubicBezier& rCubicB,
422 sal_uInt32 nIndA, sal_uInt32 nIndB,
423 temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
428 B2DPolygon aTempPolygonA;
429 B2DPolygon aTempPolygonB;
430 temporaryPointVector aTempPointVectorA;
431 temporaryPointVector aTempPointVectorB;
436 aTempPolygonA.append(rCubicA.getStartPoint());
439 aTempPolygonB.append(rCubicB.getStartPoint());
443 findCutsAndTouchesAndCommonForBezier(aTempPolygonA, aTempPolygonB, aTempPointVectorA, aTempPointVectorB);
445 if(!aTempPointVectorA.empty())
448 adaptAndTransferCutsWithBezierSegment(aTempPointVectorA, aTempPolygonA, nIndA, rTempPointsA);
451 if(!aTempPointVectorB.empty())
454 adaptAndTransferCutsWithBezierSegment(aTempPointVectorB, aTempPolygonB, nIndB, rTempPointsB);
458 void findEdgeCutsOneBezier(
459 const B2DCubicBezier& rCubicA,
460 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
465 const bool bHasAnyExtremum = rCubicA.getMinimumExtremumPosition( fDummy );
466 if( !bHasAnyExtremum )
472 B2DPolygon aTempPolygon;
473 temporaryPointVector aTempPointVector;
478 aTempPolygon.append(rCubicA.getStartPoint());
480 findCuts(aTempPolygon, aTempPointVector);
482 if(!aTempPointVector.empty())
485 adaptAndTransferCutsWithBezierSegment(aTempPointVector, aTempPolygon, nInd, rTempPoints);
489 void findCuts(
const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints,
size_t* pPointLimit)
493 const sal_uInt32 nPointCount(rCandidate.count());
498 const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
503 const bool bCurvesInvolved(rCandidate.areControlPointsUsed());
507 B2DCubicBezier aCubicA;
508 B2DCubicBezier aCubicB;
510 for(sal_uInt32
a(0);
a < nEdgeCount - 1;
a++)
512 rCandidate.getBezierSegment(a, aCubicA);
513 aCubicA.testAndSolveTrivialBezier();
514 const bool bEdgeAIsCurve(aCubicA.isBezier());
515 const B2DRange aRangeA(aCubicA.getRange());
520 findEdgeCutsOneBezier(aCubicA, a, rTempPoints);
523 for(sal_uInt32 b(a + 1); b < nEdgeCount; b++)
525 rCandidate.getBezierSegment(b, aCubicB);
526 aCubicB.testAndSolveTrivialBezier();
527 const B2DRange aRangeB(aCubicB.getRange());
531 bool bOverlap =
false;
533 bOverlap = aRangeA.overlaps(aRangeB);
535 bOverlap = aRangeA.overlapsMore(aRangeB);
538 const bool bEdgeBIsCurve(aCubicB.isBezier());
539 if(bEdgeAIsCurve && bEdgeBIsCurve)
542 findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, rTempPoints, rTempPoints);
544 else if(bEdgeAIsCurve)
547 findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, rTempPoints, rTempPoints);
549 else if(bEdgeBIsCurve)
552 findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, rTempPoints, rTempPoints);
557 findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(),
558 a, b, rTempPoints, rTempPoints);
566 B2DPoint aCurrA(rCandidate.getB2DPoint(0));
568 for(sal_uInt32
a(0);
a < nEdgeCount - 1;
a++)
570 const B2DPoint aNextA(rCandidate.getB2DPoint(a + 1 == nPointCount ? 0 : a + 1));
571 const B2DRange aRangeA(aCurrA, aNextA);
572 B2DPoint aCurrB(rCandidate.getB2DPoint(a + 1));
574 for(sal_uInt32 b(a + 1); b < nEdgeCount; b++)
576 const B2DPoint aNextB(rCandidate.getB2DPoint(b + 1 == nPointCount ? 0 : b + 1));
577 const B2DRange aRangeB(aCurrB, aNextB);
580 bool bOverlap =
false;
582 bOverlap = aRangeA.overlaps(aRangeB);
584 bOverlap = aRangeA.overlapsMore(aRangeB);
587 findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPoints, rTempPoints);
590 if (pPointLimit && rTempPoints.size() > *pPointLimit)
604 if (rTempPoints.size() > *pPointLimit)
607 *pPointLimit -= rTempPoints.size();
619 void findTouchesOnEdge(
620 const B2DPoint& rCurr,
const B2DPoint& rNext,
const B2DPolygon& rPointPolygon,
621 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
625 const sal_uInt32 nPointCount(rPointPolygon.count());
630 const B2DRange aRange(rCurr, rNext);
631 const B2DVector aEdgeVector(rNext - rCurr);
632 bool bTestUsingX(fabs(aEdgeVector.getX()) > fabs(aEdgeVector.getY()));
634 for(sal_uInt32
a(0);
a < nPointCount;
a++)
636 const B2DPoint aTestPoint(rPointPolygon.getB2DPoint(a));
638 if(aRange.isInside(aTestPoint))
640 if(!aTestPoint.equal(rCurr) && !aTestPoint.equal(rNext))
642 const B2DVector aTestVector(aTestPoint - rCurr);
646 const double fCut(bTestUsingX
647 ? aTestVector.getX() / aEdgeVector.getX()
648 : aTestVector.getY() / aEdgeVector.getY());
649 const double fZero(0.0);
650 const double fOne(1.0);
654 rTempPoints.emplace_back(aTestPoint, nInd, fCut);
662 void findTouchesOnCurve(
663 const B2DCubicBezier& rCubicA,
const B2DPolygon& rPointPolygon,
664 sal_uInt32 nInd, temporaryPointVector& rTempPoints)
669 B2DPolygon aTempPolygon;
670 temporaryPointVector aTempPointVector;
675 aTempPolygon.append(rCubicA.getStartPoint());
677 findTouches(aTempPolygon, rPointPolygon, aTempPointVector);
679 if(!aTempPointVector.empty())
682 adaptAndTransferCutsWithBezierSegment(aTempPointVector, aTempPolygon, nInd, rTempPoints);
686 void findTouches(
const B2DPolygon& rEdgePolygon,
const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints)
690 const sal_uInt32 nPointCount(rPointPolygon.count());
691 const sal_uInt32 nEdgePointCount(rEdgePolygon.count());
693 if(!(nPointCount && nEdgePointCount))
696 const sal_uInt32 nEdgeCount(rEdgePolygon.isClosed() ? nEdgePointCount : nEdgePointCount - 1);
697 B2DPoint aCurr(rEdgePolygon.getB2DPoint(0));
699 for(sal_uInt32
a(0);
a < nEdgeCount;
a++)
701 const sal_uInt32 nNextIndex((a + 1) % nEdgePointCount);
702 const B2DPoint aNext(rEdgePolygon.getB2DPoint(nNextIndex));
704 if(!aCurr.equal(aNext))
706 bool bHandleAsSimpleEdge(
true);
708 if(rEdgePolygon.areControlPointsUsed())
710 const B2DPoint aNextControlPoint(rEdgePolygon.getNextControlPoint(a));
711 const B2DPoint aPrevControlPoint(rEdgePolygon.getPrevControlPoint(nNextIndex));
712 const bool bEdgeIsCurve(!aNextControlPoint.equal(aCurr) || !aPrevControlPoint.equal(aNext));
716 bHandleAsSimpleEdge =
false;
717 const B2DCubicBezier aCubicA(aCurr, aNextControlPoint, aPrevControlPoint, aNext);
718 findTouchesOnCurve(aCubicA, rPointPolygon, a, rTempPoints);
722 if(bHandleAsSimpleEdge)
724 findTouchesOnEdge(aCurr, aNext, rPointPolygon, a, rTempPoints);
741 void findCuts(
const B2DPolygon& rCandidateA,
const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB)
745 const sal_uInt32 nPointCountA(rCandidateA.count());
746 const sal_uInt32 nPointCountB(rCandidateB.count());
748 if(!(nPointCountA && nPointCountB))
751 const sal_uInt32 nEdgeCountA(rCandidateA.isClosed() ? nPointCountA : nPointCountA - 1);
752 const sal_uInt32 nEdgeCountB(rCandidateB.isClosed() ? nPointCountB : nPointCountB - 1);
754 if(!(nEdgeCountA && nEdgeCountB))
757 const bool bCurvesInvolved(rCandidateA.areControlPointsUsed() || rCandidateB.areControlPointsUsed());
761 B2DCubicBezier aCubicA;
762 B2DCubicBezier aCubicB;
764 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
766 rCandidateA.getBezierSegment(a, aCubicA);
767 aCubicA.testAndSolveTrivialBezier();
768 const bool bEdgeAIsCurve(aCubicA.isBezier());
769 const B2DRange aRangeA(aCubicA.getRange());
771 for(sal_uInt32 b(0); b < nEdgeCountB; b++)
773 rCandidateB.getBezierSegment(b, aCubicB);
774 aCubicB.testAndSolveTrivialBezier();
775 const B2DRange aRangeB(aCubicB.getRange());
778 bool bOverlap =
false;
780 bOverlap = aRangeA.overlaps(aRangeB);
782 bOverlap = aRangeA.overlapsMore(aRangeB);
785 const bool bEdgeBIsCurve(aCubicB.isBezier());
786 if(bEdgeAIsCurve && bEdgeBIsCurve)
789 findEdgeCutsTwoBeziers(aCubicA, aCubicB, a, b, rTempPointsA, rTempPointsB);
791 else if(bEdgeAIsCurve)
794 findEdgeCutsBezierAndEdge(aCubicA, aCubicB.getStartPoint(), aCubicB.getEndPoint(), a, b, rTempPointsA, rTempPointsB);
796 else if(bEdgeBIsCurve)
799 findEdgeCutsBezierAndEdge(aCubicB, aCubicA.getStartPoint(), aCubicA.getEndPoint(), b, a, rTempPointsB, rTempPointsA);
804 findEdgeCutsTwoEdges(aCubicA.getStartPoint(), aCubicA.getEndPoint(), aCubicB.getStartPoint(), aCubicB.getEndPoint(),
805 a, b, rTempPointsA, rTempPointsB);
813 B2DPoint aCurrA(rCandidateA.getB2DPoint(0));
815 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
817 const B2DPoint aNextA(rCandidateA.getB2DPoint(a + 1 == nPointCountA ? 0 : a + 1));
818 const B2DRange aRangeA(aCurrA, aNextA);
819 B2DPoint aCurrB(rCandidateB.getB2DPoint(0));
821 for(sal_uInt32 b(0); b < nEdgeCountB; b++)
823 const B2DPoint aNextB(rCandidateB.getB2DPoint(b + 1 == nPointCountB ? 0 : b + 1));
824 const B2DRange aRangeB(aCurrB, aNextB);
827 bool bOverlap =
false;
829 bOverlap = aRangeA.overlaps(aRangeB);
831 bOverlap = aRangeA.overlapsMore(aRangeB);
835 findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPointsA, rTempPointsB);
856 if(rCandidate.
count())
858 temporaryPointVector aTempPoints;
860 findTouches(rCandidate, rCandidate, aTempPoints);
861 findCuts(rCandidate, aTempPoints, pPointLimit);
862 if (pPointLimit && !*pPointLimit)
864 SAL_WARN(
"basegfx",
"addPointsAtCutsAndTouches hit point limit");
868 return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
892 std::unique_ptr<temporaryPolygonData[]> pTempData(
new temporaryPolygonData[
nCount]);
901 if (pPointLimit && !*pPointLimit)
903 SAL_WARN(
"basegfx",
"addPointsAtCutsAndTouches hit point limit");
910 for(b = 0; b <
nCount; b++)
917 findTouches(pTempData[
a].getPolygon(), pTempData[b].getPolygon(), pTempData[
a].getTemporaryPointVector());
926 findCuts(pTempData[
a].getPolygon(), pTempData[b].getPolygon(), pTempData[
a].getTemporaryPointVector(), pTempData[b].getTemporaryPointVector());
935 aRetval.
append(mergeTemporaryPointsAndPolygon(pTempData[
a].getPolygon(), pTempData[
a].getTemporaryPointVector()));
954 const B2DRange aEdgeRange(rStart, rEnd);
956 if(aPolygonRange.
overlaps(aEdgeRange))
959 temporaryPointVector aTempPoints;
960 temporaryPointVector aUnusedTempPoints;
963 for(sal_uInt32
a(0);
a < nEdgeCount;
a++)
973 if(aCubicRange.
overlaps(aEdgeRange))
975 findEdgeCutsBezierAndEdge(aCubic, rStart, rEnd,
a, 0, aTempPoints, aUnusedTempPoints);
980 if(aCubicRange.
overlaps(aEdgeRange))
987 return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
996 const sal_uInt32 nCountA(rCandidate.
count());
997 const sal_uInt32 nCountM(rPolyMask.
count());
999 if(nCountA && nCountM)
1006 const sal_uInt32 nEdgeCountA(rCandidate.
isClosed() ? nCountA : nCountA - 1);
1007 temporaryPointVector aTempPointsA;
1008 temporaryPointVector aUnusedTempPointsB;
1010 for(sal_uInt32
m(0);
m < nCountM;
m++)
1013 const sal_uInt32 nCountB(aMask.
count());
1020 for(sal_uInt32
a(0);
a < nEdgeCountA;
a++)
1023 const bool bCubicAIsCurve(aCubicA.
isBezier());
1032 for(sal_uInt32 b(0); b < nCountB; b++)
1035 const bool bCubicBIsCurve(aCubicB.
isBezier());
1044 if(aCubicRangeA.
overlaps(aCubicRangeB))
1046 if(bCubicAIsCurve && bCubicBIsCurve)
1048 findEdgeCutsTwoBeziers(aCubicA, aCubicB,
a, b, aTempPointsA, aUnusedTempPointsB);
1050 else if(bCubicAIsCurve)
1052 findEdgeCutsBezierAndEdge(aCubicA, aCubicB.
getStartPoint(), aCubicB.
getEndPoint(),
a, b, aTempPointsA, aUnusedTempPointsB);
1054 else if(bCubicBIsCurve)
1056 findEdgeCutsBezierAndEdge(aCubicB, aCubicA.
getStartPoint(), aCubicA.
getEndPoint(), b,
a, aUnusedTempPointsB, aTempPointsA);
1068 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)