13
13
using namespace scratchcppgui ;
14
14
using namespace libscratchcpp ;
15
15
16
+ static const double SVG_SCALE_LIMIT = 0.1 ; // the maximum viewport dimensions are multiplied by this
17
+
16
18
RenderedTarget::RenderedTarget (QNanoQuickItem *parent) :
17
19
IRenderedTarget(parent)
18
20
{
21
+ // Get maximum viewport dimensions
22
+ QOpenGLContext context;
23
+ context.create ();
24
+ Q_ASSERT (context.isValid ());
25
+
26
+ if (context.isValid ()) {
27
+ QOffscreenSurface surface;
28
+ surface.create ();
29
+ Q_ASSERT (surface.isValid ());
30
+
31
+ if (surface.isValid ()) {
32
+ context.makeCurrent (&surface);
33
+ GLint dims[2 ];
34
+ glGetIntegerv (GL_MAX_VIEWPORT_DIMS, dims);
35
+ m_maximumWidth = dims[0 ] * SVG_SCALE_LIMIT;
36
+ m_maximumHeight = dims[1 ] * SVG_SCALE_LIMIT;
37
+ context.doneCurrent ();
38
+ }
39
+ }
19
40
}
20
41
21
42
void RenderedTarget::loadProperties ()
@@ -31,6 +52,9 @@ void RenderedTarget::loadProperties()
31
52
// Visibility
32
53
m_visible = sprite->visible ();
33
54
55
+ m_size = sprite->size () / 100 ;
56
+ updateCostumeData ();
57
+
34
58
if (m_visible) {
35
59
// Direction
36
60
switch (sprite->rotationStyle ()) {
@@ -54,18 +78,19 @@ void RenderedTarget::loadProperties()
54
78
}
55
79
56
80
// Coordinates
57
- double size = sprite-> size () / 100 ;
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 ();
81
+ double clampedSize = std::min (m_size, m_maxSize) ;
82
+ m_x = static_cast <double >(m_engine->stageWidth ()) / 2 + sprite->x () - m_costume->rotationCenterX () * clampedSize / m_costume->bitmapResolution () * (m_newMirrorHorizontally ? -1 : 1 );
83
+ m_y = static_cast <double >(m_engine->stageHeight ()) / 2 - sprite->y () - m_costume->rotationCenterY () * clampedSize / m_costume->bitmapResolution ();
84
+ m_originX = m_costume->rotationCenterX () * clampedSize / m_costume->bitmapResolution ();
85
+ m_originY = m_costume->rotationCenterY () * clampedSize / m_costume->bitmapResolution ();
62
86
63
87
// Layer
64
88
m_z = sprite->layerOrder ();
65
89
}
66
90
67
91
mutex.unlock ();
68
92
} else if (m_stageModel) {
93
+ updateCostumeData ();
69
94
m_x = static_cast <double >(m_engine->stageWidth ()) / 2 - m_costume->rotationCenterX () / m_costume->bitmapResolution ();
70
95
m_y = static_cast <double >(m_engine->stageHeight ()) / 2 - m_costume->rotationCenterY () / m_costume->bitmapResolution ();
71
96
m_originX = m_costume->rotationCenterX () / m_costume->bitmapResolution ();
@@ -79,13 +104,8 @@ void RenderedTarget::loadCostume(Costume *costume)
79
104
return ;
80
105
81
106
m_costumeMutex.lock ();
82
- m_imageChanged = true ;
83
-
84
- if (costume->dataFormat () == " svg" ) {
85
- if (costume != m_costume)
86
- m_svgRenderer.load (QByteArray::fromRawData (static_cast <const char *>(costume->data ()), costume->dataSize ()));
87
- }
88
-
107
+ m_loadCostume = true ;
108
+ m_costumeChanged = (costume != m_costume);
89
109
m_costume = costume;
90
110
m_costumeMutex.unlock ();
91
111
}
@@ -97,16 +117,23 @@ void RenderedTarget::updateProperties()
97
117
98
118
if (m_visible) {
99
119
if (m_imageChanged) {
100
- doLoadCostume ();
101
120
update ();
102
121
m_imageChanged = false ;
103
122
}
104
123
105
124
setX (m_x);
106
125
setY (m_y);
107
126
setZ (m_z);
127
+ setWidth (m_width);
128
+ setHeight (m_height);
108
129
setRotation (m_rotation);
109
130
setTransformOriginPoint (QPointF (m_originX, m_originY));
131
+ Q_ASSERT (m_maxSize > 0 );
132
+
133
+ if (!m_stageModel && (m_size > m_maxSize) && (m_maxSize != 0 ))
134
+ setScale (m_size / m_maxSize);
135
+ else
136
+ setScale (1 );
110
137
111
138
if (m_newMirrorHorizontally != m_mirrorHorizontally) {
112
139
m_mirrorHorizontally = m_newMirrorHorizontally;
@@ -194,6 +221,28 @@ QNanoQuickItemPainter *RenderedTarget::createItemPainter() const
194
221
return new TargetPainter ();
195
222
}
196
223
224
+ void RenderedTarget::updateCostumeData ()
225
+ {
226
+ // Costume
227
+ m_costumeMutex.lock ();
228
+
229
+ if (m_loadCostume) {
230
+ m_loadCostume = false ;
231
+ m_imageChanged = true ;
232
+
233
+ if (m_costumeChanged) {
234
+ m_costumeChanged = false ;
235
+ assert (m_costume);
236
+
237
+ if (m_costume->dataFormat () == " svg" )
238
+ m_svgRenderer.load (QByteArray::fromRawData (static_cast <const char *>(m_costume->data ()), m_costume->dataSize ()));
239
+ }
240
+ }
241
+
242
+ m_costumeMutex.unlock ();
243
+ doLoadCostume ();
244
+ }
245
+
197
246
void RenderedTarget::doLoadCostume ()
198
247
{
199
248
m_costumeMutex.lock ();
@@ -240,13 +289,9 @@ void RenderedTarget::paintSvg(QNanoPainter *painter)
240
289
QSurface *oldSurface = context->surface ();
241
290
context->makeCurrent (&surface);
242
291
243
- const QRectF drawRect (0 , 0 , width (), height ());
292
+ const QRectF drawRect (0 , 0 , std::min ( width (), m_maximumWidth), std::min ( height (), m_maximumHeight ));
244
293
const QSize drawRectSize = drawRect.size ().toSize ();
245
294
246
- /* QOpenGLFramebufferObjectFormat fboFormat;
247
- fboFormat.setSamples(16);
248
- fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);*/
249
-
250
295
QOpenGLPaintDevice device (drawRectSize);
251
296
QPainter qPainter;
252
297
qPainter.begin (&device);
@@ -262,15 +307,16 @@ void RenderedTarget::calculateSize(Target *target, double costumeWidth, double c
262
307
{
263
308
if (m_costume) {
264
309
double bitmapRes = m_costume->bitmapResolution ();
310
+ m_maxSize = std::min (m_maximumWidth / costumeWidth, m_maximumHeight / costumeHeight);
265
311
Sprite *sprite = dynamic_cast <Sprite *>(target);
266
312
267
313
if (sprite) {
268
- double size = sprite-> size ( );
269
- setWidth ( costumeWidth * size / 100 / bitmapRes) ;
270
- setHeight ( costumeHeight * size / 100 / bitmapRes) ;
314
+ double clampedSize = std::min (m_size, m_maxSize );
315
+ m_width = costumeWidth * clampedSize / bitmapRes;
316
+ m_height = costumeHeight * clampedSize / bitmapRes;
271
317
} else {
272
- setWidth ( costumeWidth / bitmapRes) ;
273
- setHeight ( costumeHeight / bitmapRes) ;
318
+ m_width = costumeWidth / bitmapRes;
319
+ m_height = costumeHeight / bitmapRes;
274
320
}
275
321
}
276
322
}
0 commit comments