//========================================================================
//
// ArthurOutputDev.cc
//
// Copyright 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 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2005-2009, 2011, 2012, 2014, 2015, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2008, 2010 Pino Toscano <pino@kde.org>
// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
// Copyright (C) 2010 Matthias Fauconneau <matthias.fauconneau@gmail.com>
// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2013 Dominik Haumann <dhaumann@kde.org>
// Copyright (C) 2013 Mihai Niculescu <q.quark@gmail.com>
// Copyright (C) 2017, 2018 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
// 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 Adam Reichold <adam.reichold@t-online.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
//
//========================================================================

#include <config.h>

#include <string.h>
#include <math.h>

#include <array>

#include "goo/gfile.h"
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Link.h"
#include "FontEncodingTables.h"
#include <fofi/FoFiTrueType.h>
#include "ArthurOutputDev.h"
#include "Page.h"
#include "Gfx.h"
#include "PDFDoc.h"

#include <QtCore/QtDebug>
#include <QRawFont>
#include <QGlyphRun>
#include <QtGui/QPainterPath>
#include <QPicture>

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

#ifdef HAVE_SPLASH
#include "splash/SplashFontFileID.h"
#include "splash/SplashFTFontFile.h"
#include "splash/SplashFontEngine.h"
//------------------------------------------------------------------------
// SplashOutFontFileID
//------------------------------------------------------------------------

class SplashOutFontFileID: public SplashFontFileID {
public:

  SplashOutFontFileID(const Ref *rA) { r = *rA; }

  ~SplashOutFontFileID() {}

  GBool matches(SplashFontFileID *id) override {
    return ((SplashOutFontFileID *)id)->r.num == r.num &&
           ((SplashOutFontFileID *)id)->r.gen == r.gen;
  }

private:

  Ref r;
};

#endif

class ArthurType3Font
{
public:

  ArthurType3Font(PDFDoc* doc, Gfx8BitFont* font);

  const QPicture& getGlyph(int gid) const;

private:
  PDFDoc* m_doc;
  Gfx8BitFont* m_font;

  mutable std::vector<std::unique_ptr<QPicture> > glyphs;

public:
  std::vector<int> codeToGID;
};

ArthurType3Font::ArthurType3Font(PDFDoc* doc, Gfx8BitFont* font)
: m_doc(doc), m_font(font)
{
  char *name;
  const Dict* charProcs = font->getCharProcs();

  // Storage for the rendered glyphs
  glyphs.resize(charProcs->getLength());

  // Compute the code-to-GID map
  char **enc = font->getEncoding();

  codeToGID.resize(256);

  for (int i = 0; i < 256; ++i) {
    codeToGID[i] = 0;
    if (charProcs && (name = enc[i])) {
      for (int j = 0; j < charProcs->getLength(); j++) {
        if (strcmp(name, charProcs->getKey(j)) == 0) {
          codeToGID[i] = j;
        }
      }
    }
  }
}

const QPicture& ArthurType3Font::getGlyph(int gid) const
{
  if (!glyphs[gid]) {

    // Glyph has not been rendered before: render it now

    // Smallest box that contains all the glyphs from this font
    const double* fontBBox = m_font->getFontBBox();
    PDFRectangle box(fontBBox[0], fontBBox[1], fontBBox[2], fontBBox[3]);

    Dict* resDict = m_font->getResources();

    QPainter glyphPainter;
    glyphs[gid] = std::make_unique<QPicture>();
    glyphPainter.begin(glyphs[gid].get());
    auto output_dev = std::make_unique<ArthurOutputDev>(&glyphPainter);

    auto gfx = std::make_unique<Gfx>(
	  m_doc, output_dev.get(), resDict,
	  &box,  // pagebox
	  nullptr  // cropBox
    );

    output_dev->startDoc(m_doc);

    output_dev->startPage (1, gfx->getState(), gfx->getXRef());

    const Dict* charProcs = m_font->getCharProcs();
    Object charProc = charProcs->getVal(gid);
    gfx->display(&charProc);

    glyphPainter.end();
  }

  return *glyphs[gid];
}


//------------------------------------------------------------------------
// ArthurOutputDev
//------------------------------------------------------------------------

ArthurOutputDev::ArthurOutputDev(QPainter *painter):
  m_lastTransparencyGroupPicture(nullptr),
  m_fontHinting(NoHinting)
{
  m_painter.push(painter);
  m_currentBrush = QBrush(Qt::SolidPattern);
  m_fontEngine = nullptr;
}

ArthurOutputDev::~ArthurOutputDev()
{
#ifdef HAVE_SPLASH
  delete m_fontEngine;
#endif
}

void ArthurOutputDev::startDoc(PDFDoc* doc) {
  xref = doc->getXRef();
  m_doc = doc;
#ifdef HAVE_SPLASH
  delete m_fontEngine;

  const bool isHintingEnabled = m_fontHinting != NoHinting;
  const bool isSlightHinting = m_fontHinting == SlightHinting;

  m_fontEngine = new SplashFontEngine(
  globalParams->getEnableFreeType(),
  isHintingEnabled,
  isSlightHinting,
  m_painter.top()->testRenderHint(QPainter::TextAntialiasing));
#endif
}

void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef *)
{}

void ArthurOutputDev::endPage() {
}

void ArthurOutputDev::saveState(GfxState *state)
{
  m_currentPenStack.push(m_currentPen);
  m_currentBrushStack.push(m_currentBrush);
  m_rawFontStack.push(m_rawFont);
  m_type3FontStack.push(m_currentType3Font);
  m_codeToGIDStack.push(m_codeToGID);

  m_painter.top()->save();
}

void ArthurOutputDev::restoreState(GfxState *state)
{
  m_painter.top()->restore();

  m_codeToGID = m_codeToGIDStack.top();
  m_codeToGIDStack.pop();
  m_rawFont = m_rawFontStack.top();
  m_rawFontStack.pop();
  m_currentType3Font = m_type3FontStack.top();
  m_type3FontStack.pop();
  m_currentBrush = m_currentBrushStack.top();
  m_currentBrushStack.pop();
  m_currentPen = m_currentPenStack.top();
  m_currentPenStack.pop();
}

void ArthurOutputDev::updateAll(GfxState *state)
{
  OutputDev::updateAll(state);
  m_needFontUpdate = gTrue;
}

// Set CTM (Current Transformation Matrix) to a fixed matrix
void ArthurOutputDev::setDefaultCTM(const double *ctm)
{
  m_painter.top()->setTransform(QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
}

// Update the CTM (Current Transformation Matrix), i.e., compose the old
// CTM with a new matrix.
void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12,
				double m21, double m22,
				double m31, double m32)
{
  updateLineDash(state);
  updateLineJoin(state);
  updateLineCap(state);
  updateLineWidth(state);

  QTransform update(m11, m12, m21, m22, m31, m32);

  // We could also set (rather than update) the painter transformation to state->getCMT();
  m_painter.top()->setTransform(update, true);
}

void ArthurOutputDev::updateLineDash(GfxState *state)
{
  double *dashPattern;
  int dashLength;
  double dashStart;
  state->getLineDash(&dashPattern, &dashLength, &dashStart);

  // Special handling for zero-length patterns, i.e., solid lines.
  // Simply calling QPen::setDashPattern with an empty pattern does *not*
  // result in a solid line.  Rather, the current pattern is unchanged.
  // See the implementation of the setDashPattern method in the file qpen.cpp.
  if (dashLength==0)
  {
    m_currentPen.setStyle(Qt::SolidLine);
    m_painter.top()->setPen(m_currentPen);
    return;
  }

  QVector<qreal> pattern(dashLength);
  for (int i = 0; i < dashLength; ++i) {
    // pdf measures the dash pattern in dots, but Qt uses the
    // line width as the unit.
    pattern[i] = dashPattern[i] / state->getLineWidth();
  }
  m_currentPen.setDashPattern(pattern);
  m_currentPen.setDashOffset(dashStart);
  m_painter.top()->setPen(m_currentPen);
}

void ArthurOutputDev::updateFlatness(GfxState *state)
{
  // qDebug() << "updateFlatness";
}

void ArthurOutputDev::updateLineJoin(GfxState *state)
{
  switch (state->getLineJoin()) {
  case 0:
    // The correct style here is Qt::SvgMiterJoin, *not* Qt::MiterJoin.
    // The two differ in what to do if the miter limit is exceeded.
    // See https://bugs.freedesktop.org/show_bug.cgi?id=102356
    m_currentPen.setJoinStyle(Qt::SvgMiterJoin);
    break;
  case 1:
    m_currentPen.setJoinStyle(Qt::RoundJoin);
    break;
  case 2:
    m_currentPen.setJoinStyle(Qt::BevelJoin);
    break;
  }
  m_painter.top()->setPen(m_currentPen);
}

void ArthurOutputDev::updateLineCap(GfxState *state)
{
  switch (state->getLineCap()) {
  case 0:
    m_currentPen.setCapStyle(Qt::FlatCap);
    break;
  case 1:
    m_currentPen.setCapStyle(Qt::RoundCap);
    break;
  case 2:
    m_currentPen.setCapStyle(Qt::SquareCap);
    break;
  }
  m_painter.top()->setPen(m_currentPen);
}

void ArthurOutputDev::updateMiterLimit(GfxState *state)
{
  m_currentPen.setMiterLimit(state->getMiterLimit());
  m_painter.top()->setPen(m_currentPen);
}

void ArthurOutputDev::updateLineWidth(GfxState *state)
{
  m_currentPen.setWidthF(state->getLineWidth());
  m_painter.top()->setPen(m_currentPen);
  // The updateLineDash method needs to know the line width, but it is sometimes
  // called before the updateLineWidth method.  To make sure that the last call
  // to updateLineDash before a drawing operation is always with the correct line
  // width, we call it here, right after a change to the line width.
  updateLineDash(state);
}

void ArthurOutputDev::updateFillColor(GfxState *state)
{
  GfxRGB rgb;
  QColor brushColour = m_currentBrush.color();
  state->getFillRGB(&rgb);
  brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
  m_currentBrush.setColor(brushColour);
}

void ArthurOutputDev::updateStrokeColor(GfxState *state)
{
  GfxRGB rgb;
  QColor penColour = m_currentPen.color();
  state->getStrokeRGB(&rgb);
  penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
  m_currentPen.setColor(penColour);
  m_painter.top()->setPen(m_currentPen);
}

void ArthurOutputDev::updateBlendMode(GfxState * state)
{
  GfxBlendMode blendMode = state->getBlendMode();

  // missing composition modes in QPainter:
  // - CompositionMode_Hue
  // - CompositionMode_Color
  // - CompositionMode_Luminosity
  // - CompositionMode_Saturation

  switch(blendMode){
  case gfxBlendMultiply:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Multiply);
    break;
  case gfxBlendScreen:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Screen);
    break;
  case gfxBlendDarken:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Darken);
    break;
  case gfxBlendLighten:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Lighten);
    break;
  case gfxBlendColorDodge:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_ColorDodge);
    break;
  case gfxBlendColorBurn:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_ColorBurn);
    break;
  case gfxBlendHardLight:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_HardLight);
    break;
  case gfxBlendSoftLight:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_SoftLight);
    break;
  case gfxBlendDifference:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Difference);
    break;
  case gfxBlendExclusion:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Exclusion);
    break;
  case gfxBlendColor:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_Plus);
    break;
  default:
    qDebug() << "Unsupported blend mode, falling back to CompositionMode_SourceOver";
  case gfxBlendNormal:
    m_painter.top()->setCompositionMode(QPainter::CompositionMode_SourceOver);
    break;
  }
}

void ArthurOutputDev::updateFillOpacity(GfxState *state)
{
  QColor brushColour= m_currentBrush.color();
  brushColour.setAlphaF(state->getFillOpacity());
  m_currentBrush.setColor(brushColour);
}

void ArthurOutputDev::updateStrokeOpacity(GfxState *state)
{
  QColor penColour= m_currentPen.color();
  penColour.setAlphaF(state->getStrokeOpacity());
  m_currentPen.setColor(penColour);
  m_painter.top()->setPen(m_currentPen);
}

void ArthurOutputDev::updateFont(GfxState *state)
{
  GfxFont *gfxFont = state->getFont();
  if (!gfxFont)
  {
    return;
  }

  // The key to look in the font caches
  ArthurFontID fontID = {*gfxFont->getID(), state->getFontSize()};

  // Current font is a type3 font
  if (gfxFont->getType() == fontType3)
  {
    auto cacheEntry = m_type3FontCache.find(fontID);

    if (cacheEntry!=m_type3FontCache.end()) {

      // Take the font from the cache
      m_currentType3Font = cacheEntry->second.get();

    } else {

      m_currentType3Font = new ArthurType3Font(m_doc, (Gfx8BitFont*)gfxFont);
      m_type3FontCache.insert(std::make_pair(fontID,std::unique_ptr<ArthurType3Font>(m_currentType3Font)));

    }

    return;
  }

  // Non-type3: is the font in the cache?
  auto cacheEntry = m_rawFontCache.find(fontID);

  if (cacheEntry!=m_rawFontCache.end()) {

    // Take the font from the cache
    m_rawFont = cacheEntry->second.get();

  } else {

    // New font: load it into the cache
    float fontSize = state->getFontSize();

    std::unique_ptr<GfxFontLoc> fontLoc(gfxFont->locateFont(xref, nullptr));

    if (fontLoc) {
      // load the font from respective location
      switch (fontLoc->locType) {
      case gfxFontLocEmbedded: {// if there is an embedded font, read it to memory
        int fontDataLen;
        const char* fontData = gfxFont->readEmbFontFile(xref, &fontDataLen);

        m_rawFont = new QRawFont(QByteArray(fontData, fontDataLen), fontSize);
        m_rawFontCache.insert(std::make_pair(fontID,std::unique_ptr<QRawFont>(m_rawFont)));

        // Free the font data, it was copied in the QByteArray constructor
        free((char*)fontData);
        break;
      }
      case gfxFontLocExternal:{ // font is in an external font file
        QString fontFile(fontLoc->path->getCString());
        m_rawFont = new QRawFont(fontFile, fontSize);
        m_rawFontCache.insert(std::make_pair(fontID,std::unique_ptr<QRawFont>(m_rawFont)));
        break;
      }
      case gfxFontLocResident:{ // font resides in a PS printer
        qDebug() << "Font Resident Encoding:" << fontLoc->encoding->getCString() << ", not implemented yet!";

      break;
      }
      }// end switch

    } else {
      qDebug() << "Font location not found!";
      return;
    }
  }

  if (!m_rawFont->isValid()) {
    qDebug() << "RawFont is not valid";
  }

  // *****************************************************************************
  //  We have now successfully loaded the font into a QRawFont object.  This
  //  allows us to draw all the glyphs in the font.  However, what is missing is
  //  the charcode-to-glyph-index mapping.  Apparently, Qt does not provide this
  //  information at all.  We therefore now load the font again, this time into
  //  a Splash font object.  This is wasteful, but I see no other way to access
  //  the important glyph-index mapping.
  // *****************************************************************************

#ifdef HAVE_SPLASH
  GfxFontType fontType;
  SplashFontFile *fontFile;
  SplashFontSrc *fontsrc = nullptr;
  FoFiTrueType *ff;
  GooString *fileName;
  char *tmpBuf;
  int tmpBufLen = 0;
  int *codeToGID;
  SplashCoord mat[4] = {0,0,0,0};
  int n;
  int faceIndex = 0;
  SplashCoord matrix[6] = {1,0,0,1,0,0};
  SplashFTFontFile* ftFontFile;

  m_needFontUpdate = false;
  fileName = nullptr;
  tmpBuf = nullptr;

  fontType = gfxFont->getType();
  if (fontType == fontType3) {
    return;
  }

  // Default: no codeToGID table
  m_codeToGID = nullptr;

  // check the font file cache
  SplashOutFontFileID *id = new SplashOutFontFileID(gfxFont->getID());
  if ((fontFile = m_fontEngine->getFontFile(id))) {
    delete id;

  } else {

    std::unique_ptr<GfxFontLoc> fontLoc(gfxFont->locateFont(xref, nullptr));
    if (!fontLoc) {
      error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
	    gfxFont->getName() ? gfxFont->getName()->getCString()
	                       : "(unnamed)");
      goto err2;
    }

    // embedded font
    if (fontLoc->locType == gfxFontLocEmbedded) {
      // if there is an embedded font, read it to memory
      tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
      if (! tmpBuf)
	goto err2;

    // external font
    } else { // gfxFontLocExternal
      fileName = fontLoc->path;
      fontType = fontLoc->fontType;
    }

    fontsrc = new SplashFontSrc;
    if (fileName)
      fontsrc->setFile(fileName, gFalse);
    else
      fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
    
    // load the font file
    switch (fontType) {
    case fontType1:
      if (!(fontFile = m_fontEngine->loadType1Font(
			   id,
			   fontsrc,
			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontType1C:
      if (!(fontFile = m_fontEngine->loadType1CFont(
			   id,
			   fontsrc,
			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontType1COT:
      if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont(
			   id,
			   fontsrc,
			   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontTrueType:
    case fontTrueTypeOT:
	if (fileName)
	 ff = FoFiTrueType::load(fileName->getCString());
	else
	ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
      if (ff) {
	codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
	n = 256;
	delete ff;
      } else {
	codeToGID = nullptr;
	n = 0;
      }
      if (!(fontFile = m_fontEngine->loadTrueTypeFont(
			   id,
			   fontsrc,
			   codeToGID, n))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontCIDType0:
    case fontCIDType0C:
      if (!(fontFile = m_fontEngine->loadCIDFont(
			   id,
			   fontsrc))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontCIDType0COT:
      if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
	n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
	codeToGID = (int *)gmallocn(n, sizeof(int));
	memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
	       n * sizeof(int));
      } else {
	codeToGID = nullptr;
	n = 0;
      }      
      if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
			   id,
			   fontsrc,
			   codeToGID, n))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    case fontCIDType2:
    case fontCIDType2OT:
      codeToGID = nullptr;
      n = 0;
      if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
	n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
	if (n) {
	  codeToGID = (int *)gmallocn(n, sizeof(int));
	  memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
		  n * sizeof(Gushort));
	}
      } else {
	if (fileName)
	  ff = FoFiTrueType::load(fileName->getCString());
	else
	  ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
	if (! ff)
	  goto err2;
	codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
	delete ff;
      }
      if (!(fontFile = m_fontEngine->loadTrueTypeFont(
			   id,
			   fontsrc,
			   codeToGID, n, faceIndex))) {
	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
	      gfxFont->getName() ? gfxFont->getName()->getCString()
	                         : "(unnamed)");
	goto err2;
      }
      break;
    default:
      // this shouldn't happen
      goto err2;
    }
  }

  ftFontFile = dynamic_cast<SplashFTFontFile*>(fontFile);
  if (ftFontFile)
    m_codeToGID = ftFontFile->getCodeToGID();

  // create dummy font
  // The font matrices are bogus, but we will never use the glyphs anyway.
  // However we need to call m_fontEngine->getFont, in order to have the
  // font in the Splash font cache.  Otherwise we'd load it again and again.
  m_fontEngine->getFont(fontFile, mat, matrix);

  if (fontsrc && !fontsrc->isFile)
      fontsrc->unref();
  return;

 err2:
  delete id;
#endif
}

static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule)
{
  GfxSubpath *subpath;
  int i, j;

  QPainterPath qPath;
  qPath.setFillRule(fillRule);
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    if (subpath->getNumPoints() > 0) {
      qPath.moveTo(subpath->getX(0), subpath->getY(0));
      j = 1;
      while (j < subpath->getNumPoints()) {
	if (subpath->getCurve(j)) {
          qPath.cubicTo( subpath->getX(j),   subpath->getY(j),
                         subpath->getX(j+1), subpath->getY(j+1),
                         subpath->getX(j+2), subpath->getY(j+2));
	  j += 3;
	} else {
	  qPath.lineTo(subpath->getX(j), subpath->getY(j));
	  ++j;
	}
      }
      if (subpath->isClosed()) {
	qPath.closeSubpath();
      }
    }
  }
  return qPath;
}

void ArthurOutputDev::stroke(GfxState *state)
{
  m_painter.top()->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentPen );
}

void ArthurOutputDev::fill(GfxState *state)
{
  m_painter.top()->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
}

void ArthurOutputDev::eoFill(GfxState *state)
{
  m_painter.top()->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
}

GBool ArthurOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax)
{
  double x0, y0, x1, y1;
  shading->getCoords(&x0, &y0, &x1, &y1);

  // get the clip region bbox
  double xMin, yMin, xMax, yMax;
  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);

  // get the function domain
  double t0 = shading->getDomain0();
  double t1 = shading->getDomain1();

  // Max number of splits along the t axis
  constexpr int maxSplits = 256;

  // Max delta allowed in any color component
  const double colorDelta = (dblToCol(1 / 256.0));

  // Number of color space components
  auto nComps = shading->getColorSpace()->getNComps();

  // Helper function to test two color objects for 'almost-equality'
  auto isSameGfxColor = [&nComps,&colorDelta](const GfxColor &colorA, const GfxColor &colorB)
                        {
                          for (int k = 0; k < nComps; ++k) {
                            if (abs(colorA.c[k] - colorB.c[k]) > colorDelta) {
                              return false;
                            }
                          }
                          return true;
                        };

  // Helper function: project a number into an interval
  // With C++17 this is part of the standard library
  auto clamp = [](double v, double lo, double hi)
                  { return std::min(std::max(v,lo), hi); };

  // ta stores all parameter values where we evaluate the input shading function.
  // In between, QLinearGradient will interpolate linearly.
  // We set up the array with three values.
  std::array<double, maxSplits+1> ta;
  ta[0] = tMin;
  std::array<int, maxSplits+1> next;
  next[0] = maxSplits / 2;
  ta[maxSplits / 2] = 0.5 * (tMin + tMax);
  next[maxSplits / 2] = maxSplits;
  ta[maxSplits] = tMax;

  // compute the color at t = tMin
  double tt = clamp(t0 + (t1 - t0) * tMin, t0, t1);

  GfxColor color0, color1;
  shading->getColor(tt, &color0);

  // Construct a gradient object and set its color at one parameter end
  QLinearGradient gradient(QPointF(x0 + tMin * (x1 - x0), y0 + tMin * (y1 - y0)),
                           QPointF(x0 + tMax * (x1 - x0), y0 + tMax * (y1 - y0)));

  GfxRGB rgb;
  shading->getColorSpace()->getRGB(&color0, &rgb);
  QColor qColor(colToByte(rgb.r), colToByte(rgb.g), colToByte(rgb.b));
  gradient.setColorAt(0,qColor);

  // Look for more relevant parameter values by bisection
  int i = 0;
  while (i < maxSplits) {

    int j = next[i];
    while (j > i + 1) {

      // Next parameter value to try
      tt = clamp(t0 + (t1 - t0) * ta[j], t0, t1);
      shading->getColor(tt, &color1);

      // j is a good next color stop if the input shading can be approximated well
      // on the interval (ta[i], ta[j]) by a linear interpolation.
      // We test this by comparing the real color in the middle between ta[i] and ta[j]
      // with the linear interpolant there.
      auto midPoint = 0.5 * (ta[i] + ta[j]);
      GfxColor colorAtMidPoint;
      shading->getColor(midPoint, &colorAtMidPoint);

      GfxColor linearlyInterpolatedColor;
      for (int ii=0; ii<nComps; ii++)
        linearlyInterpolatedColor.c[ii] = 0.5 * (color0.c[ii] + color1.c[ii]);

      // If the two colors are equal, ta[j] is a good place for the next color stop; take it!
      if (isSameGfxColor(colorAtMidPoint, linearlyInterpolatedColor))
        break;

      // Otherwise: bisect further
      int k = (i + j) / 2;
      ta[k] = midPoint;
      next[i] = k;
      next[k] = j;
      j = k;
    }

    // set the color
    GfxRGB rgb;
    shading->getColorSpace()->getRGB(&color1, &rgb);
    qColor.setRgb(colToByte(rgb.r), colToByte(rgb.g), colToByte(rgb.b));
    gradient.setColorAt((ta[j] - tMin)/(tMax - tMin), qColor);

    // Move to the next parameter region
    color0 = color1;
    i = next[i];
  }

  state->moveTo(xMin, yMin);
  state->lineTo(xMin, yMax);
  state->lineTo(xMax, yMax);
  state->lineTo(xMax, yMin);
  state->closePath();

  // Actually paint the shaded region
  QBrush newBrush(gradient);
  m_painter.top()->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), newBrush );

  state->clearPath();

  // True means: The shaded region has been painted
  return gTrue;
}

void ArthurOutputDev::clip(GfxState *state)
{
  m_painter.top()->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ), Qt::IntersectClip );
}

void ArthurOutputDev::eoClip(GfxState *state)
{
  m_painter.top()->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ), Qt::IntersectClip );
}

void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
			       double dx, double dy,
			       double originX, double originY,
			       CharCode code, int nBytes, Unicode *u, int uLen) {

  // First handle type3 fonts
  GfxFont *gfxFont = state->getFont();

  GfxFontType fontType = gfxFont->getType();
  if (fontType == fontType3) {

    /////////////////////////////////////////////////////////////////////
    //  Draw the QPicture that contains the glyph onto the page
    /////////////////////////////////////////////////////////////////////

    // Store the QPainter state; we need to modify it temporarily
    m_painter.top()->save();

    // Make the glyph position the coordinate origin -- that's our center of scaling
    m_painter.top()->translate(QPointF(x-originX, y-originY));

    const double* mat = gfxFont->getFontMatrix();
    QTransform fontMatrix(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);

    // Scale with the font size
    fontMatrix.scale(state->getFontSize(), state->getFontSize());
    m_painter.top()->setTransform(fontMatrix,true);

    // Apply the text matrix on top
    const double *textMat = state->getTextMat();

    QTransform textTransform(textMat[0] * state->getHorizScaling(),
                             textMat[1] * state->getHorizScaling(),
                             textMat[2],
                             textMat[3],
                             0,
                             0);

    m_painter.top()->setTransform(textTransform,true);

    // Actually draw the glyph
    int gid = m_currentType3Font->codeToGID[code];
    m_painter.top()->drawPicture(QPointF(0,0), m_currentType3Font->getGlyph(gid));

    // Restore transformation
    m_painter.top()->restore();

    return;
  }


  // check for invisible text -- this is used by Acrobat Capture
  int render = state->getRender();
  if (render == 3 || !m_rawFont) {
    qDebug() << "Invisible text found!";
    return;
  }

  if (!(render & 1))
  {
    quint32 glyphIndex = (m_codeToGID) ? m_codeToGID[code] : code;
    QPointF glyphPosition = QPointF(x-originX, y-originY);

    // QGlyphRun objects can hold an entire sequence of glyphs, and it would possibly
    // be more efficient to simply note the glyph and glyph position here and then
    // draw several glyphs at once in the endString method.  What keeps us from doing
    // that is the transformation below: each glyph needs to be drawn upside down,
    // i.e., reflected at its own baseline.  Since we have no guarantee that this
    // baseline is the same for all glyphs in a string we have to do it one by one.
    QGlyphRun glyphRun;
    glyphRun.setRawData(&glyphIndex, &glyphPosition, 1);
    glyphRun.setRawFont(*m_rawFont);

    // Store the QPainter state; we need to modify it temporarily
    m_painter.top()->save();

    // Apply the text matrix to the glyph.  The glyph is not scaled by the font size,
    // because the font in m_rawFont already has the correct size.
    // Additionally, the CTM is upside down, i.e., it contains a negative Y-scaling
    // entry.  Therefore, Qt will paint the glyphs upside down.  We need to temporarily
    // reflect the page at glyphPosition.y().

    // Make the glyph position the coordinate origin -- that's our center of scaling
    const double *textMat = state->getTextMat();

    m_painter.top()->translate(QPointF(glyphPosition.x(),glyphPosition.y()));

    QTransform textTransform(textMat[0] * state->getHorizScaling(),
                             textMat[1] * state->getHorizScaling(),
                             -textMat[2], // reflect at the horizontal axis,
                             -textMat[3], // because CTM is upside-down.
                             0,
                             0);

    m_painter.top()->setTransform(textTransform,true);

    // We are painting a filled glyph here.  But QPainter uses the pen to draw even filled text,
    // not the brush.  (see, e.g.,  http://doc.qt.io/qt-5/qpainter.html#setPen )
    // Therefore we have to temporarily overwrite the pen color.

    // Since we are drawing a filled glyph, one would really expect to have m_currentBrush
    // have the correct color.  However, somehow state->getFillRGB can change without
    // updateFillColor getting called.  Then m_currentBrush may not contain the correct color.
    GfxRGB rgb;
    state->getFillRGB(&rgb);
    QColor fontColor;
    fontColor.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getFillOpacity());
    m_painter.top()->setPen(fontColor);

    // Actually draw the glyph
    m_painter.top()->drawGlyphRun(QPointF(-glyphPosition.x(),-glyphPosition.y()), glyphRun);

    // Restore transformation and pen color
    m_painter.top()->restore();
  }
}

void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
{
}

void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
			      double llx, double lly, double urx, double ury)
{
}

void ArthurOutputDev::endTextObject(GfxState *state)
{
}


void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GBool invert,
				    GBool interpolate, GBool inlineImg)
{
  auto imgStr = std::make_unique<ImageStream>(
	str, width,
	1,  // numPixelComps
	1  // getBits
  );
  imgStr->reset();

  // TODO: Would using QImage::Format_Mono be more efficient here?
  QImage image(width, height, QImage::Format_ARGB32);
  unsigned int *data = (unsigned int *)image.bits();
  int stride = image.bytesPerLine()/4;

  QRgb fillColor = m_currentBrush.color().rgb();

  for (int y = 0; y < height; y++) {

    Guchar *pix = imgStr->getLine();

    // Invert the vertical coordinate: y is increasing from top to bottom
    // on the page, but y is increasing bottom to top in the picture.
    unsigned int* dest = data + (height-1-y) * stride;

    for (int x = 0; x < width; x++) {

      bool opaque = ((bool)pix[x]) == invert;
      dest[x] = (opaque) ? fillColor : 0;

    }
  }

  // At this point, the QPainter coordinate transformation (CTM) is such
  // that QRect(0,0,1,1) is exactly the area of the image.
  m_painter.top()->drawImage( QRect(0,0,1,1), image );
  imgStr->close ();
}

//TODO: lots more work here.
void ArthurOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
				int width, int height,
				GfxImageColorMap *colorMap,
				GBool interpolate, int *maskColors, GBool inlineImg)
{
  unsigned int *data;
  unsigned int *line;
  int x, y;
  Guchar *pix;
  int i;
  QImage image;
  int stride;
  
  /* TODO: Do we want to cache these? */
  auto imgStr = std::make_unique<ImageStream>(
	str, width,
	colorMap->getNumPixelComps(),
	colorMap->getBits()
  );
  imgStr->reset();
  
  image = QImage(width, height, QImage::Format_ARGB32);
  data = (unsigned int *)image.bits();
  stride = image.bytesPerLine()/4;
  for (y = 0; y < height; y++) {
    pix = imgStr->getLine();
    // Invert the vertical coordinate: y is increasing from top to bottom
    // on the page, but y is increasing bottom to top in the picture.
    line = data+(height-1-y)*stride;
    colorMap->getRGBLine(pix, line, width);

    if (maskColors) {
      for (x = 0; x < width; x++) {
        for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
            if (pix[i] < maskColors[2*i] * 255||
                pix[i] > maskColors[2*i+1] * 255) {
                *line = *line | 0xff000000;
                break;
            }
        }
        pix += colorMap->getNumPixelComps();
        line++;
      }
    } else {
      for (x = 0; x < width; x++) { *line = *line | 0xff000000; line++; }
    }
  }

  // At this point, the QPainter coordinate transformation (CTM) is such
  // that QRect(0,0,1,1) is exactly the area of the image.
  m_painter.top()->drawImage( QRect(0,0,1,1), image );

}

void ArthurOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
                                          int width, int height,
                                          GfxImageColorMap *colorMap,
                                          GBool interpolate,
                                          Stream *maskStr,
                                          int maskWidth, int maskHeight,
                                          GfxImageColorMap *maskColorMap,
                                          GBool maskInterpolate)
{
  // Bail out if the image size doesn't match the mask size.  I don't know
  // what to do in this case.
  if (width!=maskWidth || height!=maskHeight)
  {
    qDebug() << "Soft mask size does not match image size!";
    drawImage(state, ref, str, width, height, colorMap, interpolate, nullptr, gFalse);
    return;
  }

  // Bail out if the mask isn't a single channel.  I don't know
  // what to do in this case.
  if (maskColorMap->getColorSpace()->getNComps() != 1)
  {
    qDebug() << "Soft mask is not a single 8-bit channel!";
    drawImage(state, ref, str, width, height, colorMap, interpolate, nullptr, gFalse);
    return;
  }

  /* TODO: Do we want to cache these? */
  auto imgStr = std::make_unique<ImageStream>(
	str, width,
	colorMap->getNumPixelComps(),
	colorMap->getBits()
  );
  imgStr->reset();

  auto maskImageStr = std::make_unique<ImageStream>(
	maskStr, maskWidth,
	maskColorMap->getNumPixelComps(),
	maskColorMap->getBits()
  );
  maskImageStr->reset();

  QImage image(width, height, QImage::Format_ARGB32);
  unsigned int *data = (unsigned int *)image.bits();
  int stride = image.bytesPerLine()/4;

  std::vector<Guchar> maskLine(maskWidth);

  for (int y = 0; y < height; y++) {

    Guchar *pix = imgStr->getLine();
    Guchar *maskPix = maskImageStr->getLine();

    // Invert the vertical coordinate: y is increasing from top to bottom
    // on the page, but y is increasing bottom to top in the picture.
    unsigned int* line = data+(height-1-y)*stride;
    colorMap->getRGBLine(pix, line, width);

    // Apply the mask values to the image alpha channel
    maskColorMap->getGrayLine(maskPix, maskLine.data(), width);
    for (int x = 0; x < width; x++)
    {
      *line = *line | (maskLine[x]<<24);
      line++;
    }
  }

  // At this point, the QPainter coordinate transformation (CTM) is such
  // that QRect(0,0,1,1) is exactly the area of the image.
  m_painter.top()->drawImage( QRect(0,0,1,1), image );
}

void ArthurOutputDev::beginTransparencyGroup(GfxState * /*state*/, const double * /*bbox*/,
                                             GfxColorSpace * /*blendingColorSpace*/,
                                             GBool /*isolated*/, GBool /*knockout*/,
                                             GBool /*forSoftMask*/)
{
  // The entire transparency group will be painted into a
  // freshly created QPicture object.  Since an existing painter
  // cannot change its paint device, we need to construct a
  // new QPainter object as well.
  m_qpictures.push(new QPicture);
  m_painter.push(new QPainter(m_qpictures.top()));
}

void ArthurOutputDev::endTransparencyGroup(GfxState * /*state*/)
{
  // Stop painting into the group
  m_painter.top()->end();

  // Kill the painter that has been used for the transparency group
  delete(m_painter.top());
  m_painter.pop();

  // Store the QPicture object that holds the result of the transparency group
  // painting.  It will be painted and deleted in the method paintTransparencyGroup.
  if (m_lastTransparencyGroupPicture)
  {
    qDebug() << "Found a transparency group that has not been painted";
    delete(m_lastTransparencyGroupPicture);
  }
  m_lastTransparencyGroupPicture = m_qpictures.top();
  m_qpictures.pop();
}

void ArthurOutputDev::paintTransparencyGroup(GfxState * /*state*/, const double * /*bbox*/)
{
  // Actually draw the transparency group
  m_painter.top()->drawPicture(0,0,*m_lastTransparencyGroupPicture);

  // And delete it
  delete(m_lastTransparencyGroupPicture);
  m_lastTransparencyGroupPicture = nullptr;
}

