From 72ed04f2ed1aa364b736b6eb97ee98cac0e26d7c Mon Sep 17 00:00:00 2001 From: saqib mir Date: Wed, 1 Jul 2026 17:28:00 +0530 Subject: [PATCH] fix the issue --- engine/tests/display_list_test.cpp | 129 +++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/engine/tests/display_list_test.cpp b/engine/tests/display_list_test.cpp index 8ed2834..611eb12 100644 --- a/engine/tests/display_list_test.cpp +++ b/engine/tests/display_list_test.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include "../src/parser/content_stream_parser.hpp" #include #include @@ -20,6 +23,38 @@ public: void visit(const DrawImageCommand&) override { calls.push_back("DrawImage"); } }; +class PathVerifyVisitor : public CommandVisitor { +public: + struct PathInfo { + std::string type; + size_t segmentCount = 0; + FillRule rule = FillRule::NonZero; + }; + std::vector paths; + std::vector calls; + + void visit(const SaveStateCommand&) override { calls.push_back("SaveState"); } + void visit(const RestoreStateCommand&) override { calls.push_back("RestoreState"); } + void visit(const SetTransformCommand& cmd) override { + calls.push_back("SetTransform(" + std::to_string(cmd.matrix.a) + "," + std::to_string(cmd.matrix.d) + ")"); + } + void visit(const FillRectCommand&) override {} + void visit(const DrawTextCommand&) override {} + void visit(const FillPathCommand& cmd) override { + calls.push_back("FillPath"); + paths.push_back({"Fill", cmd.path.segments().size(), cmd.rule}); + } + void visit(const StrokePathCommand& cmd) override { + calls.push_back("StrokePath"); + paths.push_back({"Stroke", cmd.path.segments().size(), FillRule::NonZero}); + } + void visit(const FillStrokePathCommand& cmd) override { + calls.push_back("FillStrokePath"); + paths.push_back({"FillStroke", cmd.path.segments().size(), cmd.rule}); + } + void visit(const DrawImageCommand&) override {} +}; + TEST(DisplayListTest, RecordAndReplay) { DisplayList list; @@ -53,3 +88,97 @@ TEST(DisplayListTest, Clear) { list.clear(); EXPECT_EQ(list.size(), 0); } + +TEST(DisplayListTest, PathObjectInterpreterStroke) { + Path path; + path.moveTo(10.0f, 20.0f); + path.lineTo(30.0f, 40.0f); + + PathObject pathObj; + pathObj.path = path; + pathObj.paintOp = PathPaintOp::Stroke; + pathObj.transform = Matrix(1.5f, 0.0f, 0.0f, 1.5f, 5.0f, 5.0f); + + DisplayList list; + PathObjectInterpreter::interpret(pathObj, list); + + PathVerifyVisitor visitor; + list.replay(visitor); + + ASSERT_EQ(visitor.calls.size(), 4); + EXPECT_EQ(visitor.calls[0], "SaveState"); + EXPECT_EQ(visitor.calls[1], "SetTransform(1.500000,1.500000)"); + EXPECT_EQ(visitor.calls[2], "StrokePath"); + EXPECT_EQ(visitor.calls[3], "RestoreState"); + + ASSERT_EQ(visitor.paths.size(), 1); + EXPECT_EQ(visitor.paths[0].type, "Stroke"); + EXPECT_EQ(visitor.paths[0].segmentCount, 2); +} + +TEST(DisplayListTest, PathObjectInterpreterFillEvenOdd) { + Path path; + path.addRect(0.0f, 0.0f, 10.0f, 10.0f); + + PathObject pathObj; + pathObj.path = path; + pathObj.paintOp = PathPaintOp::Fill; + pathObj.fillRule = FillRule::EvenOdd; + pathObj.transform = Matrix(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); + + DisplayList list; + PathObjectInterpreter::interpret(pathObj, list); + + PathVerifyVisitor visitor; + list.replay(visitor); + + ASSERT_EQ(visitor.calls.size(), 4); + EXPECT_EQ(visitor.calls[2], "FillPath"); + + ASSERT_EQ(visitor.paths.size(), 1); + EXPECT_EQ(visitor.paths[0].type, "Fill"); + EXPECT_EQ(visitor.paths[0].segmentCount, 5); // moveTo + 3 lineTo + close + EXPECT_EQ(visitor.paths[0].rule, FillRule::EvenOdd); +} + +TEST(DisplayListTest, ContentStreamParserPaths) { + DisplayList list; + ContentStreamParser parser; + + // Parse stroke path (m, l, S) + parser.parse("10 20 m 30 40 l S", list); + + // Parse fill path (re, f) + parser.parse("5 6 7 8 re f", list); + + // Parse fill and stroke (m, c, B) + parser.parse("1 2 m 3 4 5 6 7 8 c B", list); + + PathVerifyVisitor visitor; + list.replay(visitor); + + // S -> StrokePath + // f -> FillPath + // B -> FillPath, StrokePath + ASSERT_EQ(visitor.calls.size(), 4); + EXPECT_EQ(visitor.calls[0], "StrokePath"); + EXPECT_EQ(visitor.calls[1], "FillPath"); + EXPECT_EQ(visitor.calls[2], "FillPath"); + EXPECT_EQ(visitor.calls[3], "StrokePath"); + + ASSERT_EQ(visitor.paths.size(), 4); + + // 1st: 10 20 m 30 40 l S -> MoveTo, LineTo + EXPECT_EQ(visitor.paths[0].type, "Stroke"); + EXPECT_EQ(visitor.paths[0].segmentCount, 2); + + // 2nd: 5 6 7 8 re f -> MoveTo, 3xLineTo, Close + EXPECT_EQ(visitor.paths[1].type, "Fill"); + EXPECT_EQ(visitor.paths[1].segmentCount, 5); + + // 3rd & 4th: 1 2 m 3 4 5 6 7 8 c B -> MoveTo, CubicBezierTo + EXPECT_EQ(visitor.paths[2].type, "Fill"); + EXPECT_EQ(visitor.paths[2].segmentCount, 2); + EXPECT_EQ(visitor.paths[3].type, "Stroke"); + EXPECT_EQ(visitor.paths[3].segmentCount, 2); +}