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