Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquicktextnode.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 "qquicktextnode_p.h"
5
7
8#include <private/qsgadaptationlayer_p.h>
9#include <private/qsgdistancefieldglyphnode_p.h>
10#include <private/qquickclipnode_p.h>
11#include <private/qquickitem_p.h>
12#include <private/qquicktextdocument_p.h>
13#include <QtQuick/private/qsgcontext_p.h>
14
15#include <QtCore/qpoint.h>
16#include <qtextdocument.h>
17#include <qtextlayout.h>
19#include <private/qquickstyledtext_p.h>
20#include <private/qquicktext_p_p.h>
21#include <private/qfont_p.h>
22#include <private/qfontengine_p.h>
23
24#include <private/qtextdocumentlayout_p.h>
25#include <qhash.h>
26
28
30
31
35 : m_cursorNode(nullptr), m_ownerElement(ownerElement), m_useNativeRenderer(false), m_renderTypeQuality(-1)
36{
37#ifdef QSG_RUNTIME_DESCRIPTION
39#endif
40}
41
43{
44 qDeleteAll(m_textures);
45}
46
48 QQuickText::TextStyle style, const QColor &styleColor,
49 QSGNode *parentNode)
50{
52 QRawFont font = glyphs.rawFont();
53 bool preferNativeGlyphNode = m_useNativeRenderer;
54 if (!preferNativeGlyphNode) {
56 if (fontPriv->fontEngine->hasUnreliableGlyphOutline()) {
57 preferNativeGlyphNode = true;
58 } else {
60 preferNativeGlyphNode = !fe->isSmoothlyScalable;
61 }
62 }
63
64 QSGGlyphNode *node = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode, m_renderTypeQuality);
65
66 node->setOwnerElement(m_ownerElement);
67 node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
68 node->setStyle(style);
69 node->setStyleColor(styleColor);
70 node->setColor(color);
71 node->update();
72
73 /* We flag the geometry as static, but we never call markVertexDataDirty
74 or markIndexDataDirty on them. This is because all text nodes are
75 discarded when a change occurs. If we start appending/removing from
76 existing geometry, then we also need to start marking the geometry as
77 dirty.
78 */
81
82 if (parentNode == nullptr)
83 parentNode = this;
84 parentNode->appendChildNode(node);
85
86 if (style == QQuickText::Outline && color.alpha() > 0 && styleColor != color) {
87 QSGGlyphNode *fillNode = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode, m_renderTypeQuality);
88 fillNode->setOwnerElement(m_ownerElement);
89 fillNode->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
92 fillNode->setColor(color);
93 fillNode->update();
94
97
98 parentNode->appendChildNode(fillNode);
99 fillNode->setRenderOrder(node->renderOrder() + 1);
100 }
101
102 return node;
103}
104
106{
107 if (m_cursorNode != nullptr)
108 delete m_cursorNode;
109
112 appendChildNode(m_cursorNode);
113}
114
116{
117 if (m_cursorNode)
118 removeChildNode(m_cursorNode);
119 delete m_cursorNode;
120 m_cursorNode = nullptr;
121}
122
124{
127}
128
129
131{
135 if (m_ownerElement->smooth())
137 m_textures.append(texture);
138 node->setTargetRect(rect);
140 node->setTexture(texture);
141 if (m_ownerElement->smooth())
143 appendChildNode(node);
144 node->update();
145}
146
148 const QColor &textColor,
149 QQuickText::TextStyle style, const QColor &styleColor,
150 const QColor &anchorColor,
151 const QColor &selectionColor, const QColor &selectedTextColor,
152 int selectionStart, int selectionEnd)
153{
155 engine.setTextColor(textColor);
156 engine.setSelectedTextColor(selectedTextColor);
157 engine.setSelectionColor(selectionColor);
158 engine.setAnchorColor(anchorColor);
159 engine.setPosition(position);
160
161 QList<QTextFrame *> frames;
162 frames.append(textDocument->rootFrame());
163 while (!frames.isEmpty()) {
164 QTextFrame *textFrame = frames.takeFirst();
165 frames.append(textFrame->childFrames());
166
167 engine.addFrameDecorations(textDocument, textFrame);
168
169 if (textFrame->firstPosition() > textFrame->lastPosition()
170 && textFrame->frameFormat().position() != QTextFrameFormat::InFlow) {
171 const int pos = textFrame->firstPosition() - 1;
172 auto *a = static_cast<QtPrivate::ProtectedLayoutAccessor *>(textDocument->documentLayout());
173 QTextCharFormat format = a->formatAccessor(pos);
174 QRectF rect = a->frameBoundingRect(textFrame);
175
176 QTextBlock block = textFrame->firstCursorPosition().block();
177 engine.setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
178 engine.addTextObject(block, rect.topLeft(), format, QQuickTextNodeEngine::Unselected, textDocument,
179 pos, textFrame->frameFormat().position());
180 } else {
181 QTextFrame::iterator it = textFrame->begin();
182
183 while (!it.atEnd()) {
184 Q_ASSERT(!engine.currentLine().isValid());
185
186 QTextBlock block = it.currentBlock();
187 engine.addTextBlock(textDocument, block, position, textColor, anchorColor, selectionStart, selectionEnd,
189 m_ownerElement->clipRect() : QRectF()));
190 ++it;
191 }
192 }
193 }
194
195 engine.addToSceneGraph(this, style, styleColor);
196}
197
199 QQuickText::TextStyle style, const QColor &styleColor,
200 const QColor &anchorColor,
201 const QColor &selectionColor, const QColor &selectedTextColor,
202 int selectionStart, int selectionEnd,
203 int lineStart, int lineCount)
204{
206 engine.setTextColor(color);
207 engine.setSelectedTextColor(selectedTextColor);
208 engine.setSelectionColor(selectionColor);
209 engine.setAnchorColor(anchorColor);
210 engine.setPosition(position);
211
212#if QT_CONFIG(im)
213 int preeditLength = textLayout->preeditAreaText().size();
214 int preeditPosition = textLayout->preeditAreaPosition();
215#endif
216
218 engine.mergeFormats(textLayout, &colorChanges);
219
220 // If there's a lot of text, insert only the range of lines that can possibly be visible within the viewport.
222 if (m_ownerElement->flags().testFlag(QQuickItem::ItemObservesViewport)) {
223 viewport = m_ownerElement->clipRect();
224 qCDebug(lcVP) << "text viewport" << viewport;
225 }
226 lineCount = lineCount >= 0
227 ? qMin(lineStart + lineCount, textLayout->lineCount())
228 : textLayout->lineCount();
229
230 bool inViewport = false;
231 for (int i=lineStart; i<lineCount; ++i) {
232 QTextLine line = textLayout->lineAt(i);
233
234 int start = line.textStart();
235 int length = line.textLength();
236 int end = start + length;
237
238#if QT_CONFIG(im)
239 if (preeditPosition >= 0
240 && preeditPosition >= start
241 && preeditPosition < end) {
242 end += preeditLength;
243 }
244#endif
245 if (viewport.isNull() || (line.y() + line.height() > viewport.top() && line.y() < viewport.bottom())) {
246 if (!inViewport && !viewport.isNull()) {
247 m_firstLineInViewport = i;
248 qCDebug(lcVP) << "first line in viewport" << i << "@" << line.y();
249 }
250 inViewport = true;
251 engine.setCurrentLine(line);
252 engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
253 } else if (inViewport) {
254 Q_ASSERT(!viewport.isNull());
255 m_firstLinePastViewport = i;
256 qCDebug(lcVP) << "first omitted line past bottom of viewport" << i << "@" << line.y();
257 break; // went past the bottom of the viewport, so we're done
258 }
259 }
260
261 engine.addToSceneGraph(this, style, styleColor);
262}
263
265{
266 while (firstChild() != nullptr)
267 delete firstChild();
268 m_cursorNode = nullptr;
269 qDeleteAll(m_textures);
270 m_textures.clear();
271}
272
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
bool isSmoothlyScalable
virtual bool hasUnreliableGlyphOutline() const
The QGlyphRun class provides direct access to the internal glyphs in a font.
Definition qglyphrun.h:20
QRawFont rawFont() const
Returns the font selected for this QGlyphRun object.
\inmodule QtGui
Definition qimage.h:37
Definition qlist.h:74
bool isEmpty() const noexcept
Definition qlist.h:390
value_type takeFirst()
Definition qlist.h:549
void append(parameter_type t)
Definition qlist.h:441
void clear()
Definition qlist.h:417
\inmodule QtCore\reentrant
Definition qpoint.h:214
QSGRenderContext * sceneGraphRenderContext() const
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
Flags flags() const
Returns the item flags for this item.
bool smooth
\qmlproperty bool QtQuick::Item::smooth
Definition qquickitem.h:111
virtual QRectF clipRect() const
Returns the rectangular area within this item that is currently visible in \l viewportItem(),...
@ ItemObservesViewport
Definition qquickitem.h:137
QSGGlyphNode * addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color, QQuickText::TextStyle style=QQuickText::Normal, const QColor &styleColor=QColor(), QSGNode *parentNode=0)
void addImage(const QRectF &rect, const QImage &image)
void addRectangleNode(const QRectF &rect, const QColor &color)
void setCursor(const QRectF &rect, const QColor &color)
void addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color=QColor(), QQuickText::TextStyle style=QQuickText::Normal, const QColor &styleColor=QColor(), const QColor &anchorColor=QColor(), const QColor &selectionColor=QColor(), const QColor &selectedTextColor=QColor(), int selectionStart=-1, int selectionEnd=-1, int lineStart=0, int lineCount=-1)
void addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &color=QColor(), QQuickText::TextStyle style=QQuickText::Normal, const QColor &styleColor=QColor(), const QColor &anchorColor=QColor(), const QColor &selectionColor=QColor(), const QColor &selectedTextColor=QColor(), int selectionStart=-1, int selectionEnd=-1)
static const int largeTextSizeThreshold
static QRawFontPrivate * get(const QRawFont &font)
Definition qrawfont_p.h:104
QFontEngine * fontEngine
Definition qrawfont_p.h:106
The QRawFont class provides access to a single physical instance of a font.
Definition qrawfont.h:24
qreal ascent() const
Returns the ascent of this QRawFont in pixel units.
Definition qrawfont.cpp:314
\inmodule QtCore\reentrant
Definition qrect.h:483
const QSGGeometry * geometry() const
Returns this node's geometry.
Definition qsgnode.h:160
virtual QSGInternalImageNode * createInternalImageNode(QSGRenderContext *renderContext)=0
virtual QSGGlyphNode * createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode, int renderTypeQuality)=0
QSGInternalRectangleNode * createInternalRectangleNode(const QRectF &rect, const QColor &c)
Convenience factory function for creating a colored rectangle with the given geometry.
void setRenderOrder(int order)
Sets the render order of this node to be order.
Definition qsgnode.cpp:908
int renderOrder() const
Returns the render order of this geometry node.
Definition qsgnode.h:205
void setVertexDataPattern(DataPattern p)
Sets the usage pattern for vertices to p.
void setIndexDataPattern(DataPattern p)
Sets the usage pattern for indices to p.
void setOwnerElement(QQuickItem *ownerElement)
virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs)=0
virtual void setPreferredAntialiasingMode(AntialiasingMode)=0
virtual void setStyle(QQuickText::TextStyle style)=0
virtual void setColor(const QColor &color)=0
virtual void update()=0
virtual void setStyleColor(const QColor &color)=0
virtual void setTexture(QSGTexture *texture)=0
virtual void setTargetRect(const QRectF &rect)=0
virtual void setFiltering(QSGTexture::Filtering filtering)=0
virtual void update()=0
virtual void setInnerTargetRect(const QRectF &rect)=0
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
void removeChildNode(QSGNode *node)
Removes node from this node's list of children.
Definition qsgnode.cpp:498
void appendChildNode(QSGNode *node)
Appends node to this node's list of children.
Definition qsgnode.cpp:396
QSGNode * firstChild() const
Returns the first child of this node.
Definition qsgnode.h:105
virtual QSGTexture * createTexture(const QImage &image, uint flags=CreateTexture_Alpha) const =0
QSGContext * sceneGraphContext() const
\inmodule QtQuick
Definition qsgtexture.h:20
void setFiltering(Filtering filter)
Sets the sampling mode to filter.
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
\reentrant
QTextLayout * layout() const
Returns the QTextLayout that is used to lay out and display the block's contents.
int position() const
Returns the index of the block's first character within the document.
QTextBlock block() const
Returns the block that contains the cursor.
\reentrant \inmodule QtGui
QAbstractTextDocumentLayout * documentLayout() const
Returns the document layout for this document.
QTextFrame * rootFrame() const
Returns the document's root frame.
int characterCount() const
Position position() const
Returns the positioning policy for frames with this frame format.
\reentrant
Definition qtextobject.h:81
int lastPosition() const
Returns the last document position inside the frame.
QList< QTextFrame * > childFrames() const
Returns a (possibly empty) list of the frame's child frames.
QTextFrameFormat frameFormat() const
Returns the frame's format.
Definition qtextobject.h:89
iterator begin() const
Returns an iterator pointing to the first document element inside the frame.
int firstPosition() const
Returns the first document position inside the frame.
QTextCursor firstCursorPosition() const
Returns the first cursor position inside the frame.
\reentrant
Definition qtextlayout.h:70
QTextLine lineForTextPosition(int pos) const
Returns the line that contains the cursor position specified by pos.
int lineCount() const
Returns the number of lines in this text layout.
int preeditAreaPosition() const
Returns the position of the area in the text layout that will be processed before editing occurs.
QTextLine lineAt(int i) const
Returns the {i}-th line of text in this text layout.
QString preeditAreaText() const
Returns the text that is inserted in the layout before editing occurs.
\reentrant
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
rect
[4]
Combined button and popup list for selecting options.
Definition image.cpp:4
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLuint texture
GLuint start
GLint GLsizei GLsizei GLenum format
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
void qsgnode_set_description(QSGNode *node, const QString &description)
Definition qsgnode.cpp:639
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
view viewport() -> scroll(dx, dy, deviceRect)
QJSEngine engine
[0]