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

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

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

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