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