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
qsginternaltextnode.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
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
14#include <QtCore/qpoint.h>
15#include <qtextdocument.h>
16#include <qtextlayout.h>
18#include <private/qquickstyledtext_p.h>
19#include <private/qquicktext_p_p.h>
20#include <private/qfont_p.h>
21#include <private/qfontengine_p.h>
22
23#include <private/qtextdocumentlayout_p.h>
24#include <qhash.h>
25
27
29
30
34 : m_renderContext(renderContext)
35{
36#ifdef QSG_RUNTIME_DESCRIPTION
38#endif
39
40 static_assert(int(QSGTextNode::Normal) == int(QQuickText::Normal));
41 static_assert(int(QSGTextNode::Outline) == int(QQuickText::Outline));
42 static_assert(int(QSGTextNode::Raised) == int(QQuickText::Raised));
43 static_assert(int(QSGTextNode::Sunken) == int(QQuickText::Sunken));
44
45 static_assert(int(QSGTextNode::QtRendering) == int(QQuickText::QtRendering));
48}
49
54
56 QQuickText::TextStyle style, const QColor &styleColor,
57 QSGNode *parentNode)
58{
59 QRawFont font = glyphs.rawFont();
60
61 QSGTextNode::RenderType preferredRenderType = m_renderType;
62 if (m_renderType != NativeRendering) {
63 if (const QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine)
64 if (fe->hasUnreliableGlyphOutline() || !fe->isSmoothlyScalable)
65 preferredRenderType = QSGTextNode::NativeRendering;
66 }
67
68 QSGGlyphNode *node = m_renderContext->sceneGraphContext()->createGlyphNode(m_renderContext,
69 preferredRenderType,
70 m_renderTypeQuality);
71 node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
72 node->setStyle(style);
74 node->setColor(color);
75 node->update();
76
77 /* We flag the geometry as static, but we never call markVertexDataDirty
78 or markIndexDataDirty on them. This is because all text nodes are
79 discarded when a change occurs. If we start appending/removing from
80 existing geometry, then we also need to start marking the geometry as
81 dirty.
82 */
85
86 if (parentNode == nullptr)
87 parentNode = this;
88 parentNode->appendChildNode(node);
89
90 if (style == QQuickText::Outline && color.alpha() > 0 && styleColor != color) {
91 QSGGlyphNode *fillNode = m_renderContext->sceneGraphContext()->createGlyphNode(m_renderContext,
92 preferredRenderType,
93 m_renderTypeQuality);
94 fillNode->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
95 fillNode->setStyle(QQuickText::Normal);
96 fillNode->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
97 fillNode->setColor(color);
98 fillNode->update();
99
100 fillNode->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
101 fillNode->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
102
103 parentNode->appendChildNode(fillNode);
104 fillNode->setRenderOrder(node->renderOrder() + 1);
105 }
106
107 return node;
108}
109
111{
112 if (m_cursorNode != nullptr)
113 delete m_cursorNode;
114
115 m_cursorNode = m_renderContext->sceneGraphContext()->createInternalRectangleNode(rect, color);
116 appendChildNode(m_cursorNode);
117}
118
120{
121 if (m_cursorNode)
122 removeChildNode(m_cursorNode);
123 delete m_cursorNode;
124 m_cursorNode = nullptr;
125}
126
131
136
138{
139 QSGInternalImageNode *node = m_renderContext->sceneGraphContext()->createInternalImageNode(m_renderContext);
140 QSGTexture *texture = m_renderContext->createTexture(image);
141 texture->setFiltering(m_filtering);
142 m_textures.append(texture);
143 node->setTargetRect(rect);
145 node->setTexture(texture);
146 node->setFiltering(m_filtering);
147 appendChildNode(node);
148 node->update();
149}
150
152 int selectionStart, int selectionEnd)
153{
155 engine.setTextColor(m_color);
156 engine.setSelectedTextColor(m_selectionTextColor);
157 engine.setSelectionColor(m_selectionColor);
158 engine.setAnchorColor(m_linkColor);
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, m_color, m_linkColor, selectionStart, selectionEnd,
189 m_viewport : QRectF()));
190 ++it;
191 }
192 }
193 }
194
195 engine.addToSceneGraph(this, QQuickText::TextStyle(m_textStyle), m_styleColor);
196}
197
199 int selectionStart, int selectionEnd,
200 int lineStart, int lineCount)
201{
203 engine.setTextColor(m_color);
204 engine.setSelectedTextColor(m_selectionTextColor);
205 engine.setSelectionColor(m_selectionColor);
206 engine.setAnchorColor(m_linkColor);
207 engine.setPosition(position);
208
209#if QT_CONFIG(im)
210 int preeditLength = textLayout->preeditAreaText().size();
211 int preeditPosition = textLayout->preeditAreaPosition();
212#endif
213
214 QVarLengthArray<QTextLayout::FormatRange> colorChanges;
215 engine.mergeFormats(textLayout, &colorChanges);
216
217 lineCount = lineCount >= 0
218 ? qMin(lineStart + lineCount, textLayout->lineCount())
219 : textLayout->lineCount();
220
221 bool inViewport = false;
222 for (int i=lineStart; i<lineCount; ++i) {
223 QTextLine line = textLayout->lineAt(i);
224
225 int start = line.textStart();
226 int length = line.textLength();
227 int end = start + length;
228
229#if QT_CONFIG(im)
230 if (preeditPosition >= 0
231 && preeditPosition >= start
232 && preeditPosition < end) {
233 end += preeditLength;
234 }
235#endif
236 // If there's a lot of text, insert only the range of lines that can possibly be visible within the viewport.
237 if (m_viewport.isNull() || (line.y() + line.height() > m_viewport.top() && line.y() < m_viewport.bottom())) {
238 if (!inViewport && !m_viewport.isNull()) {
239 m_firstLineInViewport = i;
240 qCDebug(lcVP) << "first line in viewport" << i << "@" << line.y();
241 }
242 inViewport = true;
243 engine.setCurrentLine(line);
244 engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
245 } else if (inViewport) {
246 Q_ASSERT(!m_viewport.isNull());
247 m_firstLinePastViewport = i;
248 qCDebug(lcVP) << "first omitted line past bottom of viewport" << i << "@" << line.y();
249 break; // went past the bottom of the viewport, so we're done
250 }
251 }
252
253 engine.addToSceneGraph(this, QQuickText::TextStyle(m_textStyle), m_styleColor);
254}
255
257{
258 while (firstChild() != nullptr)
259 delete firstChild();
260 m_cursorNode = nullptr;
261 qDeleteAll(m_textures);
262 m_textures.clear();
263}
264
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
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
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore\reentrant
Definition qpoint.h:217
static const int largeTextSizeThreshold
static QRawFontPrivate * get(const QRawFont &font)
Definition qrawfont_p.h:104
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:484
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:500
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition qrect.h:658
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:498
const QSGGeometry * geometry() const
Returns this node's geometry.
Definition qsgnode.h:160
virtual QSGInternalImageNode * createInternalImageNode(QSGRenderContext *renderContext)=0
QSGInternalRectangleNode * createInternalRectangleNode(const QRectF &rect, const QColor &c)
Convenience factory function for creating a colored rectangle with the given geometry.
virtual QSGGlyphNode * createGlyphNode(QSGRenderContext *rc, QSGTextNode::RenderType renderType, int renderTypeQuality)=0
int renderOrder() const
Returns the render order of this geometry node.
Definition qsgnode.h:202
void setVertexDataPattern(DataPattern p)
Sets the usage pattern for vertices to p.
void setIndexDataPattern(DataPattern p)
Sets the usage pattern for indices to p.
virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs)=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
void addImage(const QRectF &rect, const QImage &image)
void clear() override
Clears the contents of the node, deleting nodes and other data that represents the layouts and docume...
void doAddTextLayout(QPointF position, QTextLayout *textLayout, int selectionStart, int selectionEnd, int lineStart, int lineCount) override
Virtual function called by addTextLayout(), which converts the contents of layout to scene graph node...
void doAddTextDocument(QPointF position, QTextDocument *textDocument, int selectionStart, int selectionEnd) override
Virtual function called by addTextDocument(), which converts the contents of document to scene graph ...
virtual void addDecorationNode(const QRectF &rect, const QColor &color)
QSGGlyphNode * addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color, QQuickText::TextStyle style=QQuickText::Normal, const QColor &styleColor=QColor(), QSGNode *parentNode=0)
void addRectangleNode(const QRectF &rect, const QColor &color)
void setCursor(const QRectF &rect, const QColor &color)
QColor styleColor() const override
Returns the style color used when rendering the text.
\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:500
void appendChildNode(QSGNode *node)
Appends node to this node's list of children.
Definition qsgnode.cpp:398
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
RenderType
This enum type describes type of glyph node used for rendering the text.
Definition qsgtextnode.h:29
\inmodule QtQuick
Definition qsgtexture.h:20
iterator begin()
Definition qset.h:136
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
\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.
\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
\reentrant
Definition qtextobject.h:81
\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
GLuint color
[2]
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:641
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
QJSEngine engine
[0]