summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2025-03-20 17:06:19 +0100
committerj-p <jp_bruyere@hotmail.com>2025-03-24 19:12:00 +0100
commit6fc9877b8a0e9b18d8afbcdadad1746dd0d4b31a (patch)
tree93d167d4957721907e1907b7b32a667dbb7f6704
parent788e4c70acf22de7f2dc6c7c2cc987869c6bfa7a (diff)
wip
-rw-r--r--gunit_tests/CMakeLists.txt4
-rw-r--r--gunit_tests/basicDraw.cpp154
-rw-r--r--gunit_tests/drawTestBase.cpp82
-rw-r--r--gunit_tests/drawTestBase.h22
-rw-r--r--src/vkvg_context.c4
5 files changed, 176 insertions, 90 deletions
diff --git a/gunit_tests/CMakeLists.txt b/gunit_tests/CMakeLists.txt
index 4a17f20..6e45efe 100644
--- a/gunit_tests/CMakeLists.txt
+++ b/gunit_tests/CMakeLists.txt
@@ -18,6 +18,7 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
set(GTEST_PNG_ROOT "${CMAKE_SOURCE_DIR}/ReferenceImages" CACHE STRING "Reference png root path")
+set(GTEST_DATA_ROOT "${CMAKE_SOURCE_DIR}/tests/data" CACHE STRING "Data path for unit tests")
add_executable("${PROJECT_NAME}"
main.cpp
@@ -25,9 +26,12 @@ add_executable("${PROJECT_NAME}"
surface.cpp
context.cpp
basicDraw.cpp
+ drawTestBase.cpp
+ drawTestBase.h
)
target_compile_definitions("${PROJECT_NAME}" PUBLIC
GTEST_PNG_ROOT="${GTEST_PNG_ROOT}"
+ GTEST_DATA_ROOT="${GTEST_DATA_ROOT}"
)
target_include_directories("${PROJECT_NAME}" PUBLIC
"${CMAKE_SOURCE_DIR}/include"
diff --git a/gunit_tests/basicDraw.cpp b/gunit_tests/basicDraw.cpp
index 6234306..e4e290f 100644
--- a/gunit_tests/basicDraw.cpp
+++ b/gunit_tests/basicDraw.cpp
@@ -1,100 +1,14 @@
-#include "vkvg.h"
-#include <gtest/gtest.h>
-#include <filesystem>
+#include "drawTestBase.h"
-//#define STB_IMAGE_IMPLEMENTATION
-#include "stb_image.h"
-//#define STB_IMAGE_WRITE_IMPLEMENTATION
-#include "stb_image_write.h"
-
-namespace fs = std::filesystem;
-
-
-class BasicDrawTest : public testing::Test {
- public:
- VkvgDevice dev;
- VkvgSurface surf;
- fs::path targetDir;
- fs::path diffDir;
+class BasicDrawTest : public DrawTestBase {
protected:
- BasicDrawTest() {
- targetDir = fs::path(GTEST_PNG_ROOT) / ::testing::UnitTest::GetInstance()->current_test_suite()->name();
- if (!fs::is_directory(targetDir) || !fs::exists(targetDir))
- fs::create_directories(targetDir);
- diffDir = fs::path("DiffImages") / ::testing::UnitTest::GetInstance()->current_test_suite()->name();
- if (!fs::is_directory(diffDir) || !fs::exists(diffDir))
- fs::create_directories(diffDir);
-
- vkvg_device_create_info_t info{};
- dev = vkvg_device_create(&info);
- }
-
- ~BasicDrawTest() override {
- vkvg_device_destroy(dev);
- }
void SetUp() override {
surf = vkvg_surface_create(dev, 256, 256);
}
-
- void TearDown() override {
- vkvg_surface_destroy(surf);
- }
-
- void compareWithRefImage() {
- fs::path targetPath = targetDir / ::testing::UnitTest::GetInstance()->current_test_info()->name();
- targetPath.replace_extension(".png");
-
- if (fs::exists(targetPath)) {
- int w = 0, h = 0, channels = 0;
- unsigned char *refImg = stbi_load(targetPath.c_str(), &w, &h, &channels, 4); // force 4 components per pixel
- EXPECT_TRUE(refImg != nullptr) << "Could not load texture from " << targetPath << stbi_failure_reason();
- EXPECT_EQ(vkvg_surface_get_width(surf),w);
- EXPECT_EQ(vkvg_surface_get_height(surf),h);
-
- unsigned char *img = (unsigned char*)malloc(w*h*4);
- unsigned char *diffImg = (unsigned char*)malloc(w*h*4);
-
- vkvg_status_t result = vkvg_surface_write_to_memory(surf, img);
- EXPECT_EQ(result, VKVG_STATUS_SUCCESS);
-
- uint32_t totDiff = 0;
-
-
- for(int y = 0; y < h; y++) {
- for(int x = 0; x < w; x++) {
- unsigned char* refPix = refImg + (y * w + x) * 4;
- unsigned char* pix = img + (y * w + x) * 4;
- unsigned char* diffPix = diffImg + (y * w + x) * 4;
- if (*refPix < *pix)
- *diffPix = *pix - *refPix;
- else if (*refPix > *pix)
- *diffPix = *refPix - *pix;
- else
- *diffPix = 0;
- totDiff += (uint32_t)*diffPix;
- }
- }
- EXPECT_EQ(totDiff, 0);
-
- if (totDiff > 0) {
- fs::path diffPath = diffDir / ::testing::UnitTest::GetInstance()->current_test_info()->name();
- targetPath.replace_extension(".png");
- stbi_write_png(diffPath.c_str(), (int32_t)w, (int32_t)h, 4, diffImg, (int32_t)(4 * w));
- }
-
- free(img);
- free(diffImg);
- } else {
- vkvg_status_t result = vkvg_surface_write_to_png(surf, targetPath.c_str());
- EXPECT_EQ(result, VKVG_STATUS_SUCCESS);
- GTEST_SKIP() << "Updating reference image: " << targetPath;
- }
-
-
- }
};
+
TEST_F(BasicDrawTest, CtxSolidPaintRGB) {
VkvgContext ctx = vkvg_create(surf);
vkvg_set_source_rgb(ctx,1,0,0);
@@ -153,4 +67,66 @@ TEST_F(BasicDrawTest, CtxSolidPaintRectanglesOver) {
compareWithRefImage();
}
+TEST_F(BasicDrawTest, CtxSolidFillOver) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,1,0,0,0.5);
+ vkvg_rectangle(ctx,50,50,100,100);
+ vkvg_fill(ctx);
+ vkvg_set_source_rgba(ctx,0,0,1,0.5);
+ vkvg_rectangle(ctx,100,100,100,100);
+ vkvg_fill(ctx);
+ vkvg_destroy(ctx);
+ compareWithRefImage();
+}
+TEST_F(BasicDrawTest, CtxSolidPaintRectangleOver) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,1,0,0,0.5f);
+ vkvg_paint(ctx);
+ vkvg_set_source_rgba(ctx,0,0,1,0.5f);
+ vkvg_rectangle(ctx,100,100,100,100);
+ vkvg_paint(ctx);
+
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
+TEST_F(BasicDrawTest, CtxSolidPaintRectangleOverClipped) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_rectangle(ctx,90,90,70,70);
+ vkvg_clip(ctx);
+ vkvg_set_source_rgba(ctx,1,0,0,0.5);
+ vkvg_rectangle(ctx,50,50,100,100);
+ vkvg_fill(ctx);
+ vkvg_set_source_rgba(ctx,0,0,1,0.5);
+ vkvg_rectangle(ctx,100,100,100,100);
+ vkvg_fill(ctx);
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
+TEST_F(BasicDrawTest, CtxSolidPaintClipped) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_rectangle(ctx,50,50,200,150);
+ vkvg_clip(ctx);
+
+ vkvg_set_source_rgba(ctx,1,0,0,0.5f);
+ vkvg_paint(ctx);
+
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
+TEST_F(BasicDrawTest, CtxSolidPaintClippedOver) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,1,0,0,0.5f);
+ vkvg_paint(ctx);
+ vkvg_rectangle(ctx,50,50,200,150);
+ vkvg_clip(ctx);
+ vkvg_set_source_rgba(ctx,0,0,1,0.5f);
+ vkvg_paint(ctx);
+
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
diff --git a/gunit_tests/drawTestBase.cpp b/gunit_tests/drawTestBase.cpp
new file mode 100644
index 0000000..71a022c
--- /dev/null
+++ b/gunit_tests/drawTestBase.cpp
@@ -0,0 +1,82 @@
+#include "drawTestBase.h"
+
+//#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+//#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "stb_image_write.h"
+
+DrawTestBase::DrawTestBase() {
+ targetDir = fs::path(GTEST_PNG_ROOT) / ::testing::UnitTest::GetInstance()->current_test_suite()->name();
+ if (!fs::is_directory(targetDir) || !fs::exists(targetDir))
+ fs::create_directories(targetDir);
+ diffDir = fs::path("DiffImages") / ::testing::UnitTest::GetInstance()->current_test_suite()->name();
+ if (!fs::is_directory(diffDir) || !fs::exists(diffDir))
+ fs::create_directories(diffDir);
+
+ vkvg_device_create_info_t info{};
+ dev = vkvg_device_create(&info);
+}
+
+DrawTestBase::~DrawTestBase() {
+ vkvg_device_destroy(dev);
+}
+
+void DrawTestBase::SetUp() {
+ surf = vkvg_surface_create(dev, 256, 256);
+}
+
+void DrawTestBase::TearDown() {
+ vkvg_surface_destroy(surf);
+}
+
+void DrawTestBase::compareWithRefImage() {
+ fs::path targetPath = targetDir / ::testing::UnitTest::GetInstance()->current_test_info()->name();
+ targetPath.replace_extension(".png");
+
+ if (fs::exists(targetPath)) {
+ int w = 0, h = 0, channels = 0;
+ unsigned char *refImg = stbi_load(targetPath.c_str(), &w, &h, &channels, 4); // force 4 components per pixel
+ EXPECT_TRUE(refImg != nullptr) << "Could not load image from " << targetPath << stbi_failure_reason();
+ EXPECT_EQ(vkvg_surface_get_width(surf),w);
+ EXPECT_EQ(vkvg_surface_get_height(surf),h);
+
+ unsigned char *img = (unsigned char*)malloc(w*h*4);
+ unsigned char *diffImg = (unsigned char*)malloc(w*h*4);
+
+ vkvg_status_t result = vkvg_surface_write_to_memory(surf, img);
+ EXPECT_EQ(result, VKVG_STATUS_SUCCESS);
+
+ uint32_t totDiff = 0;
+
+ for(int y = 0; y < h; y++) {
+ for(int x = 0; x < w; x++) {
+ unsigned char* refPix = refImg + (y * w + x) * 4;
+ unsigned char* pix = img + (y * w + x) * 4;
+ unsigned char* diffPix = diffImg + (y * w + x) * 4;
+ if (*refPix < *pix)
+ *diffPix = *pix - *refPix;
+ else if (*refPix > *pix)
+ *diffPix = *refPix - *pix;
+ else
+ *diffPix = 0;
+ totDiff += (uint32_t)*diffPix;
+ }
+ }
+ EXPECT_EQ(totDiff, 0);
+
+ if (totDiff > 0) {
+ fs::path diffPath = diffDir / ::testing::UnitTest::GetInstance()->current_test_info()->name();
+ targetPath.replace_extension(".png");
+ stbi_write_png(diffPath.c_str(), (int32_t)w, (int32_t)h, 4, diffImg, (int32_t)(4 * w));
+ }
+
+ free(img);
+ free(diffImg);
+ } else {
+ vkvg_status_t result = vkvg_surface_write_to_png(surf, targetPath.c_str());
+ EXPECT_EQ(result, VKVG_STATUS_SUCCESS);
+ GTEST_SKIP() << "Updating reference image: " << targetPath;
+ }
+}
+
+
diff --git a/gunit_tests/drawTestBase.h b/gunit_tests/drawTestBase.h
new file mode 100644
index 0000000..97d8eae
--- /dev/null
+++ b/gunit_tests/drawTestBase.h
@@ -0,0 +1,22 @@
+#include "vkvg.h"
+#include <gtest/gtest.h>
+#include <filesystem>
+
+namespace fs = std::filesystem;
+
+class DrawTestBase : public testing::Test {
+ public:
+ VkvgDevice dev;
+ VkvgSurface surf;
+ fs::path targetDir;
+ fs::path diffDir;
+
+ protected:
+ DrawTestBase();
+ ~DrawTestBase() override;
+ void SetUp() override;
+ void TearDown() override;
+
+ void compareWithRefImage();
+};
+
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index 6e8f6b0..83372ab 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -299,6 +299,8 @@ void vkvg_destroy(VkvgContext ctx) {
}
_release_context_ressources(ctx);
+
+ ctx = NULL;
}
void vkvg_set_opacity(VkvgContext ctx, float opacity) {
if (vkvg_status(ctx))
@@ -563,7 +565,7 @@ void _curve_to(VkvgContext ctx, float x1, float y1, float x2, float y2, float x3
_set_curve_end(ctx);
}
const double quadraticFact = 2.0 / 3.0;
-void _quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2) {
+void _quadratic_to(VkvgContext ctx, float x1, float y1, float x2, float y2) {
float x0, y0;
if (_current_path_is_empty(ctx)) {
x0 = x1;