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

source code of qtbase/src/gui/text/qfontmetrics.cpp