| 1327 | } |
| 1328 | |
| 1329 | Rectf Path2d::calcPreciseBoundingBox() const |
| 1330 | { |
| 1331 | if( mPoints.empty() ) |
| 1332 | return Rectf(); |
| 1333 | else if( mPoints.size() == 1 ) |
| 1334 | return Rectf( mPoints[0], mPoints[0] ); |
| 1335 | else if( mPoints.size() == 2 ) |
| 1336 | return Rectf( mPoints[0], mPoints[1] ); |
| 1337 | |
| 1338 | Rectf result( mPoints[0], mPoints[0] ); |
| 1339 | size_t firstPoint = 0; |
| 1340 | for( size_t s = 0; s < mSegments.size(); ++s ) { |
| 1341 | switch( mSegments[s] ) { |
| 1342 | case CUBICTO: { |
| 1343 | float monotoneT[4]; |
| 1344 | int monotoneCnt = calcCubicBezierMonotoneRegions( &(mPoints[firstPoint]), monotoneT ); |
| 1345 | for( int monotoneIdx = 0; monotoneIdx < monotoneCnt; ++monotoneIdx ) |
| 1346 | result.include( calcCubicBezierPos( &(mPoints[firstPoint]), monotoneT[monotoneIdx] ) ); |
| 1347 | result.include( mPoints[firstPoint+0] ); |
| 1348 | result.include( mPoints[firstPoint+3] ); |
| 1349 | } |
| 1350 | break; |
| 1351 | case QUADTO: { |
| 1352 | float monotoneT[2]; |
| 1353 | int monotoneCnt = calcQuadraticBezierMonotoneRegions( &(mPoints[firstPoint]), monotoneT ); |
| 1354 | for( int monotoneIdx = 0; monotoneIdx < monotoneCnt; ++monotoneIdx ) |
| 1355 | result.include( calcQuadraticBezierPos( &(mPoints[firstPoint]), monotoneT[monotoneIdx] ) ); |
| 1356 | result.include( mPoints[firstPoint+0] ); |
| 1357 | result.include( mPoints[firstPoint+2] ); |
| 1358 | } |
| 1359 | break; |
| 1360 | case LINETO: |
| 1361 | result.include( mPoints[firstPoint] ); |
| 1362 | result.include( mPoints[firstPoint+1] ); |
| 1363 | break; |
| 1364 | case CLOSE: |
| 1365 | break; |
| 1366 | default: |
| 1367 | throw Path2dExc(); |
| 1368 | } |
| 1369 | |
| 1370 | firstPoint += sSegmentTypePointCounts[mSegments[s]]; |
| 1371 | } |
| 1372 | |
| 1373 | return result; |
| 1374 | } |
| 1375 | |
| 1376 | bool Path2d::calcClockwise() const |
| 1377 | { |
no test coverage detected