//========================================================================
//
// 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 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 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
//
// 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>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

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

#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 <QtCore/QtDebug>
#include <QRawFont>
#include <QGlyphRun>
#include <QtGui/QPainterPath>
//------------------------------------------------------------------------

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

class SplashOutFontFileID: public SplashFontFileID {
public:

  SplashOutFontFileID(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

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

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

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

void ArthurOutputDev::startDoc(XRef *xrefA) {
  xref = xrefA;
#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->testRenderHint(QPainter::TextAntialiasing));
#endif
}

void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef *xref)
{
  // fill page with white background.
  int w = static_cast<int>(state->getPageWidth());
  int h = static_cast<int>(state->getPageHeight());
  QColor fillColour(Qt::white);
  QBrush fill(fillColour);
  m_painter->save();
  m_painter->setPen(fillColour);
  m_painter->setBrush(fill);
  m_painter->drawRect(0, 0, w, h);
  m_painter->restore();
}

void ArthurOutputDev::endPage() {
}

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

  m_painter->save();
}

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

  m_codeToGID = m_codeToGIDStack.top();
  m_codeToGIDStack.pop();
  m_rawFont = m_rawFontStack.top();
  m_rawFontStack.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(double *ctm)
{
  m_painter->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->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->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->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->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->setPen(m_currentPen);
}

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

void ArthurOutputDev::updateLineWidth(GfxState *state)
{
  m_currentPen.setWidthF(state->getLineWidth());
  m_painter->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->setPen(m_currentPen);
}

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->setPen(m_currentPen);
}

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

  // is the font in the cache?
  ArthurFontID fontID = {*gfxFont->getID(), state->getFontSize()};
  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;
  Object refObj, strObj;
  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->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentPen );
}

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

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

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

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

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) {

  // 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->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->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->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->setPen(fontColor);

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

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

GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
				      double dx, double dy,
				      CharCode code, Unicode *u, int uLen)
{
  return gFalse;
}

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

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)
{
  qDebug() << "drawImageMask";
#if 0
  unsigned char *buffer;
  unsigned char *dest;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  int x, y;
  ImageStream *imgStr;
  Guchar *pix;
  double *ctm;
  cairo_matrix_t matrix;
  int invert_bit;
  int row_stride;

  row_stride = (width + 3) & ~3;
  buffer = (unsigned char *) malloc (height * row_stride);
  if (buffer == nullptr) {
    error(-1, "Unable to allocate memory for image.");
    return;
  }

  /* TODO: Do we want to cache these? */
  imgStr = new ImageStream(str, width, 1, 1);
  imgStr->reset();

  invert_bit = invert ? 1 : 0;

  for (y = 0; y < height; y++) {
    pix = imgStr->getLine();
    dest = buffer + y * row_stride;
    for (x = 0; x < width; x++) {

      if (pix[x] ^ invert_bit)
	*dest++ = 0;
      else
	*dest++ = 255;
    }
  }

  image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
					  width, height, row_stride);
  if (image == nullptr)
    return;
  pattern = cairo_pattern_create_for_surface (image);
  if (pattern == nullptr)
    return;

  ctm = state->getCTM();
  LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
	       width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
  matrix.xx = ctm[0] / width;
  matrix.xy = -ctm[2] / height;
  matrix.yx = ctm[1] / width;
  matrix.yy = -ctm[3] / height;
  matrix.x0 = ctm[2] + ctm[4];
  matrix.y0 = ctm[3] + ctm[5];
  cairo_matrix_invert (&matrix);
  cairo_pattern_set_matrix (pattern, &matrix);

  cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
  /* FIXME: Doesn't the image mask support any colorspace? */
  cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b);
  cairo_mask (cairo, pattern);

  cairo_pattern_destroy (pattern);
  cairo_surface_destroy (image);
  free (buffer);
  imgStr->close ();
  delete imgStr;
#endif
}

//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;
  ImageStream *imgStr;
  Guchar *pix;
  int i;
  QImage image;
  int stride;
  
  /* TODO: Do we want to cache these? */
  imgStr = new 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->drawImage( QRect(0,0,1,1), image );
  delete imgStr;

}

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? */
  std::unique_ptr<ImageStream> imgStr(new ImageStream(str, width,
                                                      colorMap->getNumPixelComps(),
                                                      colorMap->getBits()));
  imgStr->reset();

  std::unique_ptr<ImageStream> maskImageStr(new 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->drawImage( QRect(0,0,1,1), image );
}

