Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[needs-docs][layouts] Add checkbox to disable raster tiling for PDF/S…
…VG exports

This setting, which is disabled by default and placed into an
"advanced" group on PDF/SFG export, disables the built-in
raster layer tiled rendering. While the tiling is good for
memory usage, it can cause visible "seams" in the rasters
for generated PDF/SVG files.

The setting has a tooltip warning users that disabling the
tiling results in high memory usage during exports.

Fixes #19500
  • Loading branch information
nyalldawson committed Jan 29, 2019
1 parent 2752f83 commit 60b8d05
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 15 deletions.
Expand Up @@ -30,6 +30,7 @@ Stores information relating to the current rendering settings for a layout.
FlagForceVectorOutput,
FlagHideCoverageLayer,
FlagDrawSelection,
FlagDisableTiledRasterLayerRenders,
};
typedef QFlags<QgsLayoutRenderContext::Flag> Flags;

Expand Down
19 changes: 19 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -4034,6 +4034,7 @@ bool QgsLayoutDesignerDialog::getSvgExportSettings( QgsLayoutExporter::SvgExport
double bottomMargin = 0.0;
double leftMargin = 0.0;
bool includeMetadata = true;
bool disableRasterTiles = false;
if ( mLayout )
{
forceVector = mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool();
Expand All @@ -4044,6 +4045,7 @@ bool QgsLayoutDesignerDialog::getSvgExportSettings( QgsLayoutExporter::SvgExport
bottomMargin = mLayout->customProperty( QStringLiteral( "svgCropMarginBottom" ), 0 ).toInt();
leftMargin = mLayout->customProperty( QStringLiteral( "svgCropMarginLeft" ), 0 ).toInt();
includeMetadata = mLayout->customProperty( QStringLiteral( "svgIncludeMetadata" ), 1 ).toBool();
disableRasterTiles = mLayout->customProperty( QStringLiteral( "svgDisableRasterTiles" ), 0 ).toBool();
const int prevLayoutSettingLabelsAsOutlines = mLayout->customProperty( QStringLiteral( "svgTextFormat" ), -1 ).toInt();
if ( prevLayoutSettingLabelsAsOutlines >= 0 )
{
Expand All @@ -4069,6 +4071,7 @@ bool QgsLayoutDesignerDialog::getSvgExportSettings( QgsLayoutExporter::SvgExport
options.mBottomMarginSpinBox->setValue( bottomMargin );
options.mLeftMarginSpinBox->setValue( leftMargin );
options.mIncludeMetadataCheckbox->setChecked( includeMetadata );
options.mDisableRasterTilingCheckBox->setChecked( disableRasterTiles );

if ( dialog.exec() != QDialog::Accepted )
return false;
Expand All @@ -4081,6 +4084,7 @@ bool QgsLayoutDesignerDialog::getSvgExportSettings( QgsLayoutExporter::SvgExport
marginLeft = options.mLeftMarginSpinBox->value();
includeMetadata = options.mIncludeMetadataCheckbox->isChecked();
forceVector = options.mForceVectorCheckBox->isChecked();
disableRasterTiles = options.mDisableRasterTilingCheckBox->isChecked();
QgsRenderContext::TextRenderFormat textRenderFormat = static_cast< QgsRenderContext::TextRenderFormat >( options.mTextRenderFormatComboBox->currentData().toInt() );

if ( mLayout )
Expand All @@ -4095,6 +4099,7 @@ bool QgsLayoutDesignerDialog::getSvgExportSettings( QgsLayoutExporter::SvgExport
mLayout->setCustomProperty( QStringLiteral( "svgIncludeMetadata" ), includeMetadata ? 1 : 0 );
mLayout->setCustomProperty( QStringLiteral( "forceVector" ), forceVector ? 1 : 0 );
mLayout->setCustomProperty( QStringLiteral( "svgTextFormat" ), static_cast< int >( textRenderFormat ) );
mLayout->setCustomProperty( QStringLiteral( "svgDisableRasterTiles" ), disableRasterTiles ? 1 : 0 );
}

settings.cropToContents = clipToContent;
Expand All @@ -4104,6 +4109,11 @@ bool QgsLayoutDesignerDialog::getSvgExportSettings( QgsLayoutExporter::SvgExport
settings.exportMetadata = includeMetadata;
settings.textRenderFormat = textRenderFormat;

if ( disableRasterTiles )
settings.flags = settings.flags | QgsLayoutRenderContext::FlagDisableTiledRasterLayerRenders;
else
settings.flags = settings.flags & ~QgsLayoutRenderContext::FlagDisableTiledRasterLayerRenders;

return true;
}

Expand All @@ -4112,10 +4122,12 @@ bool QgsLayoutDesignerDialog::getPdfExportSettings( QgsLayoutExporter::PdfExport
QgsRenderContext::TextRenderFormat prevTextRenderFormat = mMasterLayout->layoutProject()->labelingEngineSettings().defaultTextRenderFormat();
bool forceVector = false;
bool includeMetadata = true;
bool disableRasterTiles = false;
if ( mLayout )
{
forceVector = mLayout->customProperty( QStringLiteral( "forceVector" ), 0 ).toBool();
includeMetadata = mLayout->customProperty( QStringLiteral( "pdfIncludeMetadata" ), 1 ).toBool();
disableRasterTiles = mLayout->customProperty( QStringLiteral( "pdfDisableRasterTiles" ), 0 ).toBool();
const int prevLayoutSettingLabelsAsOutlines = mLayout->customProperty( QStringLiteral( "pdfTextFormat" ), -1 ).toInt();
if ( prevLayoutSettingLabelsAsOutlines >= 0 )
{
Expand All @@ -4135,25 +4147,32 @@ bool QgsLayoutDesignerDialog::getPdfExportSettings( QgsLayoutExporter::PdfExport
options.mTextRenderFormatComboBox->setCurrentIndex( options.mTextRenderFormatComboBox->findData( prevTextRenderFormat ) );
options.mForceVectorCheckBox->setChecked( forceVector );
options.mIncludeMetadataCheckbox->setChecked( includeMetadata );
options.mDisableRasterTilingCheckBox->setChecked( disableRasterTiles );

if ( dialog.exec() != QDialog::Accepted )
return false;

includeMetadata = options.mIncludeMetadataCheckbox->isChecked();
forceVector = options.mForceVectorCheckBox->isChecked();
disableRasterTiles = options.mDisableRasterTilingCheckBox->isChecked();
QgsRenderContext::TextRenderFormat textRenderFormat = static_cast< QgsRenderContext::TextRenderFormat >( options.mTextRenderFormatComboBox->currentData().toInt() );

if ( mLayout )
{
//save dialog settings
mLayout->setCustomProperty( QStringLiteral( "forceVector" ), forceVector ? 1 : 0 );
mLayout->setCustomProperty( QStringLiteral( "pdfIncludeMetadata" ), includeMetadata ? 1 : 0 );
mLayout->setCustomProperty( QStringLiteral( "pdfDisableRasterTiles" ), disableRasterTiles ? 1 : 0 );
mLayout->setCustomProperty( QStringLiteral( "pdfTextFormat" ), static_cast< int >( textRenderFormat ) );
}

settings.forceVectorOutput = forceVector;
settings.exportMetadata = includeMetadata;
settings.textRenderFormat = textRenderFormat;
if ( disableRasterTiles )
settings.flags = settings.flags | QgsLayoutRenderContext::FlagDisableTiledRasterLayerRenders;
else
settings.flags = settings.flags & ~QgsLayoutRenderContext::FlagDisableTiledRasterLayerRenders;

return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -1182,6 +1182,7 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF
jobMapSettings.setFlag( QgsMapSettings::DrawEditingInfo, false );
jobMapSettings.setSelectionColor( mLayout->renderContext().selectionColor() );
jobMapSettings.setFlag( QgsMapSettings::DrawSelection, mLayout->renderContext().flags() & QgsLayoutRenderContext::FlagDrawSelection );
jobMapSettings.setFlag( QgsMapSettings::RenderPartialOutput, mLayout->renderContext().flags() & QgsLayoutRenderContext::FlagDisableTiledRasterLayerRenders );
jobMapSettings.setFlag( QgsMapSettings::UseAdvancedEffects, mLayout->renderContext().flags() & QgsLayoutRenderContext::FlagUseAdvancedEffects );
jobMapSettings.setTransformContext( mLayout->project()->transformContext() );
jobMapSettings.setPathResolver( mLayout->project()->pathResolver() );
Expand Down
1 change: 1 addition & 0 deletions src/core/layout/qgslayoutrendercontext.h
Expand Up @@ -46,6 +46,7 @@ class CORE_EXPORT QgsLayoutRenderContext : public QObject
FlagForceVectorOutput = 1 << 5, //!< Force output in vector format where possible, even if items require rasterization to keep their correct appearance.
FlagHideCoverageLayer = 1 << 6, //!< Hide coverage layer in outputs
FlagDrawSelection = 1 << 7, //!< Draw selection
FlagDisableTiledRasterLayerRenders = 1 << 8, //!< If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in exported files, at the cost of much higher memory usage during exports.
};
Q_DECLARE_FLAGS( Flags, Flag )

Expand Down
50 changes: 36 additions & 14 deletions src/ui/layout/qgspdfexportoptions.ui
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>489</width>
<height>197</height>
<height>276</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -20,33 +20,55 @@
<string>Export Options</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="mIncludeMetadataCheckbox">
<property name="text">
<string>Export RDF metadata</string>
<item row="3" column="1">
<widget class="QComboBox" name="mTextRenderFormatComboBox"/>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="mForceVectorCheckBox">
<property name="toolTip">
<string>If checked, the layout will always be kept as vector objects when exported to a compatible format, even if the appearance of the resultant file does not match the layouts settings. If unchecked, some elements in the layout may be rasterized in order to keep their appearance intact.</string>
</property>
<property name="checked">
<bool>true</bool>
<property name="text">
<string>Always export as vectors</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="mTextRenderFormatComboBox"/>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Text export</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="mIncludeMetadataCheckbox">
<property name="text">
<string>Export RDF metadata</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox_2">
<property name="title">
<string>Advanced Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="mForceVectorCheckBox">
<widget class="QCheckBox" name="mDisableRasterTilingCheckBox">
<property name="toolTip">
<string>If checked, the layout will always be kept as vector objects when exported to a compatible format, even if the appearance of the resultant file does not match the layouts settings. If unchecked, some elements in the layout may be rasterized in order to keep their appearance intact.</string>
<string>Disables tiled rendering of raster layers. This setting may improve the export quality in some circumstances, at the cost of much greater memory usage during exports.</string>
</property>
<property name="text">
<string>Always export as vectors</string>
<string>Disable tiled raster layer exports</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
Expand Down
24 changes: 23 additions & 1 deletion src/ui/layout/qgssvgexportoptions.ui
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>489</width>
<height>385</height>
<height>464</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -181,6 +181,28 @@
</property>
</spacer>
</item>
<item>
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox_2">
<property name="title">
<string>Advanced Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="mDisableRasterTilingCheckBox">
<property name="toolTip">
<string>Disables tiled rendering of raster layers. This setting may improve the export quality in some circumstances, at the cost of much greater memory usage during exports.</string>
</property>
<property name="text">
<string>Disable tiled raster layer exports</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
Expand Down

0 comments on commit 60b8d05

Please sign in to comment.