fix the issue
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <pdfengine/display_list.hpp>
|
||||
#include <pdfengine/path_interpreter.hpp>
|
||||
#include <pdfengine/content_object.hpp>
|
||||
#include "../src/parser/content_stream_parser.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -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<PathInfo> paths;
|
||||
std::vector<std::string> 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user