Skip to content

Commit 3db89da

Browse files
committed
Add BitmapSkin class
1 parent 5818643 commit 3db89da

8 files changed

+175
-0
lines changed

src/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ qt_add_qml_module(scratchcpp-render
3535
texture.h
3636
skin.cpp
3737
skin.h
38+
bitmapskin.cpp
39+
bitmapskin.h
3840
renderedtarget.cpp
3941
renderedtarget.h
4042
targetpainter.cpp

src/bitmapskin.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#include <scratchcpp/costume.h>
4+
5+
#include "bitmapskin.h"
6+
7+
using namespace scratchcpprender;
8+
9+
BitmapSkin::BitmapSkin(libscratchcpp::Costume *costume) :
10+
Skin(costume)
11+
{
12+
if (!costume)
13+
return;
14+
15+
// Read image data
16+
QBuffer buffer;
17+
buffer.open(QBuffer::WriteOnly);
18+
buffer.write(static_cast<const char *>(costume->data()), costume->dataSize());
19+
buffer.close();
20+
const char *format;
21+
22+
{
23+
QImageReader reader(&buffer);
24+
format = reader.format();
25+
}
26+
27+
buffer.close();
28+
m_image.load(&buffer, format);
29+
30+
// Paint the image into a texture
31+
m_texture = createAndPaintTexture(m_image.width(), m_image.height(), false);
32+
m_textureSize.setWidth(m_image.width());
33+
m_textureSize.setHeight(m_image.height());
34+
Q_ASSERT(m_texture.isValid());
35+
}
36+
37+
BitmapSkin::~BitmapSkin()
38+
{
39+
m_texture.release();
40+
}
41+
42+
Texture BitmapSkin::getTexture(double scale) const
43+
{
44+
return m_texture;
45+
}
46+
47+
double BitmapSkin::getTextureScale(const Texture &texture) const
48+
{
49+
return 1;
50+
}
51+
52+
void BitmapSkin::paint(QPainter *painter)
53+
{
54+
painter->drawImage(m_image.rect(), m_image, m_image.rect());
55+
}

src/bitmapskin.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#pragma once
4+
5+
#include "skin.h"
6+
#include "texture.h"
7+
8+
namespace scratchcpprender
9+
{
10+
11+
class BitmapSkin : public Skin
12+
{
13+
public:
14+
BitmapSkin(libscratchcpp::Costume *costume);
15+
~BitmapSkin();
16+
17+
Texture getTexture(double scale) const override;
18+
double getTextureScale(const Texture &texture) const override;
19+
20+
protected:
21+
void paint(QPainter *painter) override;
22+
23+
private:
24+
Texture m_texture;
25+
QSize m_textureSize;
26+
QImage m_image;
27+
};
28+
29+
} // namespace scratchcpprender

test/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ add_subdirectory(mouseeventhandler)
3030
add_subdirectory(scenemousearea)
3131
add_subdirectory(monitor_models)
3232
add_subdirectory(texture)
33+
add_subdirectory(skins)

test/jpeg_result.png

157 Bytes
Loading

test/png_result.png

127 Bytes
Loading

test/skins/CMakeLists.txt

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
add_executable(
2+
bitmapskin_test
3+
bitmapskin_test.cpp
4+
)
5+
6+
target_link_libraries(
7+
bitmapskin_test
8+
GTest::gtest_main
9+
scratchcpp-render
10+
${QT_LIBS}
11+
)
12+
13+
add_test(bitmapskin_test)
14+
gtest_discover_tests(bitmapskin_test)

test/skins/bitmapskin_test.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include <scratchcpp/costume.h>
2+
#include <bitmapskin.h>
3+
4+
#include "../common.h"
5+
6+
using namespace scratchcpprender;
7+
using namespace libscratchcpp;
8+
9+
class BitmapSkinTest : public testing::Test
10+
{
11+
public:
12+
void SetUp() override
13+
{
14+
m_context.create();
15+
ASSERT_TRUE(m_context.isValid());
16+
17+
m_surface.setFormat(m_context.format());
18+
m_surface.create();
19+
Q_ASSERT(m_surface.isValid());
20+
m_context.makeCurrent(&m_surface);
21+
22+
Costume jpegCostume("", "", "");
23+
std::string costumeData = readFileStr("image.jpg");
24+
jpegCostume.setData(costumeData.size(), costumeData.data());
25+
m_jpegSkin = std::make_unique<BitmapSkin>(&jpegCostume);
26+
27+
Costume pngCostume("", "", "");
28+
costumeData = readFileStr("image.png");
29+
pngCostume.setData(costumeData.size(), costumeData.data());
30+
m_pngSkin = std::make_unique<BitmapSkin>(&pngCostume);
31+
}
32+
33+
void TearDown() override
34+
{
35+
ASSERT_EQ(m_context.surface(), &m_surface);
36+
m_context.doneCurrent();
37+
}
38+
39+
QOpenGLContext m_context;
40+
QOffscreenSurface m_surface;
41+
std::unique_ptr<Skin> m_jpegSkin;
42+
std::unique_ptr<Skin> m_pngSkin;
43+
};
44+
45+
TEST_F(BitmapSkinTest, GetTexture)
46+
{
47+
Texture texture = m_jpegSkin->getTexture(1);
48+
ASSERT_EQ(texture.width(), 4);
49+
ASSERT_EQ(texture.height(), 6);
50+
51+
QBuffer jpegBuffer;
52+
texture.toImage().save(&jpegBuffer, "png");
53+
QFile jpegRef("jpeg_result.png");
54+
jpegRef.open(QFile::ReadOnly);
55+
jpegBuffer.open(QBuffer::ReadOnly);
56+
ASSERT_EQ(jpegBuffer.readAll(), jpegRef.readAll());
57+
58+
texture = m_pngSkin->getTexture(1);
59+
ASSERT_EQ(texture.width(), 4);
60+
ASSERT_EQ(texture.height(), 6);
61+
62+
QBuffer pngBuffer;
63+
texture.toImage().save(&pngBuffer, "png");
64+
QFile pngRef("png_result.png");
65+
pngRef.open(QFile::ReadOnly);
66+
pngBuffer.open(QBuffer::ReadOnly);
67+
ASSERT_EQ(pngBuffer.readAll(), pngRef.readAll());
68+
}
69+
70+
TEST_F(BitmapSkinTest, GetTextureScale)
71+
{
72+
ASSERT_EQ(m_jpegSkin->getTextureScale(Texture()), 1);
73+
ASSERT_EQ(m_pngSkin->getTextureScale(Texture()), 1);
74+
}

0 commit comments

Comments
 (0)