blob: f143ee8e7c27edac20652e9cf751c18bb41593ed (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#include "glyph.h"
#include <cmath>
#include <QSGGeometry>
#include <QSGGeometryNode>
#include <QSGMaterial>
#include <QSGFlatColorMaterial>
const float PI = 3.1415f;
Glyph::Glyph(QQuickItem *parent)
: QQuickItem(parent)
, m_size(0)
{
setFlag(QQuickItem::ItemHasContents);
}
void Glyph::setSize(qreal size)
{
if (size == m_size)
return;
m_size = size;
setWidth(size);
setHeight(size);
emit sizeChanged();
update();
}
void Glyph::setColor(const QColor &color)
{
if (color == m_color)
return;
m_color = color;
emit colorChanged();
update();
}
int calculateCircleVertexCount(qreal radius)
{
// 10 * sqrt(r) \approx 2*pi / acos(1 - 1 / (4*r))
return (int) (10.0 * sqrt(radius));
}
void updateCircleGeometry(QSGGeometry *geometry, const QRectF &bounds)
{
int vertexCount = geometry->vertexCount();
float cy = bounds.center().x();
float cx = bounds.center().y();
float theta = 2 * PI / float(vertexCount);
float c = cosf(theta);
float s = sinf(theta);
float x = bounds.width() / 2;
float y = 0;
QSGGeometry::Point2D *vertexData = geometry->vertexDataAsPoint2D();
for (int i = 0; i < vertexCount; i++) {
vertexData[i].set(x + cx, y + cy);
float t = x;
x = c*x - s*y;
y = s*t + c*y;
}
}
QSGNode *Glyph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGGeometryNode *node = 0;
QSGGeometry *geometry = 0;
QSGFlatColorMaterial *material = 0;
int vertexCount = calculateCircleVertexCount(m_size / 2);
if (!oldNode) {
node = new QSGGeometryNode;
geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertexCount);
geometry->setDrawingMode(GL_POLYGON);
node->setGeometry(geometry);
node->setFlag(QSGNode::OwnsGeometry);
material = new QSGFlatColorMaterial;
material->setColor(m_color);
node->setMaterial(material);
node->setFlag(QSGNode::OwnsMaterial);
} else {
node = static_cast<QSGGeometryNode *>(oldNode);
geometry = node->geometry();
geometry->allocate(vertexCount);
}
updateCircleGeometry(geometry, boundingRect());
node->markDirty(QSGNode::DirtyGeometry);
material = static_cast<QSGFlatColorMaterial *>(node->material());
if (material->color() != m_color) {
material->setColor(m_color);
node->markDirty(QSGNode::DirtyMaterial);
}
return node;
}
|