[layouts][FEATURE] Don't force the whole layout to be rasterized

when exporting to PDF

If an individual layout item needs rasterisation in order to
be exported correctly, it can now be individually rasterised
without forcing every other item to also be rasterised.

This allows exports to PDF keeping as much as possible as vectors,
e.g. a map with layer opacity won't force labels, scalebars, etc
to be rasterised too.

To accompany this, a new "Always export as vectors" checkbox
was added to layout properties. If checked, this will force
the export to keep items as vectors, even when it causes the
output to look different to layouts.

Fixes #7885
This commit is contained in:
Nyall Dawson 2017-12-12 17:08:34 +10:00
parent 91179f1396
commit b992e871ee
17 changed files with 236 additions and 40 deletions

View File

@ -27,6 +27,7 @@ class QgsLayoutContext : QObject
FlagOutlineOnly, FlagOutlineOnly,
FlagAntialiasing, FlagAntialiasing,
FlagUseAdvancedEffects, FlagUseAdvancedEffects,
FlagForceVectorOutput,
}; };
typedef QFlags<QgsLayoutContext::Flag> Flags; typedef QFlags<QgsLayoutContext::Flag> Flags;

View File

@ -212,7 +212,18 @@ Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
bool rasterizeWholeImage; bool rasterizeWholeImage;
%Docstring %Docstring
Set to true to force whole layout to be rasterized while exporting Set to true to force whole layout to be rasterized while exporting.
This option is mutually exclusive with forceVectorOutput.
%End
bool forceVectorOutput;
%Docstring
Set to true to force vector object exports, even when the resultant appearance will differ
from the layout. If false, some items may be rasterized in order to maintain their
correct appearance in the output.
This option is mutually exclusive with rasterizeWholeImage.
%End %End
QgsLayoutContext::Flags flags; QgsLayoutContext::Flags flags;

View File

@ -827,6 +827,16 @@ Sets whether the item should be excluded from composer exports and prints.
Subclasses should ensure that implemented overrides of this method Subclasses should ensure that implemented overrides of this method
also check the base class result. also check the base class result.
.. seealso:: :py:func:`requiresRasterization()`
:rtype: bool
%End
virtual bool requiresRasterization() const;
%Docstring
Returns true if the item is drawn in such a way that forces the whole layout
to be rasterised when exporting to vector formats.
.. seealso:: :py:func:`containsAdvancedEffects()`
:rtype: bool :rtype: bool
%End %End

View File

@ -296,6 +296,8 @@ Forces a recalculation of the picture's frame size
virtual void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties ); virtual void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties );
virtual bool containsAdvancedEffects() const;
signals: signals:
void pictureRotationChanged( double newRotation ); void pictureRotationChanged( double newRotation );

View File

@ -1552,9 +1552,14 @@ void QgsLayoutDesignerDialog::exportToPdf()
showWmsPrintingWarning(); showWmsPrintingWarning();
} }
if ( containsAdvancedEffects() ) if ( requiresRasterization() )
{ {
showAdvancedEffectsWarning(); showRasterizationWarning();
}
if ( containsAdvancedEffects() && ( mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool() ) )
{
showForceVectorWarning();
} }
QgsSettings settings; QgsSettings settings;
@ -1602,7 +1607,8 @@ void QgsLayoutDesignerDialog::exportToPdf()
QApplication::setOverrideCursor( Qt::BusyCursor ); QApplication::setOverrideCursor( Qt::BusyCursor );
QgsLayoutExporter::PdfExportSettings pdfSettings; QgsLayoutExporter::PdfExportSettings pdfSettings;
pdfSettings.rasteriseWholeImage = mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool(); pdfSettings.rasterizeWholeImage = mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool();
pdfSettings.forceVectorOutput = mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool();
QgsLayoutExporter exporter( mLayout ); QgsLayoutExporter exporter( mLayout );
switch ( exporter.exportToPdf( outputFileName, pdfSettings ) ) switch ( exporter.exportToPdf( outputFileName, pdfSettings ) )
@ -1783,6 +1789,19 @@ void QgsLayoutDesignerDialog::showWmsPrintingWarning()
} }
} }
bool QgsLayoutDesignerDialog::requiresRasterization() const
{
QList< QgsLayoutItem *> items;
mLayout->layoutItems( items );
for ( QgsLayoutItem *currentItem : qgis::as_const( items ) )
{
if ( currentItem->requiresRasterization() )
return true;
}
return false;
}
bool QgsLayoutDesignerDialog::containsAdvancedEffects() const bool QgsLayoutDesignerDialog::containsAdvancedEffects() const
{ {
QList< QgsLayoutItem *> items; QList< QgsLayoutItem *> items;
@ -1796,10 +1815,11 @@ bool QgsLayoutDesignerDialog::containsAdvancedEffects() const
return false; return false;
} }
void QgsLayoutDesignerDialog::showAdvancedEffectsWarning() void QgsLayoutDesignerDialog::showRasterizationWarning()
{ {
bool rasterize = mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool();
if ( rasterise ) if ( mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool() ||
mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool() )
return; return;
QgsMessageViewer *m = new QgsMessageViewer( this, QgsGuiUtils::ModalDialogFlags, false ); QgsMessageViewer *m = new QgsMessageViewer( this, QgsGuiUtils::ModalDialogFlags, false );
@ -1817,6 +1837,27 @@ void QgsLayoutDesignerDialog::showAdvancedEffectsWarning()
delete m; delete m;
} }
void QgsLayoutDesignerDialog::showForceVectorWarning()
{
QgsSettings settings;
if ( settings.value( QStringLiteral( "LayoutDesigner/hideForceVectorWarning" ), false, QgsSettings::App ).toBool() )
return;
QgsMessageViewer *m = new QgsMessageViewer( this, QgsGuiUtils::ModalDialogFlags, false );
m->setWindowTitle( tr( "Force Vector" ) );
m->setMessage( tr( "This layout has the \"Always export as vectors\" option enabled, but the layout contains effects such as blend modes or vector layer transparency, which cannot be printed as vectors. The generated file will differ from the layout contents." ), QgsMessageOutput::MessageText );
m->setCheckBoxText( tr( "Never show this message again" ) );
m->setCheckBoxState( Qt::Unchecked );
m->setCheckBoxVisible( true );
m->showMessage( true );
if ( m->checkBoxState() == Qt::Checked )
{
settings.setValue( QStringLiteral( "LayoutDesigner/hideForceVectorWarning" ), true, QgsSettings::App );
}
delete m;
}
void QgsLayoutDesignerDialog::selectItems( const QList<QgsLayoutItem *> items ) void QgsLayoutDesignerDialog::selectItems( const QList<QgsLayoutItem *> items )
{ {
for ( QGraphicsItem *item : items ) for ( QGraphicsItem *item : items )

View File

@ -371,10 +371,13 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
void showWmsPrintingWarning(); void showWmsPrintingWarning();
//! True if the layout contains advanced effects, such as blend modes //! True if the layout contains advanced effects, such as blend modes
bool requiresRasterization() const;
bool containsAdvancedEffects() const; bool containsAdvancedEffects() const;
//! Displays a warning because of incompatibility between blend modes and QPrinter //! Displays a warning because of incompatibility between blend modes and QPrinter
void showAdvancedEffectsWarning(); void showRasterizationWarning();
void showForceVectorWarning();
}; };
#endif // QGSLAYOUTDESIGNERDIALOG_H #endif // QGSLAYOUTDESIGNERDIALOG_H

View File

@ -59,6 +59,7 @@ QgsLayoutPropertiesWidget::QgsLayoutPropertiesWidget( QWidget *parent, QgsLayout
connect( mGenerateWorldFileCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::worldFileToggled ); connect( mGenerateWorldFileCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::worldFileToggled );
connect( mRasterizeCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::rasteriseToggled ); connect( mRasterizeCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::rasteriseToggled );
connect( mForceVectorCheckBox, &QCheckBox::toggled, this, &QgsLayoutPropertiesWidget::forceVectorToggled );
mTopMarginSpinBox->setValue( topMargin ); mTopMarginSpinBox->setValue( topMargin );
mMarginUnitsComboBox->linkToWidget( mTopMarginSpinBox ); mMarginUnitsComboBox->linkToWidget( mTopMarginSpinBox );
@ -93,6 +94,19 @@ void QgsLayoutPropertiesWidget::updateGui()
bool rasterise = mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool(); bool rasterise = mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool();
whileBlocking( mRasterizeCheckBox )->setChecked( rasterise ); whileBlocking( mRasterizeCheckBox )->setChecked( rasterise );
bool forceVectors = mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool();
whileBlocking( mForceVectorCheckBox )->setChecked( forceVectors );
if ( rasterise )
{
mForceVectorCheckBox->setChecked( false );
mForceVectorCheckBox->setEnabled( false );
}
else
{
mForceVectorCheckBox->setEnabled( true );
}
} }
void QgsLayoutPropertiesWidget::updateSnappingElements() void QgsLayoutPropertiesWidget::updateSnappingElements()
@ -197,6 +211,21 @@ void QgsLayoutPropertiesWidget::worldFileToggled()
void QgsLayoutPropertiesWidget::rasteriseToggled() void QgsLayoutPropertiesWidget::rasteriseToggled()
{ {
mLayout->setCustomProperty( QStringLiteral( "rasterise" ), mRasterizeCheckBox->isChecked() ); mLayout->setCustomProperty( QStringLiteral( "rasterise" ), mRasterizeCheckBox->isChecked() );
if ( mRasterizeCheckBox->isChecked() )
{
mForceVectorCheckBox->setChecked( false );
mForceVectorCheckBox->setEnabled( false );
}
else
{
mForceVectorCheckBox->setEnabled( true );
}
}
void QgsLayoutPropertiesWidget::forceVectorToggled()
{
mLayout->setCustomProperty( QStringLiteral( "forceVector" ), mForceVectorCheckBox->isChecked() );
} }
void QgsLayoutPropertiesWidget::blockSignals( bool block ) void QgsLayoutPropertiesWidget::blockSignals( bool block )

View File

@ -47,6 +47,7 @@ class QgsLayoutPropertiesWidget: public QgsPanelWidget, private Ui::QgsLayoutWid
void dpiChanged( int value ); void dpiChanged( int value );
void worldFileToggled(); void worldFileToggled();
void rasteriseToggled(); void rasteriseToggled();
void forceVectorToggled();
private: private:

View File

@ -45,6 +45,7 @@ class CORE_EXPORT QgsLayoutContext : public QObject
FlagOutlineOnly = 1 << 2, //!< Render items as outlines only. FlagOutlineOnly = 1 << 2, //!< Render items as outlines only.
FlagAntialiasing = 1 << 3, //!< Use antialiasing when drawing items. FlagAntialiasing = 1 << 3, //!< Use antialiasing when drawing items.
FlagUseAdvancedEffects = 1 << 4, //!< Enable advanced effects such as blend modes. FlagUseAdvancedEffects = 1 << 4, //!< Enable advanced effects such as blend modes.
FlagForceVectorOutput = 1 << 5, //!< Force output in vector format where possible, even if items require rasterization to keep their correct appearance.
}; };
Q_DECLARE_FLAGS( Flags, Flag ) Q_DECLARE_FLAGS( Flags, Flag )

View File

@ -310,7 +310,9 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToPdf( const QString &f
// If we are not printing as raster, temporarily disable advanced effects // If we are not printing as raster, temporarily disable advanced effects
// as QPrinter does not support composition modes and can result // as QPrinter does not support composition modes and can result
// in items missing from the output // in items missing from the output
mLayout->context().setFlag( QgsLayoutContext::FlagUseAdvancedEffects, settings.rasteriseWholeImage ); mLayout->context().setFlag( QgsLayoutContext::FlagUseAdvancedEffects, !settings.forceVectorOutput );
mLayout->context().setFlag( QgsLayoutContext::FlagForceVectorOutput, settings.forceVectorOutput );
QPrinter printer; QPrinter printer;
preparePrintAsPdf( printer, filePath ); preparePrintAsPdf( printer, filePath );
@ -322,7 +324,7 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToPdf( const QString &f
return PrintError; return PrintError;
} }
ExportResult result = printPrivate( printer, p, false, settings.dpi, settings.rasteriseWholeImage ); ExportResult result = printPrivate( printer, p, false, settings.dpi, settings.rasterizeWholeImage );
p.end(); p.end();
#if 0//TODO #if 0//TODO

View File

@ -216,9 +216,22 @@ class CORE_EXPORT QgsLayoutExporter
//! Resolution to export layout at. If dpi <= 0 the default layout dpi will be used. //! Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
double dpi = -1; double dpi = -1;
//! Set to true to force whole layout to be rasterized while exporting /**
* Set to true to force whole layout to be rasterized while exporting.
*
* This option is mutually exclusive with forceVectorOutput.
*/
bool rasterizeWholeImage = false; bool rasterizeWholeImage = false;
/**
* Set to true to force vector object exports, even when the resultant appearance will differ
* from the layout. If false, some items may be rasterized in order to maintain their
* correct appearance in the output.
*
* This option is mutually exclusive with rasterizeWholeImage.
*/
bool forceVectorOutput = false;
/** /**
* Layout context flags, which control how the export will be created. * Layout context flags, which control how the export will be created.
*/ */

View File

@ -242,18 +242,32 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
return; return;
} }
double destinationDpi = itemStyle->matrix.m11() * 25.4; bool previewRender = !mLayout || mLayout->context().isPreviewRender();
double destinationDpi = previewRender ? itemStyle->matrix.m11() * 25.4 : mLayout->context().dpi();
bool useImageCache = false; bool useImageCache = false;
bool forceRasterOutput = containsAdvancedEffects() && ( !mLayout || !( mLayout->context().flags() & QgsLayoutContext::FlagForceVectorOutput ) );
if ( useImageCache ) if ( useImageCache || forceRasterOutput )
{ {
double widthInPixels = boundingRect().width() * itemStyle->matrix.m11(); double widthInPixels = 0;
double heightInPixels = boundingRect().height() * itemStyle->matrix.m11(); double heightInPixels = 0;
if ( previewRender )
{
widthInPixels = boundingRect().width() * itemStyle->matrix.m11();
heightInPixels = boundingRect().height() * itemStyle->matrix.m11();
}
else
{
double layoutUnitsToPixels = mLayout ? mLayout->convertFromLayoutUnits( 1, QgsUnitTypes::LayoutPixels ).length() : destinationDpi / 25.4;
widthInPixels = boundingRect().width() * layoutUnitsToPixels;
heightInPixels = boundingRect().height() * layoutUnitsToPixels;
}
// limit size of image for better performance // limit size of image for better performance
double scale = 1.0; if ( previewRender && ( widthInPixels > CACHE_SIZE_LIMIT || heightInPixels > CACHE_SIZE_LIMIT ) )
if ( widthInPixels > CACHE_SIZE_LIMIT || heightInPixels > CACHE_SIZE_LIMIT )
{ {
double scale = 1.0;
if ( widthInPixels > heightInPixels ) if ( widthInPixels > heightInPixels )
{ {
scale = widthInPixels / CACHE_SIZE_LIMIT; scale = widthInPixels / CACHE_SIZE_LIMIT;
@ -269,7 +283,7 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
destinationDpi = destinationDpi / scale; destinationDpi = destinationDpi / scale;
} }
if ( !mItemCachedImage.isNull() && qgsDoubleNear( mItemCacheDpi, destinationDpi ) ) if ( previewRender && !mItemCachedImage.isNull() && qgsDoubleNear( mItemCacheDpi, destinationDpi ) )
{ {
// can reuse last cached image // can reuse last cached image
QgsRenderContext context = QgsLayoutUtils::createRenderContextForMap( nullptr, painter, destinationDpi ); QgsRenderContext context = QgsLayoutUtils::createRenderContextForMap( nullptr, painter, destinationDpi );
@ -284,13 +298,11 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
} }
else else
{ {
mItemCacheDpi = destinationDpi; QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
mItemCachedImage = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 ); image.setDotsPerMeterX( 1000 * destinationDpi * 25.4 );
mItemCachedImage.fill( Qt::transparent ); image.setDotsPerMeterY( 1000 * destinationDpi * 25.4 );
mItemCachedImage.setDotsPerMeterX( 1000 * destinationDpi * 25.4 ); QPainter p( &image );
mItemCachedImage.setDotsPerMeterY( 1000 * destinationDpi * 25.4 );
QPainter p( &mItemCachedImage );
preparePainter( &p ); preparePainter( &p );
QgsRenderContext context = QgsLayoutUtils::createRenderContextForLayout( nullptr, &p, destinationDpi ); QgsRenderContext context = QgsLayoutUtils::createRenderContextForLayout( nullptr, &p, destinationDpi );
@ -306,8 +318,14 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
// scale painter from mm to dots // scale painter from mm to dots
painter->scale( 1.0 / context.scaleFactor(), 1.0 / context.scaleFactor() ); painter->scale( 1.0 / context.scaleFactor(), 1.0 / context.scaleFactor() );
painter->drawImage( boundingRect().x() * context.scaleFactor(), painter->drawImage( boundingRect().x() * context.scaleFactor(),
boundingRect().y() * context.scaleFactor(), mItemCachedImage ); boundingRect().y() * context.scaleFactor(), image );
painter->restore(); painter->restore();
if ( previewRender )
{
mItemCacheDpi = destinationDpi;
mItemCachedImage = image;
}
} }
} }
else else
@ -842,7 +860,12 @@ void QgsLayoutItem::setExcludeFromExports( bool exclude )
bool QgsLayoutItem::containsAdvancedEffects() const bool QgsLayoutItem::containsAdvancedEffects() const
{ {
return blendMode() != QPainter::CompositionMode_SourceOver; return false;
}
bool QgsLayoutItem::requiresRasterization() const
{
return itemOpacity() < 1.0 || blendMode() != QPainter::CompositionMode_SourceOver;
} }
double QgsLayoutItem::estimatedFrameBleed() const double QgsLayoutItem::estimatedFrameBleed() const

View File

@ -748,9 +748,18 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
* *
* Subclasses should ensure that implemented overrides of this method * Subclasses should ensure that implemented overrides of this method
* also check the base class result. * also check the base class result.
*
* \see requiresRasterization()
*/ */
virtual bool containsAdvancedEffects() const; virtual bool containsAdvancedEffects() const;
/**
* Returns true if the item is drawn in such a way that forces the whole layout
* to be rasterised when exporting to vector formats.
* \see containsAdvancedEffects()
*/
virtual bool requiresRasterization() const;
/** /**
* Returns the estimated amount the item's frame bleeds outside the item's * Returns the estimated amount the item's frame bleeds outside the item's
* actual rectangle. For instance, if the item has a 2mm frame stroke, then * actual rectangle. For instance, if the item has a 2mm frame stroke, then

View File

@ -798,19 +798,46 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem
} }
QgsRectangle cExtent = extent(); QgsRectangle cExtent = extent();
QSizeF size( cExtent.width() * mapUnitsToLayoutUnits(), cExtent.height() * mapUnitsToLayoutUnits() ); QSizeF size( cExtent.width() * mapUnitsToLayoutUnits(), cExtent.height() * mapUnitsToLayoutUnits() );
painter->save(); if ( containsAdvancedEffects() && ( !mLayout || !( mLayout->context().flags() & QgsLayoutContext::FlagForceVectorOutput ) ) )
painter->translate( mXOffset, mYOffset ); {
// rasterise
double destinationDpi = mLayout ? mLayout->context().dpi() : style->matrix.m11() * 25.4;
double dotsPerMM = paintDevice->logicalDpiX() / 25.4; double layoutUnitsToPixels = mLayout ? mLayout->convertFromLayoutUnits( 1, QgsUnitTypes::LayoutPixels ).length() : destinationDpi / 25.4;
size *= dotsPerMM; // output size will be in dots (pixels) double widthInPixels = boundingRect().width() * layoutUnitsToPixels;
painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots double heightInPixels = boundingRect().height() * layoutUnitsToPixels;
drawMap( painter, cExtent, size, paintDevice->logicalDpiX() ); QImage image = QImage( widthInPixels, heightInPixels, QImage::Format_ARGB32 );
image.fill( Qt::transparent );
image.setDotsPerMeterX( 1000 * destinationDpi / 25.4 );
image.setDotsPerMeterY( 1000 * destinationDpi / 25.4 );
QPainter p( &image );
double dotsPerMM = image.logicalDpiX() / 25.4;
drawMap( &p, cExtent, image.size(), destinationDpi );
p.end();
dotsPerMM = paintDevice->logicalDpiX() / 25.4;
painter->save();
painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
painter->drawImage( 0, 0, image );
painter->restore();
}
else
{
painter->save();
painter->translate( mXOffset, mYOffset );
double dotsPerMM = paintDevice->logicalDpiX() / 25.4;
size *= dotsPerMM; // output size will be in dots (pixels)
painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
drawMap( painter, cExtent, size, paintDevice->logicalDpiX() );
painter->restore();
}
//restore rotation
painter->restore();
mDrawing = false; mDrawing = false;
} }

View File

@ -666,6 +666,14 @@ void QgsLayoutItemPicture::refreshDataDefinedProperty( const QgsLayoutObject::Da
QgsLayoutItem::refreshDataDefinedProperty( property ); QgsLayoutItem::refreshDataDefinedProperty( property );
} }
bool QgsLayoutItemPicture::containsAdvancedEffects() const
{
if ( QgsLayoutItem::containsAdvancedEffects() )
return true;
return mMode == FormatSVG && itemOpacity() < 1.0;
}
void QgsLayoutItemPicture::setPicturePath( const QString &path ) void QgsLayoutItemPicture::setPicturePath( const QString &path )
{ {
mSourcePath = path; mSourcePath = path;

View File

@ -265,6 +265,7 @@ class CORE_EXPORT QgsLayoutItemPicture: public QgsLayoutItem
void recalculateSize(); void recalculateSize();
void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties ) override; void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties ) override;
bool containsAdvancedEffects() const override;
signals: signals:
//! Is emitted on picture rotation change //! Is emitted on picture rotation change

View File

@ -53,9 +53,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>-316</y>
<width>297</width> <width>297</width>
<height>778</height> <height>810</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
@ -210,7 +210,7 @@
<string>Export settings</string> <string>Export settings</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="0" colspan="2"> <item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="mGenerateWorldFileCheckBox"> <widget class="QCheckBox" name="mGenerateWorldFileCheckBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
@ -251,8 +251,21 @@
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="mRasterizeCheckBox"> <widget class="QCheckBox" name="mRasterizeCheckBox">
<property name="toolTip">
<string>If checked, exports from this layout will be rasterized.</string>
</property>
<property name="text"> <property name="text">
<string>Export as raster</string> <string>Print as raster</string>
</property>
</widget>
</item>
<item row="3" 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 rasterised in order to keep their appearance intact.</string>
</property>
<property name="text">
<string>Always export as vectors</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -445,6 +458,7 @@
<tabstop>mSnapToleranceSpinBox</tabstop> <tabstop>mSnapToleranceSpinBox</tabstop>
<tabstop>mResolutionSpinBox</tabstop> <tabstop>mResolutionSpinBox</tabstop>
<tabstop>mRasterizeCheckBox</tabstop> <tabstop>mRasterizeCheckBox</tabstop>
<tabstop>mForceVectorCheckBox</tabstop>
<tabstop>mGenerateWorldFileCheckBox</tabstop> <tabstop>mGenerateWorldFileCheckBox</tabstop>
<tabstop>mMarginUnitsComboBox</tabstop> <tabstop>mMarginUnitsComboBox</tabstop>
<tabstop>mTopMarginSpinBox</tabstop> <tabstop>mTopMarginSpinBox</tabstop>