22
33#include < scratchcpp/iengine.h>
44#include < scratchcpp/costume.h>
5+ #include < QtSvg/QSvgRenderer>
6+ #include < qnanopainter.h>
57
68#include " renderedtarget.h"
79#include " targetpainter.h"
@@ -16,12 +18,6 @@ RenderedTarget::RenderedTarget(QNanoQuickItem *parent) :
1618{
1719}
1820
19- RenderedTarget::~RenderedTarget ()
20- {
21- if (m_svgBitmap)
22- free (m_svgBitmap);
23- }
24-
2521void RenderedTarget::loadProperties ()
2622{
2723 Q_ASSERT (!(m_spriteModel && m_stageModel));
@@ -59,21 +55,21 @@ void RenderedTarget::loadProperties()
5955
6056 // Coordinates
6157 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 () ;
6662
6763 // Layer
6864 m_z = sprite->layerOrder ();
6965 }
7066
7167 mutex.unlock ();
7268 } 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 () ;
7773 }
7874}
7975
@@ -83,30 +79,14 @@ void RenderedTarget::loadCostume(Costume *costume)
8379 return ;
8480
8581 m_costumeMutex.lock ();
86- Target *target = scratchTarget ();
87- m_costume = costume;
8882 m_imageChanged = true ;
8983
9084 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 ()));
10887 }
10988
89+ m_costume = costume;
11090 m_costumeMutex.unlock ();
11191}
11292
@@ -116,8 +96,12 @@ void RenderedTarget::updateProperties()
11696 setVisible (m_visible);
11797
11898 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+
121105 setX (m_x);
122106 setY (m_y);
123107 setZ (m_z);
@@ -128,11 +112,6 @@ void RenderedTarget::updateProperties()
128112 m_mirrorHorizontally = m_newMirrorHorizontally;
129113 emit mirrorHorizontallyChanged ();
130114 }
131-
132- if (m_imageChanged) {
133- update ();
134- m_imageChanged = false ;
135- }
136115 }
137116
138117 mutex.unlock ();
@@ -210,38 +189,73 @@ void RenderedTarget::setHeight(qreal height)
210189 QNanoQuickItem::setHeight (height);
211190}
212191
213- double RenderedTarget::costumeWidth () const
192+ QNanoQuickItemPainter * RenderedTarget::createItemPainter () const
214193{
215- return m_width ;
194+ return new TargetPainter () ;
216195}
217196
218- void RenderedTarget::setCostumeWidth ( double width )
197+ void RenderedTarget::doLoadCostume ( )
219198{
220- mutex.lock ();
221- m_width = width;
222- mutex.unlock ();
223- }
199+ m_costumeMutex.lock ();
224200
225- double RenderedTarget::costumeHeight () const
226- {
227- return m_height ;
228- }
201+ if (!m_costume) {
202+ m_costumeMutex. unlock ();
203+ return ;
204+ }
229205
230- void RenderedTarget::setCostumeHeight (double height)
231- {
232- mutex.lock ();
233- m_height = height;
234- mutex.unlock ();
235- }
206+ Target *target = scratchTarget ();
236207
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 ();
240224}
241225
242- QNanoQuickItemPainter * RenderedTarget::createItemPainter () const
226+ void RenderedTarget::paintSvg (QNanoPainter *painter)
243227{
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);
245259}
246260
247261void RenderedTarget::calculateSize (Target *target, double costumeWidth, double costumeHeight)
@@ -252,11 +266,11 @@ void RenderedTarget::calculateSize(Target *target, double costumeWidth, double c
252266
253267 if (sprite) {
254268 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) ;
257271 } else {
258- m_width = costumeWidth / bitmapRes;
259- m_height = costumeHeight / bitmapRes;
272+ setWidth ( costumeWidth / bitmapRes) ;
273+ setHeight ( costumeHeight / bitmapRes) ;
260274 }
261275 }
262276}
@@ -285,3 +299,11 @@ bool RenderedTarget::mirrorHorizontally() const
285299{
286300 return m_mirrorHorizontally;
287301}
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