Fix infinite loop in SHAPE_LINE_CHAIN::Slice
Was resulting in infinite loop due to wrong calculation in NextShape.
This commit is contained in:
parent
69322a18e7
commit
11fc74920c
|
@ -859,6 +859,17 @@ protected:
|
||||||
amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
|
amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the arc index for the given segment index, looking backwards
|
||||||
|
*/
|
||||||
|
ssize_t reversedArcIndex( size_t aSegment ) const
|
||||||
|
{
|
||||||
|
if( IsSharedPt( aSegment ) )
|
||||||
|
return m_shapes[aSegment].first;
|
||||||
|
else
|
||||||
|
return m_shapes[aSegment].second;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation
|
* Create a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -760,14 +760,18 @@ int SHAPE_LINE_CHAIN::NextShape( int aPointIndex, bool aForwards ) const
|
||||||
assert( m_shapes[aPointIndex].first != SHAPE_IS_PT );
|
assert( m_shapes[aPointIndex].first != SHAPE_IS_PT );
|
||||||
|
|
||||||
// Start with the assumption the point is shared
|
// Start with the assumption the point is shared
|
||||||
int arcIndex = m_shapes[aPointIndex].second;
|
auto arcIndex = [&]( int aIndex ) -> ssize_t
|
||||||
|
{
|
||||||
if( arcIndex == SHAPE_IS_PT || !aForwards )
|
if( aForwards )
|
||||||
arcIndex = m_shapes[aPointIndex].first; // Not a shared point or we are going backwards
|
return ArcIndex( aIndex );
|
||||||
|
else
|
||||||
|
return reversedArcIndex( aIndex );
|
||||||
|
};
|
||||||
|
|
||||||
|
ssize_t currentArcIdx = arcIndex( aPointIndex );
|
||||||
|
|
||||||
// Now skip the rest of the arc
|
// Now skip the rest of the arc
|
||||||
while( aPointIndex < lastIndex && aPointIndex >= 0 && m_shapes[aPointIndex].first == arcIndex )
|
while( aPointIndex < lastIndex && aPointIndex >= 0 && arcIndex( aPointIndex ) == currentArcIdx )
|
||||||
aPointIndex += delta;
|
aPointIndex += delta;
|
||||||
|
|
||||||
if( aPointIndex == lastIndex )
|
if( aPointIndex == lastIndex )
|
||||||
|
@ -778,7 +782,7 @@ int SHAPE_LINE_CHAIN::NextShape( int aPointIndex, bool aForwards ) const
|
||||||
return lastIndex; // Segment between last point and the start
|
return lastIndex; // Segment between last point and the start
|
||||||
}
|
}
|
||||||
|
|
||||||
bool indexStillOnArc = alg::pair_contains( m_shapes[aPointIndex], arcIndex );
|
bool indexStillOnArc = alg::pair_contains( m_shapes[aPointIndex], currentArcIdx );
|
||||||
|
|
||||||
// We want the last vertex of the arc if the initial point was the start of one
|
// We want the last vertex of the arc if the initial point was the start of one
|
||||||
// Well-formed arcs should generate more than one point to travel above
|
// Well-formed arcs should generate more than one point to travel above
|
||||||
|
@ -885,8 +889,11 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex )
|
||||||
aStartIndex += rv.PointCount();
|
aStartIndex += rv.PointCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i = aStartIndex; i <= aEndIndex && i < numPoints; i++ )
|
for( int i = aStartIndex; i <= aEndIndex && i < numPoints; i = NextShape( i ) )
|
||||||
{
|
{
|
||||||
|
if( i == -1 )
|
||||||
|
return rv; // NextShape reached the end
|
||||||
|
|
||||||
if( IsArcStart( i ) )
|
if( IsArcStart( i ) )
|
||||||
{
|
{
|
||||||
const SHAPE_ARC ¤tArc = Arc( ArcIndex( i ) );
|
const SHAPE_ARC ¤tArc = Arc( ArcIndex( i ) );
|
||||||
|
@ -908,8 +915,11 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex )
|
||||||
const SHAPE_ARC& currentArc = Arc( arcIndex );
|
const SHAPE_ARC& currentArc = Arc( arcIndex );
|
||||||
|
|
||||||
// Copy the points as arc points
|
// Copy the points as arc points
|
||||||
for( ; i <= aEndIndex; i++ )
|
for( ; i <= aEndIndex && i < numPoints; i++ )
|
||||||
{
|
{
|
||||||
|
if( arcIndex != ArcIndex( i ) )
|
||||||
|
break;
|
||||||
|
|
||||||
rv.m_points.push_back( m_points[i] );
|
rv.m_points.push_back( m_points[i] );
|
||||||
rv.m_shapes.push_back( { rv.m_arcs.size(), SHAPE_IS_PT } );
|
rv.m_shapes.push_back( { rv.m_arcs.size(), SHAPE_IS_PT } );
|
||||||
rv.m_bbox.Merge( m_points[i] );
|
rv.m_bbox.Merge( m_points[i] );
|
||||||
|
@ -937,9 +947,6 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex )
|
||||||
|
|
||||||
if( isLastShape )
|
if( isLastShape )
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
i = nextShape;
|
|
||||||
i--;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue