blob: 5b9de05fdbf1d47eed55d01c7e7aae19596a149e [file] [log] [blame]
//========================================================================
//
// 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; }
GBool upsideDown() override { return gTrue; }
GBool useDrawChar() override { return gTrue; }
GBool interpretType3Chars() override { return gFalse; }
GBool needNonText() override { return gFalse; }
GBool needCharCount() override { return gFalse; }
void startPage(int pageNum, GfxState *state, XRef *xref) override;
void endPage() override;
void drawChar(GfxState *state,
double xx, double yy,
double dx, double dy,
double ox, double oy,
CharCode c, int nBytes,
Unicode *u, int uLen) override;
void beginMarkedContent(char *name, Dict *properties) override;
void endMarkedContent(GfxState *state) override;
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 */