/src/qtbase/src/gui/text/qfontmetrics.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 0 | : d(font.d) |
132 | 0 | { |
133 | 0 | } |
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 | 0 | { |
152 | 0 | const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); |
153 | 0 | if (font.d->dpi != dpi) { |
154 | 0 | d = new QFontPrivate(*font.d); |
155 | 0 | d->dpi = dpi; |
156 | 0 | } else { |
157 | 0 | d = font.d; |
158 | 0 | } |
159 | |
|
160 | 0 | } |
161 | | |
162 | | /*! |
163 | | Constructs a copy of \a fm. |
164 | | */ |
165 | | QFontMetrics::QFontMetrics(const QFontMetrics &fm) |
166 | 0 | : d(fm.d) |
167 | 0 | { |
168 | 0 | } |
169 | | |
170 | | /*! |
171 | | Destroys the font metrics object and frees all allocated |
172 | | resources. |
173 | | */ |
174 | | QFontMetrics::~QFontMetrics() |
175 | 0 | { |
176 | 0 | } |
177 | | |
178 | | /*! |
179 | | Assigns the font metrics \a fm. |
180 | | */ |
181 | | QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) |
182 | 0 | { |
183 | 0 | d = fm.d; |
184 | 0 | return *this; |
185 | 0 | } |
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 | 0 | { |
218 | 0 | return d == other.d; |
219 | 0 | } |
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 | 0 | { |
246 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
247 | 0 | Q_ASSERT(engine != nullptr); |
248 | 0 | return qRound(engine->ascent()); |
249 | 0 | } |
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 | 0 | { |
265 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
266 | 0 | Q_ASSERT(engine != nullptr); |
267 | 0 | return qRound(engine->capHeight()); |
268 | 0 | } |
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 | 0 | { |
282 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
283 | 0 | Q_ASSERT(engine != nullptr); |
284 | 0 | return qRound(engine->descent()); |
285 | 0 | } |
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 | 0 | { |
296 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
297 | 0 | Q_ASSERT(engine != nullptr); |
298 | 0 | return qRound(engine->ascent()) + qRound(engine->descent()); |
299 | 0 | } |
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 | 0 | { |
310 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
311 | 0 | Q_ASSERT(engine != nullptr); |
312 | 0 | return qRound(engine->leading()); |
313 | 0 | } |
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 | 0 | { |
324 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
325 | 0 | Q_ASSERT(engine != nullptr); |
326 | 0 | return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent()); |
327 | 0 | } |
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 | 0 | { |
341 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
342 | 0 | Q_ASSERT(engine != nullptr); |
343 | 0 | return qRound(engine->minLeftBearing()); |
344 | 0 | } |
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 | 0 | { |
358 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
359 | 0 | Q_ASSERT(engine != nullptr); |
360 | 0 | return qRound(engine->minRightBearing()); |
361 | 0 | } |
362 | | |
363 | | /*! |
364 | | Returns the width of the widest character in the font. |
365 | | */ |
366 | | int QFontMetrics::maxWidth() const |
367 | 0 | { |
368 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
369 | 0 | Q_ASSERT(engine != nullptr); |
370 | 0 | return qRound(engine->maxCharWidth()); |
371 | 0 | } |
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 | 0 | { |
379 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
380 | 0 | Q_ASSERT(engine != nullptr); |
381 | 0 | if (d->capital == QFont::SmallCaps) |
382 | 0 | return qRound(d->smallCapsFontPrivate()->engineForScript(QChar::Script_Common)->ascent()); |
383 | 0 | return qRound(engine->xHeight()); |
384 | 0 | } |
385 | | |
386 | | /*! |
387 | | \since 4.2 |
388 | | |
389 | | Returns the average width of glyphs in the font. |
390 | | */ |
391 | | int QFontMetrics::averageCharWidth() const |
392 | 0 | { |
393 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
394 | 0 | Q_ASSERT(engine != nullptr); |
395 | 0 | return qRound(engine->averageCharWidth()); |
396 | 0 | } |
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 | 0 | { |
404 | 0 | return inFontUcs4(ch.unicode()); |
405 | 0 | } |
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 | 0 | { |
413 | 0 | const int script = QChar::script(ucs4); |
414 | 0 | QFontEngine *engine = d->engineForScript(script); |
415 | 0 | Q_ASSERT(engine != nullptr); |
416 | 0 | if (engine->type() == QFontEngine::Box) |
417 | 0 | return false; |
418 | 0 | return engine->canRender(ucs4); |
419 | 0 | } |
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 | 0 | { |
435 | 0 | const int script = ch.script(); |
436 | 0 | QFontEngine *engine; |
437 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
438 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
439 | 0 | else |
440 | 0 | engine = d->engineForScript(script); |
441 | 0 | Q_ASSERT(engine != nullptr); |
442 | 0 | if (engine->type() == QFontEngine::Box) |
443 | 0 | return 0; |
444 | | |
445 | 0 | d->alterCharForCapitalization(ch); |
446 | |
|
447 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
448 | |
|
449 | 0 | qreal lb; |
450 | 0 | engine->getGlyphBearings(glyph, &lb); |
451 | 0 | return qRound(lb); |
452 | 0 | } |
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 | 0 | { |
468 | 0 | const int script = ch.script(); |
469 | 0 | QFontEngine *engine; |
470 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
471 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
472 | 0 | else |
473 | 0 | engine = d->engineForScript(script); |
474 | 0 | Q_ASSERT(engine != nullptr); |
475 | 0 | if (engine->type() == QFontEngine::Box) |
476 | 0 | return 0; |
477 | | |
478 | 0 | d->alterCharForCapitalization(ch); |
479 | |
|
480 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
481 | |
|
482 | 0 | qreal rb; |
483 | 0 | engine->getGlyphBearings(glyph, nullptr, &rb); |
484 | 0 | return qRound(rb); |
485 | 0 | } |
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 | 0 | { |
504 | 0 | int pos = (len >= 0) |
505 | 0 | ? QStringView(text).left(len).indexOf(s_variableLengthStringSeparator) |
506 | 0 | : text.indexOf(s_variableLengthStringSeparator); |
507 | 0 | if (pos != -1) { |
508 | 0 | len = pos; |
509 | 0 | } else if (len < 0) { |
510 | 0 | len = text.size(); |
511 | 0 | } |
512 | 0 | if (len == 0) |
513 | 0 | return 0; |
514 | | |
515 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
516 | 0 | return qRound(layout.width(0, len)); |
517 | 0 | } |
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 | 0 | { |
531 | 0 | int pos = text.indexOf(s_variableLengthStringSeparator); |
532 | 0 | int len = -1; |
533 | 0 | if (pos != -1) { |
534 | 0 | len = pos; |
535 | 0 | } else { |
536 | 0 | len = text.size(); |
537 | 0 | } |
538 | 0 | if (len == 0) |
539 | 0 | return 0; |
540 | | |
541 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
542 | 0 | layout.option = option; |
543 | 0 | return qRound(layout.width(0, len)); |
544 | 0 | } |
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 | 0 | { |
574 | 0 | if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) |
575 | 0 | return 0; |
576 | | |
577 | 0 | const int script = ch.script(); |
578 | 0 | QFontEngine *engine; |
579 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
580 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
581 | 0 | else |
582 | 0 | engine = d->engineForScript(script); |
583 | 0 | Q_ASSERT(engine != nullptr); |
584 | |
|
585 | 0 | d->alterCharForCapitalization(ch); |
586 | |
|
587 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
588 | 0 | QFixed advance; |
589 | |
|
590 | 0 | QGlyphLayout glyphs; |
591 | 0 | glyphs.numGlyphs = 1; |
592 | 0 | glyphs.glyphs = &glyph; |
593 | 0 | glyphs.advances = &advance; |
594 | 0 | engine->recalcAdvances(&glyphs, { }); |
595 | |
|
596 | 0 | return qRound(advance); |
597 | 0 | } |
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 | 0 | { |
623 | 0 | if (text.size() == 0) |
624 | 0 | return QRect(); |
625 | | |
626 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
627 | 0 | layout.itemize(); |
628 | 0 | glyph_metrics_t gm = layout.boundingBox(0, text.size()); |
629 | 0 | return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); |
630 | 0 | } |
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 | 0 | { |
658 | 0 | if (text.size() == 0) |
659 | 0 | return QRect(); |
660 | | |
661 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
662 | 0 | layout.option = option; |
663 | 0 | layout.itemize(); |
664 | 0 | glyph_metrics_t gm = layout.boundingBox(0, text.size()); |
665 | 0 | return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); |
666 | 0 | } |
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 | 0 | { |
687 | 0 | const int script = ch.script(); |
688 | 0 | QFontEngine *engine; |
689 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
690 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
691 | 0 | else |
692 | 0 | engine = d->engineForScript(script); |
693 | 0 | Q_ASSERT(engine != nullptr); |
694 | |
|
695 | 0 | d->alterCharForCapitalization(ch); |
696 | |
|
697 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
698 | |
|
699 | 0 | glyph_metrics_t gm = engine->boundingBox(glyph); |
700 | 0 | return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); |
701 | 0 | } |
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 | 0 | { |
762 | 0 | int tabArrayLen = 0; |
763 | 0 | if (tabArray) |
764 | 0 | while (tabArray[tabArrayLen]) |
765 | 0 | tabArrayLen++; |
766 | |
|
767 | 0 | QRectF rb; |
768 | 0 | QRectF rr(rect); |
769 | 0 | qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, |
770 | 0 | tabArrayLen, nullptr); |
771 | |
|
772 | 0 | return rb.toAlignedRect(); |
773 | 0 | } |
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 | 0 | { |
800 | 0 | return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); |
801 | 0 | } |
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 | 0 | { |
826 | 0 | if (text.size() == 0) |
827 | 0 | return QRect(); |
828 | | |
829 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
830 | 0 | layout.itemize(); |
831 | 0 | glyph_metrics_t gm = layout.tightBoundingBox(0, text.size()); |
832 | 0 | return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); |
833 | 0 | } |
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 | 0 | { |
858 | 0 | if (text.size() == 0) |
859 | 0 | return QRect(); |
860 | | |
861 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
862 | 0 | layout.option = option; |
863 | 0 | layout.itemize(); |
864 | 0 | glyph_metrics_t gm = layout.tightBoundingBox(0, text.size()); |
865 | 0 | return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height)); |
866 | 0 | } |
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 | 0 | { |
892 | 0 | QString _text = text; |
893 | 0 | if (!(flags & Qt::TextLongestVariant)) { |
894 | 0 | int posA = 0; |
895 | 0 | int posB = _text.indexOf(s_variableLengthStringSeparator); |
896 | 0 | while (posB >= 0) { |
897 | 0 | QString portion = _text.mid(posA, posB - posA); |
898 | 0 | if (size(flags, portion).width() <= width) |
899 | 0 | return portion; |
900 | 0 | posA = posB + 1; |
901 | 0 | posB = _text.indexOf(s_variableLengthStringSeparator, posA); |
902 | 0 | } |
903 | 0 | _text = _text.mid(posA); |
904 | 0 | } |
905 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine engine(_text, QFont(d.data())); |
906 | 0 | return engine.elidedText(mode, width, flags); |
907 | 0 | } |
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 | 0 | { |
917 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
918 | 0 | Q_ASSERT(engine != nullptr); |
919 | 0 | return qRound(engine->underlinePosition()); |
920 | 0 | } |
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 | 0 | { |
930 | 0 | return ascent() + 1; |
931 | 0 | } |
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 | 0 | { |
941 | 0 | int pos = ascent() / 3; |
942 | 0 | return pos > 0 ? pos : 1; |
943 | 0 | } |
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 | 0 | { |
953 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
954 | 0 | Q_ASSERT(engine != nullptr); |
955 | 0 | return qRound(engine->lineThickness()); |
956 | 0 | } |
957 | | |
958 | | /*! |
959 | | \since 5.14 |
960 | | |
961 | | Returns the font DPI. |
962 | | */ |
963 | | qreal QFontMetrics::fontDpi() const |
964 | 0 | { |
965 | 0 | return d->dpi; |
966 | 0 | } |
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 | 0 | : d(fontMetrics.d) |
1027 | 0 | { |
1028 | 0 | } |
1029 | | |
1030 | | /*! |
1031 | | \since 4.2 |
1032 | | |
1033 | | Assigns \a other to this object. |
1034 | | */ |
1035 | | QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) |
1036 | 0 | { |
1037 | 0 | d = other.d; |
1038 | 0 | return *this; |
1039 | 0 | } |
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 | 0 | : d(font.d) |
1064 | 0 | { |
1065 | 0 | } |
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 | 0 | { |
1084 | 0 | int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); |
1085 | 0 | if (font.d->dpi != dpi) { |
1086 | 0 | d = new QFontPrivate(*font.d); |
1087 | 0 | d->dpi = dpi; |
1088 | 0 | } else { |
1089 | 0 | d = font.d; |
1090 | 0 | } |
1091 | |
|
1092 | 0 | } |
1093 | | |
1094 | | /*! |
1095 | | Constructs a copy of \a fm. |
1096 | | */ |
1097 | | QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) |
1098 | 0 | : d(fm.d) |
1099 | 0 | { |
1100 | 0 | } |
1101 | | |
1102 | | /*! |
1103 | | Destroys the font metrics object and frees all allocated |
1104 | | resources. |
1105 | | */ |
1106 | | QFontMetricsF::~QFontMetricsF() |
1107 | 0 | { |
1108 | 0 | } |
1109 | | |
1110 | | /*! |
1111 | | Assigns the font metrics \a fm to this font metrics object. |
1112 | | */ |
1113 | | QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) |
1114 | 0 | { |
1115 | 0 | d = fm.d; |
1116 | 0 | return *this; |
1117 | 0 | } |
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 | 0 | { |
1129 | 0 | return d == other.d; |
1130 | 0 | } |
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 | 0 | { |
1155 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1156 | 0 | Q_ASSERT(engine != nullptr); |
1157 | 0 | return engine->ascent().toReal(); |
1158 | 0 | } |
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 | 0 | { |
1174 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1175 | 0 | Q_ASSERT(engine != nullptr); |
1176 | 0 | return engine->capHeight().toReal(); |
1177 | 0 | } |
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 | 0 | { |
1192 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1193 | 0 | Q_ASSERT(engine != nullptr); |
1194 | 0 | return engine->descent().toReal(); |
1195 | 0 | } |
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 | 0 | { |
1206 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1207 | 0 | Q_ASSERT(engine != nullptr); |
1208 | |
|
1209 | 0 | return (engine->ascent() + engine->descent()).toReal(); |
1210 | 0 | } |
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 | 0 | { |
1221 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1222 | 0 | Q_ASSERT(engine != nullptr); |
1223 | 0 | return engine->leading().toReal(); |
1224 | 0 | } |
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 | 0 | { |
1235 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1236 | 0 | Q_ASSERT(engine != nullptr); |
1237 | 0 | return (engine->leading() + engine->ascent() + engine->descent()).toReal(); |
1238 | 0 | } |
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 | 0 | { |
1252 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1253 | 0 | Q_ASSERT(engine != nullptr); |
1254 | 0 | return engine->minLeftBearing(); |
1255 | 0 | } |
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 | 0 | { |
1269 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1270 | 0 | Q_ASSERT(engine != nullptr); |
1271 | 0 | return engine->minRightBearing(); |
1272 | 0 | } |
1273 | | |
1274 | | /*! |
1275 | | Returns the width of the widest character in the font. |
1276 | | */ |
1277 | | qreal QFontMetricsF::maxWidth() const |
1278 | 0 | { |
1279 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1280 | 0 | Q_ASSERT(engine != nullptr); |
1281 | 0 | return engine->maxCharWidth(); |
1282 | 0 | } |
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 | 0 | { |
1290 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1291 | 0 | Q_ASSERT(engine != nullptr); |
1292 | 0 | if (d->capital == QFont::SmallCaps) |
1293 | 0 | return d->smallCapsFontPrivate()->engineForScript(QChar::Script_Common)->ascent().toReal(); |
1294 | 0 | return engine->xHeight().toReal(); |
1295 | 0 | } |
1296 | | |
1297 | | /*! |
1298 | | \since 4.2 |
1299 | | |
1300 | | Returns the average width of glyphs in the font. |
1301 | | */ |
1302 | | qreal QFontMetricsF::averageCharWidth() const |
1303 | 0 | { |
1304 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1305 | 0 | Q_ASSERT(engine != nullptr); |
1306 | 0 | return engine->averageCharWidth().toReal(); |
1307 | 0 | } |
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 | 0 | { |
1315 | 0 | return inFontUcs4(ch.unicode()); |
1316 | 0 | } |
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 | 0 | { |
1326 | 0 | const int script = QChar::script(ucs4); |
1327 | 0 | QFontEngine *engine = d->engineForScript(script); |
1328 | 0 | Q_ASSERT(engine != nullptr); |
1329 | 0 | if (engine->type() == QFontEngine::Box) |
1330 | 0 | return false; |
1331 | 0 | return engine->canRender(ucs4); |
1332 | 0 | } |
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 | 0 | { |
1348 | 0 | const int script = ch.script(); |
1349 | 0 | QFontEngine *engine; |
1350 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
1351 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
1352 | 0 | else |
1353 | 0 | engine = d->engineForScript(script); |
1354 | 0 | Q_ASSERT(engine != nullptr); |
1355 | 0 | if (engine->type() == QFontEngine::Box) |
1356 | 0 | return 0; |
1357 | | |
1358 | 0 | d->alterCharForCapitalization(ch); |
1359 | |
|
1360 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
1361 | |
|
1362 | 0 | qreal lb; |
1363 | 0 | engine->getGlyphBearings(glyph, &lb); |
1364 | 0 | return lb; |
1365 | 0 | } |
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 | 0 | { |
1381 | 0 | const int script = ch.script(); |
1382 | 0 | QFontEngine *engine; |
1383 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
1384 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
1385 | 0 | else |
1386 | 0 | engine = d->engineForScript(script); |
1387 | 0 | Q_ASSERT(engine != nullptr); |
1388 | 0 | if (engine->type() == QFontEngine::Box) |
1389 | 0 | return 0; |
1390 | | |
1391 | 0 | d->alterCharForCapitalization(ch); |
1392 | |
|
1393 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
1394 | |
|
1395 | 0 | qreal rb; |
1396 | 0 | engine->getGlyphBearings(glyph, nullptr, &rb); |
1397 | 0 | return rb; |
1398 | |
|
1399 | 0 | } |
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 | 0 | { |
1416 | 0 | int pos = (length >= 0) |
1417 | 0 | ? QStringView(text).left(length).indexOf(s_variableLengthStringSeparator) |
1418 | 0 | : text.indexOf(s_variableLengthStringSeparator); |
1419 | 0 | if (pos != -1) |
1420 | 0 | length = pos; |
1421 | 0 | else if (length < 0) |
1422 | 0 | length = text.size(); |
1423 | |
|
1424 | 0 | if (length == 0) |
1425 | 0 | return 0; |
1426 | | |
1427 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
1428 | 0 | layout.itemize(); |
1429 | 0 | return layout.width(0, length).toReal(); |
1430 | 0 | } |
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 | 0 | { |
1444 | 0 | int pos = text.indexOf(s_variableLengthStringSeparator); |
1445 | 0 | int length = -1; |
1446 | 0 | if (pos != -1) |
1447 | 0 | length = pos; |
1448 | 0 | else |
1449 | 0 | length = text.size(); |
1450 | |
|
1451 | 0 | if (length == 0) |
1452 | 0 | return 0; |
1453 | | |
1454 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
1455 | 0 | layout.option = option; |
1456 | 0 | layout.itemize(); |
1457 | 0 | return layout.width(0, length).toReal(); |
1458 | 0 | } |
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 | 0 | { |
1488 | 0 | if (ch.category() == QChar::Mark_NonSpacing) |
1489 | 0 | return 0.; |
1490 | | |
1491 | 0 | const int script = ch.script(); |
1492 | 0 | QFontEngine *engine; |
1493 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
1494 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
1495 | 0 | else |
1496 | 0 | engine = d->engineForScript(script); |
1497 | 0 | Q_ASSERT(engine != nullptr); |
1498 | |
|
1499 | 0 | d->alterCharForCapitalization(ch); |
1500 | |
|
1501 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
1502 | 0 | QFixed advance; |
1503 | |
|
1504 | 0 | QGlyphLayout glyphs; |
1505 | 0 | glyphs.numGlyphs = 1; |
1506 | 0 | glyphs.glyphs = &glyph; |
1507 | 0 | glyphs.advances = &advance; |
1508 | 0 | engine->recalcAdvances(&glyphs, { }); |
1509 | |
|
1510 | 0 | return advance.toReal(); |
1511 | 0 | } |
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 | 0 | { |
1536 | 0 | int len = text.size(); |
1537 | 0 | if (len == 0) |
1538 | 0 | return QRectF(); |
1539 | | |
1540 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
1541 | 0 | layout.itemize(); |
1542 | 0 | glyph_metrics_t gm = layout.boundingBox(0, len); |
1543 | 0 | return QRectF(gm.x.toReal(), gm.y.toReal(), |
1544 | 0 | gm.width.toReal(), gm.height.toReal()); |
1545 | 0 | } |
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 | 0 | { |
1571 | 0 | if (text.size() == 0) |
1572 | 0 | return QRectF(); |
1573 | | |
1574 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
1575 | 0 | layout.option = option; |
1576 | 0 | layout.itemize(); |
1577 | 0 | glyph_metrics_t gm = layout.boundingBox(0, text.size()); |
1578 | 0 | return QRectF(gm.x.toReal(), gm.y.toReal(), |
1579 | 0 | gm.width.toReal(), gm.height.toReal()); |
1580 | 0 | } |
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 | 0 | { |
1598 | 0 | const int script = ch.script(); |
1599 | 0 | QFontEngine *engine; |
1600 | 0 | if (d->capital == QFont::SmallCaps && ch.isLower()) |
1601 | 0 | engine = d->smallCapsFontPrivate()->engineForScript(script); |
1602 | 0 | else |
1603 | 0 | engine = d->engineForScript(script); |
1604 | 0 | Q_ASSERT(engine != nullptr); |
1605 | |
|
1606 | 0 | d->alterCharForCapitalization(ch); |
1607 | |
|
1608 | 0 | glyph_t glyph = engine->glyphIndex(ch.unicode()); |
1609 | |
|
1610 | 0 | glyph_metrics_t gm = engine->boundingBox(glyph); |
1611 | 0 | return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal()); |
1612 | 0 | } |
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 | 0 | { |
1678 | 0 | int tabArrayLen = 0; |
1679 | 0 | if (tabArray) |
1680 | 0 | while (tabArray[tabArrayLen]) |
1681 | 0 | tabArrayLen++; |
1682 | |
|
1683 | 0 | QRectF rb; |
1684 | 0 | qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, |
1685 | 0 | tabArrayLen, nullptr); |
1686 | 0 | return rb; |
1687 | 0 | } |
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 | 0 | { |
1719 | 0 | return boundingRect(QRectF(), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); |
1720 | 0 | } |
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 | 0 | { |
1745 | 0 | if (text.size() == 0) |
1746 | 0 | return QRectF(); |
1747 | | |
1748 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
1749 | 0 | layout.itemize(); |
1750 | 0 | glyph_metrics_t gm = layout.tightBoundingBox(0, text.size()); |
1751 | 0 | return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal()); |
1752 | 0 | } |
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 | 0 | { |
1777 | 0 | if (text.size() == 0) |
1778 | 0 | return QRectF(); |
1779 | | |
1780 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine layout(text, QFont(d.data())); |
1781 | 0 | layout.option = option; |
1782 | 0 | layout.itemize(); |
1783 | 0 | glyph_metrics_t gm = layout.tightBoundingBox(0, text.size()); |
1784 | 0 | return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal()); |
1785 | 0 | } |
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 | 0 | { |
1810 | 0 | QString _text = text; |
1811 | 0 | if (!(flags & Qt::TextLongestVariant)) { |
1812 | 0 | int posA = 0; |
1813 | 0 | int posB = _text.indexOf(s_variableLengthStringSeparator); |
1814 | 0 | while (posB >= 0) { |
1815 | 0 | QString portion = _text.mid(posA, posB - posA); |
1816 | 0 | if (size(flags, portion).width() <= width) |
1817 | 0 | return portion; |
1818 | 0 | posA = posB + 1; |
1819 | 0 | posB = _text.indexOf(s_variableLengthStringSeparator, posA); |
1820 | 0 | } |
1821 | 0 | _text = _text.mid(posA); |
1822 | 0 | } |
1823 | 0 | Q_DECL_UNINITIALIZED QStackTextEngine engine(_text, QFont(d.data())); |
1824 | 0 | return engine.elidedText(mode, QFixed::fromReal(width), flags); |
1825 | 0 | } |
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 | 0 | { |
1835 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1836 | 0 | Q_ASSERT(engine != nullptr); |
1837 | 0 | return engine->underlinePosition().toReal(); |
1838 | 0 | } |
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 | 0 | { |
1848 | 0 | return ascent() + 1; |
1849 | 0 | } |
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 | 0 | { |
1859 | 0 | return ascent() / 3.; |
1860 | 0 | } |
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 | 0 | { |
1870 | 0 | QFontEngine *engine = d->engineForScript(QChar::Script_Common); |
1871 | 0 | Q_ASSERT(engine != nullptr); |
1872 | 0 | return engine->lineThickness().toReal(); |
1873 | 0 | } |
1874 | | |
1875 | | /*! |
1876 | | \since 5.14 |
1877 | | |
1878 | | Returns the font DPI. |
1879 | | */ |
1880 | | qreal QFontMetricsF::fontDpi() const |
1881 | 0 | { |
1882 | 0 | return d->dpi; |
1883 | 0 | } |
1884 | | |
1885 | | QT_END_NAMESPACE |