[layouts] Fix line height setting not respected for HTML-enabled label items

This commit is contained in:
Mathieu Pellerin 2023-10-11 12:02:10 +07:00 committed by Nyall Dawson
parent c99a33d224
commit 0e6b4fb118
9 changed files with 99 additions and 5 deletions

View File

@ -729,6 +729,20 @@ Returns a pixmap preview for a text ``format``.
:param screen: can be used to specify the destination screen properties for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
.. versionadded:: 3.10
%End
QString asCSS( double pointToPixelMultiplier = 1.0 ) const;
%Docstring
Returns a CSS string representing the specified text format as closely as possible.
:param pointToPixelMultiplier: scaling factor to apply to convert point sizes to pixel font sizes.
The CSS returned by this function will always use pixels for font sizes, so this parameter
should be set to a suitable value to convert point sizes to pixels (e.g., taking into account
destination DPI)
:return: partial CSS string, e.g., "line-height: 120%;"
.. versionadded:: 3.34
%End
};

View File

@ -1124,6 +1124,12 @@ QList< QgsLayoutItem * > QgsLayout::addItemsFromXml( const QDomElement &parentEl
{
if ( label->mode() == QgsLayoutItemLabel::ModeHtml )
{
QgsTextFormat textFormat = label->textFormat();
if ( textFormat.lineHeightUnit() == Qgis::RenderUnit::Percentage )
{
textFormat.setLineHeight( textFormat.lineHeight() + 0.22 );
label->setTextFormat( textFormat );
}
QgsLayoutMultiFrame *html = QgsLayoutItemHtml::createFromLabel( label );
addMultiFrame( html );
if ( item->isGroupMember() )

View File

@ -641,12 +641,9 @@ double QgsLayoutItemLabel::htmlUnitsToLayoutUnits()
QString QgsLayoutItemLabel::createStylesheet() const
{
QString stylesheet;
stylesheet += QStringLiteral( "body { margin: %1 %2;" ).arg( std::max( mMarginY * mHtmlUnitsToLayoutUnits, 0.0 ) ).arg( std::max( mMarginX * mHtmlUnitsToLayoutUnits, 0.0 ) );
QFont f = createDefaultFont();
stylesheet += QgsFontUtils::asCSS( f, 0.352778 * mHtmlUnitsToLayoutUnits );
stylesheet += QStringLiteral( "color: rgba(%1,%2,%3,%4);" ).arg( mFormat.color().red() ).arg( mFormat.color().green() ).arg( mFormat.color().blue() ).arg( QString::number( mFormat.color().alphaF(), 'f', 4 ) );
stylesheet += mFormat.asCSS( 0.352778 * mHtmlUnitsToLayoutUnits );
stylesheet += QStringLiteral( "text-align: %1; }" ).arg( mHAlignment == Qt::AlignLeft ? QStringLiteral( "left" ) : mHAlignment == Qt::AlignRight ? QStringLiteral( "right" ) : mHAlignment == Qt::AlignHCenter ? QStringLiteral( "center" ) : QStringLiteral( "justify" ) );
return stylesheet;

View File

@ -1225,3 +1225,40 @@ QPixmap QgsTextFormat::textFormatPreviewPixmap( const QgsTextFormat &format, QSi
painter.end();
return pixmap;
}
QString QgsTextFormat::asCSS( double pointToPixelMultiplier ) const
{
QString css;
switch ( lineHeightUnit() )
{
case Qgis::RenderUnit::Percentage:
css += QStringLiteral( "line-height: %1%;" ).arg( lineHeight() * 100 );
break;
case Qgis::RenderUnit::Pixels:
css += QStringLiteral( "line-height: %1px;" ).arg( lineHeight() );
break;
case Qgis::RenderUnit::Points:
// While the Qt documentation states pt unit type is supported, it's ignored, convert to px
css += QStringLiteral( "line-height: %1px;" ).arg( lineHeight() * pointToPixelMultiplier );
break;
case Qgis::RenderUnit::Millimeters:
// While the Qt documentation states cm unit type is supported, it's ignored, convert to px
css += QStringLiteral( "line-height: %1px;" ).arg( lineHeight() * 2.83464567 * pointToPixelMultiplier );
break;
case Qgis::RenderUnit::MetersInMapUnits:
case Qgis::RenderUnit::MapUnits:
case Qgis::RenderUnit::Inches:
case Qgis::RenderUnit::Unknown:
break;
}
css += QStringLiteral( "color: rgba(%1,%2,%3,%4);" ).arg( color().red() ).arg( color().green() ).arg( color().blue() ).arg( QString::number( color().alphaF(), 'f', 4 ) );
QFont f = toQFont();
if ( sizeUnit() == Qgis::RenderUnit::Millimeters )
{
f.setPointSizeF( size() / 0.352778 );
}
css += QgsFontUtils::asCSS( toQFont(), pointToPixelMultiplier );
return css;
}

View File

@ -657,6 +657,17 @@ class CORE_EXPORT QgsTextFormat
*/
static QPixmap textFormatPreviewPixmap( const QgsTextFormat &format, QSize size, const QString &previewText = QString(), int padding = 0, const QgsScreenProperties &screen = QgsScreenProperties() );
/**
* Returns a CSS string representing the specified text format as closely as possible.
* \param pointToPixelMultiplier scaling factor to apply to convert point sizes to pixel font sizes.
* The CSS returned by this function will always use pixels for font sizes, so this parameter
* should be set to a suitable value to convert point sizes to pixels (e.g., taking into account
* destination DPI)
* \returns partial CSS string, e.g., "line-height: 120%;"
* \since QGIS 3.34
*/
QString asCSS( double pointToPixelMultiplier = 1.0 ) const;
private:
QgsTextBufferSettings mBufferSettings;

View File

@ -55,6 +55,7 @@ class TestQgsLayoutLabel : public QgsTest
void marginMethods(); //tests getting/setting margins
void render();
void renderAsHtml();
void renderAsHtmlLineHeight();
#ifdef WITH_QTWEBKIT
void convertToHtml();
void renderAsHtmlRelative();
@ -313,6 +314,34 @@ void TestQgsLayoutLabel::renderAsHtml()
QVERIFY( layoutCheck( QStringLiteral( "composerlabel_renderhtml" ), &l, 0, 10 ) );
}
void TestQgsLayoutLabel::renderAsHtmlLineHeight()
{
QgsLayout l( QgsProject::instance() );
l.initializeDefaults();
QgsLayoutItemLabel *label = new QgsLayoutItemLabel( &l );
label->setMargin( 1 );
l.addLayoutItem( label );
label->setText( QStringLiteral( "test <i>html</i><br>with <u>line height</u>." ) );
QgsTextFormat format;
format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ) );
format.setSize( 48 );
format.setSizeUnit( Qgis::RenderUnit::Points );
format.setColor( QColor( 200, 40, 60 ) );
format.setLineHeight( 2.0 );
format.setLineHeightUnit( Qgis::RenderUnit::Percentage );
label->setTextFormat( format );
label->setPos( 70, 70 );
label->adjustSizeToText();
label->setMode( QgsLayoutItemLabel::ModeHtml );
label->update();
QVERIFY( layoutCheck( QStringLiteral( "composerlabel_renderhtmllineheight" ), &l, 0, 10 ) );
}
#ifdef WITH_QTWEBKIT
void TestQgsLayoutLabel::convertToHtml()
{