Skip to content

Commit

Permalink
Showing 8 changed files with 46 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -190,7 +190,7 @@ Sets whether the format has overline ``enabled``.
.. seealso:: :py:func:`overline`
%End

void updateFontForFormat( QFont &font, double scaleFactor = 1.0 ) const;
void updateFontForFormat( QFont &font, const QgsRenderContext &context, double scaleFactor = 1.0 ) const;
%Docstring
Updates the specified ``font`` in place, applying character formatting options which
are applicable on a font level.
Original file line number Diff line number Diff line change
@@ -64,10 +64,10 @@ Sets the character ``format`` for the fragment.
.. seealso:: :py:func:`characterFormat`
%End

double horizontalAdvance( const QFont &font, bool fontHasBeenUpdatedForFragment = false, double scaleFactor = 1.0 ) const;
double horizontalAdvance( const QFont &font, const QgsRenderContext &context, bool fontHasBeenUpdatedForFragment = false, double scaleFactor = 1.0 ) const;
%Docstring
Returns the horizontal advance associated with this fragment, when rendered using
the specified base ``font``.
the specified base ``font`` within the specified render ``context``.

Set ``fontHasBeenUpdatedForFragment`` to ``True`` if ``font`` already represents the character
format for this fragment.
7 changes: 3 additions & 4 deletions src/core/textrenderer/qgstextcharacterformat.cpp
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
***************************************************************************/

#include "qgstextcharacterformat.h"
#include "qgsrendercontext.h"

#include <QTextCharFormat>

@@ -90,18 +91,16 @@ void QgsTextCharacterFormat::setOverline( QgsTextCharacterFormat::BooleanValue e
mOverline = enabled;
}

void QgsTextCharacterFormat::updateFontForFormat( QFont &font, const double scaleFactor ) const
void QgsTextCharacterFormat::updateFontForFormat( QFont &font, const QgsRenderContext &context, const double scaleFactor ) const
{
Q_UNUSED( scaleFactor );

if ( mItalic != QgsTextCharacterFormat::BooleanValue::NotSet )
font.setItalic( mItalic == QgsTextCharacterFormat::BooleanValue::SetTrue );
if ( mFontWeight != -1 )
font.setWeight( mFontWeight );
if ( !mFontFamily.isEmpty() )
font.setFamily( mFontFamily );
if ( mFontPointSize != -1 )
font.setPointSizeF( mFontPointSize );
font.setPixelSize( scaleFactor * context.convertToPainterUnits( mFontPointSize, QgsUnitTypes::RenderPoints ) );
if ( mUnderline != BooleanValue::NotSet )
font.setUnderline( mUnderline == QgsTextCharacterFormat::BooleanValue::SetTrue );
if ( mOverline != BooleanValue::NotSet )
3 changes: 2 additions & 1 deletion src/core/textrenderer/qgstextcharacterformat.h
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
#include <QColor>

class QTextCharFormat;
class QgsRenderContext;

/**
* \class QgsTextCharacterFormat
@@ -202,7 +203,7 @@ class CORE_EXPORT QgsTextCharacterFormat
* based on the resultant font metrics. Failure to do so will result in poor quality text rendering
* at small font sizes.
*/
void updateFontForFormat( QFont &font, double scaleFactor = 1.0 ) const;
void updateFontForFormat( QFont &font, const QgsRenderContext &context, double scaleFactor = 1.0 ) const;

private:

4 changes: 2 additions & 2 deletions src/core/textrenderer/qgstextfragment.cpp
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ void QgsTextFragment::setCharacterFormat( const QgsTextCharacterFormat &charForm
mCharFormat = charFormat;
}

double QgsTextFragment::horizontalAdvance( const QFont &font, bool fontHasBeenUpdatedForFragment, double scaleFactor ) const
double QgsTextFragment::horizontalAdvance( const QFont &font, const QgsRenderContext &context, bool fontHasBeenUpdatedForFragment, double scaleFactor ) const
{
if ( fontHasBeenUpdatedForFragment )
{
@@ -55,7 +55,7 @@ double QgsTextFragment::horizontalAdvance( const QFont &font, bool fontHasBeenUp
else
{
QFont updatedFont = font;
mCharFormat.updateFontForFormat( updatedFont, scaleFactor );
mCharFormat.updateFontForFormat( updatedFont, context, scaleFactor );
const QFontMetricsF fm( updatedFont );
return fm.horizontalAdvance( mText );
}
4 changes: 2 additions & 2 deletions src/core/textrenderer/qgstextfragment.h
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ class CORE_EXPORT QgsTextFragment

/**
* Returns the horizontal advance associated with this fragment, when rendered using
* the specified base \a font.
* the specified base \a font within the specified render \a context.
*
* Set \a fontHasBeenUpdatedForFragment to TRUE if \a font already represents the character
* format for this fragment.
@@ -86,7 +86,7 @@ class CORE_EXPORT QgsTextFragment
* based on the resultant font metrics. Failure to do so will result in poor quality text rendering
* at small font sizes.
*/
double horizontalAdvance( const QFont &font, bool fontHasBeenUpdatedForFragment = false, double scaleFactor = 1.0 ) const;
double horizontalAdvance( const QFont &font, const QgsRenderContext &context, bool fontHasBeenUpdatedForFragment = false, double scaleFactor = 1.0 ) const;

/**
* Applies a \a capitalization style to the fragment's text.
28 changes: 14 additions & 14 deletions src/core/textrenderer/qgstextrenderer.cpp
Original file line number Diff line number Diff line change
@@ -337,14 +337,14 @@ double QgsTextRenderer::drawBuffer( QgsRenderContext &context, const QgsTextRend
for ( const QgsTextFragment &fragment : component.block )
{
QFont fragmentFont = font;
fragment.characterFormat().updateFontForFormat( fragmentFont, scaleFactor );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, scaleFactor );

if ( component.extraWordSpacing || component.extraLetterSpacing )
applyExtraSpacingForLineJustification( fragmentFont, component.extraWordSpacing, component.extraLetterSpacing );

path.addText( xOffset, 0, fragmentFont, fragment.text() );

xOffset += fragment.horizontalAdvance( fragmentFont, true, scaleFactor );
xOffset += fragment.horizontalAdvance( fragmentFont, context, true, scaleFactor );
}
advance = xOffset;
break;
@@ -358,7 +358,7 @@ double QgsTextRenderer::drawBuffer( QgsRenderContext &context, const QgsTextRend
for ( const QgsTextFragment &fragment : component.block )
{
QFont fragmentFont = font;
fragment.characterFormat().updateFontForFormat( fragmentFont, scaleFactor );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, scaleFactor );

QFontMetricsF fragmentMetrics( fragmentFont );
const double labelWidth = fragmentMetrics.maxWidth();
@@ -492,11 +492,11 @@ void QgsTextRenderer::drawMask( QgsRenderContext &context, const QgsTextRenderer
for ( const QgsTextFragment &fragment : component.block )
{
QFont fragmentFont = font;
fragment.characterFormat().updateFontForFormat( fragmentFont, scaleFactor );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, scaleFactor );

path.addText( xOffset, 0, fragmentFont, fragment.text() );

xOffset += fragment.horizontalAdvance( fragmentFont, true );
xOffset += fragment.horizontalAdvance( fragmentFont, context, true, scaleFactor );
}

QColor bufferColor( Qt::gray );
@@ -577,7 +577,7 @@ double QgsTextRenderer::textWidth( const QgsRenderContext &context, const QgsTex
double blockWidth = 0;
for ( const QgsTextFragment &fragment : block )
{
blockWidth += fragment.horizontalAdvance( baseFont, false, scaleFactor );
blockWidth += fragment.horizontalAdvance( baseFont, context, false, scaleFactor );
}
maxLineWidth = std::max( maxLineWidth, blockWidth );
}
@@ -596,7 +596,7 @@ double QgsTextRenderer::textWidth( const QgsRenderContext &context, const QgsTex
for ( const QgsTextFragment &fragment : block )
{
QFont fragmentFont = baseFont;
fragment.characterFormat().updateFontForFormat( fragmentFont, scaleFactor );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, scaleFactor );
blockWidth = std::max( QFontMetricsF( fragmentFont ).maxWidth(), blockWidth );
}

@@ -792,7 +792,7 @@ double QgsTextRenderer::textHeight( const QgsRenderContext &context, const QgsTe
for ( const QgsTextFragment &fragment : block )
{
QFont fragmentFont = baseFont;
fragment.characterFormat().updateFontForFormat( fragmentFont, scaleFactor );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, scaleFactor );
const QFontMetricsF fm( fragmentFont );

const double fragmentHeight = fm.ascent() + fm.descent(); // ignore +1 for baseline
@@ -839,7 +839,7 @@ double QgsTextRenderer::textHeight( const QgsRenderContext &context, const QgsTe
for ( const QgsTextFragment &fragment : block )
{
QFont fragmentFont = baseFont;
fragment.characterFormat().updateFontForFormat( fragmentFont, scaleFactor );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, scaleFactor );
const QFontMetricsF fm( fragmentFont );

const double labelHeight = fm.ascent();
@@ -1761,7 +1761,7 @@ void QgsTextRenderer::drawTextInternalHorizontal( QgsRenderContext &context, con
path.setFillRule( Qt::WindingFill );

QFont fragmentFont = font;
fragment.characterFormat().updateFontForFormat( fragmentFont, fontScale );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, fontScale );

if ( extraWordSpace || extraLetterSpace )
applyExtraSpacingForLineJustification( fragmentFont, extraWordSpace * fontScale, extraLetterSpace * fontScale );
@@ -1773,7 +1773,7 @@ void QgsTextRenderer::drawTextInternalHorizontal( QgsRenderContext &context, con
textp.setBrush( textColor );
textp.drawPath( path );

xOffset += fragment.horizontalAdvance( fragmentFont, true );
xOffset += fragment.horizontalAdvance( fragmentFont, context, true, fontScale );
}
textp.end();
}
@@ -1812,7 +1812,7 @@ void QgsTextRenderer::drawTextInternalHorizontal( QgsRenderContext &context, con
for ( const QgsTextFragment &fragment : block )
{
QFont fragmentFont = font;
fragment.characterFormat().updateFontForFormat( fragmentFont, fontScale );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, fontScale );

if ( extraWordSpace || extraLetterSpace )
applyExtraSpacingForLineJustification( fragmentFont, extraWordSpace * fontScale, extraLetterSpace * fontScale );
@@ -1828,7 +1828,7 @@ void QgsTextRenderer::drawTextInternalHorizontal( QgsRenderContext &context, con
context.painter()->drawText( xOffset, 0, fragment.text() );
context.painter()->scale( fontScale, fontScale );

xOffset += fragment.horizontalAdvance( fragmentFont, true, fontScale );
xOffset += fragment.horizontalAdvance( fragmentFont, context, true, fontScale );
}
}
}
@@ -1980,7 +1980,7 @@ void QgsTextRenderer::drawTextInternalVertical( QgsRenderContext &context, const
const QString line = QgsStringUtils::substituteVerticalCharacters( fragment.text() );

QFont fragmentFont( font );
fragment.characterFormat().updateFontForFormat( fragmentFont, fontScale );
fragment.characterFormat().updateFontForFormat( fragmentFont, context, fontScale );

QFontMetricsF fragmentMetrics( fragmentFont );

32 changes: 20 additions & 12 deletions tests/src/python/test_qgstextcharacterformat.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,8 @@

from qgis.core import (
QgsFontUtils,
QgsTextCharacterFormat
QgsTextCharacterFormat,
QgsRenderContext
)
from qgis.PyQt.QtGui import QColor
from qgis.testing import start_app, unittest
@@ -59,13 +60,14 @@ def testGettersSetters(self):
self.assertEqual(format.family(), 'comic sans')

def testUpdateFont(self):
context = QgsRenderContext()
font = QgsFontUtils.getStandardTestFont()

old_size = font.pointSizeF()
old_family = font.family()

format = QgsTextCharacterFormat()
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)

self.assertFalse(font.underline())
self.assertFalse(font.strikeOut())
@@ -74,52 +76,58 @@ def testUpdateFont(self):
self.assertEqual(font.pointSizeF(), old_size)

format.setUnderline(QgsTextCharacterFormat.BooleanValue.SetTrue)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertTrue(font.underline())
self.assertFalse(font.strikeOut())
self.assertFalse(font.overline())

format.setUnderline(QgsTextCharacterFormat.BooleanValue.NotSet)
format.setStrikeOut(QgsTextCharacterFormat.BooleanValue.SetTrue)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertTrue(font.underline())
self.assertTrue(font.strikeOut())
self.assertFalse(font.overline())

format.setUnderline(QgsTextCharacterFormat.BooleanValue.SetFalse)
format.setStrikeOut(QgsTextCharacterFormat.BooleanValue.NotSet)
format.setOverline(QgsTextCharacterFormat.BooleanValue.SetTrue)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertFalse(font.underline())
self.assertTrue(font.strikeOut())
self.assertTrue(font.overline())

format.setStrikeOut(QgsTextCharacterFormat.BooleanValue.SetFalse)
format.setOverline(QgsTextCharacterFormat.BooleanValue.NotSet)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertFalse(font.strikeOut())
self.assertTrue(font.overline())

format.setOverline(QgsTextCharacterFormat.BooleanValue.SetFalse)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertFalse(font.overline())
self.assertEqual(font.pointSizeF(), old_size)

format.setFontPointSize(49)
format.updateFontForFormat(font)
self.assertEqual(font.pointSizeF(), 49)
format.updateFontForFormat(font, context)
self.assertEqual(font.pixelSize(), 17)

context.setScaleFactor(10)
format.updateFontForFormat(font, context)
self.assertEqual(font.pixelSize(), 172)
format.updateFontForFormat(font, context, 5)
self.assertEqual(font.pixelSize(), 864)
format.setFontPointSize(-1)
font.setPointSizeF(old_size)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertEqual(font.pointSizeF(), old_size)

self.assertEqual(font.family(), old_family)
format.setFamily('Serif')
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertEqual(font.family(), 'Serif')
format.setFamily('')
font.setFamily(old_family)
format.updateFontForFormat(font)
format.updateFontForFormat(font, context)
self.assertEqual(font.family(), old_family)


0 comments on commit 5f2aca4

Please sign in to comment.