From 55a905ada643891c12216e74e4e45e791f706f7d Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 22 Dec 2023 21:18:54 +0100 Subject: [PATCH 1/5] fix #50: Get size from the event loop thread --- ScratchCPPGui/renderedtarget.cpp | 55 +++++++++----- ScratchCPPGui/renderedtarget.h | 6 ++ test/renderedtarget/renderedtarget_test.cpp | 79 ++++++++++++++++++++- 3 files changed, 120 insertions(+), 20 deletions(-) diff --git a/ScratchCPPGui/renderedtarget.cpp b/ScratchCPPGui/renderedtarget.cpp index 308b807..37f176d 100644 --- a/ScratchCPPGui/renderedtarget.cpp +++ b/ScratchCPPGui/renderedtarget.cpp @@ -54,11 +54,12 @@ void RenderedTarget::loadProperties() } // Coordinates - double size = sprite->size() / 100; - m_x = static_cast(m_engine->stageWidth()) / 2 + sprite->x() - m_costume->rotationCenterX() * size / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1); - m_y = static_cast(m_engine->stageHeight()) / 2 - sprite->y() - m_costume->rotationCenterY() * size / m_costume->bitmapResolution(); - m_originX = m_costume->rotationCenterX() * size / m_costume->bitmapResolution(); - m_originY = m_costume->rotationCenterY() * size / m_costume->bitmapResolution(); + m_size = sprite->size() / 100; + updateCostumeData(); + m_x = static_cast(m_engine->stageWidth()) / 2 + sprite->x() - m_costume->rotationCenterX() * m_size / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1); + m_y = static_cast(m_engine->stageHeight()) / 2 - sprite->y() - m_costume->rotationCenterY() * m_size / m_costume->bitmapResolution(); + m_originX = m_costume->rotationCenterX() * m_size / m_costume->bitmapResolution(); + m_originY = m_costume->rotationCenterY() * m_size / m_costume->bitmapResolution(); // Layer m_z = sprite->layerOrder(); @@ -66,6 +67,7 @@ void RenderedTarget::loadProperties() mutex.unlock(); } else if (m_stageModel) { + updateCostumeData(); m_x = static_cast(m_engine->stageWidth()) / 2 - m_costume->rotationCenterX() / m_costume->bitmapResolution(); m_y = static_cast(m_engine->stageHeight()) / 2 - m_costume->rotationCenterY() / m_costume->bitmapResolution(); m_originX = m_costume->rotationCenterX() / m_costume->bitmapResolution(); @@ -79,13 +81,8 @@ void RenderedTarget::loadCostume(Costume *costume) return; m_costumeMutex.lock(); - m_imageChanged = true; - - if (costume->dataFormat() == "svg") { - if (costume != m_costume) - m_svgRenderer.load(QByteArray::fromRawData(static_cast(costume->data()), costume->dataSize())); - } - + m_loadCostume = true; + m_costumeChanged = (costume != m_costume); m_costume = costume; m_costumeMutex.unlock(); } @@ -97,7 +94,6 @@ void RenderedTarget::updateProperties() if (m_visible) { if (m_imageChanged) { - doLoadCostume(); update(); m_imageChanged = false; } @@ -105,6 +101,8 @@ void RenderedTarget::updateProperties() setX(m_x); setY(m_y); setZ(m_z); + setWidth(m_width); + setHeight(m_height); setRotation(m_rotation); setTransformOriginPoint(QPointF(m_originX, m_originY)); @@ -194,6 +192,28 @@ QNanoQuickItemPainter *RenderedTarget::createItemPainter() const return new TargetPainter(); } +void RenderedTarget::updateCostumeData() +{ + // Costume + m_costumeMutex.lock(); + + if (m_loadCostume) { + m_loadCostume = false; + m_imageChanged = true; + + if (m_costumeChanged) { + m_costumeChanged = false; + assert(m_costume); + + if (m_costume->dataFormat() == "svg") + m_svgRenderer.load(QByteArray::fromRawData(static_cast(m_costume->data()), m_costume->dataSize())); + } + } + + m_costumeMutex.unlock(); + doLoadCostume(); +} + void RenderedTarget::doLoadCostume() { m_costumeMutex.lock(); @@ -265,12 +285,11 @@ void RenderedTarget::calculateSize(Target *target, double costumeWidth, double c Sprite *sprite = dynamic_cast(target); if (sprite) { - double size = sprite->size(); - setWidth(costumeWidth * size / 100 / bitmapRes); - setHeight(costumeHeight * size / 100 / bitmapRes); + m_width = costumeWidth * m_size / bitmapRes; + m_height = costumeHeight * m_size / bitmapRes; } else { - setWidth(costumeWidth / bitmapRes); - setHeight(costumeHeight / bitmapRes); + m_width = costumeWidth / bitmapRes; + m_height = costumeHeight / bitmapRes; } } } diff --git a/ScratchCPPGui/renderedtarget.h b/ScratchCPPGui/renderedtarget.h index 9b8dffe..14066bf 100644 --- a/ScratchCPPGui/renderedtarget.h +++ b/ScratchCPPGui/renderedtarget.h @@ -70,6 +70,7 @@ class RenderedTarget : public IRenderedTarget QNanoQuickItemPainter *createItemPainter() const override; private: + void updateCostumeData(); void doLoadCostume(); void calculateSize(libscratchcpp::Target *target, double costumeWidth, double costumeHeight); @@ -82,11 +83,16 @@ class RenderedTarget : public IRenderedTarget QString m_bitmapUniqueKey; QMutex m_costumeMutex; QMutex mutex; + bool m_loadCostume = false; + bool m_costumeChanged = false; bool m_imageChanged = false; bool m_visible = true; + double m_size = 1; double m_x = 0; double m_y = 0; double m_z = 0; + double m_width = 0; + double m_height = 0; double m_rotation = 0; bool m_mirrorHorizontally = false; bool m_newMirrorHorizontally = false; diff --git a/test/renderedtarget/renderedtarget_test.cpp b/test/renderedtarget/renderedtarget_test.cpp index 55dc454..87449b8 100644 --- a/test/renderedtarget/renderedtarget_test.cpp +++ b/test/renderedtarget/renderedtarget_test.cpp @@ -130,8 +130,8 @@ TEST_F(RenderedTargetTest, LoadAndUpdateProperties) ASSERT_EQ(target.transformOriginPoint(), QPointF(3.4, 9.7)); target.updateProperties(); - ASSERT_EQ(target.width(), 14.3); - ASSERT_EQ(target.height(), 5.8); + ASSERT_EQ(target.width(), 5.7592); + ASSERT_EQ(target.height(), 8.6388); ASSERT_EQ(std::round(target.x() * 100) / 100, 237.18); ASSERT_EQ(std::round(target.y() * 100) / 100, -100.93); ASSERT_EQ(target.z(), 3); @@ -197,6 +197,41 @@ TEST_F(RenderedTargetTest, LoadJpegCostume) ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); target.bitmapBuffer()->close(); + EngineMock engine; + SpriteModel spriteModel; + Sprite sprite; + sprite.setSize(196.5); + spriteModel.init(&sprite); + + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); + target.setEngine(&engine); + target.setSpriteModel(&spriteModel); + target.loadProperties(); + ASSERT_FALSE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_EQ(target.bitmapBuffer()->readAll().toStdString(), str); + ASSERT_EQ(target.bitmapUniqueKey().toStdString(), costume.id()); + target.bitmapBuffer()->close(); + target.bitmapBuffer()->open(QBuffer::WriteOnly); // clear the buffer + target.bitmapBuffer()->close(); + + StageModel stageModel; + Stage stage; + + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); + target.setSpriteModel(nullptr); + target.setStageModel(&stageModel); + target.loadProperties(); + ASSERT_FALSE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_EQ(target.bitmapBuffer()->readAll().toStdString(), str); + ASSERT_EQ(target.bitmapUniqueKey().toStdString(), costume.id()); + target.bitmapBuffer()->close(); + target.updateProperties(); ASSERT_FALSE(target.isSvg()); ASSERT_FALSE(target.bitmapBuffer()->isOpen()); @@ -223,6 +258,41 @@ TEST_F(RenderedTargetTest, LoadPngCostume) ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); target.bitmapBuffer()->close(); + EngineMock engine; + SpriteModel spriteModel; + Sprite sprite; + sprite.setSize(196.5); + spriteModel.init(&sprite); + + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); + target.setEngine(&engine); + target.setSpriteModel(&spriteModel); + target.loadProperties(); + ASSERT_FALSE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_EQ(target.bitmapBuffer()->readAll().toStdString(), str); + ASSERT_EQ(target.bitmapUniqueKey().toStdString(), costume.id()); + target.bitmapBuffer()->close(); + target.bitmapBuffer()->open(QBuffer::WriteOnly); // clear the buffer + target.bitmapBuffer()->close(); + + StageModel stageModel; + Stage stage; + + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); + target.setSpriteModel(nullptr); + target.setStageModel(&stageModel); + target.loadProperties(); + ASSERT_FALSE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_EQ(target.bitmapBuffer()->readAll().toStdString(), str); + ASSERT_EQ(target.bitmapUniqueKey().toStdString(), costume.id()); + target.bitmapBuffer()->close(); + target.updateProperties(); ASSERT_FALSE(target.isSvg()); ASSERT_FALSE(target.bitmapBuffer()->isOpen()); @@ -265,15 +335,20 @@ TEST_F(RenderedTargetTest, PaintSvg) costume.setData(str.size(), static_cast(const_cast(str.c_str()))); costume.setBitmapResolution(3); + EngineMock engine; Sprite sprite; sprite.setSize(2525.7); SpriteModel model; model.init(&sprite); + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); RenderedTarget target; + target.setEngine(&engine); target.setSpriteModel(&model); target.loadCostume(&costume); + target.loadProperties(); target.updateProperties(); // Create OpenGL context From 9b5193705d5b1fc7a25a66445b62735786ae1f9e Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 22 Dec 2023 22:42:01 +0100 Subject: [PATCH 2/5] fix #51: Add SVG scale limit --- ScratchCPPGui/renderedtarget.cpp | 44 ++++++++-- ScratchCPPGui/renderedtarget.h | 3 + test/renderedtarget/renderedtarget_test.cpp | 92 ++++++++++++++++++++- 3 files changed, 128 insertions(+), 11 deletions(-) diff --git a/ScratchCPPGui/renderedtarget.cpp b/ScratchCPPGui/renderedtarget.cpp index 37f176d..6e7ec62 100644 --- a/ScratchCPPGui/renderedtarget.cpp +++ b/ScratchCPPGui/renderedtarget.cpp @@ -13,9 +13,30 @@ using namespace scratchcppgui; using namespace libscratchcpp; +static const double SVG_SCALE_LIMIT = 0.25; // the maximum viewport dimensions are multiplied by this + RenderedTarget::RenderedTarget(QNanoQuickItem *parent) : IRenderedTarget(parent) { + // Get maximum viewport dimensions + QOpenGLContext context; + context.create(); + Q_ASSERT(context.isValid()); + + if (context.isValid()) { + QOffscreenSurface surface; + surface.create(); + Q_ASSERT(surface.isValid()); + + if (surface.isValid()) { + context.makeCurrent(&surface); + GLint dims[2]; + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); + m_maximumWidth = dims[0] * SVG_SCALE_LIMIT; + m_maximumHeight = dims[1] * SVG_SCALE_LIMIT; + context.doneCurrent(); + } + } } void RenderedTarget::loadProperties() @@ -56,10 +77,11 @@ void RenderedTarget::loadProperties() // Coordinates m_size = sprite->size() / 100; updateCostumeData(); - m_x = static_cast(m_engine->stageWidth()) / 2 + sprite->x() - m_costume->rotationCenterX() * m_size / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1); - m_y = static_cast(m_engine->stageHeight()) / 2 - sprite->y() - m_costume->rotationCenterY() * m_size / m_costume->bitmapResolution(); - m_originX = m_costume->rotationCenterX() * m_size / m_costume->bitmapResolution(); - m_originY = m_costume->rotationCenterY() * m_size / m_costume->bitmapResolution(); + double clampedSize = std::min(m_size, m_maxSize); + m_x = static_cast(m_engine->stageWidth()) / 2 + sprite->x() - m_costume->rotationCenterX() * clampedSize / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1); + m_y = static_cast(m_engine->stageHeight()) / 2 - sprite->y() - m_costume->rotationCenterY() * clampedSize / m_costume->bitmapResolution(); + m_originX = m_costume->rotationCenterX() * clampedSize / m_costume->bitmapResolution(); + m_originY = m_costume->rotationCenterY() * clampedSize / m_costume->bitmapResolution(); // Layer m_z = sprite->layerOrder(); @@ -105,6 +127,12 @@ void RenderedTarget::updateProperties() setHeight(m_height); setRotation(m_rotation); setTransformOriginPoint(QPointF(m_originX, m_originY)); + Q_ASSERT(m_maxSize > 0); + + if (!m_stageModel && (m_size > m_maxSize) && (m_maxSize != 0)) + setScale(m_size / m_maxSize); + else + setScale(1); if (m_newMirrorHorizontally != m_mirrorHorizontally) { m_mirrorHorizontally = m_newMirrorHorizontally; @@ -260,7 +288,7 @@ void RenderedTarget::paintSvg(QNanoPainter *painter) QSurface *oldSurface = context->surface(); context->makeCurrent(&surface); - const QRectF drawRect(0, 0, width(), height()); + const QRectF drawRect(0, 0, std::min(width(), m_maximumWidth), std::min(height(), m_maximumHeight)); const QSize drawRectSize = drawRect.size().toSize(); /*QOpenGLFramebufferObjectFormat fboFormat; @@ -282,11 +310,13 @@ void RenderedTarget::calculateSize(Target *target, double costumeWidth, double c { if (m_costume) { double bitmapRes = m_costume->bitmapResolution(); + m_maxSize = std::min(m_maximumWidth / costumeWidth, m_maximumHeight / costumeHeight); Sprite *sprite = dynamic_cast(target); if (sprite) { - m_width = costumeWidth * m_size / bitmapRes; - m_height = costumeHeight * m_size / bitmapRes; + double clampedSize = std::min(m_size, m_maxSize); + m_width = costumeWidth * clampedSize / bitmapRes; + m_height = costumeHeight * clampedSize / bitmapRes; } else { m_width = costumeWidth / bitmapRes; m_height = costumeHeight / bitmapRes; diff --git a/ScratchCPPGui/renderedtarget.h b/ScratchCPPGui/renderedtarget.h index 14066bf..992414c 100644 --- a/ScratchCPPGui/renderedtarget.h +++ b/ScratchCPPGui/renderedtarget.h @@ -88,6 +88,7 @@ class RenderedTarget : public IRenderedTarget bool m_imageChanged = false; bool m_visible = true; double m_size = 1; + double m_maxSize = 1; double m_x = 0; double m_y = 0; double m_z = 0; @@ -98,6 +99,8 @@ class RenderedTarget : public IRenderedTarget bool m_newMirrorHorizontally = false; double m_originX = 0; double m_originY = 0; + qreal m_maximumWidth = std::numeric_limits::infinity(); + qreal m_maximumHeight = std::numeric_limits::infinity(); }; } // namespace scratchcppgui diff --git a/test/renderedtarget/renderedtarget_test.cpp b/test/renderedtarget/renderedtarget_test.cpp index 87449b8..b1daa27 100644 --- a/test/renderedtarget/renderedtarget_test.cpp +++ b/test/renderedtarget/renderedtarget_test.cpp @@ -304,14 +304,90 @@ TEST_F(RenderedTargetTest, LoadPngCostume) TEST_F(RenderedTargetTest, LoadSvgCostume) { + // Get maximum viewport dimensions + QOpenGLContext context; + context.create(); + Q_ASSERT(context.isValid()); + + QOffscreenSurface surface; + surface.create(); + Q_ASSERT(surface.isValid()); + + context.makeCurrent(&surface); + GLint dims[2]; + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); + double maxWidth = dims[0] * 0.25; + double maxHeight = dims[1] * 0.25; + double maxSize = std::min(maxWidth / (1143 / 90.0), maxHeight / (1143 / 90.0)); + context.doneCurrent(); + std::string str = readFileStr("image.svg"); - Costume costume("", "abc", "svg"); - costume.setData(str.size(), static_cast(const_cast(str.c_str()))); - costume.setBitmapResolution(3); + auto costume = std::make_shared("", "abc", "svg"); + costume->setData(str.size(), static_cast(const_cast(str.c_str()))); + costume->setBitmapResolution(1); + + EngineMock engine; + SpriteModel model; + Sprite sprite; + sprite.setSize(maxSize * 100); + sprite.setX(49.7); + sprite.setY(-64.15); + costume->setRotationCenterX(-84); + costume->setRotationCenterY(53); + model.init(&sprite); RenderedTarget target; + target.setEngine(&engine); + target.setSpriteModel(&model); - target.loadCostume(&costume); + target.loadCostume(costume.get()); + ASSERT_TRUE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_TRUE(target.bitmapBuffer()->readAll().toStdString().empty()); + ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); + target.bitmapBuffer()->close(); + + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); + target.loadProperties(); + ASSERT_TRUE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_TRUE(target.bitmapBuffer()->readAll().toStdString().empty()); + ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); + target.bitmapBuffer()->close(); + + target.updateProperties(); + ASSERT_TRUE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_TRUE(target.bitmapBuffer()->readAll().toStdString().empty()); + ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); + target.bitmapBuffer()->close(); + + ASSERT_EQ(std::round(target.width() * 100) / 100, maxWidth); + ASSERT_EQ(std::round(target.height() * 100) / 100, maxHeight); + ASSERT_EQ(target.scale(), 1); + ASSERT_EQ(std::round(target.x() * 100) / 100, 27381.35); + ASSERT_EQ(std::round(target.y() * 100) / 100, -16849.39); + ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -27091.65); + ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 17093.54); + + // Test scale limit + sprite.setSize(maxSize * 250); + + target.loadCostume(costume.get()); + ASSERT_TRUE(target.isSvg()); + ASSERT_FALSE(target.bitmapBuffer()->isOpen()); + target.bitmapBuffer()->open(QBuffer::ReadOnly); + ASSERT_TRUE(target.bitmapBuffer()->readAll().toStdString().empty()); + ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); + target.bitmapBuffer()->close(); + + EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); + EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); + target.loadProperties(); ASSERT_TRUE(target.isSvg()); ASSERT_FALSE(target.bitmapBuffer()->isOpen()); target.bitmapBuffer()->open(QBuffer::ReadOnly); @@ -326,6 +402,14 @@ TEST_F(RenderedTargetTest, LoadSvgCostume) ASSERT_TRUE(target.bitmapBuffer()->readAll().toStdString().empty()); ASSERT_TRUE(target.bitmapUniqueKey().toStdString().empty()); target.bitmapBuffer()->close(); + + ASSERT_EQ(std::round(target.width() * 100) / 100, maxWidth); + ASSERT_EQ(std::round(target.height() * 100) / 100, maxHeight); + ASSERT_EQ(target.scale(), 2.5); + ASSERT_EQ(std::round(target.x() * 100) / 100, 27381.35); + ASSERT_EQ(std::round(target.y() * 100) / 100, -16849.39); + ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -27091.65); + ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 17093.54); } TEST_F(RenderedTargetTest, PaintSvg) From eba3471c49ba1d315652290a6def96236d3ea552 Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:37:14 +0100 Subject: [PATCH 3/5] fix #47: Force FBO multisampling in QNanoPainter --- ScratchCPPGui/renderedtarget.cpp | 4 ---- thirdparty/libqnanopainter/qnanoquickitempainter.cpp | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/ScratchCPPGui/renderedtarget.cpp b/ScratchCPPGui/renderedtarget.cpp index 6e7ec62..f09905a 100644 --- a/ScratchCPPGui/renderedtarget.cpp +++ b/ScratchCPPGui/renderedtarget.cpp @@ -291,10 +291,6 @@ void RenderedTarget::paintSvg(QNanoPainter *painter) const QRectF drawRect(0, 0, std::min(width(), m_maximumWidth), std::min(height(), m_maximumHeight)); const QSize drawRectSize = drawRect.size().toSize(); - /*QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setSamples(16); - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);*/ - QOpenGLPaintDevice device(drawRectSize); QPainter qPainter; qPainter.begin(&device); diff --git a/thirdparty/libqnanopainter/qnanoquickitempainter.cpp b/thirdparty/libqnanopainter/qnanoquickitempainter.cpp index 170e344..a2041dd 100644 --- a/thirdparty/libqnanopainter/qnanoquickitempainter.cpp +++ b/thirdparty/libqnanopainter/qnanoquickitempainter.cpp @@ -154,6 +154,7 @@ QOpenGLFramebufferObject *QNanoQuickItemPainter::createFramebufferObject(const Q { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + format.setSamples(16); QSize fboSize(size); if (m_textureWidth > -1) fboSize.setWidth(static_cast(m_textureWidth*m_itemData.devicePixelRatio)); if (m_textureHeight > -1) fboSize.setHeight(static_cast(m_textureHeight*m_itemData.devicePixelRatio)); From 4a94a3f911871b4d70c7bf377b78ee8a3ec7229d Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 23 Dec 2023 00:09:36 +0100 Subject: [PATCH 4/5] RenderedTarget: Update costume of invisible sprites --- ScratchCPPGui/renderedtarget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ScratchCPPGui/renderedtarget.cpp b/ScratchCPPGui/renderedtarget.cpp index f09905a..852b5b5 100644 --- a/ScratchCPPGui/renderedtarget.cpp +++ b/ScratchCPPGui/renderedtarget.cpp @@ -52,6 +52,9 @@ void RenderedTarget::loadProperties() // Visibility m_visible = sprite->visible(); + m_size = sprite->size() / 100; + updateCostumeData(); + if (m_visible) { // Direction switch (sprite->rotationStyle()) { @@ -75,8 +78,6 @@ void RenderedTarget::loadProperties() } // Coordinates - m_size = sprite->size() / 100; - updateCostumeData(); double clampedSize = std::min(m_size, m_maxSize); m_x = static_cast(m_engine->stageWidth()) / 2 + sprite->x() - m_costume->rotationCenterX() * clampedSize / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1); m_y = static_cast(m_engine->stageHeight()) / 2 - sprite->y() - m_costume->rotationCenterY() * clampedSize / m_costume->bitmapResolution(); From 2de1c321fb1bb0a743cbc4c4a91386d22950fa3d Mon Sep 17 00:00:00 2001 From: adazem009 <68537469+adazem009@users.noreply.github.com> Date: Sat, 23 Dec 2023 00:11:12 +0100 Subject: [PATCH 5/5] Set SVG scale limit to 0.1 --- ScratchCPPGui/renderedtarget.cpp | 2 +- test/renderedtarget/renderedtarget_test.cpp | 22 ++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ScratchCPPGui/renderedtarget.cpp b/ScratchCPPGui/renderedtarget.cpp index 852b5b5..d3f0185 100644 --- a/ScratchCPPGui/renderedtarget.cpp +++ b/ScratchCPPGui/renderedtarget.cpp @@ -13,7 +13,7 @@ using namespace scratchcppgui; using namespace libscratchcpp; -static const double SVG_SCALE_LIMIT = 0.25; // the maximum viewport dimensions are multiplied by this +static const double SVG_SCALE_LIMIT = 0.1; // the maximum viewport dimensions are multiplied by this RenderedTarget::RenderedTarget(QNanoQuickItem *parent) : IRenderedTarget(parent) diff --git a/test/renderedtarget/renderedtarget_test.cpp b/test/renderedtarget/renderedtarget_test.cpp index b1daa27..d8aa3ec 100644 --- a/test/renderedtarget/renderedtarget_test.cpp +++ b/test/renderedtarget/renderedtarget_test.cpp @@ -316,8 +316,8 @@ TEST_F(RenderedTargetTest, LoadSvgCostume) context.makeCurrent(&surface); GLint dims[2]; glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); - double maxWidth = dims[0] * 0.25; - double maxHeight = dims[1] * 0.25; + double maxWidth = dims[0] * 0.1; + double maxHeight = dims[1] * 0.1; double maxSize = std::min(maxWidth / (1143 / 90.0), maxHeight / (1143 / 90.0)); context.doneCurrent(); @@ -369,10 +369,10 @@ TEST_F(RenderedTargetTest, LoadSvgCostume) ASSERT_EQ(std::round(target.width() * 100) / 100, maxWidth); ASSERT_EQ(std::round(target.height() * 100) / 100, maxHeight); ASSERT_EQ(target.scale(), 1); - ASSERT_EQ(std::round(target.x() * 100) / 100, 27381.35); - ASSERT_EQ(std::round(target.y() * 100) / 100, -16849.39); - ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -27091.65); - ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 17093.54); + ASSERT_EQ(std::round(target.x() * 100) / 100, 11126.36); + ASSERT_EQ(std::round(target.y() * 100) / 100, -6593.27); + ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -10836.66); + ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 6837.42); // Test scale limit sprite.setSize(maxSize * 250); @@ -405,11 +405,11 @@ TEST_F(RenderedTargetTest, LoadSvgCostume) ASSERT_EQ(std::round(target.width() * 100) / 100, maxWidth); ASSERT_EQ(std::round(target.height() * 100) / 100, maxHeight); - ASSERT_EQ(target.scale(), 2.5); - ASSERT_EQ(std::round(target.x() * 100) / 100, 27381.35); - ASSERT_EQ(std::round(target.y() * 100) / 100, -16849.39); - ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -27091.65); - ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 17093.54); + ASSERT_EQ(std::round(target.scale() * 100) / 100, 2.5); + ASSERT_EQ(std::round(target.x() * 100) / 100, 11126.36); + ASSERT_EQ(std::round(target.y() * 100) / 100, -6593.27); + ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -10836.66); + ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 6837.42); } TEST_F(RenderedTargetTest, PaintSvg)