Skip to content

Commit c04a540

Browse files
committedJul 13, 2014
[composer] Hard code drawing a maximum of 1000 horizontal or vertical grid lines. Prevents hangs if grid settings are poorly chosen, resulting in millions of grid lines
1 parent ae84a07 commit c04a540

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed
 

‎src/core/composer/qgscomposermapgrid.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <QPainter>
2929
#include <QPen>
3030

31+
#define MAX_GRID_LINES 1000 //maximum number of horizontal or vertical grid lines to draw
32+
3133
QgsComposerMapGrid::QgsComposerMapGrid( const QString& name, QgsComposerMap* map ):
3234
mComposerMap( map ),
3335
mName( name ),
@@ -370,13 +372,13 @@ void QgsComposerMapGrid::drawGrid( QPainter* p ) const
370372
void QgsComposerMapGrid::drawGridNoTransform( QgsRenderContext &context, double dotsPerMM, QList< QPair< double, QLineF > > &horizontalLines,
371373
QList< QPair< double, QLineF > > &verticalLines ) const
372374
{
373-
//get line positions
375+
//get line positions
374376
yGridLines( verticalLines );
375377
QList< QPair< double, QLineF > >::const_iterator vIt = verticalLines.constBegin();
376378
xGridLines( horizontalLines );
377379
QList< QPair< double, QLineF > >::const_iterator hIt = horizontalLines.constBegin();
378380

379-
//simple approach: draw vertical lines first, then horizontal ones
381+
//simple approach: draw vertical lines first, then horizontal ones
380382
if ( mGridStyle == QgsComposerMap::Solid )
381383
{
382384
//we need to scale line coordinates to dots, rather than mm, since the painter has already been scaled to dots
@@ -815,16 +817,18 @@ int QgsComposerMapGrid::xGridLines( QList< QPair< double, QLineF > >& lines ) co
815817
double roundCorrection = mapBoundingRect.top() > 0 ? 1.0 : 0.0;
816818
double currentLevel = ( int )(( mapBoundingRect.top() - gridOffsetY ) / gridIntervalY + roundCorrection ) * gridIntervalY + gridOffsetY;
817819

820+
int gridLineCount = 0;
818821
if ( qgsDoubleNear( mComposerMap->mapRotation(), 0.0 ) || mGridUnit != MapUnit )
819822
{
820823
//no rotation. Do it 'the easy way'
821824

822825
double yCanvasCoord;
823-
while ( currentLevel <= mapBoundingRect.bottom() )
826+
while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < MAX_GRID_LINES )
824827
{
825828
yCanvasCoord = mComposerMap->rect().height() * ( 1 - ( currentLevel - mapBoundingRect.top() ) / mapBoundingRect.height() );
826829
lines.push_back( qMakePair( currentLevel * annotationScale, QLineF( 0, yCanvasCoord, mComposerMap->rect().width(), yCanvasCoord ) ) );
827830
currentLevel += gridIntervalY;
831+
gridLineCount++;
828832
}
829833
return 0;
830834
}
@@ -838,7 +842,7 @@ int QgsComposerMapGrid::xGridLines( QList< QPair< double, QLineF > >& lines ) co
838842

839843
QList<QPointF> intersectionList; //intersects between border lines and grid lines
840844

841-
while ( currentLevel <= mapBoundingRect.bottom() )
845+
while ( currentLevel <= mapBoundingRect.bottom() && gridLineCount < MAX_GRID_LINES )
842846
{
843847
intersectionList.clear();
844848
QLineF gridLine( mapBoundingRect.left(), currentLevel, mapBoundingRect.right(), currentLevel );
@@ -860,6 +864,7 @@ int QgsComposerMapGrid::xGridLines( QList< QPair< double, QLineF > >& lines ) co
860864
if ( intersectionList.size() >= 2 )
861865
{
862866
lines.push_back( qMakePair( currentLevel, QLineF( mComposerMap->mapToItemCoords( intersectionList.at( 0 ) ), mComposerMap->mapToItemCoords( intersectionList.at( 1 ) ) ) ) );
867+
gridLineCount++;
863868
}
864869
currentLevel += gridIntervalY;
865870
}
@@ -896,16 +901,17 @@ int QgsComposerMapGrid::yGridLines( QList< QPair< double, QLineF > >& lines ) co
896901
double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
897902
double currentLevel = ( int )(( mapBoundingRect.left() - gridOffsetX ) / gridIntervalX + roundCorrection ) * gridIntervalX + gridOffsetX;
898903

904+
int gridLineCount = 0;
899905
if ( qgsDoubleNear( mComposerMap->mapRotation(), 0.0 ) || mGridUnit != MapUnit )
900906
{
901907
//no rotation. Do it 'the easy way'
902908
double xCanvasCoord;
903-
904-
while ( currentLevel <= mapBoundingRect.right() )
909+
while ( currentLevel <= mapBoundingRect.right() && gridLineCount < MAX_GRID_LINES )
905910
{
906911
xCanvasCoord = mComposerMap->rect().width() * ( currentLevel - mapBoundingRect.left() ) / mapBoundingRect.width();
907912
lines.push_back( qMakePair( currentLevel * annotationScale, QLineF( xCanvasCoord, 0, xCanvasCoord, mComposerMap->rect().height() ) ) );
908913
currentLevel += gridIntervalX;
914+
gridLineCount++;
909915
}
910916
return 0;
911917
}
@@ -919,7 +925,7 @@ int QgsComposerMapGrid::yGridLines( QList< QPair< double, QLineF > >& lines ) co
919925

920926
QList<QPointF> intersectionList; //intersects between border lines and grid lines
921927

922-
while ( currentLevel <= mapBoundingRect.right() )
928+
while ( currentLevel <= mapBoundingRect.right() && gridLineCount < MAX_GRID_LINES )
923929
{
924930
intersectionList.clear();
925931
QLineF gridLine( currentLevel, mapBoundingRect.bottom(), currentLevel, mapBoundingRect.top() );
@@ -941,6 +947,7 @@ int QgsComposerMapGrid::yGridLines( QList< QPair< double, QLineF > >& lines ) co
941947
if ( intersectionList.size() >= 2 )
942948
{
943949
lines.push_back( qMakePair( currentLevel, QLineF( mComposerMap->mapToItemCoords( intersectionList.at( 0 ) ), mComposerMap->mapToItemCoords( intersectionList.at( 1 ) ) ) ) );
950+
gridLineCount++;
944951
}
945952
currentLevel += gridIntervalX;
946953
}

0 commit comments

Comments
 (0)
Please sign in to comment.