Handle view device pixel ratio when generating preview icons

for text format and label settings
This commit is contained in:
Nyall Dawson 2023-06-20 13:52:00 +10:00
parent 86f06d065b
commit 730081dceb
7 changed files with 38 additions and 22 deletions

View File

@ -636,7 +636,7 @@ Sets the label placement ``settings``.
.. versionadded:: 3.26 .. versionadded:: 3.26
%End %End
static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0 ); static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0, double devicePixelRatio = 1 );
%Docstring %Docstring
Returns a pixmap preview for label ``settings``. Returns a pixmap preview for label ``settings``.
@ -644,6 +644,7 @@ Returns a pixmap preview for label ``settings``.
:param size: target pixmap size :param size: target pixmap size
:param previewText: text to render in preview, or empty for default text :param previewText: text to render in preview, or empty for default text
:param padding: space between icon edge and color ramp :param padding: space between icon edge and color ramp
:param devicePixelRatio: can be used to generate a pixmap using a specific device pixel ratio (since QGIS 3.32)
.. versionadded:: 3.10 .. versionadded:: 3.10
%End %End

View File

@ -708,7 +708,7 @@ Updates the format by evaluating current values of data defined properties.
.. versionadded:: 3.10 .. versionadded:: 3.10
%End %End
static QPixmap textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText = QString(), int padding = 0 ); static QPixmap textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText = QString(), int padding = 0, double devicePixelRatio = 1 );
%Docstring %Docstring
Returns a pixmap preview for a text ``format``. Returns a pixmap preview for a text ``format``.
@ -716,6 +716,7 @@ Returns a pixmap preview for a text ``format``.
:param size: target pixmap size :param size: target pixmap size
:param previewText: text to render in preview, or empty for default text :param previewText: text to render in preview, or empty for default text
:param padding: space between icon edge and color ramp :param padding: space between icon edge and color ramp
:param devicePixelRatio: can be used to generate a pixmap using a specific device pixel ratio (since QGIS 3.32)
.. versionadded:: 3.10 .. versionadded:: 3.10
%End %End

View File

@ -1357,18 +1357,19 @@ void QgsPalLayerSettings::setCallout( QgsCallout *callout )
mCallout.reset( callout ); mCallout.reset( callout );
} }
QPixmap QgsPalLayerSettings::labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText, int padding ) QPixmap QgsPalLayerSettings::labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText, int padding, double devicePixelRatio )
{ {
// for now, just use format // for now, just use format
QgsTextFormat tempFormat = settings.format(); QgsTextFormat tempFormat = settings.format();
QPixmap pixmap( size ); QPixmap pixmap( size * devicePixelRatio );
pixmap.fill( Qt::transparent ); pixmap.fill( Qt::transparent );
pixmap.setDevicePixelRatio( devicePixelRatio );
QPainter painter; QPainter painter;
painter.begin( &pixmap ); painter.begin( &pixmap );
painter.setRenderHint( QPainter::Antialiasing ); painter.setRenderHint( QPainter::Antialiasing );
QRect rect( 0, 0, size.width(), size.height() ); const QRectF rect( 0, 0, size.width(), size.height() );
// shameless eye candy - use a subtle gradient when drawing background // shameless eye candy - use a subtle gradient when drawing background
painter.setPen( Qt::NoPen ); painter.setPen( Qt::NoPen );
@ -1406,8 +1407,10 @@ QPixmap QgsPalLayerSettings::labelSettingsPreviewPixmap( const QgsPalLayerSettin
context.setFlag( Qgis::RenderContextFlag::Antialiasing, true ); context.setFlag( Qgis::RenderContextFlag::Antialiasing, true );
QWidget *activeWindow = QApplication::activeWindow(); QWidget *activeWindow = QApplication::activeWindow();
const double logicalDpiX = activeWindow && activeWindow->screen() ? activeWindow->screen()->logicalDotsPerInchX() : 96.0; const double physicalDpiX = activeWindow && activeWindow->screen() ? activeWindow->screen()->physicalDotsPerInchX() : 96.0;
context.setScaleFactor( logicalDpiX / 25.4 ); context.setScaleFactor( physicalDpiX / 25.4 );
context.setDevicePixelRatio( devicePixelRatio );
context.setUseAdvancedEffects( true ); context.setUseAdvancedEffects( true );
context.setPainter( &painter ); context.setPainter( &painter );

View File

@ -968,9 +968,10 @@ class CORE_EXPORT QgsPalLayerSettings
* \param size target pixmap size * \param size target pixmap size
* \param previewText text to render in preview, or empty for default text * \param previewText text to render in preview, or empty for default text
* \param padding space between icon edge and color ramp * \param padding space between icon edge and color ramp
* \param devicePixelRatio can be used to generate a pixmap using a specific device pixel ratio (since QGIS 3.32)
* \since QGIS 3.10 * \since QGIS 3.10
*/ */
static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0 ); static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0, double devicePixelRatio = 1 );
/** /**
* Returns the layer's unplaced label visibility. * Returns the layer's unplaced label visibility.

View File

@ -302,11 +302,14 @@ QVariant QgsStyleModel::data( const QModelIndex &index, int role ) const
return icon; return icon;
const QgsTextFormat format( mStyle->textFormat( name ) ); const QgsTextFormat format( mStyle->textFormat( name ) );
if ( mAdditionalSizes.isEmpty() ) for ( const double pixelRatio : std::as_const( mDevicePixelRatios ) )
icon.addPixmap( QgsTextFormat::textFormatPreviewPixmap( format, QSize( 24, 24 ), QString(), 1 ) );
for ( const QSize &s : mAdditionalSizes )
{ {
icon.addPixmap( QgsTextFormat::textFormatPreviewPixmap( format, s, QString(), static_cast< int >( s.width() * ICON_PADDING_FACTOR ) ) ); if ( mAdditionalSizes.isEmpty() )
icon.addPixmap( QgsTextFormat::textFormatPreviewPixmap( format, QSize( 24, 24 ), QString(), 1, pixelRatio ) );
for ( const QSize &s : mAdditionalSizes )
{
icon.addPixmap( QgsTextFormat::textFormatPreviewPixmap( format, s, QString(), static_cast< int >( s.width() * ICON_PADDING_FACTOR ), pixelRatio ) );
}
} }
mIconCache[ entityType ].insert( name, icon ); mIconCache[ entityType ].insert( name, icon );
return icon; return icon;
@ -320,11 +323,14 @@ QVariant QgsStyleModel::data( const QModelIndex &index, int role ) const
return icon; return icon;
const QgsPalLayerSettings settings( mStyle->labelSettings( name ) ); const QgsPalLayerSettings settings( mStyle->labelSettings( name ) );
if ( mAdditionalSizes.isEmpty() ) for ( const double pixelRatio : std::as_const( mDevicePixelRatios ) )
icon.addPixmap( QgsPalLayerSettings::labelSettingsPreviewPixmap( settings, QSize( 24, 24 ), QString(), 1 ) );
for ( const QSize &s : mAdditionalSizes )
{ {
icon.addPixmap( QgsPalLayerSettings::labelSettingsPreviewPixmap( settings, s, QString(), static_cast< int >( s.width() * ICON_PADDING_FACTOR ) ) ); if ( mAdditionalSizes.isEmpty() )
icon.addPixmap( QgsPalLayerSettings::labelSettingsPreviewPixmap( settings, QSize( 24, 24 ), QString(), 1, pixelRatio ) );
for ( const QSize &s : mAdditionalSizes )
{
icon.addPixmap( QgsPalLayerSettings::labelSettingsPreviewPixmap( settings, s, QString(), static_cast< int >( s.width() * ICON_PADDING_FACTOR ), pixelRatio ) );
}
} }
mIconCache[ entityType ].insert( name, icon ); mIconCache[ entityType ].insert( name, icon );
return icon; return icon;

View File

@ -1093,17 +1093,19 @@ void QgsTextFormat::updateDataDefinedProperties( QgsRenderContext &context )
mMaskSettings.updateDataDefinedProperties( context, d->mDataDefinedProperties ); mMaskSettings.updateDataDefinedProperties( context, d->mDataDefinedProperties );
} }
QPixmap QgsTextFormat::textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText, int padding ) QPixmap QgsTextFormat::textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText, int padding, double devicePixelRatio )
{ {
QgsTextFormat tempFormat = format; QgsTextFormat tempFormat = format;
QPixmap pixmap( size ); QPixmap pixmap( size * devicePixelRatio );
pixmap.fill( Qt::transparent ); pixmap.fill( Qt::transparent );
pixmap.setDevicePixelRatio( devicePixelRatio );
QPainter painter; QPainter painter;
painter.begin( &pixmap ); painter.begin( &pixmap );
painter.setRenderHint( QPainter::Antialiasing ); painter.setRenderHint( QPainter::Antialiasing );
QRect rect( 0, 0, size.width(), size.height() ); const QRectF rect( 0, 0, size.width(), size.height() );
// shameless eye candy - use a subtle gradient when drawing background // shameless eye candy - use a subtle gradient when drawing background
painter.setPen( Qt::NoPen ); painter.setPen( Qt::NoPen );
@ -1140,8 +1142,9 @@ QPixmap QgsTextFormat::textFormatPreviewPixmap( const QgsTextFormat &format, QSi
context.setMapToPixel( newCoordXForm ); context.setMapToPixel( newCoordXForm );
QWidget *activeWindow = QApplication::activeWindow(); QWidget *activeWindow = QApplication::activeWindow();
const double logicalDpiX = activeWindow && activeWindow->screen() ? activeWindow->screen()->logicalDotsPerInchX() : 96.0; const double physicalDpiX = ( activeWindow && activeWindow->screen() ? activeWindow->screen()->physicalDotsPerInch() : 96.0 );
context.setScaleFactor( logicalDpiX / 25.4 ); context.setScaleFactor( physicalDpiX / 25.4 );
context.setDevicePixelRatio( devicePixelRatio );
context.setUseAdvancedEffects( true ); context.setUseAdvancedEffects( true );
context.setFlag( Qgis::RenderContextFlag::Antialiasing, true ); context.setFlag( Qgis::RenderContextFlag::Antialiasing, true );

View File

@ -641,9 +641,10 @@ class CORE_EXPORT QgsTextFormat
* \param size target pixmap size * \param size target pixmap size
* \param previewText text to render in preview, or empty for default text * \param previewText text to render in preview, or empty for default text
* \param padding space between icon edge and color ramp * \param padding space between icon edge and color ramp
* \param devicePixelRatio can be used to generate a pixmap using a specific device pixel ratio (since QGIS 3.32)
* \since QGIS 3.10 * \since QGIS 3.10
*/ */
static QPixmap textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText = QString(), int padding = 0 ); static QPixmap textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText = QString(), int padding = 0, double devicePixelRatio = 1 );
private: private: