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
qsgcurveglyphatlas.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
8#include "util/qquadpath_p.h"
9
10#include <QtGui/qrawfont.h>
11#include <QtGui/qpainterpath.h>
12
14
16 : m_font(font)
17{
18 // The font size used for the curve atlas currently affects the outlines, since we don't
19 // really support cosmetic outlines. Therefore we need to pick one which gives large enough
20 // triangles relative to glyph size that we can reuse the same triangles for any font size.
21 // When experimenting, 10 works for all font sizes we tested, so we currently default to this
22 // but allow overriding it.
23 static int curveGlyphAtlasFontSize = qEnvironmentVariableIntValue("QSGCURVEGLYPHATLAS_FONT_SIZE");
24 m_font.setPixelSize(curveGlyphAtlasFontSize > 0 ? qreal(curveGlyphAtlasFontSize) : 10.0);
25}
26
30
31void QSGCurveGlyphAtlas::populate(const QList<glyph_t> &glyphs)
32{
33 for (glyph_t glyphIndex : glyphs) {
34 if (!m_glyphs.contains(glyphIndex)) {
35 QPainterPath path = m_font.pathForGlyph(glyphIndex);
37 quadPath.setFillRule(Qt::WindingFill);
38
39 Glyph glyph;
40
42 [&glyph](const std::array<QVector2D, 3> &s,
43 const std::array<QVector2D, 3> &p,
44 const std::array<QVector2D, 3> &n,
45 bool isLine) {
46 glyph.strokeVertices.append(s.at(0));
47 glyph.strokeVertices.append(s.at(1));
48 glyph.strokeVertices.append(s.at(2));
49
50 glyph.strokeUvs.append(p.at(0));
51 glyph.strokeUvs.append(p.at(1));
52 glyph.strokeUvs.append(p.at(2));
53
54 glyph.strokeNormals.append(n.at(0));
55 glyph.strokeNormals.append(n.at(1));
56 glyph.strokeNormals.append(n.at(2));
57
58 glyph.strokeElementIsLine.append(isLine);
59 });
60
61 quadPath = quadPath.subPathsClosed();
62 quadPath.addCurvatureData(); // ### Since the inside of glyphs is defined by order of
63 // vertices, this step could be simplified
65
68 [&glyph](const std::array<QVector2D, 3> &v,
69 const std::array<QVector2D, 3> &n,
71 {
72 glyph.vertices.append(v.at(0));
73 glyph.vertices.append(v.at(1));
74 glyph.vertices.append(v.at(2));
75
76 QVector3D uv1 = uvForPoint(v.at(0));
77 glyph.uvs.append(uv1);
78 glyph.uvs.append(uvForPoint(v.at(1)));
79 glyph.uvs.append(uvForPoint(v.at(2)));
80
81 glyph.normals.append(n.at(0));
82 glyph.normals.append(n.at(1));
83 glyph.normals.append(n.at(2));
84
85 glyph.duvdx.append(QVector2D(uvForPoint(v.at(0) + QVector2D(1, 0))) - QVector2D(uv1));
86 glyph.duvdy.append(QVector2D(uvForPoint(v.at(0) + QVector2D(0, 1))) - QVector2D(uv1));
87 });
88
89 m_glyphs.insert(glyphIndex, glyph);
90 }
91 }
92}
93
95 glyph_t glyphIndex,
96 const QPointF &position) const
97{
98 const Glyph &glyph = m_glyphs[glyphIndex];
99
100 const QVector2D v(position);
101 for (qsizetype i = glyph.strokeElementIsLine.size() - 1; i >= 0; --i) {
102 QVector2D v1 = glyph.strokeVertices.at(i * 3 + 0) + v;
103 QVector2D v2 = glyph.strokeVertices.at(i * 3 + 1) + v;
104 QVector2D v3 = glyph.strokeVertices.at(i * 3 + 2) + v;
105 if (glyph.strokeElementIsLine.at(i)) {
106 node->appendTriangle({ v1, v2, v3 },
107 std::array<QVector2D, 2>({ glyph.strokeUvs.at(i * 3 + 0) + v, glyph.strokeUvs.at(i * 3 + 2) + v }),
108 { glyph.strokeNormals.at(i * 3 + 0), glyph.strokeNormals.at(i * 3 + 1), glyph.strokeNormals.at(i * 3 + 2) });
109 } else {
110 node->appendTriangle({ v1, v2, v3 },
111 { glyph.strokeUvs.at(i * 3 + 0) + v, glyph.strokeUvs.at(i * 3 + 1) + v, glyph.strokeUvs.at(i * 3 + 2) + v },
112 { glyph.strokeNormals.at(i * 3 + 0), glyph.strokeNormals.at(i * 3 + 1), glyph.strokeNormals.at(i * 3 + 2) });
113
114 }
115 }
116}
117
119 glyph_t glyphIndex,
120 const QPointF &position,
121 qreal pixelSize) const
122{
123 const Glyph &glyph = m_glyphs[glyphIndex];
124
125 const float scaleFactor = pixelSize / m_font.pixelSize();
126 const QVector2D v(position);
127 for (qsizetype i = 0; i < glyph.vertices.size() / 3; ++i) {
128 node->appendTriangle(scaleFactor * glyph.vertices.at(i * 3 + 0) + v,
129 scaleFactor * glyph.vertices.at(i * 3 + 1) + v,
130 scaleFactor * glyph.vertices.at(i * 3 + 2) + v,
131 glyph.uvs.at(i * 3 + 0),
132 glyph.uvs.at(i * 3 + 1),
133 glyph.uvs.at(i * 3 + 2),
134 glyph.normals.at(i * 3 + 0),
135 glyph.normals.at(i * 3 + 1),
136 glyph.normals.at(i * 3 + 2),
137 glyph.duvdx.at(i) / scaleFactor,
138 glyph.duvdy.at(i) / scaleFactor);
139 }
140}
141
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
Definition qhash.h:1007
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
qsizetype size() const noexcept
Definition qlist.h:397
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void append(parameter_type t)
Definition qlist.h:458
\inmodule QtGui
\inmodule QtCore\reentrant
Definition qpoint.h:217
static QQuadPath fromPainterPath(const QPainterPath &path, PathHints hints={})
The QRawFont class provides access to a single physical instance of a font.
Definition qrawfont.h:24
qreal pixelSize() const
Returns the pixel size set for this QRawFont.
Definition qrawfont.cpp:402
void setPixelSize(qreal pixelSize)
Sets the pixel size with which this font should be rendered to pixelSize.
Definition qrawfont.cpp:774
QPainterPath pathForGlyph(quint32 glyphIndex) const
This function returns the shape of the glyph at a given glyphIndex in the underlying font if the QRaw...
Definition qrawfont.cpp:264
void appendTriangle(const std::array< QVector2D, 3 > &v, const std::array< QVector2D, 3 > &n, std::function< QVector3D(QVector2D)> uvForPoint)
QSGCurveGlyphAtlas(const QRawFont &font)
void addStroke(QSGCurveStrokeNode *node, glyph_t glyph, const QPointF &position) const
void addGlyph(QSGCurveFillNode *node, glyph_t glyph, const QPointF &position, qreal pixelSize) const
void populate(const QList< glyph_t > &glyphs)
static void processStroke(const QQuadPath &strokePath, float miterLimit, float penWidth, Qt::PenJoinStyle joinStyle, Qt::PenCapStyle capStyle, addStrokeTriangleCallback addTriangle, int subdivisions=3)
std::function< QVector3D(QVector2D)> uvForPointCallback
static bool solveOverlaps(QQuadPath &path)
static void processFill(const QQuadPath &path, Qt::FillRule fillRule, addTriangleCallback addTriangle)
void appendTriangle(const std::array< QVector2D, 3 > &v, const std::array< QVector2D, 3 > &p, const std::array< QVector2D, 3 > &n)
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
Combined button and popup list for selecting options.
@ MiterJoin
@ WindingFill
@ FlatCap
GLint GLfloat GLfloat GLfloat v2
GLsizei const GLfloat * v
[13]
GLint GLfloat GLfloat v1
GLint GLfloat GLfloat GLfloat GLfloat v3
GLfloat n
GLdouble s
[6]
Definition qopenglext.h:235
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
static bool isLine(const QBezier &bezier)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define v1
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
unsigned int glyph_t
ptrdiff_t qsizetype
Definition qtypes.h:165
double qreal
Definition qtypes.h:187