Coverage Report

Created: 2026-08-17 07:50

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