From: Jean-Philippe Bruyère Date: Thu, 20 Mar 2025 16:06:19 +0000 (+0100) Subject: wip X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=6fc9877b8a0e9b18d8afbcdadad1746dd0d4b31a;p=jp%2Fvkvg.git wip --- 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 -#include +#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 +#include + +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;