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