Skip to content

Commit 1eaf95a

Browse files
committed
[api] Move setting to control how text is rendered to QgsRenderContext
The new QgsRenderContext::TextRenderFormat enum controls how text should be handled during a render operation, e.g. whether to render text as outlines (paths) or keep it as real text objects. Deprecate previous arguments in QgsTextRenderer which handled this same use case. This allows us to make the setting vary per-render, instead of having a single global flag controlling the setting. Ultimately this will allow us to have different behaviour within the canvas renders vs print layout exports. Refs #3975
1 parent 44fbb89 commit 1eaf95a

12 files changed

+289
-41
lines changed

python/core/auto_generated/qgsmapsettings.sip.in

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,24 @@ Returns combination of flags used for rendering
281281
bool testFlag( Flag flag ) const;
282282
%Docstring
283283
Check whether a particular flag is enabled
284+
%End
285+
286+
QgsRenderContext::TextRenderFormat textRenderFormat() const;
287+
%Docstring
288+
Returns the text render format, which dictates how text is rendered (e.g. as paths or real text objects).
289+
290+
.. seealso:: :py:func:`setTextRenderFormat`
291+
292+
.. versionadded:: 3.4.3
293+
%End
294+
295+
void setTextRenderFormat( QgsRenderContext::TextRenderFormat format );
296+
%Docstring
297+
Sets the text render ``format``, which dictates how text is rendered (e.g. as paths or real text objects).
298+
299+
.. seealso:: :py:func:`textRenderFormat`
300+
301+
.. versionadded:: 3.4.3
284302
%End
285303

286304
void setOutputImageFormat( QImage::Format format );
@@ -516,6 +534,7 @@ Returns global configuration of the labeling engine
516534

517535

518536

537+
519538
void updateDerived();
520539
};
521540

python/core/auto_generated/qgsrendercontext.sip.in

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ to be rendered etc.
4545
typedef QFlags<QgsRenderContext::Flag> Flags;
4646

4747

48+
enum TextRenderFormat
49+
{
50+
TextFormatAlwaysOutlines,
51+
TextFormatAlwaysText,
52+
};
53+
4854
void setFlags( QgsRenderContext::Flags flags );
4955
%Docstring
5056
Set combination of flags that will be used for rendering.
@@ -392,6 +398,24 @@ Convert meter distances to active MapUnit values for QgsUnitTypes.RenderMetersIn
392398
When the sourceCrs() is geographic, the center of the Extent will be used
393399

394400
.. versionadded:: 3.0
401+
%End
402+
403+
TextRenderFormat textRenderFormat() const;
404+
%Docstring
405+
Returns the text render format, which dictates how text is rendered (e.g. as paths or real text objects).
406+
407+
.. seealso:: :py:func:`setTextRenderFormat`
408+
409+
.. versionadded:: 3.4.3
410+
%End
411+
412+
void setTextRenderFormat( TextRenderFormat format );
413+
%Docstring
414+
Sets the text render ``format``, which dictates how text is rendered (e.g. as paths or real text objects).
415+
416+
.. seealso:: :py:func:`textRenderFormat`
417+
418+
.. versionadded:: 3.4.3
395419
%End
396420

397421
};

python/core/auto_generated/qgstextrenderer.sip.in

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,7 @@ Calculates pixel size (considering output size should be in pixel or map units,
15551555
:return: font pixel size
15561556
%End
15571557

1558+
15581559
static void drawText( const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines,
15591560
QgsRenderContext &context, const QgsTextFormat &format,
15601561
bool drawAsOutlines = true );
@@ -1569,7 +1570,8 @@ Draws text within a rectangle using the specified settings.
15691570
:param format: text format
15701571
:param drawAsOutlines: set to false to render text as text. This allows outputs to
15711572
formats like SVG to maintain text as text objects, but at the cost of degraded
1572-
rendering and may result in side effects like misaligned text buffers.
1573+
rendering and may result in side effects like misaligned text buffers. This setting is deprecated and has no effect
1574+
as of QGIS 3.4.3 and the text format should be set using QgsRenderContext.setTextRenderFormat() instead.
15731575
%End
15741576

15751577
static void drawText( QPointF point, double rotation, HAlignment alignment, const QStringList &textLines,
@@ -1586,7 +1588,8 @@ Draws text at a point origin using the specified settings.
15861588
:param format: text format
15871589
:param drawAsOutlines: set to false to render text as text. This allows outputs to
15881590
formats like SVG to maintain text as text objects, but at the cost of degraded
1589-
rendering and may result in side effects like misaligned text buffers.
1591+
rendering and may result in side effects like misaligned text buffers. This setting is deprecated and has no effect
1592+
as of QGIS 3.4.3 and the text format should be set using QgsRenderContext.setTextRenderFormat() instead.
15901593
%End
15911594

15921595
static void drawPart( const QRectF &rect, double rotation, HAlignment alignment, const QStringList &textLines,
@@ -1606,7 +1609,8 @@ Draws a single component of rendered text using the specified settings.
16061609
with the text or background parts)
16071610
:param drawAsOutlines: set to false to render text as text. This allows outputs to
16081611
formats like SVG to maintain text as text objects, but at the cost of degraded
1609-
rendering and may result in side effects like misaligned text buffers.
1612+
rendering and may result in side effects like misaligned text buffers. This setting is deprecated and has no effect
1613+
as of QGIS 3.4.3 and the text format should be set using QgsRenderContext.setTextRenderFormat() instead.
16101614
%End
16111615

16121616
static void drawPart( QPointF origin, double rotation, HAlignment alignment, const QStringList &textLines,
@@ -1626,7 +1630,8 @@ Draws a single component of rendered text using the specified settings.
16261630
with the text or background parts)
16271631
:param drawAsOutlines: set to false to render text as text. This allows outputs to
16281632
formats like SVG to maintain text as text objects, but at the cost of degraded
1629-
rendering and may result in side effects like misaligned text buffers.
1633+
rendering and may result in side effects like misaligned text buffers. This setting is deprecated and has no effect
1634+
as of QGIS 3.4.3 and the text format should be set using QgsRenderContext.setTextRenderFormat() instead.
16301635
%End
16311636

16321637
static QFontMetricsF fontMetrics( QgsRenderContext &context, const QgsTextFormat &format );

src/core/qgsmapsettings.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,28 @@ class CORE_EXPORT QgsMapSettings
253253
//! Check whether a particular flag is enabled
254254
bool testFlag( Flag flag ) const;
255255

256+
/**
257+
* Returns the text render format, which dictates how text is rendered (e.g. as paths or real text objects).
258+
*
259+
* \see setTextRenderFormat()
260+
* \since QGIS 3.4.3
261+
*/
262+
QgsRenderContext::TextRenderFormat textRenderFormat() const
263+
{
264+
return mTextRenderFormat;
265+
}
266+
267+
/**
268+
* Sets the text render \a format, which dictates how text is rendered (e.g. as paths or real text objects).
269+
*
270+
* \see textRenderFormat()
271+
* \since QGIS 3.4.3
272+
*/
273+
void setTextRenderFormat( QgsRenderContext::TextRenderFormat format )
274+
{
275+
mTextRenderFormat = format;
276+
}
277+
256278
//! sets format of internal QImage
257279
void setOutputImageFormat( QImage::Format format ) { mImageFormat = format; }
258280
//! format of internal QImage, default QImage::Format_ARGB32_Premultiplied
@@ -470,6 +492,8 @@ class CORE_EXPORT QgsMapSettings
470492

471493
QgsPathResolver mPathResolver;
472494

495+
QgsRenderContext::TextRenderFormat mTextRenderFormat = QgsRenderContext::TextFormatAlwaysOutlines;
496+
473497
#ifdef QGISDEBUG
474498
bool mHasTransformContext = false;
475499
#endif

src/core/qgsrendercontext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
5757
, mSegmentationToleranceType( rh.mSegmentationToleranceType )
5858
, mTransformContext( rh.mTransformContext )
5959
, mPathResolver( rh.mPathResolver )
60+
, mTextRenderFormat( rh.mTextRenderFormat )
6061
#ifdef QGISDEBUG
6162
, mHasTransformContext( rh.mHasTransformContext )
6263
#endif
@@ -84,6 +85,7 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
8485
mDistanceArea = rh.mDistanceArea;
8586
mTransformContext = rh.mTransformContext;
8687
mPathResolver = rh.mPathResolver;
88+
mTextRenderFormat = rh.mTextRenderFormat;
8789
#ifdef QGISDEBUG
8890
mHasTransformContext = rh.mHasTransformContext;
8991
#endif
@@ -172,6 +174,7 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings &mapSet
172174
ctx.mDistanceArea.setEllipsoid( mapSettings.ellipsoid() );
173175
ctx.setTransformContext( mapSettings.transformContext() );
174176
ctx.setPathResolver( mapSettings.pathResolver() );
177+
ctx.setTextRenderFormat( mapSettings.textRenderFormat() );
175178
//this flag is only for stopping during the current rendering progress,
176179
//so must be false at every new render operation
177180
ctx.setRenderingStopped( false );
@@ -446,3 +449,5 @@ double QgsRenderContext::convertMetersToMapUnits( double meters ) const
446449
}
447450
return meters;
448451
}
452+
453+

src/core/qgsrendercontext.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ class CORE_EXPORT QgsRenderContext
7575
};
7676
Q_DECLARE_FLAGS( Flags, Flag )
7777

78+
/**
79+
* Options for rendering text.
80+
* \since QGIS 3.4.3
81+
*/
82+
enum TextRenderFormat
83+
{
84+
TextFormatAlwaysOutlines, //!< Always render text using path objects (AKA outlines/curves). This always results in the best quality rendering.
85+
TextFormatAlwaysText, //!< Always render text as text objects. This may result in rendering artefacts or poor quality rendering, depending on the text format settings.
86+
};
87+
7888
/**
7989
* Set combination of flags that will be used for rendering.
8090
* \since QGIS 2.14
@@ -386,6 +396,28 @@ class CORE_EXPORT QgsRenderContext
386396
*/
387397
double convertMetersToMapUnits( double meters ) const;
388398

399+
/**
400+
* Returns the text render format, which dictates how text is rendered (e.g. as paths or real text objects).
401+
*
402+
* \see setTextRenderFormat()
403+
* \since QGIS 3.4.3
404+
*/
405+
TextRenderFormat textRenderFormat() const
406+
{
407+
return mTextRenderFormat;
408+
}
409+
410+
/**
411+
* Sets the text render \a format, which dictates how text is rendered (e.g. as paths or real text objects).
412+
*
413+
* \see textRenderFormat()
414+
* \since QGIS 3.4.3
415+
*/
416+
void setTextRenderFormat( TextRenderFormat format )
417+
{
418+
mTextRenderFormat = format;
419+
}
420+
389421
private:
390422

391423
Flags mFlags;
@@ -442,6 +474,8 @@ class CORE_EXPORT QgsRenderContext
442474

443475
QgsPathResolver mPathResolver;
444476

477+
TextRenderFormat mTextRenderFormat = TextFormatAlwaysOutlines;
478+
445479
#ifdef QGISDEBUG
446480
bool mHasTransformContext = false;
447481
#endif

src/core/qgstextrenderer.cpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,38 +1708,38 @@ int QgsTextRenderer::sizeToPixel( double size, const QgsRenderContext &c, QgsUni
17081708
return static_cast< int >( c.convertToPainterUnits( size, unit, mapUnitScale ) + 0.5 ); //NOLINT
17091709
}
17101710

1711-
void QgsTextRenderer::drawText( const QRectF &rect, double rotation, QgsTextRenderer::HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines )
1711+
void QgsTextRenderer::drawText( const QRectF &rect, double rotation, QgsTextRenderer::HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool )
17121712
{
17131713
QgsTextFormat tmpFormat = updateShadowPosition( format );
17141714

17151715
if ( tmpFormat.background().enabled() )
17161716
{
1717-
drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Background, drawAsOutlines );
1717+
drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Background );
17181718
}
17191719

17201720
if ( tmpFormat.buffer().enabled() )
17211721
{
1722-
drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Buffer, drawAsOutlines );
1722+
drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Buffer );
17231723
}
17241724

1725-
drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Text, drawAsOutlines );
1725+
drawPart( rect, rotation, alignment, textLines, context, tmpFormat, Text );
17261726
}
17271727

1728-
void QgsTextRenderer::drawText( QPointF point, double rotation, QgsTextRenderer::HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines )
1728+
void QgsTextRenderer::drawText( QPointF point, double rotation, QgsTextRenderer::HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool )
17291729
{
17301730
QgsTextFormat tmpFormat = updateShadowPosition( format );
17311731

17321732
if ( tmpFormat.background().enabled() )
17331733
{
1734-
drawPart( point, rotation, alignment, textLines, context, tmpFormat, Background, drawAsOutlines );
1734+
drawPart( point, rotation, alignment, textLines, context, tmpFormat, Background );
17351735
}
17361736

17371737
if ( tmpFormat.buffer().enabled() )
17381738
{
1739-
drawPart( point, rotation, alignment, textLines, context, tmpFormat, Buffer, drawAsOutlines );
1739+
drawPart( point, rotation, alignment, textLines, context, tmpFormat, Buffer );
17401740
}
17411741

1742-
drawPart( point, rotation, alignment, textLines, context, tmpFormat, Text, drawAsOutlines );
1742+
drawPart( point, rotation, alignment, textLines, context, tmpFormat, Text );
17431743
}
17441744

17451745
QgsTextFormat QgsTextRenderer::updateShadowPosition( const QgsTextFormat &format )
@@ -1764,7 +1764,7 @@ QgsTextFormat QgsTextRenderer::updateShadowPosition( const QgsTextFormat &format
17641764
}
17651765

17661766
void QgsTextRenderer::drawPart( const QRectF &rect, double rotation, HAlignment alignment,
1767-
const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, QgsTextRenderer::TextPart part, bool drawAsOutlines )
1767+
const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, QgsTextRenderer::TextPart part, bool )
17681768
{
17691769
if ( !context.painter() )
17701770
{
@@ -1821,14 +1821,13 @@ void QgsTextRenderer::drawPart( const QRectF &rect, double rotation, HAlignment
18211821
drawTextInternal( part, context, format, component,
18221822
textLines,
18231823
&fm,
1824-
alignment,
1825-
drawAsOutlines );
1824+
alignment );
18261825
break;
18271826
}
18281827
}
18291828
}
18301829

1831-
void QgsTextRenderer::drawPart( QPointF origin, double rotation, QgsTextRenderer::HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, QgsTextRenderer::TextPart part, bool drawAsOutlines )
1830+
void QgsTextRenderer::drawPart( QPointF origin, double rotation, QgsTextRenderer::HAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, QgsTextRenderer::TextPart part, bool )
18321831
{
18331832
if ( !context.painter() )
18341833
{
@@ -1866,7 +1865,6 @@ void QgsTextRenderer::drawPart( QPointF origin, double rotation, QgsTextRenderer
18661865
textLines,
18671866
&fm,
18681867
alignment,
1869-
drawAsOutlines,
18701868
Point );
18711869
break;
18721870
}
@@ -2511,9 +2509,7 @@ void QgsTextRenderer::drawTextInternal( TextPart drawType,
25112509
const Component &component,
25122510
const QStringList &textLines,
25132511
const QFontMetricsF *fontMetrics,
2514-
HAlignment alignment,
2515-
bool drawAsOutlines
2516-
, DrawMode mode )
2512+
HAlignment alignment, DrawMode mode )
25172513
{
25182514
if ( !context.painter() )
25192515
{
@@ -2665,21 +2661,25 @@ void QgsTextRenderer::drawTextInternal( TextPart drawType,
26652661
// scale for any print output or image saving @ specific dpi
26662662
context.painter()->scale( subComponent.dpiRatio, subComponent.dpiRatio );
26672663

2668-
if ( drawAsOutlines )
2664+
switch ( context.textRenderFormat() )
26692665
{
2670-
// draw outlined text
2671-
_fixQPictureDPI( context.painter() );
2672-
context.painter()->drawPicture( 0, 0, textPict );
2673-
}
2674-
else
2675-
{
2676-
// draw text as text (for SVG and PDF exports)
2677-
context.painter()->setFont( format.scaledFont( context ) );
2678-
QColor textColor = format.color();
2679-
textColor.setAlphaF( format.opacity() );
2680-
context.painter()->setPen( textColor );
2681-
context.painter()->setRenderHint( QPainter::TextAntialiasing );
2682-
context.painter()->drawText( 0, 0, subComponent.text );
2666+
case QgsRenderContext::TextFormatAlwaysOutlines:
2667+
{
2668+
// draw outlined text
2669+
_fixQPictureDPI( context.painter() );
2670+
context.painter()->drawPicture( 0, 0, textPict );
2671+
break;
2672+
}
2673+
2674+
case QgsRenderContext::TextFormatAlwaysText:
2675+
{
2676+
context.painter()->setFont( format.scaledFont( context ) );
2677+
QColor textColor = format.color();
2678+
textColor.setAlphaF( format.opacity() );
2679+
context.painter()->setPen( textColor );
2680+
context.painter()->setRenderHint( QPainter::TextAntialiasing );
2681+
context.painter()->drawText( 0, 0, subComponent.text );
2682+
}
26832683
}
26842684
}
26852685
context.painter()->restore();

0 commit comments

Comments
 (0)