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