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
This commit is contained in:
Larry Shaffer 2014-06-13 10:13:55 -06:00
parent 469be12e79
commit c1d80ed6a6
5 changed files with 100 additions and 66 deletions

View File

@ -666,6 +666,10 @@ class QgsPalLabeling : QgsLabelingEngineInterface
bool isShowingPartialsLabels() const;
void setShowingPartialsLabels( bool showing );
//! @note added in 2.4
bool isDrawingOutlineLabels() const;
void setDrawingOutlineLabels( bool outline );
// implemented methods from labeling engine interface
//! called when we're going to start with rendering

View File

@ -46,6 +46,7 @@ QgsLabelEngineConfigDialog::QgsLabelEngineConfigDialog( QWidget* parent )
mShadowDebugRectChkBox->setChecked( lbl.isShowingShadowRectangles() );
chkShowPartialsLabels->setChecked( lbl.isShowingPartialsLabels() );
mDrawOutlinesChkBox->setChecked( lbl.isDrawingOutlineLabels() );
}
@ -64,6 +65,7 @@ void QgsLabelEngineConfigDialog::onOK()
lbl.setShowingShadowRectangles( mShadowDebugRectChkBox->isChecked() );
lbl.setShowingAllLabels( chkShowAllLabels->isChecked() );
lbl.setShowingPartialsLabels( chkShowPartialsLabels->isChecked() );
lbl.setDrawingOutlineLabels( mDrawOutlinesChkBox->isChecked() );
lbl.saveEngineSettings();
@ -81,4 +83,5 @@ void QgsLabelEngineConfigDialog::setDefaults()
chkShowAllLabels->setChecked( false );
mShadowDebugRectChkBox->setChecked( false );
chkShowPartialsLabels->setChecked( p.getShowPartial() );
mDrawOutlinesChkBox->setChecked( true );
}

View File

@ -3211,6 +3211,7 @@ QgsPalLabeling::QgsPalLabeling()
mShowingShadowRects = false;
mShowingAllLabels = false;
mShowingPartialsLabels = p.getShowPartial();
mDrawOutlineLabels = true;
}
QgsPalLabeling::~QgsPalLabeling()
@ -4443,6 +4444,11 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
textp.setPen( Qt::NoPen );
textp.setBrush( tmpLyr.textColor );
textp.drawPath( path );
// TODO: why are some font settings lost on drawPicture() when using drawText() inside QPicture?
// e.g. some capitalization options, but not others
//textp.setFont( tmpLyr.textFont );
//textp.setPen( tmpLyr.textColor );
//textp.drawText( 0, 0, component.text() );
textp.end();
if ( tmpLyr.shadowDraw && tmpLyr.shadowUnder == QgsPalLayerSettings::ShadowText )
@ -4459,20 +4465,24 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
{
painter->setCompositionMode( tmpLyr.blendMode );
}
// painter->setPen( Qt::NoPen );
// painter->setBrush( tmpLyr.textColor );
// painter->drawPath( path );
// scale for any print output or image saving @ specific dpi
painter->scale( component.dpiRatio(), component.dpiRatio() );
_fixQPictureDPI( painter );
painter->drawPicture( 0, 0, textPict );
// regular text draw, for testing optimization
// painter->setFont( tmpLyr.textFont );
// painter->setPen( tmpLyr.textColor );
// painter->drawText( 0, 0, multiLineList.at( i ) );
if ( mDrawOutlineLabels )
{
// draw outlined text
_fixQPictureDPI( painter );
painter->drawPicture( 0, 0, textPict );
}
else
{
// draw text as text (for SVG and PDF exports)
painter->setFont( tmpLyr.textFont );
painter->setPen( tmpLyr.textColor );
painter->setRenderHint( QPainter::TextAntialiasing );
painter->drawText( 0, 0, component.text() );
}
}
painter->restore();
}
@ -5004,6 +5014,8 @@ void QgsPalLabeling::loadEngineSettings()
"PAL", "/ShowingAllLabels", false, &saved );
mShowingPartialsLabels = QgsProject::instance()->readBoolEntry(
"PAL", "/ShowingPartialsLabels", p.getShowPartial(), &saved );
mDrawOutlineLabels = QgsProject::instance()->readBoolEntry(
"PAL", "/DrawOutlineLabels", true, &saved );
}
void QgsPalLabeling::saveEngineSettings()
@ -5016,6 +5028,7 @@ void QgsPalLabeling::saveEngineSettings()
QgsProject::instance()->writeEntry( "PAL", "/ShowingShadowRects", mShowingShadowRects );
QgsProject::instance()->writeEntry( "PAL", "/ShowingAllLabels", mShowingAllLabels );
QgsProject::instance()->writeEntry( "PAL", "/ShowingPartialsLabels", mShowingPartialsLabels );
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", mDrawOutlineLabels );
}
void QgsPalLabeling::clearEngineSettings()
@ -5028,6 +5041,7 @@ void QgsPalLabeling::clearEngineSettings()
QgsProject::instance()->removeEntry( "PAL", "/ShowingShadowRects" );
QgsProject::instance()->removeEntry( "PAL", "/ShowingAllLabels" );
QgsProject::instance()->removeEntry( "PAL", "/ShowingPartialsLabels" );
QgsProject::instance()->removeEntry( "PAL", "/DrawOutlineLabels" );
}
QgsLabelingEngineInterface* QgsPalLabeling::clone()
@ -5037,6 +5051,7 @@ QgsLabelingEngineInterface* QgsPalLabeling::clone()
lbl->mShowingCandidates = mShowingCandidates;
lbl->mShowingShadowRects = mShowingShadowRects;
lbl->mShowingPartialsLabels = mShowingPartialsLabels;
lbl->mDrawOutlineLabels = mDrawOutlineLabels;
return lbl;
}

View File

@ -740,6 +740,10 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
bool isShowingPartialsLabels() const { return mShowingPartialsLabels; }
void setShowingPartialsLabels( bool showing ) { mShowingPartialsLabels = showing; }
//! @note added in 2.4
bool isDrawingOutlineLabels() const { return mDrawOutlineLabels; }
void setDrawingOutlineLabels( bool outline ) { mDrawOutlineLabels = outline; }
// implemented methods from labeling engine interface
//! called when we're going to start with rendering
@ -856,6 +860,7 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
bool mShowingAllLabels; // whether to avoid collisions or not
bool mShowingShadowRects; // whether to show debugging rectangles for drop shadows
bool mShowingPartialsLabels; // whether to avoid partials labels or not
bool mDrawOutlineLabels; // whether to draw labels as text or outlines
QgsLabelingResults* mResults;
};

View File

@ -215,7 +215,67 @@
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="2" column="0">
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="chkShowPartialsLabels">
<property name="text">
<string>Show partials labels</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="QCheckBox" name="mShadowDebugRectChkBox">
<property name="text">
<string>Show shadow rectangles (for debugging)</string>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="chkShowCandidates">
<property name="text">
<string>Show candidates (for debugging)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>(i.e. including colliding objects)</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QCheckBox" name="chkShowAllLabels">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show all labels and features for all layers</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -231,63 +291,10 @@
</property>
</spacer>
</item>
<item row="1" column="0" colspan="3">
<widget class="QCheckBox" name="chkShowAllLabels">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show all labels and features for all layers</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QCheckBox" name="chkShowCandidates">
<property name="text">
<string>Show candidates (for debugging)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>(i.e. including colliding objects)</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="mShadowDebugRectChkBox">
<property name="text">
<string>Show shadow rectangles (for debugging)</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QCheckBox" name="chkShowPartialsLabels">
<widget class="QCheckBox" name="mDrawOutlinesChkBox">
<property name="text">
<string>Show partials labels</string>
<string>Draw text as outlines (recommended)</string>
</property>
</widget>
</item>