mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Fix #11006 (wrong size of symbols in print composer legend if map units are used)
This commit is contained in:
parent
d3e24c75b1
commit
d994e0a1b3
@ -71,6 +71,12 @@ class QgsLegendSettings
|
||||
bool useAdvancedEffects() const;
|
||||
void setUseAdvancedEffects( bool use );
|
||||
|
||||
double mapScale() const;
|
||||
void setMapScale( double scale );
|
||||
|
||||
int dpi() const;
|
||||
void setDpi( int dpi );
|
||||
|
||||
// utility functions
|
||||
|
||||
/** Splits a string using the wrap char taking into account handling empty
|
||||
|
@ -80,7 +80,10 @@ class QgsSymbolV2
|
||||
void setColor( const QColor& color );
|
||||
QColor color() const;
|
||||
|
||||
void drawPreviewIcon( QPainter* painter, QSize size );
|
||||
//! Draw icon of the symbol that occupyies area given by size using the painter.
|
||||
//! Optionally custom context may be given in order to get rendering of symbols that use map units right.
|
||||
//! @note customContext parameter added in 2.6
|
||||
void drawPreviewIcon( QPainter* painter, QSize size, QgsRenderContext* customContext = 0 );
|
||||
|
||||
QImage bigSymbolPreviewImage();
|
||||
|
||||
|
@ -65,7 +65,11 @@ void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem
|
||||
|
||||
|
||||
if ( mComposition )
|
||||
{
|
||||
mSettings.setUseAdvancedEffects( mComposition->useAdvancedEffects() );
|
||||
mSettings.setMapScale( mComposition->mapSettings().scale() );
|
||||
mSettings.setDpi( painter->device()->logicalDpiX() );
|
||||
}
|
||||
if ( mComposerMap )
|
||||
mSettings.setMmPerMapUnit( mComposerMap->mapUnitsToMM() );
|
||||
|
||||
|
@ -207,9 +207,13 @@ QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, Ite
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
//consider relation to composer map for symbol sizes in mm
|
||||
bool sizeInMapUnits = s->outputUnit() == QgsSymbolV2::MapUnit;
|
||||
QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( s );
|
||||
// setup temporary render context
|
||||
QgsRenderContext context;
|
||||
context.setScaleFactor( settings.dpi() / 25.4 );
|
||||
context.setRendererScale( settings.mapScale() );
|
||||
context.setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * context.scaleFactor() ) ) ); // hope it's ok to leave out other params
|
||||
context.setForceVectorOutput( true );
|
||||
context.setPainter( ctx ? ctx->painter : 0 );
|
||||
|
||||
//Consider symbol size for point markers
|
||||
double height = settings.symbolSize().height();
|
||||
@ -219,17 +223,12 @@ QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, Ite
|
||||
double widthOffset = 0;
|
||||
double heightOffset = 0;
|
||||
|
||||
if ( markerSymbol )
|
||||
if ( QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( s ) )
|
||||
{
|
||||
size = markerSymbol->size();
|
||||
// allow marker symbol to occupy bigger area if necessary
|
||||
size = markerSymbol->size() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, s->outputUnit(), s->mapUnitScale() ) / context.scaleFactor();
|
||||
height = size;
|
||||
width = size;
|
||||
if ( sizeInMapUnits )
|
||||
{
|
||||
height *= settings.mmPerMapUnit();
|
||||
width *= settings.mmPerMapUnit();
|
||||
markerSymbol->setSize( width );
|
||||
}
|
||||
if ( width < settings.symbolSize().width() )
|
||||
{
|
||||
widthOffset = ( settings.symbolSize().width() - width ) / 2.0;
|
||||
@ -247,18 +246,7 @@ QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, Ite
|
||||
QPainter* p = ctx->painter;
|
||||
|
||||
//setup painter scaling to dots so that raster symbology is drawn to scale
|
||||
double dotsPerMM = 1.0;
|
||||
QPaintDevice* paintDevice = p->device();
|
||||
if ( !paintDevice )
|
||||
{
|
||||
return QSizeF();
|
||||
}
|
||||
dotsPerMM = paintDevice->logicalDpiX() / 25.4;
|
||||
|
||||
if ( markerSymbol && sizeInMapUnits )
|
||||
{
|
||||
s->setOutputUnit( QgsSymbolV2::MM );
|
||||
}
|
||||
double dotsPerMM = context.scaleFactor();
|
||||
|
||||
int opacity = 255;
|
||||
if ( QgsVectorLayer* vectorLayer = dynamic_cast<QgsVectorLayer*>( parent()->layer() ) )
|
||||
@ -275,7 +263,7 @@ QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, Ite
|
||||
tempImage.fill( Qt::transparent );
|
||||
imagePainter.translate( dotsPerMM * ( currentXPosition + widthOffset ),
|
||||
dotsPerMM * ( currentYCoord + heightOffset ) );
|
||||
s->drawPreviewIcon( &imagePainter, QSize( width * dotsPerMM, height * dotsPerMM ) );
|
||||
s->drawPreviewIcon( &imagePainter, QSize( width * dotsPerMM, height * dotsPerMM ), &context );
|
||||
//reduce opacity of image
|
||||
imagePainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
|
||||
imagePainter.fillRect( tempImage.rect(), QColor( 0, 0, 0, opacity ) );
|
||||
@ -287,15 +275,9 @@ QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, Ite
|
||||
{
|
||||
p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset );
|
||||
p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
|
||||
s->drawPreviewIcon( p, QSize( width * dotsPerMM, height * dotsPerMM ) );
|
||||
s->drawPreviewIcon( p, QSize( width * dotsPerMM, height * dotsPerMM ), &context );
|
||||
}
|
||||
p->restore();
|
||||
|
||||
if ( markerSymbol && sizeInMapUnits )
|
||||
{
|
||||
s->setOutputUnit( QgsSymbolV2::MapUnit );
|
||||
markerSymbol->setSize( size );
|
||||
}
|
||||
}
|
||||
|
||||
return QSizeF( qMax( width + 2 * widthOffset, settings.symbolSize().width() ),
|
||||
|
@ -32,6 +32,8 @@ QgsLegendSettings::QgsLegendSettings()
|
||||
, mEqualColumnWidth( false )
|
||||
, mMmPerMapUnit( 1 )
|
||||
, mUseAdvancedEffects( true )
|
||||
, mMapScale( 1 )
|
||||
, mDpi( 96 ) // based on QImage's default DPI
|
||||
{
|
||||
rstyle( QgsComposerLegendStyle::Title ).setMargin( QgsComposerLegendStyle::Bottom, 2 );
|
||||
rstyle( QgsComposerLegendStyle::Group ).setMargin( QgsComposerLegendStyle::Top, 2 );
|
||||
|
@ -94,6 +94,12 @@ class CORE_EXPORT QgsLegendSettings
|
||||
bool useAdvancedEffects() const { return mUseAdvancedEffects; }
|
||||
void setUseAdvancedEffects( bool use ) { mUseAdvancedEffects = use; }
|
||||
|
||||
double mapScale() const { return mMapScale; }
|
||||
void setMapScale( double scale ) { mMapScale = scale; }
|
||||
|
||||
int dpi() const { return mDpi; }
|
||||
void setDpi( int dpi ) { mDpi = dpi; }
|
||||
|
||||
// utility functions
|
||||
|
||||
/** Splits a string using the wrap char taking into account handling empty
|
||||
@ -175,6 +181,12 @@ class CORE_EXPORT QgsLegendSettings
|
||||
|
||||
/** Whether to use advanced effects like transparency for symbols - may require their rasterization */
|
||||
bool mUseAdvancedEffects;
|
||||
|
||||
/** Denominator of map's scale */
|
||||
double mMapScale;
|
||||
|
||||
/** DPI to be used when rendering legend */
|
||||
int mDpi;
|
||||
};
|
||||
|
||||
|
||||
|
@ -283,9 +283,9 @@ QColor QgsSymbolV2::color() const
|
||||
return QColor( 0, 0, 0 );
|
||||
}
|
||||
|
||||
void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
|
||||
void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size, QgsRenderContext* customContext )
|
||||
{
|
||||
QgsRenderContext context = QgsSymbolLayerV2Utils::createRenderContext( painter );
|
||||
QgsRenderContext context = customContext ? *customContext : QgsSymbolLayerV2Utils::createRenderContext( painter );
|
||||
context.setForceVectorOutput( true );
|
||||
QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints, 0, 0, mapUnitScale() );
|
||||
|
||||
|
@ -105,7 +105,10 @@ class CORE_EXPORT QgsSymbolV2
|
||||
void setColor( const QColor& color );
|
||||
QColor color() const;
|
||||
|
||||
void drawPreviewIcon( QPainter* painter, QSize size );
|
||||
//! Draw icon of the symbol that occupyies area given by size using the painter.
|
||||
//! Optionally custom context may be given in order to get rendering of symbols that use map units right.
|
||||
//! @note customContext parameter added in 2.6
|
||||
void drawPreviewIcon( QPainter* painter, QSize size, QgsRenderContext* customContext = 0 );
|
||||
|
||||
QImage bigSymbolPreviewImage();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user