diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/gui/text/qfontmetrics.cpp | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'src/gui/text/qfontmetrics.cpp')
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 1739 |
1 files changed, 1739 insertions, 0 deletions
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp new file mode 100644 index 0000000..88d0610 --- /dev/null +++ b/src/gui/text/qfontmetrics.cpp @@ -0,0 +1,1739 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfont.h" +#include "qpaintdevice.h" +#include "qfontmetrics.h" + +#include "qfont_p.h" +#include "qfontengine_p.h" +#include <private/qunicodetables_p.h> + +#include <math.h> + +#ifdef Q_WS_X11 +#include "qx11info_x11.h" +#endif + +QT_BEGIN_NAMESPACE + +#ifdef Q_WS_X11 +extern const QX11Info *qt_x11Info(const QPaintDevice *pd); +#endif + +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); +extern int qt_defaultDpi(); + +/***************************************************************************** + QFontMetrics member functions + *****************************************************************************/ + +/*! + \class QFontMetrics + \reentrant + + \brief The QFontMetrics class provides font metrics information. + + \ingroup multimedia + \ingroup shared + \ingroup text + + 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 + \o 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.) + + \o 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. + + \o 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 width(), 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, + and size(), to return the size of that rectangle. + + Example: + \snippet doc/src/snippets/code/src_gui_text_qfontmetrics.cpp 0 + + \sa QFont, QFontInfo, QFontDatabase, QFontComboBox, {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) +{ + d->ref.ref(); +} + +/*! + 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, + ie. the metrics you get if you use the font for drawing text on a + \link QWidget widgets\endlink or \link QPixmap pixmaps\endlink, + 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. +*/ +QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) +{ + int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); +#ifdef Q_WS_X11 + const QX11Info *info = qt_x11Info(paintdevice); + int screen = info ? info->screen() : 0; +#else + const int screen = 0; +#endif + if (font.d->dpi != dpi || font.d->screen != screen ) { + d = new QFontPrivate(*font.d); + d->dpi = dpi; + d->screen = screen; + } else { + d = font.d; + d->ref.ref(); + } + +} + +/*! + Constructs a copy of \a fm. +*/ +QFontMetrics::QFontMetrics(const QFontMetrics &fm) + : d(fm.d) +{ d->ref.ref(); } + +/*! + Destroys the font metrics object and frees all allocated + resources. +*/ +QFontMetrics::~QFontMetrics() +{ + if (!d->ref.deref()) + delete d; +} + +/*! + Assigns the font metrics \a fm. +*/ +QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) +{ + qAtomicAssign(d, fm.d); + return *this; +} + +/*! + \overload + Returns true if \a other is equal to this object; otherwise + returns 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; +} + +/*! + Returns true if \a other is equal to this object; otherwise + returns 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) +{ + return d == other.d; +} + +/*! + \fn bool QFontMetrics::operator!=(const QFontMetrics &other) + + Returns true if \a other is not equal to this object; otherwise returns 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==() +*/ + +/*! + \fn bool QFontMetrics::operator !=(const QFontMetrics &other) const + + Returns true if \a other is not equal to this object; otherwise returns 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->ascent()); +} + + +/*! + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->descent()); +} + +/*! + Returns the height of the font. + + This is always equal to ascent()+descent()+1 (the 1 is for the + base line). + + \sa leading(), lineSpacing() +*/ +int QFontMetrics::height() const +{ + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->ascent() + engine->descent()) + 1; +} + +/*! + Returns the leading of the font. + + This is the natural inter-line spacing. + + \sa height(), lineSpacing() +*/ +int QFontMetrics::leading() const +{ + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->leading() + engine->ascent() + engine->descent()) + 1; +} + +/*! + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->minRightBearing()); +} + +/*! + Returns the width of the widest character in the font. +*/ +int QFontMetrics::maxWidth() const +{ + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + if (d->capital == QFont::SmallCaps) + return qRound(d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->averageCharWidth()); +} + +/*! + Returns true if character \a ch is a valid character in the font; + otherwise returns false. +*/ +bool QFontMetrics::inFont(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + if (engine->type() == QFontEngine::Box) + return false; + return engine->canRender(&ch, 1); +} + +/*! + 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 width(QChar) for a graphical description of this metric. + + \sa rightBearing(), minLeftBearing(), width() +*/ +int QFontMetrics::leftBearing(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + if (engine->type() == QFontEngine::Box) + return 0; + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<10> glyphs; + int nglyphs = 9; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + // ### can nglyphs != 1 happen at all? Not currently I think + glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]); + return qRound(gi.x); +} + +/*! + 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 width() of the character. + + See width() for a graphical description of this metric. + + \sa leftBearing(), minRightBearing(), width() +*/ +int QFontMetrics::rightBearing(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + if (engine->type() == QFontEngine::Box) + return 0; + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<10> glyphs; + int nglyphs = 9; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + // ### can nglyphs != 1 happen at all? Not currently I think + glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]); + return qRound(gi.xoff - gi.x - gi.width); +} + +/*! + 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. + + \sa boundingRect() +*/ +int QFontMetrics::width(const QString &text, int len) const +{ + if (len < 0) + len = text.length(); + if (len == 0) + return 0; + + QTextEngine layout(text, d); + layout.ignoreBidi = true; + return qRound(layout.width(0, len)); +} + +/*! + \overload + + \img 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. + + \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. Use charWidth() + instead if you aren't looking for the width of isolated + characters. + + \sa boundingRect(), charWidth() +*/ +int QFontMetrics::width(QChar ch) const +{ + if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) + return 0; + + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<8> glyphs; + int nglyphs = 7; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + return qRound(glyphs.advances_x[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 +{ + if (pos < 0 || pos > (int)text.length()) + return 0; + + QChar ch = text.unicode()[pos]; + const int script = QUnicodeTables::script(ch); + int width; + + if (script != QUnicodeTables::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); + QTextEngine layout(cstr, d); + layout.ignoreBidi = true; + layout.itemize(); + width = qRound(layout.width(pos-from, 1)); + } else if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) { + width = 0; + } else { + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<8> glyphs; + int nglyphs = 7; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + width = qRound(glyphs.advances_x[0]); + } + return width; +} + +/*! + 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 width() method returns. + + If you want to know the advance width of the string (to layout + a set of strings next to each other), use width() 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 width(), height(), QPainter::boundingRect(), tightBoundingRect() +*/ +QRect QFontMetrics::boundingRect(const QString &text) const +{ + if (text.length() == 0) + return QRect(); + + QTextEngine layout(text, d); + layout.ignoreBidi = true; + 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 width() instead. + + \sa width() +*/ +QRect QFontMetrics::boundingRect(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<10> glyphs; + int nglyphs = 9; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]); + 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 + \o Qt::AlignLeft aligns to the left border, except for + Arabic and Hebrew where it aligns to the right. + \o Qt::AlignRight aligns to the right border, except for + Arabic and Hebrew where it aligns to the left. + \o Qt::AlignJustify produces justified text. + \o Qt::AlignHCenter aligns horizontally centered. + \o Qt::AlignTop aligns to the top border. + \o Qt::AlignBottom aligns to the bottom border. + \o Qt::AlignVCenter aligns vertically centered + \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter}) + \o Qt::TextSingleLine ignores newline characters in the text. + \o Qt::TextExpandTabs expands tabs (see below) + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o 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 \link minLeftBearing() maximum left \endlink and + \link minRightBearing() right \endlink 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 width(), 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), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + tabArrayLen, 0); + + return rb.toAlignedRect(); +} + +/*! + Returns the size in pixels of \a text. + + The \a flags argument is the bitwise OR of the following flags: + \list + \o Qt::TextSingleLine ignores newline characters. + \o Qt::TextExpandTabs expands tabs (see below) + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o Qt::TextWordBreak 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, 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 width() method returns. + + If you want to know the advance width of the string (to layout + a set of strings next to each other), use width() instead. + + Newline characters are processed as normal characters, \e not as + linebreaks. + + \warning Calling this method is very slow on Windows. + + \sa width(), height(), boundingRect() +*/ +QRect QFontMetrics::tightBoundingRect(const QString &text) const +{ + if (text.length() == 0) + return QRect(); + + QTextEngine layout(text, d); + layout.ignoreBidi = true; + 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 will follow the \l{Qt::LayoutDirection}{layout + direction}; it will be on the right side of the text for + right-to-left layouts, and on the left side for right-to-left + layouts. Note that this behavior is independent of the text + language. + +*/ +QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const +{ + QStackTextEngine engine(text, QFont(d)); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return qRound(engine->lineThickness()); +} + + + + +/***************************************************************************** + QFontMetricsF member functions + *****************************************************************************/ + +/*! + \class QFontMetricsF + \reentrant + + \brief The QFontMetricsF class provides font metrics information. + + \ingroup multimedia + \ingroup shared + \ingroup text + + 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 width(), 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, + and size(), to return the size of that rectangle. + + Example: + \snippet doc/src/snippets/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) +{ + d->ref.ref(); +} + +/*! + \since 4.2 + + Assigns \a other to this object. +*/ +QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) +{ + qAtomicAssign(d, other.d); + return *this; +} + +/*! + 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) +{ + d->ref.ref(); +} + +/*! + 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, + ie. the metrics you get if you use the font for drawing text on a + \link QWidget widgets\endlink or \link QPixmap pixmaps\endlink, + 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. +*/ +QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) +{ + int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); +#ifdef Q_WS_X11 + const QX11Info *info = qt_x11Info(paintdevice); + int screen = info ? info->screen() : 0; +#else + const int screen = 0; +#endif + if (font.d->dpi != dpi || font.d->screen != screen ) { + d = new QFontPrivate(*font.d); + d->dpi = dpi; + d->screen = screen; + } else { + d = font.d; + d->ref.ref(); + } + +} + +/*! + Constructs a copy of \a fm. +*/ +QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) + : d(fm.d) +{ d->ref.ref(); } + +/*! + Destroys the font metrics object and frees all allocated + resources. +*/ +QFontMetricsF::~QFontMetricsF() +{ + if (!d->ref.deref()) + delete d; +} + +/*! + Assigns the font metrics \a fm to this font metrics object. +*/ +QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) +{ + qAtomicAssign(d, fm.d); + return *this; +} + +/*! + \overload + Returns true if the font metrics are equal to the \a other font + metrics; otherwise returns 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; +} + +/*! + Returns true if the font metrics are equal to the \a other font + metrics; otherwise returns 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) +{ + return d == other.d; +} + +/*! + \fn bool QFontMetricsF::operator!=(const QFontMetricsF &other) + + Returns true if the font metrics are not equal to the \a other font + metrics; otherwise returns false. + + \sa operator==() +*/ + +/*! + \fn bool QFontMetricsF::operator !=(const QFontMetricsF &other) const + \overload + + Returns true if the font metrics are not equal to the \a other font + metrics; otherwise returns 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return engine->ascent().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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return engine->descent().toReal(); +} + +/*! + Returns the height of the font. + + This is always equal to ascent()+descent()+1 (the 1 is for the + base line). + + \sa leading(), lineSpacing() +*/ +qreal QFontMetricsF::height() const +{ + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + + return (engine->ascent() + engine->descent() + 1).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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return (engine->leading() + engine->ascent() + engine->descent() + 1).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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return engine->minRightBearing(); +} + +/*! + Returns the width of the widest character in the font. +*/ +qreal QFontMetricsF::maxWidth() const +{ + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + if (d->capital == QFont::SmallCaps) + return d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return engine->averageCharWidth().toReal(); +} + +/*! + Returns true if character \a ch is a valid character in the font; + otherwise returns false. +*/ +bool QFontMetricsF::inFont(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + if (engine->type() == QFontEngine::Box) + return false; + return engine->canRender(&ch, 1); +} + +/*! + 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 width(QChar) for a graphical description of this metric. + + \sa rightBearing(), minLeftBearing(), width() +*/ +qreal QFontMetricsF::leftBearing(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + if (engine->type() == QFontEngine::Box) + return 0; + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<10> glyphs; + int nglyphs = 9; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + // ### can nglyphs != 1 happen at all? Not currently I think + glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]); + return gi.x.toReal(); +} + +/*! + 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 width() of the character. + + See width() for a graphical description of this metric. + + \sa leftBearing(), minRightBearing(), width() +*/ +qreal QFontMetricsF::rightBearing(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + if (engine->type() == QFontEngine::Box) + return 0; + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<10> glyphs; + int nglyphs = 9; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + // ### can nglyphs != 1 happen at all? Not currently I think + glyph_metrics_t gi = engine->boundingBox(glyphs.glyphs[0]); + return (gi.xoff - gi.x - gi.width).toReal(); +} + +/*! + 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. + + \sa boundingRect() +*/ +qreal QFontMetricsF::width(const QString &text) const +{ + QTextEngine layout(text, d); + layout.ignoreBidi = true; + layout.itemize(); + return layout.width(0, text.length()).toReal(); +} + +/*! + \overload + + \img 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. + + \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. Use charWidth() + instead if you aren't looking for the width of isolated + characters. + + \sa boundingRect() +*/ +qreal QFontMetricsF::width(QChar ch) const +{ + if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) + return 0.; + + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<8> glyphs; + int nglyphs = 7; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + return glyphs.advances_x[0].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 width() method returns. + + If you want to know the advance width of the string (to layout + a set of strings next to each other), use width() 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 width(), height(), QPainter::boundingRect() +*/ +QRectF QFontMetricsF::boundingRect(const QString &text) const +{ + int len = text.length(); + if (len == 0) + return QRectF(); + + QTextEngine layout(text, d); + layout.ignoreBidi = true; + 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 width() +*/ +QRectF QFontMetricsF::boundingRect(QChar ch) const +{ + const int script = QUnicodeTables::script(ch); + QFontEngine *engine; + if (d->capital == QFont::SmallCaps && ch.isLower()) + engine = d->smallCapsFontPrivate()->engineForScript(script); + else + engine = d->engineForScript(script); + Q_ASSERT(engine != 0); + + d->alterCharForCapitalization(ch); + + QGlyphLayoutArray<10> glyphs; + int nglyphs = 9; + engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0); + glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]); + 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 + \o Qt::AlignLeft aligns to the left border, except for + Arabic and Hebrew where it aligns to the right. + \o Qt::AlignRight aligns to the right border, except for + Arabic and Hebrew where it aligns to the left. + \o Qt::AlignJustify produces justified text. + \o Qt::AlignHCenter aligns horizontally centered. + \o Qt::AlignTop aligns to the top border. + \o Qt::AlignBottom aligns to the bottom border. + \o Qt::AlignVCenter aligns vertically centered + \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter}) + \o Qt::TextSingleLine ignores newline characters in the text. + \o Qt::TextExpandTabs expands tabs (see below) + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o 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 + \o If \a tabArray is non-null, it specifies a 0-terminated sequence of + pixel-positions for tabs in the text. + \o 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 \link minLeftBearing() maximum left \endlink and + \link minRightBearing() right \endlink 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 width(), 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), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + tabArrayLen, 0); + 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 + \o Qt::TextSingleLine ignores newline characters. + \o Qt::TextExpandTabs expands tabs (see below) + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o Qt::TextWordBreak breaks the text to fit the rectangle. + \endlist + + These flags are defined in \l{Qt::TextFlags}. + + If Qt::TextExpandTabs is set in \a flags, the following behavior is + used to interpret tab characters in the text: + \list + \o If \a tabArray is non-null, it specifies a 0-terminated sequence of + pixel-positions for tabs in the text. + \o 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, 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 width() method returns. + + If you want to know the advance width of the string (to layout + a set of strings next to each other), use width() instead. + + Newline characters are processed as normal characters, \e not as + linebreaks. + + \warning Calling this method is very slow on Windows. + + \sa width(), height(), boundingRect() +*/ +QRectF QFontMetricsF::tightBoundingRect(const QString &text) const +{ + if (text.length() == 0) + return QRect(); + + QTextEngine layout(text, d); + layout.ignoreBidi = true; + 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 (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. +*/ +QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const +{ + QStackTextEngine engine(text, QFont(d)); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + 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(QUnicodeTables::Common); + Q_ASSERT(engine != 0); + return engine->lineThickness().toReal(); +} + +/*! + \fn QSize QFontMetrics::size(int flags, const QString &text, int len, + int tabStops, int *tabArray) const + \compat + + Use the size() function in combination with QString::left() + instead. + + \oldcode + QSize size = size(flags, str, len, tabstops, tabarray); + \newcode + QSize size = size(flags, str.left(len), tabstops, tabarray); + \endcode +*/ + +/*! + \fn QRect QFontMetrics::boundingRect(int x, int y, int w, int h, int flags, + const QString& text, int len, int tabStops, int *tabArray) const + \compat + + Use the boundingRect() function in combination with + QString::left() and a QRect constructor instead. + + \oldcode + QRect rect = boundingRect(x, y, w, h , flags, text, len, + tabStops, tabArray); + \newcode + QRect rect = boundingRect(QRect(x, y, w, h), flags, text.left(len), + tabstops, tabarray); + \endcode + +*/ + +/*! + \fn QRect QFontMetrics::boundingRect(const QString &text, int len) const + \compat + + Use the boundingRect() function in combination with + QString::left() instead. + + \oldcode + QRect rect = boundingRect(text, len); + \newcode + QRect rect = boundingRect(text.left(len)); + \endcode +*/ + +QT_END_NAMESPACE |