diff --git a/python/core/auto_generated/layout/qgslayoutexporter.sip.in b/python/core/auto_generated/layout/qgslayoutexporter.sip.in index 8062212f440..401bc0c79c0 100644 --- a/python/core/auto_generated/layout/qgslayoutexporter.sip.in +++ b/python/core/auto_generated/layout/qgslayoutexporter.sip.in @@ -188,6 +188,8 @@ Constructor for PdfExportSettings QgsLayoutRenderContext::Flags flags; + QgsRenderContext::TextRenderFormat textRenderFormat; + }; ExportResult exportToPdf( const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings ); @@ -286,6 +288,8 @@ Constructor for SvgExportSettings QgsLayoutRenderContext::Flags flags; + QgsRenderContext::TextRenderFormat textRenderFormat; + }; ExportResult exportToSvg( const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings ); diff --git a/src/core/layout/qgslayoutexporter.cpp b/src/core/layout/qgslayoutexporter.cpp index d9f8df63c15..8dd28170bcb 100644 --- a/src/core/layout/qgslayoutexporter.cpp +++ b/src/core/layout/qgslayoutexporter.cpp @@ -299,6 +299,7 @@ class LayoutContextSettingsRestorer : mLayout( layout ) , mPreviousDpi( layout->renderContext().dpi() ) , mPreviousFlags( layout->renderContext().flags() ) + , mPreviousTextFormat( layout->renderContext().textRenderFormat() ) , mPreviousExportLayer( layout->renderContext().currentExportLayer() ) { } @@ -307,6 +308,7 @@ class LayoutContextSettingsRestorer { mLayout->renderContext().setDpi( mPreviousDpi ); mLayout->renderContext().setFlags( mPreviousFlags ); + mLayout->renderContext().setTextRenderFormat( mPreviousTextFormat ); mLayout->renderContext().setCurrentExportLayer( mPreviousExportLayer ); } @@ -317,6 +319,7 @@ class LayoutContextSettingsRestorer QgsLayout *mLayout = nullptr; double mPreviousDpi = 0; QgsLayoutRenderContext::Flags mPreviousFlags = nullptr; + QgsRenderContext::TextRenderFormat mPreviousTextFormat = QgsRenderContext::TextFormatAlwaysOutlines; int mPreviousExportLayer = 0; }; ///@endcond PRIVATE @@ -496,6 +499,8 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToPdf( const QString &f mLayout->renderContext().setFlag( QgsLayoutRenderContext::FlagForceVectorOutput, settings.forceVectorOutput ); + mLayout->renderContext().setTextRenderFormat( settings.textRenderFormat ); + QPrinter printer; preparePrintAsPdf( mLayout, printer, filePath ); preparePrint( mLayout, printer, false ); @@ -565,6 +570,8 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToPdf( QgsAbstractLayou iterator->layout()->renderContext().setFlag( QgsLayoutRenderContext::FlagForceVectorOutput, settings.forceVectorOutput ); + iterator->layout()->renderContext().setTextRenderFormat( settings.textRenderFormat ); + if ( first ) { preparePrintAsPdf( iterator->layout(), printer, fileName ); @@ -780,6 +787,7 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToSvg( const QString &f mLayout->renderContext().setDpi( settings.dpi ); mLayout->renderContext().setFlag( QgsLayoutRenderContext::FlagForceVectorOutput, settings.forceVectorOutput ); + mLayout->renderContext().setTextRenderFormat( s.textRenderFormat ); QFileInfo fi( filePath ); PageExportDetails pageDetails; diff --git a/src/core/layout/qgslayoutexporter.h b/src/core/layout/qgslayoutexporter.h index 8b91718c400..0a53ef7dee7 100644 --- a/src/core/layout/qgslayoutexporter.h +++ b/src/core/layout/qgslayoutexporter.h @@ -278,6 +278,14 @@ class CORE_EXPORT QgsLayoutExporter */ QgsLayoutRenderContext::Flags flags = nullptr; + /** + * Text rendering format, which controls how text should be rendered in the export (e.g. + * as paths or real text objects). + * + * \since QGIS 3.4.3 + */ + QgsRenderContext::TextRenderFormat textRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines; + }; /** @@ -417,6 +425,14 @@ class CORE_EXPORT QgsLayoutExporter */ QgsLayoutRenderContext::Flags flags = nullptr; + /** + * Text rendering format, which controls how text should be rendered in the export (e.g. + * as paths or real text objects). + * + * \since QGIS 3.4.3 + */ + QgsRenderContext::TextRenderFormat textRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines; + }; /** diff --git a/tests/src/python/test_qgslayoutexporter.py b/tests/src/python/test_qgslayoutexporter.py index 79a05ba843a..c6719c381e2 100644 --- a/tests/src/python/test_qgslayoutexporter.py +++ b/tests/src/python/test_qgslayoutexporter.py @@ -31,6 +31,7 @@ from qgis.core import (QgsMultiRenderChecker, QgsRectangle, QgsLayoutItemPage, QgsLayoutItemMap, + QgsLayoutItemScaleBar, QgsLayoutPoint, QgsLayoutMeasurement, QgsUnitTypes, @@ -40,6 +41,7 @@ from qgis.core import (QgsMultiRenderChecker, QgsCoordinateReferenceSystem, QgsPrintLayout, QgsSingleSymbolRenderer, + QgsRenderContext, QgsReport) from qgis.PyQt.QtCore import QSize, QSizeF, QDir, QRectF, Qt, QDateTime, QDate, QTime, QTimeZone from qgis.PyQt.QtGui import QImage, QPainter @@ -615,6 +617,53 @@ class TestQgsLayoutExporter(unittest.TestCase): for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, False) + def testExportToSvgTextRenderFormat(self): + l = QgsLayout(QgsProject.instance()) + l.initializeDefaults() + + # add a map and scalebar + mapitem = QgsLayoutItemMap(l) + mapitem.attemptSetSceneRect(QRectF(110, 120, 200, 250)) + mapitem.zoomToExtent(QgsRectangle(1, 1, 10, 10)) + mapitem.setScale(666) # unlikely to appear in the SVG by accident... unless... oh no! RUN! + l.addItem(mapitem) + + item1 = QgsLayoutItemScaleBar(l) + item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) + item1.setLinkedMap(mapitem) + item1.setStyle('Numeric') + l.addItem(item1) + + exporter = QgsLayoutExporter(l) + # setup settings + settings = QgsLayoutExporter.SvgExportSettings() + settings.dpi = 80 + settings.forceVectorOutput = False + settings.exportMetadata = True + settings.textRenderFormat = QgsRenderContext.TextFormatAlwaysText + + svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgtextformattext.svg') + self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) + self.assertTrue(os.path.exists(svg_file_path)) + + # expect svg to contain a text object with the scale + with open(svg_file_path, 'r') as f: + lines = ''.join(f.readlines()) + self.assertIn('1:666<', lines) + + # force use of outlines + os.unlink(svg_file_path) + settings.textRenderFormat = QgsRenderContext.TextFormatAlwaysOutlines + self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) + self.assertTrue(os.path.exists(svg_file_path)) + + # expect svg NOT to contain a text object with the scale + with open(svg_file_path, 'r') as f: + lines = ''.join(f.readlines()) + self.assertNotIn('1:666<', lines) + def testPrint(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults()