Compile with clang when C++11 support is enabled
[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
69     \brief The QFontMetrics class provides font metrics information.
70
71     \ingroup painting
72     \ingroup shared
73
74     QFontMetrics functions calculate the size of characters and
75     strings for a given font. There are three ways you can create a
76     QFontMetrics object:
77
78     \list 1
79     \li Calling the QFontMetrics constructor with a QFont creates a
80     font metrics object for a screen-compatible font, i.e. the font
81     cannot be a printer font. If the font is changed
82     later, the font metrics object is \e not updated.
83
84     (Note: If you use a printer font the values returned may be
85     inaccurate. Printer fonts are not always accessible so the nearest
86     screen font is used if a printer font is supplied.)
87
88     \li QWidget::fontMetrics() returns the font metrics for a widget's
89     font. This is equivalent to QFontMetrics(widget->font()). If the
90     widget's font is changed later, the font metrics object is \e not
91     updated.
92
93     \li QPainter::fontMetrics() returns the font metrics for a
94     painter's current font. If the painter's font is changed later, the
95     font metrics object is \e not updated.
96     \endlist
97
98     Once created, the object provides functions to access the
99     individual metrics of the font, its characters, and for strings
100     rendered in the font.
101
102     There are several functions that operate on the font: ascent(),
103     descent(), height(), leading() and lineSpacing() return the basic
104     size properties of the font. The underlinePos(), overlinePos(),
105     strikeOutPos() and lineWidth() functions, return the properties of
106     the line that underlines, overlines or strikes out the
107     characters. These functions are all fast.
108
109     There are also some functions that operate on the set of glyphs in
110     the font: minLeftBearing(), minRightBearing() and maxWidth().
111     These are by necessity slow, and we recommend avoiding them if
112     possible.
113
114     For each character, you can get its width(), leftBearing() and
115     rightBearing() and find out whether it is in the font using
116     inFont(). You can also treat the character as a string, and use
117     the string functions on it.
118
119     The string functions include width(), to return the width of a
120     string in pixels (or points, for a printer), boundingRect(), to
121     return a rectangle large enough to contain the rendered string,
122     and size(), to return the size of that rectangle.
123
124     Example:
125     \snippet code/src_gui_text_qfontmetrics.cpp 0
126
127     \sa QFont, QFontInfo, QFontDatabase, QFontComboBox, {Character Map Example}
128 */
129
130 /*!
131     \fn QRect QFontMetrics::boundingRect(int x, int y, int width, int height,
132         int flags, const QString &text, int tabStops, int *tabArray) const
133     \overload
134
135     Returns the bounding rectangle for the given \a text within the
136     rectangle specified by the \a x and \a y coordinates, \a width, and
137     \a height.
138
139     If Qt::TextExpandTabs is set in \a flags and \a tabArray is
140     non-null, it specifies a 0-terminated sequence of pixel-positions
141     for tabs; otherwise, if \a tabStops is non-zero, it is used as the
142     tab spacing (in pixels).
143 */
144
145 /*!
146     Constructs a font metrics object for \a font.
147
148     The font metrics will be compatible with the paintdevice used to
149     create \a font.
150
151     The font metrics object holds the information for the font that is
152     passed in the constructor at the time it is created, and is not
153     updated if the font's attributes are changed later.
154
155     Use QFontMetrics(const QFont &, QPaintDevice *) to get the font
156     metrics that are compatible with a certain paint device.
157 */
158 QFontMetrics::QFontMetrics(const QFont &font)
159     : d(font.d.data())
160 {
161 }
162
163 /*!
164     Constructs a font metrics object for \a font and \a paintdevice.
165
166     The font metrics will be compatible with the paintdevice passed.
167     If the \a paintdevice is 0, the metrics will be screen-compatible,
168     ie. the metrics you get if you use the font for drawing text on a
169     \l{QWidget}{widgets} or \l{QPixmap}{pixmaps},
170     not on a QPicture or QPrinter.
171
172     The font metrics object holds the information for the font that is
173     passed in the constructor at the time it is created, and is not
174     updated if the font's attributes are changed later.
175 */
176 QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
177 {
178     int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
179     const int screen = 0;
180     if (font.d->dpi != dpi || font.d->screen != screen ) {
181         d = new QFontPrivate(*font.d);
182         d->dpi = dpi;
183         d->screen = screen;
184     } else {
185         d = font.d.data();
186     }
187
188 }
189
190 /*!
191     Constructs a copy of \a fm.
192 */
193 QFontMetrics::QFontMetrics(const QFontMetrics &fm)
194     : d(fm.d.data())
195 {
196 }
197
198 /*!
199     Destroys the font metrics object and frees all allocated
200     resources.
201 */
202 QFontMetrics::~QFontMetrics()
203 {
204 }
205
206 /*!
207     Assigns the font metrics \a fm.
208 */
209 QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm)
210 {
211     d = fm.d.data();
212     return *this;
213 }
214
215 /*!
216     Returns true if \a other is equal to this object; otherwise
217     returns false.
218
219     Two font metrics are considered equal if they were constructed
220     from the same QFont and the paint devices they were constructed
221     for are considered compatible.
222
223     \sa operator!=()
224 */
225 bool QFontMetrics::operator ==(const QFontMetrics &other) const
226 {
227     return d == other.d;
228 }
229
230 /*!
231     \fn bool QFontMetrics::operator !=(const QFontMetrics &other) const
232
233     Returns true if \a other is not equal to this object; otherwise returns false.
234
235     Two font metrics are considered equal if they were constructed
236     from the same QFont and the paint devices they were constructed
237     for are considered compatible.
238
239     \sa operator==()
240 */
241
242 /*!
243     Returns the ascent of the font.
244
245     The ascent of a font is the distance from the baseline to the
246     highest position characters extend to. In practice, some font
247     designers break this rule, e.g. when they put more than one accent
248     on top of a character, or to accommodate an unusual character in
249     an exotic language, so it is possible (though rare) that this
250     value will be too small.
251
252     \sa descent()
253 */
254 int QFontMetrics::ascent() const
255 {
256     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
257     Q_ASSERT(engine != 0);
258     return qRound(engine->ascent());
259 }
260
261
262 /*!
263     Returns the descent of the font.
264
265     The descent is the distance from the base line to the lowest point
266     characters extend to. In practice, some font designers break this rule,
267     e.g. to accommodate an unusual character in an exotic language, so
268     it is possible (though rare) that this value will be too small.
269
270     \sa ascent()
271 */
272 int QFontMetrics::descent() const
273 {
274     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
275     Q_ASSERT(engine != 0);
276     return qRound(engine->descent());
277 }
278
279 /*!
280     Returns the height of the font.
281
282     This is always equal to ascent()+descent()+1 (the 1 is for the
283     base line).
284
285     \sa leading(), lineSpacing()
286 */
287 int QFontMetrics::height() const
288 {
289     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
290     Q_ASSERT(engine != 0);
291     return qRound(engine->ascent()) + qRound(engine->descent());
292 }
293
294 /*!
295     Returns the leading of the font.
296
297     This is the natural inter-line spacing.
298
299     \sa height(), lineSpacing()
300 */
301 int QFontMetrics::leading() const
302 {
303     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
304     Q_ASSERT(engine != 0);
305     return qRound(engine->leading());
306 }
307
308 /*!
309     Returns the distance from one base line to the next.
310
311     This value is always equal to leading()+height().
312
313     \sa height(), leading()
314 */
315 int QFontMetrics::lineSpacing() const
316 {
317     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
318     Q_ASSERT(engine != 0);
319     return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent());
320 }
321
322 /*!
323     Returns the minimum left bearing of the font.
324
325     This is the smallest leftBearing(char) of all characters in the
326     font.
327
328     Note that this function can be very slow if the font is large.
329
330     \sa minRightBearing(), leftBearing()
331 */
332 int QFontMetrics::minLeftBearing() const
333 {
334     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
335     Q_ASSERT(engine != 0);
336     return qRound(engine->minLeftBearing());
337 }
338
339 /*!
340     Returns the minimum right bearing of the font.
341
342     This is the smallest rightBearing(char) of all characters in the
343     font.
344
345     Note that this function can be very slow if the font is large.
346
347     \sa minLeftBearing(), rightBearing()
348 */
349 int QFontMetrics::minRightBearing() const
350 {
351     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
352     Q_ASSERT(engine != 0);
353     return qRound(engine->minRightBearing());
354 }
355
356 /*!
357     Returns the width of the widest character in the font.
358 */
359 int QFontMetrics::maxWidth() const
360 {
361     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
362     Q_ASSERT(engine != 0);
363     return qRound(engine->maxCharWidth());
364 }
365
366 /*!
367     Returns the 'x' height of the font. This is often but not always
368     the same as the height of the character 'x'.
369 */
370 int QFontMetrics::xHeight() const
371 {
372     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
373     Q_ASSERT(engine != 0);
374     if (d->capital == QFont::SmallCaps)
375         return qRound(d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::Common)->ascent());
376     return qRound(engine->xHeight());
377 }
378
379 /*!
380     \since 4.2
381
382     Returns the average width of glyphs in the font.
383 */
384 int QFontMetrics::averageCharWidth() const
385 {
386     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
387     Q_ASSERT(engine != 0);
388     return qRound(engine->averageCharWidth());
389 }
390
391 /*!
392     Returns true if character \a ch is a valid character in the font;
393     otherwise returns false.
394 */
395 bool QFontMetrics::inFont(QChar ch) const
396 {
397     const int script = QUnicodeTables::script(ch);
398     QFontEngine *engine = d->engineForScript(script);
399     Q_ASSERT(engine != 0);
400     if (engine->type() == QFontEngine::Box)
401         return false;
402     return engine->canRender(&ch, 1);
403 }
404
405 /*!
406    Returns true if the character encoded in UCS-4/UTF-32 is a valid
407    character in the font; otherwise returns false.
408 */
409 bool QFontMetrics::inFontUcs4(uint ucs4) const
410 {
411     const int script = QUnicodeTables::script(ucs4);
412     QFontEngine *engine = d->engineForScript(script);
413     Q_ASSERT(engine != 0);
414     if (engine->type() == QFontEngine::Box)
415         return false;
416     QString utf16 = QString::fromUcs4(&ucs4, 1);
417     return engine->canRender(utf16.data(), utf16.length());
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
942     \brief The QFontMetricsF class provides font metrics information.
943
944     \ingroup painting
945     \ingroup shared
946
947     QFontMetricsF functions calculate the size of characters and
948     strings for a given font. You can construct a QFontMetricsF object
949     with an existing QFont to obtain metrics for that font. If the
950     font is changed later, the font metrics object is \e not updated.
951
952     Once created, the object provides functions to access the
953     individual metrics of the font, its characters, and for strings
954     rendered in the font.
955
956     There are several functions that operate on the font: ascent(),
957     descent(), height(), leading() and lineSpacing() return the basic
958     size properties of the font. The underlinePos(), overlinePos(),
959     strikeOutPos() and lineWidth() functions, return the properties of
960     the line that underlines, overlines or strikes out the
961     characters. These functions are all fast.
962
963     There are also some functions that operate on the set of glyphs in
964     the font: minLeftBearing(), minRightBearing() and maxWidth().
965     These are by necessity slow, and we recommend avoiding them if
966     possible.
967
968     For each character, you can get its width(), leftBearing() and
969     rightBearing() and find out whether it is in the font using
970     inFont(). You can also treat the character as a string, and use
971     the string functions on it.
972
973     The string functions include width(), to return the width of a
974     string in pixels (or points, for a printer), boundingRect(), to
975     return a rectangle large enough to contain the rendered string,
976     and size(), to return the size of that rectangle.
977
978     Example:
979     \snippet code/src_gui_text_qfontmetrics.cpp 1
980
981     \sa QFont, QFontInfo, QFontDatabase
982 */
983
984 /*!
985     \since 4.2
986
987     Constructs a font metrics object with floating point precision
988     from the given \a fontMetrics object.
989 */
990 QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
991     : d(fontMetrics.d.data())
992 {
993 }
994
995 /*!
996     \since 4.2
997
998     Assigns \a other to this object.
999 */
1000 QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
1001 {
1002     d = other.d.data();
1003     return *this;
1004 }
1005
1006 /*!
1007     Constructs a font metrics object for \a font.
1008
1009     The font metrics will be compatible with the paintdevice used to
1010     create \a font.
1011
1012     The font metrics object holds the information for the font that is
1013     passed in the constructor at the time it is created, and is not
1014     updated if the font's attributes are changed later.
1015
1016     Use QFontMetricsF(const QFont &, QPaintDevice *) to get the font
1017     metrics that are compatible with a certain paint device.
1018 */
1019 QFontMetricsF::QFontMetricsF(const QFont &font)
1020     : d(font.d.data())
1021 {
1022 }
1023
1024 /*!
1025     Constructs a font metrics object for \a font and \a paintdevice.
1026
1027     The font metrics will be compatible with the paintdevice passed.
1028     If the \a paintdevice is 0, the metrics will be screen-compatible,
1029     ie. the metrics you get if you use the font for drawing text on a
1030     \l{QWidget}{widgets} or \l{QPixmap}{pixmaps},
1031     not on a QPicture or QPrinter.
1032
1033     The font metrics object holds the information for the font that is
1034     passed in the constructor at the time it is created, and is not
1035     updated if the font's attributes are changed later.
1036 */
1037 QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
1038 {
1039     int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
1040     const int screen = 0;
1041     if (font.d->dpi != dpi || font.d->screen != screen ) {
1042         d = new QFontPrivate(*font.d);
1043         d->dpi = dpi;
1044         d->screen = screen;
1045     } else {
1046         d = font.d.data();
1047     }
1048
1049 }
1050
1051 /*!
1052     Constructs a copy of \a fm.
1053 */
1054 QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
1055     : d(fm.d.data())
1056 {
1057 }
1058
1059 /*!
1060     Destroys the font metrics object and frees all allocated
1061     resources.
1062 */
1063 QFontMetricsF::~QFontMetricsF()
1064 {
1065 }
1066
1067 /*!
1068     Assigns the font metrics \a fm to this font metrics object.
1069 */
1070 QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm)
1071 {
1072     d = fm.d.data();
1073     return *this;
1074 }
1075
1076 /*!
1077   Returns true if the font metrics are equal to the \a other font
1078   metrics; otherwise returns false.
1079
1080   Two font metrics are considered equal if they were constructed from the
1081   same QFont and the paint devices they were constructed for are
1082   considered to be compatible.
1083 */
1084 bool QFontMetricsF::operator ==(const QFontMetricsF &other) const
1085 {
1086     return d == other.d;
1087 }
1088
1089 /*!
1090     \fn bool QFontMetricsF::operator !=(const QFontMetricsF &other) const
1091     \overload
1092
1093     Returns true if the font metrics are not equal to the \a other font
1094     metrics; otherwise returns false.
1095
1096     \sa operator==()
1097 */
1098
1099 /*!
1100     Returns the ascent of the font.
1101
1102     The ascent of a font is the distance from the baseline to the
1103     highest position characters extend to. In practice, some font
1104     designers break this rule, e.g. when they put more than one accent
1105     on top of a character, or to accommodate an unusual character in
1106     an exotic language, so it is possible (though rare) that this
1107     value will be too small.
1108
1109     \sa descent()
1110 */
1111 qreal QFontMetricsF::ascent() const
1112 {
1113     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1114     Q_ASSERT(engine != 0);
1115     return engine->ascent().toReal();
1116 }
1117
1118
1119 /*!
1120     Returns the descent of the font.
1121
1122     The descent is the distance from the base line to the lowest point
1123     characters extend to. (Note that this is different from X, which
1124     adds 1 pixel.) In practice, some font designers break this rule,
1125     e.g. to accommodate an unusual character in an exotic language, so
1126     it is possible (though rare) that this value will be too small.
1127
1128     \sa ascent()
1129 */
1130 qreal QFontMetricsF::descent() const
1131 {
1132     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1133     Q_ASSERT(engine != 0);
1134     return engine->descent().toReal();
1135 }
1136
1137 /*!
1138     Returns the height of the font.
1139
1140     This is always equal to ascent()+descent()+1 (the 1 is for the
1141     base line).
1142
1143     \sa leading(), lineSpacing()
1144 */
1145 qreal QFontMetricsF::height() const
1146 {
1147     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1148     Q_ASSERT(engine != 0);
1149
1150     return (engine->ascent() + engine->descent()).toReal();
1151 }
1152
1153 /*!
1154     Returns the leading of the font.
1155
1156     This is the natural inter-line spacing.
1157
1158     \sa height(), lineSpacing()
1159 */
1160 qreal QFontMetricsF::leading() const
1161 {
1162     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1163     Q_ASSERT(engine != 0);
1164     return engine->leading().toReal();
1165 }
1166
1167 /*!
1168     Returns the distance from one base line to the next.
1169
1170     This value is always equal to leading()+height().
1171
1172     \sa height(), leading()
1173 */
1174 qreal QFontMetricsF::lineSpacing() const
1175 {
1176     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1177     Q_ASSERT(engine != 0);
1178     return (engine->leading() + engine->ascent() + engine->descent()).toReal();
1179 }
1180
1181 /*!
1182     Returns the minimum left bearing of the font.
1183
1184     This is the smallest leftBearing(char) of all characters in the
1185     font.
1186
1187     Note that this function can be very slow if the font is large.
1188
1189     \sa minRightBearing(), leftBearing()
1190 */
1191 qreal QFontMetricsF::minLeftBearing() const
1192 {
1193     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1194     Q_ASSERT(engine != 0);
1195     return engine->minLeftBearing();
1196 }
1197
1198 /*!
1199     Returns the minimum right bearing of the font.
1200
1201     This is the smallest rightBearing(char) of all characters in the
1202     font.
1203
1204     Note that this function can be very slow if the font is large.
1205
1206     \sa minLeftBearing(), rightBearing()
1207 */
1208 qreal QFontMetricsF::minRightBearing() const
1209 {
1210     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1211     Q_ASSERT(engine != 0);
1212     return engine->minRightBearing();
1213 }
1214
1215 /*!
1216     Returns the width of the widest character in the font.
1217 */
1218 qreal QFontMetricsF::maxWidth() const
1219 {
1220     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1221     Q_ASSERT(engine != 0);
1222     return engine->maxCharWidth();
1223 }
1224
1225 /*!
1226     Returns the 'x' height of the font. This is often but not always
1227     the same as the height of the character 'x'.
1228 */
1229 qreal QFontMetricsF::xHeight() const
1230 {
1231     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1232     Q_ASSERT(engine != 0);
1233     if (d->capital == QFont::SmallCaps)
1234         return d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::Common)->ascent().toReal();
1235     return engine->xHeight().toReal();
1236 }
1237
1238 /*!
1239     \since 4.2
1240
1241     Returns the average width of glyphs in the font.
1242 */
1243 qreal QFontMetricsF::averageCharWidth() const
1244 {
1245     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
1246     Q_ASSERT(engine != 0);
1247     return engine->averageCharWidth().toReal();
1248 }
1249
1250 /*!
1251     Returns true if character \a ch is a valid character in the font;
1252     otherwise returns false.
1253 */
1254 bool QFontMetricsF::inFont(QChar ch) const
1255 {
1256     const int script = QUnicodeTables::script(ch);
1257     QFontEngine *engine = d->engineForScript(script);
1258     Q_ASSERT(engine != 0);
1259     if (engine->type() == QFontEngine::Box)
1260         return false;
1261     return engine->canRender(&ch, 1);
1262 }
1263
1264 /*!
1265     \fn bool QFontMetricsF::inFontUcs4(uint ch) const
1266
1267     Returns true if the character given by \a ch, encoded in UCS-4/UTF-32,
1268     is a valid character in the font; otherwise returns false.
1269 */
1270 bool QFontMetricsF::inFontUcs4(uint ucs4) const
1271 {
1272     const int script = QUnicodeTables::script(ucs4);
1273     QFontEngine *engine = d->engineForScript(script);
1274     Q_ASSERT(engine != 0);
1275     if (engine->type() == QFontEngine::Box)
1276         return false;
1277     QString utf16 = QString::fromUcs4(&ucs4, 1);
1278     return engine->canRender(utf16.data(), utf16.length());
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