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