20#include <osl/endian.h>
21#include <osl/diagnose.h>
54#define FSQRT2 1.4142135623730950488016887242097
58 const double nDX =
static_cast<double>(rPt.
X()) - rCenter.
X();
59 const double nDY =
static_cast<double>(rCenter.
Y()) - rPt.
Y();
60 double fAngle = atan2(nDY, nDX);
62 return atan2(fWR*sin(fAngle), fHR*cos(fAngle));
97 memcpy(
mxFlagAry.get(), pInitFlags, nInitSize);
126 nHorzRound = std::min( nHorzRound,
static_cast<sal_uInt32
>(
std::abs( aRect.
GetWidth() >> 1 )) );
127 nVertRound = std::min( nVertRound,
static_cast<sal_uInt32
>(
std::abs( aRect.
GetHeight() >> 1 )) );
129 if( !nHorzRound && !nVertRound )
140 const Point aTL( aRect.
Left() + nHorzRound, aRect.
Top() + nVertRound );
141 const Point aTR( aRect.
Right() - nHorzRound, aRect.
Top() + nVertRound );
143 const Point aBL( aRect.
Left() + nHorzRound, aRect.
Bottom() - nVertRound );
145 sal_uInt16
i, nEnd, nSize4 = aEllipsePoly.
GetSize() >> 2;
152 for(
i = 0, nEnd = nSize4;
i < nEnd;
i++ )
153 pDstAry[
i ] = pSrcAry[
i ] + aTR;
155 for( nEnd = nEnd + nSize4;
i < nEnd;
i++ )
156 pDstAry[
i ] = pSrcAry[
i ] + aTL;
158 for( nEnd = nEnd + nSize4;
i < nEnd;
i++ )
159 pDstAry[
i ] = pSrcAry[
i ] + aBL;
161 for( nEnd = nEnd + nSize4;
i < nEnd;
i++ )
162 pDstAry[
i ] = pSrcAry[
i ] + aBR;
164 pDstAry[ nEnd ] = pDstAry[ 0 ];
181 nPoints =
static_cast<sal_uInt16
>(
MinMax(
182 ( M_PI * ( 1.5 * ( nRadX + nRadY ) -
183 sqrt(
static_cast<double>(
std::abs(nRadXY)) ) ) ),
191 if( ( nRadX > 32 ) && ( nRadY > 32 ) && ( nRadX + nRadY ) < 8192 )
195 nPoints = (nPoints + 3) & ~3;
199 sal_uInt16 nPoints2 = nPoints >> 1;
200 sal_uInt16 nPoints4 = nPoints >> 2;
202 double nAngleStep = M_PI_2 / ( nPoints4 - 1 );
204 for(
i=0, nAngle = 0.0;
i < nPoints4;
i++, nAngle += nAngleStep )
210 pPt->
setX( nX + rCenter.
X() );
211 pPt->
setY( nY + rCenter.
Y() );
213 pPt->
setX( -nX + rCenter.
X() );
214 pPt->
setY( nY + rCenter.
Y() );
216 pPt->
setX( -nX + rCenter.
X() );
217 pPt->
setY( -nY + rCenter.
Y() );
219 pPt->
setX( nX + rCenter.
X() );
220 pPt->
setY( -nY + rCenter.
Y() );
228 PolyStyle eStyle,
const bool bClockWiseArcDirection)
230 const auto nWidth = rBound.
GetWidth();
233 if ((nWidth != 0) && (nHeight != 0))
237 const auto aBoundLeft = rBound.
Left() < aCenter.
X() ? rBound.
Left() : rBound.
Right();
238 const auto aBoundTop = rBound.
Top() < aCenter.
Y() ? rBound.
Top() : rBound.
Bottom();
247 nPoints =
static_cast<sal_uInt16
>(
MinMax(
248 ( M_PI * ( 1.5 * ( nRadX + nRadY ) -
249 sqrt(
static_cast<double>(
std::abs(nRadXY)) ) ) ),
262 const double fRadX = nRadX;
263 const double fRadY = nRadY;
264 const double fCenterX = aCenter.
X();
265 const double fCenterY = aCenter.
Y();
268 double fDiff = fEnd - fStart;
273 if (bClockWiseArcDirection ==
false)
281 fDiff = (2. * M_PI) - fDiff;
282 if (fDiff > 2. * M_PI)
287 nPoints = std::max(
static_cast<sal_uInt16
>((fDiff / (2. * M_PI)) * nPoints), sal_uInt16(16));
288 fStep = fDiff / (nPoints - 1);
289 if (bClockWiseArcDirection ==
true)
309 for(; nStart < nEnd; nStart++, fStart += fStep )
313 rPt.
setX(
FRound( fCenterX + fRadX * cos( fStart ) ) );
314 rPt.
setY(
FRound( fCenterY - fRadY * sin( fStart ) ) );
325 const Point& rBezPt2,
const Point& rCtrlPt2, sal_uInt16 nPoints )
327 nPoints = ( 0 == nPoints ) ? 25 : ( ( nPoints < 2 ) ? 2 : nPoints );
329 const double fInc = 1.0 / ( nPoints - 1 );
330 double fK_1 = 0.0, fK1_1 = 1.0;
331 double fK_2, fK_3, fK1_2, fK1_3;
332 const double fX0 = rBezPt1.
X();
333 const double fY0 = rBezPt1.
Y();
334 const double fX1 = 3.0 * rCtrlPt1.
X();
335 const double fY1 = 3.0 * rCtrlPt1.
Y();
336 const double fX2 = 3.0 * rCtrlPt2.
X();
337 const double fY2 = 3.0 * rCtrlPt2.
Y();
338 const double fX3 = rBezPt2.
X();
339 const double fY3 = rBezPt2.
Y();
343 for( sal_uInt16
i = 0;
i < nPoints;
i++, fK_1 += fInc, fK1_1 -= fInc )
355 double fK12 = fK_1 * fK1_2;
356 double fK21 = fK_2 * fK1_1;
358 rPt.
setX(
FRound( fK1_3 * fX0 + fK12 * fX1 + fK21 * fX2 + fK_3 * fX3 ) );
359 rPt.
setY(
FRound( fK1_3 * fY0 + fK12 * fY1 + fK21 * fY2 + fK_3 * fY3 ) );
373 const bool bClosed(rPolygon.
isClosed());
374 sal_uInt32 nB2DLocalCount(rPolygon.
count());
379 if(nB2DLocalCount > ((0x0000ffff / 3) - 1))
381 OSL_FAIL(
"Polygon::Polygon: Too many points in given B2DPolygon, need to reduce hard to maximum of tools Polygon (!)");
382 nB2DLocalCount = ((0x0000ffff / 3) - 1);
386 const sal_uInt32 nLoopCount(bClosed ? nB2DLocalCount : (nB2DLocalCount ? nB2DLocalCount - 1 : 0 ));
391 const sal_uInt32 nMaxTargetCount((nLoopCount * 3) + 1);
392 ImplInitSize(
static_cast< sal_uInt16
>(nMaxTargetCount),
true);
395 sal_uInt32 nArrayInsert(0);
399 for(sal_uInt32
a(0);
a < nLoopCount;
a++)
403 const sal_uInt32 nStartPointIndex(nArrayInsert);
409 const sal_uInt32 nNextIndex((
a + 1) % nB2DLocalCount);
462 DBG_ASSERT(nArrayInsert <= nMaxTargetCount,
"Polygon::Polygon from basegfx::B2DPolygon: wrong max point count estimation (!)");
464 if(nArrayInsert != nMaxTargetCount)
466 ImplSetSize(
static_cast< sal_uInt16
>(nArrayInsert));
473 if(nB2DLocalCount > (0x0000ffff - 1))
475 OSL_FAIL(
"Polygon::Polygon: Too many points in given B2DPolygon, need to reduce hard to maximum of tools Polygon (!)");
476 nB2DLocalCount = (0x0000ffff - 1);
482 const sal_uInt32 nTargetCount(nB2DLocalCount + (bClosed ? 1 : 0));
486 for(sal_uInt32
a(0);
a < nB2DLocalCount;
a++)
530 std::unique_ptr<Point[]> xNewAry;
534 const std::size_t nNewSz(
static_cast<std::size_t
>(nNewSize)*
sizeof(
Point));
535 xNewAry.reset(
new Point[nNewSize]);
545 memcpy(xNewAry.get(),
mxPointAry.get(), nOldSz);
550 memcpy(xNewAry.get(),
mxPointAry.get(), nNewSz);
560 std::unique_ptr<PolyFlags[]> xNewFlagAry;
564 xNewFlagAry.reset(
new PolyFlags[nNewSize]);
576 memcpy(xNewFlagAry.get(),
mxFlagAry.get(), nNewSize);
591 SAL_WARN(
"tools",
"Polygon needs " <<
mnPoints + nSpace <<
" points, but only " << USHRT_MAX <<
" possible");
595 const sal_uInt16 nNewSize =
mnPoints + nSpace;
596 const std::size_t nSpaceSize =
static_cast<std::size_t
>(nSpace) *
sizeof(
Point);
614 const sal_uInt16 nSecPos =
nPos + nSpace;
617 std::unique_ptr<Point[]> xNewAry(
new Point[nNewSize]);
621 memcpy(xNewAry.get() +
nPos, pInitPoly->
mxPointAry.get(), nSpaceSize);
629 std::unique_ptr<PolyFlags[]> xNewFlagAry(
new PolyFlags[nNewSize]);
634 memcpy(xNewFlagAry.get() +
nPos, pInitPoly->
mxFlagAry.get(), nSpace);
636 memset(xNewFlagAry.get() +
nPos, 0, nSpace);
638 memcpy(xNewFlagAry.get() + nSecPos,
mxFlagAry.get() +
nPos, nRest);
662 virtual void LastPoint() = 0;
663 virtual void Input(
const Point& rPoint ) = 0;
666 ~ImplPointFilter() {}
669class ImplPolygonPointFilter :
public ImplPointFilter
674 explicit ImplPolygonPointFilter(sal_uInt16 nDestSize)
680 virtual ~ImplPolygonPointFilter()
684 virtual void LastPoint()
override;
685 virtual void Input(
const Point& rPoint )
override;
692void ImplPolygonPointFilter::Input(
const Point& rPoint )
694 if ( !mnSize || (rPoint != maPoly.mxPointAry[mnSize-1]) )
697 if ( mnSize > maPoly.mnPoints )
698 maPoly.ImplSetSize( mnSize );
699 maPoly.mxPointAry[
mnSize-1] = rPoint;
703void ImplPolygonPointFilter::LastPoint()
705 if ( mnSize < maPoly.mnPoints )
706 maPoly.ImplSetSize( mnSize );
711class ImplEdgePointFilter :
public ImplPointFilter
715 ImplPointFilter& mrNextFilter;
724 ImplPointFilter& rNextFilter ) :
725 mrNextFilter( rNextFilter ),
734 virtual ~ImplEdgePointFilter() {}
736 Point EdgeSection(
const Point& rPoint,
int nEdge )
const;
737 int VisibleSide(
const Point& rPoint )
const;
738 bool IsPolygon()
const
739 {
return maFirstPoint == maLastPoint; }
741 virtual void Input(
const Point& rPoint )
override;
742 virtual void LastPoint()
override;
747inline int ImplEdgePointFilter::VisibleSide(
const Point& rPoint )
const
761Point ImplEdgePointFilter::EdgeSection(
const Point& rPoint,
int nEdge )
const
772 nNewY = (nEdge ==
EDGE_TOP) ? mnLow : mnHigh;
777 nNewX = (dy * md) / mn + lx;
798 nNewX = (nEdge ==
EDGE_LEFT) ? mnLow : mnHigh;
803 nNewY = (dx * mn) /
md + ly;
823 return Point( nNewX, nNewY );
826void ImplEdgePointFilter::Input(
const Point& rPoint )
828 int nOutside = VisibleSide( rPoint );
832 maFirstPoint = rPoint;
835 mrNextFilter.Input( rPoint );
837 else if ( rPoint == maLastPoint )
839 else if ( !nOutside )
842 mrNextFilter.Input( EdgeSection( rPoint, mnLastOutside ) );
843 mrNextFilter.Input( rPoint );
845 else if ( !mnLastOutside )
846 mrNextFilter.Input( EdgeSection( rPoint, nOutside ) );
847 else if ( nOutside != mnLastOutside )
849 mrNextFilter.Input( EdgeSection( rPoint, mnLastOutside ) );
850 mrNextFilter.Input( EdgeSection( rPoint, nOutside ) );
853 maLastPoint = rPoint;
854 mnLastOutside = nOutside;
857void ImplEdgePointFilter::LastPoint()
861 int nOutside = VisibleSide( maFirstPoint );
863 if ( nOutside != mnLastOutside )
864 Input( maFirstPoint );
865 mrNextFilter.LastPoint();
899 : mpImplPolygon(std::move(rPoly.mpImplPolygon))
908 : mpImplPolygon(
ImplPolygon(rRect, nHorzRound, nVertRound))
913 : mpImplPolygon(
ImplPolygon(rCenter, nRadX, nRadY))
918 PolyStyle eStyle,
const bool bClockWiseArcDirection)
919 : mpImplPolygon(
ImplPolygon(rBound, rStart, rEnd, eStyle, bClockWiseArcDirection))
925 sal_uInt16 nPoints ) : mpImplPolygon(
ImplPolygon(rBezPt1, rCtrlPt1, rBezPt2, rCtrlPt2, nPoints))
951 "Polygon::SetPoint(): nPos >= nPoints" );
959 "Polygon::SetFlags(): nPos >= nPoints" );
973 "Polygon::GetPoint(): nPos >= nPoints" );
981 "Polygon::GetFlags(): nPos >= nPoints" );
994 bool bIsRect =
false;
1031 "Polygon::CalcDistance(): nPos1 >= nPoints" );
1033 "Polygon::CalcDistance(): nPos2 >= nPoints" );
1037 const double fDx = rP2.
X() - rP1.
X();
1038 const double fDy = rP2.
Y() - rP1.
Y();
1040 return std::hypot( fDx, fDy );
1047 if( !(
bool(nOptimizeFlags) && nSize) )
1054 const sal_uInt16 nPercent = 50;
1064 while( nSize && (
mpImplPolygon->mxPointAry[ nSize - 1 ] == rFirst ) )
1069 sal_uInt16 nLast = 0, nNewCount = 1;
1072 aNewPoly[ 0 ] = rFirst;
1074 for( sal_uInt16
i = 1;
i < nSize;
i++ )
1083 if( nNewCount == 1 )
1086 aNewPoly.
SetSize( nNewCount );
1123 const double old_d2,
1126 const double P1x,
const double P1y,
1127 const double P2x,
const double P2y,
1128 const double P3x,
const double P3y,
1129 const double P4x,
const double P4y )
1132 enum {maxRecursionDepth=128};
1144 const double fJ1x( P2x - P1x - 1.0/3.0*(P4x - P1x) );
1145 const double fJ1y( P2y - P1y - 1.0/3.0*(P4y - P1y) );
1146 const double fJ2x( P3x - P1x - 2.0/3.0*(P4x - P1x) );
1147 const double fJ2y( P3y - P1y - 2.0/3.0*(P4y - P1y) );
1148 const double distance2( ::std::max( fJ1x*fJ1x + fJ1y*fJ1y,
1149 fJ2x*fJ2x + fJ2y*fJ2y) );
1157 recursionDepth < maxRecursionDepth &&
1163 const double L1x( P1x ), L1y( P1y );
1164 const double L2x( (P1x + P2x)*0.5 ), L2y( (P1y + P2y)*0.5 );
1165 const double Hx ( (P2x + P3x)*0.5 ), Hy ( (P2y + P3y)*0.5 );
1166 const double L3x( (L2x + Hx)*0.5 ), L3y( (L2y + Hy)*0.5 );
1167 const double R4x( P4x ), R4y( P4y );
1168 const double R3x( (P3x + P4x)*0.5 ), R3y( (P3y + P4y)*0.5 );
1169 const double R2x( (Hx + R3x)*0.5 ), R2y( (Hy + R3y)*0.5 );
1170 const double R1x( (L3x + R2x)*0.5 ), R1y( (L3y + R2y)*0.5 );
1171 const double L4x( R1x ), L4y( R1y );
1175 ImplAdaptiveSubdivide(rPoints, distance2, recursionDepth, d2, L1x, L1y, L2x, L2y, L3x, L3y, L4x, L4y);
1176 ImplAdaptiveSubdivide(rPoints, distance2, recursionDepth, d2, R1x, R1y, R2x, R2y, R3x, R3y, R4x, R4y);
1197 ::std::vector< Point > aPoints;
1198 aPoints.reserve( nPts );
1202 if( (
i + 3 ) < nPts )
1227 "Polygon::AdaptiveSubdivision created polygon too many points;"
1228 " using original polygon instead");
1239 rResult =
tools::Polygon(
static_cast<sal_uInt16
>(aPoints.size()) );
1240 ::std::copy(aPoints.begin(), aPoints.end(), rResult.
mpImplPolygon->mxPointAry.
get());
1252 explicit Vector2D(
const Point& rPoint ) :
mfX( rPoint.
X() ),
mfY( rPoint.
Y() ) {};
1253 double GetLength()
const {
return hypot(
mfX,
mfY ); }
1254 Vector2D&
operator-=(
const Vector2D& rVec ) {
mfX -= rVec.mfX;
mfY -= rVec.mfY;
return *
this; }
1255 double Scalar(
const Vector2D& rVec )
const {
return mfX * rVec.mfX +
mfY * rVec.mfY ; }
1256 Vector2D& Normalize();
1257 bool IsPositive( Vector2D
const & rVec )
const {
return (
mfX * rVec.mfY -
mfY * rVec.mfX ) >= 0.0; }
1258 bool IsNegative( Vector2D
const & rVec )
const {
return !IsPositive( rVec ); }
1263Vector2D& Vector2D::Normalize()
1265 double fLen = Scalar( *
this );
1267 if( ( fLen != 0.0 ) && ( fLen != 1.0 ) )
1269 fLen = sqrt( fLen );
1282 const double fBound = 2000.0 * ( 100 - nPercent ) * 0.01;
1283 sal_uInt16 nNumNoChange = 0,
1286 while( nNumNoChange < 2 )
1288 sal_uInt16 nPntCnt = rPoly.
GetSize(), nNewPos = 0;
1290 bool bChangeInThisRun =
false;
1292 for( sal_uInt16
n = 0;
n < nPntCnt;
n++ )
1294 bool bDeletePoint =
false;
1296 if( (
n + nNumRuns ) % 2 )
1298 sal_uInt16 nIndPrev = !
n ? nPntCnt - 1 :
n - 1;
1299 sal_uInt16 nIndPrevPrev = !nIndPrev ? nPntCnt - 1 : nIndPrev - 1;
1300 sal_uInt16 nIndNext = (
n == nPntCnt-1 ) ? 0 :
n + 1;
1301 sal_uInt16 nIndNextNext = ( nIndNext == nPntCnt - 1 ) ? 0 : nIndNext + 1;
1302 Vector2D aVec1( rPoly[ nIndPrev ] ); aVec1 -= Vector2D(rPoly[ nIndPrevPrev ]);
1303 Vector2D aVec2( rPoly[
n ] ); aVec2 -= Vector2D(rPoly[ nIndPrev ]);
1304 Vector2D aVec3( rPoly[ nIndNext ] ); aVec3 -= Vector2D(rPoly[
n ]);
1305 Vector2D aVec4( rPoly[ nIndNextNext ] ); aVec4 -= Vector2D(rPoly[ nIndNext ]);
1306 double fDist1 = aVec1.GetLength(), fDist2 = aVec2.GetLength();
1307 double fDist3 = aVec3.GetLength(), fDist4 = aVec4.GetLength();
1308 double fTurnB = aVec2.Normalize().Scalar( aVec3.Normalize() );
1311 bDeletePoint =
true;
1314 Vector2D aVecB( rPoly[ nIndNext ] );
1315 aVecB -= Vector2D(rPoly[ nIndPrev ] );
1316 double fDistB = aVecB.GetLength();
1317 double fLenWithB = fDist2 + fDist3;
1318 double fLenFact = ( fDistB != 0.0 ) ? fLenWithB / fDistB : 1.0;
1319 double fTurnPrev = aVec1.Normalize().Scalar( aVec2 );
1320 double fTurnNext = aVec3.Scalar( aVec4.Normalize() );
1321 double fGradPrev, fGradB, fGradNext;
1326 fGradPrev =
basegfx::rad2deg(acos(fTurnPrev)) * (aVec1.IsNegative(aVec2) ? -1 : 1);
1328 fGradB =
basegfx::rad2deg(acos(fTurnB)) * (aVec2.IsNegative(aVec3) ? -1 : 1);
1333 fGradNext =
basegfx::rad2deg(acos(fTurnNext)) * (aVec3.IsNegative(aVec4) ? -1 : 1);
1335 if( ( fGradPrev > 0.0 && fGradB < 0.0 && fGradNext > 0.0 ) ||
1336 ( fGradPrev < 0.0 && fGradB > 0.0 && fGradNext < 0.0 ) )
1339 ( ( ( fDist1 + fDist4 ) / ( fDist2 + fDist3 ) ) * 2000.0 ) > fBound )
1341 bDeletePoint =
true;
1346 double fRelLen = 1.0 - sqrt( fDistB / rArea );
1350 else if( fRelLen > 1.0 )
1353 if( ( std::round( ( fLenFact - 1.0 ) * 1000000.0 ) < fBound ) &&
1354 ( fabs( fGradB ) <= ( fRelLen * fBound * 0.01 ) ) )
1356 bDeletePoint =
true;
1363 aNewPoly[ nNewPos++ ] = rPoly[
n ];
1365 bChangeInThisRun =
true;
1368 if( bChangeInThisRun && nNewPos )
1384 if ( !nHorzMove && !nVertMove )
1389 for ( sal_uInt16
i = 0;
i <
nCount;
i++ )
1415 nAngle10 %= 3600_deg10;
1419 const double fAngle =
toRadians(nAngle10);
1420 Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
1435 rPt.
setX(
FRound(fCos * nX + fSin * nY + nCenterX) );
1436 rPt.
setY(
FRound(-(fSin * nX - fCos * nY - nCenterY)) );
1451 ImplPolygonPointFilter aPolygon( nSourceSize );
1452 ImplEdgePointFilter aHorzFilter(
EDGE_HORZ, aJustifiedRect.
Left(), aJustifiedRect.
Right(),
1454 ImplEdgePointFilter aVertFilter(
EDGE_VERT, aJustifiedRect.
Top(), aJustifiedRect.
Bottom(),
1457 for ( sal_uInt16
i = 0;
i < nSourceSize;
i++ )
1459 if ( aVertFilter.IsPolygon() )
1460 aVertFilter.LastPoint();
1462 aPolygon.LastPoint();
1487 nXMin = nXMax = pFirstPt.
X();
1488 nYMin = nYMax = pFirstPt.
Y();
1490 for ( sal_uInt16
i = 0;
i <
nCount;
i++ )
1494 if (rPt.
X() < nXMin)
1496 if (rPt.
X() > nXMax)
1498 if (rPt.
Y() < nYMin)
1500 if (rPt.
Y() > nYMax)
1512 const Line aLine( rPoint,
Point( aBound.
Right() + 100, rPoint.
Y() ) );
1514 sal_uInt16 nPCounter = 0;
1519 Point aIntersection;
1520 Point aLastIntersection;
1525 for ( sal_uInt16
i = 1;
i <=
nCount;
i++ )
1534 if ( aIntersection != aLastIntersection )
1536 aLastIntersection = aIntersection;
1542 aLastIntersection = aIntersection;
1552 return ( ( nPCounter & 1 ) == 1 );
1566 const sal_uInt16 nInsertCount = rPoly.
mpImplPolygon->mnPoints;
1582 assert( nPos < mpImplPolygon->mnPoints );
1595 mpImplPolygon = std::move(rPoly.mpImplPolygon);
1606 bool bIsEqual =
true;
1627 sal_uInt16 nPoints(0);
1632 const size_t nMaxRecordsPossible = rIStream.
remainingSize() / (2 *
sizeof(sal_Int32));
1633 if (nPoints > nMaxRecordsPossible)
1635 SAL_WARN(
"tools",
"Polygon claims " << nPoints <<
" records, but only " << nMaxRecordsPossible <<
" possible");
1636 nPoints = nMaxRecordsPossible;
1641 for (sal_uInt16
i = 0;
i < nPoints;
i++)
1643 sal_Int32 nTmpX(0), nTmpY(0);
1654 sal_uInt16 nPoints = rPoly.
GetSize();
1659 for (sal_uInt16
i = 0;
i < nPoints;
i++)
1675 if ( bHasPolyFlags )
1700 if ( bHasPolyFlags )
1714 const sal_uInt32 nPointCount(roPolygon.
count());
1715 OSL_ENSURE(
nIndex < nPointCount,
"impCorrectContinuity: index access out of range (!)");
1748 const double fDirectionLen =
aDirection.getLength();
1749 if (fDirectionLen == 0.0)
1755 const double fInvDirectionLen(1.0 / fDirectionLen);
1763 const double fMedLength((aNext.
getLength() + aPrev.
getLength()) * (0.5 / fDirectionLen));
1786 Point aControlA, aControlB;
1790 bool bControlA(
false);
1791 bool bControlB(
false);
1799 if(a < nCount && PolyFlags::Control == mpImplPolygon->mxFlagAry[
a])
1806 OSL_ENSURE(bControlA == bControlB,
"Polygon::getB2DPolygon: Invalid source polygon (!)");
void ImplCreateFlagArray()
void ImplInitSize(sal_uInt16 nInitSize, bool bFlags=false)
std::unique_ptr< Point[]> mxPointAry
bool ImplSplit(sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon const *pInitPoly=nullptr)
void ImplSetSize(sal_uInt16 nSize, bool bResize=true)
bool operator==(const ImplPolygon &rCandidate) const
std::unique_ptr< PolyFlags[]> mxFlagAry
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
SvStream & WriteInt32(sal_Int32 nInt32)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteBool(bool b)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
sal_uInt64 remainingSize()
SvStream & ReadUChar(unsigned char &rChar)
void setStartPoint(const B2DPoint &rValue)
const B2DPoint & getStartPoint() const
const B2DPoint & getControlPointB() const
void setControlPointA(const B2DPoint &rValue)
void setEndPoint(const B2DPoint &rValue)
void setControlPointB(const B2DPoint &rValue)
const B2DPoint & getEndPoint() const
const B2DPoint & getControlPointA() const
bool isPrevControlPointUsed(sal_uInt32 nIndex) const
bool isNextControlPointUsed(sal_uInt32 nIndex) const
void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const
bool areControlPointsUsed() const
B2VectorContinuity getContinuityInPoint(sal_uInt32 nIndex) const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const
void appendBezierSegment(const basegfx::B2DPoint &rNextControlPoint, const basegfx::B2DPoint &rPrevControlPoint, const basegfx::B2DPoint &rPoint)
#define DBG_ASSERT(sCon, aError)
Degree100 abs(Degree100 x)
tools::Long FRound(double fVal)
std::enable_if< std::is_signed< T >::value||std::is_floating_point< T >::value, long >::type MinMax(T nVal, tools::Long nMin, tools::Long nMax)
#define SAL_WARN(area, stream)
void checkClosed(B2DPolygon &rCandidate)
constexpr double rad2deg(double v)
constexpr sal_Int64 md(U i, U)
std::enable_if< std::is_signed< T >::value, bool >::type checked_multiply(T a, T b, T &result)
constexpr T saturating_add(T a, T b)
constexpr T saturating_sub(T a, T b)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
static double ImplGetParameter(const Point &rCenter, const Point &rPt, double fWR, double fHR)
constexpr double SMALL_DVALUE
constexpr int EDGE_BOTTOM
timeval & operator-=(timeval &t1, const timeval &t2)
css::drawing::Direction3D aDirection