QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmaprenderercustompainterjob.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaprenderercustompainterjob.cpp
3  --------------------------------------
4  Date : December 2013
5  Copyright : (C) 2013 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgsfeedback.h"
19 #include "qgslabelingengine.h"
20 #include "qgslogger.h"
21 #include "qgsmaplayerrenderer.h"
22 #include "qgsmaplayerlistutils_p.h"
23 #include "qgsvectorlayerlabeling.h"
24 #include "qgsrasterlayerrenderer.h"
25 
26 #include <QtConcurrentRun>
27 
28 Q_GUI_EXPORT extern int qt_defaultDpiX();
29 Q_GUI_EXPORT extern int qt_defaultDpiY();
30 
31 static void _fixQPictureDPI( QPainter *p )
32 {
33  // QPicture makes an assumption that we drawing to it with system DPI.
34  // Then when being drawn, it scales the painter. The following call
35  // negates the effect. There is no way of setting QPicture's DPI.
36  // See QTBUG-20361
37  p->scale( static_cast< double >( qt_defaultDpiX() ) / p->device()->logicalDpiX(),
38  static_cast< double >( qt_defaultDpiY() ) / p->device()->logicalDpiY() );
39 }
40 
41 //
42 // QgsMapRendererAbstractCustomPainterJob
43 //
44 
46  : QgsMapRendererJob( settings )
47 {
48 
49 }
50 
51 void QgsMapRendererAbstractCustomPainterJob::preparePainter( QPainter *painter, const QColor &backgroundColor )
52 {
53  // clear the background
54  painter->fillRect( 0, 0, mSettings.deviceOutputSize().width(), mSettings.deviceOutputSize().height(), backgroundColor );
55 
56  painter->setRenderHint( QPainter::Antialiasing, mSettings.testFlag( Qgis::MapSettingsFlag::Antialiasing ) );
57  painter->setRenderHint( QPainter::SmoothPixmapTransform, mSettings.testFlag( Qgis::MapSettingsFlag::HighQualityImageTransforms ) );
58 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
59  painter->setRenderHint( QPainter::LosslessImageRendering, mSettings.testFlag( Qgis::MapSettingsFlag::LosslessImageRendering ) );
60 #endif
61 
62 #ifndef QT_NO_DEBUG
63  QPaintDevice *paintDevice = painter->device();
64  const QString errMsg = QStringLiteral( "pre-set DPI not equal to painter's DPI (%1 vs %2)" )
65  .arg( paintDevice->logicalDpiX() )
66  .arg( mSettings.outputDpi() );
67  Q_ASSERT_X( qgsDoubleNear( paintDevice->logicalDpiX(), mSettings.outputDpi(), 1.0 ),
68  "Job::startRender()", errMsg.toLatin1().data() );
69 #endif
70 }
71 
72 
73 //
74 // QgsMapRendererCustomPainterJob
75 //
76 
79  , mPainter( painter )
80  , mActive( false )
81  , mRenderSynchronously( false )
82 {
83  QgsDebugMsgLevel( QStringLiteral( "QPAINTER construct" ), 5 );
84 }
85 
87 {
88  QgsDebugMsgLevel( QStringLiteral( "QPAINTER destruct" ), 5 );
89  Q_ASSERT( !mFutureWatcher.isRunning() );
90  //cancel();
91 }
92 
93 void QgsMapRendererCustomPainterJob::startPrivate()
94 {
95  if ( isActive() )
96  return;
97 
98  if ( !mPrepareOnly )
99  mRenderingStart.start();
100 
101  mActive = true;
102 
103  mErrors.clear();
104 
105  QgsDebugMsgLevel( QStringLiteral( "QPAINTER run!" ), 5 );
106 
107  QgsDebugMsgLevel( QStringLiteral( "Preparing list of layer jobs for rendering" ), 5 );
108  QElapsedTimer prepareTime;
109  prepareTime.start();
110 
112 
113  mLabelingEngineV2.reset();
114 
116  {
117  mLabelingEngineV2.reset( new QgsDefaultLabelingEngine() );
118  mLabelingEngineV2->setMapSettings( mSettings );
119  }
120 
121  const bool canUseLabelCache = prepareLabelCache();
122  mLayerJobs = prepareJobs( mPainter, mLabelingEngineV2.get() );
123  mLabelJob = prepareLabelingJob( mPainter, mLabelingEngineV2.get(), canUseLabelCache );
124  mSecondPassLayerJobs = prepareSecondPassJobs( mLayerJobs, mLabelJob );
125 
126  QgsDebugMsgLevel( QStringLiteral( "Rendering prepared in (seconds): %1" ).arg( prepareTime.elapsed() / 1000.0 ), 4 );
127 
128  if ( mRenderSynchronously )
129  {
130  if ( !mPrepareOnly )
131  {
132  // do the rendering right now!
133  doRender();
134  }
135  return;
136  }
137 
138  // now we are ready to start rendering!
139  connect( &mFutureWatcher, &QFutureWatcher<void>::finished, this, &QgsMapRendererCustomPainterJob::futureFinished );
140 
141  mFuture = QtConcurrent::run( staticRender, this );
142  mFutureWatcher.setFuture( mFuture );
143 }
144 
145 
147 {
148  if ( !isActive() )
149  {
150  QgsDebugMsgLevel( QStringLiteral( "QPAINTER not running!" ), 4 );
151  return;
152  }
153 
154  QgsDebugMsgLevel( QStringLiteral( "QPAINTER canceling" ), 5 );
155  disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished, this, &QgsMapRendererCustomPainterJob::futureFinished );
157 
158  QElapsedTimer t;
159  t.start();
160 
161  mFutureWatcher.waitForFinished();
162 
163  QgsDebugMsgLevel( QStringLiteral( "QPAINER cancel waited %1 ms" ).arg( t.elapsed() / 1000.0 ), 5 );
164 
165  futureFinished();
166 
167  QgsDebugMsgLevel( QStringLiteral( "QPAINTER canceled" ), 5 );
168 }
169 
171 {
172  if ( !isActive() )
173  {
174  QgsDebugMsg( QStringLiteral( "QPAINTER not running!" ) );
175  return;
176  }
177 
178  mLabelJob.context.setRenderingStopped( true );
179  for ( LayerRenderJob &job : mLayerJobs )
180  {
181  job.context()->setRenderingStopped( true );
182  if ( job.renderer && job.renderer->feedback() )
183  job.renderer->feedback()->cancel();
184  }
185 }
186 
188 {
189  if ( !isActive() )
190  return;
191 
192  disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished, this, &QgsMapRendererCustomPainterJob::futureFinished );
193 
194  QElapsedTimer t;
195  t.start();
196 
197  mFutureWatcher.waitForFinished();
198 
199  QgsDebugMsgLevel( QStringLiteral( "waitForFinished: %1 ms" ).arg( t.elapsed() / 1000.0 ), 4 );
200 
201  futureFinished();
202 }
203 
205 {
206  return mActive;
207 }
208 
210 {
211  return mLabelJob.cached;
212 }
213 
215 {
216  if ( mLabelingEngineV2 )
217  return mLabelingEngineV2->takeResults();
218  else
219  return nullptr;
220 }
221 
222 
223 void QgsMapRendererCustomPainterJob::waitForFinishedWithEventLoop( QEventLoop::ProcessEventsFlags flags )
224 {
225  QEventLoop loop;
226  connect( &mFutureWatcher, &QFutureWatcher<void>::finished, &loop, &QEventLoop::quit );
227  loop.exec( flags );
228 }
229 
230 
232 {
233  mRenderSynchronously = true;
234  start();
235  futureFinished();
236  mRenderSynchronously = false;
237 }
238 
240 {
241  mRenderSynchronously = true;
242  mPrepareOnly = true;
243  start();
244  mPrepared = true;
245 }
246 
248 {
249  if ( !mPrepared )
250  return;
251 
252  doRender();
253  futureFinished();
254  mRenderSynchronously = false;
255  mPrepareOnly = false;
256  mPrepared = false;
257 }
258 
259 void QgsMapRendererCustomPainterJob::futureFinished()
260 {
261  mActive = false;
262  if ( !mPrepared ) // can't access from other thread
263  mRenderingTime = mRenderingStart.elapsed();
264  QgsDebugMsgLevel( QStringLiteral( "QPAINTER futureFinished" ), 5 );
265 
266  if ( !mPrepared )
267  logRenderingTime( mLayerJobs, {}, mLabelJob );
268 
269  // final cleanup
270  cleanupJobs( mLayerJobs );
271  cleanupSecondPassJobs( mSecondPassLayerJobs );
272  cleanupLabelJob( mLabelJob );
273 
274  emit finished();
275 }
276 
277 
278 void QgsMapRendererCustomPainterJob::staticRender( QgsMapRendererCustomPainterJob *self )
279 {
280  try
281  {
282  self->doRender();
283  }
284  catch ( QgsException &e )
285  {
286  Q_UNUSED( e )
287  QgsDebugMsg( "Caught unhandled QgsException: " + e.what() );
288  }
289  catch ( std::exception &e )
290  {
291  Q_UNUSED( e )
292  QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
293  }
294  catch ( ... )
295  {
296  QgsDebugMsg( QStringLiteral( "Caught unhandled unknown exception" ) );
297  }
298 }
299 
300 void QgsMapRendererCustomPainterJob::doRender()
301 {
302  const bool hasSecondPass = ! mSecondPassLayerJobs.empty();
303  QgsDebugMsgLevel( QStringLiteral( "Starting to render layer stack." ), 5 );
304  QElapsedTimer renderTime;
305  renderTime.start();
306 
307  for ( LayerRenderJob &job : mLayerJobs )
308  {
309  if ( job.context()->renderingStopped() )
310  break;
311 
312  emit layerRenderingStarted( job.layerId );
313 
314  if ( ! hasSecondPass && job.context()->useAdvancedEffects() )
315  {
316  // Set the QPainter composition mode so that this layer is rendered using
317  // the desired blending mode
318  mPainter->setCompositionMode( job.blendMode );
319  }
320 
321  if ( !job.cached )
322  {
323  QElapsedTimer layerTime;
324  layerTime.start();
325 
326  if ( job.img )
327  {
328  job.img->fill( 0 );
329  job.imageInitialized = true;
330  }
331 
332  job.completed = job.renderer->render();
333 
334  if ( job.picture )
335  {
336  job.renderer->renderContext()->painter()->end();
337  }
338 
339  job.renderingTime += layerTime.elapsed();
340  }
341 
342  if ( ! hasSecondPass && job.img )
343  {
344  // If we flattened this layer for alternate blend modes, composite it now
345  mPainter->setOpacity( job.opacity );
346  mPainter->drawImage( 0, 0, *job.img );
347  mPainter->setOpacity( 1.0 );
348  }
349 
350  emit layerRendered( job.layerId );
351  }
352 
354  QgsDebugMsgLevel( QStringLiteral( "Done rendering map layers" ), 5 );
355 
356  if ( mSettings.testFlag( Qgis::MapSettingsFlag::DrawLabeling ) && !mLabelJob.context.renderingStopped() )
357  {
358  if ( !mLabelJob.cached )
359  {
360  QElapsedTimer labelTime;
361  labelTime.start();
362 
363  if ( mLabelJob.img )
364  {
365  QPainter painter;
366  mLabelJob.img->fill( 0 );
367  painter.begin( mLabelJob.img );
368  mLabelJob.context.setPainter( &painter );
369  drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), &painter );
370  painter.end();
371  }
372  else if ( mLabelJob.picture )
373  {
374  QPainter painter;
375  painter.begin( mLabelJob.picture.get() );
376  mLabelJob.context.setPainter( &painter );
377  drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), &painter );
378  painter.end();
379  }
380  else
381  {
382  drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), mPainter );
383  }
384 
385  mLabelJob.complete = true;
386  mLabelJob.renderingTime = labelTime.elapsed();
387  mLabelJob.participatingLayers = _qgis_listRawToQPointer( mLabelingEngineV2->participatingLayers() );
388  }
389  }
390 
391  if ( ! hasSecondPass )
392  {
393  if ( mLabelJob.img && mLabelJob.complete )
394  {
395  mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
396  mPainter->setOpacity( 1.0 );
397  mPainter->drawImage( 0, 0, *mLabelJob.img );
398  }
399  }
400  else
401  {
402  initSecondPassJobs( mSecondPassLayerJobs, mLabelJob );
403 
404  for ( LayerRenderJob &job : mSecondPassLayerJobs )
405  {
406  if ( job.context()->renderingStopped() )
407  break;
408 
409  if ( !job.cached )
410  {
411  QElapsedTimer layerTime;
412  layerTime.start();
413 
414  if ( job.img )
415  {
416  job.img->fill( 0 );
417  job.imageInitialized = true;
418  }
419 
420  job.completed = job.renderer->render();
421 
422  if ( job.picture )
423  {
424  job.renderer->renderContext()->painter()->end();
425  }
426 
427  job.renderingTime += layerTime.elapsed();
428  }
429  }
430 
432  composeSecondPass( mSecondPassLayerJobs, mLabelJob, forceVector );
433 
434  if ( !forceVector )
435  {
436  const QImage finalImage = composeImage( mSettings, mLayerJobs, mLabelJob );
437 
438  mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
439  mPainter->setOpacity( 1.0 );
440  mPainter->drawImage( 0, 0, finalImage );
441  }
442  else
443  {
444  //Vector composition is simply draw the saved picture on the painter
445  for ( LayerRenderJob &job : mLayerJobs )
446  {
447  // if there is vector rendering we use it, else we use the raster rendering
448  if ( job.picture )
449  {
450  mPainter->save();
451  _fixQPictureDPI( mPainter );
452  mPainter->drawPicture( 0, 0, *job.picture );
453  mPainter->restore();
454  }
455  else
456  mPainter->drawImage( 0, 0, *job.img );
457  }
458 
459  if ( mLabelJob.picture )
460  {
461  mPainter->save();
462  _fixQPictureDPI( mPainter );
463  mPainter->drawPicture( 0, 0, *mLabelJob.picture );
464  mPainter->restore();
465  }
466  }
467  }
468 
469  QgsDebugMsgLevel( QStringLiteral( "Rendering completed in (seconds): %1" ).arg( renderTime.elapsed() / 1000.0 ), 2 );
470 }
QgsMapRendererJob::layerRenderingStarted
void layerRenderingStarted(const QString &layerId)
Emitted just before rendering starts for a particular layer.
QgsException
Defines a QGIS exception class.
Definition: qgsexception.h:34
QgsMapRendererJob::logRenderingTime
void logRenderingTime(const std::vector< LayerRenderJob > &jobs, const std::vector< LayerRenderJob > &secondPassJobs, const LabelRenderJob &labelJob)
QgsMapRendererJob::composeImage
static QImage composeImage(const QgsMapSettings &settings, const std::vector< LayerRenderJob > &jobs, const LabelRenderJob &labelJob, const QgsMapRendererCache *cache=nullptr)
QgsMapRendererCustomPainterJob::waitForFinished
void waitForFinished() override
Block until the job has finished.
Definition: qgsmaprenderercustompainterjob.cpp:187
QgsMapRendererJob::mErrors
Errors mErrors
Definition: qgsmaprendererjob.h:492
QgsMapRendererAbstractCustomPainterJob
Abstract base class for map renderer jobs which use custom painters.
Definition: qgsmaprenderercustompainterjob.h:31
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsMapRendererJob::renderingLayersFinished
void renderingLayersFinished()
Emitted when the layers are rendered.
qt_defaultDpiY
Q_GUI_EXPORT int qt_defaultDpiY()
Qgis::MapSettingsFlag::DrawLabeling
@ DrawLabeling
Enable drawing of labels on top of the map.
QgsMapRendererCustomPainterJob::isActive
bool isActive() const override
Tell whether the rendering job is currently running in background.
Definition: qgsmaprenderercustompainterjob.cpp:204
QgsMapRendererJob::prepareSecondPassJobs
std::vector< LayerRenderJob > prepareSecondPassJobs(std::vector< LayerRenderJob > &firstPassJobs, LabelRenderJob &labelJob)
Prepares jobs for a second pass, if selective masks exist (from labels or symbol layers).
QgsLabelingResults
Class that stores computed placement from labeling engine.
Definition: qgslabelingresults.h:32
QgsMapRendererJob::mRenderingStart
QElapsedTimer mRenderingStart
Definition: qgsmaprendererjob.h:491
QgsMapRendererJob::prepareJobs
std::vector< LayerRenderJob > prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool deferredPainterSet=false)
Creates a list of layer rendering jobs and prepares them for later render.
qgsmaprenderercustompainterjob.h
QgsMapRendererJob::prepareLabelCache
bool prepareLabelCache() const
Prepares the cache for storing the result of labeling.
QgsDefaultLabelingEngine
Default QgsLabelingEngine implementation, which completes the whole labeling operation (including lab...
Definition: qgslabelingengine.h:464
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsMapRendererCustomPainterJob::cancel
void cancel() override
Stop the rendering job - does not return until the job has terminated.
Definition: qgsmaprenderercustompainterjob.cpp:146
QgsMapRendererJob::layerRendered
void layerRendered(const QString &layerId)
Emitted when a layer has completed rendering.
qt_defaultDpiX
Q_GUI_EXPORT int qt_defaultDpiX()
QgsMapRendererJob::prepareLabelingJob
LabelRenderJob prepareLabelingJob(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool canUseLabelCache=true)
Prepares a labeling job.
Qgis::MapSettingsFlag::Antialiasing
@ Antialiasing
Enable anti-aliasing for map rendering.
QgsMapRendererCustomPainterJob::takeLabelingResults
QgsLabelingResults * takeLabelingResults() override
Gets pointer to internal labeling engine (in order to get access to the results).
Definition: qgsmaprenderercustompainterjob.cpp:214
qgsmaplayerlistutils_p.h
QgsMapRendererCustomPainterJob::waitForFinishedWithEventLoop
void waitForFinishedWithEventLoop(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Wait for the job to be finished - and keep the thread's event loop running while waiting.
Definition: qgsmaprenderercustompainterjob.cpp:223
QgsMapRendererJob::mRenderingTime
int mRenderingTime
Definition: qgsmaprendererjob.h:496
QgsMapRendererCustomPainterJob::cancelWithoutBlocking
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
Definition: qgsmaprenderercustompainterjob.cpp:170
QgsMapRendererJob::start
void start()
Start the rendering job and immediately return.
Qgis::MapSettingsFlag::ForceRasterMasks
@ ForceRasterMasks
Force symbol masking to be applied using a raster method. This is considerably faster when compared t...
QgsMapRendererCustomPainterJob::usedCachedLabels
bool usedCachedLabels() const override
Returns true if the render job was able to use a cached labeling solution.
Definition: qgsmaprenderercustompainterjob.cpp:209
QgsMapSettings::testFlag
bool testFlag(Qgis::MapSettingsFlag flag) const
Check whether a particular flag is enabled.
Definition: qgsmapsettings.cpp:395
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2265
QgsException::what
QString what() const
Definition: qgsexception.h:48
QgsMapRendererJob::composeSecondPass
static void composeSecondPass(std::vector< LayerRenderJob > &secondPassJobs, LabelRenderJob &labelJob, bool forceVector=false)
Compose second pass images into first pass images.
QgsMapSettings::backgroundColor
QColor backgroundColor() const
Returns the background color of the map.
Definition: qgsmapsettings.h:388
Qgis::MapSettingsFlag::ForceVectorOutput
@ ForceVectorOutput
Vector graphics should not be cached and drawn as raster images.
QgsMapRendererCustomPainterJob::QgsMapRendererCustomPainterJob
QgsMapRendererCustomPainterJob(const QgsMapSettings &settings, QPainter *painter)
Definition: qgsmaprenderercustompainterjob.cpp:77
qgsmaplayerrenderer.h
QgsMapRendererJob::cleanupLabelJob
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
Qgis::MapSettingsFlag::HighQualityImageTransforms
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
qgsrasterlayerrenderer.h
QgsMapRendererCustomPainterJob::prepare
void prepare()
Prepares the job for rendering synchronously in a background thread.
Definition: qgsmaprenderercustompainterjob.cpp:239
QgsMapRendererCustomPainterJob
Job implementation that renders everything sequentially using a custom painter.
Definition: qgsmaprenderercustompainterjob.h:63
QgsMapRendererCustomPainterJob::renderSynchronously
void renderSynchronously()
Render the map synchronously in this thread.
Definition: qgsmaprenderercustompainterjob.cpp:231
QgsMapSettings::deviceOutputSize
QSize deviceOutputSize() const
Returns the device output size of the map render.
Definition: qgsmapsettings.cpp:262
QgsMapRendererAbstractCustomPainterJob::preparePainter
void preparePainter(QPainter *painter, const QColor &backgroundColor=Qt::transparent)
Prepares the given painter ready for a map render.
Definition: qgsmaprenderercustompainterjob.cpp:51
QgsMapRendererJob::cleanupJobs
void cleanupJobs(std::vector< LayerRenderJob > &jobs)
QgsMapRendererCustomPainterJob::~QgsMapRendererCustomPainterJob
~QgsMapRendererCustomPainterJob() override
Definition: qgsmaprenderercustompainterjob.cpp:86
QgsMapRendererJob::initSecondPassJobs
void initSecondPassJobs(std::vector< LayerRenderJob > &secondPassJobs, LabelRenderJob &labelJob) const
Initialize secondPassJobs according to what have been rendered (mask clipping path e....
QgsMapRendererJob::mSettings
QgsMapSettings mSettings
Definition: qgsmaprendererjob.h:490
QgsMapRendererJob
Abstract base class for map rendering implementations.
Definition: qgsmaprendererjob.h:269
QgsMapRendererCustomPainterJob::renderPrepared
void renderPrepared()
Render a pre-prepared job.
Definition: qgsmaprenderercustompainterjob.cpp:247
QgsMapRendererJob::cleanupSecondPassJobs
void cleanupSecondPassJobs(std::vector< LayerRenderJob > &jobs)
qgsvectorlayerlabeling.h
QgsMapRendererAbstractCustomPainterJob::QgsMapRendererAbstractCustomPainterJob
QgsMapRendererAbstractCustomPainterJob(const QgsMapSettings &settings)
Constructor for QgsMapRendererAbstractCustomPainterJob, using the given map settings.
Definition: qgsmaprenderercustompainterjob.cpp:45
qgslogger.h
QgsMapSettings::outputDpi
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
Definition: qgsmapsettings.cpp:267
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
qgsfeedback.h
Qgis::MapSettingsFlag::LosslessImageRendering
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
qgslabelingengine.h
QgsMapRendererJob::finished
void finished()
emitted when asynchronous rendering is finished (or canceled).
QgsMapRendererJob::drawLabeling
static Q_DECL_DEPRECATED void drawLabeling(const QgsMapSettings &settings, QgsRenderContext &renderContext, QgsLabelingEngine *labelingEngine2, QPainter *painter)