#pragma once #include #include #include #include #include #include namespace pdfengine { class CommandVisitor; struct Command { virtual ~Command() = default; virtual void accept(CommandVisitor& visitor) const = 0; }; struct SaveStateCommand : public Command { void accept(CommandVisitor& visitor) const override; }; struct RestoreStateCommand : public Command { void accept(CommandVisitor& visitor) const override; }; struct SetTransformCommand : public Command { Matrix matrix; explicit SetTransformCommand(const Matrix& m) : matrix(m) {} void accept(CommandVisitor& visitor) const override; }; struct FillRectCommand : public Command { float x, y, width, height; FillRectCommand(float x, float y, float w, float h) : x(x), y(y), width(w), height(h) {} void accept(CommandVisitor& visitor) const override; }; struct DrawTextCommand : public Command { std::string text; float x, y; DrawTextCommand(std::string text, float x, float y) : text(std::move(text)), x(x), y(y) {} void accept(CommandVisitor& visitor) const override; }; struct FillPathCommand : public Command { Path path; explicit FillPathCommand(Path path) : path(std::move(path)) {} void accept(CommandVisitor& visitor) const override; }; struct StrokePathCommand : public Command { Path path; explicit StrokePathCommand(Path path) : path(std::move(path)) {} void accept(CommandVisitor& visitor) const override; }; struct DrawImageCommand : public Command { ImageInfo image; Matrix matrix; float opacity; DrawImageCommand(ImageInfo img, Matrix m, float op = 1.0f) : image(std::move(img)), matrix(m), opacity(op) {} void accept(CommandVisitor& visitor) const override; }; class CommandVisitor { public: virtual ~CommandVisitor() = default; virtual void visit(const SaveStateCommand& cmd) = 0; virtual void visit(const RestoreStateCommand& cmd) = 0; virtual void visit(const SetTransformCommand& cmd) = 0; virtual void visit(const FillRectCommand& cmd) = 0; virtual void visit(const DrawTextCommand& cmd) = 0; virtual void visit(const FillPathCommand& cmd) = 0; virtual void visit(const StrokePathCommand& cmd) = 0; virtual void visit(const DrawImageCommand& cmd) = 0; }; class DisplayList { public: DisplayList() = default; void addCommand(std::unique_ptr cmd); void replay(CommandVisitor& visitor) const; void saveState(); void restoreState(); void setTransform(const Matrix& m); void fillRect(float x, float y, float w, float h); void drawText(const std::string& text, float x, float y); void fillPath(const Path& path); void strokePath(const Path& path); void drawImage(const ImageInfo& image, const Matrix& m, float opacity = 1.0f); [[nodiscard]] size_t size() const noexcept { return m_commands.size(); } void clear() { m_commands.clear(); } private: std::vector> m_commands; }; }