Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qstatictext.cpp
Go to the documentation of this file.
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 "qstatictext.h"
5#include "qstatictext_p.h"
6#include <qmath.h>
7#include <private/qtextengine_p.h>
8#include <private/qfontengine_p.h>
10
12
14
18
126
132{
133 data->text = text;
134 data->invalidate();
135}
136
144
149{
150 Q_ASSERT(!data || data->ref.loadRelaxed() >= 1);
151}
152
156void QStaticText::detach()
157{
158 if (data->ref.loadRelaxed() != 1)
159 data.detach();
160}
161
179{
180 data->matrix = matrix;
181 data->font = font;
182 data->init();
183}
184
185
190{
191 data = other.data;
192 return *this;
193}
194
208{
209 return (data == other.data
210 || (data->text == other.data->text
211 && data->font == other.data->font
212 && data->textWidth == other.data->textWidth));
213}
214
220{
221 return !(*this == other);
222}
223
232{
233 detach();
234 data->text = text;
235 data->invalidate();
236}
237
250{
251 detach();
252 data->textFormat = textFormat;
253 data->invalidate();
254}
255
262{
263 return Qt::TextFormat(data->textFormat);
264}
265
272{
273 return data->text;
274}
275
289{
290 if ((performanceHint == ModerateCaching && !data->useBackendOptimizations)
291 || (performanceHint == AggressiveCaching && data->useBackendOptimizations)) {
292 return;
293 }
294 detach();
295 data->useBackendOptimizations = (performanceHint == AggressiveCaching);
296 data->invalidate();
297}
298
305{
306 return data->useBackendOptimizations ? AggressiveCaching : ModerateCaching;
307}
308
315{
316 detach();
317 data->textOption = textOption;
318 data->invalidate();
319}
320
325{
326 return data->textOption;
327}
328
343{
344 detach();
345 data->textWidth = textWidth;
346 data->invalidate();
347}
348
355{
356 return data->textWidth;
357}
358
365{
366 if (data->needsRelayout)
367 data->init();
368 return data->actualSize;
369}
370
372 : textWidth(-1.0), items(nullptr), itemCount(0), glyphPool(nullptr), positionPool(nullptr),
373 needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText),
374 untransformedCoordinates(false)
375{
376}
377
379 : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix),
380 items(nullptr), itemCount(0), glyphPool(nullptr), positionPool(nullptr), textOption(other.textOption),
381 needsRelayout(true), useBackendOptimizations(other.useBackendOptimizations),
382 textFormat(other.textFormat), untransformedCoordinates(other.untransformedCoordinates)
383{
384}
385
387{
388 delete[] items;
389 delete[] glyphPool;
390 delete[] positionPool;
391}
392
394{
395 return q->data.data();
396}
397
398namespace {
399
400 class DrawTextItemRecorder: public QPaintEngine
401 {
402 public:
403 DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations)
404 : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations),
405 m_untransformedCoordinates(untransformedCoordinates), m_currentColor(0, 0, 0, 0)
406 {
407 }
408
409 virtual void updateState(const QPaintEngineState &newState) override
410 {
411 if (newState.state() & QPaintEngine::DirtyPen
412 && newState.pen().color() != m_currentColor) {
413 m_dirtyPen = true;
414 m_currentColor = newState.pen().color();
415 }
416 }
417
418 virtual void drawTextItem(const QPointF &position, const QTextItem &textItem) override
419 {
420 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
421
422 QStaticTextItem currentItem;
423 currentItem.setFontEngine(ti.fontEngine);
424 currentItem.font = ti.font();
425 currentItem.glyphOffset = m_glyphs.size(); // Store offset into glyph pool
426 currentItem.positionOffset = m_glyphs.size(); // Offset into position pool
427 currentItem.useBackendOptimizations = m_useBackendOptimizations;
428 if (m_dirtyPen)
429 currentItem.color = m_currentColor;
430
431 QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform();
432 matrix.translate(position.x(), position.y());
433
434 QVarLengthArray<glyph_t> glyphs;
435 QVarLengthArray<QFixedPoint> positions;
436 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
437
438 int size = glyphs.size();
439 Q_ASSERT(size == positions.size());
440 currentItem.numGlyphs = size;
441
442 m_glyphs.resize(m_glyphs.size() + size);
443 m_positions.resize(m_glyphs.size());
444
445 glyph_t *glyphsDestination = m_glyphs.data() + currentItem.glyphOffset;
446 memcpy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * currentItem.numGlyphs);
447
448 QFixedPoint *positionsDestination = m_positions.data() + currentItem.positionOffset;
449 memcpy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * currentItem.numGlyphs);
450
451 m_items.append(currentItem);
452 }
453
454 virtual void drawPolygon(const QPointF *, int , PolygonDrawMode ) override
455 {
456 /* intentionally empty */
457 }
458
459 virtual bool begin(QPaintDevice *) override { return true; }
460 virtual bool end() override { return true; }
461 virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) override {}
462 virtual Type type() const override
463 {
464 return User;
465 }
466
467 QList<QStaticTextItem> items() const
468 {
469 return m_items;
470 }
471
472 QList<QFixedPoint> positions() const
473 {
474 return m_positions;
475 }
476
477 QList<glyph_t> glyphs() const
478 {
479 return m_glyphs;
480 }
481
482 private:
483 QList<QStaticTextItem> m_items;
484 QList<QFixedPoint> m_positions;
485 QList<glyph_t> m_glyphs;
486
487 bool m_dirtyPen;
488 bool m_useBackendOptimizations;
489 bool m_untransformedCoordinates;
490 QColor m_currentColor;
491 };
492
493 class DrawTextItemDevice: public QPaintDevice
494 {
495 public:
496 DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations)
497 {
498 m_paintEngine = new DrawTextItemRecorder(untransformedCoordinates,
499 useBackendOptimizations);
500 }
501
502 ~DrawTextItemDevice()
503 {
504 delete m_paintEngine;
505 }
506
507 int metric(PaintDeviceMetric m) const override
508 {
509 int val;
510 switch (m) {
511 case PdmWidth:
512 case PdmHeight:
513 case PdmWidthMM:
514 case PdmHeightMM:
515 val = 0;
516 break;
517 case PdmDpiX:
518 case PdmPhysicalDpiX:
520 break;
521 case PdmDpiY:
522 case PdmPhysicalDpiY:
524 break;
525 case PdmNumColors:
526 val = 16777216;
527 break;
528 case PdmDepth:
529 val = 24;
530 break;
531 case PdmDevicePixelRatio:
532 val = 1;
533 break;
534 case PdmDevicePixelRatioScaled:
535 val = devicePixelRatioFScale();
536 break;
537 default:
538 val = 0;
539 qWarning("DrawTextItemDevice::metric: Invalid metric command");
540 }
541 return val;
542 }
543
544 virtual QPaintEngine *paintEngine() const override
545 {
546 return m_paintEngine;
547 }
548
549 QList<glyph_t> glyphs() const
550 {
551 return m_paintEngine->glyphs();
552 }
553
554 QList<QFixedPoint> positions() const
555 {
556 return m_paintEngine->positions();
557 }
558
559 QList<QStaticTextItem> items() const
560 {
561 return m_paintEngine->items();
562 }
563
564 private:
565 DrawTextItemRecorder *m_paintEngine;
566 };
567}
568
569void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p, const QColor &pen)
570{
571 bool preferRichText = textFormat == Qt::RichText
573
574 if (!preferRichText) {
575 QTextLayout textLayout;
576 textLayout.setText(text);
577 textLayout.setFont(font);
578 textLayout.setTextOption(textOption);
579 textLayout.setCacheEnabled(true);
580
581 qreal height = 0;
582 textLayout.beginLayout();
583 while (1) {
584 QTextLine line = textLayout.createLine();
585 if (!line.isValid())
586 break;
587 line.setLeadingIncluded(true);
588
589 if (textWidth >= 0.0)
590 line.setLineWidth(textWidth);
591 else
592 line.setLineWidth(QFIXED_MAX);
593 line.setPosition(QPointF(0.0, height));
594 height += line.height();
595 if (line.leading() < 0)
596 height += qCeil(line.leading());
597 }
598 textLayout.endLayout();
599
600 actualSize = textLayout.boundingRect().size();
601 p->setPen(pen);
602 textLayout.draw(p, topLeftPosition);
603 } else {
604 QTextDocument document;
605#ifndef QT_NO_CSSPARSER
606 document.setDefaultStyleSheet(QString::fromLatin1("body { color: rgba(%1, %2, %3, %4%) }")
607 .arg(QString::number(pen.red()))
608 .arg(QString::number(pen.green()))
609 .arg(QString::number(pen.blue()))
610 .arg(QString::number(pen.alpha())));
611#endif
612 document.setDefaultFont(font);
613 document.setDocumentMargin(0.0);
614#ifndef QT_NO_TEXTHTMLPARSER
615 document.setHtml(text);
616#else
617 document.setPlainText(text);
618#endif
619 if (textWidth >= 0.0)
620 document.setTextWidth(textWidth);
621 else
622 document.adjustSize();
623 document.setDefaultTextOption(textOption);
624
625 p->save();
626 p->translate(topLeftPosition);
628 ctx.palette.setColor(QPalette::Text, pen);
629 document.documentLayout()->draw(p, ctx);
630 p->restore();
631
632 actualSize = document.size();
633 }
634}
635
637{
638 delete[] items;
639 delete[] glyphPool;
640 delete[] positionPool;
641
642 position = QPointF(0, 0);
643
645 {
649
650 paintText(QPointF(0, 0), &painter, QColor(0, 0, 0, 0));
651 }
652
653 QList<QStaticTextItem> deviceItems = device.items();
654 QList<QFixedPoint> positions = device.positions();
655 QList<glyph_t> glyphs = device.glyphs();
656
657 itemCount = deviceItems.size();
659
660 glyphPool = new glyph_t[glyphs.size()];
661 memcpy(glyphPool, glyphs.constData(), glyphs.size() * sizeof(glyph_t));
662
663 positionPool = new QFixedPoint[positions.size()];
664 memcpy(positionPool, positions.constData(), positions.size() * sizeof(QFixedPoint));
665
666 for (int i=0; i<itemCount; ++i) {
667 items[i] = deviceItems.at(i);
668
671 }
672
673 needsRelayout = false;
674}
675
IOBluetoothDevice * device
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
int alpha() const noexcept
Returns the alpha color component of this color.
Definition qcolor.cpp:1466
int red() const noexcept
Returns the red color component of this color.
Definition qcolor.cpp:1528
int blue() const noexcept
Returns the blue color component of this color.
Definition qcolor.cpp:1583
int green() const noexcept
Returns the green color component of this color.
Definition qcolor.cpp:1555
\reentrant
Definition qfont.h:22
The QPaintEngineState class provides information about the active paint engine's current state....
\inmodule QtGui
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void setFont(const QFont &f)
Sets the painter's font to the given font.
void setTransform(const QTransform &transform, bool combine=false)
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:217
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:735
\inmodule QtCore
Definition qsize.h:208
char useBackendOptimizations
QFixedPoint * glyphPositions
void setFontEngine(QFontEngine *fe)
unsigned char textFormat
unsigned char useBackendOptimizations
void paintText(const QPointF &pos, QPainter *p, const QColor &pen)
static QStaticTextPrivate * get(const QStaticText *q)
QTextOption textOption
unsigned char needsRelayout
QFixedPoint * positionPool
QStaticTextItem * items
unsigned char untransformedCoordinates
The QStaticText class enables optimized drawing of text when the text and its layout is updated rarel...
Definition qstatictext.h:21
void setText(const QString &text)
Sets the text of the QStaticText to text.
QStaticText()
Constructs an empty QStaticText.
QTextOption textOption() const
Returns the current text option used to control the layout process.
void setTextWidth(qreal textWidth)
Sets the preferred width for this QStaticText.
qreal textWidth() const
Returns the preferred width for this QStaticText.
Qt::TextFormat textFormat() const
Returns the text format of the QStaticText.
void prepare(const QTransform &matrix=QTransform(), const QFont &font=QFont())
Prepares the QStaticText object for being painted with the given matrix and the given font to avoid o...
PerformanceHint performanceHint() const
Returns which performance hint is set for the QStaticText.
bool operator!=(const QStaticText &) const
Compares other to this QStaticText.
QStaticText & operator=(const QStaticText &)
Assigns other to this QStaticText.
void setTextFormat(Qt::TextFormat textFormat)
Sets the text format of the QStaticText to textFormat.
~QStaticText()
Destroys the QStaticText.
void setPerformanceHint(PerformanceHint performanceHint)
Sets the performance hint of the QStaticText according to the performanceHint provided.
QSizeF size() const
Returns the size of the bounding rect for this QStaticText.
void setTextOption(const QTextOption &textOption)
Sets the text option structure that controls the layout process to the given textOption.
QString text() const
Returns the text of the QStaticText.
bool operator==(const QStaticText &) const
Compares other to this QStaticText.
PerformanceHint
This enum the different performance hints that can be set on the QStaticText.
Definition qstatictext.h:23
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\reentrant \inmodule QtGui
Internal QTextItem.
\inmodule QtGui
\reentrant
Definition qtextlayout.h:70
void setFont(const QFont &f)
Sets the layout's font to the given font.
QTextLine createLine()
Returns a new text line to be laid out if there is text to be inserted into the layout; otherwise ret...
void beginLayout()
Begins the layout process.
void setCacheEnabled(bool enable)
Enables caching of the complete layout information if enable is true; otherwise disables layout cachi...
void setText(const QString &string)
Sets the layout's text to the given string.
void setTextOption(const QTextOption &option)
Sets the text option structure that controls the layout process to the given option.
void draw(QPainter *p, const QPointF &pos, const QList< FormatRange > &selections=QList< FormatRange >(), const QRectF &clip=QRectF()) const
Draws the whole layout on the painter p at the position specified by pos.
void endLayout()
Ends the layout process.
QRectF boundingRect() const
The smallest rectangle that contains all the lines in the layout.
\reentrant
\reentrant
Definition qtextoption.h:18
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
EGLContext ctx
QString text
else opt state
[0]
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
Definition qcompare.h:63
TextFormat
@ RichText
@ AutoText
Q_GUI_EXPORT bool mightBeRichText(QAnyStringView)
Returns true if the string text is likely to be rich text; otherwise returns false.
static const QCssKnownValue positions[NumKnownPositionModes - 1]
#define QFIXED_MAX
Definition qfixed_p.h:127
Q_GUI_EXPORT int qt_defaultDpiX()
Definition qfont.cpp:110
Q_GUI_EXPORT int qt_defaultDpiY()
Definition qfont.cpp:125
#define qWarning
Definition qlogging.h:166
int qCeil(T v)
Definition qmath.h:36
@ User
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition qmetatype.h:1390
const GLfloat * m
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint end
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLuint GLenum GLenum transform
GLuint GLfloat * val
GLuint GLenum matrix
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
unsigned int glyph_t
double qreal
Definition qtypes.h:187
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QList< QTreeWidgetItem * > items
QPainter painter(this)
[7]
Definition moc.h:23