2
2
3
3
#include < scratchcpp/iengine.h>
4
4
#include < scratchcpp/costume.h>
5
+ #include < QtSvg/QSvgRenderer>
6
+ #include < qnanopainter.h>
5
7
6
8
#include " renderedtarget.h"
7
9
#include " targetpainter.h"
@@ -16,12 +18,6 @@ RenderedTarget::RenderedTarget(QNanoQuickItem *parent) :
16
18
{
17
19
}
18
20
19
- RenderedTarget::~RenderedTarget ()
20
- {
21
- if (m_svgBitmap)
22
- free (m_svgBitmap);
23
- }
24
-
25
21
void RenderedTarget::loadProperties ()
26
22
{
27
23
Q_ASSERT (!(m_spriteModel && m_stageModel));
@@ -59,21 +55,21 @@ void RenderedTarget::loadProperties()
59
55
60
56
// Coordinates
61
57
double size = sprite->size () / 100 ;
62
- m_x = static_cast <double >(m_engine->stageWidth ()) / 2 + sprite->x () - m_costume->rotationCenterX () * size / 2 * (m_newMirrorHorizontally ? -1 : 1 );
63
- m_y = static_cast <double >(m_engine->stageHeight ()) / 2 - sprite->y () - m_costume->rotationCenterY () * size / 2 ;
64
- m_originX = m_costume->rotationCenterX () * size / 2.0 ;
65
- m_originY = m_costume->rotationCenterY () * size / 2.0 ;
58
+ m_x = static_cast <double >(m_engine->stageWidth ()) / 2 + sprite->x () - m_costume->rotationCenterX () * size / m_costume-> bitmapResolution () * (m_newMirrorHorizontally ? -1 : 1 );
59
+ m_y = static_cast <double >(m_engine->stageHeight ()) / 2 - sprite->y () - m_costume->rotationCenterY () * size / m_costume-> bitmapResolution () ;
60
+ m_originX = m_costume->rotationCenterX () * size / m_costume-> bitmapResolution () ;
61
+ m_originY = m_costume->rotationCenterY () * size / m_costume-> bitmapResolution () ;
66
62
67
63
// Layer
68
64
m_z = sprite->layerOrder ();
69
65
}
70
66
71
67
mutex.unlock ();
72
68
} else if (m_stageModel) {
73
- m_x = static_cast <double >(m_engine->stageWidth ()) / 2 - m_costume->rotationCenterX () / 2.0 ;
74
- m_y = static_cast <double >(m_engine->stageHeight ()) / 2 - m_costume->rotationCenterY () / 2.0 ;
75
- m_originX = m_costume->rotationCenterX () / 2.0 ;
76
- m_originY = m_costume->rotationCenterY () / 2.0 ;
69
+ m_x = static_cast <double >(m_engine->stageWidth ()) / 2 - m_costume->rotationCenterX () / m_costume-> bitmapResolution () ;
70
+ m_y = static_cast <double >(m_engine->stageHeight ()) / 2 - m_costume->rotationCenterY () / m_costume-> bitmapResolution () ;
71
+ m_originX = m_costume->rotationCenterX () / m_costume-> bitmapResolution () ;
72
+ m_originY = m_costume->rotationCenterY () / m_costume-> bitmapResolution () ;
77
73
}
78
74
}
79
75
@@ -83,30 +79,14 @@ void RenderedTarget::loadCostume(Costume *costume)
83
79
return ;
84
80
85
81
m_costumeMutex.lock ();
86
- Target *target = scratchTarget ();
87
- m_costume = costume;
88
82
m_imageChanged = true ;
89
83
90
84
if (costume->dataFormat () == " svg" ) {
91
- // TODO: Load SVG here
92
- // In case of rasterizing, write the bitmap to m_svgBitmap
93
- } else {
94
- if (m_svgBitmap) {
95
- free (m_svgBitmap);
96
- m_svgBitmap = nullptr ;
97
- }
98
-
99
- m_bitmapBuffer.open (QBuffer::WriteOnly);
100
- m_bitmapBuffer.write (static_cast <const char *>(costume->data ()), costume->dataSize ());
101
- m_bitmapBuffer.close ();
102
- m_bitmapUniqueKey = QString::fromStdString (costume->id ());
103
-
104
- QImageReader reader (&m_bitmapBuffer);
105
- QSize size = reader.size ();
106
- calculateSize (target, size.width (), size.height ());
107
- m_bitmapBuffer.close ();
85
+ if (costume != m_costume)
86
+ m_svgRenderer.load (QByteArray::fromRawData (static_cast <const char *>(costume->data ()), costume->dataSize ()));
108
87
}
109
88
89
+ m_costume = costume;
110
90
m_costumeMutex.unlock ();
111
91
}
112
92
@@ -116,8 +96,12 @@ void RenderedTarget::updateProperties()
116
96
setVisible (m_visible);
117
97
118
98
if (m_visible) {
119
- setWidth (m_width);
120
- setHeight (m_height);
99
+ if (m_imageChanged) {
100
+ doLoadCostume ();
101
+ update ();
102
+ m_imageChanged = false ;
103
+ }
104
+
121
105
setX (m_x);
122
106
setY (m_y);
123
107
setZ (m_z);
@@ -128,11 +112,6 @@ void RenderedTarget::updateProperties()
128
112
m_mirrorHorizontally = m_newMirrorHorizontally;
129
113
emit mirrorHorizontallyChanged ();
130
114
}
131
-
132
- if (m_imageChanged) {
133
- update ();
134
- m_imageChanged = false ;
135
- }
136
115
}
137
116
138
117
mutex.unlock ();
@@ -210,38 +189,73 @@ void RenderedTarget::setHeight(qreal height)
210
189
QNanoQuickItem::setHeight (height);
211
190
}
212
191
213
- double RenderedTarget::costumeWidth () const
192
+ QNanoQuickItemPainter * RenderedTarget::createItemPainter () const
214
193
{
215
- return m_width ;
194
+ return new TargetPainter () ;
216
195
}
217
196
218
- void RenderedTarget::setCostumeWidth ( double width )
197
+ void RenderedTarget::doLoadCostume ( )
219
198
{
220
- mutex.lock ();
221
- m_width = width;
222
- mutex.unlock ();
223
- }
199
+ m_costumeMutex.lock ();
224
200
225
- double RenderedTarget::costumeHeight () const
226
- {
227
- return m_height ;
228
- }
201
+ if (!m_costume) {
202
+ m_costumeMutex. unlock ();
203
+ return ;
204
+ }
229
205
230
- void RenderedTarget::setCostumeHeight (double height)
231
- {
232
- mutex.lock ();
233
- m_height = height;
234
- mutex.unlock ();
235
- }
206
+ Target *target = scratchTarget ();
236
207
237
- unsigned char *RenderedTarget::svgBitmap () const
238
- {
239
- return m_svgBitmap;
208
+ if (m_costume->dataFormat () == " svg" ) {
209
+ QRectF rect = m_svgRenderer.viewBoxF ();
210
+ calculateSize (target, rect.width (), rect.height ());
211
+ } else {
212
+ m_bitmapBuffer.open (QBuffer::WriteOnly);
213
+ m_bitmapBuffer.write (static_cast <const char *>(m_costume->data ()), m_costume->dataSize ());
214
+ m_bitmapBuffer.close ();
215
+ m_bitmapUniqueKey = QString::fromStdString (m_costume->id ());
216
+
217
+ QImageReader reader (&m_bitmapBuffer);
218
+ QSize size = reader.size ();
219
+ calculateSize (target, size.width (), size.height ());
220
+ m_bitmapBuffer.close ();
221
+ }
222
+
223
+ m_costumeMutex.unlock ();
240
224
}
241
225
242
- QNanoQuickItemPainter * RenderedTarget::createItemPainter () const
226
+ void RenderedTarget::paintSvg (QNanoPainter *painter)
243
227
{
244
- return new TargetPainter ();
228
+ Q_ASSERT (painter);
229
+ QOpenGLContext *context = QOpenGLContext::currentContext ();
230
+ Q_ASSERT (context);
231
+
232
+ if (!context)
233
+ return ;
234
+
235
+ QOffscreenSurface surface;
236
+ surface.setFormat (context->format ());
237
+ surface.create ();
238
+ Q_ASSERT (surface.isValid ());
239
+
240
+ QSurface *oldSurface = context->surface ();
241
+ context->makeCurrent (&surface);
242
+
243
+ const QRectF drawRect (0 , 0 , width (), height ());
244
+ const QSize drawRectSize = drawRect.size ().toSize ();
245
+
246
+ /* QOpenGLFramebufferObjectFormat fboFormat;
247
+ fboFormat.setSamples(16);
248
+ fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);*/
249
+
250
+ QOpenGLPaintDevice device (drawRectSize);
251
+ QPainter qPainter;
252
+ qPainter.begin (&device);
253
+ qPainter.setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
254
+ m_svgRenderer.render (&qPainter, drawRect);
255
+ qPainter.end ();
256
+
257
+ context->doneCurrent ();
258
+ context->makeCurrent (oldSurface);
245
259
}
246
260
247
261
void RenderedTarget::calculateSize (Target *target, double costumeWidth, double costumeHeight)
@@ -252,11 +266,11 @@ void RenderedTarget::calculateSize(Target *target, double costumeWidth, double c
252
266
253
267
if (sprite) {
254
268
double size = sprite->size ();
255
- m_width = costumeWidth * size / 100 / bitmapRes;
256
- m_height = costumeHeight * size / 100 / bitmapRes;
269
+ setWidth ( costumeWidth * size / 100 / bitmapRes) ;
270
+ setHeight ( costumeHeight * size / 100 / bitmapRes) ;
257
271
} else {
258
- m_width = costumeWidth / bitmapRes;
259
- m_height = costumeHeight / bitmapRes;
272
+ setWidth ( costumeWidth / bitmapRes) ;
273
+ setHeight ( costumeHeight / bitmapRes) ;
260
274
}
261
275
}
262
276
}
@@ -285,3 +299,11 @@ bool RenderedTarget::mirrorHorizontally() const
285
299
{
286
300
return m_mirrorHorizontally;
287
301
}
302
+
303
+ bool RenderedTarget::isSvg () const
304
+ {
305
+ if (!m_costume)
306
+ return false ;
307
+
308
+ return (m_costume->dataFormat () == " svg" );
309
+ }
0 commit comments