summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qfontmetrics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qfontmetrics.cpp')
-rw-r--r--src/gui/text/qfontmetrics.cpp573
1 files changed, 264 insertions, 309 deletions
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index a79957797d..f7e405f0b5 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfont.h"
#include "qpaintdevice.h"
@@ -106,20 +70,28 @@ extern void qt_format_text(const QFont& font, const QRectF &_r,
These are by necessity slow, and we recommend avoiding them if
possible.
- For each character, you can get its width(), leftBearing() and
- rightBearing() and find out whether it is in the font using
+ For each character, you can get its horizontalAdvance(), leftBearing(),
+ and rightBearing(), and find out whether it is in the font using
inFont(). You can also treat the character as a string, and use
the string functions on it.
- The string functions include width(), to return the width of a
- string in pixels (or points, for a printer), boundingRect(), to
- return a rectangle large enough to contain the rendered string,
+ The string functions include horizontalAdvance(), to return the advance
+ width of a string in pixels (or points, for a printer), boundingRect(),
+ to return a rectangle large enough to contain the rendered string,
and size(), to return the size of that rectangle.
+ \note The advance width can be different from the width of the actual
+ rendered text. It refers to the distance from the origin of the string to
+ where you would append additional characters. As text may have overhang
+ (in the case of an italic font for instance) or padding between
+ characters, the advance width can be either smaller or larger than the
+ actual rendering of the text. This is called the right bearing of the
+ text.
+
Example:
\snippet code/src_gui_text_qfontmetrics.cpp 0
- \sa QFont, QFontInfo, QFontDatabase, {Character Map Example}
+ \sa QFont, QFontInfo, QFontDatabase
*/
/*!
@@ -161,7 +133,7 @@ QFontMetrics::QFontMetrics(const QFont &font)
Constructs a font metrics object for \a font and \a paintdevice.
The font metrics will be compatible with the paintdevice passed.
- If the \a paintdevice is 0, the metrics will be screen-compatible,
+ If the \a paintdevice is \nullptr, the metrics will be screen-compatible,
ie. the metrics you get if you use the font for drawing text on a
\l{QWidget}{widgets} or \l{QPixmap}{pixmaps},
not on a QPicture or QPrinter.
@@ -170,19 +142,7 @@ QFontMetrics::QFontMetrics(const QFont &font)
passed in the constructor at the time it is created, and is not
updated if the font's attributes are changed later.
*/
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-/*!
- \fn QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
- \obsolete
- Identical to QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
-*/
-
-
-QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
-#else
QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
-#endif
{
const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
if (font.d->dpi != dpi) {
@@ -273,9 +233,8 @@ bool QFontMetrics::operator ==(const QFontMetrics &other) const
The ascent of a font is the distance from the baseline to the
highest position characters extend to. In practice, some font
designers break this rule, e.g. when they put more than one accent
- on top of a character, or to accommodate an unusual character in
- an exotic language, so it is possible (though rare) that this
- value will be too small.
+ on top of a character, or to accommodate a certain character, so it
+ is possible (though rare) that this value will be too small.
\sa descent()
*/
@@ -310,8 +269,8 @@ int QFontMetrics::capHeight() const
The descent is the distance from the base line to the lowest point
characters extend to. In practice, some font designers break this rule,
- e.g. to accommodate an unusual character in an exotic language, so
- it is possible (though rare) that this value will be too small.
+ e.g. to accommodate a certain character, so it is possible (though
+ rare) that this value will be too small.
\sa ascent()
*/
@@ -464,9 +423,9 @@ bool QFontMetrics::inFontUcs4(uint ucs4) const
value is negative if the pixels of the character extend to the
left of the logical origin.
- See width() for a graphical description of this metric.
+ See horizontalAdvance() for a graphical description of this metric.
- \sa rightBearing(), minLeftBearing(), width()
+ \sa rightBearing(), minLeftBearing(), horizontalAdvance()
*/
int QFontMetrics::leftBearing(QChar ch) const
{
@@ -495,11 +454,11 @@ int QFontMetrics::leftBearing(QChar ch) const
The right bearing is the left-ward distance of the right-most
pixel of the character from the logical origin of a subsequent
character. This value is negative if the pixels of the character
- extend to the right of the width() of the character.
+ extend to the right of the horizontalAdvance() of the character.
- See width() for a graphical description of this metric.
+ See horizontalAdvance() for a graphical description of this metric.
- \sa leftBearing(), minRightBearing(), width()
+ \sa leftBearing(), minRightBearing(), horizontalAdvance()
*/
int QFontMetrics::rightBearing(QChar ch) const
{
@@ -522,117 +481,62 @@ int QFontMetrics::rightBearing(QChar ch) const
return qRound(rb);
}
-#if QT_DEPRECATED_SINCE(5, 11)
+static constexpr QLatin1Char s_variableLengthStringSeparator('\x9c');
+
/*!
- Returns the width in pixels of the first \a len characters of \a
+ Returns the horizontal advance in pixels of the first \a len characters of \a
text. If \a len is negative (the default), the entire string is
- used.
+ used. The entire length of \a text is analysed even if \a len is substantially
+ shorter.
- Note that this value is \e not equal to boundingRect().width();
- boundingRect() returns a rectangle describing the pixels this
- string will cover whereas width() returns the distance to where
- the next string should be drawn.
+ This is the distance appropriate for drawing a subsequent character
+ after \a text.
- \deprecated in Qt 5.11. Use horizontalAdvance() instead.
+ \since 5.11
\sa boundingRect()
*/
-int QFontMetrics::width(const QString &text, int len) const
-{
- return horizontalAdvance(text, len);
-}
-
-/*!
- \internal
-*/
-int QFontMetrics::width(const QString &text, int len, int flags) const
+int QFontMetrics::horizontalAdvance(const QString &text, int len) const
{
-#if QT_DEPRECATED_SINCE(5, 11) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- if (flags & Qt::TextBypassShaping) {
- int pos = text.indexOf(QLatin1Char('\x9c'));
- if (pos != -1) {
- len = (len < 0) ? pos : qMin(pos, len);
- } else if (len < 0) {
- len = text.length();
- }
- if (len == 0)
- return 0;
-
- // Skip complex shaping, only use advances
- int numGlyphs = len;
- QVarLengthGlyphLayoutArray glyphs(numGlyphs);
- QFontEngine *engine = d->engineForScript(QChar::Script_Common);
- if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, { }))
- Q_UNREACHABLE();
-
- QFixed width;
- for (int i = 0; i < numGlyphs; ++i)
- width += glyphs.advances[i];
- return qRound(width);
+ int pos = (len >= 0)
+ ? QStringView(text).left(len).indexOf(s_variableLengthStringSeparator)
+ : text.indexOf(s_variableLengthStringSeparator);
+ if (pos != -1) {
+ len = pos;
+ } else if (len < 0) {
+ len = text.size();
}
-#else
- Q_UNUSED(flags)
-#endif
-
- return horizontalAdvance(text, len);
-}
-
-/*!
- \overload
-
- \image bearings.png Bearings
-
- Returns the logical width of character \a ch in pixels. This is a
- distance appropriate for drawing a subsequent character after \a
- ch.
-
- Some of the metrics are described in the image to the right. The
- central dark rectangles cover the logical width() of each
- character. The outer pale rectangles cover the leftBearing() and
- rightBearing() of each character. Notice that the bearings of "f"
- in this particular font are both negative, while the bearings of
- "o" are both positive.
-
- \deprecated in Qt 5.11. Use horizontalAdvance() instead.
-
- \warning This function will produce incorrect results for Arabic
- characters or non-spacing marks in the middle of a string, as the
- glyph shaping and positioning of marks that happens when
- processing strings cannot be taken into account. When implementing
- an interactive text control, use QTextLayout instead.
+ if (len == 0)
+ return 0;
- \sa boundingRect()
-*/
-int QFontMetrics::width(QChar ch) const
-{
- return horizontalAdvance(ch);
+ QStackTextEngine layout(text, QFont(d.data()));
+ return qRound(layout.width(0, len));
}
-#endif // QT_DEPRECATED_SINCE(5, 11)
/*!
- Returns the horizontal advance in pixels of the first \a len characters of \a
- text. If \a len is negative (the default), the entire string is
- used.
+ Returns the horizontal advance in pixels of \a text laid out using \a option.
- This is the distance appropriate for drawing a subsequent character
- after \a text.
+ The advance is the distance appropriate for drawing a subsequent
+ character after \a text.
- \since 5.11
+ \since 6.3
\sa boundingRect()
*/
-int QFontMetrics::horizontalAdvance(const QString &text, int len) const
+int QFontMetrics::horizontalAdvance(const QString &text, const QTextOption &option) const
{
- int pos = text.indexOf(QLatin1Char('\x9c'));
+ int pos = text.indexOf(s_variableLengthStringSeparator);
+ int len = -1;
if (pos != -1) {
- len = (len < 0) ? pos : qMin(pos, len);
- } else if (len < 0) {
- len = text.length();
+ len = pos;
+ } else {
+ len = text.size();
}
if (len == 0)
return 0;
QStackTextEngine layout(text, QFont(d.data()));
+ layout.option = option;
return qRound(layout.width(0, len));
}
@@ -689,69 +593,48 @@ int QFontMetrics::horizontalAdvance(QChar ch) const
return qRound(advance);
}
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
-/*! \obsolete
+/*!
+ Returns the bounding rectangle of 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, 0).
- Returns the width of the character at position \a pos in the
- string \a text.
+ 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.
- The whole string is needed, as the glyph drawn may change
- depending on the context (the letter before and after the current
- one) for some languages (e.g. Arabic).
+ 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.
- This function also takes non spacing marks and ligatures into
- account.
+ The height of the bounding rectangle is at least as large as the
+ value returned by height().
+
+ \sa horizontalAdvance(), height(), QPainter::boundingRect(),
+ tightBoundingRect()
*/
-int QFontMetrics::charWidth(const QString &text, int pos) const
+QRect QFontMetrics::boundingRect(const QString &text) const
{
- int width = 0;
- if (pos < 0 || pos > (int)text.length())
- return width;
+ if (text.size() == 0)
+ return QRect();
- QChar ch = text.at(pos);
- const int script = ch.script();
- if (script != QChar::Script_Common) {
- // complex script shaping. Have to do some hard work
- int from = qMax(0, pos - 8);
- int to = qMin(text.length(), pos + 8);
- QString cstr = QString::fromRawData(text.unicode() + from, to - from);
- QStackTextEngine layout(cstr, QFont(d.data()));
- layout.ignoreBidi = true;
- layout.itemize();
- width = qRound(layout.width(pos-from, 1));
- } else if (ch.category() != QChar::Mark_NonSpacing) {
- QFontEngine *engine;
- if (d->capital == QFont::SmallCaps && ch.isLower())
- engine = d->smallCapsFontPrivate()->engineForScript(script);
- else
- engine = d->engineForScript(script);
- Q_ASSERT(engine != nullptr);
-
- d->alterCharForCapitalization(ch);
-
- glyph_t glyph = engine->glyphIndex(ch.unicode());
- QFixed advance;
-
- QGlyphLayout glyphs;
- glyphs.numGlyphs = 1;
- glyphs.glyphs = &glyph;
- glyphs.advances = &advance;
- engine->recalcAdvances(&glyphs, { });
-
- width = qRound(advance);
- }
- return width;
+ QStackTextEngine layout(text, QFont(d.data()));
+ layout.itemize();
+ glyph_metrics_t gm = layout.boundingBox(0, text.size());
+ return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
-#endif
/*!
Returns the bounding rectangle of 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, 0).
+ 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 width() method returns.
+ 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.
@@ -762,16 +645,20 @@ int QFontMetrics::charWidth(const QString &text, int pos) const
The height of the bounding rectangle is at least as large as the
value returned by height().
- \sa width(), height(), QPainter::boundingRect(), tightBoundingRect()
+ \since 6.3
+
+ \sa horizontalAdvance(), height(), QPainter::boundingRect(),
+ tightBoundingRect()
*/
-QRect QFontMetrics::boundingRect(const QString &text) const
+QRect QFontMetrics::boundingRect(const QString &text, const QTextOption &option) const
{
- if (text.length() == 0)
+ if (text.size() == 0)
return QRect();
QStackTextEngine layout(text, QFont(d.data()));
+ layout.option = option;
layout.itemize();
- glyph_metrics_t gm = layout.boundingBox(0, text.length());
+ glyph_metrics_t gm = layout.boundingBox(0, text.size());
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
@@ -790,7 +677,7 @@ QRect QFontMetrics::boundingRect(const QString &text) const
\warning The width of the returned rectangle is not the advance width
of the character. Use boundingRect(const QString &) or horizontalAdvance() instead.
- \sa width()
+ \sa horizontalAdvance()
*/
QRect QFontMetrics::boundingRect(QChar ch) const
{
@@ -864,7 +751,7 @@ QRect QFontMetrics::boundingRect(QChar ch) const
fontHeight() and lineSpacing() are used to calculate the height,
rather than individual character heights.
- \sa width(), QPainter::boundingRect(), Qt::Alignment
+ \sa horizontalAdvance(), QPainter::boundingRect(), Qt::Alignment
*/
QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &text, int tabStops,
int *tabArray) const
@@ -911,8 +798,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,
@@ -920,7 +805,8 @@ QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabA
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 width() method returns.
+ 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.
@@ -928,21 +814,53 @@ 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 width(), height(), boundingRect()
+ \sa horizontalAdvance(), height(), boundingRect()
*/
QRect QFontMetrics::tightBoundingRect(const QString &text) const
{
- if (text.length() == 0)
+ if (text.size() == 0)
return QRect();
QStackTextEngine layout(text, QFont(d.data()));
layout.itemize();
- glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
+ glyph_metrics_t gm = layout.tightBoundingBox(0, text.size());
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.size() == 0)
+ return QRect();
+
+ QStackTextEngine layout(text, QFont(d.data()));
+ layout.option = option;
+ layout.itemize();
+ glyph_metrics_t gm = layout.tightBoundingBox(0, text.size());
+ return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
+}
/*!
\since 4.2
@@ -971,13 +889,13 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in
QString _text = text;
if (!(flags & Qt::TextLongestVariant)) {
int posA = 0;
- int posB = _text.indexOf(QLatin1Char('\x9c'));
+ int posB = _text.indexOf(s_variableLengthStringSeparator);
while (posB >= 0) {
QString portion = _text.mid(posA, posB - posA);
if (size(flags, portion).width() <= width)
return portion;
posA = posB + 1;
- posB = _text.indexOf(QLatin1Char('\x9c'), posA);
+ posB = _text.indexOf(s_variableLengthStringSeparator, posA);
}
_text = _text.mid(posA);
}
@@ -1079,12 +997,12 @@ qreal QFontMetrics::fontDpi() const
These are by necessity slow, and we recommend avoiding them if
possible.
- For each character, you can get its width(), leftBearing() and
- rightBearing() and find out whether it is in the font using
+ For each character, you can get its horizontalAdvance(), leftBearing(), and
+ rightBearing(), and find out whether it is in the font using
inFont(). You can also treat the character as a string, and use
the string functions on it.
- The string functions include width(), to return the width of a
+ The string functions include horizontalAdvance(), to return the width of a
string in pixels (or points, for a printer), boundingRect(), to
return a rectangle large enough to contain the rendered string,
and size(), to return the size of that rectangle.
@@ -1151,7 +1069,7 @@ QFontMetricsF::QFontMetricsF(const QFont &font)
Constructs a font metrics object for \a font and \a paintdevice.
The font metrics will be compatible with the paintdevice passed.
- If the \a paintdevice is 0, the metrics will be screen-compatible,
+ If the \a paintdevice is \nullptr, the metrics will be screen-compatible,
ie. the metrics you get if you use the font for drawing text on a
\l{QWidget}{widgets} or \l{QPixmap}{pixmaps},
not on a QPicture or QPrinter.
@@ -1160,20 +1078,7 @@ QFontMetricsF::QFontMetricsF(const QFont &font)
passed in the constructor at the time it is created, and is not
updated if the font's attributes are changed later.
*/
-
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-/*!
- \fn QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
- \obsolete
- Identical to QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
-*/
-
-
-QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
-#else
QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
-#endif
{
int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
if (font.d->dpi != dpi) {
@@ -1239,9 +1144,8 @@ bool QFontMetricsF::operator ==(const QFontMetricsF &other) const
The ascent of a font is the distance from the baseline to the
highest position characters extend to. In practice, some font
designers break this rule, e.g. when they put more than one accent
- on top of a character, or to accommodate an unusual character in
- an exotic language, so it is possible (though rare) that this
- value will be too small.
+ on top of a character, or to accommodate a certain character, so
+ it is possible (though rare) that this value will be too small.
\sa descent()
*/
@@ -1277,8 +1181,8 @@ qreal QFontMetricsF::capHeight() const
The descent is the distance from the base line to the lowest point
characters extend to. (Note that this is different from X, which
adds 1 pixel.) In practice, some font designers break this rule,
- e.g. to accommodate an unusual character in an exotic language, so
- it is possible (though rare) that this value will be too small.
+ e.g. to accommodate a certain character, so it is possible (though
+ rare) that this value will be too small.
\sa ascent()
*/
@@ -1434,9 +1338,9 @@ bool QFontMetricsF::inFontUcs4(uint ucs4) const
value is negative if the pixels of the character extend to the
left of the logical origin.
- See width() for a graphical description of this metric.
+ See horizontalAdvance() for a graphical description of this metric.
- \sa rightBearing(), minLeftBearing(), width()
+ \sa rightBearing(), minLeftBearing(), horizontalAdvance()
*/
qreal QFontMetricsF::leftBearing(QChar ch) const
{
@@ -1465,11 +1369,11 @@ qreal QFontMetricsF::leftBearing(QChar ch) const
The right bearing is the left-ward distance of the right-most
pixel of the character from the logical origin of a subsequent
character. This value is negative if the pixels of the character
- extend to the right of the width() of the character.
+ extend to the right of the horizontalAdvance() of the character.
- See width() for a graphical description of this metric.
+ See horizontalAdvance() for a graphical description of this metric.
- \sa leftBearing(), minRightBearing(), width()
+ \sa leftBearing(), minRightBearing(), horizontalAdvance()
*/
qreal QFontMetricsF::rightBearing(QChar ch) const
{
@@ -1493,80 +1397,61 @@ qreal QFontMetricsF::rightBearing(QChar ch) const
}
-#if QT_DEPRECATED_SINCE(5, 11)
/*!
- Returns the width in pixels of the characters in the given \a text.
+ Returns the horizontal advance in pixels of the first \a length characters of \a
+ text. If \a length is negative (the default), the entire string is
+ used. The entire length of \a text is analysed even if \a length is substantially
+ shorter.
- Note that this value is \e not equal to the width returned by
- boundingRect().width() because boundingRect() returns a rectangle
- describing the pixels this string will cover whereas width()
- returns the distance to where the next string should be drawn.
+ The advance is the distance appropriate for drawing a subsequent
+ character after \a text.
- \deprecated in Qt 5.11. Use horizontalAdvance() instead.
+ \since 5.11
\sa boundingRect()
*/
-qreal QFontMetricsF::width(const QString &text) const
+qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const
{
- return horizontalAdvance(text);
-}
-
-/*!
- \overload
-
- \image bearings.png Bearings
-
- Returns the logical width of character \a ch in pixels. This is a
- distance appropriate for drawing a subsequent character after \a
- ch.
-
- Some of the metrics are described in the image to the right. The
- central dark rectangles cover the logical width() of each
- character. The outer pale rectangles cover the leftBearing() and
- rightBearing() of each character. Notice that the bearings of "f"
- in this particular font are both negative, while the bearings of
- "o" are both positive.
-
- \deprecated in Qt 5.11. Use horizontalAdvance() instead.
+ int pos = (length >= 0)
+ ? QStringView(text).left(length).indexOf(s_variableLengthStringSeparator)
+ : text.indexOf(s_variableLengthStringSeparator);
+ if (pos != -1)
+ length = pos;
+ else if (length < 0)
+ length = text.size();
- \warning This function will produce incorrect results for Arabic
- characters or non-spacing marks in the middle of a string, as the
- glyph shaping and positioning of marks that happens when
- processing strings cannot be taken into account. When implementing
- an interactive text control, use QTextLayout instead.
+ if (length == 0)
+ return 0;
- \sa boundingRect()
-*/
-qreal QFontMetricsF::width(QChar ch) const
-{
- return horizontalAdvance(ch);
+ QStackTextEngine layout(text, QFont(d.data()));
+ layout.itemize();
+ return layout.width(0, length).toReal();
}
-#endif
/*!
- Returns the horizontal advance in pixels of the first \a length characters of \a
- text. If \a length is negative (the default), the entire string is
- used.
+ 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 5.11
+ \since 6.3
\sa boundingRect()
*/
-qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const
+qreal QFontMetricsF::horizontalAdvance(const QString &text, const QTextOption &option) const
{
- int pos = text.indexOf(QLatin1Char('\x9c'));
+ int pos = text.indexOf(s_variableLengthStringSeparator);
+ int length = -1;
if (pos != -1)
- length = (length < 0) ? pos : qMin(pos, length);
- else if (length < 0)
- length = text.length();
+ length = pos;
+ else
+ length = text.size();
if (length == 0)
return 0;
QStackTextEngine layout(text, QFont(d.data()));
+ layout.option = option;
layout.itemize();
return layout.width(0, length).toReal();
}
@@ -1581,7 +1466,7 @@ qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const
ch.
Some of the metrics are described in the image to the right. The
- central dark rectangles cover the logical width() of each
+ central dark rectangles cover the logical horizontalAdvance() of each
character. The outer pale rectangles cover the leftBearing() and
rightBearing() of each character. Notice that the bearings of "f"
in this particular font are both negative, while the bearings of
@@ -1632,7 +1517,7 @@ qreal QFontMetricsF::horizontalAdvance(QChar ch) const
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 width() method returns.
+ 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.
@@ -1643,11 +1528,11 @@ qreal QFontMetricsF::horizontalAdvance(QChar ch) const
The height of the bounding rectangle is at least as large as the
value returned height().
- \sa width(), height(), QPainter::boundingRect()
+ \sa horizontalAdvance(), height(), QPainter::boundingRect()
*/
QRectF QFontMetricsF::boundingRect(const QString &text) const
{
- int len = text.length();
+ int len = text.size();
if (len == 0)
return QRectF();
@@ -1659,6 +1544,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.size() == 0)
+ return QRectF();
+
+ QStackTextEngine layout(text, QFont(d.data()));
+ layout.option = option;
+ layout.itemize();
+ glyph_metrics_t gm = layout.boundingBox(0, text.size());
+ 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.
@@ -1669,7 +1590,7 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const
Note that the rectangle usually extends both above and below the
base line.
- \sa width()
+ \sa horizontalAdvance()
*/
QRectF QFontMetricsF::boundingRect(QChar ch) const
{
@@ -1694,7 +1615,9 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
Returns the bounding rectangle of the characters in the given \a text.
This is the set of pixels the text would cover if drawn when constrained
- to the bounding rectangle specified by \a rect.
+ to the bounding rectangle specified by \a rect. If \a rect is a reference
+ to a \nullptr object, e.g. when passing a default constructed QRectF, the
+ bounding rectangle will not constrain itself to the size.
The \a flags argument is the bitwise OR of the following flags:
\list
@@ -1746,7 +1669,7 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
fontHeight() and lineSpacing() are used to calculate the height,
rather than individual character heights.
- \sa width(), QPainter::boundingRect(), Qt::Alignment
+ \sa horizontalAdvance(), QPainter::boundingRect(), Qt::Alignment
*/
QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& text,
int tabStops, int *tabArray) const
@@ -1805,7 +1728,8 @@ QSizeF QFontMetricsF::size(int flags, const QString &text, int tabStops, int *ta
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 width() method returns.
+ 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.
@@ -1813,18 +1737,49 @@ 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 width(), height(), boundingRect()
+ \sa horizontalAdvance(), height(), boundingRect()
*/
QRectF QFontMetricsF::tightBoundingRect(const QString &text) const
{
- if (text.length() == 0)
- return QRect();
+ if (text.size() == 0)
+ return QRectF();
+
+ QStackTextEngine layout(text, QFont(d.data()));
+ layout.itemize();
+ glyph_metrics_t gm = layout.tightBoundingBox(0, text.size());
+ 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.size() == 0)
+ return QRectF();
QStackTextEngine layout(text, QFont(d.data()));
+ layout.option = option;
layout.itemize();
- glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
+ glyph_metrics_t gm = layout.tightBoundingBox(0, text.size());
return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
}
@@ -1854,13 +1809,13 @@ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, q
QString _text = text;
if (!(flags & Qt::TextLongestVariant)) {
int posA = 0;
- int posB = _text.indexOf(QLatin1Char('\x9c'));
+ int posB = _text.indexOf(s_variableLengthStringSeparator);
while (posB >= 0) {
QString portion = _text.mid(posA, posB - posA);
if (size(flags, portion).width() <= width)
return portion;
posA = posB + 1;
- posB = _text.indexOf(QLatin1Char('\x9c'), posA);
+ posB = _text.indexOf(s_variableLengthStringSeparator, posA);
}
_text = _text.mid(posA);
}