| 1176 | } // getSubPath helpers |
| 1177 | |
| 1178 | Path2d Path2d::getSubPath( float startT, float endT ) const |
| 1179 | { |
| 1180 | if( mSegments.empty() ) |
| 1181 | return Path2d(); |
| 1182 | |
| 1183 | float startRelT, endRelT; |
| 1184 | size_t startSegment, endSegment; |
| 1185 | getSegmentRelativeT( startT, &startSegment, &startRelT ); |
| 1186 | getSegmentRelativeT( endT, &endSegment, &endRelT ); |
| 1187 | |
| 1188 | Path2d result; |
| 1189 | // startT and endT are the same segment |
| 1190 | if( startSegment == endSegment ) { |
| 1191 | // iterate to first point of the segment |
| 1192 | size_t firstPoint = 0; |
| 1193 | for( size_t s = 0; s < startSegment; ++s ) |
| 1194 | firstPoint += sSegmentTypePointCounts[mSegments[s]]; |
| 1195 | |
| 1196 | switch( mSegments[startSegment] ) { |
| 1197 | case LINETO: // trim line |
| 1198 | result.mPoints.push_back( mPoints[firstPoint] + startRelT * ( mPoints[firstPoint+1] - mPoints[firstPoint] ) ); |
| 1199 | result.mPoints.push_back( mPoints[firstPoint] + endRelT * ( mPoints[firstPoint+1] - mPoints[firstPoint] ) ); |
| 1200 | result.mSegments.push_back( LINETO ); |
| 1201 | break; |
| 1202 | case QUADTO: |
| 1203 | result.mPoints.resize( 3 ); |
| 1204 | trimQuadAt( &mPoints[firstPoint], result.mPoints.data(), startRelT, endRelT ); |
| 1205 | result.mSegments.push_back( QUADTO ); |
| 1206 | break; |
| 1207 | case CUBICTO: |
| 1208 | result.mPoints.resize( 4 ); |
| 1209 | trimCubicAt( &mPoints[firstPoint], result.mPoints.data(), startRelT, endRelT ); |
| 1210 | result.mSegments.push_back( CUBICTO ); |
| 1211 | break; |
| 1212 | case CLOSE: |
| 1213 | result.mPoints.push_back( mPoints[firstPoint] + startRelT * ( mPoints[0] - mPoints[firstPoint] ) ); |
| 1214 | result.mPoints.push_back( mPoints[firstPoint] + endRelT * ( mPoints[0] - mPoints[firstPoint] ) ); |
| 1215 | result.mSegments.push_back( LINETO ); |
| 1216 | break; |
| 1217 | default: |
| 1218 | throw Path2dExc(); |
| 1219 | } |
| 1220 | } |
| 1221 | else { |
| 1222 | // append first segment chopped at startRelT |
| 1223 | appendChopped( *this, startSegment, startRelT, true, &result ); |
| 1224 | // append all intermediate segments |
| 1225 | for( size_t s = startSegment + 1; s < endSegment; ++s ) |
| 1226 | append( *this, s, &result ); |
| 1227 | // append last segment chopped at endRelT |
| 1228 | appendChopped( *this, endSegment, endRelT, false, &result ); |
| 1229 | } |
| 1230 | |
| 1231 | return result; |
| 1232 | } |
| 1233 | |
| 1234 | Rectf Path2d::calcBoundingBox() const |
| 1235 | { |