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