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

Last change on this file since 318 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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