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