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