//========================================================================
//
// TextOutputDev.h
//
// Copyright 1997-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005-2007 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk>
// Copyright (C) 2007, 2008, 2011, 2013 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2007, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2008, 2010, 2015, 2016, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Brian Ewins <brian.ewins@gmail.com>
// Copyright (C) 2012, 2013, 2015, 2016 Jason Crain <jason@aquaticape.us>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Sanchit Anand <sanxchit@gmail.com>
// Copyright (C) 2018 Nelson Benítez León <nbenitezl@gmail.com>
// Copyright (C) 2019 Oliver Sander <oliver.sander@tu-dresden.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef TEXTOUTPUTDEV_H
#define TEXTOUTPUTDEV_H

#include "poppler-config.h"
#include <stdio.h>
#include "GfxFont.h"
#include "GfxState.h"
#include "OutputDev.h"

class GooString;
class Gfx;
class GfxFont;
class GfxState;
class UnicodeMap;
class AnnotLink;

class TextWord;
class TextPool;
class TextLine;
class TextLineFrag;
class TextBlock;
class TextFlow;
class TextLink;
class TextUnderline;
class TextWordList;
class TextPage;
class TextSelectionVisitor;

//------------------------------------------------------------------------

typedef void (*TextOutputFunc)(void *stream, const char *text, int len);

enum SelectionStyle {
  selectionStyleGlyph,
  selectionStyleWord,
  selectionStyleLine
};

//------------------------------------------------------------------------
// TextFontInfo
//------------------------------------------------------------------------

class TextFontInfo {
public:

  TextFontInfo(GfxState *state);
  ~TextFontInfo();

  TextFontInfo(const TextFontInfo &) = delete;
  TextFontInfo& operator=(const TextFontInfo &) = delete;

  bool matches(GfxState *state) const;
  bool matches(const TextFontInfo *fontInfo) const;

  // Get the font ascent, or a default value if the font is not set
  double getAscent() const;

  // Get the font descent, or a default value if the font is not set
  double getDescent() const;

  // Get the writing mode (0 or 1), or 0 if the font is not set
  int getWMode() const;

#ifdef TEXTOUT_WORD_LIST
  // Get the font name (which may be NULL).
  const GooString *getFontName() const { return fontName; }

  // Get font descriptor flags.
  bool isFixedWidth() const { return flags & fontFixedWidth; }
  bool isSerif() const { return flags & fontSerif; }
  bool isSymbolic() const { return flags & fontSymbolic; }
  bool isItalic() const { return flags & fontItalic; }
  bool isBold() const { return flags & fontBold; }
#endif

private:

  GfxFont *gfxFont;
#ifdef TEXTOUT_WORD_LIST
  GooString *fontName;
  int flags;
#endif

  friend class TextWord;
  friend class TextPage;
  friend class TextSelectionPainter;
};

//------------------------------------------------------------------------
// TextWord
//------------------------------------------------------------------------

class TextWord {
public:

  // Constructor.
  TextWord(const GfxState *state, int rotA, double fontSize);

  // Destructor.
  ~TextWord();

  TextWord(const TextWord &) = delete;
  TextWord& operator=(const TextWord &) = delete;

  // Add a character to the word.
  void addChar(GfxState *state, TextFontInfo *fontA, double x, double y,
	       double dx, double dy, int charPosA, int charLen,
	       CharCode c, Unicode u, const Matrix &textMatA);

  // Attempt to add a character to the word as a combining character.
  // Either character u or the last character in the word must be an
  // acute, dieresis, or other combining character.  Returns true if
  // the character was added.
  bool addCombining(GfxState *state, TextFontInfo *fontA, double fontSizeA, double x, double y,
		     double dx, double dy, int charPosA, int charLen,
		     CharCode c, Unicode u, const Matrix &textMatA);

  // Merge <word> onto the end of <this>.
  void merge(TextWord *word);

  // Compares <this> to <word>, returning -1 (<), 0 (=), or +1 (>),
  // based on a primary-axis comparison, e.g., x ordering if rot=0.
  int primaryCmp(TextWord *word);

  // Return the distance along the primary axis between <this> and
  // <word>.
  double primaryDelta(TextWord *word);

  static int cmpYX(const void *p1, const void *p2);

  void visitSelection(TextSelectionVisitor *visitor,
		      PDFRectangle *selection,
		      SelectionStyle style);

  // Get the TextFontInfo object associated with a character.
  TextFontInfo *getFontInfo(int idx) { return font[idx]; }

  // Get the next TextWord on the linked list.
  TextWord *getNext() { return next; }

#ifdef TEXTOUT_WORD_LIST
  int getLength() { return len; }
  const Unicode *getChar(int idx) { return &text[idx]; }
  GooString *getText();
  GooString *getFontName(int idx) { return font[idx]->fontName; }
  void getColor(double *r, double *g, double *b)
    { *r = colorR; *g = colorG; *b = colorB; }
  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
    { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
  void getCharBBox(int charIdx, double *xMinA, double *yMinA,
		   double *xMaxA, double *yMaxA);
  double getFontSize() { return fontSize; }
  int getRotation() { return rot; }
  int getCharPos() { return charPos[0]; }
  int getCharLen() { return charPos[len] - charPos[0]; }
  bool getSpaceAfter() { return spaceAfter; }
#endif
  bool isUnderlined() { return underlined; }
  AnnotLink *getLink() { return link; }
  double getEdge(int i) { return edge[i]; }
  double getBaseline () { return base; }
  bool hasSpaceAfter  () { return spaceAfter; }
  TextWord* nextWord () { return next; };
private:
  void ensureCapacity(int capacity);
  void setInitialBounds(TextFontInfo *fontA, double x, double y);

  int rot;			// rotation, multiple of 90 degrees
				//   (0, 1, 2, or 3)
  int wMode;			// horizontal (0) or vertical (1) writing mode
  double xMin, xMax;		// bounding box x coordinates
  double yMin, yMax;		// bounding box y coordinates
  double base;			// baseline x or y coordinate
  Unicode *text;		// the text
  CharCode *charcode;		// glyph indices
  double *edge;			// "near" edge x or y coord of each char
				//   (plus one extra entry for the last char)
  int *charPos;			// character position (within content stream)
				//   of each char (plus one extra entry for
				//   the last char)
  int len;			// length of text/edge/charPos/font arrays
  int size;			// size of text/edge/charPos/font arrays
  TextFontInfo **font;		// font information for each char
  Matrix *textMat;		// transformation matrix for each char
  double fontSize;		// font size
  bool spaceAfter;		// set if there is a space between this
				//   word and the next word on the line
  bool underlined;
  TextWord *next;		// next word in line

#ifdef TEXTOUT_WORD_LIST
  double colorR,		// word color
         colorG,
         colorB;
#endif

  AnnotLink *link;

  friend class TextPool;
  friend class TextLine;
  friend class TextBlock;
  friend class TextFlow;
  friend class TextWordList;
  friend class TextPage;

  friend class TextSelectionPainter;
  friend class TextSelectionDumper;
};

//------------------------------------------------------------------------
// TextPool
//------------------------------------------------------------------------

class TextPool {
public:

  TextPool();
  ~TextPool();

  TextPool(const TextPool &) = delete;
  TextPool& operator=(const TextPool &) = delete;

  TextWord *getPool(int baseIdx) { return pool[baseIdx - minBaseIdx]; }
  void setPool(int baseIdx, TextWord *p) { pool[baseIdx - minBaseIdx] = p; }

  int getBaseIdx(double base);

  void addWord(TextWord *word);

private:

  int minBaseIdx;		// min baseline bucket index
  int maxBaseIdx;		// max baseline bucket index
  TextWord **pool;		// array of linked lists, one for each
				//   baseline value (multiple of 4 pts)
  TextWord *cursor;		// pointer to last-accessed word
  int cursorBaseIdx;		// baseline bucket index of last-accessed word

  friend class TextBlock;
  friend class TextPage;
};

struct TextFlowData;

//------------------------------------------------------------------------
// TextLine
//------------------------------------------------------------------------

class TextLine {
public:

  TextLine(TextBlock *blkA, int rotA, double baseA);
  ~TextLine();

  TextLine(const TextLine &) = delete;
  TextLine& operator=(const TextLine &) = delete;

  void addWord(TextWord *word);

  // Return the distance along the primary axis between <this> and
  // <line>.
  double primaryDelta(TextLine *line);

  // Compares <this> to <line>, returning -1 (<), 0 (=), or +1 (>),
  // based on a primary-axis comparison, e.g., x ordering if rot=0.
  int primaryCmp(TextLine *line);

  // Compares <this> to <line>, returning -1 (<), 0 (=), or +1 (>),
  // based on a secondary-axis comparison of the baselines, e.g., y
  // ordering if rot=0.
  int secondaryCmp(TextLine *line);

  int cmpYX(TextLine *line);

  static int cmpXY(const void *p1, const void *p2);

  void coalesce(UnicodeMap *uMap);

  void visitSelection(TextSelectionVisitor *visitor,
		      PDFRectangle *selection,
		      SelectionStyle style);

  // Get the head of the linked list of TextWords.
  TextWord *getWords() { return words; }

  // Get the next TextLine on the linked list.
  TextLine *getNext() { return next; }

  // Returns true if the last char of the line is a hyphen.
  bool isHyphenated() { return hyphenated; }

private:

  TextBlock *blk;		// parent block
  int rot;			// text rotation
  double xMin, xMax;		// bounding box x coordinates
  double yMin, yMax;		// bounding box y coordinates
  double base;			// baseline x or y coordinate
  TextWord *words;		// words in this line
  TextWord *lastWord;		// last word in this line
  Unicode *text;		// Unicode text of the line, including
				//   spaces between words
  double *edge;			// "near" edge x or y coord of each char
				//   (plus one extra entry for the last char)
  int *col;			// starting column number of each Unicode char
  int len;			// number of Unicode chars
  int convertedLen;		// total number of converted characters
  bool hyphenated;		// set if last char is a hyphen
  TextLine *next;		// next line in block
  Unicode *normalized;		// normalized form of Unicode text
  int normalized_len;		// number of normalized Unicode chars
  int *normalized_idx;		// indices of normalized chars into Unicode text
  Unicode *ascii_translation;	// ascii translation from the normalized text
  int ascii_len;		// length of ascii translation text
  int *ascii_idx;		// indices of ascii chars into Unicode text of line

  friend class TextLineFrag;
  friend class TextBlock;
  friend class TextFlow;
  friend class TextWordList;
  friend class TextPage;

  friend class TextSelectionPainter;
  friend class TextSelectionSizer;
  friend class TextSelectionDumper;
};

//------------------------------------------------------------------------
// TextBlock
//------------------------------------------------------------------------

class TextBlock {
public:

  TextBlock(TextPage *pageA, int rotA);
  ~TextBlock();

  TextBlock(const TextBlock &) = delete;
  TextBlock& operator=(const TextBlock &) = delete;

  void addWord(TextWord *word);

  void coalesce(UnicodeMap *uMap, double fixedPitch);

  // Update this block's priMin and priMax values, looking at <blk>.
  void updatePriMinMax(TextBlock *blk);

  static int cmpXYPrimaryRot(const void *p1, const void *p2);

  static int cmpYXPrimaryRot(const void *p1, const void *p2);

  int primaryCmp(TextBlock *blk);

  double secondaryDelta(TextBlock *blk);

  // Returns true if <this> is below <blk>, relative to the page's
  // primary rotation.
  bool isBelow(TextBlock *blk);

  void visitSelection(TextSelectionVisitor *visitor,
		      PDFRectangle *selection,
		      SelectionStyle style);

  // Get the head of the linked list of TextLines.
  TextLine *getLines() { return lines; }

  // Get the next TextBlock on the linked list.
  TextBlock *getNext() { return next; }

  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
    { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }

  int getLineCount() { return nLines; }

private:

  bool isBeforeByRule1(TextBlock *blk1);
  bool isBeforeByRepeatedRule1(TextBlock *blkList, TextBlock *blk1);
  bool isBeforeByRule2(TextBlock *blk1);

  int visitDepthFirst(TextBlock *blkList, int pos1,
		      TextBlock **sorted, int sortPos,
		      bool* visited);
  int visitDepthFirst(TextBlock *blkList, int pos1,
		      TextBlock **sorted, int sortPos,
		      bool* visited,
		      TextBlock **cache, int cacheSize);

  TextPage *page;		// the parent page
  int rot;			// text rotation
  double xMin, xMax;		// bounding box x coordinates
  double yMin, yMax;		// bounding box y coordinates
  double priMin, priMax;	// whitespace bounding box along primary axis
  double ExMin, ExMax;		// extended bounding box x coordinates
  double EyMin, EyMax;		// extended bounding box y coordinates
  int tableId;			// id of table to which this block belongs
  bool tableEnd;		// is this block at end of line of actual table

  TextPool *pool;		// pool of words (used only until lines
				//   are built)
  TextLine *lines;		// linked list of lines
  TextLine *curLine;		// most recently added line
  int nLines;			// number of lines
  int charCount;		// number of characters in the block
  int col;			// starting column
  int nColumns;			// number of columns in the block

  TextBlock *next;
  TextBlock *stackNext;

  friend class TextLine;
  friend class TextLineFrag;
  friend class TextFlow;
  friend class TextWordList;
  friend class TextPage;
  friend class TextSelectionPainter;
  friend class TextSelectionDumper;
};

//------------------------------------------------------------------------
// TextFlow
//------------------------------------------------------------------------

class TextFlow {
public:

  TextFlow(TextPage *pageA, TextBlock *blk);
  ~TextFlow();

  TextFlow(const TextFlow &) = delete;
  TextFlow& operator=(const TextFlow &) = delete;

  // Add a block to the end of this flow.
  void addBlock(TextBlock *blk);

  // Returns true if <blk> fits below <prevBlk> in the flow, i.e., (1)
  // it uses a font no larger than the last block added to the flow,
  // and (2) it fits within the flow's [priMin, priMax] along the
  // primary axis.
  bool blockFits(TextBlock *blk, TextBlock *prevBlk);

  // Get the head of the linked list of TextBlocks.
  TextBlock *getBlocks() { return blocks; }

  // Get the next TextFlow on the linked list.
  TextFlow *getNext() { return next; }

private:

  TextPage *page;		// the parent page
  double xMin, xMax;		// bounding box x coordinates
  double yMin, yMax;		// bounding box y coordinates
  double priMin, priMax;	// whitespace bounding box along primary axis
  TextBlock *blocks;		// blocks in flow
  TextBlock *lastBlk;		// last block in this flow
  TextFlow *next;

  friend class TextWordList;
  friend class TextPage;
};

#ifdef TEXTOUT_WORD_LIST

//------------------------------------------------------------------------
// TextWordList
//------------------------------------------------------------------------

class TextWordList {
public:

  // Build a flat word list, in content stream order (if
  // text->rawOrder is true), physical layout order (if <physLayout>
  // is true and text->rawOrder is false), or reading order (if both
  // flags are false).
  TextWordList(TextPage *text, bool physLayout);

  ~TextWordList();

  TextWordList(const TextWordList &) = delete;
  TextWordList& operator=(const TextWordList &) = delete;

  // Return the number of words on the list.
  int getLength();

  // Return the <idx>th word from the list.
  TextWord *get(int idx);

private:

  std::vector<TextWord*> *words;
};

#endif // TEXTOUT_WORD_LIST

class TextWordSelection {
public:
  TextWordSelection(TextWord *wordA, int beginA, int endA)
    : word(wordA), begin(beginA), end(endA)
  {
  }

  TextWord * getWord() const { return word; }
  int getBegin() const { return begin; }
  int getEnd() const { return end; }

private:
  TextWord *word;
  int begin;
  int end;

  friend class TextSelectionPainter;
  friend class TextSelectionDumper;
};

//------------------------------------------------------------------------
// TextPage
//------------------------------------------------------------------------

class TextPage {
public:

  // Constructor.
  TextPage(bool rawOrderA);

  TextPage(const TextPage &) = delete;
  TextPage& operator=(const TextPage &) = delete;

  void incRefCnt();
  void decRefCnt();

  // Start a new page.
  void startPage(GfxState *state);

  // End the current page.
  void endPage();

  // Update the current font.
  void updateFont(GfxState *state);

  // Begin a new word.
  void beginWord(GfxState *state);

  // Add a character to the current word.
  void addChar(GfxState *state, double x, double y,
	       double dx, double dy,
	       CharCode c, int nBytes, Unicode *u, int uLen);

  // Add <nChars> invisible characters.
  void incCharCount(int nChars);

  // End the current word, sorting it into the list of words.
  void endWord();

  // Add a word, sorting it into the list of words.
  void addWord(TextWord *word);

  // Add a (potential) underline.
  void addUnderline(double x0, double y0, double x1, double y1);

  // Add a hyperlink.
  void addLink(int xMin, int yMin, int xMax, int yMax, AnnotLink *link);

  // Coalesce strings that look like parts of the same line.
  void coalesce(bool physLayout, double fixedPitch, bool doHTML);

  // Find a string.  If <startAtTop> is true, starts looking at the
  // top of the page; else if <startAtLast> is true, starts looking
  // immediately after the last find result; else starts looking at
  // <xMin>,<yMin>.  If <stopAtBottom> is true, stops looking at the
  // bottom of the page; else if <stopAtLast> is true, stops looking
  // just before the last find result; else stops looking at
  // <xMax>,<yMax>.
  bool findText(Unicode *s, int len,
		 bool startAtTop, bool stopAtBottom,
		 bool startAtLast, bool stopAtLast,
		 bool caseSensitive, bool backward,
		 bool wholeWord,
		 double *xMin, double *yMin,
		 double *xMax, double *yMax);

  // Adds new parameter ignoreDiacritics, which will do diacritics
  // insensitive search, i.e. ignore accents, umlauts, diaeresis,etc.
  // while matching. This option will be ignored if <s> contains characters
  // which are not pure ascii.
  bool findText(Unicode *s, int len,
		 bool startAtTop, bool stopAtBottom,
		 bool startAtLast, bool stopAtLast,
		 bool caseSensitive, bool ignoreDiacritics,
		 bool backward, bool wholeWord,
		 double *xMin, double *yMin,
		 double *xMax, double *yMax);

  // Get the text which is inside the specified rectangle.
  GooString *getText(double xMin, double yMin,
		     double xMax, double yMax);

  void visitSelection(TextSelectionVisitor *visitor,
		      PDFRectangle *selection,
		      SelectionStyle style);

  void drawSelection(OutputDev *out,
		     double scale,
		     int rotation,
		     PDFRectangle *selection,
		     SelectionStyle style,
		     GfxColor *glyph_color, GfxColor *box_color);

  std::vector<PDFRectangle*> *getSelectionRegion(PDFRectangle *selection,
			      SelectionStyle style,
			      double scale);

  GooString *getSelectionText(PDFRectangle *selection,
			      SelectionStyle style);

  std::vector<TextWordSelection*> **getSelectionWords(PDFRectangle *selection,
                              SelectionStyle style,
                              int *nLines);

  // Find a string by character position and length.  If found, sets
  // the text bounding rectangle and returns true; otherwise returns
  // false.
  bool findCharRange(int pos, int length,
		      double *xMin, double *yMin,
		      double *xMax, double *yMax);

  // Dump contents of page to a file.
  void dump(void *outputStream, TextOutputFunc outputFunc,
	    bool physLayout);

  // Get the head of the linked list of TextFlows.
  TextFlow *getFlows() { return flows; }

  // If true, will combine characters when a base and combining
  // character are drawn on eachother.
  void setMergeCombining(bool merge);

#ifdef TEXTOUT_WORD_LIST
  // Build a flat word list, in content stream order (if
  // this->rawOrder is true), physical layout order (if <physLayout>
  // is true and this->rawOrder is false), or reading order (if both
  // flags are false).
  TextWordList *makeWordList(bool physLayout);
#endif

private:
  
  // Destructor.
  ~TextPage();
  
  void clear();
  void assignColumns(TextLineFrag *frags, int nFrags, bool rot);
  int dumpFragment(Unicode *text, int len, UnicodeMap *uMap, GooString *s);

  bool rawOrder;		// keep text in content stream order
  bool mergeCombining;		// merge when combining and base characters
				// are drawn on top of each other

  double pageWidth, pageHeight;	// width and height of current page
  TextWord *curWord;		// currently active string
  int charPos;			// next character position (within content
				//   stream)
  TextFontInfo *curFont;	// current font
  double curFontSize;		// current font size
  int nest;			// current nesting level (for Type 3 fonts)
  int nTinyChars;		// number of "tiny" chars seen so far
  bool lastCharOverlap;	// set if the last added char overlapped the
				//   previous char

  TextPool *pools[4];		// a "pool" of TextWords for each rotation
  TextFlow *flows;		// linked list of flows
  TextBlock **blocks;		// array of blocks, in yx order
  int nBlocks;			// number of blocks
  int primaryRot;		// primary rotation
  bool primaryLR;		// primary direction (true means L-to-R,
				//   false means R-to-L)
  TextWord *rawWords;		// list of words, in raw order (only if
				//   rawOrder is set)
  TextWord *rawLastWord;	// last word on rawWords list

  std::vector<TextFontInfo*> *fonts;// all font info objects used on this page

  double lastFindXMin,		// coordinates of the last "find" result
         lastFindYMin;
  bool haveLastFind;

  std::vector<TextUnderline*> *underlines;
  std::vector<TextLink*> *links;

  int refCnt;

  friend class TextLine;
  friend class TextLineFrag;
  friend class TextBlock;
  friend class TextFlow;
  friend class TextWordList;
  friend class TextSelectionPainter;
  friend class TextSelectionDumper;
};

//------------------------------------------------------------------------
// ActualText
//------------------------------------------------------------------------

class ActualText {
public:
  // Create an ActualText
  ActualText(TextPage *out);
  ~ActualText();

  ActualText(const ActualText &) = delete;
  ActualText& operator=(const ActualText &) = delete;

  void addChar(GfxState *state, double x, double y,
	       double dx, double dy,
	       CharCode c, int nBytes, Unicode *u, int uLen);
  void begin(GfxState *state, const GooString *text);
  void end(GfxState *state);

private:
  TextPage *text;

  GooString *actualText;        // replacement text for the span
  double actualTextX0;
  double actualTextY0;
  double actualTextX1;
  double actualTextY1;
  int actualTextNBytes;
};
  

//------------------------------------------------------------------------
// TextOutputDev
//------------------------------------------------------------------------

class TextOutputDev: public OutputDev {
public:

  // Open a text output file.  If <fileName> is NULL, no file is
  // written (this is useful, e.g., for searching text).  If
  // <physLayoutA> is true, the original physical layout of the text
  // is maintained.  If <rawOrder> is true, the text is kept in
  // content stream order.
  TextOutputDev(const char *fileName, bool physLayoutA,
		double fixedPitchA, bool rawOrderA,
		bool append);

  // Create a TextOutputDev which will write to a generic stream.  If
  // <physLayoutA> is true, the original physical layout of the text
  // is maintained.  If <rawOrder> is true, the text is kept in
  // content stream order.
  TextOutputDev(TextOutputFunc func, void *stream,
		bool physLayoutA, double fixedPitchA,
		bool rawOrderA);

  // Destructor.
  ~TextOutputDev();

  // Check if file was successfully created.
  virtual bool isOk() { return ok; }

  //---- get info about output device

  // Does this device use upside-down coordinates?
  // (Upside-down means (0,0) is the top left corner of the page.)
  bool upsideDown() override { return true; }

  // Does this device use drawChar() or drawString()?
  bool useDrawChar() override { return true; }

  // Does this device use beginType3Char/endType3Char?  Otherwise,
  // text in Type 3 fonts will be drawn with drawChar/drawString.
  bool interpretType3Chars() override { return false; }

  // Does this device need non-text content?
  bool needNonText() override { return false; }

  // Does this device require incCharCount to be called for text on
  // non-shown layers?
  bool needCharCount() override { return true; }

  //----- initialization and control

  // Start a page.
  void startPage(int pageNum, GfxState *state, XRef *xref) override;

  // End a page.
  void endPage() override;

  //----- save/restore graphics state
  void restoreState(GfxState *state) override;

  //----- update text state
  void updateFont(GfxState *state) override;

  //----- text drawing
  void beginString(GfxState *state, const GooString *s) override;
  void endString(GfxState *state) override;
  void drawChar(GfxState *state, double x, double y,
		double dx, double dy,
		double originX, double originY,
		CharCode c, int nBytes, Unicode *u, int uLen) override;
  void incCharCount(int nChars) override;
  void beginActualText(GfxState *state, const GooString *text) override;
  void endActualText(GfxState *state) override;

  //----- path painting
  void stroke(GfxState *state) override;
  void fill(GfxState *state) override;
  void eoFill(GfxState *state) override;

  //----- link borders
  void processLink(AnnotLink *link) override;

  //----- special access

  // Find a string.  If <startAtTop> is true, starts looking at the
  // top of the page; else if <startAtLast> is true, starts looking
  // immediately after the last find result; else starts looking at
  // <xMin>,<yMin>.  If <stopAtBottom> is true, stops looking at the
  // bottom of the page; else if <stopAtLast> is true, stops looking
  // just before the last find result; else stops looking at
  // <xMax>,<yMax>.
  bool findText(Unicode *s, int len,
		 bool startAtTop, bool stopAtBottom,
		 bool startAtLast, bool stopAtLast,
		 bool caseSensitive, bool backward,
		 bool wholeWord,
		 double *xMin, double *yMin,
		 double *xMax, double *yMax);

  // Get the text which is inside the specified rectangle.
  GooString *getText(double xMin, double yMin,
		   double xMax, double yMax);

  // Find a string by character position and length.  If found, sets
  // the text bounding rectangle and returns true; otherwise returns
  // false.
  bool findCharRange(int pos, int length,
		      double *xMin, double *yMin,
		      double *xMax, double *yMax);

  void drawSelection(OutputDev *out, double scale, int rotation,
		     PDFRectangle *selection,
		     SelectionStyle style,
		     GfxColor *glyph_color, GfxColor *box_color);

  std::vector<PDFRectangle*> *getSelectionRegion(PDFRectangle *selection,
			      SelectionStyle style,
			      double scale);

  GooString *getSelectionText(PDFRectangle *selection,
			      SelectionStyle style);

  // If true, will combine characters when a base and combining
  // character are drawn on eachother.
  void setMergeCombining(bool merge);

#ifdef TEXTOUT_WORD_LIST
  // Build a flat word list, in content stream order (if
  // this->rawOrder is true), physical layout order (if
  // this->physLayout is true and this->rawOrder is false), or reading
  // order (if both flags are false).
  TextWordList *makeWordList();
#endif

  // Returns the TextPage object for the last rasterized page,
  // transferring ownership to the caller.
  TextPage *takeText();

  // Turn extra processing for HTML conversion on or off.
  void enableHTMLExtras(bool doHTMLA) { doHTML = doHTMLA; }

  // Get the head of the linked list of TextFlows for the
  // last rasterized page.
  TextFlow *getFlows();

private:

  TextOutputFunc outputFunc;	// output function
  void *outputStream;		// output stream
  bool needClose;		// need to close the output file?
				//   (only if outputStream is a FILE*)
  TextPage *text;		// text for the current page
  bool physLayout;		// maintain original physical layout when
				//   dumping text
  double fixedPitch;		// if physLayout is true and this is non-zero,
				//   assume fixed-pitch characters with this
				//   width
  bool rawOrder;		// keep text in content stream order
  bool doHTML;			// extra processing for HTML conversion
  bool ok;			// set up ok?

  ActualText *actualText;
};

#endif
