@@ -58,11 +58,7 @@ void PenLayer::setEngine(libscratchcpp::IEngine *newEngine)
58
58
59
59
if (m_engine && QOpenGLContext::currentContext ()) {
60
60
m_projectPenLayers[m_engine] = this ;
61
- QOpenGLFramebufferObjectFormat fboFormat;
62
- fboFormat.setAttachment (QOpenGLFramebufferObject::CombinedDepthStencil);
63
- m_fbo = std::make_unique<QOpenGLFramebufferObject>(m_engine->stageWidth (), m_engine->stageHeight (), fboFormat);
64
- Q_ASSERT (m_fbo->isValid ());
65
- m_texture = Texture (m_fbo->texture (), m_fbo->size ());
61
+ createFbo ();
66
62
67
63
if (!m_painter)
68
64
m_painter = std::make_unique<QNanoPainter>();
@@ -106,6 +102,21 @@ void PenLayer::setEngine(libscratchcpp::IEngine *newEngine)
106
102
emit engineChanged ();
107
103
}
108
104
105
+ bool PenLayer::hqPen () const
106
+ {
107
+ return m_hqPen;
108
+ }
109
+
110
+ void PenLayer::setHqPen (bool newHqPen)
111
+ {
112
+ if (m_hqPen == newHqPen)
113
+ return ;
114
+
115
+ m_hqPen = newHqPen;
116
+ createFbo ();
117
+ emit hqPenChanged ();
118
+ }
119
+
109
120
void scratchcpprender::PenLayer::clear ()
110
121
{
111
122
if (!m_fbo)
@@ -138,16 +149,23 @@ void scratchcpprender::PenLayer::drawLine(const PenAttributes &penAttributes, do
138
149
139
150
m_painter->beginFrame (m_fbo->width (), m_fbo->height ());
140
151
152
+ // Apply scale (HQ pen)
153
+ x0 *= m_scale;
154
+ y0 *= m_scale;
155
+ x1 *= m_scale;
156
+ y1 *= m_scale;
157
+
141
158
// Translate to Scratch coordinate system
142
- double stageWidthHalf = m_engine-> stageWidth () / 2 ;
143
- double stageHeightHalf = m_engine-> stageHeight () / 2 ;
159
+ double stageWidthHalf = width () / 2 ;
160
+ double stageHeightHalf = height () / 2 ;
144
161
x0 += stageWidthHalf;
145
162
y0 = stageHeightHalf - y0 ;
146
163
x1 += stageWidthHalf;
147
164
y1 = stageHeightHalf - y1 ;
148
165
149
166
// Set pen attributes
150
- m_painter->setLineWidth (penAttributes.diameter );
167
+ const double diameter = penAttributes.diameter * m_scale;
168
+ m_painter->setLineWidth (diameter);
151
169
m_painter->setStrokeStyle (penAttributes.color );
152
170
m_painter->setFillStyle (penAttributes.color );
153
171
m_painter->setLineJoin (QNanoPainter::JOIN_ROUND);
@@ -156,11 +174,11 @@ void scratchcpprender::PenLayer::drawLine(const PenAttributes &penAttributes, do
156
174
m_painter->beginPath ();
157
175
158
176
// Width 1 and 3 lines need to be offset by 0.5
159
- const double offset = (std::fmod (std::max (4 - penAttributes. diameter , 0.0 ), 2 )) / 2 ;
177
+ const double offset = (std::fmod (std::max (4 - diameter, 0.0 ), 2 )) / 2 ;
160
178
161
179
// If the start and end coordinates are the same, draw a point, otherwise draw a line
162
180
if (x0 == x1 && y0 == y1 ) {
163
- m_painter->circle (x0 + offset, y0 + offset, penAttributes. diameter / 2 );
181
+ m_painter->circle (x0 + offset, y0 + offset, diameter / 2 );
164
182
m_painter->fill ();
165
183
} else {
166
184
m_painter->moveTo (x0 + offset, y0 + offset);
@@ -223,6 +241,9 @@ void PenLayer::stamp(IRenderedTarget *target)
223
241
} else
224
242
costume = target->stageModel ()->stage ()->currentCostume ();
225
243
244
+ // Apply scale (HQ pen)
245
+ scale *= m_scale;
246
+
226
247
const double bitmapRes = costume->bitmapResolution ();
227
248
const double centerX = costume->rotationCenterX () / bitmapRes;
228
249
const double centerY = costume->rotationCenterY () / bitmapRes;
@@ -234,8 +255,11 @@ void PenLayer::stamp(IRenderedTarget *target)
234
255
235
256
const double textureScale = texture.width () / static_cast <double >(target->costumeWidth ());
236
257
258
+ // Apply scale (HQ pen)
259
+ x *= m_scale;
260
+ y *= m_scale;
261
+
237
262
// Translate the coordinates
238
- // TODO: Apply scale (HQ pen)
239
263
x = std::floor (x + m_texture.width () / 2.0 );
240
264
y = std::floor (-y + m_texture.height () / 2.0 );
241
265
@@ -352,8 +376,11 @@ QRgb PenLayer::colorAtScratchPoint(double x, double y) const
352
376
const double width = m_texture.width ();
353
377
const double height = m_texture.height ();
354
378
379
+ // Apply scale (HQ pen)
380
+ x *= m_scale;
381
+ y *= m_scale;
382
+
355
383
// Translate the coordinates
356
- // TODO: Apply scale
357
384
x = std::floor (x + width / 2.0 );
358
385
y = std::floor (-y + height / 2.0 );
359
386
@@ -393,7 +420,6 @@ const libscratchcpp::Rect &PenLayer::getBounds() const
393
420
}
394
421
395
422
for (const QPointF &point : points) {
396
- // TODO: Apply scale
397
423
double x = point.x () - width / 2 ;
398
424
double y = -point.y () + height / 2 ;
399
425
@@ -410,10 +436,10 @@ const libscratchcpp::Rect &PenLayer::getBounds() const
410
436
bottom = y;
411
437
}
412
438
413
- m_bounds.setLeft (left);
414
- m_bounds.setTop (top);
415
- m_bounds.setRight (right + 1 );
416
- m_bounds.setBottom (bottom - 1 );
439
+ m_bounds.setLeft (left / m_scale );
440
+ m_bounds.setTop (top / m_scale );
441
+ m_bounds.setRight (right / m_scale + 1 );
442
+ m_bounds.setBottom (bottom / m_scale - 1 );
417
443
}
418
444
419
445
return m_bounds;
@@ -439,6 +465,33 @@ QNanoQuickItemPainter *PenLayer::createItemPainter() const
439
465
return new PenLayerPainter;
440
466
}
441
467
468
+ void PenLayer::geometryChange (const QRectF &newGeometry, const QRectF &oldGeometry)
469
+ {
470
+ if (m_hqPen && newGeometry != oldGeometry)
471
+ createFbo ();
472
+
473
+ QNanoQuickItem::geometryChange (newGeometry, oldGeometry);
474
+ }
475
+
476
+ void PenLayer::createFbo ()
477
+ {
478
+ if (!QOpenGLContext::currentContext () || !m_engine)
479
+ return ;
480
+
481
+ QOpenGLFramebufferObjectFormat fboFormat;
482
+ fboFormat.setAttachment (QOpenGLFramebufferObject::CombinedDepthStencil);
483
+
484
+ QOpenGLFramebufferObject *newFbo = new QOpenGLFramebufferObject (width (), height (), fboFormat);
485
+ Q_ASSERT (newFbo->isValid ());
486
+
487
+ if (m_fbo)
488
+ QOpenGLFramebufferObject::blitFramebuffer (newFbo, m_fbo.get ());
489
+
490
+ m_fbo.reset (newFbo);
491
+ m_texture = Texture (m_fbo->texture (), m_fbo->size ());
492
+ m_scale = width () / m_engine->stageWidth ();
493
+ }
494
+
442
495
void PenLayer::updateTexture ()
443
496
{
444
497
if (!m_fbo)
0 commit comments