36QSGInternalTextNode::QSGInternalTextNode(QSGRenderContext *renderContext)
37 : m_renderContext(renderContext)
39#ifdef QSG_RUNTIME_DESCRIPTION
40 qsgnode_set_description(
this, QLatin1String(
"text"));
43 static_assert(
int(QSGTextNode::Normal) ==
int(QQuickText::Normal));
44 static_assert(
int(QSGTextNode::Outline) ==
int(QQuickText::Outline));
45 static_assert(
int(QSGTextNode::Raised) ==
int(QQuickText::Raised));
46 static_assert(
int(QSGTextNode::Sunken) ==
int(QQuickText::Sunken));
48 static_assert(
int(QSGTextNode::QtRendering) ==
int(QQuickText::QtRendering));
49 static_assert(
int(QSGTextNode::NativeRendering) ==
int(QQuickText::NativeRendering));
50 static_assert(
int(QSGTextNode::CurveRendering) ==
int(QQuickText::CurveRendering));
58QSGGlyphNode *QSGInternalTextNode::addGlyphs(
const QPointF &position,
const QGlyphRun &glyphs,
const QColor &color,
59 QQuickText::TextStyle style,
const QColor &styleColor,
62 QRawFont font = glyphs.rawFont();
64 QSGTextNode::RenderType preferredRenderType = m_renderType;
65 if (m_renderType != NativeRendering) {
66 if (
const QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine)
67 if (fe->hasUnreliableGlyphOutline() || !fe->isSmoothlyScalable)
68 preferredRenderType = QSGTextNode::NativeRendering;
71 if (preferredRenderType == NativeRendering)
72 m_containsUnscalableGlyphs =
true;
74 QSGGlyphNode *node = m_renderContext->sceneGraphContext()->createGlyphNode(m_renderContext,
77 node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
78 node->setStyle(style);
79 node->setStyleColor(styleColor);
80 node->setColor(color);
84
85
86
87
88
89 node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
90 node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
92 if (parentNode ==
nullptr)
94 parentNode->appendChildNode(node);
96 if (style == QQuickText::Outline && color.alpha() > 0 && styleColor != color) {
97 QSGGlyphNode *fillNode = m_renderContext->sceneGraphContext()->createGlyphNode(m_renderContext,
100 fillNode->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
101 fillNode->setStyle(QQuickText::Normal);
102 fillNode->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
103 fillNode->setColor(color);
106 fillNode->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
107 fillNode->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
109 parentNode->appendChildNode(fillNode);
110 fillNode->setRenderOrder(node->renderOrder() + 1);
143void QSGInternalTextNode::addImage(
const QRectF &rect,
const QImage &image)
145 QSGInternalImageNode *node = m_renderContext->sceneGraphContext()->createInternalImageNode(m_renderContext);
146 QSGTexture *texture = m_renderContext->createTexture(image);
147 texture->setFiltering(m_filtering);
148 m_textures.append(texture);
149 node->setTargetRect(rect);
150 node->setInnerTargetRect(rect);
151 node->setTexture(texture);
152 node->setFiltering(m_filtering);
153 appendChildNode(node);
157void QSGInternalTextNode::doAddTextDocument(QPointF position, QTextDocument *textDocument,
158 int selectionStart,
int selectionEnd)
160 QQuickTextNodeEngine engine;
161 engine.setTextColor(m_color);
162 engine.setSelectedTextColor(m_selectionTextColor);
163 engine.setSelectionColor(m_selectionColor);
164 engine.setAnchorColor(m_linkColor);
165 engine.setPosition(position);
166 engine.setDevicePixelRatio(m_devicePixelRatio);
168 QList<QTextFrame *> frames;
169 frames.append(textDocument->rootFrame());
170 while (!frames.isEmpty()) {
171 QTextFrame *textFrame = frames.takeFirst();
172 frames.append(textFrame->childFrames());
174 engine.addFrameDecorations(textDocument, textFrame);
176 if (textFrame->firstPosition() > textFrame->lastPosition()
177 && textFrame->frameFormat().position() != QTextFrameFormat::InFlow) {
178 const int pos = textFrame->firstPosition() - 1;
179 auto *a =
static_cast<QtPrivate::ProtectedLayoutAccessor *>(textDocument->documentLayout());
180 QTextCharFormat format = a->formatAccessor(pos);
181 QRectF rect = a->frameBoundingRect(textFrame);
183 QTextBlock block = textFrame->firstCursorPosition().block();
184 engine.setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
185 engine.addTextObject(block, rect.topLeft(), format, QQuickTextNodeEngine::Unselected, textDocument,
186 pos, textFrame->frameFormat().position());
188 QTextFrame::iterator it = textFrame->begin();
190 while (!it.atEnd()) {
191 Q_ASSERT(!engine.currentLine().isValid());
193 QTextBlock block = it.currentBlock();
194 engine.addTextBlock(textDocument, block, position, m_color, m_linkColor, selectionStart, selectionEnd,
195 (textDocument->characterCount() > QQuickTextPrivate::largeTextSizeThreshold ?
196 m_viewport : QRectF()));
202 engine.addToSceneGraph(
this, QQuickText::TextStyle(m_textStyle), m_styleColor);
205void QSGInternalTextNode::doAddTextLayout(QPointF position, QTextLayout *textLayout,
206 int selectionStart,
int selectionEnd,
207 int lineStart,
int lineCount)
209 QQuickTextNodeEngine engine;
210 engine.setTextColor(m_color);
211 engine.setSelectedTextColor(m_selectionTextColor);
212 engine.setSelectionColor(m_selectionColor);
213 engine.setAnchorColor(m_linkColor);
214 engine.setPosition(position);
215 engine.setDevicePixelRatio(m_devicePixelRatio);
218 int preeditLength = textLayout->preeditAreaText().size();
219 int preeditPosition = textLayout->preeditAreaPosition();
222 QVarLengthArray<QTextLayout::FormatRange> colorChanges;
223 engine.mergeFormats(textLayout, &colorChanges);
225 lineCount = lineCount >= 0
226 ? qMin(lineStart + lineCount, textLayout->lineCount())
227 : textLayout->lineCount();
229 bool inViewport =
false;
230 for (
int i=lineStart; i<lineCount; ++i) {
231 QTextLine line = textLayout->lineAt(i);
233 int start = line.textStart();
234 int length = line.textLength();
235 int end = start + length;
238 if (preeditPosition >= 0
239 && preeditPosition >= start
240 && preeditPosition < end) {
241 end += preeditLength;
245 if (m_viewport.isNull() || (line.y() + line.height() > m_viewport.top() && line.y() < m_viewport.bottom())) {
246 if (!inViewport && !m_viewport.isNull()) {
247 m_firstLineInViewport = i;
248 qCDebug(lcVP) <<
"first line in viewport" << i <<
"@" << line.y();
251 engine.setCurrentLine(line);
252 engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
253 }
else if (inViewport) {
254 Q_ASSERT(!m_viewport.isNull());
255 m_firstLinePastViewport = i;
256 qCDebug(lcVP) <<
"first omitted line past bottom of viewport" << i <<
"@" << line.y();
261 engine.addToSceneGraph(
this, QQuickText::TextStyle(m_textStyle), m_styleColor);