1//========================================================================
2//
3// MarkedContentOutputDev.h
4//
5// This file is licensed under the GPLv2 or later
6//
7// Copyright 2013 Igalia S.L.
8// Copyright 2018-2021 Albert Astals Cid <aacid@kde.org>
9// Copyright 2021, 2023 Adrian Johnson <ajohnson@redneon.com>
10// Copyright 2022 Oliver Sander <oliver.sander@tu-dresden.de>
11//
12//========================================================================
13
14#ifndef MARKEDCONTENTOUTPUTDEV_H
15#define MARKEDCONTENTOUTPUTDEV_H
16
17#include "goo/gmem.h"
18#include "poppler_private_export.h"
19#include "OutputDev.h"
20#include "GfxState.h"
21#include "GfxFont.h"
22#include <vector>
23
24class Dict;
25class UnicodeMap;
26
27class TextSpan
28{
29public:
30 TextSpan(const TextSpan &other) : data(other.data) { data->refcount++; }
31
32 TextSpan &operator=(const TextSpan &other)
33 {
34 if (this != &other) {
35 data = other.data;
36 data->refcount++;
37 }
38 return *this;
39 }
40
41 ~TextSpan()
42 {
43 if (data && --data->refcount == 0) {
44 delete data;
45 }
46 }
47
48 const std::shared_ptr<GfxFont> &getFont() const { return data->font; }
49 GooString *getText() const { return data->text; }
50 GfxRGB &getColor() const { return data->color; }
51
52private:
53 // Note: Takes ownership of strings, increases refcount for font.
54 TextSpan(GooString *text, std::shared_ptr<GfxFont> font, const GfxRGB color) : data(new Data)
55 {
56 data->text = text;
57 data->font = std::move(font);
58 data->color = color;
59 }
60
61 struct Data
62 {
63 std::shared_ptr<GfxFont> font;
64 GooString *text;
65 GfxRGB color;
66 unsigned refcount;
67
68 Data() : refcount(1) { }
69
70 ~Data()
71 {
72 assert(refcount == 0);
73 delete text;
74 }
75
76 Data(const Data &) = delete;
77 Data &operator=(const Data &) = delete;
78 };
79
80 Data *data;
81
82 friend class MarkedContentOutputDev;
83};
84
85typedef std::vector<TextSpan> TextSpanArray;
86
87class POPPLER_PRIVATE_EXPORT MarkedContentOutputDev : public OutputDev
88{
89public:
90 explicit MarkedContentOutputDev(int mcidA, const Object &stmObj);
91 ~MarkedContentOutputDev() override;
92
93 virtual bool isOk() { return true; }
94 bool upsideDown() override { return true; }
95 bool useDrawChar() override { return true; }
96 bool interpretType3Chars() override { return false; }
97 bool needNonText() override { return false; }
98 bool needCharCount() override { return false; }
99
100 void startPage(int pageNum, GfxState *state, XRef *xref) override;
101 void endPage() override;
102
103 void beginForm(Object * /* obj */, Ref id) override;
104 void endForm(Object * /* obj */, Ref id) override;
105
106 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;
107
108 void beginMarkedContent(const char *name, Dict *properties) override;
109 void endMarkedContent(GfxState *state) override;
110
111 const TextSpanArray &getTextSpans() const;
112
113private:
114 void endSpan();
115 bool inMarkedContent() const { return mcidStack.size() > 0; }
116 bool contentStreamMatch();
117 bool needFontChange(const std::shared_ptr<const GfxFont> &font) const;
118
119 std::shared_ptr<GfxFont> currentFont;
120 GooString *currentText;
121 GfxRGB currentColor;
122 TextSpanArray textSpans;
123 int mcid;
124 std::vector<int> mcidStack;
125 std::vector<Ref> formStack;
126 double pageWidth;
127 double pageHeight;
128 const UnicodeMap *unicodeMap;
129 Object stmRef;
130};
131
132#endif /* !MARKEDCONTENTOUTPUTDEV_H */
133

source code of poppler/poppler/MarkedContentOutputDev.h