//========================================================================
//
// CairoOutputDev.cc
//
// Copyright 2003 Glyph & Cog, LLC
// Copyright 2004 Red Hat, Inc
//
//========================================================================

//========================================================================
//
// 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-2008 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005, 2009, 2012, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
// Copyright (C) 2006-2011, 2013, 2014, 2017, 2018 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2008 Carl Worth <cworth@cworth.org>
// Copyright (C) 2008-2018 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2008, 2009 Chris Wilson <chris@chris-wilson.co.uk>
// Copyright (C) 2008, 2012 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
// Copyright (C) 2011-2014 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012 Patrick Pfeifer <p2000@mailinator.com>
// Copyright (C) 2012, 2015, 2016 Jason Crain <jason@aquaticape.us>
// Copyright (C) 2015 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
// 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 <cstdint>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <cairo.h>

#include "goo/gfile.h"
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
#include "Gfx.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Page.h"
#include "Link.h"
#include "FontEncodingTables.h"
#include "PDFDocEncoding.h"
#include <fofi/FoFiTrueType.h>
#include <splash/SplashBitmap.h>
#include "CairoOutputDev.h"
#include "CairoFontEngine.h"
#include "CairoRescaleBox.h"
#include "UnicodeMap.h"
#include "JBIG2Stream.h"
//------------------------------------------------------------------------

// #define LOG_CAIRO

// To limit memory usage and improve performance when printing, limit
// cairo images to this size. 8192 is sufficient for an A2 sized
// 300ppi image.
#define MAX_PRINT_IMAGE_SIZE 8192

#ifdef LOG_CAIRO
#define LOG(x) (x)
#else
#define LOG(x)
#endif


#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))


//------------------------------------------------------------------------
// CairoImage
//------------------------------------------------------------------------

CairoImage::CairoImage (double x1, double y1, double x2, double y2) {
  this->image = nullptr;
  this->x1 = x1;
  this->y1 = y1;
  this->x2 = x2;
  this->y2 = y2;
}

CairoImage::~CairoImage () {
  if (image)
    cairo_surface_destroy (image);
}

void CairoImage::setImage (cairo_surface_t *image) {
  if (this->image)
    cairo_surface_destroy (this->image);
  this->image = cairo_surface_reference (image);
}

//------------------------------------------------------------------------
// CairoOutputDev
//------------------------------------------------------------------------

// We cannot tie the lifetime of an FT_Library object to that of
// CairoOutputDev, since any FT_Faces created with it may end up with a
// reference by Cairo which can be held long after the CairoOutputDev is
// deleted.  The simplest way to avoid problems is to never tear down the
// FT_Library instance; to avoid leaks, just use a single global instance
// initialized the first time it is needed.
FT_Library CairoOutputDev::ft_lib;
bool CairoOutputDev::ft_lib_initialized = false;

CairoOutputDev::CairoOutputDev() {
  doc = nullptr;

  if (!ft_lib_initialized) {
    FT_Init_FreeType(&ft_lib);
    ft_lib_initialized = true;
  }

  fontEngine = nullptr;
  fontEngine_owner = false;
  glyphs = nullptr;
  fill_pattern = nullptr;
  fill_color.r = fill_color.g = fill_color.b = 0;
  stroke_pattern = nullptr;
  stroke_color.r = stroke_color.g = stroke_color.b = 0;
  stroke_opacity = 1.0;
  fill_opacity = 1.0;
  textClipPath = nullptr;
  strokePathClip = nullptr;
  cairo = nullptr;
  currentFont = nullptr;
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
  prescaleImages = false;
#else
  prescaleImages = true;
#endif
  printing = true;
  use_show_text_glyphs = false;
  inUncoloredPattern = false;
  inType3Char = false;
  t3_glyph_has_bbox = false;
  text_matrix_valid = true;
  antialias = CAIRO_ANTIALIAS_DEFAULT;

  groupColorSpaceStack = nullptr;
  maskStack = nullptr;
  group = nullptr;
  mask = nullptr;
  shape = nullptr;
  cairo_shape = nullptr;
  knockoutCount = 0;

  text = nullptr;
  actualText = nullptr;

  // the SA parameter supposedly defaults to false, but Acrobat
  // apparently hardwires it to true
  stroke_adjust = true;
  align_stroke_coords = false;
  adjusted_stroke_width = false;
  xref = nullptr;
}

CairoOutputDev::~CairoOutputDev() {
  if (fontEngine_owner && fontEngine) {
    delete fontEngine;
  }

  if (cairo)
    cairo_destroy (cairo);
  cairo_pattern_destroy (stroke_pattern);
  cairo_pattern_destroy (fill_pattern);
  if (group)
    cairo_pattern_destroy (group);
  if (mask)
    cairo_pattern_destroy (mask);
  if (shape)
    cairo_pattern_destroy (shape);
  if (text) 
    text->decRefCnt();
  if (actualText)
    delete actualText;  
}

void CairoOutputDev::setCairo(cairo_t *cairo)
{
  if (this->cairo != nullptr) {
    cairo_status_t status = cairo_status (this->cairo);
    if (status) {
      error(errInternal, -1, "cairo context error: {0:s}\n", cairo_status_to_string(status));
    }
    cairo_destroy (this->cairo);
    assert(!cairo_shape);
  }
  if (cairo != nullptr) {
    this->cairo = cairo_reference (cairo);
	/* save the initial matrix so that we can use it for type3 fonts. */
	//XXX: is this sufficient? could we miss changes to the matrix somehow?
	cairo_get_matrix(cairo, &orig_matrix);
	setContextAntialias(cairo, antialias);
  } else {
    this->cairo = nullptr;
    this->cairo_shape = nullptr;
  }
}

void CairoOutputDev::setTextPage(TextPage *text)
{
  if (this->text) 
    this->text->decRefCnt();
  if (actualText)
    delete actualText;
  if (text) {
    this->text = text;
    this->text->incRefCnt();
    actualText = new ActualText(text);
  } else {
    this->text = nullptr;
    actualText = nullptr;
  }
}

void CairoOutputDev::setAntialias(cairo_antialias_t antialias)
{
  this->antialias = antialias;
  if (cairo)
    setContextAntialias (cairo, antialias);
  if (cairo_shape)
    setContextAntialias (cairo_shape, antialias);
}

void CairoOutputDev::setContextAntialias(cairo_t *cr, cairo_antialias_t antialias)
{
  cairo_font_options_t *font_options;
  cairo_set_antialias (cr, antialias);
  font_options = cairo_font_options_create ();
  cairo_get_font_options (cr, font_options);
  cairo_font_options_set_antialias (font_options, antialias);
  cairo_set_font_options (cr, font_options);
  cairo_font_options_destroy (font_options);
}

void CairoOutputDev::startDoc(PDFDoc *docA,
			      CairoFontEngine *parentFontEngine) {
  doc = docA;
  if (parentFontEngine) {
    fontEngine = parentFontEngine;
  } else {
    if (fontEngine) {
      delete fontEngine;
    }
    fontEngine = new CairoFontEngine(ft_lib);
    fontEngine_owner = true;
  }
  xref = doc->getXRef();
}

void CairoOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
  /* set up some per page defaults */
  cairo_pattern_destroy(fill_pattern);
  cairo_pattern_destroy(stroke_pattern);

  fill_pattern = cairo_pattern_create_rgb(0., 0., 0.);
  fill_color.r = fill_color.g = fill_color.b = 0;
  stroke_pattern = cairo_pattern_reference(fill_pattern);
  stroke_color.r = stroke_color.g = stroke_color.b = 0;

  if (text)
    text->startPage(state);
  if (xrefA != nullptr) {
    xref = xrefA;
  }
}

void CairoOutputDev::endPage() {
  if (text) {
    text->endPage();
    text->coalesce(true, 0, false);
  }
}

void CairoOutputDev::saveState(GfxState *state) {
  LOG(printf ("save\n"));
  cairo_save (cairo);
  if (cairo_shape)
      cairo_save (cairo_shape);

  MaskStack *ms = new MaskStack;
  ms->mask = cairo_pattern_reference(mask);
  ms->mask_matrix = mask_matrix;
  ms->next = maskStack;
  maskStack = ms;

  if (strokePathClip)
    strokePathClip->ref_count++;
}

void CairoOutputDev::restoreState(GfxState *state) {
  LOG(printf ("restore\n"));
  cairo_restore (cairo);
  if (cairo_shape)
      cairo_restore (cairo_shape);

  text_matrix_valid = true;

  /* These aren't restored by cairo_restore() since we keep them in
   * the output device. */
  updateFillColor(state);
  updateStrokeColor(state);
  updateFillOpacity(state);
  updateStrokeOpacity(state);
  updateBlendMode(state);

  MaskStack* ms = maskStack;
  if (ms) {
    if (mask)
      cairo_pattern_destroy(mask);
    mask = ms->mask;
    mask_matrix = ms->mask_matrix;
    maskStack = ms->next;
    delete ms;
  }

  if (strokePathClip && --strokePathClip->ref_count == 0) {
    delete strokePathClip->path;
    if (strokePathClip->dashes)
      gfree (strokePathClip->dashes);
    gfree (strokePathClip);
    strokePathClip = nullptr;
  }
}

void CairoOutputDev::updateAll(GfxState *state) {
  updateLineDash(state);
  updateLineJoin(state);
  updateLineCap(state);
  updateLineWidth(state);
  updateFlatness(state);
  updateMiterLimit(state);
  updateFillColor(state);
  updateStrokeColor(state);
  updateFillOpacity(state);
  updateStrokeOpacity(state);
  updateBlendMode(state);
  needFontUpdate = true;
  if (text)
    text->updateFont(state);
}

void CairoOutputDev::setDefaultCTM(const double *ctm) {
  cairo_matrix_t matrix;
  matrix.xx = ctm[0];
  matrix.yx = ctm[1];
  matrix.xy = ctm[2];
  matrix.yy = ctm[3];
  matrix.x0 = ctm[4];
  matrix.y0 = ctm[5];

  cairo_transform (cairo, &matrix);
  if (cairo_shape)
      cairo_transform (cairo_shape, &matrix);

  OutputDev::setDefaultCTM(ctm);
}

void CairoOutputDev::updateCTM(GfxState *state, double m11, double m12,
				double m21, double m22,
				double m31, double m32) {
  cairo_matrix_t matrix, invert_matrix;
  matrix.xx = m11;
  matrix.yx = m12;
  matrix.xy = m21;
  matrix.yy = m22;
  matrix.x0 = m31;
  matrix.y0 = m32;

  /* Make sure the matrix is invertible before setting it.
   * cairo will blow up if we give it a matrix that's not
   * invertible, so we need to check before passing it
   * to cairo_transform. Ignoring it is likely to give better
   * results than not rendering anything at all. See #14398
   *
   * Ideally, we could do the cairo_transform
   * and then check if anything went wrong and fix it then
   * instead of having to invert the matrix. */
  invert_matrix = matrix;
  if (cairo_matrix_invert(&invert_matrix)) {
    error(errSyntaxWarning, -1, "matrix not invertible\n");
    return;
  }

  cairo_transform (cairo, &matrix);
  if (cairo_shape)
    cairo_transform (cairo_shape, &matrix);
  updateLineDash(state);
  updateLineJoin(state);
  updateLineCap(state);
  updateLineWidth(state);
}

void CairoOutputDev::updateLineDash(GfxState *state) {
  double *dashPattern;
  int dashLength;
  double dashStart;

  state->getLineDash(&dashPattern, &dashLength, &dashStart);
  cairo_set_dash (cairo, dashPattern, dashLength, dashStart);
  if (cairo_shape)
    cairo_set_dash (cairo_shape, dashPattern, dashLength, dashStart);
}

void CairoOutputDev::updateFlatness(GfxState *state) {
  // cairo_set_tolerance (cairo, state->getFlatness());
}

void CairoOutputDev::updateLineJoin(GfxState *state) {
  switch (state->getLineJoin()) {
  case 0:
    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
    break;
  case 1:
    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_ROUND);
    break;
  case 2:
    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_BEVEL);
    break;
  }
  if (cairo_shape)
    cairo_set_line_join (cairo_shape, cairo_get_line_join(cairo));
}

void CairoOutputDev::updateLineCap(GfxState *state) {
  switch (state->getLineCap()) {
  case 0:
    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT);
    break;
  case 1:
    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_ROUND);
    break;
  case 2:
    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE);
    break;
  }
  if (cairo_shape)
    cairo_set_line_cap (cairo_shape, cairo_get_line_cap(cairo));
}

void CairoOutputDev::updateMiterLimit(GfxState *state) {
  cairo_set_miter_limit (cairo, state->getMiterLimit());
  if (cairo_shape)
    cairo_set_miter_limit (cairo_shape, state->getMiterLimit());
}

void CairoOutputDev::updateLineWidth(GfxState *state) {
  LOG(printf ("line width: %f\n", state->getLineWidth()));
  adjusted_stroke_width = false;
  double width = state->getLineWidth();
  if (stroke_adjust && !printing) {
    double x, y;
    x = y = width;

    /* find out line width in device units */
    cairo_user_to_device_distance(cairo, &x, &y);
    if (fabs(x) <= 1.0 && fabs(y) <= 1.0) {
      /* adjust width to at least one device pixel */
      x = y = 1.0;
      cairo_device_to_user_distance(cairo, &x, &y);
      width = MIN(fabs(x),fabs(y));
      adjusted_stroke_width = true;
    }
  } else if (width == 0.0) {
    /* Cairo does not support 0 line width == 1 device pixel. Find out
     * how big pixels (device unit) are in the x and y
     * directions. Choose the smaller of the two as our line width.
     */
    double x = 1.0, y = 1.0;
    if (printing) {
      // assume printer pixel size is 1/600 inch
      x = 72.0/600;
      y = 72.0/600;
    }
    cairo_device_to_user_distance(cairo, &x, &y);
    width = MIN(fabs(x),fabs(y));
  }
  cairo_set_line_width (cairo, width);
  if (cairo_shape)
    cairo_set_line_width (cairo_shape, cairo_get_line_width (cairo));
}

void CairoOutputDev::updateFillColor(GfxState *state) {
  GfxRGB color = fill_color;

  if (inUncoloredPattern)
    return;

  state->getFillRGB(&fill_color);
  if (cairo_pattern_get_type (fill_pattern) != CAIRO_PATTERN_TYPE_SOLID ||
      color.r != fill_color.r ||
      color.g != fill_color.g ||
      color.b != fill_color.b)
  {
    cairo_pattern_destroy(fill_pattern);
    fill_pattern = cairo_pattern_create_rgba(colToDbl(fill_color.r),
					     colToDbl(fill_color.g),
					     colToDbl(fill_color.b),
					     fill_opacity);

    LOG(printf ("fill color: %d %d %d\n",
		fill_color.r, fill_color.g, fill_color.b));
  }
}

void CairoOutputDev::updateStrokeColor(GfxState *state) {
  GfxRGB color = stroke_color;

  if (inUncoloredPattern)
    return;

  state->getStrokeRGB(&stroke_color);
  if (cairo_pattern_get_type (fill_pattern) != CAIRO_PATTERN_TYPE_SOLID ||
      color.r != stroke_color.r ||
      color.g != stroke_color.g ||
      color.b != stroke_color.b)
  {
    cairo_pattern_destroy(stroke_pattern);
    stroke_pattern = cairo_pattern_create_rgba(colToDbl(stroke_color.r),
					       colToDbl(stroke_color.g),
					       colToDbl(stroke_color.b),
					       stroke_opacity);

    LOG(printf ("stroke color: %d %d %d\n",
		stroke_color.r, stroke_color.g, stroke_color.b));
  }
}

void CairoOutputDev::updateFillOpacity(GfxState *state) {
  double opacity = fill_opacity;

  if (inUncoloredPattern)
    return;

  fill_opacity = state->getFillOpacity();
  if (opacity != fill_opacity) {
    cairo_pattern_destroy(fill_pattern);
    fill_pattern = cairo_pattern_create_rgba(colToDbl(fill_color.r),
					     colToDbl(fill_color.g),
					     colToDbl(fill_color.b),
					     fill_opacity);

    LOG(printf ("fill opacity: %f\n", fill_opacity));
  }
}

void CairoOutputDev::updateStrokeOpacity(GfxState *state) {
  double opacity = stroke_opacity;

  if (inUncoloredPattern)
    return;

  stroke_opacity = state->getStrokeOpacity();
  if (opacity != stroke_opacity) {
    cairo_pattern_destroy(stroke_pattern);
    stroke_pattern = cairo_pattern_create_rgba(colToDbl(stroke_color.r),
					       colToDbl(stroke_color.g),
					       colToDbl(stroke_color.b),
					       stroke_opacity);

    LOG(printf ("stroke opacity: %f\n", stroke_opacity));
  }
}

void CairoOutputDev::updateFillColorStop(GfxState *state, double offset) {
  if (inUncoloredPattern)
    return;

  state->getFillRGB(&fill_color);

  cairo_pattern_add_color_stop_rgba(fill_pattern, offset,
				    colToDbl(fill_color.r),
				    colToDbl(fill_color.g),
				    colToDbl(fill_color.b),
				    fill_opacity);
  LOG(printf ("fill color stop: %f (%d, %d, %d)\n",
	      offset, fill_color.r, fill_color.g, fill_color.b));
}

void CairoOutputDev::updateBlendMode(GfxState *state) {
  switch (state->getBlendMode()) {
  default:
  case gfxBlendNormal:
    cairo_set_operator (cairo, CAIRO_OPERATOR_OVER);
    break;
  case gfxBlendMultiply:
    cairo_set_operator (cairo, CAIRO_OPERATOR_MULTIPLY);
    break;
  case gfxBlendScreen:
    cairo_set_operator (cairo, CAIRO_OPERATOR_SCREEN);
    break;
  case gfxBlendOverlay:
    cairo_set_operator (cairo, CAIRO_OPERATOR_OVERLAY);
    break;
  case gfxBlendDarken:
    cairo_set_operator (cairo, CAIRO_OPERATOR_DARKEN);
    break;
  case gfxBlendLighten:
    cairo_set_operator (cairo, CAIRO_OPERATOR_LIGHTEN);
    break;
  case gfxBlendColorDodge:
    cairo_set_operator (cairo, CAIRO_OPERATOR_COLOR_DODGE);
    break;
  case gfxBlendColorBurn:
    cairo_set_operator (cairo, CAIRO_OPERATOR_COLOR_BURN);
    break;
  case gfxBlendHardLight:
    cairo_set_operator (cairo, CAIRO_OPERATOR_HARD_LIGHT);
    break;
  case gfxBlendSoftLight:
    cairo_set_operator (cairo, CAIRO_OPERATOR_SOFT_LIGHT);
    break;
  case gfxBlendDifference:
    cairo_set_operator (cairo, CAIRO_OPERATOR_DIFFERENCE);
    break;
  case gfxBlendExclusion:
    cairo_set_operator (cairo, CAIRO_OPERATOR_EXCLUSION);
    break;
  case gfxBlendHue:
    cairo_set_operator (cairo, CAIRO_OPERATOR_HSL_HUE);
    break;
  case gfxBlendSaturation:
    cairo_set_operator (cairo, CAIRO_OPERATOR_HSL_SATURATION);
    break;
  case gfxBlendColor:
    cairo_set_operator (cairo, CAIRO_OPERATOR_HSL_COLOR);
    break;
  case gfxBlendLuminosity:
    cairo_set_operator (cairo, CAIRO_OPERATOR_HSL_LUMINOSITY);
    break;
  }
  LOG(printf ("blend mode: %d\n", (int)state->getBlendMode()));
}

void CairoOutputDev::updateFont(GfxState *state) {
  cairo_font_face_t *font_face;
  cairo_matrix_t matrix, invert_matrix;

  LOG(printf ("updateFont() font=%s\n", state->getFont()->getName()->c_str()));

  needFontUpdate = false;

  //FIXME: use cairo font engine?
  if (text)
    text->updateFont(state);
  
  currentFont = fontEngine->getFont (state->getFont(), doc, printing, xref);

  if (!currentFont)
    return;

  font_face = currentFont->getFontFace();
  cairo_set_font_face (cairo, font_face);

  use_show_text_glyphs = state->getFont()->hasToUnicodeCMap() &&
    cairo_surface_has_show_text_glyphs (cairo_get_target (cairo));
 
  double fontSize = state->getFontSize();
  const double *m = state->getTextMat();
  /* NOTE: adjusting by a constant is hack. The correct solution
   * is probably to use user-fonts and compute the scale on a per
   * glyph basis instead of for the entire font */
  double w = currentFont->getSubstitutionCorrection(state->getFont());
  matrix.xx = m[0] * fontSize * state->getHorizScaling() * w;
  matrix.yx = m[1] * fontSize * state->getHorizScaling() * w;
  matrix.xy = -m[2] * fontSize;
  matrix.yy = -m[3] * fontSize;
  matrix.x0 = 0;
  matrix.y0 = 0;

  LOG(printf ("font matrix: %f %f %f %f\n", matrix.xx, matrix.yx, matrix.xy, matrix.yy));

 /* Make sure the font matrix is invertible before setting it.  cairo
  * will blow up if we give it a matrix that's not invertible, so we
  * need to check before passing it to cairo_set_font_matrix. Ignoring it
  * is likely to give better results than not rendering anything at
  * all. See #18254.
  */
  invert_matrix = matrix;
  if (cairo_matrix_invert(&invert_matrix)) {
    error(errSyntaxWarning, -1, "font matrix not invertible");
    text_matrix_valid = false;
    return;
  }

  cairo_set_font_matrix (cairo, &matrix);
  text_matrix_valid = true;
}

/* Tolerance in pixels for checking if strokes are horizontal or vertical
 * lines in device space */
#define STROKE_COORD_TOLERANCE 0.5

/* Align stroke coordinate i if the point is the start or end of a
 * horizontal or vertical line */
void CairoOutputDev::alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y)
{
  double x1, y1, x2, y2;
  bool align = false;

  x1 = subpath->getX(i);
  y1 = subpath->getY(i);
  cairo_user_to_device (cairo, &x1, &y1);

  // Does the current coord and prev coord form a horiz or vert line?
  if (i > 0 && !subpath->getCurve(i - 1)) {
    x2 = subpath->getX(i - 1);
    y2 = subpath->getY(i - 1);
    cairo_user_to_device (cairo, &x2, &y2);
    if (fabs(x2 - x1) < STROKE_COORD_TOLERANCE || fabs(y2 - y1) < STROKE_COORD_TOLERANCE)
      align = true;
  }

  // Does the current coord and next coord form a horiz or vert line?
  if (i < subpath->getNumPoints() - 1 && !subpath->getCurve(i + 1)) {
    x2 = subpath->getX(i + 1);
    y2 = subpath->getY(i + 1);
    cairo_user_to_device (cairo, &x2, &y2);
    if (fabs(x2 - x1) < STROKE_COORD_TOLERANCE || fabs(y2 - y1) < STROKE_COORD_TOLERANCE)
      align = true;
  }

  *x = subpath->getX(i);
  *y = subpath->getY(i);
  if (align) {
    /* see http://www.cairographics.org/FAQ/#sharp_lines */
    cairo_user_to_device (cairo, x, y);
    *x = floor(*x) + 0.5;
    *y = floor(*y) + 0.5;
    cairo_device_to_user (cairo, x, y);
  }
}

#undef STROKE_COORD_TOLERANCE

void CairoOutputDev::doPath(cairo_t *cairo, GfxState *state, GfxPath *path) {
  GfxSubpath *subpath;
  int i, j;
  double x, y;
  cairo_new_path (cairo);
  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    if (subpath->getNumPoints() > 0) {
      if (align_stroke_coords) {
        alignStrokeCoords(subpath, 0, &x, &y);
      } else {
        x = subpath->getX(0);
        y = subpath->getY(0);
      }
      cairo_move_to (cairo, x, y);
      j = 1;
      while (j < subpath->getNumPoints()) {
	if (subpath->getCurve(j)) {
	  if (align_stroke_coords) {
            alignStrokeCoords(subpath, j + 2, &x, &y);
          } else {
            x = subpath->getX(j+2);
            y = subpath->getY(j+2);
          }
	  cairo_curve_to( cairo,
			  subpath->getX(j), subpath->getY(j),
			  subpath->getX(j+1), subpath->getY(j+1),
			  x, y);

	  j += 3;
	} else {
	  if (align_stroke_coords) {
            alignStrokeCoords(subpath, j, &x, &y);
          } else {
            x = subpath->getX(j);
            y = subpath->getY(j);
          }
          cairo_line_to (cairo, x, y);
	  ++j;
	}
      }
      if (subpath->isClosed()) {
	LOG (printf ("close\n"));
	cairo_close_path (cairo);
      }
    }
  }
}

void CairoOutputDev::stroke(GfxState *state) {
  if (inType3Char) {
      GfxGray gray;
      state->getFillGray(&gray);
      if (colToDbl(gray) > 0.5)
	  return;
  }

  if (adjusted_stroke_width)
    align_stroke_coords = true;
  doPath (cairo, state, state->getPath());
  align_stroke_coords = false;
  cairo_set_source (cairo, stroke_pattern);
  LOG(printf ("stroke\n"));
  if (strokePathClip) {
    cairo_push_group (cairo);
    cairo_stroke (cairo);
    cairo_pop_group_to_source (cairo);
    fillToStrokePathClip (state);
  } else {
    cairo_stroke (cairo);
  }
  if (cairo_shape) {
    doPath (cairo_shape, state, state->getPath());
    cairo_stroke (cairo_shape);
  }
}

void CairoOutputDev::fill(GfxState *state) {
  if (inType3Char) {
      GfxGray gray;
      state->getFillGray(&gray);
      if (colToDbl(gray) > 0.5)
	  return;
  }

  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
  cairo_set_source (cairo, fill_pattern);
  LOG(printf ("fill\n"));
  //XXX: how do we get the path
  if (mask) {
    cairo_save (cairo);
    cairo_clip (cairo);
    if (strokePathClip) {
      cairo_push_group (cairo);
      fillToStrokePathClip (state);
      cairo_pop_group_to_source (cairo);
    }
    cairo_set_matrix (cairo, &mask_matrix);
    cairo_mask (cairo, mask);
    cairo_restore (cairo);
  } else if (strokePathClip) {
    fillToStrokePathClip(state);
  } else {
    cairo_fill (cairo);
  }
  if (cairo_shape) {
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
    doPath (cairo_shape, state, state->getPath());
    cairo_fill (cairo_shape);
  }
}

void CairoOutputDev::eoFill(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_set_source (cairo, fill_pattern);
  LOG(printf ("fill-eo\n"));

  if (mask) {
    cairo_save (cairo);
    cairo_clip (cairo);
    cairo_set_matrix (cairo, &mask_matrix);
    cairo_mask (cairo, mask);
    cairo_restore (cairo);
  } else {
    cairo_fill (cairo);
  }
  if (cairo_shape) {
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_EVEN_ODD);
    doPath (cairo_shape, state, state->getPath());
    cairo_fill (cairo_shape);
  }

}

bool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat, Object *str,
					const double *pmat, int paintType, int /*tilingType*/, Dict *resDict,
					const double *mat, const double *bbox,
					int x0, int y0, int x1, int y1,
					double xStep, double yStep)
{
  PDFRectangle box;
  Gfx *gfx;
  cairo_pattern_t *pattern;
  cairo_surface_t *surface;
  cairo_matrix_t matrix;
  cairo_matrix_t pattern_matrix;
  cairo_t *old_cairo;
  double xMin, yMin, xMax, yMax;
  double width, height;
  double scaleX, scaleY;
  int surface_width, surface_height;
  StrokePathClip *strokePathTmp;
  bool adjusted_stroke_width_tmp;
  cairo_pattern_t *maskTmp;

  width = bbox[2] - bbox[0];
  height = bbox[3] - bbox[1];

  if (xStep != width || yStep != height)
    return false;
  /* TODO: implement the other cases here too */

  // Find the width and height of the transformed pattern
  cairo_get_matrix (cairo, &matrix);
  cairo_matrix_init (&pattern_matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
  cairo_matrix_multiply (&matrix, &matrix, &pattern_matrix);

  double widthX = width, widthY = 0;
  cairo_matrix_transform_distance (&matrix, &widthX, &widthY);
  surface_width = ceil (sqrt (widthX * widthX + widthY * widthY));

  double heightX = 0, heightY = height;
  cairo_matrix_transform_distance (&matrix, &heightX, &heightY);
  surface_height = ceil (sqrt (heightX * heightX + heightY * heightY));
  scaleX = surface_width / width;
  scaleY = surface_height / height;

  surface = cairo_surface_create_similar (cairo_get_target (cairo),
					  CAIRO_CONTENT_COLOR_ALPHA,
					  surface_width, surface_height);
  if (cairo_surface_status (surface))
    return false;

  old_cairo = cairo;
  cairo = cairo_create (surface);
  cairo_surface_destroy (surface);
  setContextAntialias(cairo, antialias);

  box.x1 = bbox[0]; box.y1 = bbox[1];
  box.x2 = bbox[2]; box.y2 = bbox[3];
  cairo_scale (cairo, scaleX, scaleY);
  cairo_translate (cairo, -box.x1, -box.y1);

  strokePathTmp = strokePathClip;
  strokePathClip = nullptr;
  adjusted_stroke_width_tmp = adjusted_stroke_width;
  maskTmp = mask;
  mask = nullptr;
  gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, gfxA);
  if (paintType == 2)
    inUncoloredPattern = true;
  gfx->display(str);
  if (paintType == 2)
    inUncoloredPattern = false;
  delete gfx;
  strokePathClip = strokePathTmp;
  adjusted_stroke_width = adjusted_stroke_width_tmp;
  mask = maskTmp;

  pattern = cairo_pattern_create_for_surface (cairo_get_target (cairo));
  cairo_destroy (cairo);
  cairo = old_cairo;
  if (cairo_pattern_status (pattern))
    return false;

  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
  cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);

  cairo_matrix_init_scale (&matrix, scaleX, scaleY);
  cairo_matrix_translate (&matrix, -box.x1, -box.y1);
  cairo_pattern_set_matrix (pattern, &matrix);

  cairo_transform (cairo, &pattern_matrix);
  cairo_set_source (cairo, pattern);
  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
  if (strokePathClip) {
    fillToStrokePathClip(state);
  } else {
    cairo_fill (cairo);
  }

  cairo_pattern_destroy (pattern);

  return true;
}

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
bool CairoOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *shading)
{
  // Function shaded fills are subdivided to rectangles that are the
  // following size in device space.  Note when printing this size is
  // in points.
  const int subdivide_pixels = 10;

  double x_begin, x_end, x1, x2;
  double y_begin, y_end, y1, y2;
  double x_step;
  double y_step;
  GfxColor color;
  GfxRGB rgb;
  cairo_matrix_t mat;

  const double *matrix = shading->getMatrix();
  mat.xx = matrix[0];
  mat.yx = matrix[1];
  mat.xy = matrix[2];
  mat.yy = matrix[3];
  mat.x0 = matrix[4];
  mat.y0 = matrix[5];
  if (cairo_matrix_invert(&mat)) {
    error(errSyntaxWarning, -1, "matrix not invertible\n");
    return false;
    }

  // get cell size in pattern space
  x_step = y_step = subdivide_pixels;
  cairo_matrix_transform_distance (&mat, &x_step, &y_step);

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_mesh ();
  cairo_pattern_set_matrix(fill_pattern, &mat);
  shading->getDomain(&x_begin, &y_begin, &x_end, &y_end);

  for (x1 = x_begin; x1 < x_end; x1 += x_step) {
    x2 = x1 + x_step;
    if (x2 > x_end)
      x2 = x_end;

    for (y1 = y_begin; y1 < y_end; y1 += y_step) {
      y2 = y1 + y_step;
      if (y2 > y_end)
	y2 = y_end;

      cairo_mesh_pattern_begin_patch (fill_pattern);
      cairo_mesh_pattern_move_to (fill_pattern, x1, y1);
      cairo_mesh_pattern_line_to (fill_pattern, x2, y1);
      cairo_mesh_pattern_line_to (fill_pattern, x2, y2);
      cairo_mesh_pattern_line_to (fill_pattern, x1, y2);

      shading->getColor(x1, y1, &color);
      shading->getColorSpace()->getRGB(&color, &rgb);
      cairo_mesh_pattern_set_corner_color_rgb (fill_pattern, 0,
					       colToDbl(rgb.r),
					       colToDbl(rgb.g),
					       colToDbl(rgb.b));

      shading->getColor(x2, y1, &color);
      shading->getColorSpace()->getRGB(&color, &rgb);
      cairo_mesh_pattern_set_corner_color_rgb (fill_pattern, 1,
					       colToDbl(rgb.r),
					       colToDbl(rgb.g),
					       colToDbl(rgb.b));

      shading->getColor(x2, y2, &color);
      shading->getColorSpace()->getRGB(&color, &rgb);
      cairo_mesh_pattern_set_corner_color_rgb (fill_pattern, 2,
					       colToDbl(rgb.r),
					       colToDbl(rgb.g),
					       colToDbl(rgb.b));

      shading->getColor(x1, y2, &color);
      shading->getColorSpace()->getRGB(&color, &rgb);
      cairo_mesh_pattern_set_corner_color_rgb (fill_pattern, 3,
					       colToDbl(rgb.r),
					       colToDbl(rgb.g),
					       colToDbl(rgb.b));

      cairo_mesh_pattern_end_patch (fill_pattern);
    }
  }

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

  return true;
}
#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0) */

bool CairoOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) {
  double x0, y0, x1, y1;
  double dx, dy;

  shading->getCoords(&x0, &y0, &x1, &y1);
  dx = x1 - x0;
  dy = y1 - y0;

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_linear (x0 + tMin * dx, y0 + tMin * dy,
					      x0 + tMax * dx, y0 + tMax * dy);
  if (!shading->getExtend0() && !shading->getExtend1())
    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_NONE);
  else
    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_PAD);

  LOG (printf ("axial-sh\n"));

  // TODO: use the actual stops in the shading in the case
  // of linear interpolation (Type 2 Exponential functions with N=1)
  return false;
}

bool CairoOutputDev::axialShadedSupportExtend(GfxState *state, GfxAxialShading *shading)
{
  return (shading->getExtend0() == shading->getExtend1());
}

bool CairoOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax) {
  double x0, y0, r0, x1, y1, r1;
  double dx, dy, dr;
  cairo_matrix_t matrix;
  double scale;

  shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
  dx = x1 - x0;
  dy = y1 - y0;
  dr = r1 - r0;

  // Cairo/pixman do not work well with a very large or small scaled
  // matrix.  See cairo bug #81657.
  //
  // As a workaround, scale the pattern by the average of the vertical
  // and horizontal scaling of the current transformation matrix.
  cairo_get_matrix(cairo, &matrix);
  scale = (sqrt(matrix.xx * matrix.xx + matrix.yx * matrix.yx)
	   + sqrt(matrix.xy * matrix.xy + matrix.yy * matrix.yy)) / 2;
  cairo_matrix_init_scale(&matrix, scale, scale);

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_radial ((x0 + sMin * dx) * scale,
					      (y0 + sMin * dy) * scale,
					      (r0 + sMin * dr) * scale,
					      (x0 + sMax * dx) * scale,
					      (y0 + sMax * dy) * scale,
					      (r0 + sMax * dr) * scale);
  cairo_pattern_set_matrix(fill_pattern, &matrix);
  if (shading->getExtend0() && shading->getExtend1())
    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_PAD);
  else
    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_NONE);

  LOG (printf ("radial-sh\n"));

  return false;
}

bool CairoOutputDev::radialShadedSupportExtend(GfxState *state, GfxRadialShading *shading)
{
  return (shading->getExtend0() == shading->getExtend1());
}

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
bool CairoOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading)
{
  double x0, y0, x1, y1, x2, y2;
  GfxColor color[3];
  int i, j;
  GfxRGB rgb;

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_mesh ();

  for (i = 0; i < shading->getNTriangles(); i++) {
    if (shading->isParameterized()) {
      double color0, color1, color2;
      shading->getTriangle(i, &x0, &y0, &color0,
                              &x1, &y1, &color1,
                              &x2, &y2, &color2);
      shading->getParameterizedColor(color0, &color[0]);
      shading->getParameterizedColor(color1, &color[1]);
      shading->getParameterizedColor(color2, &color[2]);
    } else {
      shading->getTriangle(i,
                           &x0, &y0, &color[0],
                           &x1, &y1, &color[1],
                           &x2, &y2, &color[2]);

    }

    cairo_mesh_pattern_begin_patch (fill_pattern);

    cairo_mesh_pattern_move_to (fill_pattern, x0, y0);
    cairo_mesh_pattern_line_to (fill_pattern, x1, y1);
    cairo_mesh_pattern_line_to (fill_pattern, x2, y2);

    for (j = 0; j < 3; j++) {
	shading->getColorSpace()->getRGB(&color[j], &rgb);
	cairo_mesh_pattern_set_corner_color_rgb (fill_pattern, j,
						 colToDbl(rgb.r),
						 colToDbl(rgb.g),
						 colToDbl(rgb.b));
    }

    cairo_mesh_pattern_end_patch (fill_pattern);
  }

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

  return true;
}

bool CairoOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading)
{
  int i, j, k;

  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_mesh ();

  for (i = 0; i < shading->getNPatches(); i++) {
    const GfxPatch *patch = shading->getPatch(i);
    GfxColor color;
    GfxRGB rgb;

    cairo_mesh_pattern_begin_patch (fill_pattern);

    cairo_mesh_pattern_move_to (fill_pattern, patch->x[0][0], patch->y[0][0]);
    cairo_mesh_pattern_curve_to (fill_pattern,
			    patch->x[0][1], patch->y[0][1],
			    patch->x[0][2], patch->y[0][2],
			    patch->x[0][3], patch->y[0][3]);

    cairo_mesh_pattern_curve_to (fill_pattern,
			    patch->x[1][3], patch->y[1][3],
			    patch->x[2][3], patch->y[2][3],
			    patch->x[3][3], patch->y[3][3]);

    cairo_mesh_pattern_curve_to (fill_pattern,
			    patch->x[3][2], patch->y[3][2],
			    patch->x[3][1], patch->y[3][1],
			    patch->x[3][0], patch->y[3][0]);

    cairo_mesh_pattern_curve_to (fill_pattern,
			    patch->x[2][0], patch->y[2][0],
			    patch->x[1][0], patch->y[1][0],
			    patch->x[0][0], patch->y[0][0]);

    cairo_mesh_pattern_set_control_point (fill_pattern, 0, patch->x[1][1], patch->y[1][1]);
    cairo_mesh_pattern_set_control_point (fill_pattern, 1, patch->x[1][2], patch->y[1][2]);
    cairo_mesh_pattern_set_control_point (fill_pattern, 2, patch->x[2][2], patch->y[2][2]);
    cairo_mesh_pattern_set_control_point (fill_pattern, 3, patch->x[2][1], patch->y[2][1]);

    for (j = 0; j < 4; j++) {
      int u, v;

      switch (j) {
	case 0:
	  u = 0; v = 0;
	  break;
	case 1:
	  u = 0; v = 1;
	  break;
	case 2:
	  u = 1; v = 1;
	  break;
	case 3:
	  u = 1; v = 0;
	  break;
      }

      if (shading->isParameterized()) {
	shading->getParameterizedColor (patch->color[u][v].c[0], &color);
      } else {
	for (k = 0; k < shading->getColorSpace()->getNComps(); k++) {
          // simply cast to the desired type; that's all what is needed.
	  color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
	}
      }

      shading->getColorSpace()->getRGB(&color, &rgb);
      cairo_mesh_pattern_set_corner_color_rgb (fill_pattern, j,
					       colToDbl(rgb.r),
					       colToDbl(rgb.g),
					       colToDbl(rgb.b));
    }
    cairo_mesh_pattern_end_patch (fill_pattern);
  }

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

  return true;
}
#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0) */

void CairoOutputDev::clip(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
  cairo_clip (cairo);
  LOG (printf ("clip\n"));
  if (cairo_shape) {
    doPath (cairo_shape, state, state->getPath());
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
    cairo_clip (cairo_shape);
  }
}

void CairoOutputDev::eoClip(GfxState *state) {
  doPath (cairo, state, state->getPath());
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_clip (cairo);
  LOG (printf ("clip-eo\n"));
  if (cairo_shape) {
    doPath (cairo_shape, state, state->getPath());
    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_EVEN_ODD);
    cairo_clip (cairo_shape);
  }

}

void CairoOutputDev::clipToStrokePath(GfxState *state) {
  LOG(printf("clip-to-stroke-path\n"));
  strokePathClip = (StrokePathClip*)gmalloc (sizeof(*strokePathClip));
  strokePathClip->path = state->getPath()->copy();
  cairo_get_matrix (cairo, &strokePathClip->ctm);
  strokePathClip->line_width = cairo_get_line_width (cairo);
  strokePathClip->dash_count = cairo_get_dash_count (cairo);
  if (strokePathClip->dash_count) {
    strokePathClip->dashes = (double*) gmallocn (sizeof(double), strokePathClip->dash_count);
    cairo_get_dash (cairo, strokePathClip->dashes, &strokePathClip->dash_offset);
  } else {
    strokePathClip->dashes = nullptr;
  }
  strokePathClip->cap = cairo_get_line_cap (cairo);
  strokePathClip->join = cairo_get_line_join (cairo);
  strokePathClip->miter = cairo_get_miter_limit (cairo);
  strokePathClip->ref_count = 1;
}

void CairoOutputDev::fillToStrokePathClip(GfxState *state) {
  cairo_save (cairo);

  cairo_set_matrix (cairo, &strokePathClip->ctm);
  cairo_set_line_width (cairo, strokePathClip->line_width);
  cairo_set_dash (cairo, strokePathClip->dashes, strokePathClip->dash_count, strokePathClip->dash_offset);
  cairo_set_line_cap (cairo, strokePathClip->cap);
  cairo_set_line_join (cairo, strokePathClip->join);
  cairo_set_miter_limit (cairo, strokePathClip->miter);
  doPath (cairo, state, strokePathClip->path);
  cairo_stroke (cairo);

  cairo_restore (cairo);
}

void CairoOutputDev::beginString(GfxState *state, const GooString *s)
{
  int len = s->getLength();

  if (needFontUpdate)
    updateFont(state);

  if (!currentFont)
    return;

  glyphs = (cairo_glyph_t *) gmallocn (len, sizeof (cairo_glyph_t));
  glyphCount = 0;
  if (use_show_text_glyphs) {
    clusters = (cairo_text_cluster_t *) gmallocn (len, sizeof (cairo_text_cluster_t));
    clusterCount = 0;
    utf8Max = len*2; // start with twice the number of glyphs. we will realloc if we need more.
    utf8 = (char *) gmalloc (utf8Max);
    utf8Count = 0;
  }
}

void CairoOutputDev::drawChar(GfxState *state, double x, double y,
			      double dx, double dy,
			      double originX, double originY,
			      CharCode code, int nBytes, Unicode *u, int uLen)
{
  if (currentFont) {
    glyphs[glyphCount].index = currentFont->getGlyph (code, u, uLen);
    glyphs[glyphCount].x = x - originX;
    glyphs[glyphCount].y = y - originY;
    glyphCount++;
    if (use_show_text_glyphs) {
      GooString enc("UTF-8");
      UnicodeMap *utf8Map = globalParams->getUnicodeMap(&enc);
      if (utf8Max - utf8Count < uLen*6) {
        // utf8 encoded characters can be up to 6 bytes
	if (utf8Max > uLen*6)
	  utf8Max *= 2;
	else
	  utf8Max += 2*uLen*6;
	utf8 = (char *) grealloc (utf8, utf8Max);
      }
      clusters[clusterCount].num_bytes = 0;
      for (int i = 0; i < uLen; i++) {
	int size = utf8Map->mapUnicode(u[i], utf8 + utf8Count, utf8Max - utf8Count);
	utf8Count += size;
	clusters[clusterCount].num_bytes += size;
      }
      clusters[clusterCount].num_glyphs = 1;
      clusterCount++;
    }
  }

  if (!text)
    return;
  actualText->addChar (state, x, y, dx, dy, code, nBytes, u, uLen);
}

void CairoOutputDev::endString(GfxState *state)
{
  int render;

  if (!currentFont)
    return;

  // endString can be called without a corresponding beginString. If this
  // happens glyphs will be null so don't draw anything, just return.
  // XXX: OutputDevs should probably not have to deal with this...
  if (!glyphs)
    return;

  // ignore empty strings and invisible text -- this is used by
  // Acrobat Capture
  render = state->getRender();
  if (render == 3 || glyphCount == 0 || !text_matrix_valid) {
    goto finish;
  }

  if (!(render & 1)) {
    LOG (printf ("fill string\n"));
    cairo_set_source (cairo, fill_pattern);
    if (use_show_text_glyphs)
      cairo_show_text_glyphs (cairo, utf8, utf8Count, glyphs, glyphCount, clusters, clusterCount, (cairo_text_cluster_flags_t)0);
    else
        cairo_show_glyphs (cairo, glyphs, glyphCount);
    if (cairo_shape)
      cairo_show_glyphs (cairo_shape, glyphs, glyphCount);
  }

  // stroke
  if ((render & 3) == 1 || (render & 3) == 2) {
    LOG (printf ("stroke string\n"));
    cairo_set_source (cairo, stroke_pattern);
    cairo_glyph_path (cairo, glyphs, glyphCount);
    cairo_stroke (cairo);
    if (cairo_shape) {
      cairo_glyph_path (cairo_shape, glyphs, glyphCount);
      cairo_stroke (cairo_shape);
    }
  }

  // clip
  if ((render & 4)) {
    LOG (printf ("clip string\n"));
    // append the glyph path to textClipPath.

    // set textClipPath as the currentPath
    if (textClipPath) {
      cairo_append_path (cairo, textClipPath);
      if (cairo_shape) {
	cairo_append_path (cairo_shape, textClipPath);
      }
      cairo_path_destroy (textClipPath);
    }
    
    // append the glyph path
    cairo_glyph_path (cairo, glyphs, glyphCount);
   
    // move the path back into textClipPath 
    // and clear the current path
    textClipPath = cairo_copy_path (cairo);
    cairo_new_path (cairo);
    if (cairo_shape) {
      cairo_new_path (cairo_shape);
    }
  }

finish:
  gfree (glyphs);
  glyphs = nullptr;
  if (use_show_text_glyphs) {
    gfree (clusters);
    clusters = nullptr;
    gfree (utf8);
    utf8 = nullptr;
  }
}


bool CairoOutputDev::beginType3Char(GfxState *state, double x, double y,
				      double dx, double dy,
				      CharCode code, Unicode *u, int uLen) {

  cairo_save (cairo);
  cairo_matrix_t matrix;

  const double *ctm = state->getCTM();
  matrix.xx = ctm[0];
  matrix.yx = ctm[1];
  matrix.xy = ctm[2];
  matrix.yy = ctm[3];
  matrix.x0 = ctm[4];
  matrix.y0 = ctm[5];
  /* Restore the original matrix and then transform to matrix needed for the
   * type3 font. This is ugly but seems to work. Perhaps there is a better way to do it?*/
  cairo_set_matrix(cairo, &orig_matrix);
  cairo_transform(cairo, &matrix);
  if (cairo_shape) {
    cairo_save (cairo_shape);
    cairo_set_matrix(cairo_shape, &orig_matrix);
    cairo_transform(cairo_shape, &matrix);
  }
  cairo_pattern_destroy(stroke_pattern);
  cairo_pattern_reference(fill_pattern);
  stroke_pattern = fill_pattern;
  return false;
}

void CairoOutputDev::endType3Char(GfxState *state) {
  cairo_restore (cairo);
  if (cairo_shape) {
    cairo_restore (cairo_shape);
  }
}

void CairoOutputDev::type3D0(GfxState *state, double wx, double wy) {
  t3_glyph_wx = wx;
  t3_glyph_wy = wy;
}

void CairoOutputDev::type3D1(GfxState *state, double wx, double wy,
			     double llx, double lly, double urx, double ury) {
  t3_glyph_wx = wx;
  t3_glyph_wy = wy;
  t3_glyph_bbox[0] = llx;
  t3_glyph_bbox[1] = lly;
  t3_glyph_bbox[2] = urx;
  t3_glyph_bbox[3] = ury;
  t3_glyph_has_bbox = true;
}

void CairoOutputDev::beginTextObject(GfxState *state) {
}

void CairoOutputDev::endTextObject(GfxState *state) {
  if (textClipPath) {
    // clip the accumulated text path
    cairo_append_path (cairo, textClipPath);
    cairo_clip (cairo);
    if (cairo_shape) {
      cairo_append_path (cairo_shape, textClipPath);
      cairo_clip (cairo_shape);
    }
    cairo_path_destroy (textClipPath);
    textClipPath = nullptr;
  }
}

void CairoOutputDev::beginActualText(GfxState *state, const GooString *text)
{
  if (this->text)
    actualText->begin(state, text);
}

void CairoOutputDev::endActualText(GfxState *state)
{
  if (text)
    actualText->end(state);
}

static inline int splashRound(SplashCoord x) {
  return (int)floor(x + 0.5);
}

static inline int splashCeil(SplashCoord x) {
  return (int)ceil(x);
}

static inline int splashFloor(SplashCoord x) {
  return (int)floor(x);
}

static
cairo_surface_t *cairo_surface_create_similar_clip (cairo_t *cairo, cairo_content_t content)
{
  cairo_pattern_t *pattern;
  cairo_surface_t *surface = nullptr;

  cairo_push_group_with_content (cairo, content);
  pattern = cairo_pop_group (cairo);
  cairo_pattern_get_surface (pattern, &surface);
  cairo_surface_reference (surface);
  cairo_pattern_destroy (pattern);
  return surface;
}



void CairoOutputDev::beginTransparencyGroup(GfxState * /*state*/, const double * /*bbox*/,
                                      GfxColorSpace * blendingColorSpace,
                                      bool /*isolated*/, bool knockout,
				      bool forSoftMask) {
  /* push color space */
  ColorSpaceStack* css = new ColorSpaceStack;
  css->cs = blendingColorSpace;
  css->knockout = knockout;
  cairo_get_matrix(cairo, &css->group_matrix);
  css->next = groupColorSpaceStack;
  groupColorSpaceStack = css;

  LOG(printf ("begin transparency group. knockout: %s\n", knockout ? "yes":"no"));

  if (knockout) {
    knockoutCount++;
    if (!cairo_shape) {
      /* create a surface for tracking the shape */
      cairo_surface_t *cairo_shape_surface = cairo_surface_create_similar_clip (cairo, CAIRO_CONTENT_ALPHA);
      cairo_shape = cairo_create (cairo_shape_surface);
      cairo_surface_destroy (cairo_shape_surface);
      setContextAntialias(cairo_shape, antialias);

      /* the color doesn't matter as long as it is opaque */
      cairo_set_source_rgb (cairo_shape, 0, 0, 0);
      cairo_matrix_t matrix;
      cairo_get_matrix (cairo, &matrix);
      cairo_set_matrix (cairo_shape, &matrix);
    }
  }
  if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) {
    /* we need to track the shape */
    cairo_push_group (cairo_shape);
  }
  if (0 && forSoftMask)
    cairo_push_group_with_content (cairo, CAIRO_CONTENT_ALPHA);
  else
    cairo_push_group (cairo);

  /* push_group has an implicit cairo_save() */
  if (knockout) {
    /*XXX: let's hope this matches the semantics needed */
    cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
  } else {
    cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
  }
}

void CairoOutputDev::endTransparencyGroup(GfxState * /*state*/) {
  if (group)
    cairo_pattern_destroy(group);
  group = cairo_pop_group (cairo);

  LOG(printf ("end transparency group\n"));

  if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) {
    if (shape)
      cairo_pattern_destroy(shape);
    shape = cairo_pop_group (cairo_shape);
  }
}

void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, const double * /*bbox*/) {
  LOG(printf ("paint transparency group\n"));

  cairo_save (cairo);
  cairo_set_matrix (cairo, &groupColorSpaceStack->group_matrix);

  if (shape) {
    /* OPERATOR_SOURCE w/ a mask is defined as (src IN mask) ADD (dest OUT mask)
     * however our source has already been clipped to mask so we only need to
     * do ADD and OUT */

    /* clear the shape mask */
    cairo_set_source (cairo, shape);
    cairo_set_operator (cairo, CAIRO_OPERATOR_DEST_OUT);
    cairo_paint (cairo);
    cairo_set_operator (cairo, CAIRO_OPERATOR_ADD);
  }
  cairo_set_source (cairo, group);

  if (!mask) {
    cairo_paint_with_alpha (cairo, fill_opacity);
    cairo_status_t status = cairo_status(cairo);
    if (status)
      printf("BAD status: %s\n", cairo_status_to_string(status));
  } else {
    if (fill_opacity < 1.0) {
      cairo_push_group(cairo);
    }
    cairo_save(cairo);
    cairo_set_matrix(cairo, &mask_matrix);
    cairo_mask(cairo, mask);
    cairo_restore(cairo);
    if (fill_opacity < 1.0) {
      cairo_pop_group_to_source(cairo);
      cairo_paint_with_alpha (cairo, fill_opacity);
    }
    cairo_pattern_destroy(mask);
    mask = nullptr;
  }

  if (shape) {
    if (cairo_shape) {
      cairo_set_source (cairo_shape, shape);
      cairo_paint (cairo_shape);
      cairo_set_source_rgb (cairo_shape, 0, 0, 0);
    }
    cairo_pattern_destroy (shape);
    shape = nullptr;
  }

  popTransparencyGroup();
  cairo_restore(cairo);
}

static int luminocity(uint32_t x)
{
  int r = (x >> 16) & 0xff;
  int g = (x >>  8) & 0xff;
  int b = (x >>  0) & 0xff;
  // an arbitrary integer approximation of .3*r + .59*g + .11*b
  int y = (r*19661+g*38666+b*7209 + 32829)>>16;
  return y;
}


/* XXX: do we need to deal with shape here? */
void CairoOutputDev::setSoftMask(GfxState * state, const double * bbox, bool alpha,
                                 Function * transferFunc, GfxColor * backdropColor) {
  cairo_pattern_destroy(mask);

  LOG(printf ("set softMask\n"));

  if (!alpha || transferFunc) {
    /* We need to mask according to the luminocity of the group.
     * So we paint the group to an image surface convert it to a luminocity map
     * and then use that as the mask. */

    /* Get clip extents in device space */
    double x1, y1, x2, y2, x_min, y_min, x_max, y_max;
    cairo_clip_extents(cairo, &x1, &y1, &x2, &y2);
    cairo_user_to_device(cairo, &x1, &y1);
    cairo_user_to_device(cairo, &x2, &y2);
    x_min = MIN(x1, x2);
    y_min = MIN(y1, y2);
    x_max = MAX(x1, x2);
    y_max = MAX(y1, y2);
    cairo_clip_extents(cairo, &x1, &y1, &x2, &y2);
    cairo_user_to_device(cairo, &x1, &y2);
    cairo_user_to_device(cairo, &x2, &y1);
    x_min = MIN(x_min,MIN(x1, x2));
    y_min = MIN(y_min,MIN(y1, y2));
    x_max = MAX(x_max,MAX(x1, x2));
    y_max = MAX(y_max,MAX(y1, y2));

    int width = (int)(ceil(x_max) - floor(x_min));
    int height = (int)(ceil(y_max) - floor(y_min));

    /* Get group device offset */
    double x_offset, y_offset;
    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
      cairo_surface_get_device_offset(cairo_get_group_target(cairo), &x_offset, &y_offset);
    } else {
      cairo_surface_t *pats;
      cairo_pattern_get_surface(group, &pats);
      cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
    }

    /* Adjust extents by group offset */
    x_min += x_offset;
    y_min += y_offset;

    cairo_surface_t *source = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
    cairo_t *maskCtx = cairo_create(source);
    setContextAntialias(maskCtx, antialias);

    //XXX: hopefully this uses the correct color space */
    if (!alpha && groupColorSpaceStack->cs) {
      GfxRGB backdropColorRGB;
      groupColorSpaceStack->cs->getRGB(backdropColor, &backdropColorRGB);
      /* paint the backdrop */
      cairo_set_source_rgb(maskCtx,
                           colToDbl(backdropColorRGB.r),
                           colToDbl(backdropColorRGB.g),
                           colToDbl(backdropColorRGB.b));
    }
    cairo_paint(maskCtx);

    /* Copy source ctm to mask ctm and translate origin so that the
     * mask appears it the same location on the source surface.  */
    cairo_matrix_t mat, tmat;
    cairo_matrix_init_translate(&tmat, -x_min, -y_min);
    cairo_get_matrix(cairo, &mat);
    cairo_matrix_multiply(&mat, &mat, &tmat);
    cairo_set_matrix(maskCtx, &mat);

    /* make the device offset of the new mask match that of the group */
    cairo_surface_set_device_offset(source, x_offset, y_offset);

    /* paint the group */
    cairo_set_source(maskCtx, group);
    cairo_paint(maskCtx);

    /* XXX status = cairo_status(maskCtx); */
    cairo_destroy(maskCtx);

    /* convert to a luminocity map */
    uint32_t *source_data = reinterpret_cast<uint32_t *>(cairo_image_surface_get_data(source));
    /* get stride in units of 32 bits */
    ptrdiff_t stride = cairo_image_surface_get_stride(source)/4;
    for (int y=0; y<height; y++) {
      for (int x=0; x<width; x++) {
	int lum = alpha ? fill_opacity : luminocity(source_data[y*stride + x]);
        if (transferFunc) {
          double lum_in, lum_out;
          lum_in = lum/256.0;
          transferFunc->transform(&lum_in, &lum_out);
          lum = (int)(lum_out * 255.0 + 0.5);
        }
        source_data[y*stride + x] = lum << 24;
      }
    }
    cairo_surface_mark_dirty (source);

    /* setup the new mask pattern */
    mask = cairo_pattern_create_for_surface(source);
    cairo_get_matrix(cairo, &mask_matrix);

    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
      cairo_pattern_set_matrix(mask, &mat);
    } else {
      cairo_matrix_t patMatrix;
      cairo_pattern_get_matrix(group, &patMatrix);
      /* Apply x_min, y_min offset to it appears in the same location as source. */
      cairo_matrix_multiply(&patMatrix, &patMatrix, &tmat);
      cairo_pattern_set_matrix(mask, &patMatrix);
    }

    cairo_surface_destroy(source);
  } else if (alpha) {
    mask = cairo_pattern_reference(group);
    cairo_get_matrix(cairo, &mask_matrix);
  }

  popTransparencyGroup();
}

void CairoOutputDev::popTransparencyGroup() {
  /* pop color space */
  ColorSpaceStack *css = groupColorSpaceStack;
  if (css->knockout) {
    knockoutCount--;
    if (!knockoutCount) {
      /* we don't need to track the shape anymore because
       * we are not above any knockout groups */
      cairo_destroy(cairo_shape);
      cairo_shape = nullptr;
    }
  }
  groupColorSpaceStack = css->next;
  delete css;
}


void CairoOutputDev::clearSoftMask(GfxState * /*state*/) {
  if (mask)
    cairo_pattern_destroy(mask);
  mask = nullptr;
}

/* Taken from cairo/doc/tutorial/src/singular.c */
static void
get_singular_values (const cairo_matrix_t *matrix,
		     double               *major,
		     double               *minor)
{
	double xx = matrix->xx, xy = matrix->xy;
	double yx = matrix->yx, yy = matrix->yy;

	double a = xx*xx+yx*yx;
	double b = xy*xy+yy*yy;
	double k = xx*xy+yx*yy;

	double f = (a+b) * .5;
	double g = (a-b) * .5;
	double delta = sqrt (g*g + k*k);

	if (major)
		*major = sqrt (f + delta);
	if (minor)
		*minor = sqrt (f - delta);
}

void CairoOutputDev::getScaledSize(const cairo_matrix_t *matrix,
                                   int                   orig_width,
				   int                   orig_height,
				   int                  *scaledWidth,
				   int                  *scaledHeight)
{
  double xScale;
  double yScale;
  if (orig_width > orig_height)
    get_singular_values (matrix, &xScale, &yScale);
  else
    get_singular_values (matrix, &yScale, &xScale);

  int tx, tx2, ty, ty2; /* the integer co-ordinates of the resulting image */
  if (xScale >= 0) {
    tx = splashRound(matrix->x0 - 0.01);
    tx2 = splashRound(matrix->x0 + xScale + 0.01) - 1;
  } else {
    tx = splashRound(matrix->x0 + 0.01) - 1;
    tx2 = splashRound(matrix->x0 + xScale - 0.01);
  }
  *scaledWidth = abs(tx2 - tx) + 1;
  //scaledWidth = splashRound(fabs(xScale));
  if (*scaledWidth == 0) {
    // technically, this should draw nothing, but it generally seems
    // better to draw a one-pixel-wide stripe rather than throwing it
    // away
    *scaledWidth = 1;
  }
  if (yScale >= 0) {
    ty = splashFloor(matrix->y0 + 0.01);
    ty2 = splashCeil(matrix->y0 + yScale - 0.01);
  } else {
    ty = splashCeil(matrix->y0 - 0.01);
    ty2 = splashFloor(matrix->y0 + yScale + 0.01);
  }
  *scaledHeight = abs(ty2 - ty);
  if (*scaledHeight == 0) {
    *scaledHeight = 1;
  }
}

cairo_filter_t
CairoOutputDev::getFilterForSurface(cairo_surface_t *image,
				    bool interpolate)
{
  if (interpolate)
    return CAIRO_FILTER_GOOD;

  int orig_width = cairo_image_surface_get_width (image);
  int orig_height = cairo_image_surface_get_height (image);
  if (orig_width == 0 || orig_height == 0)
	  return CAIRO_FILTER_NEAREST;

  /* When printing, don't change the interpolation. */
  if (printing)
    return CAIRO_FILTER_NEAREST;

  cairo_matrix_t matrix;
  cairo_get_matrix(cairo, &matrix);
  int scaled_width, scaled_height;
  getScaledSize (&matrix, orig_width, orig_height, &scaled_width, &scaled_height);

  /* When scale factor is >= 400% we don't interpolate. See bugs #25268, #9860 */
  if (scaled_width / orig_width >= 4 || scaled_height / orig_height >= 4)
	  return CAIRO_FILTER_NEAREST;

  return CAIRO_FILTER_GOOD;
}

void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
				   int width, int height, bool invert,
				   bool interpolate, bool inlineImg) {

  /* FIXME: Doesn't the image mask support any colorspace? */
  cairo_set_source (cairo, fill_pattern);

  /* work around a cairo bug when scaling 1x1 surfaces */
  if (width == 1 && height == 1) {
    ImageStream *imgStr;
    unsigned char pix;
    int invert_bit;

    imgStr = new ImageStream(str, width, 1, 1);
    imgStr->reset();
    imgStr->getPixel(&pix);
    imgStr->close();
    delete imgStr;

    invert_bit = invert ? 1 : 0;
    if (pix ^ invert_bit)
      return;

    cairo_save (cairo);
    cairo_rectangle (cairo, 0., 0., width, height);
    cairo_fill (cairo);
    cairo_restore (cairo);
    if (cairo_shape) {
      cairo_save (cairo_shape);
      cairo_rectangle (cairo_shape, 0., 0., width, height);
      cairo_fill (cairo_shape);
      cairo_restore (cairo_shape);
    }
    return;
  }

  /* shape is 1.0 for painted areas, 0.0 for unpainted ones */

  cairo_matrix_t matrix;
  cairo_get_matrix (cairo, &matrix);
  //XXX: it is possible that we should only do sub pixel positioning if 
  // we are rendering fonts */
  if (!printing && prescaleImages
      /* not rotated */
      && matrix.xy == 0 && matrix.yx == 0
      /* axes not flipped / not 180 deg rotated */
      && matrix.xx > 0 && (upsideDown() ? -1 : 1) * matrix.yy > 0) {
    drawImageMaskPrescaled(state, ref, str, width, height, invert, interpolate, inlineImg);
  } else {
    drawImageMaskRegular(state, ref, str, width, height, invert, interpolate, inlineImg);
  }

}

void CairoOutputDev::setSoftMaskFromImageMask(GfxState *state, Object *ref, Stream *str,
				   int width, int height, bool invert,
				   bool inlineImg, double *baseMatrix) {

  /* FIXME: Doesn't the image mask support any colorspace? */
  cairo_set_source (cairo, fill_pattern);

  /* work around a cairo bug when scaling 1x1 surfaces */
  if (width == 1 && height == 1) {
    ImageStream *imgStr;
    unsigned char pix;
    int invert_bit;

    imgStr = new ImageStream(str, width, 1, 1);
    imgStr->reset();
    imgStr->getPixel(&pix);
    imgStr->close();
    delete imgStr;

    invert_bit = invert ? 1 : 0;
    if (!(pix ^ invert_bit)) {
      cairo_save (cairo);
      cairo_rectangle (cairo, 0., 0., width, height);
      cairo_fill (cairo);
      cairo_restore (cairo);
      if (cairo_shape) {
        cairo_save (cairo_shape);
        cairo_rectangle (cairo_shape, 0., 0., width, height);
        cairo_fill (cairo_shape);
        cairo_restore (cairo_shape);
      }
    }
  } else {
    cairo_push_group_with_content (cairo, CAIRO_CONTENT_ALPHA);

    /* shape is 1.0 for painted areas, 0.0 for unpainted ones */

    cairo_matrix_t matrix;
    cairo_get_matrix (cairo, &matrix);
    //XXX: it is possible that we should only do sub pixel positioning if 
    // we are rendering fonts */
    if (!printing && prescaleImages && matrix.xy == 0.0 && matrix.yx == 0.0) {
      drawImageMaskPrescaled(state, ref, str, width, height, invert, false, inlineImg);
    } else {
      drawImageMaskRegular(state, ref, str, width, height, invert, false, inlineImg);
    }

    if (state->getFillColorSpace()->getMode() == csPattern) {
      cairo_set_source_rgb (cairo, 1, 1, 1);
      cairo_set_matrix (cairo, &mask_matrix);
      cairo_mask (cairo, mask);
    }

    if (mask)
      cairo_pattern_destroy (mask);
    mask = cairo_pop_group (cairo);
  }

  saveState(state);
  double bbox[4] = {0,0,1,1}; // dummy
  beginTransparencyGroup(state, bbox, state->getFillColorSpace(),
                         true, false, false);
}

void CairoOutputDev::unsetSoftMaskFromImageMask(GfxState *state, double *baseMatrix) {
  double bbox[4] = {0,0,1,1}; // dummy

  endTransparencyGroup(state);
  restoreState(state);
  paintTransparencyGroup(state, bbox);
  clearSoftMask(state);
}

void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream *str,
					  int width, int height, bool invert,
					  bool interpolate, bool inlineImg) {
  unsigned char *buffer;
  unsigned char *dest;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  int x, y, i, bit;
  ImageStream *imgStr;
  unsigned char *pix;
  cairo_matrix_t matrix;
  int invert_bit;
  ptrdiff_t row_stride;
  cairo_filter_t filter;

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

  image = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
  if (cairo_surface_status (image))
    goto cleanup;

  buffer = cairo_image_surface_get_data (image);
  row_stride = cairo_image_surface_get_stride (image);

  invert_bit = invert ? 1 : 0;

  for (y = 0; y < height; y++) {
    pix = imgStr->getLine();
    dest = buffer + y * row_stride;
    i = 0;
    bit = 0;
    for (x = 0; x < width; x++) {
      if (bit == 0)
	dest[i] = 0;
      if (!(pix[x] ^ invert_bit)) {
#ifdef WORDS_BIGENDIAN
	dest[i] |= (1 << (7 - bit));
#else
	dest[i] |= (1 << bit);
#endif
      }
      bit++;
      if (bit > 7) {
	bit = 0;
	i++;
      }
    }
  }

  filter = getFilterForSurface (image, interpolate);

  cairo_surface_mark_dirty (image);
  pattern = cairo_pattern_create_for_surface (image);
  cairo_surface_destroy (image);
  if (cairo_pattern_status (pattern))
    goto cleanup;

  LOG (printf ("drawImageMask %dx%d\n", width, height));

  cairo_pattern_set_filter (pattern, filter);

  cairo_matrix_init_translate (&matrix, 0, height);
  cairo_matrix_scale (&matrix, width, -height);
  cairo_pattern_set_matrix (pattern, &matrix);
  if (cairo_pattern_status (pattern)) {
    cairo_pattern_destroy (pattern);
    goto cleanup;
  }

  if (state->getFillColorSpace()->getMode() == csPattern) {
    mask = cairo_pattern_reference (pattern);
    cairo_get_matrix (cairo, &mask_matrix);
  } else if (!printing) {
    cairo_save (cairo);
    cairo_rectangle (cairo, 0., 0., 1., 1.);
    cairo_clip (cairo);
    if (strokePathClip) {
      cairo_push_group (cairo);
      fillToStrokePathClip (state);
      cairo_pop_group_to_source (cairo);
    }
    cairo_mask (cairo, pattern);
    cairo_restore (cairo);
  } else {
    cairo_mask (cairo, pattern);
  }

  if (cairo_shape) {
    cairo_save (cairo_shape);
    cairo_set_source (cairo_shape, pattern);
    if (!printing) {
      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
      cairo_fill (cairo_shape);
    } else {
      cairo_mask (cairo_shape, pattern);
    }
    cairo_restore (cairo_shape);
  }

  cairo_pattern_destroy (pattern);

cleanup:
  imgStr->close();
  delete imgStr;
}


void CairoOutputDev::drawImageMaskPrescaled(GfxState *state, Object *ref, Stream *str,
					    int width, int height, bool invert,
					    bool interpolate, bool inlineImg) {
  unsigned char *buffer;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  ImageStream *imgStr;
  unsigned char *pix;
  cairo_matrix_t matrix;
  int invert_bit;
  ptrdiff_t row_stride;

  /* cairo does a very poor job of scaling down images so we scale them ourselves */

  LOG (printf ("drawImageMaskPrescaled %dx%d\n", width, height));

  /* this scaling code is adopted from the splash image scaling code */
  cairo_get_matrix(cairo, &matrix);
#if 0
  printf("[%f %f], [%f %f], %f %f\n", matrix.xx, matrix.xy, matrix.yx, matrix.yy, matrix.x0, matrix.y0);
#endif
  /* this whole computation should be factored out */
  double xScale = matrix.xx;
  double yScale = matrix.yy;
  int tx, tx2, ty, ty2; /* the integer co-ordinates of the resulting image */
  int scaledHeight;
  int scaledWidth;
  if (xScale >= 0) {
    tx = splashRound(matrix.x0 - 0.01);
    tx2 = splashRound(matrix.x0 + xScale + 0.01) - 1;
  } else {
    tx = splashRound(matrix.x0 + 0.01) - 1;
    tx2 = splashRound(matrix.x0 + xScale - 0.01);
  }
  scaledWidth = abs(tx2 - tx) + 1;
  //scaledWidth = splashRound(fabs(xScale));
  if (scaledWidth == 0) {
    // technically, this should draw nothing, but it generally seems
    // better to draw a one-pixel-wide stripe rather than throwing it
    // away
    scaledWidth = 1;
  }
  if (yScale >= 0) {
    ty = splashFloor(matrix.y0 + 0.01);
    ty2 = splashCeil(matrix.y0 + yScale - 0.01);
  } else {
    ty = splashCeil(matrix.y0 - 0.01);
    ty2 = splashFloor(matrix.y0 + yScale + 0.01);
  }
  scaledHeight = abs(ty2 - ty);
  if (scaledHeight == 0) {
    scaledHeight = 1;
  }
#if 0
  printf("xscale: %g, yscale: %g\n", xScale, yScale);
  printf("width: %d, height: %d\n", width, height);
  printf("scaledWidth: %d, scaledHeight: %d\n", scaledWidth, scaledHeight);
#endif

  /* compute the required padding */
  /* Padding is used to preserve the aspect ratio.
     We compute total_pad to make (height+total_pad)/scaledHeight as close to height/yScale as possible */
  int head_pad = 0;
  int tail_pad = 0;
  int total_pad = splashRound(height*(scaledHeight/fabs(yScale)) - height);

  /* compute the two pieces of padding */
  if (total_pad > 0) {
    //XXX: i'm not positive fabs() is correct
    float tail_error = fabs(matrix.y0 - ty);
    float head_error = fabs(ty2 - (matrix.y0 + yScale));
    float tail_fraction = tail_error/(tail_error + head_error);
    tail_pad = splashRound(total_pad*tail_fraction);
    head_pad = total_pad - tail_pad;
  } else {
    tail_pad = 0;
    head_pad = 0;
  }
  int origHeight = height;
  height += tail_pad;
  height += head_pad;
#if 0
  printf("head_pad: %d tail_pad: %d\n", head_pad, tail_pad);
  printf("origHeight: %d height: %d\n", origHeight, height);
  printf("ty: %d, ty2: %d\n", ty, ty2);
#endif

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

  invert_bit = invert ? 1 : 0;

  image = cairo_image_surface_create (CAIRO_FORMAT_A8, scaledWidth, scaledHeight);
  if (cairo_surface_status (image)) {
    imgStr->close();
    delete imgStr;
    return;
  }

  buffer = cairo_image_surface_get_data (image);
  row_stride = cairo_image_surface_get_stride (image);

  int yp = height / scaledHeight;
  int yq = height % scaledHeight;
  int xp = width / scaledWidth;
  int xq = width % scaledWidth;
  int yt = 0;
  int origHeight_c = origHeight;
  /* use MIN() because yp might be > origHeight because of padding */
  unsigned char *pixBuf = (unsigned char *)malloc(MIN(yp+1, origHeight)*width);
  int lastYStep = 1;
  int total = 0;
  for (int y = 0; y < scaledHeight; y++) {
    // y scale Bresenham
    int yStep = yp;
    yt += yq;

    if (yt >= scaledHeight) {
      yt -= scaledHeight;
      ++yStep;
    }

    // read row (s) from image ignoring the padding as appropriate
    {
      int n = (yp > 0) ? yStep : lastYStep;
      total += n;
      if (n > 0) {
	unsigned char *p = pixBuf;
	int head_pad_count = head_pad;
	int origHeight_count = origHeight;
	int tail_pad_count = tail_pad;
	for (int i=0; i<n; i++) {
	  // get row
	  if (head_pad_count) {
	    head_pad_count--;
	  } else if (origHeight_count) {
	    pix = imgStr->getLine();
	    for (int j=0; j<width; j++) {
	      if (pix[j] ^ invert_bit)
		p[j] = 0;
	      else
		p[j] = 255;
	    }
	    origHeight_count--;
	    p += width;
	  } else if (tail_pad_count) {
	    tail_pad_count--;
	  } else {
	    printf("%d %d\n", n, total);
	    assert(0 && "over run\n");
	  }
	}
      }
    }

    lastYStep = yStep;
    int k1 = y;

    int xt = 0;
    int xSrc = 0;
    int x1 = k1;
    int n = yStep > 0 ? yStep : 1;
    int origN = n;

    /* compute the size of padding and pixels that will be used for this row */
    int head_pad_size = MIN(n, head_pad);
    n -= head_pad_size;
    head_pad -= MIN(head_pad_size, yStep);

    int pix_size = MIN(n, origHeight);
    n -= pix_size;
    origHeight -= MIN(pix_size, yStep);

    int tail_pad_size = MIN(n, tail_pad);
    n -= tail_pad_size;
    tail_pad -= MIN(tail_pad_size, yStep);
    if (n != 0) {
      printf("n = %d (%d %d %d)\n", n, head_pad_size, pix_size, tail_pad_size);
      assert(n == 0);
    }

    for (int x = 0; x < scaledWidth; ++x) {
      int xStep = xp;
      xt += xq;
      if (xt >= scaledWidth) {
	xt -= scaledWidth;
	++xStep;
      }
      int m = xStep > 0 ? xStep : 1;
      float pixAcc0 = 0;
      /* could m * head_pad_size * tail_pad_size  overflow? */
      if (invert_bit) {
	pixAcc0 += m * head_pad_size * tail_pad_size * 255;
      } else {
	pixAcc0 += m * head_pad_size * tail_pad_size * 0;
      }
      /* Accumulate all of the source pixels for the destination pixel */
      for (int i = 0; i < pix_size; ++i) {
	for (int j = 0; j< m; ++j) {
	  if (xSrc + i*width + j > MIN(yp + 1, origHeight_c)*width) {
	    printf("%d > %d (%d %d %d %d) (%d %d %d)\n", xSrc + i*width + j, MIN(yp + 1, origHeight_c)*width, xSrc, i , width, j, yp, origHeight_c, width);
	    printf("%d %d %d\n", head_pad_size, pix_size, tail_pad_size);
	    assert(0 && "bad access\n");
	  }
	  pixAcc0 += pixBuf[xSrc + i*width + j];
	}
      }
      buffer[y * row_stride + x] = splashFloor(pixAcc0 / (origN*m));
      xSrc += xStep;
      x1 += 1;
    }

  }
  free(pixBuf);

  cairo_surface_mark_dirty (image);
  pattern = cairo_pattern_create_for_surface (image);
  cairo_surface_destroy (image);
  if (cairo_pattern_status (pattern)) {
    imgStr->close();
    delete imgStr;
    return;
  }

  /* we should actually be using CAIRO_FILTER_NEAREST here. However,
   * cairo doesn't yet do minifaction filtering causing scaled down
   * images with CAIRO_FILTER_NEAREST to look really bad */
  cairo_pattern_set_filter (pattern,
			    interpolate ? CAIRO_FILTER_GOOD : CAIRO_FILTER_FAST);

  if (state->getFillColorSpace()->getMode() == csPattern) {
    cairo_matrix_init_translate (&matrix, 0, scaledHeight);
    cairo_matrix_scale (&matrix, scaledWidth, -scaledHeight);
    cairo_pattern_set_matrix (pattern, &matrix);
    if (cairo_pattern_status (pattern)) {
      cairo_pattern_destroy (pattern);
      imgStr->close();
      delete imgStr;
      return;
    }

    mask = cairo_pattern_reference (pattern);
    cairo_get_matrix (cairo, &mask_matrix);
  } else {
    cairo_save (cairo);

    /* modify our current transformation so that the prescaled image
     * goes where it is supposed to */
    cairo_get_matrix(cairo, &matrix);
    cairo_scale(cairo, 1.0/matrix.xx, 1.0/matrix.yy);
    // get integer co-ords
    cairo_translate (cairo, tx - matrix.x0, ty2 - matrix.y0);
    if (yScale > 0)
      cairo_scale(cairo, 1, -1);

    cairo_rectangle (cairo, 0., 0., scaledWidth, scaledHeight);
    cairo_clip (cairo);
    if (strokePathClip) {
      cairo_push_group (cairo);
      fillToStrokePathClip (state);
      cairo_pop_group_to_source (cairo);
    }
    cairo_mask (cairo, pattern);

    //cairo_get_matrix(cairo, &matrix);
    //printf("mask at: [%f %f], [%f %f], %f %f\n\n", matrix.xx, matrix.xy, matrix.yx, matrix.yy, matrix.x0, matrix.y0);
    cairo_restore(cairo);
  }

  if (cairo_shape) {
    cairo_save (cairo_shape);

    /* modify our current transformation so that the prescaled image
     * goes where it is supposed to */
    cairo_get_matrix(cairo_shape, &matrix);
    cairo_scale(cairo_shape, 1.0/matrix.xx, 1.0/matrix.yy);
    // get integer co-ords
    cairo_translate (cairo_shape, tx - matrix.x0, ty2 - matrix.y0);
    if (yScale > 0)
      cairo_scale(cairo_shape, 1, -1);

    cairo_rectangle (cairo_shape, 0., 0., scaledWidth, scaledHeight);
    cairo_fill (cairo_shape);

    cairo_restore(cairo_shape);
  }

  cairo_pattern_destroy (pattern);

  imgStr->close();
  delete imgStr;
}

void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref,
				     Stream *str, int width, int height,
				     GfxImageColorMap *colorMap,
				     bool interpolate,
				     Stream *maskStr, int maskWidth,
				     int maskHeight, bool maskInvert,
				     bool maskInterpolate)
{
  ImageStream *maskImgStr, *imgStr;
  ptrdiff_t row_stride;
  unsigned char *maskBuffer, *buffer;
  unsigned char *maskDest;
  unsigned int *dest;
  cairo_surface_t *maskImage, *image;
  cairo_pattern_t *maskPattern, *pattern;
  cairo_matrix_t matrix;
  cairo_matrix_t maskMatrix;
  unsigned char *pix;
  int x, y;
  int invert_bit;
  cairo_filter_t filter;
  cairo_filter_t maskFilter;

  maskImgStr = new ImageStream(maskStr, maskWidth, 1, 1);
  maskImgStr->reset();

  maskImage = cairo_image_surface_create (CAIRO_FORMAT_A8, maskWidth, maskHeight);
  if (cairo_surface_status (maskImage)) {
    maskImgStr->close();
    delete maskImgStr;
    return;
  }

  maskBuffer = cairo_image_surface_get_data (maskImage);
  row_stride = cairo_image_surface_get_stride (maskImage);

  invert_bit = maskInvert ? 1 : 0;

  for (y = 0; y < maskHeight; y++) {
    pix = maskImgStr->getLine();
    maskDest = maskBuffer + y * row_stride;
    for (x = 0; x < maskWidth; x++) {
      if (pix[x] ^ invert_bit)
	*maskDest++ = 0;
      else
	*maskDest++ = 255;
    }
  }

  maskImgStr->close();
  delete maskImgStr;

  maskFilter = getFilterForSurface (maskImage, maskInterpolate);

  cairo_surface_mark_dirty (maskImage);
  maskPattern = cairo_pattern_create_for_surface (maskImage);
  cairo_surface_destroy (maskImage);
  if (cairo_pattern_status (maskPattern))
    return;

#if 0
  /* ICCBased color space doesn't do any color correction
   * so check its underlying color space as well */
  int is_identity_transform;
  is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
		  (colorMap->getColorSpace()->getMode() == csICCBased && 
		   ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB);
#endif

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

  image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
  if (cairo_surface_status (image))
    goto cleanup;

  buffer = cairo_image_surface_get_data (image);
  row_stride = cairo_image_surface_get_stride (image);
  for (y = 0; y < height; y++) {
    dest = reinterpret_cast<unsigned int *>(buffer + y * row_stride);
    pix = imgStr->getLine();
    colorMap->getRGBLine (pix, dest, width);
  }

  filter = getFilterForSurface (image, interpolate);

  cairo_surface_mark_dirty (image);
  pattern = cairo_pattern_create_for_surface (image);
  cairo_surface_destroy (image);
  if (cairo_pattern_status (pattern))
    goto cleanup;

  LOG (printf ("drawMaskedImage %dx%d\n", width, height));

  cairo_pattern_set_filter (pattern, filter);
  cairo_pattern_set_filter (maskPattern, maskFilter);

  if (!printing) {
    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
  }

  cairo_matrix_init_translate (&matrix, 0, height);
  cairo_matrix_scale (&matrix, width, -height);
  cairo_pattern_set_matrix (pattern, &matrix);
  if (cairo_pattern_status (pattern)) {
    cairo_pattern_destroy (pattern);
    cairo_pattern_destroy (maskPattern);
    goto cleanup;
  }

  cairo_matrix_init_translate (&maskMatrix, 0, maskHeight);
  cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
  if (cairo_pattern_status (maskPattern)) {
    cairo_pattern_destroy (maskPattern);
    cairo_pattern_destroy (pattern);
    goto cleanup;
  }

  if (!printing) {
    cairo_save (cairo);
    cairo_set_source (cairo, pattern);
    cairo_rectangle (cairo, 0., 0., 1., 1.);
    cairo_clip (cairo);
    cairo_mask (cairo, maskPattern);
    cairo_restore (cairo);
  } else {
    cairo_set_source (cairo, pattern);
    cairo_mask (cairo, maskPattern);
  }

  if (cairo_shape) {
    cairo_save (cairo_shape);
    cairo_set_source (cairo_shape, pattern);
    if (!printing) {
      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
      cairo_fill (cairo_shape);
    } else {
      cairo_mask (cairo_shape, pattern);
    }
    cairo_restore (cairo_shape);
  }

  cairo_pattern_destroy (maskPattern);
  cairo_pattern_destroy (pattern);

cleanup:
  imgStr->close();
  delete imgStr;
}


//XXX: is this affect by AIS(alpha is shape)?
void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
					 int width, int height,
					 GfxImageColorMap *colorMap,
					 bool interpolate,
					 Stream *maskStr,
					 int maskWidth, int maskHeight,
					 GfxImageColorMap *maskColorMap,
					 bool maskInterpolate)
{
  ImageStream *maskImgStr, *imgStr;
  ptrdiff_t row_stride;
  unsigned char *maskBuffer, *buffer;
  unsigned char *maskDest;
  unsigned int *dest;
  cairo_surface_t *maskImage, *image;
  cairo_pattern_t *maskPattern, *pattern;
  cairo_matrix_t maskMatrix, matrix;
  unsigned char *pix;
  int y;
  cairo_filter_t filter;
  cairo_filter_t maskFilter;

  maskImgStr = new ImageStream(maskStr, maskWidth,
			       maskColorMap->getNumPixelComps(),
			       maskColorMap->getBits());
  maskImgStr->reset();

  maskImage = cairo_image_surface_create (CAIRO_FORMAT_A8, maskWidth, maskHeight);
  if (cairo_surface_status (maskImage)) {
    maskImgStr->close();
    delete maskImgStr;
    return;
  }

  maskBuffer = cairo_image_surface_get_data (maskImage);
  row_stride = cairo_image_surface_get_stride (maskImage);
  for (y = 0; y < maskHeight; y++) {
    maskDest = (unsigned char *) (maskBuffer + y * row_stride);
    pix = maskImgStr->getLine();
    if (likely(pix != nullptr)) {
        maskColorMap->getGrayLine (pix, maskDest, maskWidth);
    }
  }

  maskImgStr->close();
  delete maskImgStr;

  maskFilter = getFilterForSurface (maskImage, maskInterpolate);

  cairo_surface_mark_dirty (maskImage);
  maskPattern = cairo_pattern_create_for_surface (maskImage);
  cairo_surface_destroy (maskImage);
  if (cairo_pattern_status (maskPattern))
    return;

#if 0
  /* ICCBased color space doesn't do any color correction
   * so check its underlying color space as well */
  int is_identity_transform;
  is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
		  (colorMap->getColorSpace()->getMode() == csICCBased &&
		   ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB);
#endif

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

  image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
  if (cairo_surface_status (image))
    goto cleanup;

  buffer = cairo_image_surface_get_data (image);
  row_stride = cairo_image_surface_get_stride (image);
  for (y = 0; y < height; y++) {
    dest = reinterpret_cast<unsigned int *>(buffer + y * row_stride);
    pix = imgStr->getLine();
    colorMap->getRGBLine (pix, dest, width);
  }

  filter = getFilterForSurface (image, interpolate);

  cairo_surface_mark_dirty (image);

  setMimeData(state, str, ref, colorMap, image, height);

  pattern = cairo_pattern_create_for_surface (image);
  cairo_surface_destroy (image);
  if (cairo_pattern_status (pattern))
    goto cleanup;

  LOG (printf ("drawSoftMaskedImage %dx%d\n", width, height));

  cairo_pattern_set_filter (pattern, filter);
  cairo_pattern_set_filter (maskPattern, maskFilter);

  if (!printing) {
    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
  }

  cairo_matrix_init_translate (&matrix, 0, height);
  cairo_matrix_scale (&matrix, width, -height);
  cairo_pattern_set_matrix (pattern, &matrix);
  if (cairo_pattern_status (pattern)) {
    cairo_pattern_destroy (pattern);
    cairo_pattern_destroy (maskPattern);
    goto cleanup;
  }

  cairo_matrix_init_translate (&maskMatrix, 0, maskHeight);
  cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
  if (cairo_pattern_status (maskPattern)) {
    cairo_pattern_destroy (maskPattern);
    cairo_pattern_destroy (pattern);
    goto cleanup;
  }

  if (fill_opacity != 1.0)
    cairo_push_group (cairo);
  else
    cairo_save (cairo);

  cairo_set_source (cairo, pattern);
  if (!printing) {
    cairo_rectangle (cairo, 0., 0., 1., 1.);
    cairo_clip (cairo);
  }
  cairo_mask (cairo, maskPattern);

  if (fill_opacity != 1.0) {
    cairo_pop_group_to_source (cairo);
    cairo_save (cairo);
    if (!printing) {
      cairo_rectangle (cairo, 0., 0., 1., 1.);
      cairo_clip (cairo);
    }
    cairo_paint_with_alpha (cairo, fill_opacity);
  }
  cairo_restore (cairo);

  if (cairo_shape) {
    cairo_save (cairo_shape);
    cairo_set_source (cairo_shape, pattern);
    if (!printing) {
      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
      cairo_fill (cairo_shape);
    } else {
      cairo_mask (cairo_shape, pattern);
    }
    cairo_restore (cairo_shape);
  }

  cairo_pattern_destroy (maskPattern);
  cairo_pattern_destroy (pattern);

cleanup:
  imgStr->close();
  delete imgStr;
}

bool CairoOutputDev::getStreamData (Stream *str, char **buffer, int *length)
{
  int len, i;
  char *strBuffer;

  len = 0;
  str->close();
  str->reset();
  while (str->getChar() != EOF) len++;
  if (len == 0)
    return false;

  strBuffer = (char *)gmalloc (len);

  str->close();
  str->reset();
  for (i = 0; i < len; ++i)
    strBuffer[i] = str->getChar();

  *buffer = strBuffer;
  *length = len;

  return true;
}

static bool colorMapHasIdentityDecodeMap(GfxImageColorMap *colorMap)
{
  for (int i = 0; i < colorMap->getNumPixelComps(); i++) {
    if (colorMap->getDecodeLow(i) != 0.0 || colorMap->getDecodeHigh(i) != 1.0)
      return false;
  }
  return true;
}

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
static cairo_status_t setMimeIdFromRef(cairo_surface_t *surface,
				       const char *mime_type,
				       const char *mime_id_prefix,
				       Ref ref)
{
  GooString *mime_id;
  char *idBuffer;
  cairo_status_t status;

  mime_id = new GooString;

  if (mime_id_prefix)
    mime_id->append(mime_id_prefix);

  mime_id->appendf("{0:d}-{1:d}", ref.gen, ref.num);

  idBuffer = copyString(mime_id->c_str());
  status = cairo_surface_set_mime_data (surface, mime_type,
                                        (const unsigned char *)idBuffer,
                                        mime_id->getLength(),
                                        gfree, idBuffer);
  delete mime_id;
  if (status)
    gfree (idBuffer);
  return status;
}
#endif

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
bool CairoOutputDev::setMimeDataForJBIG2Globals(Stream  *str,
                                                 cairo_surface_t *image)
{
  JBIG2Stream *jb2Str = static_cast<JBIG2Stream *>(str);
  Object* globalsStr = jb2Str->getGlobalsStream();
  char *globalsBuffer;
  int globalsLength;

  // nothing to do for JBIG2 stream without Globals
  if (!globalsStr->isStream())
    return true;

  if (setMimeIdFromRef(image, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID, nullptr,
                       jb2Str->getGlobalsStreamRef()))
    return false;

  if (!getStreamData(globalsStr->getStream(), &globalsBuffer, &globalsLength))
    return false;

  if (cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_JBIG2_GLOBAL,
                                   (const unsigned char*)globalsBuffer,
                                   globalsLength,
                                   gfree, (void*)globalsBuffer))
  {
    gfree (globalsBuffer);
    return false;
  }

  return true;
}
#endif

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10)
bool CairoOutputDev::setMimeDataForCCITTParams(Stream  *str,
						cairo_surface_t *image, int height)
{
  CCITTFaxStream *ccittStr = static_cast<CCITTFaxStream *>(str);

  GooString params;
  params.appendf("Columns={0:d}", ccittStr->getColumns());
  params.appendf(" Rows={0:d}", height);
  params.appendf(" K={0:d}", ccittStr->getEncoding());
  params.appendf(" EndOfLine={0:d}", ccittStr->getEndOfLine() ? 1 : 0);
  params.appendf(" EncodedByteAlign={0:d}", ccittStr->getEncodedByteAlign() ? 1 : 0);
  params.appendf(" EndOfBlock={0:d}", ccittStr->getEndOfBlock() ? 1 : 0);
  params.appendf(" BlackIs1={0:d}", ccittStr->getBlackIs1() ? 1 : 0);
  params.appendf(" DamagedRowsBeforeError={0:d}", ccittStr->getDamagedRowsBeforeError());

  char *p = strdup(params.c_str());
  if (cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
                                   (const unsigned char*)p,
                                   params.getLength(),
                                   gfree, (void*)p))
  {
    gfree (p);
    return false;
  }

  return true;
}
#endif

void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref,
				 GfxImageColorMap *colorMap, cairo_surface_t *image, int height)
{
  char *strBuffer;
  int len;
  Object obj;
  GfxColorSpace *colorSpace;
  StreamKind  strKind = str->getKind();
  const char *mime_type;

  if (!printing)
    return;

  switch (strKind) {
    case strDCT:
      mime_type = CAIRO_MIME_TYPE_JPEG;
      break;
    case strJPX:
      mime_type = CAIRO_MIME_TYPE_JP2;
      break;
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
    case strJBIG2:
      mime_type = CAIRO_MIME_TYPE_JBIG2;
      break;
#endif
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10)
    case strCCITTFax:
      mime_type = CAIRO_MIME_TYPE_CCITT_FAX;
      break;
#endif
    default:
      return;
  }

  obj = str->getDict()->lookup("ColorSpace");
  colorSpace = GfxColorSpace::parse(nullptr, &obj, this, state);

  // colorspace in stream dict may be different from colorspace in jpx
  // data
  if (strKind == strJPX && colorSpace)
    return;

  // only embed mime data for gray, rgb, and cmyk colorspaces.
  if (colorSpace) {
    GfxColorSpaceMode mode = colorSpace->getMode();
    delete colorSpace;
    switch (mode) {
      case csDeviceGray:
      case csCalGray:
      case csDeviceRGB:
      case csCalRGB:
      case csDeviceCMYK:
      case csICCBased:
	break;

      case csLab:
      case csIndexed:
      case csSeparation:
      case csDeviceN:
      case csPattern:
	return;
    }
  }

  if (!colorMapHasIdentityDecodeMap(colorMap))
    return;

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
  if (strKind == strJBIG2 && !setMimeDataForJBIG2Globals(str, image))
    return;
#endif

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10)
  if (strKind == strCCITTFax && !setMimeDataForCCITTParams(str, image, height))
    return;
#endif

  if (getStreamData (str->getNextStream(), &strBuffer, &len)) {
    cairo_status_t status = CAIRO_STATUS_SUCCESS;

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
    // Since 1.5.10 the cairo PS backend stores images with UNIQUE_ID in PS memory so the
    // image can be re-used multiple times. As we don't know how large the images are or
    // how many times they are used, there is no benefit in enabling this. Issue #106
    if (cairo_surface_get_type (cairo_get_target (cairo)) != CAIRO_SURFACE_TYPE_PS) {
      if (ref && ref->isRef()) {
        status = setMimeIdFromRef(image, CAIRO_MIME_TYPE_UNIQUE_ID,
                                  "poppler-surface-", ref->getRef());
      }
    }
#endif
    if (!status) {
      status = cairo_surface_set_mime_data (image, mime_type,
					    (const unsigned char *)strBuffer, len,
					    gfree, strBuffer);
    }

    if (status)
      gfree (strBuffer);
  }
}

class RescaleDrawImage : public CairoRescaleBox {
private:
  ImageStream *imgStr;
  GfxRGB *lookup;
  int width;
  GfxImageColorMap *colorMap;
  int *maskColors;
  int current_row;
  bool imageError;

public:
  cairo_surface_t *getSourceImage(Stream *str,
                                  int widthA, int height,
                                  int scaledWidth, int scaledHeight,
                                  bool printing,
                                  GfxImageColorMap *colorMapA,
                                  int *maskColorsA) {
    cairo_surface_t *image = nullptr;
    int i;

    lookup = nullptr;
    colorMap = colorMapA;
    maskColors = maskColorsA;
    width = widthA;
    current_row = -1;
    imageError = false;

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

#if 0
    /* ICCBased color space doesn't do any color correction
     * so check its underlying color space as well */
    int is_identity_transform;
    is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
      (colorMap->getColorSpace()->getMode() == csICCBased &&
       ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB);
#endif

    // special case for one-channel (monochrome/gray/separation) images:
    // build a lookup table here
    if (colorMap->getNumPixelComps() == 1) {
      int n;
      unsigned char pix;

      n = 1 << colorMap->getBits();
      lookup = (GfxRGB *)gmallocn(n, sizeof(GfxRGB));
      for (i = 0; i < n; ++i) {
        pix = (unsigned char)i;

        colorMap->getRGB(&pix, &lookup[i]);
      }
    }

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0)
    bool needsCustomDownscaling = false;
#else
    bool needsCustomDownscaling = true;
#endif

    if (printing) {
      if (width > MAX_PRINT_IMAGE_SIZE || height > MAX_PRINT_IMAGE_SIZE) {
	if (width > height) {
	  scaledWidth = MAX_PRINT_IMAGE_SIZE;
	  scaledHeight = MAX_PRINT_IMAGE_SIZE * (double)height/width;
	} else {
	  scaledHeight = MAX_PRINT_IMAGE_SIZE;
	  scaledWidth = MAX_PRINT_IMAGE_SIZE * (double)width/height;
	}
	needsCustomDownscaling = true;
      } else {
	needsCustomDownscaling = false;
      }
    }

    if (!needsCustomDownscaling || scaledWidth >= width || scaledHeight >= height) {
      // No downscaling. Create cairo image containing the source image data.
      unsigned char *buffer;
      ptrdiff_t stride;

      image = cairo_image_surface_create (maskColors ?
                                          CAIRO_FORMAT_ARGB32 :
                                          CAIRO_FORMAT_RGB24,
                                          width, height);
      if (cairo_surface_status (image))
        goto cleanup;

      buffer = cairo_image_surface_get_data (image);
      stride = cairo_image_surface_get_stride (image);
      for (int y = 0; y < height; y++) {
        uint32_t *dest = reinterpret_cast<uint32_t *>(buffer + y * stride);
        getRow(y, dest);
      }
    } else {
      // // Downscaling required. Create cairo image the size of the
      // rescaled image and // downscale the source image data into
      // the cairo image. downScaleImage() will call getRow() to read
      // source image data from the image stream. This avoids having
      // to create an image the size of the source image which may
      // exceed cairo's 32676x32767 image size limit (and also saves a
      // lot of memory).
      image = cairo_image_surface_create (maskColors ?
                                          CAIRO_FORMAT_ARGB32 :
                                          CAIRO_FORMAT_RGB24,
                                          scaledWidth, scaledHeight);
      if (cairo_surface_status (image))
        goto cleanup;

      downScaleImage(width, height,
                     scaledWidth, scaledHeight,
                     0, 0, scaledWidth, scaledHeight,
                     image);
    }
    cairo_surface_mark_dirty (image);

  cleanup:
    gfree(lookup);
    imgStr->close();
    delete imgStr;
    return image;
  }

  void getRow(int row_num, uint32_t *row_data) override {
    unsigned char *pix;

    if (row_num <= current_row)
      return;

    while (current_row  < row_num) {
      pix = imgStr->getLine();
      current_row++;
    }

    if (unlikely(pix == nullptr)) {
      memset(row_data, 0, width*4);
      if (!imageError) {
	error(errInternal, -1, "Bad image stream");
	imageError = true;
      }
    } else if (lookup) {
      unsigned char *p = pix;
      GfxRGB rgb;

      for (int i = 0; i < width; i++) {
        rgb = lookup[*p];
        row_data[i] =
          ((int) colToByte(rgb.r) << 16) |
          ((int) colToByte(rgb.g) << 8) |
          ((int) colToByte(rgb.b) << 0);
        p++;
      }
    } else {
      colorMap->getRGBLine (pix, row_data, width);
    }

    if (maskColors) {
      for (int x = 0; x < width; x++) {
        bool is_opaque = false;
        for (int i = 0; i < colorMap->getNumPixelComps(); ++i) {
          if (pix[i] < maskColors[2*i] ||
              pix[i] > maskColors[2*i+1]) {
            is_opaque = true;
            break;
          }
        }
        if (is_opaque)
          *row_data |= 0xff000000;
        else
          *row_data = 0;
        row_data++;
        pix += colorMap->getNumPixelComps();
      }
    }
  }

};

void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
			       int widthA, int heightA,
			       GfxImageColorMap *colorMap,
			       bool interpolate,
			       int *maskColors, bool inlineImg)
{
  cairo_surface_t *image;
  cairo_pattern_t *pattern, *maskPattern;
  cairo_matrix_t matrix;
  int width, height;
  int scaledWidth, scaledHeight;
  cairo_filter_t filter = CAIRO_FILTER_GOOD;
  RescaleDrawImage rescale;

  LOG (printf ("drawImage %dx%d\n", widthA, heightA));

  cairo_get_matrix(cairo, &matrix);
  getScaledSize (&matrix, widthA, heightA, &scaledWidth, &scaledHeight);
  image = rescale.getSourceImage(str, widthA, heightA, scaledWidth, scaledHeight, printing, colorMap, maskColors);
  if (!image)
    return;

  width = cairo_image_surface_get_width (image);
  height = cairo_image_surface_get_height (image);
  if (width == widthA && height == heightA)
    filter = getFilterForSurface (image, interpolate);

  if (!inlineImg) { /* don't read stream twice if it is an inline image */
    // cairo 1.15.10 allows mime image data to have different size to cairo image
    // mime image size will be scaled to same size as cairo image
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10)
    bool requireSameSize = false;
#else
    bool requireSameSize = true;
#endif
    if (!requireSameSize || (width == widthA && height == heightA))
      setMimeData(state, str, ref, colorMap, image, heightA);
  }

  pattern = cairo_pattern_create_for_surface (image);
  cairo_surface_destroy (image);
  if (cairo_pattern_status (pattern))
    return;

  cairo_pattern_set_filter (pattern, filter);

  if (!printing)
    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);

  cairo_matrix_init_translate (&matrix, 0, height);
  cairo_matrix_scale (&matrix, width, -height);
  cairo_pattern_set_matrix (pattern, &matrix);
  if (cairo_pattern_status (pattern)) {
    cairo_pattern_destroy (pattern);
    return;
  }

  if (!mask && fill_opacity != 1.0) {
    maskPattern = cairo_pattern_create_rgba (1., 1., 1., fill_opacity);
  } else if (mask) {
    maskPattern = cairo_pattern_reference (mask);
  } else {
    maskPattern = nullptr;
  }

  cairo_save (cairo);
  cairo_set_source (cairo, pattern);
  if (!printing)
    cairo_rectangle (cairo, 0., 0., 1., 1.);
  if (maskPattern) {
    if (!printing)
      cairo_clip (cairo);
    if (mask)
      cairo_set_matrix (cairo, &mask_matrix);
    cairo_mask (cairo, maskPattern);
  } else {
    if (printing)
      cairo_paint (cairo);
    else
      cairo_fill (cairo);
  }
  cairo_restore (cairo);

  cairo_pattern_destroy (maskPattern);

  if (cairo_shape) {
    cairo_save (cairo_shape);
    cairo_set_source (cairo_shape, pattern);
    if (printing) {
      cairo_paint (cairo_shape);
    } else {
      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
      cairo_fill (cairo_shape);
    }
    cairo_restore (cairo_shape);
  }

  cairo_pattern_destroy (pattern);
}


//------------------------------------------------------------------------
// ImageOutputDev
//------------------------------------------------------------------------

CairoImageOutputDev::CairoImageOutputDev()
{
  images = nullptr;
  numImages = 0;
  size = 0;
  imgDrawCbk = nullptr;
  imgDrawCbkData = nullptr;
}

CairoImageOutputDev::~CairoImageOutputDev()
{
  int i;

  for (i = 0; i < numImages; i++)
    delete images[i];
  gfree (images);
}

void CairoImageOutputDev::saveImage(CairoImage *image)
{ 
  if (numImages >= size) {
	  size += 16;
	  images = (CairoImage **) greallocn (images, size, sizeof (CairoImage *));
  }
  images[numImages++] = image;
}

void CairoImageOutputDev::getBBox(GfxState *state, int width, int height,
                                  double *x1, double *y1, double *x2, double *y2)
{
  const double *ctm = state->getCTM();
  cairo_matrix_t matrix;
  cairo_matrix_init(&matrix,
                    ctm[0], ctm[1],
                    -ctm[2], -ctm[3],
                    ctm[2] + ctm[4], ctm[3] + ctm[5]);

  int scaledWidth, scaledHeight;
  getScaledSize (&matrix, width, height, &scaledWidth, &scaledHeight);

  if (matrix.xx >= 0) {
    *x1 = matrix.x0;
  } else {
    *x1 = matrix.x0 - scaledWidth;
  }
  *x2 = *x1 + scaledWidth;

  if (matrix.yy >= 0) {
    *y1 = matrix.y0;
  } else {
    *y1 = matrix.y0 - scaledHeight;
  }
  *y2 = *y1 + scaledHeight;
}

void CairoImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
					int width, int height, bool invert,
					bool interpolate, bool inlineImg)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  CairoImage *image;

  getBBox(state, width, height, &x1, &y1, &x2, &y2);

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);

    CairoOutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
    image->setImage (surface);

    setCairo (nullptr);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

void CairoImageOutputDev::setSoftMaskFromImageMask(GfxState *state, Object *ref, Stream *str,
                                                   int width, int height, bool invert,
                                                   bool inlineImg, double *baseMatrix)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  CairoImage *image;

  getBBox(state, width, height, &x1, &y1, &x2, &y2);

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);

    CairoOutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg, false);
    if (state->getFillColorSpace()->getMode() == csPattern) {
      cairo_mask (cairo, mask);
    }
    image->setImage (surface);

    setCairo (nullptr);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

void CairoImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GfxImageColorMap *colorMap,
				    bool interpolate, int *maskColors, bool inlineImg)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  CairoImage *image;

  getBBox(state, width, height, &x1, &y1, &x2, &y2);

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);
    
    CairoOutputDev::drawImage(state, ref, str, width, height, colorMap, interpolate, maskColors, inlineImg);
    image->setImage (surface);
    
    setCairo (nullptr);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

void CairoImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
					      int width, int height,
					      GfxImageColorMap *colorMap,
					      bool interpolate,
					      Stream *maskStr,
					      int maskWidth, int maskHeight,
					      GfxImageColorMap *maskColorMap,
					      bool maskInterpolate)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  CairoImage *image;

  getBBox(state, width, height, &x1, &y1, &x2, &y2);

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);
    
    CairoOutputDev::drawSoftMaskedImage(state, ref, str, width, height, colorMap, interpolate,
					maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate);
    image->setImage (surface);
    
    setCairo (nullptr);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

void CairoImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
					  int width, int height,
					  GfxImageColorMap *colorMap,
					  bool interpolate,
					  Stream *maskStr,
					  int maskWidth, int maskHeight,
					  bool maskInvert, bool maskInterpolate)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  CairoImage *image;

  getBBox(state, width, height, &x1, &y1, &x2, &y2);

  image = new CairoImage (x1, y1, x2, y2);
  saveImage (image);

  if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (surface);
    setCairo (cr);
    cairo_translate (cr, 0, height);
    cairo_scale (cr, width, -height);
    
    CairoOutputDev::drawMaskedImage(state, ref, str, width, height, colorMap, interpolate,
				    maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate);
    image->setImage (surface);
    
    setCairo (nullptr);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}
