source: trunk/src/gui/text/qfontmetrics.cpp@ 642

Last change on this file since 642 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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