summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-13 15:55:49 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-22 01:05:43 +0200
commitc1a5f08ba055edc1032d3ca3bcaa978fd14234e9 (patch)
treece6783e9a3ab89d1d7b3e03e557b6fa3dc553230 /src/gui/text
parent8a4f252644b0729491bca42abe0ba88862136cfc (diff)
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>
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qfontmetrics.cpp200
-rw-r--r--src/gui/text/qfontmetrics.h7
2 files changed, 201 insertions, 6 deletions
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 42c17ced58..f5018539c3 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -537,6 +537,33 @@ int QFontMetrics::horizontalAdvance(const QString &text, int len) const
}
/*!
+ 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
\image bearings.png Bearings
@@ -623,6 +650,42 @@ QRect QFontMetrics::boundingRect(const QString &text) const
}
/*!
+ 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
@@ -1356,6 +1449,34 @@ qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const
}
/*!
+ 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
\image bearings.png Bearings
@@ -1443,6 +1564,42 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const
}
/*!
+ 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,16 +1757,47 @@ 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();
+ glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
+ 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());
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index a199e20373..cd438fff7c 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -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;