Skip to content

Commit

Permalink
Cache painter path for font marker when it doesn't change
Browse files Browse the repository at this point in the history
Speeds up font marker rendering by around 2x
  • Loading branch information
nyalldawson committed Jul 23, 2019
1 parent eeb2e2a commit 2dfcfda
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/core/symbology/qgsmarkersymbollayer.cpp
Expand Up @@ -2645,6 +2645,17 @@ void QgsFontMarkerSymbolLayer::startRender( QgsSymbolRenderContext &context )
mChrWidth = mFontMetrics->width( mChr );
mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
mOrigSize = mSize; // save in case the size would be data defined

// use caching only when not using a data defined character
mUseCachedPath = !mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyCharacter );
if ( mUseCachedPath )
{
QPointF chrOffset = mChrOffset;
double chrWidth;
QString charToRender = characterToRender( context, chrOffset, chrWidth );
mCachedPath = QPainterPath();
mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
}
}

void QgsFontMarkerSymbolLayer::stopRender( QgsSymbolRenderContext &context )
Expand Down Expand Up @@ -2789,6 +2800,7 @@ void QgsFontMarkerSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContex
}
}

p->save();
p->setBrush( mBrush );
if ( !qgsDoubleNear( penWidth, 0.0 ) )
{
Expand All @@ -2800,7 +2812,6 @@ void QgsFontMarkerSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContex
{
p->setPen( Qt::NoPen );
}
p->save();

QPointF chrOffset = mChrOffset;
double chrWidth;
Expand All @@ -2813,7 +2824,7 @@ void QgsFontMarkerSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContex
double angle = 0;
calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation, offset, angle );

transform.translate( point.x() + offset.x(), point.y() + offset.y() );
p->translate( point.x() + offset.x(), point.y() + offset.y() );

if ( !qgsDoubleNear( angle, 0.0 ) )
transform.rotate( angle );
Expand All @@ -2824,9 +2835,17 @@ void QgsFontMarkerSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContex
transform.scale( s, s );
}

QPainterPath path;
path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
p->drawPath( transform.map( path ) );
if ( mUseCachedPath )
{
p->drawPath( transform.map( mCachedPath ) );
}
else
{
QPainterPath path;
path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
p->drawPath( transform.map( path ) );
}

p->restore();
}

Expand Down
3 changes: 3 additions & 0 deletions src/core/symbology/qgsmarkersymbollayer.h
Expand Up @@ -833,6 +833,9 @@ class CORE_EXPORT QgsFontMarkerSymbolLayer : public QgsMarkerSymbolLayer
QPen mPen;
QBrush mBrush;

bool mUseCachedPath = false;
QPainterPath mCachedPath;

QString characterToRender( QgsSymbolRenderContext &context, QPointF &charOffset, double &charWidth );
void calculateOffsetAndRotation( QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle ) const;
double calculateSize( QgsSymbolRenderContext &context );
Expand Down

0 comments on commit 2dfcfda

Please sign in to comment.