~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/text/qfontmetrics.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the text module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qfont.h"
 
30
#include "qpaintdevice.h"
 
31
#include "qfontmetrics.h"
 
32
 
 
33
#include "qfont_p.h"
 
34
#include "qfontengine_p.h"
 
35
#include <private/qunicodetables_p.h>
 
36
 
 
37
#ifdef Q_WS_X11
 
38
#include "qx11info_x11.h"
 
39
extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
 
40
#endif
 
41
 
 
42
extern void qt_format_text(const QFont& font, const QRectF &_r,
 
43
                           int tf, const QString& str, QRectF *brect,
 
44
                           int tabstops, int* tabarray, int tabarraylen,
 
45
                           QPainter* painter);
 
46
extern int qt_defaultDpi();
 
47
 
 
48
/*****************************************************************************
 
49
  QFontMetrics member functions
 
50
 *****************************************************************************/
 
51
 
 
52
/*!
 
53
    \class QFontMetrics qfontmetrics.h
 
54
    \brief The QFontMetrics class provides font metrics information.
 
55
 
 
56
    \ingroup multimedia
 
57
    \ingroup shared
 
58
 
 
59
    QFontMetrics functions calculate the size of characters and
 
60
    strings for a given font. There are three ways you can create a
 
61
    QFontMetrics object:
 
62
 
 
63
    \list 1
 
64
    \i Calling the QFontMetrics constructor with a QFont creates a
 
65
    font metrics object for a screen-compatible font, i.e. the font
 
66
    cannot be a printer font. If the font is changed
 
67
    later, the font metrics object is \e not updated.
 
68
 
 
69
    (Note: If you use a printer font the values returned may be
 
70
    inaccurate. Printer fonts are not always accessible so the nearest
 
71
    screen font is used if a printer font is supplied.)
 
72
 
 
73
    \i QWidget::fontMetrics() returns the font metrics for a widget's
 
74
    font. This is equivalent to QFontMetrics(widget->font()). If the
 
75
    widget's font is changed later, the font metrics object is \e not
 
76
    updated.
 
77
 
 
78
    \i QPainter::fontMetrics() returns the font metrics for a
 
79
    painter's current font. If the painter's font is changed later, the
 
80
    font metrics object is \e not updated.
 
81
    \endlist
 
82
 
 
83
    Once created, the object provides functions to access the
 
84
    individual metrics of the font, its characters, and for strings
 
85
    rendered in the font.
 
86
 
 
87
    There are several functions that operate on the font: ascent(),
 
88
    descent(), height(), leading() and lineSpacing() return the basic
 
89
    size properties of the font. The underlinePos(), overlinePos(),
 
90
    strikeOutPos() and lineWidth() functions, return the properties of
 
91
    the line that underlines, overlines or strikes out the
 
92
    characters. These functions are all fast.
 
93
 
 
94
    There are also some functions that operate on the set of glyphs in
 
95
    the font: minLeftBearing(), minRightBearing() and maxWidth().
 
96
    These are by necessity slow, and we recommend avoiding them if
 
97
    possible.
 
98
 
 
99
    For each character, you can get its width(), leftBearing() and
 
100
    rightBearing() and find out whether it is in the font using
 
101
    inFont(). You can also treat the character as a string, and use
 
102
    the string functions on it.
 
103
 
 
104
    The string functions include width(), to return the width of a
 
105
    string in pixels (or points, for a printer), boundingRect(), to
 
106
    return a rectangle large enough to contain the rendered string,
 
107
    and size(), to return the size of that rectangle.
 
108
 
 
109
    Example:
 
110
    \code
 
111
    QFont font("times", 24);
 
112
    QFontMetrics fm(font);
 
113
    int pixelsWide = fm.width("What's the width of this text?");
 
114
    int pixelsHigh = fm.height();
 
115
    \endcode
 
116
 
 
117
    \sa QFont QFontInfo QFontDatabase
 
118
*/
 
119
 
 
120
/*!
 
121
    \fn QRect QFontMetrics::boundingRect(int x, int y, int width, int height,
 
122
        int flags, const QString &text, int tabstops, int *tabarray) const
 
123
    \overload
 
124
 
 
125
    Returns the bounding rectangle for the given \a text within the
 
126
    rectangle specified by the \a x and \a y coordinates, \a width, and
 
127
    \a height.
 
128
 
 
129
    If \c Qt::TextExpandTabs is set in \a flags and \a tabarray is
 
130
    non-null, it specifies a 0-terminated sequence of pixel-positions
 
131
    for tabs; otherwise, if \a tabstops is non-zero, it is used as the
 
132
    tab spacing (in pixels).
 
133
*/
 
134
 
 
135
/*!
 
136
    Constructs a font metrics object for \a font.
 
137
 
 
138
    The font metrics will be compatible with the paintdevice used to
 
139
    create \a font.
 
140
 
 
141
    The font metrics object holds the information for the font that is
 
142
    passed in the constructor at the time it is created, and is not
 
143
    updated if the font's attributes are changed later.
 
144
 
 
145
    Use QFontMetrics(const QFont &, QPaintDevice *) to get the font
 
146
    metrics that are compatible with a certain paint device.
 
147
*/
 
148
QFontMetrics::QFontMetrics(const QFont &font)
 
149
    : d(font.d)
 
150
{
 
151
    d->ref.ref();
 
152
}
 
153
 
 
154
/*!
 
155
    Constructs a font metrics object for \a font and \a paintdevice.
 
156
 
 
157
    The font metrics will be compatible with the paintdevice passed.
 
158
    If the \a paintdevice is 0, the metrics will be screen-compatible,
 
159
    ie. the metrics you get if you use the font for drawing text on a
 
160
    \link QWidget widgets\endlink or \link QPixmap pixmaps\endlink,
 
161
    not on a QPicture or QPrinter.
 
162
 
 
163
    The font metrics object holds the information for the font that is
 
164
    passed in the constructor at the time it is created, and is not
 
165
    updated if the font's attributes are changed later.
 
166
*/
 
167
QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
 
168
{
 
169
    int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
 
170
#ifdef Q_WS_X11
 
171
    const QX11Info *info = qt_x11Info(paintdevice);
 
172
    int screen = info ? info->screen() : 0;
 
173
#else
 
174
    const int screen = 0;
 
175
#endif
 
176
    if (font.d->dpi != dpi || font.d->screen != screen ) {
 
177
        d = new QFontPrivate(*font.d);
 
178
        d->dpi = dpi;
 
179
        d->screen = screen;
 
180
    } else {
 
181
        d = font.d;
 
182
        d->ref.ref();
 
183
    }
 
184
 
 
185
}
 
186
 
 
187
/*!
 
188
    Constructs a copy of \a fm.
 
189
*/
 
190
QFontMetrics::QFontMetrics(const QFontMetrics &fm)
 
191
    : d(fm.d)
 
192
{ d->ref.ref(); }
 
193
 
 
194
/*!
 
195
    Destroys the font metrics object and frees all allocated
 
196
    resources.
 
197
*/
 
198
QFontMetrics::~QFontMetrics()
 
199
{
 
200
    if (!d->ref.deref())
 
201
        delete d;
 
202
}
 
203
 
 
204
/*!
 
205
    Assigns the font metrics \a fm.
 
206
*/
 
207
QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm)
 
208
{
 
209
    qAtomicAssign(d, fm.d);
 
210
    return *this;
 
211
}
 
212
 
 
213
/*!
 
214
    Returns true if \a other is equal to this object; otherwise
 
215
    returns false.
 
216
 
 
217
    Two font metrics are considered equal if they were constructed
 
218
    from the same QFont and the paint devices they were constructed
 
219
    for are considered compatible.
 
220
 
 
221
    \sa operator!=()
 
222
*/
 
223
bool QFontMetrics::operator ==(const QFontMetrics &other)
 
224
{
 
225
    return d == other.d;
 
226
}
 
227
 
 
228
/*!
 
229
    \fn bool QFontMetrics::operator !=(const QFontMetrics &other)
 
230
 
 
231
    Returns true if \a other is not equal to this object; otherwise returns false.
 
232
 
 
233
    Two font metrics are considered equal if they were constructed
 
234
    from the same QFont and the paint devices they were constructed
 
235
    for are considered compatible.
 
236
 
 
237
    \sa operator==()
 
238
*/
 
239
 
 
240
/*!
 
241
    Returns the ascent of the font.
 
242
 
 
243
    The ascent of a font is the distance from the baseline to the
 
244
    highest position characters extend to. In practice, some font
 
245
    designers break this rule, e.g. when they put more than one accent
 
246
    on top of a character, or to accommodate an unusual character in
 
247
    an exotic language, so it is possible (though rare) that this
 
248
    value will be too small.
 
249
 
 
250
    \sa descent()
 
251
*/
 
252
int QFontMetrics::ascent() const
 
253
{
 
254
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
255
    Q_ASSERT(engine != 0);
 
256
    return qRound(engine->ascent());
 
257
}
 
258
 
 
259
 
 
260
/*!
 
261
    Returns the descent of the font.
 
262
 
 
263
    The descent is the distance from the base line to the lowest point
 
264
    characters extend to. (Note that this is different from X, which
 
265
    adds 1 pixel.) In practice, some font designers break this rule,
 
266
    e.g. to accommodate an unusual character in an exotic language, so
 
267
    it is possible (though rare) that this value will be too small.
 
268
 
 
269
    \sa ascent()
 
270
*/
 
271
int QFontMetrics::descent() const
 
272
{
 
273
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
274
    Q_ASSERT(engine != 0);
 
275
    return qRound(engine->descent());
 
276
}
 
277
 
 
278
/*!
 
279
    Returns the height of the font.
 
280
 
 
281
    This is always equal to ascent()+descent()+1 (the 1 is for the
 
282
    base line).
 
283
 
 
284
    \sa leading(), lineSpacing()
 
285
*/
 
286
int QFontMetrics::height() const
 
287
{
 
288
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
289
    Q_ASSERT(engine != 0);
 
290
    return qRound(engine->ascent() + engine->descent()) + 1;
 
291
}
 
292
 
 
293
/*!
 
294
    Returns the leading of the font.
 
295
 
 
296
    This is the natural inter-line spacing.
 
297
 
 
298
    \sa height(), lineSpacing()
 
299
*/
 
300
int QFontMetrics::leading() const
 
301
{
 
302
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
303
    Q_ASSERT(engine != 0);
 
304
    return qRound(engine->leading());
 
305
}
 
306
 
 
307
/*!
 
308
    Returns the distance from one base line to the next.
 
309
 
 
310
    This value is always equal to leading()+height().
 
311
 
 
312
    \sa height(), leading()
 
313
*/
 
314
int QFontMetrics::lineSpacing() const
 
315
{
 
316
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
317
    Q_ASSERT(engine != 0);
 
318
    return qRound(engine->leading() + engine->ascent() + engine->descent()) + 1;
 
319
}
 
320
 
 
321
/*!
 
322
    Returns the minimum left bearing of the font.
 
323
 
 
324
    This is the smallest leftBearing(char) of all characters in the
 
325
    font.
 
326
 
 
327
    Note that this function can be very slow if the font is large.
 
328
 
 
329
    \sa minRightBearing(), leftBearing()
 
330
*/
 
331
int QFontMetrics::minLeftBearing() const
 
332
{
 
333
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
334
    Q_ASSERT(engine != 0);
 
335
    return qRound(engine->minLeftBearing());
 
336
}
 
337
 
 
338
/*!
 
339
    Returns the minimum right bearing of the font.
 
340
 
 
341
    This is the smallest rightBearing(char) of all characters in the
 
342
    font.
 
343
 
 
344
    Note that this function can be very slow if the font is large.
 
345
 
 
346
    \sa minLeftBearing(), rightBearing()
 
347
*/
 
348
int QFontMetrics::minRightBearing() const
 
349
{
 
350
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
351
    Q_ASSERT(engine != 0);
 
352
    return qRound(engine->minRightBearing());
 
353
}
 
354
 
 
355
/*!
 
356
    Returns the width of the widest character in the font.
 
357
*/
 
358
int QFontMetrics::maxWidth() const
 
359
{
 
360
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
361
    Q_ASSERT(engine != 0);
 
362
    return qRound(engine->maxCharWidth());
 
363
}
 
364
 
 
365
/*!
 
366
    Returns true if character \a ch is a valid character in the font;
 
367
    otherwise returns false.
 
368
*/
 
369
bool QFontMetrics::inFont(QChar ch) const
 
370
{
 
371
    const int script = QUnicodeTables::script(ch);
 
372
    QFontEngine *engine = d->engineForScript(script);
 
373
    Q_ASSERT(engine != 0);
 
374
    if (engine->type() == QFontEngine::Box)
 
375
        return false;
 
376
    return engine->canRender(&ch, 1);
 
377
}
 
378
 
 
379
/*! \fn int QFontMetrics::leftBearing(QChar ch) const
 
380
    Returns the left bearing of character \a ch in the font.
 
381
 
 
382
    The left bearing is the right-ward distance of the left-most pixel
 
383
    of the character from the logical origin of the character. This
 
384
    value is negative if the pixels of the character extend to the
 
385
    left of the logical origin.
 
386
 
 
387
    See width(QChar) for a graphical description of this metric.
 
388
 
 
389
    \sa rightBearing(), minLeftBearing(), width()
 
390
*/
 
391
int QFontMetrics::leftBearing(QChar ch) const
 
392
{
 
393
    const int script = QUnicodeTables::script(ch);
 
394
    QFontEngine *engine = d->engineForScript(script);
 
395
    Q_ASSERT(engine != 0);
 
396
    if (engine->type() == QFontEngine::Box)
 
397
        return 0;
 
398
 
 
399
    QGlyphLayout glyphs[10];
 
400
    int nglyphs = 9;
 
401
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
402
    // ### can nglyphs != 1 happen at all? Not currently I think
 
403
    glyph_metrics_t gi = engine->boundingBox(glyphs[0].glyph);
 
404
    return qRound(gi.x);
 
405
}
 
406
 
 
407
/*! \fn int QFontMetrics::rightBearing(QChar ch) const
 
408
    Returns the right bearing of character \a ch in the font.
 
409
 
 
410
    The right bearing is the left-ward distance of the right-most
 
411
    pixel of the character from the logical origin of a subsequent
 
412
    character. This value is negative if the pixels of the character
 
413
    extend to the right of the width() of the character.
 
414
 
 
415
    See width() for a graphical description of this metric.
 
416
 
 
417
    \sa leftBearing(), minRightBearing(), width()
 
418
*/
 
419
int QFontMetrics::rightBearing(QChar ch) const
 
420
{
 
421
    const int script = QUnicodeTables::script(ch);
 
422
    QFontEngine *engine = d->engineForScript(script);
 
423
    Q_ASSERT(engine != 0);
 
424
    if (engine->type() == QFontEngine::Box)
 
425
        return 0;
 
426
 
 
427
    QGlyphLayout glyphs[10];
 
428
    int nglyphs = 9;
 
429
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
430
    // ### can nglyphs != 1 happen at all? Not currently I think
 
431
    glyph_metrics_t gi = engine->boundingBox(glyphs[0].glyph);
 
432
    return qRound(gi.xoff - gi.x - gi.width);
 
433
}
 
434
 
 
435
/*!
 
436
    Returns the width in pixels of the first \a len characters of \a
 
437
    str. If \a len is negative (the default), the entire string is
 
438
    used.
 
439
 
 
440
    Note that this value is \e not equal to boundingRect().width();
 
441
    boundingRect() returns a rectangle describing the pixels this
 
442
    string will cover whereas width() returns the distance to where
 
443
    the next string should be drawn.
 
444
 
 
445
    \sa boundingRect()
 
446
*/
 
447
int QFontMetrics::width(const QString &str, int len) const
 
448
{
 
449
    if (len < 0)
 
450
        len = str.length();
 
451
    if (len == 0)
 
452
        return 0;
 
453
 
 
454
    QTextEngine layout(str, d);
 
455
    layout.ignoreBidi = true;
 
456
    layout.itemize();
 
457
    return qRound(layout.width(0, len));
 
458
}
 
459
 
 
460
/*! \fn int QFontMetrics::width(QChar ch) const
 
461
 
 
462
    \overload
 
463
 
 
464
    \img bearings.png Bearings
 
465
 
 
466
    Returns the logical width of character \a ch in pixels. This is a
 
467
    distance appropriate for drawing a subsequent character after \a
 
468
    ch.
 
469
 
 
470
    Some of the metrics are described in the image to the right. The
 
471
    central dark rectangles cover the logical width() of each
 
472
    character. The outer pale rectangles cover the leftBearing() and
 
473
    rightBearing() of each character. Notice that the bearings of "f"
 
474
    in this particular font are both negative, while the bearings of
 
475
    "o" are both positive.
 
476
 
 
477
    \warning This function will produce incorrect results for Arabic
 
478
    characters or non-spacing marks in the middle of a string, as the
 
479
    glyph shaping and positioning of marks that happens when
 
480
    processing strings cannot be taken into account. Use charWidth()
 
481
    instead if you aren't looking for the width of isolated
 
482
    characters.
 
483
 
 
484
    \sa boundingRect(), charWidth()
 
485
*/
 
486
int QFontMetrics::width(QChar ch) const
 
487
{
 
488
    if (::category(ch) == QChar::Mark_NonSpacing)
 
489
        return 0;
 
490
 
 
491
    const int script = QUnicodeTables::script(ch);
 
492
    QFontEngine *engine = d->engineForScript(script);
 
493
    Q_ASSERT(engine != 0);
 
494
 
 
495
    QGlyphLayout glyphs[8];
 
496
    int nglyphs = 7;
 
497
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
498
    return qRound(glyphs[0].advance.x());
 
499
}
 
500
 
 
501
/*!
 
502
    Returns the width of the character at position \a pos in the
 
503
    string \a str.
 
504
 
 
505
    The whole string is needed, as the glyph drawn may change
 
506
    depending on the context (the letter before and after the current
 
507
    one) for some languages (e.g. Arabic).
 
508
 
 
509
    This function also takes non spacing marks and ligatures into
 
510
    account.
 
511
*/
 
512
int QFontMetrics::charWidth(const QString &str, int pos) const
 
513
{
 
514
    if (pos < 0 || pos > (int)str.length())
 
515
        return 0;
 
516
 
 
517
    const QChar &ch = str.unicode()[pos];
 
518
    const int script = QUnicodeTables::script(ch);
 
519
    int width;
 
520
 
 
521
    if (script != QUnicodeTables::Common) {
 
522
        // complex script shaping. Have to do some hard work
 
523
        int from = qMax(0, pos - 8);
 
524
        int to = qMin((int)str.length(), pos + 8);
 
525
        QString cstr = QString::fromRawData(str.unicode()+from, to-from);
 
526
        QTextEngine layout(cstr, d);
 
527
        layout.ignoreBidi = true;
 
528
        layout.itemize();
 
529
        width = qRound(layout.width(pos-from, 1));
 
530
    } else if (::category(ch) == QChar::Mark_NonSpacing) {
 
531
        width = 0;
 
532
    } else {
 
533
        QFontEngine *engine = d->engineForScript(script);
 
534
        Q_ASSERT(engine != 0);
 
535
 
 
536
        QGlyphLayout glyphs[8];
 
537
        int nglyphs = 7;
 
538
        engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
539
        width = qRound(glyphs[0].advance.x());
 
540
    }
 
541
    return width;
 
542
}
 
543
 
 
544
/*!
 
545
    Returns the bounding rectangle of the characters in the string
 
546
    specified by \a str, which is the set of pixels the text would
 
547
    cover if drawn at (0, 0).
 
548
 
 
549
    Note that the bounding rectangle may extend to the left of (0, 0),
 
550
    e.g. for italicized fonts, and that the text output may cover \e
 
551
    all pixels in the bounding rectangle.
 
552
 
 
553
    Newline characters are processed as normal characters, \e not as
 
554
    linebreaks.
 
555
 
 
556
    Due to the different actual character heights, the height of the
 
557
    bounding rectangle of e.g. "Yes" and "yes" may be different.
 
558
 
 
559
    \sa width(), QPainter::boundingRect()
 
560
*/
 
561
QRect QFontMetrics::boundingRect(const QString &str) const
 
562
{
 
563
    if (str.length() == 0)
 
564
        return QRect();
 
565
 
 
566
    QTextEngine layout(str, d);
 
567
    layout.ignoreBidi = true;
 
568
    layout.itemize();
 
569
    glyph_metrics_t gm = layout.boundingBox(0, str.length());
 
570
    return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
 
571
}
 
572
 
 
573
/*!
 
574
    Returns the bounding rectangle of the character \a ch relative to
 
575
    the left-most point on the base line.
 
576
 
 
577
    Note that the bounding rectangle may extend to the left of (0, 0),
 
578
    e.g. for italicized fonts, and that the text output may cover \e
 
579
    all pixels in the bounding rectangle.
 
580
 
 
581
    Note that the rectangle usually extends both above and below the
 
582
    base line.
 
583
 
 
584
    \sa width()
 
585
*/
 
586
QRect QFontMetrics::boundingRect(QChar ch) const
 
587
{
 
588
    const int script = QUnicodeTables::script(ch);
 
589
    QFontEngine *engine = d->engineForScript(script);
 
590
    Q_ASSERT(engine != 0);
 
591
 
 
592
    QGlyphLayout glyphs[10];
 
593
    int nglyphs = 9;
 
594
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
595
    glyph_metrics_t gm = engine->boundingBox(glyphs[0].glyph);
 
596
    return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
 
597
}
 
598
 
 
599
/*!
 
600
    \overload
 
601
 
 
602
    Returns the bounding rectangle of the characters in the string
 
603
    specified by \a str, which is the set of pixels the text would
 
604
    cover if drawn at (0, 0). The drawing, and hence the bounding
 
605
    rectangle, is constrained to the rectangle \a r.
 
606
 
 
607
    The \a flgs argument is the bitwise OR of the following flags:
 
608
    \list
 
609
    \i \c Qt::AlignLeft aligns to the left border, except for
 
610
          Arabic and Hebrew where it aligns to the right.
 
611
    \i \c Qt::AlignRight aligns to the right border, except for
 
612
          Arabic and Hebrew where it aligns to the left.
 
613
    \i \c Qt::AlignJustify produces justified text.
 
614
    \i \c Qt::AlignHCenter aligns horizontally centered.
 
615
    \i \c Qt::AlignTop aligns to the top border.
 
616
    \i \c Qt::AlignBottom aligns to the bottom border.
 
617
    \i \c Qt::AlignVCenter aligns vertically centered
 
618
    \i \c Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
 
619
    \i \c Qt::TextSingleLine ignores newline characters in the text.
 
620
    \i \c Qt::TextExpandTabs expands tabs (see below)
 
621
    \i \c Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
 
622
    \i \c Qt::TextWordBreak breaks the text to fit the rectangle.
 
623
    \endlist
 
624
 
 
625
    Qt::Horizontal alignment defaults to \c Qt::AlignLeft and vertical
 
626
    alignment defaults to \c Qt::AlignTop.
 
627
 
 
628
    If several of the horizontal or several of the vertical alignment
 
629
    flags are set, the resulting alignment is undefined.
 
630
 
 
631
    These flags are defined in \c qnamespace.h.
 
632
 
 
633
    If \c Qt::TextExpandTabs is set in \a flgs, then: if \a tabarray is
 
634
    non-null, it specifies a 0-terminated sequence of pixel-positions
 
635
    for tabs; otherwise if \a tabstops is non-zero, it is used as the
 
636
    tab spacing (in pixels).
 
637
 
 
638
    Note that the bounding rectangle may extend to the left of (0, 0),
 
639
    e.g. for italicized fonts, and that the text output may cover \e
 
640
    all pixels in the bounding rectangle.
 
641
 
 
642
    Newline characters are processed as linebreaks.
 
643
 
 
644
    Despite the different actual character heights, the heights of the
 
645
    bounding rectangles of "Yes" and "yes" are the same.
 
646
 
 
647
    The bounding rectangle returned by this function is somewhat larger
 
648
    than that calculated by the simpler boundingRect() function. This
 
649
    function uses the \link minLeftBearing() maximum left \endlink and
 
650
    \link minRightBearing() right \endlink font bearings as is
 
651
    necessary for multi-line text to align correctly. Also,
 
652
    fontHeight() and lineSpacing() are used to calculate the height,
 
653
    rather than individual character heights.
 
654
 
 
655
    \sa width(), QPainter::boundingRect(), Qt::Alignment
 
656
*/
 
657
QRect QFontMetrics::boundingRect(const QRect &r, int flgs, const QString& str, int tabstops, int *tabarray) const
 
658
{
 
659
    int tabarraylen=0;
 
660
    if (tabarray)
 
661
        while (tabarray[tabarraylen])
 
662
            tabarraylen++;
 
663
 
 
664
    QRectF rb;
 
665
    QRectF rr(r);
 
666
    qt_format_text(QFont(d), rr, flgs|Qt::TextDontPrint, str, &rb, tabstops, tabarray, tabarraylen, 0);
 
667
 
 
668
    return rb.toRect();
 
669
}
 
670
 
 
671
/*!
 
672
    Returns the size in pixels of \a text.
 
673
 
 
674
    The \a flgs argument is the bitwise OR of the following flags:
 
675
    \list
 
676
    \i \c Qt::TextSingleLine ignores newline characters.
 
677
    \i \c Qt::TextExpandTabs expands tabs (see below)
 
678
    \i \c Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
 
679
    \i \c Qt::TextWordBreak breaks the text to fit the rectangle.
 
680
    \endlist
 
681
 
 
682
    These flags are defined in \c qnamespace.h.
 
683
 
 
684
    If \c Qt::TextExpandTabs is set in \a flgs, then: if \a tabarray is
 
685
    non-null, it specifies a 0-terminated sequence of pixel-positions
 
686
    for tabs; otherwise if \a tabstops is non-zero, it is used as the
 
687
    tab spacing (in pixels).
 
688
 
 
689
    Newline characters are processed as linebreaks.
 
690
 
 
691
    Despite the different actual character heights, the heights of the
 
692
    bounding rectangles of "Yes" and "yes" are the same.
 
693
 
 
694
    \sa boundingRect()
 
695
*/
 
696
QSize QFontMetrics::size(int flgs, const QString &text, int tabstops, int *tabarray) const
 
697
{
 
698
    return boundingRect(QRect(0,0,0,0), flgs, text, tabstops, tabarray).size();
 
699
}
 
700
 
 
701
/*!
 
702
    Returns the distance from the base line to where an underscore
 
703
    should be drawn.
 
704
 
 
705
    \sa overlinePos(), strikeOutPos(), lineWidth()
 
706
*/
 
707
int QFontMetrics::underlinePos() const
 
708
{
 
709
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
710
    Q_ASSERT(engine != 0);
 
711
 
 
712
    return qRound(engine->underlinePosition());
 
713
}
 
714
 
 
715
/*!
 
716
    Returns the distance from the base line to where an overline
 
717
    should be drawn.
 
718
 
 
719
    \sa underlinePos(), strikeOutPos(), lineWidth()
 
720
*/
 
721
int QFontMetrics::overlinePos() const
 
722
{
 
723
    return ascent() + 1;
 
724
}
 
725
 
 
726
/*!
 
727
    Returns the distance from the base line to where the strikeout
 
728
    line should be drawn.
 
729
 
 
730
    \sa underlinePos(), overlinePos(), lineWidth()
 
731
*/
 
732
int QFontMetrics::strikeOutPos() const
 
733
{
 
734
    int pos = ascent() / 3;
 
735
    return pos > 0 ? pos : 1;
 
736
}
 
737
 
 
738
/*!
 
739
    Returns the width of the underline and strikeout lines, adjusted
 
740
    for the point size of the font.
 
741
 
 
742
    \sa underlinePos(), overlinePos(), strikeOutPos()
 
743
*/
 
744
int QFontMetrics::lineWidth() const
 
745
{
 
746
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
747
    Q_ASSERT(engine != 0);
 
748
    return qRound(engine->lineThickness());
 
749
}
 
750
 
 
751
 
 
752
 
 
753
 
 
754
/*****************************************************************************
 
755
  QFontMetricsF member functions
 
756
 *****************************************************************************/
 
757
 
 
758
/*!
 
759
    \class QFontMetricsF qfontmetrics.h
 
760
    \brief The QFontMetricsF class provides font metrics information.
 
761
 
 
762
    \ingroup multimedia
 
763
    \ingroup shared
 
764
 
 
765
    QFontMetricsF functions calculate the size of characters and
 
766
    strings for a given font. There are three ways you can create a
 
767
    QFontMetricsF object:
 
768
 
 
769
    \list 1
 
770
    \i Calling the QFontMetricsF constructor with a QFont creates a
 
771
    font metrics object for a screen-compatible font, i.e. the font
 
772
    cannot be a printer font. If the font is changed
 
773
    later, the font metrics object is \e not updated.
 
774
 
 
775
    (Note: If you use a printer font the values returned may be
 
776
    inaccurate. Printer fonts are not always accessible so the nearest
 
777
    screen font is used if a printer font is supplied.)
 
778
 
 
779
    \i QWidget::fontMetrics() returns the font metrics for a widget's
 
780
    font. This is equivalent to QFontMetricsF(widget->font()). If the
 
781
    widget's font is changed later, the font metrics object is \e not
 
782
    updated.
 
783
 
 
784
    \i QPainter::fontMetrics() returns the font metrics for a
 
785
    painter's current font. If the painter's font is changed later, the
 
786
    font metrics object is \e not updated.
 
787
    \endlist
 
788
 
 
789
    Once created, the object provides functions to access the
 
790
    individual metrics of the font, its characters, and for strings
 
791
    rendered in the font.
 
792
 
 
793
    There are several functions that operate on the font: ascent(),
 
794
    descent(), height(), leading() and lineSpacing() return the basic
 
795
    size properties of the font. The underlinePos(), overlinePos(),
 
796
    strikeOutPos() and lineWidth() functions, return the properties of
 
797
    the line that underlines, overlines or strikes out the
 
798
    characters. These functions are all fast.
 
799
 
 
800
    There are also some functions that operate on the set of glyphs in
 
801
    the font: minLeftBearing(), minRightBearing() and maxWidth().
 
802
    These are by necessity slow, and we recommend avoiding them if
 
803
    possible.
 
804
 
 
805
    For each character, you can get its width(), leftBearing() and
 
806
    rightBearing() and find out whether it is in the font using
 
807
    inFont(). You can also treat the character as a string, and use
 
808
    the string functions on it.
 
809
 
 
810
    The string functions include width(), to return the width of a
 
811
    string in pixels (or points, for a printer), boundingRect(), to
 
812
    return a rectangle large enough to contain the rendered string,
 
813
    and size(), to return the size of that rectangle.
 
814
 
 
815
    Example:
 
816
    \code
 
817
    QFont font("times", 24);
 
818
    QFontMetricsF fm(font);
 
819
    int pixelsWide = fm.width("What's the width of this text?");
 
820
    int pixelsHigh = fm.height();
 
821
    \endcode
 
822
 
 
823
    \sa QFont QFontInfo QFontDatabase
 
824
*/
 
825
 
 
826
/*!
 
827
    \fn QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
 
828
 
 
829
    Constructs a font metrics object with floating point precision
 
830
    from the given \a fontMetrics object.
 
831
*/
 
832
 
 
833
/*!
 
834
    \fn QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &fontMetrics)
 
835
 
 
836
    Assigns \a fontMetrics to this font metrics object.
 
837
*/
 
838
 
 
839
/*!
 
840
    Constructs a font metrics object for \a font.
 
841
 
 
842
    The font metrics will be compatible with the paintdevice used to
 
843
    create \a font.
 
844
 
 
845
    The font metrics object holds the information for the font that is
 
846
    passed in the constructor at the time it is created, and is not
 
847
    updated if the font's attributes are changed later.
 
848
 
 
849
    Use QFontMetricsF(const QFont &, QPaintDevice *) to get the font
 
850
    metrics that are compatible with a certain paint device.
 
851
*/
 
852
QFontMetricsF::QFontMetricsF(const QFont &font)
 
853
    : d(font.d)
 
854
{
 
855
    d->ref.ref();
 
856
}
 
857
 
 
858
/*!
 
859
    Constructs a font metrics object for \a font and \a paintdevice.
 
860
 
 
861
    The font metrics will be compatible with the paintdevice passed.
 
862
    If the \a paintdevice is 0, the metrics will be screen-compatible,
 
863
    ie. the metrics you get if you use the font for drawing text on a
 
864
    \link QWidget widgets\endlink or \link QPixmap pixmaps\endlink,
 
865
    not on a QPicture or QPrinter.
 
866
 
 
867
    The font metrics object holds the information for the font that is
 
868
    passed in the constructor at the time it is created, and is not
 
869
    updated if the font's attributes are changed later.
 
870
*/
 
871
QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
 
872
{
 
873
    int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
 
874
#ifdef Q_WS_X11
 
875
    int screen = paintdevice ? qt_x11Info(paintdevice)->screen() : 0;
 
876
#else
 
877
    const int screen = 0;
 
878
#endif
 
879
    if (font.d->dpi != dpi || font.d->screen != screen ) {
 
880
        d = new QFontPrivate(*font.d);
 
881
        d->dpi = dpi;
 
882
        d->screen = screen;
 
883
    } else {
 
884
        d = font.d;
 
885
        d->ref.ref();
 
886
    }
 
887
 
 
888
}
 
889
 
 
890
/*!
 
891
    Constructs a copy of \a fm.
 
892
*/
 
893
QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
 
894
    : d(fm.d)
 
895
{ d->ref.ref(); }
 
896
 
 
897
/*!
 
898
    Destroys the font metrics object and frees all allocated
 
899
    resources.
 
900
*/
 
901
QFontMetricsF::~QFontMetricsF()
 
902
{
 
903
    if (!d->ref.deref())
 
904
        delete d;
 
905
}
 
906
 
 
907
/*!
 
908
    Assigns the font metrics \a fm to this font metrics object.
 
909
*/
 
910
QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm)
 
911
{
 
912
    qAtomicAssign(d, fm.d);
 
913
    return *this;
 
914
}
 
915
 
 
916
/*!
 
917
  Returns true if the font metrics are equal to the \a other font
 
918
  metrics; otherwise returns false.
 
919
 
 
920
  Two font metrics are considered equal if they were constructed from the
 
921
  same QFont and the paint devices they were constructed for are
 
922
  considered to be compatible.
 
923
*/
 
924
bool QFontMetricsF::operator ==(const QFontMetricsF &other)
 
925
{
 
926
    return d == other.d;
 
927
}
 
928
 
 
929
/*!
 
930
  \fn bool QFontMetricsF::operator !=(const QFontMetricsF &other);
 
931
 
 
932
  Returns true if the font metrics are not equal to the \a other font
 
933
  metrics; otherwise returns false.
 
934
 
 
935
  \sa operator==()
 
936
*/
 
937
 
 
938
/*!
 
939
    Returns the ascent of the font.
 
940
 
 
941
    The ascent of a font is the distance from the baseline to the
 
942
    highest position characters extend to. In practice, some font
 
943
    designers break this rule, e.g. when they put more than one accent
 
944
    on top of a character, or to accommodate an unusual character in
 
945
    an exotic language, so it is possible (though rare) that this
 
946
    value will be too small.
 
947
 
 
948
    \sa descent()
 
949
*/
 
950
qreal QFontMetricsF::ascent() const
 
951
{
 
952
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
953
    Q_ASSERT(engine != 0);
 
954
    return engine->ascent();
 
955
}
 
956
 
 
957
 
 
958
/*!
 
959
    Returns the descent of the font.
 
960
 
 
961
    The descent is the distance from the base line to the lowest point
 
962
    characters extend to. (Note that this is different from X, which
 
963
    adds 1 pixel.) In practice, some font designers break this rule,
 
964
    e.g. to accommodate an unusual character in an exotic language, so
 
965
    it is possible (though rare) that this value will be too small.
 
966
 
 
967
    \sa ascent()
 
968
*/
 
969
qreal QFontMetricsF::descent() const
 
970
{
 
971
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
972
    Q_ASSERT(engine != 0);
 
973
    return engine->descent();
 
974
}
 
975
 
 
976
/*!
 
977
    Returns the height of the font.
 
978
 
 
979
    This is always equal to ascent()+descent()+1 (the 1 is for the
 
980
    base line).
 
981
 
 
982
    \sa leading(), lineSpacing()
 
983
*/
 
984
qreal QFontMetricsF::height() const
 
985
{
 
986
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
987
    Q_ASSERT(engine != 0);
 
988
 
 
989
    return engine->ascent() + engine->descent() + 1.0;
 
990
}
 
991
 
 
992
/*!
 
993
    Returns the leading of the font.
 
994
 
 
995
    This is the natural inter-line spacing.
 
996
 
 
997
    \sa height(), lineSpacing()
 
998
*/
 
999
qreal QFontMetricsF::leading() const
 
1000
{
 
1001
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1002
    Q_ASSERT(engine != 0);
 
1003
    return engine->leading();
 
1004
}
 
1005
 
 
1006
/*!
 
1007
    Returns the distance from one base line to the next.
 
1008
 
 
1009
    This value is always equal to leading()+height().
 
1010
 
 
1011
    \sa height(), leading()
 
1012
*/
 
1013
qreal QFontMetricsF::lineSpacing() const
 
1014
{
 
1015
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1016
    Q_ASSERT(engine != 0);
 
1017
    return engine->leading() + engine->ascent() + engine->descent() + 1.0;
 
1018
}
 
1019
 
 
1020
/*!
 
1021
    Returns the minimum left bearing of the font.
 
1022
 
 
1023
    This is the smallest leftBearing(char) of all characters in the
 
1024
    font.
 
1025
 
 
1026
    Note that this function can be very slow if the font is large.
 
1027
 
 
1028
    \sa minRightBearing(), leftBearing()
 
1029
*/
 
1030
qreal QFontMetricsF::minLeftBearing() const
 
1031
{
 
1032
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1033
    Q_ASSERT(engine != 0);
 
1034
    return engine->minLeftBearing();
 
1035
}
 
1036
 
 
1037
/*!
 
1038
    Returns the minimum right bearing of the font.
 
1039
 
 
1040
    This is the smallest rightBearing(char) of all characters in the
 
1041
    font.
 
1042
 
 
1043
    Note that this function can be very slow if the font is large.
 
1044
 
 
1045
    \sa minLeftBearing(), rightBearing()
 
1046
*/
 
1047
qreal QFontMetricsF::minRightBearing() const
 
1048
{
 
1049
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1050
    Q_ASSERT(engine != 0);
 
1051
    return engine->minRightBearing();
 
1052
}
 
1053
 
 
1054
/*!
 
1055
    Returns the width of the widest character in the font.
 
1056
*/
 
1057
qreal QFontMetricsF::maxWidth() const
 
1058
{
 
1059
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1060
    Q_ASSERT(engine != 0);
 
1061
    return engine->maxCharWidth();
 
1062
}
 
1063
 
 
1064
/*!
 
1065
    Returns true if character \a ch is a valid character in the font;
 
1066
    otherwise returns false.
 
1067
*/
 
1068
bool QFontMetricsF::inFont(QChar ch) const
 
1069
{
 
1070
    const int script = QUnicodeTables::script(ch);
 
1071
    QFontEngine *engine = d->engineForScript(script);
 
1072
    Q_ASSERT(engine != 0);
 
1073
    if (engine->type() == QFontEngine::Box)
 
1074
        return false;
 
1075
    return engine->canRender(&ch, 1);
 
1076
}
 
1077
 
 
1078
/*! \fn int QFontMetricsF::leftBearing(QChar ch) const
 
1079
    Returns the left bearing of character \a ch in the font.
 
1080
 
 
1081
    The left bearing is the right-ward distance of the left-most pixel
 
1082
    of the character from the logical origin of the character. This
 
1083
    value is negative if the pixels of the character extend to the
 
1084
    left of the logical origin.
 
1085
 
 
1086
    See width(QChar) for a graphical description of this metric.
 
1087
 
 
1088
    \sa rightBearing(), minLeftBearing(), width()
 
1089
*/
 
1090
qreal QFontMetricsF::leftBearing(QChar ch) const
 
1091
{
 
1092
    const int script = QUnicodeTables::script(ch);
 
1093
    QFontEngine *engine = d->engineForScript(script);
 
1094
    Q_ASSERT(engine != 0);
 
1095
    if (engine->type() == QFontEngine::Box)
 
1096
        return 0;
 
1097
 
 
1098
    QGlyphLayout glyphs[10];
 
1099
    int nglyphs = 9;
 
1100
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
1101
    // ### can nglyphs != 1 happen at all? Not currently I think
 
1102
    glyph_metrics_t gi = engine->boundingBox(glyphs[0].glyph);
 
1103
    return gi.x;
 
1104
}
 
1105
 
 
1106
/*! \fn int QFontMetricsF::rightBearing(QChar ch) const
 
1107
    Returns the right bearing of character \a ch in the font.
 
1108
 
 
1109
    The right bearing is the left-ward distance of the right-most
 
1110
    pixel of the character from the logical origin of a subsequent
 
1111
    character. This value is negative if the pixels of the character
 
1112
    extend to the right of the width() of the character.
 
1113
 
 
1114
    See width() for a graphical description of this metric.
 
1115
 
 
1116
    \sa leftBearing(), minRightBearing(), width()
 
1117
*/
 
1118
qreal QFontMetricsF::rightBearing(QChar ch) const
 
1119
{
 
1120
    const int script = QUnicodeTables::script(ch);
 
1121
    QFontEngine *engine = d->engineForScript(script);
 
1122
    Q_ASSERT(engine != 0);
 
1123
    if (engine->type() == QFontEngine::Box)
 
1124
        return 0;
 
1125
 
 
1126
    QGlyphLayout glyphs[10];
 
1127
    int nglyphs = 9;
 
1128
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
1129
    // ### can nglyphs != 1 happen at all? Not currently I think
 
1130
    glyph_metrics_t gi = engine->boundingBox(glyphs[0].glyph);
 
1131
    return gi.xoff - gi.x - gi.width;
 
1132
}
 
1133
 
 
1134
/*!
 
1135
    \fn qreal QFontMetricsF::width(const QString &text) const
 
1136
 
 
1137
    Returns the width in pixels of the characters in the given \a text.
 
1138
 
 
1139
    Note that this value is \e not equal to the width returned by
 
1140
    boundingRect().width() because boundingRect() returns a rectangle
 
1141
    describing the pixels this string will cover whereas width()
 
1142
    returns the distance to where the next string should be drawn.
 
1143
 
 
1144
    \sa boundingRect()
 
1145
*/
 
1146
qreal QFontMetricsF::width(const QString &str) const
 
1147
{
 
1148
    QTextEngine layout(str, d);
 
1149
    layout.ignoreBidi = true;
 
1150
    layout.itemize();
 
1151
    return layout.width(0, str.length());
 
1152
}
 
1153
 
 
1154
/*! \fn int QFontMetricsF::width(QChar ch) const
 
1155
 
 
1156
    \overload
 
1157
 
 
1158
    \img bearings.png Bearings
 
1159
 
 
1160
    Returns the logical width of character \a ch in pixels. This is a
 
1161
    distance appropriate for drawing a subsequent character after \a
 
1162
    ch.
 
1163
 
 
1164
    Some of the metrics are described in the image to the right. The
 
1165
    central dark rectangles cover the logical width() of each
 
1166
    character. The outer pale rectangles cover the leftBearing() and
 
1167
    rightBearing() of each character. Notice that the bearings of "f"
 
1168
    in this particular font are both negative, while the bearings of
 
1169
    "o" are both positive.
 
1170
 
 
1171
    \warning This function will produce incorrect results for Arabic
 
1172
    characters or non-spacing marks in the middle of a string, as the
 
1173
    glyph shaping and positioning of marks that happens when
 
1174
    processing strings cannot be taken into account. Use charWidth()
 
1175
    instead if you aren't looking for the width of isolated
 
1176
    characters.
 
1177
 
 
1178
    \sa boundingRect()
 
1179
*/
 
1180
qreal QFontMetricsF::width(QChar ch) const
 
1181
{
 
1182
    if (::category(ch) == QChar::Mark_NonSpacing)
 
1183
        return 0.;
 
1184
 
 
1185
    const int script = QUnicodeTables::script(ch);
 
1186
    QFontEngine *engine = d->engineForScript(script);
 
1187
    Q_ASSERT(engine != 0);
 
1188
 
 
1189
    QGlyphLayout glyphs[8];
 
1190
    int nglyphs = 7;
 
1191
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
1192
    return glyphs[0].advance.x();
 
1193
}
 
1194
 
 
1195
/*!
 
1196
    \fn QRectF QFontMetricsF::boundingRect(const QString &text) const
 
1197
 
 
1198
    Returns the bounding rectangle of the characters in the given
 
1199
    \a text. This is the set of pixels the text would cover if drawn
 
1200
    at (0, 0).
 
1201
 
 
1202
    Note that the bounding rectangle may extend to the left of (0, 0),
 
1203
    e.g. for italicized fonts, and that the text output may cover \e
 
1204
    all pixels in the bounding rectangle.
 
1205
 
 
1206
    Newline characters are processed as normal characters, \e not as
 
1207
    line breaks.
 
1208
 
 
1209
    Due to the different actual character heights, the height of the
 
1210
    bounding rectangle of e.g. "Yes" and "yes" may be different.
 
1211
 
 
1212
    \sa width(), QPainter::boundingRect()
 
1213
*/
 
1214
QRectF QFontMetricsF::boundingRect(const QString &str) const
 
1215
{
 
1216
    int len = str.length();
 
1217
    if (len == 0)
 
1218
        return QRectF();
 
1219
 
 
1220
    QTextEngine layout(str, d);
 
1221
    layout.ignoreBidi = true;
 
1222
    layout.itemize();
 
1223
    glyph_metrics_t gm = layout.boundingBox(0, len);
 
1224
    return QRectF(gm.x, gm.y, gm.width, gm.height);
 
1225
}
 
1226
 
 
1227
/*!
 
1228
    Returns the bounding rectangle of the character \a ch relative to
 
1229
    the left-most point on the base line.
 
1230
 
 
1231
    Note that the bounding rectangle may extend to the left of (0, 0),
 
1232
    e.g. for italicized fonts, and that the text output may cover \e
 
1233
    all pixels in the bounding rectangle.
 
1234
 
 
1235
    Note that the rectangle usually extends both above and below the
 
1236
    base line.
 
1237
 
 
1238
    \sa width()
 
1239
*/
 
1240
QRectF QFontMetricsF::boundingRect(QChar ch) const
 
1241
{
 
1242
    const int script = QUnicodeTables::script(ch);
 
1243
    QFontEngine *engine = d->engineForScript(script);
 
1244
    Q_ASSERT(engine != 0);
 
1245
 
 
1246
    QGlyphLayout glyphs[10];
 
1247
    int nglyphs = 9;
 
1248
    engine->stringToCMap(&ch, 1, glyphs, &nglyphs, 0);
 
1249
    glyph_metrics_t gm = engine->boundingBox(glyphs[0].glyph);
 
1250
    return QRectF(gm.x, gm.y, gm.width, gm.height);
 
1251
}
 
1252
 
 
1253
/*!
 
1254
    \fn QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString &text, int tabstops, int *tabarray) const
 
1255
    \overload
 
1256
 
 
1257
    Returns the bounding rectangle of the characters in the given \a text.
 
1258
    This is the set of pixels the text would cover if drawn when constrained
 
1259
    to the bounding rectangle specified by \a rect.
 
1260
 
 
1261
    The \a flags argument is the bitwise OR of the following flags:
 
1262
    \list
 
1263
    \i \c Qt::AlignLeft aligns to the left border, except for
 
1264
          Arabic and Hebrew where it aligns to the right.
 
1265
    \i \c Qt::AlignRight aligns to the right border, except for
 
1266
          Arabic and Hebrew where it aligns to the left.
 
1267
    \i \c Qt::AlignJustify produces justified text.
 
1268
    \i \c Qt::AlignHCenter aligns horizontally centered.
 
1269
    \i \c Qt::AlignTop aligns to the top border.
 
1270
    \i \c Qt::AlignBottom aligns to the bottom border.
 
1271
    \i \c Qt::AlignVCenter aligns vertically centered
 
1272
    \i \c Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter})
 
1273
    \i \c Qt::TextSingleLine ignores newline characters in the text.
 
1274
    \i \c Qt::TextExpandTabs expands tabs (see below)
 
1275
    \i \c Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
 
1276
    \i \c Qt::TextWordBreak breaks the text to fit the rectangle.
 
1277
    \endlist
 
1278
 
 
1279
    Qt::Horizontal alignment defaults to \c Qt::AlignLeft and vertical
 
1280
    alignment defaults to \c Qt::AlignTop.
 
1281
 
 
1282
    If several of the horizontal or several of the vertical alignment
 
1283
    flags are set, the resulting alignment is undefined.
 
1284
 
 
1285
    These flags are defined in \l{Qt::AlignmentFlag}.
 
1286
 
 
1287
    If \c Qt::TextExpandTabs is set in \a flags, the following behavior is
 
1288
    used to interpret tab characters in the text:
 
1289
    \list
 
1290
    \i If \a tabarray is non-null, it specifies a 0-terminated sequence of
 
1291
       pixel-positions for tabs in the text.
 
1292
    \i If \a tabstops is non-zero, it is used as the tab spacing (in pixels).
 
1293
    \endlist
 
1294
 
 
1295
    Note that the bounding rectangle may extend to the left of (0, 0),
 
1296
    e.g. for italicized fonts.
 
1297
 
 
1298
    Newline characters are processed as line breaks.
 
1299
 
 
1300
    Despite the different actual character heights, the heights of the
 
1301
    bounding rectangles of "Yes" and "yes" are the same.
 
1302
 
 
1303
    The bounding rectangle returned by this function is somewhat larger
 
1304
    than that calculated by the simpler boundingRect() function. This
 
1305
    function uses the \link minLeftBearing() maximum left \endlink and
 
1306
    \link minRightBearing() right \endlink font bearings as is
 
1307
    necessary for multi-line text to align correctly. Also,
 
1308
    fontHeight() and lineSpacing() are used to calculate the height,
 
1309
    rather than individual character heights.
 
1310
 
 
1311
    \sa width(), QPainter::boundingRect(), Qt::Alignment
 
1312
*/
 
1313
QRectF QFontMetricsF::boundingRect(const QRectF &r, int flgs, const QString& str,
 
1314
                                   int tabstops, int *tabarray) const
 
1315
{
 
1316
    int tabarraylen=0;
 
1317
    if (tabarray)
 
1318
        while (tabarray[tabarraylen])
 
1319
            tabarraylen++;
 
1320
 
 
1321
    QRectF rb;
 
1322
    qt_format_text(QFont(d), r, flgs|Qt::TextDontPrint, str, &rb, tabstops, tabarray, tabarraylen, 0);
 
1323
 
 
1324
    return rb;
 
1325
}
 
1326
 
 
1327
/*!
 
1328
    \fn QSizeF QFontMetricsF::size(int flags, const QString &text, int tabstops, int *tabarray) const
 
1329
 
 
1330
    Returns the size in pixels of the characters in the given \a text.
 
1331
 
 
1332
    The \a flags argument is the bitwise OR of the following flags:
 
1333
    \list
 
1334
    \i \c Qt::TextSingleLine ignores newline characters.
 
1335
    \i \c Qt::TextExpandTabs expands tabs (see below)
 
1336
    \i \c Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
 
1337
    \i \c Qt::TextWordBreak breaks the text to fit the rectangle.
 
1338
    \endlist
 
1339
 
 
1340
    These flags are defined in \l{Qt::TextFlags}.
 
1341
 
 
1342
    If \c Qt::TextExpandTabs is set in \a flags, the following behavior is
 
1343
    used to interpret tab characters in the text:
 
1344
    \list
 
1345
    \i If \a tabarray is non-null, it specifies a 0-terminated sequence of
 
1346
       pixel-positions for tabs in the text.
 
1347
    \i If \a tabstops is non-zero, it is used as the tab spacing (in pixels).
 
1348
    \endlist
 
1349
 
 
1350
    Newline characters are processed as line breaks.
 
1351
 
 
1352
    Note: Despite the different actual character heights, the heights of the
 
1353
    bounding rectangles of "Yes" and "yes" are the same.
 
1354
 
 
1355
    \sa boundingRect()
 
1356
*/
 
1357
QSizeF QFontMetricsF::size(int flgs, const QString &str, int tabstops, int *tabarray) const
 
1358
{
 
1359
    return boundingRect(QRectF(), flgs, str, tabstops, tabarray).size();
 
1360
}
 
1361
 
 
1362
/*!
 
1363
    Returns the distance from the base line to where an underscore
 
1364
    should be drawn.
 
1365
 
 
1366
    \sa overlinePos(), strikeOutPos(), lineWidth()
 
1367
*/
 
1368
qreal QFontMetricsF::underlinePos() const
 
1369
{
 
1370
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1371
    Q_ASSERT(engine != 0);
 
1372
    return engine->underlinePosition();
 
1373
}
 
1374
 
 
1375
/*!
 
1376
    Returns the distance from the base line to where an overline
 
1377
    should be drawn.
 
1378
 
 
1379
    \sa underlinePos(), strikeOutPos(), lineWidth()
 
1380
*/
 
1381
qreal QFontMetricsF::overlinePos() const
 
1382
{
 
1383
    return ascent() + 1;
 
1384
}
 
1385
 
 
1386
/*!
 
1387
    Returns the distance from the base line to where the strikeout
 
1388
    line should be drawn.
 
1389
 
 
1390
    \sa underlinePos(), overlinePos(), lineWidth()
 
1391
*/
 
1392
qreal QFontMetricsF::strikeOutPos() const
 
1393
{
 
1394
    return ascent() / 3.;
 
1395
}
 
1396
 
 
1397
/*!
 
1398
    Returns the width of the underline and strikeout lines, adjusted
 
1399
    for the point size of the font.
 
1400
 
 
1401
    \sa underlinePos(), overlinePos(), strikeOutPos()
 
1402
*/
 
1403
qreal QFontMetricsF::lineWidth() const
 
1404
{
 
1405
    QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
 
1406
    Q_ASSERT(engine != 0);
 
1407
    return engine->lineThickness();
 
1408
}
 
1409
 
 
1410
/*!
 
1411
    \fn QSize QFontMetrics::size(int flags, const QString &str, int len,
 
1412
                                 int tabstops, int *tabarray) const
 
1413
    \compat
 
1414
*/
 
1415
 
 
1416
/*!
 
1417
    \fn QRect QFontMetrics::boundingRect(int x, int y, int w, int h, int flags,
 
1418
        const QString& str, int len, int tabstops, int *tabarray) const
 
1419
    \compat
 
1420
*/
 
1421
 
 
1422
/*!
 
1423
    \fn QRect QFontMetrics::boundingRect(const QString &text, int len) const
 
1424
    \compat
 
1425
*/