/**************************************************************************** | |
** | |
** Copyright (C) 2011 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$ | |
** GNU Lesser General Public License Usage | |
** 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. | |
** | |
** 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. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $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); | |
Q_GUI_EXPORT 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()) | |
{ | |
} | |
/*! | |
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(); | |
} | |
} | |
/*! | |
Constructs a copy of \a fm. | |
*/ | |
QFontMetrics::QFontMetrics(const QFontMetrics &fm) | |
: d(fm.d.data()) | |
{ | |
} | |
/*! | |
Destroys the font metrics object and frees all allocated | |
resources. | |
*/ | |
QFontMetrics::~QFontMetrics() | |
{ | |
} | |
/*! | |
Assigns the font metrics \a fm. | |
*/ | |
QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) | |
{ | |
d = fm.d.data(); | |
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()) + qRound(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()) + qRound(engine->ascent()) + qRound(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 | |
qreal lb; | |
engine->getGlyphBearings(glyphs.glyphs[0], &lb); | |
return qRound(lb); | |
} | |
/*! | |
Returns the right bearing of character \a ch in the font. | |
The right bearing is the left-ward distance of the right-most | |
pixel of the character from the logical origin of a subsequent | |
character. This value is negative if the pixels of the character | |
extend to the right of the 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 | |
qreal rb; | |
engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb); | |
return qRound(rb); | |
} | |
/*! | |
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 | |
{ | |
return width(text, len, 0); | |
} | |
/*! | |
\internal | |
*/ | |
int QFontMetrics::width(const QString &text, int len, int flags) 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; | |
if (flags & Qt::TextBypassShaping) { | |
// Skip harfbuzz complex shaping, only use advances | |
int numGlyphs = len; | |
QVarLengthGlyphLayoutArray glyphs(numGlyphs); | |
QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); | |
if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) { | |
glyphs.resize(numGlyphs); | |
if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) | |
Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); | |
} | |
QFixed width; | |
for (int i = 0; i < numGlyphs; ++i) | |
width += glyphs.advances_x[i]; | |
return qRound(width); | |
} | |
QStackTextEngine layout(text, d.data()); | |
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); | |
QStackTextEngine layout(cstr, d.data()); | |
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(); | |
QStackTextEngine layout(text, d.data()); | |
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.data()), 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(); | |
QStackTextEngine layout(text, d.data()); | |
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.data())); | |
return engine.elidedText(mode, width, flags); | |
} | |
/*! | |
Returns the distance from the base line to where an underscore | |
should be drawn. | |
\sa overlinePos(), strikeOutPos(), lineWidth() | |
*/ | |
int QFontMetrics::underlinePos() const | |
{ | |
QFontEngine *engine = d->engineForScript(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.data()) | |
{ | |
} | |
/*! | |
\since 4.2 | |
Assigns \a other to this object. | |
*/ | |
QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) | |
{ | |
d = other.d.data(); | |
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()) | |
{ | |
} | |
/*! | |
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(); | |
} | |
} | |
/*! | |
Constructs a copy of \a fm. | |
*/ | |
QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) | |
: d(fm.d.data()) | |
{ | |
} | |
/*! | |
Destroys the font metrics object and frees all allocated | |
resources. | |
*/ | |
QFontMetricsF::~QFontMetricsF() | |
{ | |
} | |
/*! | |
Assigns the font metrics \a fm to this font metrics object. | |
*/ | |
QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) | |
{ | |
d = fm.d.data(); | |
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 | |
qreal lb; | |
engine->getGlyphBearings(glyphs.glyphs[0], &lb); | |
return lb; | |
} | |
/*! | |
Returns the right bearing of character \a ch in the font. | |
The right bearing is the left-ward distance of the right-most | |
pixel of the character from the logical origin of a subsequent | |
character. This value is negative if the pixels of the character | |
extend to the right of the 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 | |
qreal rb; | |
engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb); | |
return rb; | |
} | |
/*! | |
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 | |
{ | |
int pos = text.indexOf(QLatin1Char('\x9c')); | |
int len = (pos != -1) ? pos : text.length(); | |
QStackTextEngine layout(text, d.data()); | |
layout.ignoreBidi = true; | |
layout.itemize(); | |
return layout.width(0, len).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(); | |
QStackTextEngine layout(text, d.data()); | |
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.data()), 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 | 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() | |
*/ | |
QRectF QFontMetricsF::tightBoundingRect(const QString &text) const | |
{ | |
if (text.length() == 0) | |
return QRect(); | |
QStackTextEngine layout(text, d.data()); | |
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 | |
{ | |
QString _text = text; | |
if (!(flags & Qt::TextLongestVariant)) { | |
int posA = 0; | |
int posB = _text.indexOf(QLatin1Char('\x9c')); | |
while (posB >= 0) { | |
QString portion = _text.mid(posA, posB - posA); | |
if (size(flags, portion).width() <= width) | |
return portion; | |
posA = posB + 1; | |
posB = _text.indexOf(QLatin1Char('\x9c'), posA); | |
} | |
_text = _text.mid(posA); | |
} | |
QStackTextEngine engine(_text, QFont(d.data())); | |
return engine.elidedText(mode, QFixed::fromReal(width), flags); | |
} | |
/*! | |
Returns the distance from the base line to where an underscore | |
should be drawn. | |
\sa overlinePos(), strikeOutPos(), lineWidth() | |
*/ | |
qreal QFontMetricsF::underlinePos() const | |
{ | |
QFontEngine *engine = d->engineForScript(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 |