summaryrefslogtreecommitdiff
path: root/poppler/MarkedContentOutputDev.h
blob: 4ea60c255a142ea27cbe82b04fff78224546192b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//========================================================================
//
// MarkedContentOutputDev.h
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2013 Igalia S.L.
//
//========================================================================

#ifndef MARKEDCONTENTOUTPUTDEV_H
#define MARKEDCONTENTOUTPUTDEV_H

#include "goo/gtypes.h"
#include "goo/gmem.h"
#include "OutputDev.h"
#include "GfxState.h"
#include "GfxFont.h"
#include <vector>

class Dict;
class UnicodeMap;


class TextSpan {
public:
  TextSpan(const TextSpan& other): data(other.data) {
    data->refcount++;
  }

  TextSpan& operator=(const TextSpan& other) {
    if (this != &other) {
      data = other.data;
      data->refcount++;
    }
    return *this;
  }

  ~TextSpan() {
    if (data && --data->refcount == 0)
      delete data;
  }

  GfxFont* getFont() const { return data->font; }
  GooString* getText() const { return data->text; }
  GfxRGB& getColor() const { return data->color; }

private:
  // Note: Takes ownership of strings, increases refcount for font.
  TextSpan(GooString *text,
           GfxFont *font,
           const GfxRGB& color)
      : data(new Data) {
    data->text = text;
    data->font = font;
    data->color = color;
    if (data->font)
      data->font->incRefCnt();
  }

  struct Data {
    GfxFont   *font;
    GooString *text;
    GfxRGB     color;
    unsigned refcount;

    Data(): refcount(1) {}

    ~Data() {
      assert(refcount == 0);
      if (font)
        font->decRefCnt();
      delete text;
    }
  };

  Data *data;

  friend class MarkedContentOutputDev;
};


typedef std::vector<TextSpan> TextSpanArray;


class MarkedContentOutputDev: public OutputDev {
public:
  MarkedContentOutputDev(int mcidA);
  virtual ~MarkedContentOutputDev();

  virtual GBool isOk() { return gTrue; }
  virtual GBool upsideDown() { return gTrue; }
  virtual GBool useDrawChar() { return gTrue; }
  virtual GBool interpretType3Chars() { return gFalse; }
  virtual GBool needNonText() { return gFalse; }
  virtual GBool needCharCount() { return gFalse; }

  virtual void startPage(int pageNum, GfxState *state, XRef *xref);
  virtual void endPage();

  virtual void drawChar(GfxState *state,
                        double xx, double yy,
                        double dx, double dy,
                        double ox, double oy,
                        CharCode c, int nBytes,
                        Unicode *u, int uLen);

  virtual void beginMarkedContent(char *name, Dict *properties);
  virtual void endMarkedContent(GfxState *state);

  const TextSpanArray& getTextSpans() const;

private:

  void endSpan();
  bool inMarkedContent() const { return mcidStack.size() > 0; }
  bool needFontChange(GfxFont* font) const;

  GfxFont         *currentFont;
  GooString       *currentText;
  GfxRGB           currentColor;
  TextSpanArray    textSpans;
  int              mcid;
  std::vector<int> mcidStack;
  double           pageWidth;
  double           pageHeight;
  UnicodeMap      *unicodeMap;
};

#endif /* !MARKEDCONTENTOUTPUTDEV_H */