introduce VerticalAnchorMode in FontSymbols to have a proper 'hidden' setting for this mode making a differene between legacy and baseline (and future bounds) on the positioning of the characters

This commit is contained in:
signedav 2025-01-03 09:23:56 +01:00 committed by Nyall Dawson
parent f80df88534
commit 6b5396bd53
8 changed files with 76 additions and 48 deletions

View File

@ -1,4 +1,14 @@
# The following has been generated automatically from src/core/symbology/qgsmarkersymbollayer.h # The following has been generated automatically from src/core/symbology/qgsmarkersymbollayer.h
# monkey patching scoped based enum
QgsFontMarkerSymbolLayer.VerticalAnchorMode.Legacy.__doc__ = "Calculate anchor points with different offsets"
QgsFontMarkerSymbolLayer.VerticalAnchorMode.Baseline.__doc__ = "Calculate anchor points with fix baseline"
QgsFontMarkerSymbolLayer.VerticalAnchorMode.__doc__ = """Vertical anchor modes
* ``Legacy``: Calculate anchor points with different offsets
* ``Baseline``: Calculate anchor points with fix baseline
"""
# --
try: try:
QgsSimpleMarkerSymbolLayerBase.availableShapes = staticmethod(QgsSimpleMarkerSymbolLayerBase.availableShapes) QgsSimpleMarkerSymbolLayerBase.availableShapes = staticmethod(QgsSimpleMarkerSymbolLayerBase.availableShapes)
QgsSimpleMarkerSymbolLayerBase.shapeIsFilled = staticmethod(QgsSimpleMarkerSymbolLayerBase.shapeIsFilled) QgsSimpleMarkerSymbolLayerBase.shapeIsFilled = staticmethod(QgsSimpleMarkerSymbolLayerBase.shapeIsFilled)

View File

@ -931,6 +931,12 @@ class QgsFontMarkerSymbolLayer : QgsMarkerSymbolLayer
%End %End
public: public:
enum class VerticalAnchorMode /BaseType=IntEnum/
{
Legacy,
Baseline,
};
QgsFontMarkerSymbolLayer( const QString &fontFamily = DEFAULT_FONTMARKER_FONT, QgsFontMarkerSymbolLayer( const QString &fontFamily = DEFAULT_FONTMARKER_FONT,
QString chr = DEFAULT_FONTMARKER_CHR, QString chr = DEFAULT_FONTMARKER_CHR,
double pointSize = DEFAULT_FONTMARKER_SIZE, double pointSize = DEFAULT_FONTMARKER_SIZE,
@ -1119,22 +1125,22 @@ Sets the stroke join ``style``.
.. seealso:: :py:func:`penJoinStyle` .. seealso:: :py:func:`penJoinStyle`
%End %End
void setFixVerticalAnchor( const bool fixVerticalAnchor ); void setVerticalAnchorMode( VerticalAnchorMode verticalAnchorMode );
%Docstring %Docstring
Set fixVerticalAnchor that means it considers the baseline position for all the characters Sets the vertical anchor mode whether it should considers the baseline as fix point
:param fixVerticalAnchor: the bool :param verticalAnchorMode: the mode how to handle the anchor point
.. seealso:: :py:func:`fixVerticalAnchor` .. seealso:: :py:func:`verticalAnchorMode`
.. versionadded:: 3.42 .. versionadded:: 3.42
%End %End
bool fixVerticalAnchor() const; VerticalAnchorMode verticalAnchorMode() const;
%Docstring %Docstring
Returns wheter it considers teh baseline position for all the characters Returns whether it should considers the baseline as fix point
.. seealso:: :py:func:`setFixVerticalAnchor` .. seealso:: :py:func:`setVerticalAnchorMode`
.. versionadded:: 3.42 .. versionadded:: 3.42
%End %End

View File

@ -1,4 +1,14 @@
# The following has been generated automatically from src/core/symbology/qgsmarkersymbollayer.h # The following has been generated automatically from src/core/symbology/qgsmarkersymbollayer.h
# monkey patching scoped based enum
QgsFontMarkerSymbolLayer.VerticalAnchorMode.Legacy.__doc__ = "Calculate anchor points with different offsets"
QgsFontMarkerSymbolLayer.VerticalAnchorMode.Baseline.__doc__ = "Calculate anchor points with fix baseline"
QgsFontMarkerSymbolLayer.VerticalAnchorMode.__doc__ = """Vertical anchor modes
* ``Legacy``: Calculate anchor points with different offsets
* ``Baseline``: Calculate anchor points with fix baseline
"""
# --
try: try:
QgsSimpleMarkerSymbolLayerBase.availableShapes = staticmethod(QgsSimpleMarkerSymbolLayerBase.availableShapes) QgsSimpleMarkerSymbolLayerBase.availableShapes = staticmethod(QgsSimpleMarkerSymbolLayerBase.availableShapes)
QgsSimpleMarkerSymbolLayerBase.shapeIsFilled = staticmethod(QgsSimpleMarkerSymbolLayerBase.shapeIsFilled) QgsSimpleMarkerSymbolLayerBase.shapeIsFilled = staticmethod(QgsSimpleMarkerSymbolLayerBase.shapeIsFilled)

View File

@ -931,6 +931,12 @@ class QgsFontMarkerSymbolLayer : QgsMarkerSymbolLayer
%End %End
public: public:
enum class VerticalAnchorMode
{
Legacy,
Baseline,
};
QgsFontMarkerSymbolLayer( const QString &fontFamily = DEFAULT_FONTMARKER_FONT, QgsFontMarkerSymbolLayer( const QString &fontFamily = DEFAULT_FONTMARKER_FONT,
QString chr = DEFAULT_FONTMARKER_CHR, QString chr = DEFAULT_FONTMARKER_CHR,
double pointSize = DEFAULT_FONTMARKER_SIZE, double pointSize = DEFAULT_FONTMARKER_SIZE,
@ -1119,22 +1125,22 @@ Sets the stroke join ``style``.
.. seealso:: :py:func:`penJoinStyle` .. seealso:: :py:func:`penJoinStyle`
%End %End
void setFixVerticalAnchor( const bool fixVerticalAnchor ); void setVerticalAnchorMode( VerticalAnchorMode verticalAnchorMode );
%Docstring %Docstring
Set fixVerticalAnchor that means it considers the baseline position for all the characters Sets the vertical anchor mode whether it should considers the baseline as fix point
:param fixVerticalAnchor: the bool :param verticalAnchorMode: the mode how to handle the anchor point
.. seealso:: :py:func:`fixVerticalAnchor` .. seealso:: :py:func:`verticalAnchorMode`
.. versionadded:: 3.42 .. versionadded:: 3.42
%End %End
bool fixVerticalAnchor() const; VerticalAnchorMode verticalAnchorMode() const;
%Docstring %Docstring
Returns wheter it considers teh baseline position for all the characters Returns whether it should considers the baseline as fix point
.. seealso:: :py:func:`setFixVerticalAnchor` .. seealso:: :py:func:`setVerticalAnchorMode`
.. versionadded:: 3.42 .. versionadded:: 3.42
%End %End

View File

@ -3541,8 +3541,8 @@ QgsSymbolLayer *QgsFontMarkerSymbolLayer::create( const QVariantMap &props )
m->setHorizontalAnchorPoint( QgsMarkerSymbolLayer::HorizontalAnchorPoint( props[ QStringLiteral( "horizontal_anchor_point" )].toInt() ) ); m->setHorizontalAnchorPoint( QgsMarkerSymbolLayer::HorizontalAnchorPoint( props[ QStringLiteral( "horizontal_anchor_point" )].toInt() ) );
if ( props.contains( QStringLiteral( "vertical_anchor_point" ) ) ) if ( props.contains( QStringLiteral( "vertical_anchor_point" ) ) )
m->setVerticalAnchorPoint( QgsMarkerSymbolLayer::VerticalAnchorPoint( props[ QStringLiteral( "vertical_anchor_point" )].toInt() ) ); m->setVerticalAnchorPoint( QgsMarkerSymbolLayer::VerticalAnchorPoint( props[ QStringLiteral( "vertical_anchor_point" )].toInt() ) );
if ( props.contains( QStringLiteral( "fix_vertical_anchor" ) ) ) if ( props.contains( QStringLiteral( "vertical_anchor_mode" ) ) )
m->setFixVerticalAnchor( props[ QStringLiteral( "fix_vertical_anchor" )].toBool() ); m->setVerticalAnchorMode( VerticalAnchorMode( props[ QStringLiteral( "vertical_anchor_mode" )].toInt() ) );
m->restoreOldDataDefinedProperties( props ); m->restoreOldDataDefinedProperties( props );
@ -3597,7 +3597,7 @@ void QgsFontMarkerSymbolLayer::startRender( QgsSymbolRenderContext &context )
mFont.setPixelSize( std::max( 2, static_cast< int >( std::round( sizePixels ) ) ) ); mFont.setPixelSize( std::max( 2, static_cast< int >( std::round( sizePixels ) ) ) );
mFontMetrics.reset( new QFontMetrics( mFont ) ); mFontMetrics.reset( new QFontMetrics( mFont ) );
mChrWidth = mFontMetrics->horizontalAdvance( mString ); mChrWidth = mFontMetrics->horizontalAdvance( mString );
if ( mFixVerticalAnchor ) if ( mVerticalAnchorMode == VerticalAnchorMode::Baseline )
{ {
mChrOffset = QPointF( mChrWidth / 2.0, -sizePixels / 2.0 ); mChrOffset = QPointF( mChrWidth / 2.0, -sizePixels / 2.0 );
} }
@ -3637,10 +3637,10 @@ QString QgsFontMarkerSymbolLayer::characterToRender( QgsSymbolRenderContext &con
if ( stringToRender != mString ) if ( stringToRender != mString )
{ {
charWidth = mFontMetrics->horizontalAdvance( stringToRender ); charWidth = mFontMetrics->horizontalAdvance( stringToRender );
if ( mFixVerticalAnchor ) if ( mVerticalAnchorMode == VerticalAnchorMode::Baseline )
{ {
const double sizePixels = context.renderContext().convertToPainterUnits( mSize, mSizeUnit, mSizeMapUnitScale ); const double sizePixels = context.renderContext().convertToPainterUnits( mSize, mSizeUnit, mSizeMapUnitScale );
charOffset = QPointF( mChrWidth / 2.0, -sizePixels / 2.0 ); charOffset = QPointF( charWidth / 2.0, -sizePixels / 2.0 );
} }
else else
{ {
@ -3875,7 +3875,7 @@ QVariantMap QgsFontMarkerSymbolLayer::properties() const
props[QStringLiteral( "offset_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetMapUnitScale ); props[QStringLiteral( "offset_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetMapUnitScale );
props[QStringLiteral( "horizontal_anchor_point" )] = QString::number( mHorizontalAnchorPoint ); props[QStringLiteral( "horizontal_anchor_point" )] = QString::number( mHorizontalAnchorPoint );
props[QStringLiteral( "vertical_anchor_point" )] = QString::number( mVerticalAnchorPoint ); props[QStringLiteral( "vertical_anchor_point" )] = QString::number( mVerticalAnchorPoint );
props[QStringLiteral( "fix_vertical_anchor" )] = mFixVerticalAnchor; props[QStringLiteral( "vertical_anchor_mode" )] = static_cast< int >( mVerticalAnchorMode );
return props; return props;
} }
@ -3895,7 +3895,7 @@ QgsFontMarkerSymbolLayer *QgsFontMarkerSymbolLayer::clone() const
m->setSizeMapUnitScale( mSizeMapUnitScale ); m->setSizeMapUnitScale( mSizeMapUnitScale );
m->setHorizontalAnchorPoint( mHorizontalAnchorPoint ); m->setHorizontalAnchorPoint( mHorizontalAnchorPoint );
m->setVerticalAnchorPoint( mVerticalAnchorPoint ); m->setVerticalAnchorPoint( mVerticalAnchorPoint );
m->setFixVerticalAnchor( mFixVerticalAnchor ); m->setVerticalAnchorMode( mVerticalAnchorMode );
copyDataDefinedProperties( m ); copyDataDefinedProperties( m );
copyPaintEffect( m ); copyPaintEffect( m );
return m; return m;

View File

@ -856,6 +856,13 @@ class CORE_EXPORT QgsFontMarkerSymbolLayer : public QgsMarkerSymbolLayer
{ {
public: public:
//! Vertical anchor modes
enum class VerticalAnchorMode : int
{
Legacy = 0, //!< Calculate anchor points with different offsets
Baseline = 1, //!< Calculate anchor points with fix baseline
};
//! Constructs a font marker symbol layer. //! Constructs a font marker symbol layer.
QgsFontMarkerSymbolLayer( const QString &fontFamily = DEFAULT_FONTMARKER_FONT, QgsFontMarkerSymbolLayer( const QString &fontFamily = DEFAULT_FONTMARKER_FONT,
QString chr = DEFAULT_FONTMARKER_CHR, QString chr = DEFAULT_FONTMARKER_CHR,
@ -1029,19 +1036,19 @@ class CORE_EXPORT QgsFontMarkerSymbolLayer : public QgsMarkerSymbolLayer
void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; } void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; }
/** /**
* Set fixVerticalAnchor that means it considers the baseline position for all the characters * Sets the vertical anchor mode whether it should considers the baseline as fix point
* \param fixVerticalAnchor the bool * \param verticalAnchorMode the mode how to handle the anchor point
* \see fixVerticalAnchor() * \see verticalAnchorMode()
* \since QGIS 3.42 * \since QGIS 3.42
*/ */
void setFixVerticalAnchor( const bool fixVerticalAnchor ) { mFixVerticalAnchor = fixVerticalAnchor;} void setVerticalAnchorMode( VerticalAnchorMode verticalAnchorMode ) { mVerticalAnchorMode = verticalAnchorMode;}
/** /**
* Returns wheter it considers teh baseline position for all the characters * Returns whether it should considers the baseline as fix point
* \see setFixVerticalAnchor() * \see setVerticalAnchorMode()
* \since QGIS 3.42 * \since QGIS 3.42
*/ */
bool fixVerticalAnchor() const { return mFixVerticalAnchor; } VerticalAnchorMode verticalAnchorMode() const { return mVerticalAnchorMode; }
QRectF bounds( QPointF point, QgsSymbolRenderContext &context ) override; QRectF bounds( QPointF point, QgsSymbolRenderContext &context ) override;
@ -1056,7 +1063,7 @@ class CORE_EXPORT QgsFontMarkerSymbolLayer : public QgsMarkerSymbolLayer
double mChrWidth = 0; double mChrWidth = 0;
QPointF mChrOffset; QPointF mChrOffset;
bool mFixVerticalAnchor = false; VerticalAnchorMode mVerticalAnchorMode = VerticalAnchorMode::Legacy;
//! Scaling for font sizes, used if font size grows too large //! Scaling for font sizes, used if font size grows too large
double mFontSizeScale = 1.0; double mFontSizeScale = 1.0;

View File

@ -3560,8 +3560,8 @@ void QgsFontMarkerSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer )
//anchor points //anchor points
whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() ); whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
int verticalAnchorIndex = mLayer->verticalAnchorPoint(); int verticalAnchorIndex = mLayer->verticalAnchorPoint();
if ( mLayer->fixVerticalAnchor() ) if ( mLayer->verticalAnchorMode() == QgsFontMarkerSymbolLayer::VerticalAnchorMode::Baseline )
verticalAnchorIndex += 3; verticalAnchorIndex = 3;
whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( verticalAnchorIndex ); whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( verticalAnchorIndex );
registerDataDefinedButton( mFontFamilyDDBtn, QgsSymbolLayer::Property::FontFamily ); registerDataDefinedButton( mFontFamilyDDBtn, QgsSymbolLayer::Property::FontFamily );
@ -3774,16 +3774,15 @@ void QgsFontMarkerSymbolLayerWidget::mVerticalAnchorComboBox_currentIndexChanged
{ {
if ( index >= 3 ) if ( index >= 3 )
{ {
mLayer->setFixVerticalAnchor( true ); // Bottom on Baseline is selected
//pass original types mLayer->setVerticalAnchorMode( QgsFontMarkerSymbolLayer::VerticalAnchorMode::Baseline );
index -= 3; mLayer->setVerticalAnchorPoint( QgsMarkerSymbolLayer::Bottom );
} }
else else
{ {
mLayer->setVerticalAnchorMode( QgsFontMarkerSymbolLayer::VerticalAnchorMode::Legacy );
mLayer->setFixVerticalAnchor( false ); mLayer->setVerticalAnchorPoint( QgsMarkerSymbolLayer::VerticalAnchorPoint( index ) );
} }
mLayer->setVerticalAnchorPoint( QgsMarkerSymbolLayer::VerticalAnchorPoint( index ) );
emit changed(); emit changed();
} }
} }

View File

@ -309,17 +309,7 @@
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Top considering Baseline</string> <string>Bottom on Baseline</string>
</property>
</item>
<item>
<property name="text">
<string>VCenter considering Baseline</string>
</property>
</item>
<item>
<property name="text">
<string>Bottom considering Baseline</string>
</property> </property>
</item> </item>
</widget> </widget>