Coverage Report

Created: 2026-03-31 07:41

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