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

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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