//========================================================================
//
// 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 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2008 Carl Worth <cworth@cworth.org>
// Copyright (C) 2008-2011 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 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.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>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

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

#include "goo/gfile.h"
#include "goo/gtypes_p.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 "CharCodeToUnicode.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 "UTF8.h"
//------------------------------------------------------------------------

// #define LOG_CAIRO

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

static inline void printMatrix(cairo_matrix_t *matrix){
	printf("%f %f, %f %f (%f %f)\n", matrix->xx, matrix->yx,
			matrix->xy, matrix->yy,
			matrix->x0, matrix->y0);
}


#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 = NULL;
  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;
GBool CairoOutputDev::ft_lib_initialized = gFalse;

CairoOutputDev::CairoOutputDev() {
  xref = NULL;
  catalog = NULL;

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

  fontEngine = NULL;
  fontEngine_owner = gFalse;
  glyphs = NULL;
  fill_pattern = NULL;
  fill_color.r = fill_color.g = fill_color.b = 0;
  stroke_pattern = NULL;
  stroke_color.r = stroke_color.g = stroke_color.b = 0;
  stroke_opacity = 1.0;
  fill_opacity = 1.0;
  textClipPath = NULL;
  strokePathClip = NULL;
  haveCSPattern = gFalse;
  cairo = NULL;
  currentFont = NULL;
  prescaleImages = gTrue;
  printing = gTrue;
  use_show_text_glyphs = gFalse;
  inType3Char = gFalse;
  t3_glyph_has_bbox = gFalse;

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

  text = NULL;
  actualText = NULL;

  // the SA parameter supposedly defaults to false, but Acrobat
  // apparently hardwires it to true
  stroke_adjust = globalParams->getStrokeAdjust();
  align_stroke_coords = gFalse;
  adjusted_stroke_width = gFalse;
}

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 != NULL) {
    cairo_status_t status = cairo_status (this->cairo);
    if (status) {
      warning("cairo context error: %s\n", cairo_status_to_string(status));
    }
    cairo_destroy (this->cairo);
    assert(!cairo_shape);
  }
  if (cairo != NULL) {
    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);
  } else {
    this->cairo = NULL;
    this->cairo_shape = NULL;
  }
}

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 = NULL;
    actualText = NULL;
  }
}

void CairoOutputDev::startDoc(XRef *xrefA, Catalog *catalogA,
			      CairoFontEngine *parentFontEngine) {
  xref = xrefA;
  catalog = catalogA;
  if (parentFontEngine) {
    fontEngine = parentFontEngine;
  } else {
    if (fontEngine) {
      delete fontEngine;
    }
    fontEngine = new CairoFontEngine(ft_lib);
    fontEngine_owner = gTrue;
  }
}

void CairoOutputDev::startPage(int pageNum, GfxState *state) {
  /* 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.);
  stroke_pattern = cairo_pattern_reference(fill_pattern);

  if (text)
    text->startPage(state);
}

void CairoOutputDev::endPage() {
  if (text) {
    text->endPage();
    text->coalesce(gTrue, gFalse);
  }
}

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;
}

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

  /* 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;
  }
}

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 = gTrue;
  if (text)
    text->updateFont(state);
}

void CairoOutputDev::setDefaultCTM(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)) {
    warning("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 = gFalse;
  if (state->getLineWidth() == 0.0) {
    /* 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);
    cairo_set_line_width (cairo, MIN(fabs(x),fabs(y)));
  } else {
    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 (x <= 1.0 && 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 = gTrue;
      }
    }
    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;

  state->getFillRGB(&fill_color);
  if (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;

  state->getStrokeRGB(&stroke_color);
  if (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;

  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;

  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) {
  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()->getCString()));

  needFontUpdate = gFalse;

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

  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();
  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)) {
    warning("font matrix not invertible\n");
    return;
  }

  cairo_set_font_matrix (cairo, &matrix);
}

void CairoOutputDev::alignStrokeCoords(double *x, double *y)
{
  /* 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);
}

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

	  j += 3;
	} else {
	  if (align_stroke_coords) {
	    double x = subpath->getX(j);
	    double y = subpath->getY(j);
	    alignStrokeCoords(&x, &y);
	    cairo_line_to (cairo, x, y);
	  } else {
	    cairo_line_to (cairo, subpath->getX(j), subpath->getY(j));
	  }
	  ++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 = gTrue;
  doPath (cairo, state, state->getPath());
  align_stroke_coords = gFalse;
  cairo_set_source (cairo, stroke_pattern);
  LOG(printf ("stroke\n"));
  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_clip (cairo);
    cairo_save (cairo);
    cairo_set_matrix (cairo, &mask_matrix);
    cairo_mask (cairo, mask);
    cairo_restore (cairo);
  } else if (strokePathClip) {
    fillToStrokePathClip();
  } 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"));
  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);
  }

}

GBool CairoOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str,
					double *pmat, int paintType, int /*tilingType*/, Dict *resDict,
					double *mat, 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_t *old_cairo;
  double xMin, yMin, xMax, yMax;
  double width, height;
  int surface_width, surface_height;
  StrokePathClip *strokePathTmp;

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

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

  surface_width = (int) ceil (width);
  surface_height = (int) ceil (height);

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

  old_cairo = cairo;
  cairo = cairo_create (surface);
  cairo_surface_destroy (surface);

  box.x1 = bbox[0]; box.y1 = bbox[1];
  box.x2 = bbox[2]; box.y2 = bbox[3];
  strokePathTmp = strokePathClip;
  strokePathClip = NULL;
  gfx = new Gfx(xref, this, resDict, catalog, &box, NULL);
  gfx->display(str);
  delete gfx;
  strokePathClip = strokePathTmp;

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

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

  cairo_matrix_init_scale (&matrix, surface_width / width, surface_height / height);
  cairo_pattern_set_matrix (pattern, &matrix);

  cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
  cairo_transform (cairo, &matrix);
  cairo_set_source (cairo, pattern);
  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
  if (strokePathClip) {
    fillToStrokePathClip();
  } else {
    cairo_fill (cairo);
  }

  cairo_pattern_destroy (pattern);

  return gTrue;
}

GBool 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 gFalse;
}

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

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

  shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
  dx = x1 - x0;
  dy = y1 - y0;
  dr = r1 - r0;
  cairo_pattern_destroy(fill_pattern);
  fill_pattern = cairo_pattern_create_radial (x0 + sMin * dx,
					      y0 + sMin * dy,
					      r0 + sMin * dr,
					      x0 + sMax * dx,
					      y0 + sMax * dy,
					      r0 + sMax * dr);
  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 gFalse;
}

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

#if CAIRO_VERSION == CAIRO_VERSION_ENCODE(1, 11, 2)
GBool 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++) {
    shading->getTriangle(i,
			 &x0, &y0, &color[0],
			 &x1, &y1, &color[1],
			 &x2, &y2, &color[2]);

    cairo_pattern_mesh_begin_patch (fill_pattern);

    cairo_pattern_mesh_move_to (fill_pattern, x0, y0);
    cairo_pattern_mesh_line_to (fill_pattern, x1, y1);
    cairo_pattern_mesh_line_to (fill_pattern, x2, y2);

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

    cairo_pattern_mesh_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 gTrue;
}

GBool 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++) {
    GfxPatch *patch = shading->getPatch(i);
    GfxColor color;
    GfxRGB rgb;

    cairo_pattern_mesh_begin_patch (fill_pattern);

    cairo_pattern_mesh_move_to (fill_pattern, patch->x[0][0], patch->y[0][0]);
    cairo_pattern_mesh_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_pattern_mesh_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_pattern_mesh_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_pattern_mesh_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_pattern_mesh_set_control_point (fill_pattern, 0, patch->x[1][1], patch->y[1][1]);
    cairo_pattern_mesh_set_control_point (fill_pattern, 1, patch->x[1][2], patch->y[1][2]);
    cairo_pattern_mesh_set_control_point (fill_pattern, 2, patch->x[2][2], patch->y[2][2]);
    cairo_pattern_mesh_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_pattern_mesh_set_corner_color_rgb (fill_pattern, j,
					       colToDbl(rgb.r),
					       colToDbl(rgb.g),
					       colToDbl(rgb.b));
    }
    cairo_pattern_mesh_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 gTrue;
}
#endif /* CAIRO_VERSION == CAIRO_VERSION_ENCODE(1, 11, 2) */

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));
  doPath (cairo, state, state->getPath());
  strokePathClip->path = cairo_copy_path (cairo);
  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 = NULL;
  }
  strokePathClip->cap = cairo_get_line_cap (cairo);
  strokePathClip->join = cairo_get_line_join (cairo);
  strokePathClip->miter = cairo_get_miter_limit (cairo);
}

void CairoOutputDev::fillToStrokePathClip() {
  cairo_save (cairo);

  cairo_set_matrix (cairo, &strokePathClip->ctm);
  cairo_set_line_width (cairo, strokePathClip->line_width);
  strokePathClip->dash_count = cairo_get_dash_count (cairo);
  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);

  cairo_new_path (cairo);
  cairo_append_path (cairo, strokePathClip->path);
  cairo_stroke (cairo);

  cairo_restore (cairo);

  cairo_path_destroy (strokePathClip->path);
  if (strokePathClip->dashes)
    gfree (strokePathClip->dashes);
  gfree (strokePathClip);
  strokePathClip = NULL;
}

void CairoOutputDev::beginString(GfxState *state, 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) {
      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 = mapUTF8 (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) {
    gfree(glyphs);
    glyphs = NULL;
    return;
  }

  if (!(render & 1) && !haveCSPattern) {
    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 (haveCSPattern || (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);
    }
  }

  gfree (glyphs);
  glyphs = NULL;
  if (use_show_text_glyphs) {
    gfree (clusters);
    clusters = NULL;
    gfree (utf8);
    utf8 = NULL;
  }
}


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

  cairo_save (cairo);
  double *ctm;
  cairo_matrix_t matrix;

  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 gFalse;
}

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 = gTrue;
}

void CairoOutputDev::beginTextObject(GfxState *state) {
  if (!(state->getRender() & 4) && state->getFillColorSpace()->getMode() == csPattern) {
    haveCSPattern = gTrue;
    saveState(state);
  }
}

void CairoOutputDev::endTextObject(GfxState *state) {
  if (haveCSPattern) {
    haveCSPattern = gFalse;
    if (state->getFillColorSpace()->getMode() != csPattern) {
      if (textClipPath) {
	cairo_new_path (cairo);
	cairo_append_path (cairo, textClipPath);
	cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
	cairo_set_source (cairo, fill_pattern);
	cairo_fill (cairo);
	if (cairo_shape) {
	  cairo_new_path (cairo_shape);
	  cairo_append_path (cairo_shape, textClipPath);
	  cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
	  cairo_fill (cairo_shape);
	}
	cairo_path_destroy (textClipPath);
	textClipPath = NULL;
      }
      restoreState(state);
      updateFillColor(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 = NULL;
  }
}

void CairoOutputDev::beginMarkedContent(char *name, Dict *properties)
{
  if (text)
    actualText->beginMC(properties);
}

void CairoOutputDev::endMarkedContent(GfxState *state)
{
  if (text)
    actualText->endMC(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)
{
  double x1, y1, x2, y2;
  int width, height;
  cairo_clip_extents (cairo, &x1, &y1, &x2, &y2);
  cairo_matrix_t matrix;
  cairo_get_matrix (cairo, &matrix);
  //cairo_matrix_transform_point(&matrix, &x1, &y1);
  //cairo_matrix_transform_point(&matrix, &x2, &y2);*/
  cairo_user_to_device(cairo, &x1, &y1);
  cairo_user_to_device(cairo, &x2, &y2);
  width = splashCeil(x2) - splashFloor(x1);
  //XXX: negative matrix
  ////height = splashCeil(y2) - splashFloor(y1);
  height = splashFloor(y1) - splashCeil(y2);
  cairo_surface_t *target = cairo_get_target (cairo);
  cairo_surface_t *result;

  result = cairo_surface_create_similar (target, content, width, height);
  double x_offset, y_offset;
    cairo_surface_get_device_offset(target, &x_offset, &y_offset);
    cairo_surface_set_device_offset(result, x_offset, y_offset);

 
  return result;
}



void CairoOutputDev::beginTransparencyGroup(GfxState * /*state*/, double * /*bbox*/,
                                      GfxColorSpace * blendingColorSpace,
                                      GBool /*isolated*/, GBool knockout,
				      GBool forSoftMask) {
  /* push color space */
  ColorSpaceStack* css = new ColorSpaceStack;
  css->cs = blendingColorSpace;
  css->knockout = knockout;
  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);

      /* 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);
      //printMatrix(&matrix);
      cairo_set_matrix (cairo_shape, &matrix);
    } else {
      cairo_reference (cairo_shape);
    }
  }
  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*/, double * /*bbox*/) {
  cairo_set_source (cairo, group);

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

  if (!mask) {
    //XXX: deal with mask && shape case
    if (shape) {
      cairo_save (cairo);

      /* 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);
      cairo_paint (cairo);

      cairo_restore (cairo);

      cairo_pattern_destroy (shape);
      shape = NULL;
    } else {
      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 {
    cairo_save(cairo);
    cairo_set_matrix(cairo, &mask_matrix);
    cairo_mask(cairo, mask);
    cairo_restore(cairo);

    cairo_pattern_destroy(mask);
    mask = NULL;
  }

  popTransparencyGroup();
}

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, double * bbox, GBool alpha,
                                 Function * transferFunc, GfxColor * backdropColor) {
  cairo_pattern_destroy(mask);

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

  if (alpha == false) {
    /* 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);

    //XXX: hopefully this uses the correct color space */
    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 = (uint32_t*)cairo_image_surface_get_data(source);
    /* get stride in units of 32 bits */
    int stride = cairo_image_surface_get_stride(source)/4;
    for (int y=0; y<height; y++) {
      for (int x=0; x<width; x++) {
	int lum;
	lum = 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 {
    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 = NULL;
    }
  }
  groupColorSpaceStack = css->next;
  delete css;
}


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

void CairoOutputDev::endMaskClip(GfxState *state) {
  clearSoftMask(state);
}

/* 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(int  orig_width,
				   int  orig_height,
				   int *scaledWidth,
				   int *scaledHeight) {
  cairo_matrix_t matrix;
  cairo_get_matrix(cairo, &matrix);

  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-oridinates 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_surface_t *CairoOutputDev::downscaleSurface(cairo_surface_t *orig_surface) {
  cairo_surface_t *dest_surface;
  unsigned char *dest_buffer;
  int dest_stride;
  unsigned char *orig_buffer;
  int orig_width, orig_height;
  int orig_stride;
  int scaledHeight;
  int scaledWidth;
  GBool res;

  if (printing)
    return NULL;

  orig_width = cairo_image_surface_get_width (orig_surface);
  orig_height = cairo_image_surface_get_height (orig_surface);
  getScaledSize (orig_width, orig_height, &scaledWidth, &scaledHeight);
  if (scaledWidth >= orig_width || scaledHeight >= orig_height)
    return NULL;

  dest_surface = cairo_surface_create_similar (orig_surface,
					       cairo_surface_get_content (orig_surface),
					       scaledWidth, scaledHeight);
  dest_buffer = cairo_image_surface_get_data (dest_surface);
  dest_stride = cairo_image_surface_get_stride (dest_surface);

  orig_buffer = cairo_image_surface_get_data (orig_surface);
  orig_stride = cairo_image_surface_get_stride (orig_surface);

  res = downscale_box_filter((uint32_t *)orig_buffer,
			     orig_stride, orig_width, orig_height,
			     scaledWidth, scaledHeight, 0, 0,
			     scaledWidth, scaledHeight,
			     (uint32_t *)dest_buffer, dest_stride);
  if (!res) {
    cairo_surface_destroy (dest_surface);
    return NULL;
  }

  return dest_surface;

}

cairo_filter_t
CairoOutputDev::getFilterForSurface(cairo_surface_t *image,
				    GBool interpolate)
{
  if (interpolate)
    return CAIRO_FILTER_BILINEAR;

  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;

  int scaled_width, scaled_height;
  getScaledSize (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_BILINEAR;
}

void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
				   int width, int height, GBool invert,
				   GBool interpolate, GBool 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;
    Guchar 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;
  }

  if (state->getFillColorSpace()->getMode() == csPattern)
    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, interpolate, inlineImg);
  } else {
    drawImageMaskRegular(state, ref, str, width, height, invert, interpolate, inlineImg);
  }

  if (state->getFillColorSpace()->getMode() == csPattern) {
    if (mask)
      cairo_pattern_destroy (mask);
    mask = cairo_pop_group (cairo);
    cairo_get_matrix (cairo, &mask_matrix);
  }
}

void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream *str,
					  int width, int height, GBool invert,
					  GBool interpolate, GBool inlineImg) {
  unsigned char *buffer;
  unsigned char *dest;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  int x, y, i, bit;
  ImageStream *imgStr;
  Guchar *pix;
  cairo_matrix_t matrix;
  int invert_bit;
  int 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);

  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);
    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);
    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, GBool invert,
					    GBool interpolate, GBool inlineImg) {
  unsigned char *buffer;
  cairo_surface_t *image;
  cairo_pattern_t *pattern;
  ImageStream *imgStr;
  Guchar *pix;
  cairo_matrix_t matrix;
  int invert_bit;
  int row_stride;

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

  /* 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-oridinates 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_BEST : CAIRO_FILTER_FAST);
  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);

  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);
    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,
				     GBool interpolate,
				     Stream *maskStr, int maskWidth,
				     int maskHeight, GBool maskInvert,
				     GBool maskInterpolate)
{
  ImageStream *maskImgStr, *imgStr;
  int 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;
  Guchar *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 = (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,
					 GBool interpolate,
					 Stream *maskStr,
					 int maskWidth, int maskHeight,
					 GfxImageColorMap *maskColorMap,
					 GBool maskInterpolate)
{
  ImageStream *maskImgStr, *imgStr;
  int 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;
  Guchar *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();
    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 = (unsigned int *) (buffer + y * row_stride);
    pix = imgStr->getLine();
    colorMap->getRGBLine (pix, dest, width);
  }

  filter = getFilterForSurface (image, interpolate);

  cairo_surface_mark_dirty (image);

  setMimeData(str, ref, image);

  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.,
		     MIN (width, maskWidth) / (double)width,
		     MIN (height, maskHeight) / (double)height);
    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.,
		       MIN (width, maskWidth) / (double)width,
		       MIN (height, maskHeight) / (double)height);
      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.,
		       MIN (width, maskWidth) / (double)width,
		       MIN (height, maskHeight) / (double)height);
      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;
}

GBool 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 gFalse;

  strBuffer = (char *)gmalloc (len);

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

  *buffer = strBuffer;
  *length = len;

  return gTrue;
}

void CairoOutputDev::setMimeData(Stream *str, Object *ref, cairo_surface_t *image)
{
  char *strBuffer;
  int len;
  Object obj;

  if (!printing || !(str->getKind() == strDCT || str->getKind() == strJPX))
    return;

  // colorspace in stream dict may be different from colorspace in jpx
  // data
  if (str->getKind() == strJPX) {
    GBool hasColorSpace = !str->getDict()->lookup("ColorSpace", &obj)->isNull();
    obj.free();
    if (hasColorSpace)
      return;
  }

  if (getStreamData (str->getNextStream(), &strBuffer, &len)) {
    cairo_status_t st;

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
    if (ref && ref->isRef()) {
      Ref imgRef = ref->getRef();
      GooString *surfaceId = new GooString("poppler-surface-");
      surfaceId->appendf("{0:d}-{1:d}", imgRef.gen, imgRef.num);
      char *idBuffer = copyString(surfaceId->getCString());
      st = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_UNIQUE_ID,
                                        (const unsigned char *)idBuffer,
                                        surfaceId->getLength(),
                                        gfree, idBuffer);
      if (st)
        gfree(idBuffer);
      delete surfaceId;
    }
#endif

    st = cairo_surface_set_mime_data (image,
				      str->getKind() == strDCT ?
				      CAIRO_MIME_TYPE_JPEG : CAIRO_MIME_TYPE_JP2,
				      (const unsigned char *)strBuffer, len,
				      gfree, strBuffer);
    if (st)
      gfree (strBuffer);
  }
}

void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
			       int width, int height,
			       GfxImageColorMap *colorMap,
			       GBool interpolate,
			       int *maskColors, GBool inlineImg)
{
  cairo_surface_t *image;
  cairo_pattern_t *pattern, *maskPattern;
  ImageStream *imgStr;
  cairo_matrix_t matrix;
  unsigned char *buffer;
  int stride, i;
  GfxRGB *lookup = NULL;
  cairo_filter_t filter = CAIRO_FILTER_BILINEAR;

  /* 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

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

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

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

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

  buffer = cairo_image_surface_get_data (image);
  stride = cairo_image_surface_get_stride (image);
  for (int y = 0; y < height; y++) {
    uint32_t *dest = (uint32_t *) (buffer + y * stride);
    Guchar *pix = imgStr->getLine();

    if (lookup) {
      Guchar *p = pix;
      GfxRGB rgb;

      for (i = 0; i < width; i++) {
        rgb = lookup[*p];
        dest[i] =
		((int) colToByte(rgb.r) << 16) |
		((int) colToByte(rgb.g) << 8) |
		((int) colToByte(rgb.b) << 0);
	p++;
      }
    } else {
      colorMap->getRGBLine (pix, dest, 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)
	  *dest |= 0xff000000;
	else
	  *dest = 0;
	dest++;
	pix += colorMap->getNumPixelComps();
      }
    }
  }
  gfree(lookup);

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

  cairo_surface_t *scaled_surface;

  scaled_surface = downscaleSurface (image);
  if (scaled_surface) {
    if (cairo_surface_status (scaled_surface))
      goto cleanup;
    cairo_surface_destroy (image);
    image = scaled_surface;
    width = cairo_image_surface_get_width (image);
    height = cairo_image_surface_get_height (image);
  } else {
    filter = getFilterForSurface (image, interpolate);
  }

  cairo_surface_mark_dirty (image);

  setMimeData(str, ref, image);

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

  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);
    goto cleanup;
  }

  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 = NULL;
  }

  cairo_save (cairo);
  cairo_set_source (cairo, pattern);
  if (printing)
    cairo_rectangle (cairo, 0., 0., width, height);
  else
    cairo_rectangle (cairo, 0., 0., 1., 1.);
  if (maskPattern) {
    cairo_clip (cairo);
    cairo_mask (cairo, maskPattern);
  } 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_rectangle (cairo_shape, 0., 0., width, height);
    else
      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    cairo_fill (cairo_shape);
    cairo_restore (cairo_shape);
  }

  cairo_pattern_destroy (pattern);

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


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

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

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::drawImageMask(GfxState *state, Object *ref, Stream *str,
					int width, int height, GBool invert,
					GBool interpolate, GBool inlineImg)
{
  cairo_t *cr;
  cairo_surface_t *surface;
  double x1, y1, x2, y2;
  double *ctm;
  double mat[6];
  CairoImage *image;

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  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 (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

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

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  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 (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

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

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  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 (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}

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

  ctm = state->getCTM();
  
  mat[0] = ctm[0];
  mat[1] = ctm[1];
  mat[2] = -ctm[2];
  mat[3] = -ctm[3];
  mat[4] = ctm[2] + ctm[4];
  mat[5] = ctm[3] + ctm[5];
  x1 = mat[4];
  y1 = mat[5];
  x2 = x1 + width;
  y2 = y1 + height;

  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 (NULL);
    cairo_surface_destroy (surface);
    cairo_destroy (cr);
  }
}
