File indexing completed on 2025-12-10 10:23:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef MARKEDCONTENTOUTPUTDEV_H
0015 #define MARKEDCONTENTOUTPUTDEV_H
0016
0017 #include "goo/gmem.h"
0018 #include "poppler_private_export.h"
0019 #include "OutputDev.h"
0020 #include "GfxState.h"
0021 #include "GfxFont.h"
0022 #include <vector>
0023
0024 class Dict;
0025 class UnicodeMap;
0026
0027 class TextSpan
0028 {
0029 public:
0030 TextSpan(const TextSpan &other) : data(other.data) { data->refcount++; }
0031
0032 TextSpan &operator=(const TextSpan &other)
0033 {
0034 if (this != &other) {
0035 data = other.data;
0036 data->refcount++;
0037 }
0038 return *this;
0039 }
0040
0041 ~TextSpan()
0042 {
0043 if (data && --data->refcount == 0) {
0044 delete data;
0045 }
0046 }
0047
0048 const std::shared_ptr<GfxFont> &getFont() const { return data->font; }
0049 GooString *getText() const { return data->text; }
0050 GfxRGB &getColor() const { return data->color; }
0051
0052 private:
0053
0054 TextSpan(GooString *text, std::shared_ptr<GfxFont> font, const GfxRGB color) : data(new Data)
0055 {
0056 data->text = text;
0057 data->font = std::move(font);
0058 data->color = color;
0059 }
0060
0061 struct Data
0062 {
0063 std::shared_ptr<GfxFont> font;
0064 GooString *text;
0065 GfxRGB color;
0066 unsigned refcount;
0067
0068 Data() : refcount(1) { }
0069
0070 ~Data()
0071 {
0072 assert(refcount == 0);
0073 delete text;
0074 }
0075
0076 Data(const Data &) = delete;
0077 Data &operator=(const Data &) = delete;
0078 };
0079
0080 Data *data;
0081
0082 friend class MarkedContentOutputDev;
0083 };
0084
0085 typedef std::vector<TextSpan> TextSpanArray;
0086
0087 class POPPLER_PRIVATE_EXPORT MarkedContentOutputDev : public OutputDev
0088 {
0089 public:
0090 explicit MarkedContentOutputDev(int mcidA, const Object &stmObj);
0091 ~MarkedContentOutputDev() override;
0092
0093 virtual bool isOk() { return true; }
0094 bool upsideDown() override { return true; }
0095 bool useDrawChar() override { return true; }
0096 bool interpretType3Chars() override { return false; }
0097 bool needNonText() override { return false; }
0098 bool needCharCount() override { return false; }
0099
0100 void startPage(int pageNum, GfxState *state, XRef *xref) override;
0101 void endPage() override;
0102
0103 void beginForm(Ref id) override;
0104 void endForm(Ref id) override;
0105
0106 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;
0107
0108 void beginMarkedContent(const char *name, Dict *properties) override;
0109 void endMarkedContent(GfxState *state) override;
0110
0111 const TextSpanArray &getTextSpans() const;
0112
0113 private:
0114 void endSpan();
0115 bool inMarkedContent() const { return mcidStack.size() > 0; }
0116 bool contentStreamMatch();
0117 bool needFontChange(const std::shared_ptr<const GfxFont> &font) const;
0118
0119 std::shared_ptr<GfxFont> currentFont;
0120 GooString *currentText;
0121 GfxRGB currentColor;
0122 TextSpanArray textSpans;
0123 int mcid;
0124 std::vector<int> mcidStack;
0125 std::vector<Ref> formStack;
0126 double pageWidth;
0127 double pageHeight;
0128 const UnicodeMap *unicodeMap;
0129 Object stmRef;
0130 };
0131
0132 #endif