//======================================================================== // // MarkedContentOutputDev.h // // This file is licensed under the GPLv2 or later // // Copyright 2013 Igalia S.L. // Copyright 2018-2021, 2024, 2025 Albert Astals Cid // Copyright 2021, 2023 Adrian Johnson // Copyright 2022 Oliver Sander // Copyright 2025 g10 Code GmbH, Author: Sune Stolborg Vuorela // Copyright 2026 Stefan BrĂ¼ns // //======================================================================== #ifndef MARKEDCONTENTOUTPUTDEV_H #define MARKEDCONTENTOUTPUTDEV_H #include "poppler_private_export.h" #include "OutputDev.h" #include "GfxState.h" #include "GfxFont.h" #include class Dict; class UnicodeMap; class TextSpan { public: TextSpan(const TextSpan &other) = default; TextSpan &operator=(const TextSpan &other) = default; ~TextSpan() = default; const std::shared_ptr &getFont() const { return data->font; } const GooString *getText() const { return data->text.get(); } GfxRGB &getColor() const { return data->color; } private: // Note: Takes ownership of strings, increases refcount for font. TextSpan(std::unique_ptr text, std::shared_ptr font, const GfxRGB color) : data(std::make_shared()) { data->text = std::move(text); data->font = std::move(font); data->color = color; } struct Data { std::shared_ptr font; std::unique_ptr text; GfxRGB color; Data() = default; ~Data() = default; Data(const Data &) = delete; Data &operator=(const Data &) = delete; }; std::shared_ptr data; friend class MarkedContentOutputDev; }; using TextSpanArray = std::vector; class POPPLER_PRIVATE_EXPORT MarkedContentOutputDev : public OutputDev { public: explicit MarkedContentOutputDev(int mcidA, const Object &stmObj); ~MarkedContentOutputDev() override; virtual bool isOk() { return true; } bool upsideDown() override { return true; } bool useDrawChar() override { return true; } bool interpretType3Chars() override { return false; } bool needNonText() override { return false; } bool needCharCount() override { return false; } void startPage(int pageNum, GfxState *state, XRef *xref) override; void endPage() override; void beginForm(Object * /* obj */, Ref id) override; void endForm(Object * /* obj */, Ref id) override; void drawChar(GfxState *state, double xx, double yy, double dx, double dy, double ox, double oy, CharCode c, int nBytes, const Unicode *u, int uLen) override; void beginMarkedContent(const std::string &name, Dict *properties) override; void endMarkedContent(GfxState *state) override; const TextSpanArray &getTextSpans() const; private: void endSpan(); bool inMarkedContent() const { return !mcidStack.empty(); } bool contentStreamMatch(); bool needFontChange(const std::shared_ptr &font) const; std::shared_ptr currentFont; std::unique_ptr currentText; GfxRGB currentColor; TextSpanArray textSpans; int mcid; std::vector mcidStack; std::vector formStack; double pageWidth = 0.0; double pageHeight = 0.0; const UnicodeMap *unicodeMap = nullptr; Object stmRef; }; #endif /* !MARKEDCONTENTOUTPUTDEV_H */