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