| /**************************************************************************** |
| ** |
| ** 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$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qfont.h" |
| #include "qpaintdevice.h" |
| #include "qfontmetrics.h" |
| |
| #include "qfont_p.h" |
| #include "qfontengine_p.h" |
| |
| QT_BEGIN_NAMESPACE |
| |
| |
| extern void qt_format_text(const QFont& font, const QRectF &_r, |
| int tf, const QString &text, QRectF *brect, |
| int tabStops, int *tabArray, int tabArrayLen, |
| QPainter *painter); |
| |
| /***************************************************************************** |
| QFontMetrics member functions |
| *****************************************************************************/ |
| |
| /*! |
| \class QFontMetrics |
| \reentrant |
| \inmodule QtGui |
| |
| \brief The QFontMetrics class provides font metrics information. |
| |
| \ingroup painting |
| \ingroup shared |
| |
| QFontMetrics functions calculate the size of characters and |
| strings for a given font. There are three ways you can create a |
| QFontMetrics object: |
| |
| \list 1 |
| \li Calling the QFontMetrics constructor with a QFont creates a |
| font metrics object for a screen-compatible font, i.e. the font |
| cannot be a printer font. If the font is changed |
| later, the font metrics object is \e not updated. |
| |
| (Note: If you use a printer font the values returned may be |
| inaccurate. Printer fonts are not always accessible so the nearest |
| screen font is used if a printer font is supplied.) |
| |
| \li QWidget::fontMetrics() returns the font metrics for a widget's |
| font. This is equivalent to QFontMetrics(widget->font()). If the |
| widget's font is changed later, the font metrics object is \e not |
| updated. |
| |
| \li QPainter::fontMetrics() returns the font metrics for a |
| painter's current font. If the painter's font is changed later, the |
| font metrics object is \e not updated. |
| \endlist |
| |
| Once created, the object provides functions to access the |
| individual metrics of the font, its characters, and for strings |
| rendered in the font. |
| |
| There are several functions that operate on the font: ascent(), |
| descent(), height(), leading() and lineSpacing() return the basic |
| size properties of the font. The underlinePos(), overlinePos(), |
| strikeOutPos() and lineWidth() functions, return the properties of |
| the line that underlines, overlines or strikes out the |
| characters. These functions are all fast. |
| |
| There are also some functions that operate on the set of glyphs in |
| the font: minLeftBearing(), minRightBearing() and maxWidth(). |
| These are by necessity slow, and we recommend avoiding them if |
| possible. |
| |
| 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 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. |
| |
| Example: |
| \snippet code/src_gui_text_qfontmetrics.cpp 0 |
| |
| \sa QFont, QFontInfo, QFontDatabase, {Character Map Example} |
| */ |
| |
| /*! |
| \fn QRect QFontMetrics::boundingRect(int x, int y, int width, int height, |
| int flags, const QString &text, int tabStops, int *tabArray) const |
| \overload |
| |
| Returns the bounding rectangle for the given \a text within the |
| rectangle specified by the \a x and \a y coordinates, \a width, and |
| \a height. |
| |
| If Qt::TextExpandTabs is set in \a flags and \a tabArray is |
| non-null, it specifies a 0-terminated sequence of pixel-positions |
| for tabs; otherwise, if \a tabStops is non-zero, it is used as the |
| tab spacing (in pixels). |
| */ |
| |
| /*! |
| Constructs a font metrics object for \a font. |
| |
| The font metrics will be compatible with the paintdevice used to |
| create \a font. |
| |
| The font metrics object holds the information for the font that is |
| passed in the constructor at the time it is created, and is not |
| updated if the font's attributes are changed later. |
| |
| Use QFontMetrics(const QFont &, QPaintDevice *) to get the font |
| metrics that are compatible with a certain paint device. |
| */ |
| QFontMetrics::QFontMetrics(const QFont &font) |
| : d(font.d) |
| { |
| } |
| |
| /*! |
| \since 5.13 |
| \fn QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice) |
| 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 \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. |
| |
| The font metrics object holds the information for the font that is |
| 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) { |
| d = new QFontPrivate(*font.d); |
| d->dpi = dpi; |
| } else { |
| d = font.d; |
| } |
| |
| } |
| |
| /*! |
| Constructs a copy of \a fm. |
| */ |
| QFontMetrics::QFontMetrics(const QFontMetrics &fm) |
| : d(fm.d) |
| { |
| } |
| |
| /*! |
| Destroys the font metrics object and frees all allocated |
| resources. |
| */ |
| QFontMetrics::~QFontMetrics() |
| { |
| } |
| |
| /*! |
| Assigns the font metrics \a fm. |
| */ |
| QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) |
| { |
| d = fm.d; |
| return *this; |
| } |
| |
| /*! |
| \fn QFontMetrics &QFontMetrics::operator=(QFontMetrics &&other) |
| |
| Move-assigns \a other to this QFontMetrics instance. |
| |
| \since 5.2 |
| */ |
| /*! |
| \fn QFontMetricsF &QFontMetricsF::operator=(QFontMetricsF &&other) |
| |
| Move-assigns \a other to this QFontMetricsF instance. |
| */ |
| |
| /*! |
| \fn void QFontMetrics::swap(QFontMetrics &other) |
| \since 5.0 |
| |
| Swaps this font metrics instance with \a other. This function is |
| very fast and never fails. |
| */ |
| |
| /*! |
| Returns \c true if \a other is equal to this object; otherwise |
| returns \c false. |
| |
| Two font metrics are considered equal if they were constructed |
| from the same QFont and the paint devices they were constructed |
| for are considered compatible. |
| |
| \sa operator!=() |
| */ |
| bool QFontMetrics::operator ==(const QFontMetrics &other) const |
| { |
| return d == other.d; |
| } |
| |
| /*! |
| \fn bool QFontMetrics::operator !=(const QFontMetrics &other) const |
| |
| Returns \c true if \a other is not equal to this object; otherwise returns \c false. |
| |
| Two font metrics are considered equal if they were constructed |
| from the same QFont and the paint devices they were constructed |
| for are considered compatible. |
| |
| \sa operator==() |
| */ |
| |
| /*! |
| Returns the ascent of the font. |
| |
| 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. |
| |
| \sa descent() |
| */ |
| int QFontMetrics::ascent() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->ascent()); |
| } |
| |
| /*! |
| Returns the cap height of the font. |
| |
| \since 5.8 |
| |
| The cap height of a font is the height of a capital letter above |
| the baseline. It specifically is the height of capital letters |
| that are flat - such as H or I - as opposed to round letters such |
| as O, or pointed letters like A, both of which may display overshoot. |
| |
| \sa ascent() |
| */ |
| int QFontMetrics::capHeight() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->capHeight()); |
| } |
| |
| /*! |
| Returns the descent of the font. |
| |
| 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. |
| |
| \sa ascent() |
| */ |
| int QFontMetrics::descent() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->descent()); |
| } |
| |
| /*! |
| Returns the height of the font. |
| |
| This is always equal to ascent()+descent(). |
| |
| \sa leading(), lineSpacing() |
| */ |
| int QFontMetrics::height() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->ascent()) + qRound(engine->descent()); |
| } |
| |
| /*! |
| Returns the leading of the font. |
| |
| This is the natural inter-line spacing. |
| |
| \sa height(), lineSpacing() |
| */ |
| int QFontMetrics::leading() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->leading()); |
| } |
| |
| /*! |
| Returns the distance from one base line to the next. |
| |
| This value is always equal to leading()+height(). |
| |
| \sa height(), leading() |
| */ |
| int QFontMetrics::lineSpacing() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent()); |
| } |
| |
| /*! |
| Returns the minimum left bearing of the font. |
| |
| This is the smallest leftBearing(char) of all characters in the |
| font. |
| |
| Note that this function can be very slow if the font is large. |
| |
| \sa minRightBearing(), leftBearing() |
| */ |
| int QFontMetrics::minLeftBearing() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->minLeftBearing()); |
| } |
| |
| /*! |
| Returns the minimum right bearing of the font. |
| |
| This is the smallest rightBearing(char) of all characters in the |
| font. |
| |
| Note that this function can be very slow if the font is large. |
| |
| \sa minLeftBearing(), rightBearing() |
| */ |
| int QFontMetrics::minRightBearing() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->minRightBearing()); |
| } |
| |
| /*! |
| Returns the width of the widest character in the font. |
| */ |
| int QFontMetrics::maxWidth() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->maxCharWidth()); |
| } |
| |
| /*! |
| Returns the 'x' height of the font. This is often but not always |
| the same as the height of the character 'x'. |
| */ |
| int QFontMetrics::xHeight() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| if (d->capital == QFont::SmallCaps) |
| return qRound(d->smallCapsFontPrivate()->engineForScript(QChar::Script_Common)->ascent()); |
| return qRound(engine->xHeight()); |
| } |
| |
| /*! |
| \since 4.2 |
| |
| Returns the average width of glyphs in the font. |
| */ |
| int QFontMetrics::averageCharWidth() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->averageCharWidth()); |
| } |
| |
| /*! |
| Returns \c true if character \a ch is a valid character in the font; |
| otherwise returns \c false. |
| */ |
| bool QFontMetrics::inFont(QChar ch) const |
| { |
| return inFontUcs4(ch.unicode()); |
| } |
| |
| /*! |
| Returns \c true if the character \a ucs4 encoded in UCS-4/UTF-32 is a valid |
| character in the font; otherwise returns \c false. |
| */ |
| bool QFontMetrics::inFontUcs4(uint ucs4) const |
| { |
| const int script = QChar::script(ucs4); |
| QFontEngine *engine = d->engineForScript(script); |
| Q_ASSERT(engine != nullptr); |
| if (engine->type() == QFontEngine::Box) |
| return false; |
| return engine->canRender(ucs4); |
| } |
| |
| /*! |
| Returns the left bearing of character \a ch in the font. |
| |
| The left bearing is the right-ward distance of the left-most pixel |
| of the character from the logical origin of the character. This |
| value is negative if the pixels of the character extend to the |
| left of the logical origin. |
| |
| See horizontalAdvance() for a graphical description of this metric. |
| |
| \sa rightBearing(), minLeftBearing(), horizontalAdvance() |
| */ |
| int QFontMetrics::leftBearing(QChar ch) const |
| { |
| const int script = ch.script(); |
| QFontEngine *engine; |
| if (d->capital == QFont::SmallCaps && ch.isLower()) |
| engine = d->smallCapsFontPrivate()->engineForScript(script); |
| else |
| engine = d->engineForScript(script); |
| Q_ASSERT(engine != nullptr); |
| if (engine->type() == QFontEngine::Box) |
| return 0; |
| |
| d->alterCharForCapitalization(ch); |
| |
| glyph_t glyph = engine->glyphIndex(ch.unicode()); |
| |
| qreal lb; |
| engine->getGlyphBearings(glyph, &lb); |
| return qRound(lb); |
| } |
| |
| /*! |
| Returns the right bearing of character \a ch in the font. |
| |
| 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 horizontalAdvance() of the character. |
| |
| See horizontalAdvance() for a graphical description of this metric. |
| |
| \sa leftBearing(), minRightBearing(), horizontalAdvance() |
| */ |
| int QFontMetrics::rightBearing(QChar ch) const |
| { |
| const int script = ch.script(); |
| QFontEngine *engine; |
| if (d->capital == QFont::SmallCaps && ch.isLower()) |
| engine = d->smallCapsFontPrivate()->engineForScript(script); |
| else |
| engine = d->engineForScript(script); |
| Q_ASSERT(engine != nullptr); |
| if (engine->type() == QFontEngine::Box) |
| return 0; |
| |
| d->alterCharForCapitalization(ch); |
| |
| glyph_t glyph = engine->glyphIndex(ch.unicode()); |
| |
| qreal rb; |
| engine->getGlyphBearings(glyph, nullptr, &rb); |
| return qRound(rb); |
| } |
| |
| #if QT_DEPRECATED_SINCE(5, 11) |
| /*! |
| Returns the width in pixels of the first \a len characters of \a |
| text. If \a len is negative (the default), the entire string is |
| used. |
| |
| 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. |
| |
| \deprecated in Qt 5.11. Use horizontalAdvance() instead. |
| |
| \sa boundingRect(), horizontalAdvance() |
| */ |
| 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 |
| { |
| #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); |
| } |
| #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. |
| |
| \sa boundingRect(), horizontalAdvance() |
| */ |
| int QFontMetrics::width(QChar ch) const |
| { |
| return horizontalAdvance(ch); |
| } |
| #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. |
| |
| This is the distance appropriate for drawing a subsequent character |
| after \a text. |
| |
| \since 5.11 |
| |
| \sa boundingRect() |
| */ |
| int QFontMetrics::horizontalAdvance(const QString &text, int len) const |
| { |
| 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; |
| |
| QStackTextEngine layout(text, QFont(d.data())); |
| return qRound(layout.width(0, len)); |
| } |
| |
| /*! |
| \overload |
| |
| \image bearings.png Bearings |
| |
| Returns the horizontal advance 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. The |
| 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 |
| "o" are both positive. |
| |
| \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. |
| |
| \since 5.11 |
| |
| \sa boundingRect() |
| */ |
| int QFontMetrics::horizontalAdvance(QChar ch) const |
| { |
| if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) |
| return 0; |
| |
| const int script = ch.script(); |
| 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, { }); |
| |
| return qRound(advance); |
| } |
| |
| #if QT_VERSION < QT_VERSION_CHECK(6,0,0) |
| /*! \obsolete |
| |
| Returns the width of the character at position \a pos in the |
| string \a text. |
| |
| 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). |
| |
| This function also takes non spacing marks and ligatures into |
| account. |
| */ |
| int QFontMetrics::charWidth(const QString &text, int pos) const |
| { |
| int width = 0; |
| if (pos < 0 || pos > (int)text.length()) |
| return width; |
| |
| 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; |
| } |
| #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). |
| |
| 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(). |
| |
| \sa horizontalAdvance(), height(), QPainter::boundingRect(), |
| tightBoundingRect() |
| */ |
| QRect QFontMetrics::boundingRect(const QString &text) const |
| { |
| if (text.length() == 0) |
| return QRect(); |
| |
| QStackTextEngine layout(text, QFont(d.data())); |
| 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. |
| |
| Note that the bounding rectangle may extend to the left of (0, 0) |
| (e.g., for italicized fonts), and that the text output may cover \e |
| all pixels in the bounding rectangle. For a space character the rectangle |
| will usually be empty. |
| |
| Note that the rectangle usually extends both above and below the |
| base line. |
| |
| \warning The width of the returned rectangle is not the advance width |
| of the character. Use boundingRect(const QString &) or horizontalAdvance() instead. |
| |
| \sa horizontalAdvance() |
| */ |
| QRect QFontMetrics::boundingRect(QChar ch) const |
| { |
| const int script = ch.script(); |
| 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()); |
| |
| glyph_metrics_t gm = engine->boundingBox(glyph); |
| return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); |
| } |
| |
| /*! |
| \overload |
| |
| Returns the bounding rectangle of the characters in the string |
| specified by \a text, which is the set of pixels the text would |
| cover if drawn at (0, 0). The drawing, and hence the bounding |
| rectangle, is constrained to the rectangle \a rect. |
| |
| The \a flags argument is the bitwise OR of the following flags: |
| \list |
| \li Qt::AlignLeft aligns to the left border, except for |
| Arabic and Hebrew where it aligns to the right. |
| \li Qt::AlignRight aligns to the right border, except for |
| Arabic and Hebrew where it aligns to the left. |
| \li Qt::AlignJustify produces justified text. |
| \li Qt::AlignHCenter aligns horizontally centered. |
| \li Qt::AlignTop aligns to the top border. |
| \li Qt::AlignBottom aligns to the bottom border. |
| \li Qt::AlignVCenter aligns vertically centered |
| \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter}) |
| \li Qt::TextSingleLine ignores newline characters in the text. |
| \li Qt::TextExpandTabs expands tabs (see below) |
| \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. |
| \li Qt::TextWordWrap breaks the text to fit the rectangle. |
| \endlist |
| |
| Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical |
| alignment defaults to Qt::AlignTop. |
| |
| If several of the horizontal or several of the vertical alignment |
| flags are set, the resulting alignment is undefined. |
| |
| If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is |
| non-null, it specifies a 0-terminated sequence of pixel-positions |
| for tabs; otherwise if \a tabStops is non-zero, it is used as the |
| tab spacing (in pixels). |
| |
| Note that the bounding rectangle may extend to the left of (0, 0), |
| e.g. for italicized fonts, and that the text output may cover \e |
| all pixels in the bounding rectangle. |
| |
| Newline characters are processed as linebreaks. |
| |
| Despite the different actual character heights, the heights of the |
| bounding rectangles of "Yes" and "yes" are the same. |
| |
| The bounding rectangle returned by this function is somewhat larger |
| than that calculated by the simpler boundingRect() function. This |
| function uses the \l{minLeftBearing()}{maximum left} and |
| \l{minRightBearing()}{right} font bearings as is |
| necessary for multi-line text to align correctly. Also, |
| fontHeight() and lineSpacing() are used to calculate the height, |
| rather than individual character heights. |
| |
| \sa horizontalAdvance(), QPainter::boundingRect(), Qt::Alignment |
| */ |
| QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &text, int tabStops, |
| int *tabArray) const |
| { |
| int tabArrayLen = 0; |
| if (tabArray) |
| while (tabArray[tabArrayLen]) |
| tabArrayLen++; |
| |
| QRectF rb; |
| QRectF rr(rect); |
| qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, |
| tabArrayLen, nullptr); |
| |
| return rb.toAlignedRect(); |
| } |
| |
| /*! |
| Returns the size in pixels of \a text. |
| |
| The \a flags argument is the bitwise OR of the following flags: |
| \list |
| \li Qt::TextSingleLine ignores newline characters. |
| \li Qt::TextExpandTabs expands tabs (see below) |
| \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. |
| \li Qt::TextWordWrap breaks the text to fit the rectangle. |
| \endlist |
| |
| If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is |
| non-null, it specifies a 0-terminated sequence of pixel-positions |
| for tabs; otherwise if \a tabStops is non-zero, it is used as the |
| tab spacing (in pixels). |
| |
| Newline characters are processed as linebreaks. |
| |
| Despite the different actual character heights, the heights of the |
| bounding rectangles of "Yes" and "yes" are the same. |
| |
| \sa boundingRect() |
| */ |
| QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabArray) const |
| { |
| return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); |
| } |
| |
| /*! |
| \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, |
| 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. |
| |
| \warning Calling this method is very slow on Windows. |
| |
| \sa horizontalAdvance(), height(), boundingRect() |
| */ |
| QRect QFontMetrics::tightBoundingRect(const QString &text) const |
| { |
| if (text.length() == 0) |
| return QRect(); |
| |
| QStackTextEngine layout(text, QFont(d.data())); |
| 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 |
| |
| If the string \a text is wider than \a width, returns an elided |
| version of the string (i.e., a string with "..." in it). |
| Otherwise, returns the original string. |
| |
| The \a mode parameter specifies whether the text is elided on the |
| left (e.g., "...tech"), in the middle (e.g., "Tr...ch"), or on |
| the right (e.g., "Trol..."). |
| |
| The \a width is specified in pixels, not characters. |
| |
| The \a flags argument is optional and currently only supports |
| Qt::TextShowMnemonic as value. |
| |
| The elide mark follows the \l{Qt::LayoutDirection}{layoutdirection}. |
| For example, it will be on the right side of the text for right-to-left |
| layouts if the \a mode is \c{Qt::ElideLeft}, and on the left side of the |
| text if the \a mode is \c{Qt::ElideRight}. |
| |
| */ |
| QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const |
| { |
| QString _text = text; |
| if (!(flags & Qt::TextLongestVariant)) { |
| int posA = 0; |
| int posB = _text.indexOf(QLatin1Char('\x9c')); |
| 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); |
| } |
| _text = _text.mid(posA); |
| } |
| QStackTextEngine engine(_text, QFont(d.data())); |
| return engine.elidedText(mode, width, flags); |
| } |
| |
| /*! |
| Returns the distance from the base line to where an underscore |
| should be drawn. |
| |
| \sa overlinePos(), strikeOutPos(), lineWidth() |
| */ |
| int QFontMetrics::underlinePos() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->underlinePosition()); |
| } |
| |
| /*! |
| Returns the distance from the base line to where an overline |
| should be drawn. |
| |
| \sa underlinePos(), strikeOutPos(), lineWidth() |
| */ |
| int QFontMetrics::overlinePos() const |
| { |
| return ascent() + 1; |
| } |
| |
| /*! |
| Returns the distance from the base line to where the strikeout |
| line should be drawn. |
| |
| \sa underlinePos(), overlinePos(), lineWidth() |
| */ |
| int QFontMetrics::strikeOutPos() const |
| { |
| int pos = ascent() / 3; |
| return pos > 0 ? pos : 1; |
| } |
| |
| /*! |
| Returns the width of the underline and strikeout lines, adjusted |
| for the point size of the font. |
| |
| \sa underlinePos(), overlinePos(), strikeOutPos() |
| */ |
| int QFontMetrics::lineWidth() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return qRound(engine->lineThickness()); |
| } |
| |
| /*! |
| \since 5.14 |
| |
| Returns the font DPI. |
| */ |
| qreal QFontMetrics::fontDpi() const |
| { |
| return d->dpi; |
| } |
| |
| /***************************************************************************** |
| QFontMetricsF member functions |
| *****************************************************************************/ |
| |
| /*! |
| \class QFontMetricsF |
| \reentrant |
| \inmodule QtGui |
| |
| \brief The QFontMetricsF class provides font metrics information. |
| |
| \ingroup painting |
| \ingroup shared |
| |
| QFontMetricsF functions calculate the size of characters and |
| strings for a given font. You can construct a QFontMetricsF object |
| with an existing QFont to obtain metrics for that font. If the |
| font is changed later, the font metrics object is \e not updated. |
| |
| Once created, the object provides functions to access the |
| individual metrics of the font, its characters, and for strings |
| rendered in the font. |
| |
| There are several functions that operate on the font: ascent(), |
| descent(), height(), leading() and lineSpacing() return the basic |
| size properties of the font. The underlinePos(), overlinePos(), |
| strikeOutPos() and lineWidth() functions, return the properties of |
| the line that underlines, overlines or strikes out the |
| characters. These functions are all fast. |
| |
| There are also some functions that operate on the set of glyphs in |
| the font: minLeftBearing(), minRightBearing() and maxWidth(). |
| These are by necessity slow, and we recommend avoiding them if |
| possible. |
| |
| 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 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. |
| |
| Example: |
| \snippet code/src_gui_text_qfontmetrics.cpp 1 |
| |
| \sa QFont, QFontInfo, QFontDatabase |
| */ |
| |
| /*! |
| \since 4.2 |
| |
| Constructs a font metrics object with floating point precision |
| from the given \a fontMetrics object. |
| */ |
| QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) |
| : d(fontMetrics.d) |
| { |
| } |
| |
| /*! |
| \since 4.2 |
| |
| Assigns \a other to this object. |
| */ |
| QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) |
| { |
| d = other.d; |
| return *this; |
| } |
| |
| /*! |
| \fn void QFontMetricsF::swap(QFontMetricsF &other) |
| \since 5.0 |
| |
| Swaps this font metrics instance with \a other. This function is |
| very fast and never fails. |
| */ |
| |
| |
| |
| /*! |
| Constructs a font metrics object for \a font. |
| |
| The font metrics will be compatible with the paintdevice used to |
| create \a font. |
| |
| The font metrics object holds the information for the font that is |
| passed in the constructor at the time it is created, and is not |
| updated if the font's attributes are changed later. |
| |
| Use QFontMetricsF(const QFont &, QPaintDevice *) to get the font |
| metrics that are compatible with a certain paint device. |
| */ |
| QFontMetricsF::QFontMetricsF(const QFont &font) |
| : d(font.d) |
| { |
| } |
| |
| /*! |
| \fn QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice) |
| \since 5.13 |
| 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 \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. |
| |
| The font metrics object holds the information for the font that is |
| 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) { |
| d = new QFontPrivate(*font.d); |
| d->dpi = dpi; |
| } else { |
| d = font.d; |
| } |
| |
| } |
| |
| /*! |
| Constructs a copy of \a fm. |
| */ |
| QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) |
| : d(fm.d) |
| { |
| } |
| |
| /*! |
| Destroys the font metrics object and frees all allocated |
| resources. |
| */ |
| QFontMetricsF::~QFontMetricsF() |
| { |
| } |
| |
| /*! |
| Assigns the font metrics \a fm to this font metrics object. |
| */ |
| QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) |
| { |
| d = fm.d; |
| return *this; |
| } |
| |
| /*! |
| Returns \c true if the font metrics are equal to the \a other font |
| metrics; otherwise returns \c false. |
| |
| Two font metrics are considered equal if they were constructed from the |
| same QFont and the paint devices they were constructed for are |
| considered to be compatible. |
| */ |
| bool QFontMetricsF::operator ==(const QFontMetricsF &other) const |
| { |
| return d == other.d; |
| } |
| |
| /*! |
| \fn bool QFontMetricsF::operator !=(const QFontMetricsF &other) const |
| \overload |
| |
| Returns \c true if the font metrics are not equal to the \a other font |
| metrics; otherwise returns \c false. |
| |
| \sa operator==() |
| */ |
| |
| /*! |
| Returns the ascent of the font. |
| |
| 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. |
| |
| \sa descent() |
| */ |
| qreal QFontMetricsF::ascent() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->ascent().toReal(); |
| } |
| |
| /*! |
| Returns the cap height of the font. |
| |
| \since 5.8 |
| |
| The cap height of a font is the height of a capital letter above |
| the baseline. It specifically is the height of capital letters |
| that are flat - such as H or I - as opposed to round letters such |
| as O, or pointed letters like A, both of which may display overshoot. |
| |
| \sa ascent() |
| */ |
| qreal QFontMetricsF::capHeight() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->capHeight().toReal(); |
| } |
| |
| /*! |
| Returns the descent of the font. |
| |
| 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. |
| |
| \sa ascent() |
| */ |
| qreal QFontMetricsF::descent() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->descent().toReal(); |
| } |
| |
| /*! |
| Returns the height of the font. |
| |
| This is always equal to ascent()+descent(). |
| |
| \sa leading(), lineSpacing() |
| */ |
| qreal QFontMetricsF::height() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| |
| return (engine->ascent() + engine->descent()).toReal(); |
| } |
| |
| /*! |
| Returns the leading of the font. |
| |
| This is the natural inter-line spacing. |
| |
| \sa height(), lineSpacing() |
| */ |
| qreal QFontMetricsF::leading() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->leading().toReal(); |
| } |
| |
| /*! |
| Returns the distance from one base line to the next. |
| |
| This value is always equal to leading()+height(). |
| |
| \sa height(), leading() |
| */ |
| qreal QFontMetricsF::lineSpacing() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return (engine->leading() + engine->ascent() + engine->descent()).toReal(); |
| } |
| |
| /*! |
| Returns the minimum left bearing of the font. |
| |
| This is the smallest leftBearing(char) of all characters in the |
| font. |
| |
| Note that this function can be very slow if the font is large. |
| |
| \sa minRightBearing(), leftBearing() |
| */ |
| qreal QFontMetricsF::minLeftBearing() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->minLeftBearing(); |
| } |
| |
| /*! |
| Returns the minimum right bearing of the font. |
| |
| This is the smallest rightBearing(char) of all characters in the |
| font. |
| |
| Note that this function can be very slow if the font is large. |
| |
| \sa minLeftBearing(), rightBearing() |
| */ |
| qreal QFontMetricsF::minRightBearing() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->minRightBearing(); |
| } |
| |
| /*! |
| Returns the width of the widest character in the font. |
| */ |
| qreal QFontMetricsF::maxWidth() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->maxCharWidth(); |
| } |
| |
| /*! |
| Returns the 'x' height of the font. This is often but not always |
| the same as the height of the character 'x'. |
| */ |
| qreal QFontMetricsF::xHeight() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| if (d->capital == QFont::SmallCaps) |
| return d->smallCapsFontPrivate()->engineForScript(QChar::Script_Common)->ascent().toReal(); |
| return engine->xHeight().toReal(); |
| } |
| |
| /*! |
| \since 4.2 |
| |
| Returns the average width of glyphs in the font. |
| */ |
| qreal QFontMetricsF::averageCharWidth() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->averageCharWidth().toReal(); |
| } |
| |
| /*! |
| Returns \c true if character \a ch is a valid character in the font; |
| otherwise returns \c false. |
| */ |
| bool QFontMetricsF::inFont(QChar ch) const |
| { |
| return inFontUcs4(ch.unicode()); |
| } |
| |
| /*! |
| \fn bool QFontMetricsF::inFontUcs4(uint ch) const |
| |
| Returns \c true if the character given by \a ch, encoded in UCS-4/UTF-32, |
| is a valid character in the font; otherwise returns \c false. |
| */ |
| bool QFontMetricsF::inFontUcs4(uint ucs4) const |
| { |
| const int script = QChar::script(ucs4); |
| QFontEngine *engine = d->engineForScript(script); |
| Q_ASSERT(engine != nullptr); |
| if (engine->type() == QFontEngine::Box) |
| return false; |
| return engine->canRender(ucs4); |
| } |
| |
| /*! |
| Returns the left bearing of character \a ch in the font. |
| |
| The left bearing is the right-ward distance of the left-most pixel |
| of the character from the logical origin of the character. This |
| value is negative if the pixels of the character extend to the |
| left of the logical origin. |
| |
| See horizontalAdvance() for a graphical description of this metric. |
| |
| \sa rightBearing(), minLeftBearing(), horizontalAdvance() |
| */ |
| qreal QFontMetricsF::leftBearing(QChar ch) const |
| { |
| const int script = ch.script(); |
| QFontEngine *engine; |
| if (d->capital == QFont::SmallCaps && ch.isLower()) |
| engine = d->smallCapsFontPrivate()->engineForScript(script); |
| else |
| engine = d->engineForScript(script); |
| Q_ASSERT(engine != nullptr); |
| if (engine->type() == QFontEngine::Box) |
| return 0; |
| |
| d->alterCharForCapitalization(ch); |
| |
| glyph_t glyph = engine->glyphIndex(ch.unicode()); |
| |
| qreal lb; |
| engine->getGlyphBearings(glyph, &lb); |
| return lb; |
| } |
| |
| /*! |
| Returns the right bearing of character \a ch in the font. |
| |
| 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 horizontalAdvance() of the character. |
| |
| See horizontalAdvance() for a graphical description of this metric. |
| |
| \sa leftBearing(), minRightBearing(), horizontalAdvance() |
| */ |
| qreal QFontMetricsF::rightBearing(QChar ch) const |
| { |
| const int script = ch.script(); |
| QFontEngine *engine; |
| if (d->capital == QFont::SmallCaps && ch.isLower()) |
| engine = d->smallCapsFontPrivate()->engineForScript(script); |
| else |
| engine = d->engineForScript(script); |
| Q_ASSERT(engine != nullptr); |
| if (engine->type() == QFontEngine::Box) |
| return 0; |
| |
| d->alterCharForCapitalization(ch); |
| |
| glyph_t glyph = engine->glyphIndex(ch.unicode()); |
| |
| qreal rb; |
| engine->getGlyphBearings(glyph, nullptr, &rb); |
| return rb; |
| |
| } |
| |
| #if QT_DEPRECATED_SINCE(5, 11) |
| /*! |
| Returns the width in pixels of the characters in the given \a text. |
| |
| 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. |
| |
| \deprecated in Qt 5.11. Use horizontalAdvance() instead. |
| |
| \sa boundingRect(), horizontalAdvance() |
| */ |
| qreal QFontMetricsF::width(const QString &text) 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. |
| |
| \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. |
| |
| \sa boundingRect(), horizontalAdvance() |
| */ |
| qreal QFontMetricsF::width(QChar ch) const |
| { |
| return horizontalAdvance(ch); |
| } |
| #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. |
| |
| The advance is the distance appropriate for drawing a subsequent |
| character after \a text. |
| |
| \since 5.11 |
| |
| \sa boundingRect() |
| */ |
| qreal QFontMetricsF::horizontalAdvance(const QString &text, int length) const |
| { |
| int pos = text.indexOf(QLatin1Char('\x9c')); |
| 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.itemize(); |
| return layout.width(0, length).toReal(); |
| } |
| |
| /*! |
| \overload |
| |
| \image bearings.png Bearings |
| |
| Returns the horizontal advance 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 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 |
| "o" are both positive. |
| |
| \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. |
| |
| \since 5.11 |
| |
| \sa boundingRect() |
| */ |
| qreal QFontMetricsF::horizontalAdvance(QChar ch) const |
| { |
| if (ch.category() == QChar::Mark_NonSpacing) |
| return 0.; |
| |
| const int script = ch.script(); |
| 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, { }); |
| |
| return advance.toReal(); |
| } |
| |
| |
| /*! |
| 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). |
| |
| 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(). |
| |
| \sa horizontalAdvance(), height(), QPainter::boundingRect() |
| */ |
| QRectF QFontMetricsF::boundingRect(const QString &text) const |
| { |
| int len = text.length(); |
| if (len == 0) |
| return QRectF(); |
| |
| QStackTextEngine layout(text, QFont(d.data())); |
| layout.itemize(); |
| glyph_metrics_t gm = layout.boundingBox(0, len); |
| 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. |
| |
| Note that the bounding rectangle may extend to the left of (0, 0), |
| e.g. for italicized fonts, and that the text output may cover \e |
| all pixels in the bounding rectangle. |
| |
| Note that the rectangle usually extends both above and below the |
| base line. |
| |
| \sa horizontalAdvance() |
| */ |
| QRectF QFontMetricsF::boundingRect(QChar ch) const |
| { |
| const int script = ch.script(); |
| 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()); |
| |
| glyph_metrics_t gm = engine->boundingBox(glyph); |
| return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal()); |
| } |
| |
| /*! |
| \overload |
| |
| 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. |
| |
| The \a flags argument is the bitwise OR of the following flags: |
| \list |
| \li Qt::AlignLeft aligns to the left border, except for |
| Arabic and Hebrew where it aligns to the right. |
| \li Qt::AlignRight aligns to the right border, except for |
| Arabic and Hebrew where it aligns to the left. |
| \li Qt::AlignJustify produces justified text. |
| \li Qt::AlignHCenter aligns horizontally centered. |
| \li Qt::AlignTop aligns to the top border. |
| \li Qt::AlignBottom aligns to the bottom border. |
| \li Qt::AlignVCenter aligns vertically centered |
| \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter}) |
| \li Qt::TextSingleLine ignores newline characters in the text. |
| \li Qt::TextExpandTabs expands tabs (see below) |
| \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. |
| \li Qt::TextWordWrap breaks the text to fit the rectangle. |
| \endlist |
| |
| Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical |
| alignment defaults to Qt::AlignTop. |
| |
| If several of the horizontal or several of the vertical alignment |
| flags are set, the resulting alignment is undefined. |
| |
| These flags are defined in \l{Qt::AlignmentFlag}. |
| |
| If Qt::TextExpandTabs is set in \a flags, the following behavior is |
| used to interpret tab characters in the text: |
| \list |
| \li If \a tabArray is non-null, it specifies a 0-terminated sequence of |
| pixel-positions for tabs in the text. |
| \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels). |
| \endlist |
| |
| Note that the bounding rectangle may extend to the left of (0, 0), |
| e.g. for italicized fonts. |
| |
| Newline characters are processed as line breaks. |
| |
| Despite the different actual character heights, the heights of the |
| bounding rectangles of "Yes" and "yes" are the same. |
| |
| The bounding rectangle returned by this function is somewhat larger |
| than that calculated by the simpler boundingRect() function. This |
| function uses the \l{minLeftBearing()}{maximum left} and |
| \l{minRightBearing()}{right} font bearings as is |
| necessary for multi-line text to align correctly. Also, |
| fontHeight() and lineSpacing() are used to calculate the height, |
| rather than individual character heights. |
| |
| \sa horizontalAdvance(), QPainter::boundingRect(), Qt::Alignment |
| */ |
| QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& text, |
| int tabStops, int *tabArray) const |
| { |
| int tabArrayLen = 0; |
| if (tabArray) |
| while (tabArray[tabArrayLen]) |
| tabArrayLen++; |
| |
| QRectF rb; |
| qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, |
| tabArrayLen, nullptr); |
| return rb; |
| } |
| |
| /*! |
| Returns the size in pixels of the characters in the given \a text. |
| |
| The \a flags argument is the bitwise OR of the following flags: |
| \list |
| \li Qt::TextSingleLine ignores newline characters. |
| \li Qt::TextExpandTabs expands tabs (see below) |
| \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. |
| \li Qt::TextWordWrap breaks the text to fit the rectangle. |
| \endlist |
| |
| These flags are defined in the \l{Qt::TextFlag} enum. |
| |
| If Qt::TextExpandTabs is set in \a flags, the following behavior is |
| used to interpret tab characters in the text: |
| \list |
| \li If \a tabArray is non-null, it specifies a 0-terminated sequence of |
| pixel-positions for tabs in the text. |
| \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels). |
| \endlist |
| |
| Newline characters are processed as line breaks. |
| |
| Note: Despite the different actual character heights, the heights of the |
| bounding rectangles of "Yes" and "yes" are the same. |
| |
| \sa boundingRect() |
| */ |
| QSizeF QFontMetricsF::size(int flags, const QString &text, int tabStops, int *tabArray) const |
| { |
| return boundingRect(QRectF(), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); |
| } |
| |
| /*! |
| \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, |
| 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. |
| |
| \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(); |
| |
| 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()); |
| } |
| |
| /*! |
| \since 4.2 |
| |
| If the string \a text is wider than \a width, returns an elided |
| version of the string (i.e., a string with "..." in it). |
| Otherwise, returns the original string. |
| |
| The \a mode parameter specifies whether the text is elided on the |
| left (for example, "...tech"), in the middle (for example, "Tr...ch"), or |
| on the right (for example, "Trol..."). |
| |
| The \a width is specified in pixels, not characters. |
| |
| The \a flags argument is optional and currently only supports |
| Qt::TextShowMnemonic as value. |
| |
| The elide mark follows the \l{Qt::LayoutDirection}{layoutdirection}. |
| For example, it will be on the right side of the text for right-to-left |
| layouts if the \a mode is \c{Qt::ElideLeft}, and on the left side of the |
| text if the \a mode is \c{Qt::ElideRight}. |
| */ |
| QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const |
| { |
| QString _text = text; |
| if (!(flags & Qt::TextLongestVariant)) { |
| int posA = 0; |
| int posB = _text.indexOf(QLatin1Char('\x9c')); |
| 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); |
| } |
| _text = _text.mid(posA); |
| } |
| QStackTextEngine engine(_text, QFont(d.data())); |
| return engine.elidedText(mode, QFixed::fromReal(width), flags); |
| } |
| |
| /*! |
| Returns the distance from the base line to where an underscore |
| should be drawn. |
| |
| \sa overlinePos(), strikeOutPos(), lineWidth() |
| */ |
| qreal QFontMetricsF::underlinePos() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->underlinePosition().toReal(); |
| } |
| |
| /*! |
| Returns the distance from the base line to where an overline |
| should be drawn. |
| |
| \sa underlinePos(), strikeOutPos(), lineWidth() |
| */ |
| qreal QFontMetricsF::overlinePos() const |
| { |
| return ascent() + 1; |
| } |
| |
| /*! |
| Returns the distance from the base line to where the strikeout |
| line should be drawn. |
| |
| \sa underlinePos(), overlinePos(), lineWidth() |
| */ |
| qreal QFontMetricsF::strikeOutPos() const |
| { |
| return ascent() / 3.; |
| } |
| |
| /*! |
| Returns the width of the underline and strikeout lines, adjusted |
| for the point size of the font. |
| |
| \sa underlinePos(), overlinePos(), strikeOutPos() |
| */ |
| qreal QFontMetricsF::lineWidth() const |
| { |
| QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
| Q_ASSERT(engine != nullptr); |
| return engine->lineThickness().toReal(); |
| } |
| |
| /*! |
| \since 5.14 |
| |
| Returns the font DPI. |
| */ |
| qreal QFontMetricsF::fontDpi() const |
| { |
| return d->dpi; |
| } |
| |
| QT_END_NAMESPACE |