Skip to content

Commit c1d80ed

Browse files
committed
Initial fix for #3975, label engine vectorizing texts in SVG and PDF output
- Add labeling engine option to render text-as-text - Default is still text-as-outlines (vectorized), due to differences between text (as text) and buffer (as outline) methods - Good output with printing to PDF (searchable, selectable text and embedded fonts) - OK output with SVG, but differences between text (as text) and buffer (as outline) methods Does not yet include unit tests or auto-setting of text-as-text for SVG output
1 parent 469be12 commit c1d80ed

5 files changed

+79
-45
lines changed

python/core/qgspallabeling.sip

+4
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,10 @@ class QgsPalLabeling : QgsLabelingEngineInterface
666666
bool isShowingPartialsLabels() const;
667667
void setShowingPartialsLabels( bool showing );
668668

669+
//! @note added in 2.4
670+
bool isDrawingOutlineLabels() const;
671+
void setDrawingOutlineLabels( bool outline );
672+
669673
// implemented methods from labeling engine interface
670674

671675
//! called when we're going to start with rendering

src/app/qgslabelengineconfigdialog.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ QgsLabelEngineConfigDialog::QgsLabelEngineConfigDialog( QWidget* parent )
4646
mShadowDebugRectChkBox->setChecked( lbl.isShowingShadowRectangles() );
4747

4848
chkShowPartialsLabels->setChecked( lbl.isShowingPartialsLabels() );
49+
mDrawOutlinesChkBox->setChecked( lbl.isDrawingOutlineLabels() );
4950
}
5051

5152

@@ -64,6 +65,7 @@ void QgsLabelEngineConfigDialog::onOK()
6465
lbl.setShowingShadowRectangles( mShadowDebugRectChkBox->isChecked() );
6566
lbl.setShowingAllLabels( chkShowAllLabels->isChecked() );
6667
lbl.setShowingPartialsLabels( chkShowPartialsLabels->isChecked() );
68+
lbl.setDrawingOutlineLabels( mDrawOutlinesChkBox->isChecked() );
6769

6870
lbl.saveEngineSettings();
6971

@@ -81,4 +83,5 @@ void QgsLabelEngineConfigDialog::setDefaults()
8183
chkShowAllLabels->setChecked( false );
8284
mShadowDebugRectChkBox->setChecked( false );
8385
chkShowPartialsLabels->setChecked( p.getShowPartial() );
86+
mDrawOutlinesChkBox->setChecked( true );
8487
}

src/core/qgspallabeling.cpp

+25-10
Original file line numberDiff line numberDiff line change
@@ -3211,6 +3211,7 @@ QgsPalLabeling::QgsPalLabeling()
32113211
mShowingShadowRects = false;
32123212
mShowingAllLabels = false;
32133213
mShowingPartialsLabels = p.getShowPartial();
3214+
mDrawOutlineLabels = true;
32143215
}
32153216

32163217
QgsPalLabeling::~QgsPalLabeling()
@@ -4443,6 +4444,11 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
44434444
textp.setPen( Qt::NoPen );
44444445
textp.setBrush( tmpLyr.textColor );
44454446
textp.drawPath( path );
4447+
// TODO: why are some font settings lost on drawPicture() when using drawText() inside QPicture?
4448+
// e.g. some capitalization options, but not others
4449+
//textp.setFont( tmpLyr.textFont );
4450+
//textp.setPen( tmpLyr.textColor );
4451+
//textp.drawText( 0, 0, component.text() );
44464452
textp.end();
44474453

44484454
if ( tmpLyr.shadowDraw && tmpLyr.shadowUnder == QgsPalLayerSettings::ShadowText )
@@ -4459,20 +4465,24 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
44594465
{
44604466
painter->setCompositionMode( tmpLyr.blendMode );
44614467
}
4462-
// painter->setPen( Qt::NoPen );
4463-
// painter->setBrush( tmpLyr.textColor );
4464-
// painter->drawPath( path );
44654468

44664469
// scale for any print output or image saving @ specific dpi
44674470
painter->scale( component.dpiRatio(), component.dpiRatio() );
4468-
_fixQPictureDPI( painter );
4469-
painter->drawPicture( 0, 0, textPict );
4470-
4471-
// regular text draw, for testing optimization
4472-
// painter->setFont( tmpLyr.textFont );
4473-
// painter->setPen( tmpLyr.textColor );
4474-
// painter->drawText( 0, 0, multiLineList.at( i ) );
44754471

4472+
if ( mDrawOutlineLabels )
4473+
{
4474+
// draw outlined text
4475+
_fixQPictureDPI( painter );
4476+
painter->drawPicture( 0, 0, textPict );
4477+
}
4478+
else
4479+
{
4480+
// draw text as text (for SVG and PDF exports)
4481+
painter->setFont( tmpLyr.textFont );
4482+
painter->setPen( tmpLyr.textColor );
4483+
painter->setRenderHint( QPainter::TextAntialiasing );
4484+
painter->drawText( 0, 0, component.text() );
4485+
}
44764486
}
44774487
painter->restore();
44784488
}
@@ -5004,6 +5014,8 @@ void QgsPalLabeling::loadEngineSettings()
50045014
"PAL", "/ShowingAllLabels", false, &saved );
50055015
mShowingPartialsLabels = QgsProject::instance()->readBoolEntry(
50065016
"PAL", "/ShowingPartialsLabels", p.getShowPartial(), &saved );
5017+
mDrawOutlineLabels = QgsProject::instance()->readBoolEntry(
5018+
"PAL", "/DrawOutlineLabels", true, &saved );
50075019
}
50085020

50095021
void QgsPalLabeling::saveEngineSettings()
@@ -5016,6 +5028,7 @@ void QgsPalLabeling::saveEngineSettings()
50165028
QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", mShowingShadowRects );
50175029
QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", mShowingAllLabels );
50185030
QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", mShowingPartialsLabels );
5031+
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", mDrawOutlineLabels );
50195032
}
50205033

50215034
void QgsPalLabeling::clearEngineSettings()
@@ -5028,6 +5041,7 @@ void QgsPalLabeling::clearEngineSettings()
50285041
QgsProject::instance()->removeEntry( "PAL", "/ShowingShadowRects" );
50295042
QgsProject::instance()->removeEntry( "PAL", "/ShowingAllLabels" );
50305043
QgsProject::instance()->removeEntry( "PAL", "/ShowingPartialsLabels" );
5044+
QgsProject::instance()->removeEntry( "PAL", "/DrawOutlineLabels" );
50315045
}
50325046

50335047
QgsLabelingEngineInterface* QgsPalLabeling::clone()
@@ -5037,6 +5051,7 @@ QgsLabelingEngineInterface* QgsPalLabeling::clone()
50375051
lbl->mShowingCandidates = mShowingCandidates;
50385052
lbl->mShowingShadowRects = mShowingShadowRects;
50395053
lbl->mShowingPartialsLabels = mShowingPartialsLabels;
5054+
lbl->mDrawOutlineLabels = mDrawOutlineLabels;
50405055
return lbl;
50415056
}
50425057

src/core/qgspallabeling.h

+5
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,10 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
740740
bool isShowingPartialsLabels() const { return mShowingPartialsLabels; }
741741
void setShowingPartialsLabels( bool showing ) { mShowingPartialsLabels = showing; }
742742

743+
//! @note added in 2.4
744+
bool isDrawingOutlineLabels() const { return mDrawOutlineLabels; }
745+
void setDrawingOutlineLabels( bool outline ) { mDrawOutlineLabels = outline; }
746+
743747
// implemented methods from labeling engine interface
744748

745749
//! called when we're going to start with rendering
@@ -856,6 +860,7 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
856860
bool mShowingAllLabels; // whether to avoid collisions or not
857861
bool mShowingShadowRects; // whether to show debugging rectangles for drop shadows
858862
bool mShowingPartialsLabels; // whether to avoid partials labels or not
863+
bool mDrawOutlineLabels; // whether to draw labels as text or outlines
859864

860865
QgsLabelingResults* mResults;
861866
};

src/ui/qgsengineconfigdialog.ui

+42-35
Original file line numberDiff line numberDiff line change
@@ -215,43 +215,41 @@
215215
<property name="verticalSpacing">
216216
<number>6</number>
217217
</property>
218-
<item row="2" column="0">
219-
<spacer name="horizontalSpacer_3">
218+
<item row="1" column="0" colspan="3">
219+
<widget class="QCheckBox" name="chkShowPartialsLabels">
220+
<property name="text">
221+
<string>Show partials labels</string>
222+
</property>
223+
</widget>
224+
</item>
225+
<item row="5" column="0" colspan="3">
226+
<widget class="QCheckBox" name="mShadowDebugRectChkBox">
227+
<property name="text">
228+
<string>Show shadow rectangles (for debugging)</string>
229+
</property>
230+
</widget>
231+
</item>
232+
<item row="3" column="2">
233+
<spacer name="horizontalSpacer_4">
220234
<property name="orientation">
221235
<enum>Qt::Horizontal</enum>
222236
</property>
223-
<property name="sizeType">
224-
<enum>QSizePolicy::Fixed</enum>
225-
</property>
226237
<property name="sizeHint" stdset="0">
227238
<size>
228-
<width>8</width>
229-
<height>8</height>
239+
<width>0</width>
240+
<height>20</height>
230241
</size>
231242
</property>
232243
</spacer>
233244
</item>
234-
<item row="1" column="0" colspan="3">
235-
<widget class="QCheckBox" name="chkShowAllLabels">
236-
<property name="sizePolicy">
237-
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
238-
<horstretch>0</horstretch>
239-
<verstretch>0</verstretch>
240-
</sizepolicy>
241-
</property>
242-
<property name="text">
243-
<string>Show all labels and features for all layers</string>
244-
</property>
245-
</widget>
246-
</item>
247-
<item row="3" column="0" colspan="3">
245+
<item row="4" column="0" colspan="3">
248246
<widget class="QCheckBox" name="chkShowCandidates">
249247
<property name="text">
250248
<string>Show candidates (for debugging)</string>
251249
</property>
252250
</widget>
253251
</item>
254-
<item row="2" column="1">
252+
<item row="3" column="1">
255253
<widget class="QLabel" name="label_6">
256254
<property name="sizePolicy">
257255
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
@@ -264,30 +262,39 @@
264262
</property>
265263
</widget>
266264
</item>
267-
<item row="2" column="2">
268-
<spacer name="horizontalSpacer_4">
265+
<item row="2" column="0" colspan="3">
266+
<widget class="QCheckBox" name="chkShowAllLabels">
267+
<property name="sizePolicy">
268+
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
269+
<horstretch>0</horstretch>
270+
<verstretch>0</verstretch>
271+
</sizepolicy>
272+
</property>
273+
<property name="text">
274+
<string>Show all labels and features for all layers</string>
275+
</property>
276+
</widget>
277+
</item>
278+
<item row="3" column="0">
279+
<spacer name="horizontalSpacer_3">
269280
<property name="orientation">
270281
<enum>Qt::Horizontal</enum>
271282
</property>
283+
<property name="sizeType">
284+
<enum>QSizePolicy::Fixed</enum>
285+
</property>
272286
<property name="sizeHint" stdset="0">
273287
<size>
274-
<width>0</width>
275-
<height>20</height>
288+
<width>8</width>
289+
<height>8</height>
276290
</size>
277291
</property>
278292
</spacer>
279293
</item>
280-
<item row="4" column="0" colspan="3">
281-
<widget class="QCheckBox" name="mShadowDebugRectChkBox">
282-
<property name="text">
283-
<string>Show shadow rectangles (for debugging)</string>
284-
</property>
285-
</widget>
286-
</item>
287294
<item row="0" column="0" colspan="3">
288-
<widget class="QCheckBox" name="chkShowPartialsLabels">
295+
<widget class="QCheckBox" name="mDrawOutlinesChkBox">
289296
<property name="text">
290-
<string>Show partials labels</string>
297+
<string>Draw text as outlines (recommended)</string>
291298
</property>
292299
</widget>
293300
</item>

0 commit comments

Comments
 (0)