src/gui/text/qfontmetrics.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/text/qfontmetrics.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,1751 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@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 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
+    \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.data())
+{
+    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.data();
+        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
+{
+    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;
+
+    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. When implementing
+    an interactive text control, use QTextLayout instead.
+
+    \sa boundingRect()
+*/
+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 | 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 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
+{
+    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));
+    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 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 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.data())
+{
+    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.data();
+        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. When implementing
+    an interactive text control, use QTextLayout instead.
+
+    \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