Skip to content
Permalink
Browse files

Restore advanced layer effects, labeling in composer.

Also fixes DpiY setting in composer + workaround for QPicture DPI issues
  • Loading branch information
wonder-sk committed Nov 14, 2013
1 parent cf3d86c commit cfc2a48539122db0258b50f5cdd1b1c82f8fdeee
@@ -42,8 +42,6 @@ QgsLabelEngineConfigDialog::QgsLabelEngineConfigDialog( QgsPalLabeling* lbl, QWi
chkShowAllLabels->setChecked( mLBL->isShowingAllLabels() );
mShadowDebugRectChkBox->setChecked( mLBL->isShowingShadowRectangles() );

mSaveWithProjectChkBox->setChecked( mLBL->isStoredWithProject() );

chkShowPartialsLabels->setChecked( mLBL-> isShowingPartialsLabels() );
}

@@ -62,14 +60,8 @@ void QgsLabelEngineConfigDialog::onOK()
mLBL->setShowingAllLabels( chkShowAllLabels->isChecked() );
mLBL->setShowingPartialsLabels( chkShowPartialsLabels->isChecked() );

if ( mSaveWithProjectChkBox->isChecked() )
{
mLBL->saveEngineSettings();
}
else if ( mLBL->isStoredWithProject() )
{
mLBL->clearEngineSettings();
}
mLBL->saveEngineSettings();

accept();
}

@@ -160,8 +160,9 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
jobMapSettings.setExtent( extent );
jobMapSettings.setOutputSize( size.toSize() );
jobMapSettings.setOutputDpi( dpi );
/* TODO: if ( mMapRenderer->labelingEngine() )
theMapRenderer.setLabelingEngine( mMapRenderer->labelingEngine()->clone() );*/

QgsPalLabeling labeling;
labeling.loadEngineSettings();

//use stored layer set or read current set from main canvas
jobMapSettings.setLayers( mKeepLayerSet ? mLayerSet : ms.layers() );
@@ -176,6 +177,7 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const

// render
QgsMapRendererCustomPainterJob job( jobMapSettings, painter );
job.setLabelingEngine( &labeling );
job.start();
job.waitForFinished();

@@ -225,7 +227,7 @@ void QgsComposerMap::cache( void )

// set DPI of the image
mCacheImage.setDotsPerMeterX( 1000 * w / widthMM );
mCacheImage.setDotsPerMeterX( 1000 * h / heightMM );
mCacheImage.setDotsPerMeterY( 1000 * h / heightMM );

if ( hasBackground() )
{
@@ -223,9 +223,9 @@ void QgsMapRendererCustomPainterJob::startRender()

// Store the painter in case we need to swap it out for the
// cache painter
//QPainter * mypContextPainter = mRenderContext.painter();
QPainter * mypContextPainter = mRenderContext.painter();
// Flattened image for drawing when a blending mode is set
//QImage * mypFlattenedImage = 0;
QImage * mypFlattenedImage = 0;

QString layerId = li.previous();

@@ -248,12 +248,12 @@ void QgsMapRendererCustomPainterJob::startRender()
.arg( ml->blendMode() )
);

/*if ( mRenderContext.useAdvancedEffects() )
if ( mRenderContext.useAdvancedEffects() )
{
// Set the QPainter composition mode so that this layer is rendered using
// the desired blending mode
mypContextPainter->setCompositionMode( ml->blendMode() );
}*/
}

if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mSettings.scale() && mSettings.scale() < ml->maximumScale() ) ) //|| mOverview )
{
@@ -284,56 +284,14 @@ void QgsMapRendererCustomPainterJob::startRender()

mRenderContext.setCoordinateTransform( ct );

/*QSettings mySettings;
bool useRenderCaching = false;
if ( ! split )//render caching does not yet cater for split extents
{
if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
{
useRenderCaching = true;
if ( !mySameAsLastFlag || ml->cacheImage() == 0 )
{
QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" );
QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(),
mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
if ( mypImage->isNull() )
{
QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
emit drawError( ml );
painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
return;
}
mypImage->fill( 0 );
ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you
QPainter * mypPainter = new QPainter( ml->cacheImage() );
// Changed to enable anti aliasing by default in QGIS 1.7
if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
{
mypPainter->setRenderHint( QPainter::Antialiasing );
}
mRenderContext.setPainter( mypPainter );
}
else if ( mySameAsLastFlag )
{
//draw from cached image
QgsDebugMsg( "Caching enabled --- drawing layer from cached image" );
mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
//short circuit as there is nothing else to do...
continue;
}
}
}*/

// If we are drawing with an alternative blending mode then we need to render to a separate image
// before compositing this on the map. This effectively flattens the layer and prevents
// blending occuring between objects on the layer
// (this is not required for raster layers or when layer caching is enabled, since that has the same effect)
/*bool flattenedLayer = false;
bool flattenedLayer = false;
if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if (( !useRenderCaching )
&& (( vl->blendMode() != QPainter::CompositionMode_SourceOver )
if ( (( vl->blendMode() != QPainter::CompositionMode_SourceOver )
|| ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
|| ( vl->layerTransparency() != 0 ) ) )
{
@@ -343,23 +301,22 @@ void QgsMapRendererCustomPainterJob::startRender()
if ( mypFlattenedImage->isNull() )
{
QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
emit drawError( ml );
painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
// TODO emit drawError( ml );
mPainter->end(); // drawError is not caught by anyone, so we end painting to notify caller
return;
}
mypFlattenedImage->fill( 0 );
QPainter * mypPainter = new QPainter( mypFlattenedImage );
if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
if ( mSettings.testFlag( QgsMapSettings::Antialiasing ) )
{
mypPainter->setRenderHint( QPainter::Antialiasing );
}
mypPainter->scale( rasterScaleFactor, rasterScaleFactor );
mRenderContext.setPainter( mypPainter );
}
}*/
}

// Per feature blending mode
/*if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
@@ -368,7 +325,7 @@ void QgsMapRendererCustomPainterJob::startRender()
// on this layer will interact and blend with each other
mRenderContext.painter()->setCompositionMode( vl->featureBlendMode() );
}
}*/
}

if ( !ml->draw( mRenderContext ) )
{
@@ -389,7 +346,7 @@ void QgsMapRendererCustomPainterJob::startRender()
}

//apply layer transparency for vector layers
/*if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if ( vl->layerTransparency() != 0 )
@@ -402,30 +359,17 @@ void QgsMapRendererCustomPainterJob::startRender()
mRenderContext.painter()->fillRect( 0, 0, mRenderContext.painter()->device()->width(),
mRenderContext.painter()->device()->height(), transparentFillColor );
}
}*/

/*if ( useRenderCaching )
{
// composite the cached image into our view and then clean up from caching
// by reinstating the painter as it was swapped out for caching renders
delete mRenderContext.painter();
mRenderContext.setPainter( mypContextPainter );
//draw from cached image that we created further up
if ( ml->cacheImage() )
mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
}
else if ( flattenedLayer )

if ( flattenedLayer )
{
// If we flattened this layer for alternate blend modes, composite it now
delete mRenderContext.painter();
mRenderContext.setPainter( mypContextPainter );
mypContextPainter->save();
mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) );
mypContextPainter->restore();
delete mypFlattenedImage;
mypFlattenedImage = 0;
}*/
}

}
else // layer not visible due to scale
@@ -441,7 +385,8 @@ void QgsMapRendererCustomPainterJob::startRender()
// Reset the composition mode before rendering the labels
mRenderContext.painter()->setCompositionMode( QPainter::CompositionMode_SourceOver );

/*if ( !mOverview )
// old labeling - to be removed at some point...
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
{
// render all labels for vector layers in the stack, starting at the base
li.toBack();
@@ -456,40 +401,40 @@ void QgsMapRendererCustomPainterJob::startRender()

QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

if ( ml && ( ml->type() != QgsMapLayer::RasterLayer ) )
{
// only make labels if the layer is visible
// after scale dep viewing settings are checked
if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() < mScale && mScale < ml->maximumScale() ) )
{
bool split = false;
if ( !ml || ( ml->type() != QgsMapLayer::VectorLayer ) )
continue;

if ( hasCrsTransformEnabled() )
{
QgsRectangle r1 = mExtent;
split = splitLayersExtent( ml, r1, r2 );
ct = new QgsCoordinateTransform( ml->crs(), *mDestCRS );
mRenderContext.setExtent( r1 );
}
else
{
ct = NULL;
}
// only make labels if the layer is visible
// after scale dep viewing settings are checked
if ( ml->hasScaleBasedVisibility() && ( mSettings.scale() < ml->minimumScale() || mSettings.scale() > ml->maximumScale() ) )
continue;

mRenderContext.setCoordinateTransform( ct );
bool split = false;

ml->drawLabels( mRenderContext );
if ( split )
{
mRenderContext.setExtent( r2 );
ml->drawLabels( mRenderContext );
}
}
if ( mSettings.hasCrsTransformEnabled() )
{
QgsRectangle r1 = mSettings.visibleExtent();
ct = QgsCoordinateTransformCache::instance()->transform( ml->crs().authid(), mSettings.destinationCrs().authid() );
split = reprojectToLayerExtent( ct, ml->crs().geographicFlag(), r1, r2 );
mRenderContext.setExtent( r1 );
}
else
{
ct = NULL;
}

mRenderContext.setCoordinateTransform( ct );

ml->drawLabels( mRenderContext );
if ( split )
{
mRenderContext.setExtent( r2 );
ml->drawLabels( mRenderContext );
}
}
} // if (!mOverview)*/
}

if ( mLabelingEngine )
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) && mLabelingEngine )
{
// set correct extent
mRenderContext.setExtent( mSettings.visibleExtent() );
@@ -20,7 +20,7 @@ QgsMapSettings::QgsMapSettings()
, mDestCRS( GEOCRS_ID, QgsCoordinateReferenceSystem::InternalCrsId ) // WGS 84
, mBackgroundColor( Qt::white )
, mSelectionColor( Qt::yellow )
, mFlags( Antialiasing )
, mFlags( Antialiasing | UseAdvancedEffects | DrawLabeling )
{
updateDerived();

@@ -59,8 +59,9 @@ class QgsMapSettings
Antialiasing = 0x01,
DrawEditingInfo = 0x02,
ForceVectorOutput = 0x04,
UseAdvancedEffects = 0x08
// TODO: no labeling, ignore scale-based visibiity (overview)
UseAdvancedEffects = 0x08,
DrawLabeling = 0x10
// TODO: ignore scale-based visibiity (overview)
};
Q_DECLARE_FLAGS(Flags, Flag)

@@ -57,6 +57,21 @@
#include "qgssymbollayerv2utils.h"
#include <QMessageBox>


Q_GUI_EXPORT extern int qt_defaultDpiX();
Q_GUI_EXPORT extern int qt_defaultDpiY();

static void _fixQPictureDPI( QPainter* p )
{
// QPicture makes an assumption that we drawing to it with system DPI.
// Then when being drawn, it scales the painter. The following call
// negates the effect. There is no way of setting QPicture's DPI.
// See QTBUG-20361
p->scale( (double)qt_defaultDpiX() / p->device()->logicalDpiX(),
(double)qt_defaultDpiY() / p->device()->logicalDpiY() );
}


using namespace pal;


@@ -4286,6 +4301,7 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con

// scale for any print output or image saving @ specific dpi
painter->scale( component.dpiRatio(), component.dpiRatio() );
_fixQPictureDPI( painter );
painter->drawPicture( 0, 0, textPict );

// regular text draw, for testing optimization
@@ -4353,6 +4369,7 @@ void QgsPalLabeling::drawLabelBuffer( QgsRenderContext& context,

// scale for any print output or image saving @ specific dpi
p->scale( component.dpiRatio(), component.dpiRatio() );
_fixQPictureDPI( p );
p->drawPicture( 0, 0, buffPict );
p->restore();
}
@@ -4648,6 +4665,7 @@ void QgsPalLabeling::drawLabelBackground( QgsRenderContext& context,

// scale for any print output or image saving @ specific dpi
p->scale( component.dpiRatio(), component.dpiRatio() );
_fixQPictureDPI( p );
p->drawPicture( 0, 0, shapePict );
p->restore();
}
@@ -4822,7 +4840,6 @@ void QgsPalLabeling::loadEngineSettings()
"PAL", "/ShowingAllLabels", false, &saved );
mShowingPartialsLabels = QgsProject::instance()->readBoolEntry(
"PAL", "/ShowingPartialsLabels", p.getShowPartial(), &saved );
mSavedWithProject = saved;
}

void QgsPalLabeling::saveEngineSettings()
@@ -4835,7 +4852,6 @@ void QgsPalLabeling::saveEngineSettings()
QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", mShowingShadowRects );
QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", mShowingAllLabels );
QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", mShowingPartialsLabels );
mSavedWithProject = true;
}

void QgsPalLabeling::clearEngineSettings()
@@ -4848,7 +4864,6 @@ void QgsPalLabeling::clearEngineSettings()
QgsProject::instance()->removeEntry( "PAL", "/ShowingShadowRects" );
QgsProject::instance()->removeEntry( "PAL", "/ShowingAllLabels" );
QgsProject::instance()->removeEntry( "PAL", "/ShowingPartialsLabels" );
mSavedWithProject = false;
}

QgsLabelingEngineInterface* QgsPalLabeling::clone()

0 comments on commit cfc2a48

Please sign in to comment.
You can’t perform that action at this time.