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

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