Add QFontMetricsF methods taking text options into account

This is needed by Qt Quick to be able to calculate font metrics using
design metrics matching Quick text rendering.

Task-number: QTBUG-85936
Task-number: QTBUG-94023
Change-Id: I67c74e2a912bd58df7a57349a858f20f04609f0f
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
bb10
Allan Sandfeld Jensen 2021-10-13 15:55:49 +02:00
parent 8a4f252644
commit c1a5f08ba0
2 changed files with 201 additions and 6 deletions

View File

@ -536,6 +536,33 @@ int QFontMetrics::horizontalAdvance(const QString &text, int len) const
return qRound(layout.width(0, len));
}
/*!
Returns the horizontal advance in pixels of \a text laid out using \a option.
The advance is the distance appropriate for drawing a subsequent
character after \a text.
\since 6.3
\sa boundingRect()
*/
int QFontMetrics::horizontalAdvance(const QString &text, const QTextOption &option) const
{
int pos = text.indexOf(QLatin1Char('\x9c'));
int len = -1;
if (pos != -1) {
len = (len < 0) ? pos : qMin(pos, len);
} else if (len < 0) {
len = text.length();
}
if (len == 0)
return 0;
QStackTextEngine layout(text, QFont(d.data()));
layout.option = option;
return qRound(layout.width(0, len));
}
/*!
\overload
@ -622,6 +649,42 @@ QRect QFontMetrics::boundingRect(const QString &text) const
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
/*!
Returns the bounding rectangle of the characters in the string
specified by \a text laid out using \a option. The bounding rectangle always
covers at least the set of pixels the text would cover if drawn at (0, 0).
Note that the bounding rectangle may extend to the left of (0, 0),
e.g. for italicized fonts, and that the width of the returned
rectangle might be different than what the horizontalAdvance() method
returns.
If you want to know the advance width of the string (to lay out
a set of strings next to each other), use horizontalAdvance() instead.
Newline characters are processed as normal characters, \e not as
linebreaks.
The height of the bounding rectangle is at least as large as the
value returned by height().
\since 6.3
\sa horizontalAdvance(), height(), QPainter::boundingRect(),
tightBoundingRect()
*/
QRect QFontMetrics::boundingRect(const QString &text, const QTextOption &option) const
{
if (text.length() == 0)
return QRect();
QStackTextEngine layout(text, QFont(d.data()));
layout.option = option;
layout.itemize();
glyph_metrics_t gm = layout.boundingBox(0, text.length());
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
/*!
Returns the rectangle that is covered by ink if character \a ch
were to be drawn at the origin of the coordinate system.
@ -758,8 +821,6 @@ QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabA
}
/*!
\since 4.3
Returns a tight bounding rectangle around the characters in the
string specified by \a text. The bounding rectangle always covers
at least the set of pixels the text would cover if drawn at (0,
@ -776,7 +837,7 @@ QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabA
Newline characters are processed as normal characters, \e not as
linebreaks.
\warning Calling this method is very slow on Windows.
\since 4.3
\sa horizontalAdvance(), height(), boundingRect()
*/
@ -791,6 +852,38 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
/*!
Returns a tight bounding rectangle around the characters in the
string specified by \a text laid out using \a option. The bounding
rectangle always covers at least the set of pixels the text would
cover if drawn at (0, 0).
Note that the bounding rectangle may extend to the left of (0, 0),
e.g. for italicized fonts, and that the width of the returned
rectangle might be different than what the horizontalAdvance() method
returns.
If you want to know the advance width of the string (to lay out
a set of strings next to each other), use horizontalAdvance() instead.
Newline characters are processed as normal characters, \e not as
linebreaks.
\since 6.3
\sa horizontalAdvance(), height(), boundingRect()
*/
QRect QFontMetrics::tightBoundingRect(const QString &text, const QTextOption &option) const
{
if (text.length() == 0)
return QRect();
QStackTextEngine layout(text, QFont(d.data()));
layout.option = option;
layout.itemize();
glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
/*!
\since 4.2
@ -1355,6 +1448,34 @@ qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const
return layout.width(0, length).toReal();
}
/*!
Returns the horizontal advance in pixels of \a text laid out using \a option.
The advance is the distance appropriate for drawing a subsequent
character after \a text.
\since 6.3
\sa boundingRect()
*/
qreal QFontMetricsF::horizontalAdvance(const QString &text, const QTextOption &option) const
{
int pos = text.indexOf(QLatin1Char('\x9c'));
int length = -1;
if (pos != -1)
length = (length < 0) ? pos : qMin(pos, length);
else if (length < 0)
length = text.length();
if (length == 0)
return 0;
QStackTextEngine layout(text, QFont(d.data()));
layout.option = option;
layout.itemize();
return layout.width(0, length).toReal();
}
/*!
\overload
@ -1442,6 +1563,42 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const
gm.width.toReal(), gm.height.toReal());
}
/*!
Returns the bounding rectangle of the characters in the string
specified by \a text laid out using \a option. The bounding
rectangle always covers at least the set of pixels the text
would cover if drawn at (0, 0).
Note that the bounding rectangle may extend to the left of (0, 0),
e.g. for italicized fonts, and that the width of the returned
rectangle might be different than what the horizontalAdvance() method returns.
If you want to know the advance width of the string (to lay out
a set of strings next to each other), use horizontalAdvance() instead.
Newline characters are processed as normal characters, \e not as
linebreaks.
The height of the bounding rectangle is at least as large as the
value returned height().
\since 6.3
\sa horizontalAdvance(), height(), QPainter::boundingRect()
*/
QRectF QFontMetricsF::boundingRect(const QString &text, const QTextOption &option) const
{
if (text.length() == 0)
return QRectF();
QStackTextEngine layout(text, QFont(d.data()));
layout.option = option;
layout.itemize();
glyph_metrics_t gm = layout.boundingBox(0, text.length());
return QRectF(gm.x.toReal(), gm.y.toReal(),
gm.width.toReal(), gm.height.toReal());
}
/*!
Returns the bounding rectangle of the character \a ch relative to
the left-most point on the base line.
@ -1600,14 +1757,12 @@ QSizeF QFontMetricsF::size(int flags, const QString &text, int tabStops, int *ta
Newline characters are processed as normal characters, \e not as
linebreaks.
\warning Calling this method is very slow on Windows.
\sa horizontalAdvance(), height(), boundingRect()
*/
QRectF QFontMetricsF::tightBoundingRect(const QString &text) const
{
if (text.length() == 0)
return QRect();
return QRectF();
QStackTextEngine layout(text, QFont(d.data()));
layout.itemize();
@ -1615,6 +1770,39 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const
return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
}
/*!
Returns a tight bounding rectangle around the characters in the
string specified by \a text laid out using \a option. The bounding
rectangle always covers at least the set of pixels the text would
cover if drawn at (0,0).
Note that the bounding rectangle may extend to the left of (0, 0),
e.g. for italicized fonts, and that the width of the returned
rectangle might be different than what the horizontalAdvance() method
returns.
If you want to know the advance width of the string (to lay out
a set of strings next to each other), use horizontalAdvance() instead.
Newline characters are processed as normal characters, \e not as
linebreaks.
\since 6.3
\sa horizontalAdvance(), height(), boundingRect()
*/
QRectF QFontMetricsF::tightBoundingRect(const QString &text, const QTextOption &option) const
{
if (text.length() == 0)
return QRectF();
QStackTextEngine layout(text, QFont(d.data()));
layout.option = option;
layout.itemize();
glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
}
/*!
\since 4.2

View File

@ -50,6 +50,7 @@
QT_BEGIN_NAMESPACE
class QRect;
class QTextOption;
class Q_GUI_EXPORT QFontMetrics
{
@ -85,11 +86,13 @@ public:
int rightBearing(QChar) const;
int horizontalAdvance(const QString &, int len = -1) const;
int horizontalAdvance(const QString &, const QTextOption &textOption) const;
int horizontalAdvance(QChar) const;
QRect boundingRect(QChar) const;
QRect boundingRect(const QString &text) const;
QRect boundingRect(const QString &text, const QTextOption &textOption) const;
QRect boundingRect(const QRect &r, int flags, const QString &text, int tabstops = 0, int *tabarray = nullptr) const;
inline QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text,
int tabstops = 0, int *tabarray = nullptr) const
@ -97,6 +100,7 @@ public:
QSize size(int flags, const QString& str, int tabstops = 0, int *tabarray = nullptr) const;
QRect tightBoundingRect(const QString &text) const;
QRect tightBoundingRect(const QString &text, const QTextOption &textOption) const;
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags = 0) const;
@ -155,13 +159,16 @@ public:
qreal horizontalAdvance(const QString &string, int length = -1) const;
qreal horizontalAdvance(QChar) const;
qreal horizontalAdvance(const QString &string, const QTextOption &textOption) const;
QRectF boundingRect(const QString &string) const;
QRectF boundingRect(const QString &text, const QTextOption &textOption) const;
QRectF boundingRect(QChar) const;
QRectF boundingRect(const QRectF &r, int flags, const QString& string, int tabstops = 0, int *tabarray = nullptr) const;
QSizeF size(int flags, const QString& str, int tabstops = 0, int *tabarray = nullptr) const;
QRectF tightBoundingRect(const QString &text) const;
QRectF tightBoundingRect(const QString &text, const QTextOption &textOption) const;
QString elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags = 0) const;