Coverage Report

Created: 2025-07-16 07:53

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