[feature] Add "stretch" setting for labels and text formats

Allows text to be horizontally stretched or condensed by a %
factor. Handy for tweaking the widths of fonts to fit a bit
of extra text into labels (when used sparingly, that is...
you can certainly abuse font stretching with some horrendous
results!)

Requires Qt 6.3+ or KDE's 5.15 fork

Thanks for KDAB for fixing the upstream issues blocking this!
This commit is contained in:
Nyall Dawson 2021-11-05 12:27:59 +10:00
parent 044347d0d1
commit 730cd7e23a
13 changed files with 399 additions and 217 deletions

View File

@ -427,6 +427,7 @@ if(WITH_CORE)
set(QT_VERSION_BASE "Qt5")
set(HAS_KDE_QT5_PDF_TRANSFORM_FIX FALSE CACHE BOOL "Using KDE's Qt 5.15 fork with the PDF brush transform fix")
set(HAS_KDE_QT5_SMALL_CAPS_FIX FALSE CACHE BOOL "Using KDE's Qt 5.15 fork with the QFont::SmallCaps fix")
set(HAS_KDE_QT5_FONT_STRETCH_FIX FALSE CACHE BOOL "Using KDE's Qt 5.15 fork with the QFont stretch fix")
endif()
# Use Qt5SerialPort optionally for GPS

View File

@ -106,6 +106,7 @@
#cmakedefine HAS_KDE_QT5_PDF_TRANSFORM_FIX
#cmakedefine HAS_KDE_QT5_SMALL_CAPS_FIX
#cmakedefine HAS_KDE_QT5_FONT_STRETCH_FIX
#endif

View File

@ -135,6 +135,7 @@ Contains settings for how a map layer will be labeled.
FontLetterSpacing,
FontWordSpacing,
FontBlendMode,
FontStretchFactor,
// text formatting
MultiLineWrapChar,

View File

@ -346,6 +346,36 @@ Sets the text's opacity.
opaque)
.. seealso:: :py:func:`opacity`
%End
int stretchFactor() const;
%Docstring
Returns the text's stretch factor.
The stretch factor matches a condensed or expanded version of the font or applies a stretch
transform that changes the width of all characters in the font by factor percent.
For example, a factor of 150 results in all characters in the font being 1.5 times
(ie. 150%) wider. The minimum stretch factor is 1, and the maximum stretch factor is 4000.
.. seealso:: :py:func:`setStretchFactor`
.. versionadded:: 3.24
%End
void setStretchFactor( int factor );
%Docstring
Sets the text's stretch ``factor``.
The stretch factor matches a condensed or expanded version of the font or applies a stretch
transform that changes the width of all characters in the font by factor percent.
For example, setting ``factor`` to 150 results in all characters in the font being 1.5 times
(ie. 150%) wider. The minimum stretch factor is 1, and the maximum stretch factor is 4000.
.. seealso:: :py:func:`stretchFactor`
.. versionadded:: 3.24
%End
QPainter::CompositionMode blendMode() const;

View File

@ -135,6 +135,7 @@ void QgsPalLayerSettings::initPropertyDefinitions()
{ QgsPalLayerSettings::FontSizeUnit, QgsPropertyDefinition( "FontSizeUnit", QObject::tr( "Font size units" ), QgsPropertyDefinition::RenderUnits, origin ) },
{ QgsPalLayerSettings::FontTransp, QgsPropertyDefinition( "FontTransp", QObject::tr( "Text transparency" ), QgsPropertyDefinition::Opacity, origin ) },
{ QgsPalLayerSettings::FontOpacity, QgsPropertyDefinition( "FontOpacity", QObject::tr( "Text opacity" ), QgsPropertyDefinition::Opacity, origin ) },
{ QgsPalLayerSettings::FontStretchFactor, QgsPropertyDefinition( "FontStretchFactor", QObject::tr( "Font stretch factor" ), QgsPropertyDefinition::IntegerPositiveGreaterZero, origin ) },
{ QgsPalLayerSettings::FontCase, QgsPropertyDefinition( "FontCase", QgsPropertyDefinition::DataTypeString, QObject::tr( "Font case" ), QObject::tr( "string " ) + QStringLiteral( "[<b>NoChange</b>|<b>Upper</b>|<br><b>Lower</b>|<b>Title</b>|<b>Capitalize</b>|<b>SmallCaps</b>|<b>AllSmallCaps</b>]" ), origin ) },
{ QgsPalLayerSettings::FontLetterSpacing, QgsPropertyDefinition( "FontLetterSpacing", QObject::tr( "Letter spacing" ), QgsPropertyDefinition::Double, origin ) },
{ QgsPalLayerSettings::FontWordSpacing, QgsPropertyDefinition( "FontWordSpacing", QObject::tr( "Word spacing" ), QgsPropertyDefinition::Double, origin ) },
@ -3142,6 +3143,13 @@ void QgsPalLayerSettings::parseTextStyle( QFont &labelFont,
labelFont.setStrikeOut( strikeout );
}
// data defined stretch
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::FontStretchFactor ) )
{
context.expressionContext().setOriginalValueVariable( mFormat.stretchFactor() );
labelFont.setStretch( mDataDefinedProperties.valueAsInt( QgsPalLayerSettings::FontStretchFactor, context.expressionContext(), mFormat.stretchFactor() ) );
}
// data defined underline font style?
if ( mDataDefinedProperties.isActive( QgsPalLayerSettings::Underline ) )
{

View File

@ -238,6 +238,7 @@ class CORE_EXPORT QgsPalLayerSettings
FontLetterSpacing = 28, //!< Letter spacing
FontWordSpacing = 29, //!< Word spacing
FontBlendMode = 30, //!< Text blend mode
FontStretchFactor = 113, //!< Font stretch factor, since QGIS 3.24
// text formatting
MultiLineWrapChar = 31,

View File

@ -290,6 +290,17 @@ void QgsTextFormat::setOpacity( double opacity )
d->opacity = opacity;
}
int QgsTextFormat::stretchFactor() const
{
return d->textFont.stretch();
}
void QgsTextFormat::setStretchFactor( int factor )
{
d->isValid = true;
d->textFont.setStretch( factor );
}
QPainter::CompositionMode QgsTextFormat::blendMode() const
{
return d->blendMode;
@ -551,6 +562,7 @@ void QgsTextFormat::readXml( const QDomElement &elem, const QgsReadWriteContext
{
d->opacity = ( textStyleElem.attribute( QStringLiteral( "textOpacity" ) ).toDouble() );
}
d->textFont.setStretch( textStyleElem.attribute( QStringLiteral( "stretchFactor" ), QStringLiteral( "100" ) ).toInt() );
d->orientation = QgsTextRendererUtils::decodeTextOrientation( textStyleElem.attribute( QStringLiteral( "textOrientation" ) ) );
d->previewBackgroundColor = QgsSymbolLayerUtils::decodeColor( textStyleElem.attribute( QStringLiteral( "previewBkgrdColor" ), QgsSymbolLayerUtils::encodeColor( Qt::white ) ) );
@ -655,6 +667,7 @@ QDomElement QgsTextFormat::writeXml( QDomDocument &doc, const QgsReadWriteContex
textStyleElem.setAttribute( QStringLiteral( "fontWordSpacing" ), d->textFont.wordSpacing() );
textStyleElem.setAttribute( QStringLiteral( "fontKerning" ), d->textFont.kerning() );
textStyleElem.setAttribute( QStringLiteral( "textOpacity" ), d->opacity );
textStyleElem.setAttribute( QStringLiteral( "stretchFactor" ), d->textFont.stretch() );
textStyleElem.setAttribute( QStringLiteral( "textOrientation" ), QgsTextRendererUtils::encodeTextOrientation( d->orientation ) );
textStyleElem.setAttribute( QStringLiteral( "blendMode" ), QgsPainting::getBlendModeEnum( d->blendMode ) );
textStyleElem.setAttribute( QStringLiteral( "multilineHeight" ), d->multilineHeight );
@ -964,6 +977,16 @@ void QgsTextFormat::updateDataDefinedProperties( QgsRenderContext &context )
}
}
if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::FontStretchFactor ) )
{
context.expressionContext().setOriginalValueVariable( d->textFont.stretch() );
const QVariant val = d->mDataDefinedProperties.value( QgsPalLayerSettings::FontStretchFactor, context.expressionContext(), d->textFont.stretch() );
if ( !val.isNull() )
{
d->textFont.setStretch( val.toInt() );
}
}
if ( d->mDataDefinedProperties.isActive( QgsPalLayerSettings::TextOrientation ) )
{
const QString encoded = QgsTextRendererUtils::encodeTextOrientation( d->orientation );

View File

@ -324,6 +324,34 @@ class CORE_EXPORT QgsTextFormat
*/
void setOpacity( double opacity );
/**
* Returns the text's stretch factor.
*
* The stretch factor matches a condensed or expanded version of the font or applies a stretch
* transform that changes the width of all characters in the font by factor percent.
*
* For example, a factor of 150 results in all characters in the font being 1.5 times
* (ie. 150%) wider. The minimum stretch factor is 1, and the maximum stretch factor is 4000.
*
* \see setStretchFactor()
* \since QGIS 3.24
*/
int stretchFactor() const;
/**
* Sets the text's stretch \a factor.
*
* The stretch factor matches a condensed or expanded version of the font or applies a stretch
* transform that changes the width of all characters in the font by factor percent.
*
* For example, setting \a factor to 150 results in all characters in the font being 1.5 times
* (ie. 150%) wider. The minimum stretch factor is 1, and the maximum stretch factor is 4000.
*
* \see stretchFactor()
* \since QGIS 3.24
*/
void setStretchFactor( int factor );
/**
* Returns the blending mode used for drawing the text.
* \see setBlendMode()

View File

@ -329,6 +329,12 @@ void QgsTextFormatWidget::initWidget()
connect( mBackgroundEffectWidget, &QgsEffectStackCompactWidget::changed, this, &QgsTextFormatWidget::updatePreview );
mBackgroundEffectWidget->setPaintEffect( mBackgroundEffect.get() );
#ifndef HAS_KDE_QT5_FONT_STRETCH_FIX
mLabelStretch->hide();
mSpinStretch->hide();
mFontStretchDDBtn->hide();
#endif
setDockMode( false );
QList<QWidget *> widgets;
@ -366,6 +372,7 @@ void QgsTextFormatWidget::initWidget()
<< mFontStyleComboBox
<< mTextOrientationComboBox
<< mTextOpacityWidget
<< mSpinStretch
<< mFontWordSpacingSpinBox
<< mFormatNumChkBx
<< mFormatNumDecimalsSpnBx
@ -582,6 +589,10 @@ void QgsTextFormatWidget::toggleDDButtons( bool visible )
const auto buttons = findChildren< QgsPropertyOverrideButton * >();
for ( QgsPropertyOverrideButton *button : buttons )
{
#ifndef HAS_KDE_QT5_FONT_STRETCH_FIX
if ( button == mFontStretchDDBtn )
continue; // always hidden
#endif
button->setVisible( visible );
}
}
@ -693,6 +704,7 @@ void QgsTextFormatWidget::populateDataDefinedButtons()
registerDataDefinedButton( mFontLetterSpacingDDBtn, QgsPalLayerSettings::FontLetterSpacing );
registerDataDefinedButton( mFontWordSpacingDDBtn, QgsPalLayerSettings::FontWordSpacing );
registerDataDefinedButton( mFontBlendModeDDBtn, QgsPalLayerSettings::FontBlendMode );
registerDataDefinedButton( mFontStretchDDBtn, QgsPalLayerSettings::FontStretchFactor );
// text formatting
registerDataDefinedButton( mWrapCharDDBtn, QgsPalLayerSettings::MultiLineWrapChar );
@ -887,6 +899,7 @@ void QgsTextFormatWidget::updateWidgetForFormat( const QgsTextFormat &format )
mRefFont = format.font();
mFontSizeSpinBox->setValue( format.size() );
btnTextColor->setColor( format.color() );
whileBlocking( mSpinStretch )->setValue( format.stretchFactor() );
mTextOpacityWidget->setOpacity( format.opacity() );
comboBlendMode->setBlendMode( format.blendMode() );
mTextOrientationComboBox->setCurrentIndex( mTextOrientationComboBox->findData( format.orientation() ) );
@ -1025,6 +1038,7 @@ QgsTextFormat QgsTextFormatWidget::format( bool includeDataDefinedProperties ) c
format.setSize( mFontSizeSpinBox->value() );
format.setNamedStyle( mFontStyleComboBox->currentText() );
format.setOpacity( mTextOpacityWidget->opacity() );
format.setStretchFactor( mSpinStretch->value() );
format.setBlendMode( comboBlendMode->blendMode() );
format.setSizeUnit( mFontSizeUnitWidget->unit() );
format.setSizeMapUnitScale( mFontSizeUnitWidget->getMapUnitScale() );

View File

@ -109,7 +109,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<width>499</width>
<height>300</height>
</rect>
</property>
@ -654,8 +654,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>455</width>
<height>414</height>
<width>485</width>
<height>429</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
@ -1217,8 +1217,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>427</width>
<height>931</height>
<width>471</width>
<height>742</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_42">
@ -1228,23 +1228,150 @@ font-style: italic;</string>
<property name="rightMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="mFontCapitalsLabel">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mFontCapitalsComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Type case</string>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Capitalization style of text</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QComboBox" name="mTextOrientationComboBox"/>
<item row="2" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_30">
<item>
<widget class="QLabel" name="mFontWordSpacingLabel_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>word</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mFontWordSpacingSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Space in pixels or map units, relative to size unit choice</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="3">
<item row="5" column="0">
<widget class="QLabel" name="labelTextOrientation">
<property name="text">
<string>Text orientation</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_29">
<item>
<widget class="QLabel" name="mFontLetterSpacingLabel_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>letter</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mFontLetterSpacingSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Space in pixels or map units, relative to size unit choice</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Spacing</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="labelBlendMode">
<property name="text">
<string>Blend mode</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<widget class="QCheckBox" name="mCheckBoxSubstituteText">
<property name="toolTip">
<string>If enabled, the label text will automatically be modified using a preset list of substitutes</string>
</property>
<property name="text">
<string>Apply label text substitutes</string>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QToolButton" name="mToolButtonConfigureSubstitutes">
<property name="enabled">
<bool>false</bool>
@ -1257,7 +1384,31 @@ font-style: italic;</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<item row="2" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontWordSpacingDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QComboBox" name="mTextOrientationComboBox"/>
</item>
<item row="0" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontCaseDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontLetterSpacingDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="4">
<widget class="QFrame" name="mDirectSymbolsFrame">
<layout class="QGridLayout" name="gridLayout_33">
<property name="leftMargin">
@ -1557,107 +1708,33 @@ font-style: italic;</string>
</layout>
</widget>
</item>
<item row="0" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontCaseDDBtn">
<item row="0" column="0">
<widget class="QLabel" name="mFontCapitalsLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>…</string>
<string>Type case</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelTextOrientation">
<property name="text">
<string>Text orientation</string>
<item row="11" column="3">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_29">
<item>
<widget class="QLabel" name="mFontLetterSpacingLabel_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>letter</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mFontLetterSpacingSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Space in pixels or map units, relative to size unit choice</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="3">
<widget class="QgsPropertyOverrideButton" name="mTextOrientationDDBtn">
<property name="text">
<string>…</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labelBlendMode">
<property name="text">
<string>Blend mode</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="3">
<widget class="QCheckBox" name="mCheckBoxSubstituteText">
<property name="toolTip">
<string>If enabled, the label text will automatically be modified using a preset list of substitutes</string>
</property>
<property name="text">
<string>Apply label text substitutes</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontWordSpacingDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontLetterSpacingDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QgsBlendModeComboBox" name="comboBlendMode"/>
</item>
<item row="9" column="0" colspan="4">
<item row="10" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout_34">
<property name="verticalSpacing">
<number>6</number>
@ -1765,74 +1842,21 @@ font-style: italic;</string>
</item>
</layout>
</item>
<item row="2" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_30">
<item>
<widget class="QLabel" name="mFontWordSpacingLabel_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>word</string>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="mFontWordSpacingSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Space in pixels or map units, relative to size unit choice</string>
</property>
<property name="decimals">
<number>4</number>
</property>
<property name="minimum">
<double>-1000.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mFontCapitalsComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Capitalization style of text</string>
<item row="6" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontBlendModeDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="4">
<item row="5" column="3">
<widget class="QgsPropertyOverrideButton" name="mTextOrientationDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout_35">
<property name="verticalSpacing">
<number>6</number>
@ -2034,40 +2058,46 @@ font-style: italic;</string>
</item>
</layout>
</item>
<item row="10" column="3">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Spacing</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontBlendModeDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<item row="4" column="0" colspan="3">
<widget class="QCheckBox" name="mKerningCheckBox">
<property name="text">
<string>Enable kerning</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QgsBlendModeComboBox" name="comboBlendMode"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mLabelStretch">
<property name="text">
<string>Stretch</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QgsSpinBox" name="mSpinStretch">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QgsPropertyOverrideButton" name="mFontStretchDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@ -2101,8 +2131,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>338</width>
<height>401</height>
<width>299</width>
<height>308</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
@ -2447,8 +2477,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>338</width>
<height>351</height>
<width>296</width>
<height>291</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_121">
@ -2725,8 +2755,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>513</width>
<height>1053</height>
<width>438</width>
<height>753</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
@ -3476,8 +3506,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>592</height>
<width>324</width>
<height>457</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
@ -3904,8 +3934,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>181</width>
<height>227</height>
<width>159</width>
<height>211</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_46">
@ -4054,8 +4084,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<height>2074</height>
<width>472</width>
<height>1690</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
@ -5757,8 +5787,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>461</width>
<height>858</height>
<width>430</width>
<height>708</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
@ -6700,6 +6730,8 @@ font-style: italic;</string>
<tabstop>mFontLetterSpacingDDBtn</tabstop>
<tabstop>mFontWordSpacingSpinBox</tabstop>
<tabstop>mFontWordSpacingDDBtn</tabstop>
<tabstop>mSpinStretch</tabstop>
<tabstop>mFontStretchDDBtn</tabstop>
<tabstop>mKerningCheckBox</tabstop>
<tabstop>mTextOrientationComboBox</tabstop>
<tabstop>mTextOrientationDDBtn</tabstop>
@ -6926,6 +6958,7 @@ font-style: italic;</string>
<tabstop>mLimitLabelSpinBox</tabstop>
<tabstop>mMinSizeSpinBox</tabstop>
<tabstop>mFitInsidePolygonCheckBox</tabstop>
<tabstop>mCoordRotationUnitComboBox</tabstop>
</tabstops>
<resources>
<include location="../../images/images.qrc"/>

View File

@ -162,6 +162,10 @@ class PyQgsTextRenderer(unittest.TestCase):
t.setFamilies(['Arial', 'Comic Sans'])
self.assertTrue(t.isValid())
t = QgsTextFormat()
t.setStretchFactor(110)
self.assertTrue(t.isValid())
t = QgsTextFormat()
t.dataDefinedProperties().setProperty(QgsPalLayerSettings.Bold, QgsProperty.fromValue(True))
self.assertTrue(t.isValid())
@ -707,6 +711,9 @@ class PyQgsTextRenderer(unittest.TestCase):
s.setPreviewBackgroundColor(QColor(100, 150, 200))
s.setOrientation(QgsTextFormat.VerticalOrientation)
s.setAllowHtmlFormatting(True)
s.setStretchFactor(110)
s.dataDefinedProperties().setProperty(QgsPalLayerSettings.Bold, QgsProperty.fromExpression('1>2'))
return s
@ -808,6 +815,10 @@ class PyQgsTextRenderer(unittest.TestCase):
s.setFamilies(['Times New Roman'])
self.assertNotEqual(s, s2)
s = self.createFormatSettings()
s.setStretchFactor(120)
self.assertNotEqual(s, s2)
def checkTextFormat(self, s):
""" test QgsTextFormat """
self.assertTrue(s.buffer().enabled())
@ -835,6 +846,10 @@ class PyQgsTextRenderer(unittest.TestCase):
self.assertTrue(s.allowHtmlFormatting())
self.assertEqual(s.dataDefinedProperties().property(QgsPalLayerSettings.Bold).expressionString(), '1>2')
if int(QT_VERSION_STR.split('.')[0]) > 6 or (
int(QT_VERSION_STR.split('.')[0]) == 6 and int(QT_VERSION_STR.split('.')[1]) >= 3):
self.assertEqual(s.stretchFactor(), 110)
def testFormatGettersSetters(self):
s = self.createFormatSettings()
self.checkTextFormat(s)
@ -1295,6 +1310,13 @@ class PyQgsTextRenderer(unittest.TestCase):
f.updateDataDefinedProperties(context)
self.assertEqual(f.blendMode(), QPainter.CompositionMode_ColorBurn)
if int(QT_VERSION_STR.split('.')[0]) > 6 or (
int(QT_VERSION_STR.split('.')[0]) == 6 and int(QT_VERSION_STR.split('.')[1]) >= 3):
# stretch
f.dataDefinedProperties().setProperty(QgsPalLayerSettings.FontStretchFactor, QgsProperty.fromExpression("135"))
f.updateDataDefinedProperties(context)
self.assertEqual(f.stretchFactor(), 135)
def testFontFoundFromLayer(self):
layer = createEmptyLayer()
layer.setCustomProperty('labeling/fontFamily', 'asdasd')
@ -1367,6 +1389,12 @@ class PyQgsTextRenderer(unittest.TestCase):
qfont = s.toQFont()
self.assertAlmostEqual(qfont.pointSizeF(), 360.0, 2)
if int(QT_VERSION_STR.split('.')[0]) > 6 or (
int(QT_VERSION_STR.split('.')[0]) == 6 and int(QT_VERSION_STR.split('.')[1]) >= 3):
s.setStretchFactor(115)
qfont = s.toQFont()
self.assertEqual(qfont.stretch(), 115)
def testFontMetrics(self):
"""
Test calculating font metrics from scaled text formats
@ -1514,7 +1542,6 @@ class PyQgsTextRenderer(unittest.TestCase):
format.setCapitalization(Qgis.Capitalization.SmallCaps)
format.setSize(30)
assert self.checkRender(format, 'mixed_small_caps', text=['Small Caps'])
assert False
@unittest.skipIf(int(QT_VERSION_STR.split('.')[0]) < 6 or (int(QT_VERSION_STR.split('.')[0]) == 6 and int(QT_VERSION_STR.split('.')[1]) < 3), 'Too old Qt')
def testDrawAllSmallCaps(self):
@ -1523,7 +1550,22 @@ class PyQgsTextRenderer(unittest.TestCase):
format.setSize(30)
format.setCapitalization(Qgis.Capitalization.AllSmallCaps)
assert self.checkRender(format, 'all_small_caps', text=['Small Caps'])
assert False
@unittest.skipIf(int(QT_VERSION_STR.split('.')[0]) < 6 or (int(QT_VERSION_STR.split('.')[0]) == 6 and int(QT_VERSION_STR.split('.')[1]) < 3), 'Too old Qt')
def testDrawStretch(self):
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
format.setSize(30)
format.setStretchFactor(150)
assert self.checkRender(format, 'stretch_expand')
@unittest.skipIf(int(QT_VERSION_STR.split('.')[0]) < 6 or (int(QT_VERSION_STR.split('.')[0]) == 6 and int(QT_VERSION_STR.split('.')[1]) < 3), 'Too old Qt')
def testDrawStretchCondense(self):
format = QgsTextFormat()
format.setFont(getTestFont('bold'))
format.setSize(30)
format.setStretchFactor(50)
assert self.checkRender(format, 'stretch_condense')
def testDrawBackgroundDisabled(self):
format = QgsTextFormat()

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB