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