Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgcurveglyphnode.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 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// Qt-Security score:significant reason:default
4
9
10#include <private/qsgcurveabstractnode_p.h>
11#include <private/qsgcontext_p.h>
12#include <private/qsgtexturematerial_p.h>
13
14#include <private/qrawfont_p.h>
15#include <QtGui/qcolor.h>
16
17QT_BEGIN_NAMESPACE
18
19QSGCurveGlyphNode::QSGCurveGlyphNode(QSGRenderContext *context)
20 : m_context(context)
21 , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
22 , m_dirtyGeometry(false)
23{
24 setFlag(UsePreprocess);
25 setFlag(OwnsMaterial);
26
27 // #### To avoid asserts: we should probably merge this with QSGCurveFillNode
28 setGeometry(&m_geometry);
29 setMaterial(new QSGTextureMaterial);
30}
31
32QSGCurveGlyphNode::~QSGCurveGlyphNode()
33{
34}
35
36void QSGCurveGlyphNode::setPreferredAntialiasingMode(AntialiasingMode mode)
37{
38 Q_UNUSED(mode);
39}
40
41void QSGCurveGlyphNode::setColor(const QColor &color)
42{
43 m_color = color;
44 if (m_glyphNode != nullptr)
45 m_glyphNode->setColor(color);
46}
47
48void QSGCurveGlyphNode::setStyleColor(const QColor &styleColor)
49{
50 m_styleColor = styleColor;
51 if (m_styleNode != nullptr)
52 m_styleNode->setColor(styleColor);
53}
54
55void QSGCurveGlyphNode::setStyle(QQuickText::TextStyle style)
56{
57 if (m_style != style) {
58 m_style = style;
59 m_dirtyGeometry = true;
60 update();
61 }
62}
63
64void QSGCurveGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs)
65{
66 m_glyphs = glyphs;
67
68 QRawFont font = glyphs.rawFont();
69 m_fontSize = font.pixelSize();
70 m_position = QPointF(position.x(), position.y() - font.ascent());
71
72
73 m_dirtyGeometry = true;
74
75#ifdef QSG_RUNTIME_DESCRIPTION
76 qsgnode_set_description(this, QString::number(glyphs.glyphIndexes().count())
77 + QStringLiteral(" curve glyphs: ")
78 + m_glyphs.rawFont().familyName()
79 + QStringLiteral(" ")
80 + QString::number(m_glyphs.rawFont().pixelSize()));
81#endif
82}
83
84void QSGCurveGlyphNode::update()
85{
86 markDirty(DirtyGeometry);
87}
88
89void QSGCurveGlyphNode::preprocess()
90{
91 if (m_dirtyGeometry)
92 updateGeometry();
93}
94
95void QSGCurveGlyphNode::updateGeometry()
96{
97 delete m_glyphNode;
98 m_glyphNode = nullptr;
99
100 delete m_styleNode;
101 m_styleNode = nullptr;
102
103 QSGCurveGlyphAtlas *curveGlyphAtlas = m_context->curveGlyphAtlas(m_glyphs.rawFont());
104 curveGlyphAtlas->populate(m_glyphs.glyphIndexes());
105
106 m_glyphNode = new QSGCurveFillNode;
107 m_glyphNode->setColor(m_color);
108
109 QPointF offset;
110
111 float fontScale = float(m_fontSize / curveGlyphAtlas->fontSize());
112 QSGCurveFillNode *raisedSunkenStyleNode = nullptr;
113 QSGCurveStrokeNode *outlineNode = nullptr;
114 if (m_style == QQuickText::Raised || m_style == QQuickText::Sunken) {
115 raisedSunkenStyleNode = new QSGCurveFillNode;
116 raisedSunkenStyleNode ->setColor(m_styleColor);
117
118 offset = m_style == QQuickText::Raised ? QPointF(0.0f, 1.0f) : QPointF(0.0f, -1.0f);
119 m_styleNode = raisedSunkenStyleNode;
120 } else if (m_style == QQuickText::Outline) {
121 outlineNode = new QSGCurveStrokeNode;
122 outlineNode->setColor(m_styleColor);
123 outlineNode->setStrokeWidth(2 / fontScale);
124 outlineNode->setLocalScale(fontScale);
125
126 m_styleNode = outlineNode;
127 }
128
129 const QList<quint32> indexes = m_glyphs.glyphIndexes();
130 const QList<QPointF> positions = m_glyphs.positions();
131 for (qsizetype i = 0; i < indexes.size(); ++i) {
132 if (i == 0)
133 m_baseLine = positions.at(i);
134 curveGlyphAtlas->addGlyph(m_glyphNode,
135 indexes.at(i),
136 m_position + positions.at(i),
137 m_fontSize);
138 if (raisedSunkenStyleNode != nullptr) {
139 curveGlyphAtlas->addGlyph(raisedSunkenStyleNode,
140 indexes.at(i),
141 m_position + positions.at(i) + offset,
142 m_fontSize);
143 }
144 if (outlineNode != nullptr) {
145 // Since the stroke node will scale everything by fontScale internally (the
146 // shader does not support pre-transforming the vertices), we have to also first
147 // do the inverse scale on the glyph position to get the correct position.
148 curveGlyphAtlas->addStroke(outlineNode,
149 indexes.at(i),
150 (m_position + positions.at(i)) / fontScale);
151 }
152 }
153
154 if (m_styleNode != nullptr) {
155 m_styleNode->cookGeometry();
156 appendChildNode(m_styleNode);
157 }
158
159 m_glyphNode->cookGeometry();
160 appendChildNode(m_glyphNode);
161
162 m_dirtyGeometry = false;
163}
164
165QT_END_NAMESPACE