Get started with patching up the Qt GUI docs
[profile/ivi/qtbase.git] / src / gui / text / qfontmetrics.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qfont.h"
43 #include "qpaintdevice.h"
44 #include "qfontmetrics.h"
45
46 #include "qfont_p.h"
47 #include "qfontengine_p.h"
48 #include <private/qunicodetables_p.h>
49
50 #include <math.h>
51
52
53 QT_BEGIN_NAMESPACE
54
55
56 extern void qt_format_text(const QFont& font, const QRectF &_r,
57                            int tf, const QString &text, QRectF *brect,
58                            int tabStops, int *tabArray, int tabArrayLen,
59                            QPainter *painter);
60
61 /*****************************************************************************
62   QFontMetrics member functions
63  *****************************************************************************/
64
65 /*!
66     \class QFontMetrics
67     \reentrant
68     \inmodule QtGui
69
70     \brief The QFontMetrics class provides font metrics information.
71
72     \ingroup painting
73     \ingroup shared
74
75     QFontMetrics functions calculate the size of characters and
76     strings for a given font. There are three ways you can create a
77     QFontMetrics object:
78
79     \list 1
80     \li Calling the QFontMetrics constructor with a QFont creates a
81     font metrics object for a screen-compatible font, i.e. the font
82     cannot be a printer font. If the font is changed
83     later, the font metrics object is \e not updated.
84
85     (Note: If you use a printer font the values returned may be
86     inaccurate. Printer fonts are not always accessible so the nearest
87     screen font is used if a printer font is supplied.)
88
89     \li QWidget::fontMetrics() returns the font metrics for a widget's
90     font. This is equivalent to QFontMetrics(widget->font()). If the
91     widget's font is changed later, the font metrics object is \e not
92     updated.
93
94     \li QPainter::fontMetrics() returns the font metrics for a
95     painter's current font. If the painter's font is changed later, the
96     font metrics object is \e not updated.
97     \endlist
98
99     Once created, the object provides functions to access the
100     individual metrics of the font, its characters, and for strings
101     rendered in the font.
102
103     There are several functions that operate on the font: ascent(),
104     descent(), height(), leading() and lineSpacing() return the basic
105     size properties of the font. The underlinePos(), overlinePos(),
106     strikeOutPos() and lineWidth() functions, return the properties of
107     the line that underlines, overlines or strikes out the
108     characters. These functions are all fast.
109
110     There are also some functions that operate on the set of glyphs in
111     the font: minLeftBearing(), minRightBearing() and maxWidth().
112     These are by necessity slow, and we recommend avoiding them if
113     possible.
114
115     For each character, you can get its width(), leftBearing() and
116     rightBearing() and find out whether it is in the font using
117     inFont(). You can also treat the character as a string, and use
118     the string functions on it.
119
120     The string functions include width(), to return the width of a
121     string in pixels (or points, for a printer), boundingRect(), to
122     return a rectangle large enough to contain the rendered string,
123     and size(), to return the size of that rectangle.
124
125     Example:
126     \snippet code/src_gui_text_qfontmetrics.cpp 0
127
128     \sa QFont, QFontInfo, QFontDatabase, QFontComboBox, {Character Map Example}
129 */
130
131 /*!
132     \fn QRect QFontMetrics::boundingRect(int x, int y, int width, int height,
133         int flags, const QString &text, int tabStops, int *tabArray) const
134     \overload
135
136     Returns the bounding rectangle for the given \a text within the
137     rectangle specified by the \a x and \a y coordinates, \a width, and
138     \a height.
139
140     If Qt::TextExpandTabs is set in \a flags and \a tabArray is
141     non-null, it specifies a 0-terminated sequence of pixel-positions
142     for tabs; otherwise, if \a tabStops is non-zero, it is used as the
143     tab spacing (in pixels).
144 */
145
146 /*!
147     Constructs a font metrics object for \a font.
148
149     The font metrics will be compatible with the paintdevice used to
150     create \a font.
151
152     The font metrics object holds the information for the font that is
153     passed in the constructor at the time it is created, and is not
154     updated if the font's attributes are changed later.
155
156     Use QFontMetrics(const QFont &, QPaintDevice *) to get the font
157     metrics that are compatible with a certain paint device.
158 */
159 QFontMetrics::QFontMetrics(const QFont &font)
160     : d(font.d.data())
161 {
162 }
163
164 /*!
165     Constructs a font metrics object for \a font and \a paintdevice.
166
167     The font metrics will be compatible with the paintdevice passed.
168     If the \a paintdevice is 0, the metrics will be screen-compatible,
169     ie. the metrics you get if you use the font for drawing text on a
170     \l{QWidget}{widgets} or \l{QPixmap}{pixmaps},
171     not on a QPicture or QPrinter.
172
173     The font metrics object holds the information for the font that is
174     passed in the constructor at the time it is created, and is not
175     updated if the font's attributes are changed later.
176 */
177 QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
178 {
179     int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
180     const int screen = 0;
181     if (font.d->dpi != dpi || font.d->screen != screen ) {
182         d = new QFontPrivate(*font.d);
183         d->dpi = dpi;
184         d->screen = screen;
185     } else {
186         d = font.d.data();
187     }
188
189 }
190
191 /*!
192     Constructs a copy of \a fm.
193 */
194 QFontMetrics::QFontMetrics(const QFontMetrics &fm)
195     : d(fm.d.data())
196 {
197 }
198
199 /*!
200     Destroys the font metrics object and frees all allocated
201     resources.
202 */
203 QFontMetrics::~QFontMetrics()
204 {
205 }
206
207 /*!
208     Assigns the font metrics \a fm.
209 */
210 QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm)
211 {
212     d = fm.d.data();
213     return *this;
214 }
215
216 /*!
217     Returns true if \a other is equal to this object; otherwise
218     returns false.
219
220     Two font metrics are considered equal if they were constructed
221     from the same QFont and the paint devices they were constructed
222     for are considered compatible.
223
224     \sa operator!=()
225 */
226 bool QFontMetrics::operator ==(const QFontMetrics &other) const
227 {
228     return d == other.d;
229 }
230
231 /*!
232     \fn bool QFontMetrics::operator !=(const QFontMetrics &other) const
233
234     Returns true if \a other is not equal to this object; otherwise returns false.
235
236     Two font metrics are considered equal if they were constructed
237     from the same QFont and the paint devices they were constructed
238     for are considered compatible.
239
240     \sa operator==()
241 */
242
243 /*!
244     Returns the ascent of the font.
245
246     The ascent of a font is the distance from the baseline to the
247     highest position characters extend to. In practice, some font
248     designers break this rule, e.g. when they put more than one accent
249     on top of a character, or to accommodate an unusual character in
250     an exotic language, so it is possible (though rare) that this
251     value will be too small.
252
253     \sa descent()
254 */
255 int QFontMetrics::ascent() const
256 {
257     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
258     Q_ASSERT(engine != 0);
259     return qRound(engine->ascent());
260 }
261
262
263 /*!
264     Returns the descent of the font.
265
266     The descent is the distance from the base line to the lowest point
267     characters extend to. In practice, some font designers break this rule,
268     e.g. to accommodate an unusual character in an exotic language, so
269     it is possible (though rare) that this value will be too small.
270
271     \sa ascent()
272 */
273 int QFontMetrics::descent() const
274 {
275     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
276     Q_ASSERT(engine != 0);
277     return qRound(engine->descent());
278 }
279
280 /*!
281     Returns the height of the font.
282
283     This is always equal to ascent()+descent()+1 (the 1 is for the
284     base line).
285
286     \sa leading(), lineSpacing()
287 */
288 int QFontMetrics::height() const
289 {
290     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
291     Q_ASSERT(engine != 0);
292     return qRound(engine->ascent()) + qRound(engine->descent());
293 }
294
295 /*!
296     Returns the leading of the font.
297
298     This is the natural inter-line spacing.
299
300     \sa height(), lineSpacing()
301 */
302 int QFontMetrics::leading() const
303 {
304     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
305     Q_ASSERT(engine != 0);
306     return qRound(engine->leading());
307 }
308
309 /*!
310     Returns the distance from one base line to the next.
311
312     This value is always equal to leading()+height().
313
314     \sa height(), leading()
315 */
316 int QFontMetrics::lineSpacing() const
317 {
318     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
319     Q_ASSERT(engine != 0);
320     return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent());
321 }
322
323 /*!
324     Returns the minimum left bearing of the font.
325
326     This is the smallest leftBearing(char) of all characters in the
327     font.
328
329     Note that this function can be very slow if the font is large.
330
331     \sa minRightBearing(), leftBearing()
332 */
333 int QFontMetrics::minLeftBearing() const
334 {
335     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
336     Q_ASSERT(engine != 0);
337     return qRound(engine->minLeftBearing());
338 }
339
340 /*!
341     Returns the minimum right bearing of the font.
342
343     This is the smallest rightBearing(char) of all characters in the
344     font.
345
346     Note that this function can be very slow if the font is large.
347
348     \sa minLeftBearing(), rightBearing()
349 */
350 int QFontMetrics::minRightBearing() const
351 {
352     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
353     Q_ASSERT(engine != 0);
354     return qRound(engine->minRightBearing());
355 }
356
357 /*!
358     Returns the width of the widest character in the font.
359 */
360 int QFontMetrics::maxWidth() const
361 {
362     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
363     Q_ASSERT(engine != 0);
364     return qRound(engine->maxCharWidth());
365 }
366
367 /*!
368     Returns the 'x' height of the font. This is often but not always
369     the same as the height of the character 'x'.
370 */
371 int QFontMetrics::xHeight() const
372 {
373     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
374     Q_ASSERT(engine != 0);
375     if (d->capital == QFont::SmallCaps)
376         return qRound(d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::Common)->ascent());
377     return qRound(engine->xHeight());
378 }
379
380 /*!
381     \since 4.2
382
383     Returns the average width of glyphs in the font.
384 */
385 int QFontMetrics::averageCharWidth() const
386 {
387     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
388     Q_ASSERT(engine != 0);
389     return qRound(engine->averageCharWidth());
390 }
391
392 /*!
393     Returns true if character \a ch is a valid character in the font;
394     otherwise returns false.
395 */
396 bool QFontMetrics::inFont(QChar ch) const
397 {
398     const int script = QUnicodeTables::script(ch);
399     QFontEngine *engine = d->engineForScript(script);
400     Q_ASSERT(engine != 0);
401     if (engine->type() == QFontEngine::Box)
402         return false;
403     return engine->canRender(&ch, 1);
404 }
405
406 /*!
407    Returns true if the character encoded in UCS-4/UTF-32 is a valid
408    character in the font; otherwise returns false.
409 */
410 bool QFontMetrics::inFontUcs4(uint ucs4) const
411 {
412     const int script = QUnicodeTables::script(ucs4);
413     QFontEngine *engine = d->engineForScript(script);
414     Q_ASSERT(engine != 0);
415     if (engine->type() == QFontEngine::Box)
416         return false;
417     return engine->canRender(ucs4);
418 }
419
420 /*!
421     Returns the left bearing of character \a ch in the font.
422
423     The left bearing is the right-ward distance of the left-most pixel
424     of the character from the logical origin of the character. This
425     value is negative if the pixels of the character extend to the
426     left of the logical origin.
427
428     See width(QChar) for a graphical description of this metric.
429
430     \sa rightBearing(), minLeftBearing(), width()
431 */
432 int QFontMetrics::leftBearing(QChar ch) const
433 {
434     const int script = QUnicodeTables::script(ch);
435     QFontEngine *engine;
436     if (d->capital == QFont::SmallCaps && ch.isLower())
437         engine = d->smallCapsFontPrivate()->engineForScript(script);
438     else
439         engine = d->engineForScript(script);
440     Q_ASSERT(engine != 0);
441     if (engine->type() == QFontEngine::Box)
442         return 0;
443
444     d->alterCharForCapitalization(ch);
445
446     QGlyphLayoutArray<10> glyphs;
447     int nglyphs = 9;
448     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
449     // ### can nglyphs != 1 happen at all? Not currently I think
450     qreal lb;
451     engine->getGlyphBearings(glyphs.glyphs[0], &lb);
452     return qRound(lb);
453 }
454
455 /*!
456     Returns the right bearing of character \a ch in the font.
457
458     The right bearing is the left-ward distance of the right-most
459     pixel of the character from the logical origin of a subsequent
460     character. This value is negative if the pixels of the character
461     extend to the right of the width() of the character.
462
463     See width() for a graphical description of this metric.
464
465     \sa leftBearing(), minRightBearing(), width()
466 */
467 int QFontMetrics::rightBearing(QChar ch) const
468 {
469     const int script = QUnicodeTables::script(ch);
470     QFontEngine *engine;
471     if (d->capital == QFont::SmallCaps && ch.isLower())
472         engine = d->smallCapsFontPrivate()->engineForScript(script);
473     else
474         engine = d->engineForScript(script);
475     Q_ASSERT(engine != 0);
476     if (engine->type() == QFontEngine::Box)
477         return 0;
478
479     d->alterCharForCapitalization(ch);
480
481     QGlyphLayoutArray<10> glyphs;
482     int nglyphs = 9;
483     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
484     // ### can nglyphs != 1 happen at all? Not currently I think
485     qreal rb;
486     engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
487     return qRound(rb);
488 }
489
490 /*!
491     Returns the width in pixels of the first \a len characters of \a
492     text. If \a len is negative (the default), the entire string is
493     used.
494
495     Note that this value is \e not equal to boundingRect().width();
496     boundingRect() returns a rectangle describing the pixels this
497     string will cover whereas width() returns the distance to where
498     the next string should be drawn.
499
500     \sa boundingRect()
501 */
502 int QFontMetrics::width(const QString &text, int len) const
503 {
504     return width(text, len, 0);
505 }
506
507 /*!
508     \internal
509 */
510 int QFontMetrics::width(const QString &text, int len, int flags) const
511 {
512     int pos = text.indexOf(QLatin1Char('\x9c'));
513     if (pos != -1) {
514         len = (len < 0) ? pos : qMin(pos, len);
515     } else if (len < 0) {
516         len = text.length();
517     }
518     if (len == 0)
519         return 0;
520
521     if (flags & Qt::TextBypassShaping) {
522         // Skip harfbuzz complex shaping, only use advances
523         int numGlyphs = len;
524         QVarLengthGlyphLayoutArray glyphs(numGlyphs);
525         QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
526         if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) {
527             glyphs.resize(numGlyphs);
528             if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0))
529                 Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
530         }
531
532         QFixed width;
533         for (int i = 0; i < numGlyphs; ++i)
534             width += glyphs.advances_x[i];
535         return qRound(width);
536     }
537
538     QStackTextEngine layout(text, QFont(d.data()));
539     layout.ignoreBidi = true;
540     return qRound(layout.width(0, len));
541 }
542
543 /*!
544     \overload
545
546     \img bearings.png Bearings
547
548     Returns the logical width of character \a ch in pixels. This is a
549     distance appropriate for drawing a subsequent character after \a
550     ch.
551
552     Some of the metrics are described in the image to the right. The
553     central dark rectangles cover the logical width() of each
554     character. The outer pale rectangles cover the leftBearing() and
555     rightBearing() of each character. Notice that the bearings of "f"
556     in this particular font are both negative, while the bearings of
557     "o" are both positive.
558
559     \warning This function will produce incorrect results for Arabic
560     characters or non-spacing marks in the middle of a string, as the
561     glyph shaping and positioning of marks that happens when
562     processing strings cannot be taken into account. When implementing
563     an interactive text control, use QTextLayout instead.
564
565     \sa boundingRect()
566 */
567 int QFontMetrics::width(QChar ch) const
568 {
569     if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing)
570         return 0;
571
572     const int script = QUnicodeTables::script(ch);
573     QFontEngine *engine;
574     if (d->capital == QFont::SmallCaps && ch.isLower())
575         engine = d->smallCapsFontPrivate()->engineForScript(script);
576     else
577         engine = d->engineForScript(script);
578     Q_ASSERT(engine != 0);
579
580     d->alterCharForCapitalization(ch);
581
582     QGlyphLayoutArray<8> glyphs;
583     int nglyphs = 7;
584     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
585     return qRound(glyphs.advances_x[0]);
586 }
587
588 /*! \obsolete
589
590     Returns the width of the character at position \a pos in the
591     string \a text.
592
593     The whole string is needed, as the glyph drawn may change
594     depending on the context (the letter before and after the current
595     one) for some languages (e.g. Arabic).
596
597     This function also takes non spacing marks and ligatures into
598     account.
599 */
600 int QFontMetrics::charWidth(const QString &text, int pos) const
601 {
602     if (pos < 0 || pos > (int)text.length())
603         return 0;
604
605     QChar ch = text.unicode()[pos];
606     const int script = QUnicodeTables::script(ch);
607     int width;
608
609     if (script != QUnicodeTables::Common) {
610         // complex script shaping. Have to do some hard work
611         int from = qMax(0, pos - 8);
612         int to = qMin(text.length(), pos + 8);
613         QString cstr = QString::fromRawData(text.unicode() + from, to - from);
614         QStackTextEngine layout(cstr, QFont(d.data()));
615         layout.ignoreBidi = true;
616         layout.itemize();
617         width = qRound(layout.width(pos-from, 1));
618     } else if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) {
619         width = 0;
620     } else {
621         QFontEngine *engine;
622         if (d->capital == QFont::SmallCaps && ch.isLower())
623             engine = d->smallCapsFontPrivate()->engineForScript(script);
624         else
625             engine = d->engineForScript(script);
626         Q_ASSERT(engine != 0);
627
628         d->alterCharForCapitalization(ch);
629
630         QGlyphLayoutArray<8> glyphs;
631         int nglyphs = 7;
632         engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
633         width = qRound(glyphs.advances_x[0]);
634     }
635     return width;
636 }
637
638 /*!
639     Returns the bounding rectangle of the characters in the string
640     specified by \a text. The bounding rectangle always covers at least
641     the set of pixels the text would cover if drawn at (0, 0).
642
643     Note that the bounding rectangle may extend to the left of (0, 0),
644     e.g. for italicized fonts, and that the width of the returned
645     rectangle might be different than what the width() method returns.
646
647     If you want to know the advance width of the string (to layout
648     a set of strings next to each other), use width() instead.
649
650     Newline characters are processed as normal characters, \e not as
651     linebreaks.
652
653     The height of the bounding rectangle is at least as large as the
654     value returned by height().
655
656     \sa width(), height(), QPainter::boundingRect(), tightBoundingRect()
657 */
658 QRect QFontMetrics::boundingRect(const QString &text) const
659 {
660     if (text.length() == 0)
661         return QRect();
662
663     QStackTextEngine layout(text, QFont(d.data()));
664     layout.ignoreBidi = true;
665     layout.itemize();
666     glyph_metrics_t gm = layout.boundingBox(0, text.length());
667     return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
668 }
669
670 /*!
671     Returns the rectangle that is covered by ink if character \a ch
672     were to be drawn at the origin of the coordinate system.
673
674     Note that the bounding rectangle may extend to the left of (0, 0)
675     (e.g., for italicized fonts), and that the text output may cover \e
676     all pixels in the bounding rectangle. For a space character the rectangle
677     will usually be empty.
678
679     Note that the rectangle usually extends both above and below the
680     base line.
681
682     \warning The width of the returned rectangle is not the advance width
683     of the character. Use boundingRect(const QString &) or width() instead.
684
685     \sa width()
686 */
687 QRect QFontMetrics::boundingRect(QChar ch) const
688 {
689     const int script = QUnicodeTables::script(ch);
690     QFontEngine *engine;
691     if (d->capital == QFont::SmallCaps && ch.isLower())
692         engine = d->smallCapsFontPrivate()->engineForScript(script);
693     else
694         engine = d->engineForScript(script);
695     Q_ASSERT(engine != 0);
696
697     d->alterCharForCapitalization(ch);
698
699     QGlyphLayoutArray<10> glyphs;
700     int nglyphs = 9;
701     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
702     glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]);
703     return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
704 }
705
706 /*!
707     \overload
708
709     Returns the bounding rectangle of the characters in the string
710     specified by \a text, which is the set of pixels the text would
711     cover if drawn at (0, 0). The drawing, and hence the bounding
712     rectangle, is constrained to the rectangle \a rect.
713
714     The \a flags argument is the bitwise OR of the following flags:
715     \list
716     \li Qt::AlignLeft aligns to the left border, except for
717           Arabic and Hebrew where it aligns to the right.
718     \li Qt::AlignRight aligns to the right border, except for
719           Arabic and Hebrew where it aligns to the left.
720     \li Qt::AlignJustify produces justified text.
721     \li Qt::AlignHCenter aligns horizontally centered.
722     \li Qt::AlignTop aligns to the top border.
723     \li Qt::AlignBottom aligns to the bottom border.
724     \li Qt::AlignVCenter aligns vertically centered
725     \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
726     \li Qt::TextSingleLine ignores newline characters in the text.
727     \li Qt::TextExpandTabs expands tabs (see below)
728     \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
729     \li Qt::TextWordWrap breaks the text to fit the rectangle.
730     \endlist
731
732     Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical
733     alignment defaults to Qt::AlignTop.
734
735     If several of the horizontal or several of the vertical alignment
736     flags are set, the resulting alignment is undefined.
737
738     If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is
739     non-null, it specifies a 0-terminated sequence of pixel-positions
740     for tabs; otherwise if \a tabStops is non-zero, it is used as the
741     tab spacing (in pixels).
742
743     Note that the bounding rectangle may extend to the left of (0, 0),
744     e.g. for italicized fonts, and that the text output may cover \e
745     all pixels in the bounding rectangle.
746
747     Newline characters are processed as linebreaks.
748
749     Despite the different actual character heights, the heights of the
750     bounding rectangles of "Yes" and "yes" are the same.
751
752     The bounding rectangle returned by this function is somewhat larger
753     than that calculated by the simpler boundingRect() function. This
754     function uses the \l{minLeftBearing()}{maximum left} and
755     \l{minRightBearing()}{right} font bearings as is
756     necessary for multi-line text to align correctly. Also,
757     fontHeight() and lineSpacing() are used to calculate the height,
758     rather than individual character heights.
759
760     \sa width(), QPainter::boundingRect(), Qt::Alignment
761 */
762 QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &text, int tabStops,
763                                  int *tabArray) const
764 {
765     int tabArrayLen = 0;
766     if (tabArray)
767         while (tabArray[tabArrayLen])
768             tabArrayLen++;
769
770     QRectF rb;
771     QRectF rr(rect);
772     qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
773                    tabArrayLen, 0);
774
775     return rb.toAlignedRect();
776 }
777
778 /*!
779     Returns the size in pixels of \a text.
780
781     The \a flags argument is the bitwise OR of the following flags:
782     \list
783     \li Qt::TextSingleLine ignores newline characters.
784     \li Qt::TextExpandTabs expands tabs (see below)
785     \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
786     \li Qt::TextWordBreak breaks the text to fit the rectangle.
787     \endlist
788
789     If Qt::TextExpandTabs is set in \a flags, then: if \a tabArray is
790     non-null, it specifies a 0-terminated sequence of pixel-positions
791     for tabs; otherwise if \a tabStops is non-zero, it is used as the
792     tab spacing (in pixels).
793
794     Newline characters are processed as linebreaks.
795
796     Despite the different actual character heights, the heights of the
797     bounding rectangles of "Yes" and "yes" are the same.
798
799     \sa boundingRect()
800 */
801 QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabArray) const
802 {
803     return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size();
804 }
805
806 /*!
807   \since 4.3
808
809     Returns a tight bounding rectangle around the characters in the
810     string specified by \a text. The bounding rectangle always covers
811     at least the set of pixels the text would cover if drawn at (0,
812     0).
813
814     Note that the bounding rectangle may extend to the left of (0, 0),
815     e.g. for italicized fonts, and that the width of the returned
816     rectangle might be different than what the width() method returns.
817
818     If you want to know the advance width of the string (to layout
819     a set of strings next to each other), use width() instead.
820
821     Newline characters are processed as normal characters, \e not as
822     linebreaks.
823
824     \warning Calling this method is very slow on Windows.
825
826     \sa width(), height(), boundingRect()
827 */
828 QRect QFontMetrics::tightBoundingRect(const QString &text) const
829 {
830     if (text.length() == 0)
831         return QRect();
832
833     QStackTextEngine layout(text, QFont(d.data()));
834     layout.ignoreBidi = true;
835     layout.itemize();
836     glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
837     return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
838 }
839
840
841 /*!
842     \since 4.2
843
844     If the string \a text is wider than \a width, returns an elided
845     version of the string (i.e., a string with "..." in it).
846     Otherwise, returns the original string.
847
848     The \a mode parameter specifies whether the text is elided on the
849     left (e.g., "...tech"), in the middle (e.g., "Tr...ch"), or on
850     the right (e.g., "Trol...").
851
852     The \a width is specified in pixels, not characters.
853
854     The \a flags argument is optional and currently only supports
855     Qt::TextShowMnemonic as value.
856
857     The elide mark will follow the \l{Qt::LayoutDirection}{layout
858     direction}; it will be on the right side of the text for
859     right-to-left layouts, and on the left side for right-to-left
860     layouts. Note that this behavior is independent of the text
861     language.
862 */
863 QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const
864 {
865     QString _text = text;
866     if (!(flags & Qt::TextLongestVariant)) {
867         int posA = 0;
868         int posB = _text.indexOf(QLatin1Char('\x9c'));
869         while (posB >= 0) {
870             QString portion = _text.mid(posA, posB - posA);
871             if (size(flags, portion).width() <= width)
872                 return portion;
873             posA = posB + 1;
874             posB = _text.indexOf(QLatin1Char('\x9c'), posA);
875         }
876         _text = _text.mid(posA);
877     }
878     QStackTextEngine engine(_text, QFont(d.data()));
879     return engine.elidedText(mode, width, flags);
880 }
881
882 /*!
883     Returns the distance from the base line to where an underscore
884     should be drawn.
885
886     \sa overlinePos(), strikeOutPos(), lineWidth()
887 */
888 int QFontMetrics::underlinePos() const
889 {
890     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
891     Q_ASSERT(engine != 0);
892     return qRound(engine->underlinePosition());
893 }
894
895 /*!
896     Returns the distance from the base line to where an overline
897     should be drawn.
898
899     \sa underlinePos(), strikeOutPos(), lineWidth()
900 */
901 int QFontMetrics::overlinePos() const
902 {
903     return ascent() + 1;
904 }
905
906 /*!
907     Returns the distance from the base line to where the strikeout
908     line should be drawn.
909
910     \sa underlinePos(), overlinePos(), lineWidth()
911 */
912 int QFontMetrics::strikeOutPos() const
913 {
914     int pos = ascent() / 3;
915     return pos > 0 ? pos : 1;
916 }
917
918 /*!
919     Returns the width of the underline and strikeout lines, adjusted
920     for the point size of the font.
921
922     \sa underlinePos(), overlinePos(), strikeOutPos()
923 */
924 int QFontMetrics::lineWidth() const
925 {
926     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
927     Q_ASSERT(engine != 0);
928     return qRound(engine->lineThickness());
929 }
930
931
932
933
934 /*****************************************************************************
935   QFontMetricsF member functions
936  *****************************************************************************/
937
938 /*!
939     \class QFontMetricsF
940     \reentrant
941     \inmodule QtGui
942
943     \brief The QFontMetricsF class provides font metrics information.
944
945     \ingroup painting
946     \ingroup shared
947
948     QFontMetricsF functions calculate the size of characters and
949     strings for a given font. You can construct a QFontMetricsF object
950     with an existing QFont to obtain metrics for that font. If the
951     font is changed later, the font metrics object is \e not updated.
952
953     Once created, the object provides functions to access the
954     individual metrics of the font, its characters, and for strings
955     rendered in the font.
956
957     There are several functions that operate on the font: ascent(),
958     descent(), height(), leading() and lineSpacing() return the basic
959     size properties of the font. The underlinePos(), overlinePos(),
960     strikeOutPos() and lineWidth() functions, return the properties of
961     the line that underlines, overlines or strikes out the
962     characters. These functions are all fast.
963
964     There are also some functions that operate on the set of glyphs in
965     the font: minLeftBearing(), minRightBearing() and maxWidth().
966     These are by necessity slow, and we recommend avoiding them if
967     possible.
968
969     For each character, you can get its width(), leftBearing() and
970     rightBearing() and find out whether it is in the font using
971     inFont(). You can also treat the character as a string, and use
972     the string functions on it.
973
974     The string functions include width(), to return the width of a
975     string in pixels (or points, for a printer), boundingRect(), to
976     return a rectangle large enough to contain the rendered string,
977     and size(), to return the size of that rectangle.
978
979     Example:
980     \snippet code/src_gui_text_qfontmetrics.cpp 1
981
982     \sa QFont, QFontInfo, QFontDatabase
983 */
984
985 /*!
986     \since 4.2
987
988     Constructs a font metrics object with floating point precision
989     from the given \a fontMetrics object.
990 */
991 QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
992     : d(fontMetrics.d.data())
993 {
994 }
995
996 /*!
997     \since 4.2
998
999     Assigns \a other to this object.
1000 */
1001 QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
1002 {
1003     d = other.d.data();
1004     return *this;
1005 }
1006
1007 /*!
1008     Constructs a font metrics object for \a font.
1009
1010     The font metrics will be compatible with the paintdevice used to
1011     create \a font.
1012
1013     The font metrics object holds the information for the font that is
1014     passed in the constructor at the time it is created, and is not
1015     updated if the font's attributes are changed later.
1016
1017     Use QFontMetricsF(const QFont &, QPaintDevice *) to get the font
1018     metrics that are compatible with a certain paint device.
1019 */
1020 QFontMetricsF::QFontMetricsF(const QFont &font)
1021     : d(font.d.data())
1022 {
1023 }
1024
1025 /*!
1026     Constructs a font metrics object for \a font and \a paintdevice.
1027
1028     The font metrics will be compatible with the paintdevice passed.
1029     If the \a paintdevice is 0, the metrics will be screen-compatible,
1030     ie. the metrics you get if you use the font for drawing text on a
1031     \l{QWidget}{widgets} or \l{QPixmap}{pixmaps},
1032     not on a QPicture or QPrinter.
1033
1034     The font metrics object holds the information for the font that is
1035     passed in the constructor at the time it is created, and is not
1036     updated if the font's attributes are changed later.
1037 */
1038 QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
1039 {
1040     int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
1041     const int screen = 0;
1042     if (font.d->dpi != dpi || font.d->screen != screen ) {
1043         d = new QFontPrivate(*font.d);
1044         d->dpi = dpi;
1045         d->screen = screen;
1046     } else {
1047         d = font.d.data();
1048     }
1049
1050 }
1051
1052 /*!
1053     Constructs a copy of \a fm.
1054 */
1055 QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
1056     : d(fm.d.data())
1057 {
1058 }
1059
1060 /*!
1061     Destroys the font metrics object and frees all allocated
1062     resources.
1063 */
1064 QFontMetricsF::~QFontMetricsF()
1065 {
1066 }
1067
1068 /*!
1069     Assigns the font metrics \a fm to this font metrics object.
1070 */
1071 QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm)
1072 {
1073     d = fm.d.data();
1074     return *this;
1075 }
1076
1077 /*!
1078   Returns true if the font metrics are equal to the \a other font
1079   metrics; otherwise returns false.
1080
1081   Two font metrics are considered equal if they were constructed from the
1082   same QFont and the paint devices they were constructed for are
1083   considered to be compatible.
1084 */
1085 bool QFontMetricsF::operator ==(const QFontMetricsF &other) const
1086 {
1087     return d == other.d;
1088 }
1089
1090 /*!
1091     \fn bool QFontMetricsF::operator !=(const QFontMetricsF &other) const
1092     \overload
1093
1094     Returns true if the font metrics are not equal to the \a other font
1095     metrics; otherwise returns false.
1096
1097     \sa operator==()
1098 */
1099
1100 /*!
1101     Returns the ascent of the font.
1102
1103     The ascent of a font is the distance from the baseline to the
1104     highest position characters extend to. In practice, some font
1105     designers break this rule, e.g. when they put more than one accent
1106     on top of a character, or to accommodate an unusual character in
1107     an exotic language, so it is possible (though rare) that this
1108     value will be too small.
1109
1110     \sa descent()
1111 */
1112 qreal QFontMetricsF::ascent() const
1113 {
1114     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1115     Q_ASSERT(engine != 0);
1116     return engine->ascent().toReal();
1117 }
1118
1119
1120 /*!
1121     Returns the descent of the font.
1122
1123     The descent is the distance from the base line to the lowest point
1124     characters extend to. (Note that this is different from X, which
1125     adds 1 pixel.) In practice, some font designers break this rule,
1126     e.g. to accommodate an unusual character in an exotic language, so
1127     it is possible (though rare) that this value will be too small.
1128
1129     \sa ascent()
1130 */
1131 qreal QFontMetricsF::descent() const
1132 {
1133     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1134     Q_ASSERT(engine != 0);
1135     return engine->descent().toReal();
1136 }
1137
1138 /*!
1139     Returns the height of the font.
1140
1141     This is always equal to ascent()+descent()+1 (the 1 is for the
1142     base line).
1143
1144     \sa leading(), lineSpacing()
1145 */
1146 qreal QFontMetricsF::height() const
1147 {
1148     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1149     Q_ASSERT(engine != 0);
1150
1151     return (engine->ascent() + engine->descent()).toReal();
1152 }
1153
1154 /*!
1155     Returns the leading of the font.
1156
1157     This is the natural inter-line spacing.
1158
1159     \sa height(), lineSpacing()
1160 */
1161 qreal QFontMetricsF::leading() const
1162 {
1163     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1164     Q_ASSERT(engine != 0);
1165     return engine->leading().toReal();
1166 }
1167
1168 /*!
1169     Returns the distance from one base line to the next.
1170
1171     This value is always equal to leading()+height().
1172
1173     \sa height(), leading()
1174 */
1175 qreal QFontMetricsF::lineSpacing() const
1176 {
1177     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1178     Q_ASSERT(engine != 0);
1179     return (engine->leading() + engine->ascent() + engine->descent()).toReal();
1180 }
1181
1182 /*!
1183     Returns the minimum left bearing of the font.
1184
1185     This is the smallest leftBearing(char) of all characters in the
1186     font.
1187
1188     Note that this function can be very slow if the font is large.
1189
1190     \sa minRightBearing(), leftBearing()
1191 */
1192 qreal QFontMetricsF::minLeftBearing() const
1193 {
1194     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1195     Q_ASSERT(engine != 0);
1196     return engine->minLeftBearing();
1197 }
1198
1199 /*!
1200     Returns the minimum right bearing of the font.
1201
1202     This is the smallest rightBearing(char) of all characters in the
1203     font.
1204
1205     Note that this function can be very slow if the font is large.
1206
1207     \sa minLeftBearing(), rightBearing()
1208 */
1209 qreal QFontMetricsF::minRightBearing() const
1210 {
1211     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1212     Q_ASSERT(engine != 0);
1213     return engine->minRightBearing();
1214 }
1215
1216 /*!
1217     Returns the width of the widest character in the font.
1218 */
1219 qreal QFontMetricsF::maxWidth() const
1220 {
1221     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1222     Q_ASSERT(engine != 0);
1223     return engine->maxCharWidth();
1224 }
1225
1226 /*!
1227     Returns the 'x' height of the font. This is often but not always
1228     the same as the height of the character 'x'.
1229 */
1230 qreal QFontMetricsF::xHeight() const
1231 {
1232     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1233     Q_ASSERT(engine != 0);
1234     if (d->capital == QFont::SmallCaps)
1235         return d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::Common)->ascent().toReal();
1236     return engine->xHeight().toReal();
1237 }
1238
1239 /*!
1240     \since 4.2
1241
1242     Returns the average width of glyphs in the font.
1243 */
1244 qreal QFontMetricsF::averageCharWidth() const
1245 {
1246     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1247     Q_ASSERT(engine != 0);
1248     return engine->averageCharWidth().toReal();
1249 }
1250
1251 /*!
1252     Returns true if character \a ch is a valid character in the font;
1253     otherwise returns false.
1254 */
1255 bool QFontMetricsF::inFont(QChar ch) const
1256 {
1257     const int script = QUnicodeTables::script(ch);
1258     QFontEngine *engine = d->engineForScript(script);
1259     Q_ASSERT(engine != 0);
1260     if (engine->type() == QFontEngine::Box)
1261         return false;
1262     return engine->canRender(&ch, 1);
1263 }
1264
1265 /*!
1266     \fn bool QFontMetricsF::inFontUcs4(uint ch) const
1267
1268     Returns true if the character given by \a ch, encoded in UCS-4/UTF-32,
1269     is a valid character in the font; otherwise returns false.
1270 */
1271 bool QFontMetricsF::inFontUcs4(uint ucs4) const
1272 {
1273     const int script = QUnicodeTables::script(ucs4);
1274     QFontEngine *engine = d->engineForScript(script);
1275     Q_ASSERT(engine != 0);
1276     if (engine->type() == QFontEngine::Box)
1277         return false;
1278     return engine->canRender(ucs4);
1279 }
1280
1281 /*!
1282     Returns the left bearing of character \a ch in the font.
1283
1284     The left bearing is the right-ward distance of the left-most pixel
1285     of the character from the logical origin of the character. This
1286     value is negative if the pixels of the character extend to the
1287     left of the logical origin.
1288
1289     See width(QChar) for a graphical description of this metric.
1290
1291     \sa rightBearing(), minLeftBearing(), width()
1292 */
1293 qreal QFontMetricsF::leftBearing(QChar ch) const
1294 {
1295     const int script = QUnicodeTables::script(ch);
1296     QFontEngine *engine;
1297     if (d->capital == QFont::SmallCaps && ch.isLower())
1298         engine = d->smallCapsFontPrivate()->engineForScript(script);
1299     else
1300         engine = d->engineForScript(script);
1301     Q_ASSERT(engine != 0);
1302     if (engine->type() == QFontEngine::Box)
1303         return 0;
1304
1305     d->alterCharForCapitalization(ch);
1306
1307     QGlyphLayoutArray<10> glyphs;
1308     int nglyphs = 9;
1309     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
1310     // ### can nglyphs != 1 happen at all? Not currently I think
1311     qreal lb;
1312     engine->getGlyphBearings(glyphs.glyphs[0], &lb);
1313     return lb;
1314 }
1315
1316 /*!
1317     Returns the right bearing of character \a ch in the font.
1318
1319     The right bearing is the left-ward distance of the right-most
1320     pixel of the character from the logical origin of a subsequent
1321     character. This value is negative if the pixels of the character
1322     extend to the right of the width() of the character.
1323
1324     See width() for a graphical description of this metric.
1325
1326     \sa leftBearing(), minRightBearing(), width()
1327 */
1328 qreal QFontMetricsF::rightBearing(QChar ch) const
1329 {
1330     const int script = QUnicodeTables::script(ch);
1331     QFontEngine *engine;
1332     if (d->capital == QFont::SmallCaps && ch.isLower())
1333         engine = d->smallCapsFontPrivate()->engineForScript(script);
1334     else
1335         engine = d->engineForScript(script);
1336     Q_ASSERT(engine != 0);
1337     if (engine->type() == QFontEngine::Box)
1338         return 0;
1339
1340     d->alterCharForCapitalization(ch);
1341
1342     QGlyphLayoutArray<10> glyphs;
1343     int nglyphs = 9;
1344     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
1345     // ### can nglyphs != 1 happen at all? Not currently I think
1346     qreal rb;
1347     engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
1348     return rb;
1349
1350 }
1351
1352 /*!
1353     Returns the width in pixels of the characters in the given \a text.
1354
1355     Note that this value is \e not equal to the width returned by
1356     boundingRect().width() because boundingRect() returns a rectangle
1357     describing the pixels this string will cover whereas width()
1358     returns the distance to where the next string should be drawn.
1359
1360     \sa boundingRect()
1361 */
1362 qreal QFontMetricsF::width(const QString &text) const
1363 {
1364     int pos = text.indexOf(QLatin1Char('\x9c'));
1365     int len = (pos != -1) ? pos : text.length();
1366
1367     QStackTextEngine layout(text, QFont(d.data()));
1368     layout.ignoreBidi = true;
1369     layout.itemize();
1370     return layout.width(0, len).toReal();
1371 }
1372
1373 /*!
1374     \overload
1375
1376     \img bearings.png Bearings
1377
1378     Returns the logical width of character \a ch in pixels. This is a
1379     distance appropriate for drawing a subsequent character after \a
1380     ch.
1381
1382     Some of the metrics are described in the image to the right. The
1383     central dark rectangles cover the logical width() of each
1384     character. The outer pale rectangles cover the leftBearing() and
1385     rightBearing() of each character. Notice that the bearings of "f"
1386     in this particular font are both negative, while the bearings of
1387     "o" are both positive.
1388
1389     \warning This function will produce incorrect results for Arabic
1390     characters or non-spacing marks in the middle of a string, as the
1391     glyph shaping and positioning of marks that happens when
1392     processing strings cannot be taken into account. When implementing
1393     an interactive text control, use QTextLayout instead.
1394
1395     \sa boundingRect()
1396 */
1397 qreal QFontMetricsF::width(QChar ch) const
1398 {
1399     if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing)
1400         return 0.;
1401
1402     const int script = QUnicodeTables::script(ch);
1403     QFontEngine *engine;
1404     if (d->capital == QFont::SmallCaps && ch.isLower())
1405         engine = d->smallCapsFontPrivate()->engineForScript(script);
1406     else
1407         engine = d->engineForScript(script);
1408     Q_ASSERT(engine != 0);
1409
1410     d->alterCharForCapitalization(ch);
1411
1412     QGlyphLayoutArray<8> glyphs;
1413     int nglyphs = 7;
1414     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
1415     return glyphs.advances_x[0].toReal();
1416 }
1417
1418 /*!
1419     Returns the bounding rectangle of the characters in the string
1420     specified by \a text. The bounding rectangle always covers at least
1421     the set of pixels the text would cover if drawn at (0, 0).
1422
1423     Note that the bounding rectangle may extend to the left of (0, 0),
1424     e.g. for italicized fonts, and that the width of the returned
1425     rectangle might be different than what the width() method returns.
1426
1427     If you want to know the advance width of the string (to layout
1428     a set of strings next to each other), use width() instead.
1429
1430     Newline characters are processed as normal characters, \e not as
1431     linebreaks.
1432
1433     The height of the bounding rectangle is at least as large as the
1434     value returned height().
1435
1436     \sa width(), height(), QPainter::boundingRect()
1437 */
1438 QRectF QFontMetricsF::boundingRect(const QString &text) const
1439 {
1440     int len = text.length();
1441     if (len == 0)
1442         return QRectF();
1443
1444     QStackTextEngine layout(text, QFont(d.data()));
1445     layout.ignoreBidi = true;
1446     layout.itemize();
1447     glyph_metrics_t gm = layout.boundingBox(0, len);
1448     return QRectF(gm.x.toReal(), gm.y.toReal(),
1449                   gm.width.toReal(), gm.height.toReal());
1450 }
1451
1452 /*!
1453     Returns the bounding rectangle of the character \a ch relative to
1454     the left-most point on the base line.
1455
1456     Note that the bounding rectangle may extend to the left of (0, 0),
1457     e.g. for italicized fonts, and that the text output may cover \e
1458     all pixels in the bounding rectangle.
1459
1460     Note that the rectangle usually extends both above and below the
1461     base line.
1462
1463     \sa width()
1464 */
1465 QRectF QFontMetricsF::boundingRect(QChar ch) const
1466 {
1467     const int script = QUnicodeTables::script(ch);
1468     QFontEngine *engine;
1469     if (d->capital == QFont::SmallCaps && ch.isLower())
1470         engine = d->smallCapsFontPrivate()->engineForScript(script);
1471     else
1472         engine = d->engineForScript(script);
1473     Q_ASSERT(engine != 0);
1474
1475     d->alterCharForCapitalization(ch);
1476
1477     QGlyphLayoutArray<10> glyphs;
1478     int nglyphs = 9;
1479     engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
1480     glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]);
1481     return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
1482 }
1483
1484 /*!
1485     \overload
1486
1487     Returns the bounding rectangle of the characters in the given \a text.
1488     This is the set of pixels the text would cover if drawn when constrained
1489     to the bounding rectangle specified by \a rect.
1490
1491     The \a flags argument is the bitwise OR of the following flags:
1492     \list
1493     \li Qt::AlignLeft aligns to the left border, except for
1494           Arabic and Hebrew where it aligns to the right.
1495     \li Qt::AlignRight aligns to the right border, except for
1496           Arabic and Hebrew where it aligns to the left.
1497     \li Qt::AlignJustify produces justified text.
1498     \li Qt::AlignHCenter aligns horizontally centered.
1499     \li Qt::AlignTop aligns to the top border.
1500     \li Qt::AlignBottom aligns to the bottom border.
1501     \li Qt::AlignVCenter aligns vertically centered
1502     \li Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
1503     \li Qt::TextSingleLine ignores newline characters in the text.
1504     \li Qt::TextExpandTabs expands tabs (see below)
1505     \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
1506     \li Qt::TextWordWrap breaks the text to fit the rectangle.
1507     \endlist
1508
1509     Qt::Horizontal alignment defaults to Qt::AlignLeft and vertical
1510     alignment defaults to Qt::AlignTop.
1511
1512     If several of the horizontal or several of the vertical alignment
1513     flags are set, the resulting alignment is undefined.
1514
1515     These flags are defined in \l{Qt::AlignmentFlag}.
1516
1517     If Qt::TextExpandTabs is set in \a flags, the following behavior is
1518     used to interpret tab characters in the text:
1519     \list
1520     \li If \a tabArray is non-null, it specifies a 0-terminated sequence of
1521        pixel-positions for tabs in the text.
1522     \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
1523     \endlist
1524
1525     Note that the bounding rectangle may extend to the left of (0, 0),
1526     e.g. for italicized fonts.
1527
1528     Newline characters are processed as line breaks.
1529
1530     Despite the different actual character heights, the heights of the
1531     bounding rectangles of "Yes" and "yes" are the same.
1532
1533     The bounding rectangle returned by this function is somewhat larger
1534     than that calculated by the simpler boundingRect() function. This
1535     function uses the \l{minLeftBearing()}{maximum left} and
1536     \l{minRightBearing()}{right} font bearings as is
1537     necessary for multi-line text to align correctly. Also,
1538     fontHeight() and lineSpacing() are used to calculate the height,
1539     rather than individual character heights.
1540
1541     \sa width(), QPainter::boundingRect(), Qt::Alignment
1542 */
1543 QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& text,
1544                                    int tabStops, int *tabArray) const
1545 {
1546     int tabArrayLen = 0;
1547     if (tabArray)
1548         while (tabArray[tabArrayLen])
1549             tabArrayLen++;
1550
1551     QRectF rb;
1552     qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
1553                    tabArrayLen, 0);
1554     return rb;
1555 }
1556
1557 /*!
1558     Returns the size in pixels of the characters in the given \a text.
1559
1560     The \a flags argument is the bitwise OR of the following flags:
1561     \list
1562     \li Qt::TextSingleLine ignores newline characters.
1563     \li Qt::TextExpandTabs expands tabs (see below)
1564     \li Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
1565     \li Qt::TextWordBreak breaks the text to fit the rectangle.
1566     \endlist
1567
1568     These flags are defined in \l{Qt::TextFlags}.
1569
1570     If Qt::TextExpandTabs is set in \a flags, the following behavior is
1571     used to interpret tab characters in the text:
1572     \list
1573     \li If \a tabArray is non-null, it specifies a 0-terminated sequence of
1574        pixel-positions for tabs in the text.
1575     \li If \a tabStops is non-zero, it is used as the tab spacing (in pixels).
1576     \endlist
1577
1578     Newline characters are processed as line breaks.
1579
1580     Note: Despite the different actual character heights, the heights of the
1581     bounding rectangles of "Yes" and "yes" are the same.
1582
1583     \sa boundingRect()
1584 */
1585 QSizeF QFontMetricsF::size(int flags, const QString &text, int tabStops, int *tabArray) const
1586 {
1587     return boundingRect(QRectF(), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size();
1588 }
1589
1590 /*!
1591   \since 4.3
1592
1593     Returns a tight bounding rectangle around the characters in the
1594     string specified by \a text. The bounding rectangle always covers
1595     at least the set of pixels the text would cover if drawn at (0,
1596     0).
1597
1598     Note that the bounding rectangle may extend to the left of (0, 0),
1599     e.g. for italicized fonts, and that the width of the returned
1600     rectangle might be different than what the width() method returns.
1601
1602     If you want to know the advance width of the string (to layout
1603     a set of strings next to each other), use width() instead.
1604
1605     Newline characters are processed as normal characters, \e not as
1606     linebreaks.
1607
1608     \warning Calling this method is very slow on Windows.
1609
1610     \sa width(), height(), boundingRect()
1611 */
1612 QRectF QFontMetricsF::tightBoundingRect(const QString &text) const
1613 {
1614     if (text.length() == 0)
1615         return QRect();
1616
1617     QStackTextEngine layout(text, QFont(d.data()));
1618     layout.ignoreBidi = true;
1619     layout.itemize();
1620     glyph_metrics_t gm = layout.tightBoundingBox(0, text.length());
1621     return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
1622 }
1623
1624 /*!
1625     \since 4.2
1626
1627     If the string \a text is wider than \a width, returns an elided
1628     version of the string (i.e., a string with "..." in it).
1629     Otherwise, returns the original string.
1630
1631     The \a mode parameter specifies whether the text is elided on the
1632     left (e.g., "...tech"), in the middle (e.g., "Tr...ch"), or on
1633     the right (e.g., "Trol...").
1634
1635     The \a width is specified in pixels, not characters.
1636
1637     The \a flags argument is optional and currently only supports
1638     Qt::TextShowMnemonic as value.
1639 */
1640 QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const
1641 {
1642     QString _text = text;
1643     if (!(flags & Qt::TextLongestVariant)) {
1644         int posA = 0;
1645         int posB = _text.indexOf(QLatin1Char('\x9c'));
1646         while (posB >= 0) {
1647             QString portion = _text.mid(posA, posB - posA);
1648             if (size(flags, portion).width() <= width)
1649                 return portion;
1650             posA = posB + 1;
1651             posB = _text.indexOf(QLatin1Char('\x9c'), posA);
1652         }
1653         _text = _text.mid(posA);
1654     }
1655     QStackTextEngine engine(_text, QFont(d.data()));
1656     return engine.elidedText(mode, QFixed::fromReal(width), flags);
1657 }
1658
1659 /*!
1660     Returns the distance from the base line to where an underscore
1661     should be drawn.
1662
1663     \sa overlinePos(), strikeOutPos(), lineWidth()
1664 */
1665 qreal QFontMetricsF::underlinePos() const
1666 {
1667     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1668     Q_ASSERT(engine != 0);
1669     return engine->underlinePosition().toReal();
1670 }
1671
1672 /*!
1673     Returns the distance from the base line to where an overline
1674     should be drawn.
1675
1676     \sa underlinePos(), strikeOutPos(), lineWidth()
1677 */
1678 qreal QFontMetricsF::overlinePos() const
1679 {
1680     return ascent() + 1;
1681 }
1682
1683 /*!
1684     Returns the distance from the base line to where the strikeout
1685     line should be drawn.
1686
1687     \sa underlinePos(), overlinePos(), lineWidth()
1688 */
1689 qreal QFontMetricsF::strikeOutPos() const
1690 {
1691     return ascent() / 3.;
1692 }
1693
1694 /*!
1695     Returns the width of the underline and strikeout lines, adjusted
1696     for the point size of the font.
1697
1698     \sa underlinePos(), overlinePos(), strikeOutPos()
1699 */
1700 qreal QFontMetricsF::lineWidth() const
1701 {
1702     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1703     Q_ASSERT(engine != 0);
1704     return engine->lineThickness().toReal();
1705 }
1706
1707 QT_END_NAMESPACE