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