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

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

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

#include "goo/gfile.h"
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Link.h"
#include "CharCodeToUnicode.h"
#include "FontEncodingTables.h"
#include <fofi/FoFiTrueType.h>
#include <splash/SplashBitmap.h>
#include "CairoOutputDev.h"
#include "CairoFontEngine.h"

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

#define soutRound(x) ((int)(x + 0.5))

//#define LOG_CAIRO

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


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

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

  FT_Init_FreeType(&ft_lib);
  fontEngine = NULL;
}

CairoOutputDev::~CairoOutputDev() {
  if (fontEngine) {
    delete fontEngine;
  }
  cairo_destroy (cairo);
  FT_Done_FreeType(ft_lib);

}

void CairoOutputDev::startDoc(XRef *xrefA) {
  xref = xrefA;
  if (fontEngine) {
    delete fontEngine;
  }
  fontEngine = new CairoFontEngine(ft_lib);
}

void CairoOutputDev::startPage(int pageNum, GfxState *state) {
  cairo_destroy (cairo);
  createCairo (state);
  
  cairo_init_clip (cairo);
  cairo_set_rgb_color (cairo, 0, 0, 0);
  cairo_set_operator (cairo, CAIRO_OPERATOR_OVER);
  cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT);
  cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
  cairo_set_dash (cairo, NULL, 0, 0.0);
  cairo_set_miter_limit (cairo, 10);
  cairo_set_tolerance (cairo, 1);
}

void CairoOutputDev::endPage() {
}

void CairoOutputDev::drawLink(Link *link, Catalog *catalog) {
}

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

void CairoOutputDev::restoreState(GfxState *state) {
  LOG(printf ("restore\n"));
  cairo_restore (cairo);
  /* TODO: Is this really needed for cairo? Maybe not */
  needFontUpdate = gTrue;
}

void CairoOutputDev::updateAll(GfxState *state) {
  updateLineDash(state);
  updateLineJoin(state);
  updateLineCap(state);
  updateLineWidth(state);
  updateFlatness(state);
  updateMiterLimit(state);
  updateFillColor(state);
  updateStrokeColor(state);
  needFontUpdate = gTrue;
}

void CairoOutputDev::updateCTM(GfxState *state, double m11, double m12,
				double m21, double m22,
				double m31, double m32) {
  updateLineDash(state);
  updateLineJoin(state);
  updateLineCap(state);
  updateLineWidth(state);
}

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

  state->getLineDash(&dashPattern, &dashLength, &dashStart);

  transformedDash = new double[dashLength];
  
  for (i = 0; i < dashLength; ++i) {
    transformedDash[i] =  state->transformWidth(dashPattern[i]);
  }
  transformedStart = state->transformWidth(dashStart);
  cairo_set_dash (cairo, transformedDash, dashLength, transformedStart);
  delete [] transformedDash;
}

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

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

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

void CairoOutputDev::updateLineWidth(GfxState *state) {
  LOG(printf ("line width: %f\n", state->getTransformedLineWidth()));
  cairo_set_line_width (cairo, state->getTransformedLineWidth());
}

void CairoOutputDev::updateFillColor(GfxState *state) {
  state->getFillRGB(&fill_color);
  LOG(printf ("fill color: %f %f %f\n", fill_color.r, fill_color.g, fill_color.b));
}

void CairoOutputDev::updateStrokeColor(GfxState *state) {
  state->getStrokeRGB(&stroke_color);
  LOG(printf ("stroke color: %f %f %f\n", stroke_color.r, stroke_color.g, stroke_color.b));
}

void CairoOutputDev::updateFont(GfxState *state) {
  cairo_font_t *font;
  double m11, m12, m21, m22;
  double w;

  LOG(printf ("updateFont() font=%s\n", state->getFont()->getName()->getCString()));
  
  /* Needs to be rethough, since fonts are now handled by cairo */
  needFontUpdate = gFalse;

  state->getFontTransMat(&m11, &m12, &m21, &m22);
  m11 *= state->getHorizScaling();
  m12 *= state->getHorizScaling();

  /* w = currentFont->getSubstitutionCorrection(state->getFont()); */
  m12 *= -1;
  m22 *= -1;

  LOG(printf ("font matrix: %f %f %f %f\n", m11, m12, m21, m22));
  
  currentFont = fontEngine->getFont (state->getFont(), xref,
				     m11, m21, m12, m22);
  font = currentFont->getFont();
  cairo_set_font (cairo, font);
}

void CairoOutputDev::doPath(GfxState *state, GfxPath *path,
			    GBool snapToGrid) {
  GfxSubpath *subpath;
  double x1, y1, x2, y2, x3, y3;
  int i, j;

  for (i = 0; i < path->getNumSubpaths(); ++i) {
    subpath = path->getSubpath(i);
    if (subpath->getNumPoints() > 0) {
      state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
      if (snapToGrid) {
	x1 = round (x1); y1 = round (y1);
      }
      cairo_move_to (cairo, x1, y1);
      LOG (printf ("move_to %f, %f\n", x1, y1));
      j = 1;
      while (j < subpath->getNumPoints()) {
	if (subpath->getCurve(j)) {
	  if (snapToGrid) {
	    x1 = round (x1); y1 = round (y1);
	    x2 = round (x2); y2 = round (y2);
	    x3 = round (x3); y3 = round (y3);
	  }
	  state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
	  state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
	  state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
	  cairo_curve_to (cairo, 
			  x1, y1,
			  x2, y2,
			  x3, y3);
	  LOG (printf ("curve_to %f, %f  %f, %f  %f, %f\n", x1, y1, x2, y2, x3, y3));
	  j += 3;
	} else {
	  state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
	  if (snapToGrid) {
	    x1 = round (x1); y1 = round (y1);
	  }
	  cairo_line_to (cairo, x1, y1);
	  LOG(printf ("line_to %f, %f\n", x1, y1));
	  ++j;
	}
      }
      if (subpath->isClosed()) {
	LOG (printf ("close\n"));
	cairo_close_path (cairo);
      }
    }
  }
}

void CairoOutputDev::stroke(GfxState *state) {
  doPath (state, state->getPath(), gFalse);
  cairo_set_rgb_color (cairo,
		       stroke_color.r, stroke_color.g, stroke_color.b);
  LOG(printf ("stroke\n"));
  cairo_stroke (cairo);
}

void CairoOutputDev::fill(GfxState *state) {
  doPath (state, state->getPath(), gFalse);
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
  cairo_set_rgb_color (cairo,
		       fill_color.r, fill_color.g, fill_color.b);
  LOG(printf ("fill\n"));
  cairo_fill (cairo);
}

void CairoOutputDev::eoFill(GfxState *state) {
  doPath (state, state->getPath(), gFalse);
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_set_rgb_color (cairo,
		       fill_color.r, fill_color.g, fill_color.b);
  LOG(printf ("fill-eo\n"));
  cairo_fill (cairo);
}

void CairoOutputDev::clip(GfxState *state, GBool snapToGrid) {
  doPath (state, state->getPath(), snapToGrid);
  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
  cairo_clip (cairo);
  cairo_new_path (cairo); /* Consume path */
  LOG (printf ("clip\n"));
}

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

void CairoOutputDev::drawString(GfxState *state, GooString *s)
{
  GfxFont *font;
  int wMode;
  int render;
  // the number of bytes in the string and not the number of glyphs?
  int len = s->getLength();
  // need at most len glyphs
  cairo_glyph_t *glyphs;
  
  char *p = s->getCString();
  int count = 0;
  double curX, curY;
  double riseX, riseY;

  font = state->getFont();
  wMode = font->getWMode();
 
  if (needFontUpdate) {
    updateFont(state);
  }
  if (!currentFont) {
    return;
  }
   
  // check for invisible text -- this is used by Acrobat Capture
  render = state->getRender();
  if (render == 3) {
    return;
  }

  // ignore empty strings
  if (len == 0)
    return;
  
  glyphs = (cairo_glyph_t *) gmalloc (len * sizeof (cairo_glyph_t));

  state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
  curX = state->getCurX();
  curY = state->getCurY();
  while (len > 0) {
    double x, y;
    double x1, y1;
    double dx, dy, tdx, tdy;
    double originX, originY, tOriginX, tOriginY;
    int n, uLen;
    CharCode code;
    Unicode u[8];
    n = font->getNextChar(p, len, &code,
	                  u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
			  &dx, &dy, &originX, &originY);
    if (wMode) {
      dx *= state->getFontSize();
      dy = dy * state->getFontSize() + state->getCharSpace();
      if (n == 1 && *p == ' ') {
	dy += state->getWordSpace();
      }
    } else {
      dx = dx * state->getFontSize() + state->getCharSpace();
      if (n == 1 && *p == ' ') {
	dx += state->getWordSpace();
      }
      dx *= state->getHorizScaling();
      dy *= state->getFontSize();
    }
    originX *= state->getFontSize();
    originY *= state->getFontSize();
    state->textTransformDelta(dx, dy, &tdx, &tdy);
    state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
    x = curX + riseX;
    y = curY + riseY;
    x -= tOriginX;
    y -= tOriginY;
    state->transform(x, y, &x1, &y1);

    glyphs[count].index = currentFont->getGlyph (code, u, uLen);
    glyphs[count].x = x1;
    glyphs[count].y = y1;
    curX += tdx;
    curY += tdy;
    p += n;
    len -= n;
    count++;
  }
  // fill
  if (!(render & 1)) {
    LOG (printf ("fill string\n"));
    cairo_set_rgb_color (cairo,
			 fill_color.r, fill_color.g, fill_color.b);
    cairo_show_glyphs (cairo, glyphs, count);
  }
  
  // stroke
  if ((render & 3) == 1 || (render & 3) == 2) {
    LOG (printf ("stroke string\n"));
    cairo_set_rgb_color (cairo,
			 stroke_color.r, stroke_color.g, stroke_color.b);
    cairo_glyph_path (cairo, glyphs, count);
    cairo_stroke (cairo);
  }

  // clip
  if (render & 4) {
    // FIXME: This is quite right yet, we need to accumulate all
    // glyphs within one text object before we clip.  Right now this
    // just add this one string.
    LOG (printf ("clip string\n"));
    cairo_glyph_path (cairo, glyphs, count);
    cairo_clip (cairo);
  }
  
  gfree (glyphs);
}

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

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

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

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

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


void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
				    int width, int height, GBool invert,
				    GBool inlineImg) {
  char *buffer;
  char *dest;
  cairo_surface_t *image;
  int x, y;
  ImageStream *imgStr;
  Guchar *pix;
  double *ctm;
  cairo_matrix_t *mat;
  int invert_bit;

  buffer = (char *)malloc (width * height * 4);
  if (buffer == NULL) {
    error(-1, "Unable to allocate memory for image.");
    return;
  }

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

  invert_bit = invert ? 1 : 0;

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

      *dest++ = soutRound(255 * fill_color.b);
      *dest++ = soutRound(255 * fill_color.g);
      *dest++ = soutRound(255 * fill_color.r);
 
      if (pix[x] ^ invert_bit)
	*dest++ = 0;
      else
	*dest++ = 255;
    }
  }

  cairo_save (cairo);

  ctm = state->getCTM();
  mat = cairo_matrix_create ();
  LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
	       width, height,
	       ctm[0], ctm[1],
	       ctm[2], ctm[3],
	       ctm[4], ctm[5]));
  cairo_matrix_set_affine (mat,
			   ctm[0]/width, ctm[1]/width,
			   -ctm[2]/height, -ctm[3]/height,
			   ctm[2] + ctm[4], ctm[3] + ctm[5]);
  cairo_concat_matrix (cairo, mat);
  cairo_matrix_destroy (mat);

  image = cairo_surface_create_for_image (
              buffer, CAIRO_FORMAT_ARGB32, width, height, width * 4);
  cairo_surface_set_filter (image, CAIRO_FILTER_BEST);
  cairo_show_surface (cairo, image, width, height);

  cairo_restore (cairo);

  cairo_surface_destroy (image);
  free (buffer);
  delete imgStr;

  
}

void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
				int width, int height,
				GfxImageColorMap *colorMap,
				int *maskColors, GBool inlineImg) {
  char *buffer;
  char *dest;
  cairo_surface_t *image;
  int x, y;
  ImageStream *imgStr;
  Guchar *pix;
  GfxRGB rgb;
  int alpha, i;
  double *ctm;
  cairo_matrix_t *mat;
  int is_identity_transform;
  
  buffer = (char *)malloc (width * height * 4);

  if (buffer == NULL) {
    error(-1, "Unable to allocate memory for image.");
    return;
  }

  /* TODO: Do we want to cache these? */
  imgStr = new ImageStream(str, width,
			   colorMap->getNumPixelComps(),
			   colorMap->getBits());
  imgStr->reset();
  
  /* ICCBased color space doesn't do any color correction
   * so check its underlying color space as well */
  is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
		  colorMap->getColorSpace()->getMode() == csICCBased && 
		  ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB;
  
  for (y = 0; y < height; y++) {
    dest = buffer + y * 4 * width;
    pix = imgStr->getLine();
    for (x = 0; x < width; x++, pix += colorMap->getNumPixelComps()) {
      if (maskColors) {
	alpha = 0;
	for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
	  if (pix[i] < maskColors[2*i] ||
	      pix[i] > maskColors[2*i+1]) {
	    alpha = 255;
	    break;
	  }
	}
      } else {
	alpha = 255;
      }
      if (is_identity_transform) {
	*dest++ = pix[2];
	*dest++ = pix[1];
	*dest++ = pix[0];
      } else {      
	colorMap->getRGB(pix, &rgb);
	*dest++ = soutRound(255 * rgb.b);
	*dest++ = soutRound(255 * rgb.g);
	*dest++ = soutRound(255 * rgb.r);
      }
      *dest++ = alpha;
    }
  }

  cairo_save (cairo);

  ctm = state->getCTM();
  mat = cairo_matrix_create ();
  LOG (printf ("draw image %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
	       width, height,
	       ctm[0], ctm[1],
	       ctm[2], ctm[3],
	       ctm[4], ctm[5]));
  cairo_matrix_set_affine (mat,
			   ctm[0]/width, ctm[1]/width,
			   -ctm[2]/height, -ctm[3]/height,
			   ctm[2] + ctm[4], ctm[3] + ctm[5]);
  cairo_concat_matrix (cairo, mat);
  cairo_matrix_destroy (mat);
  
  image = cairo_surface_create_for_image (
              buffer, CAIRO_FORMAT_ARGB32, width, height, width * 4);
  cairo_surface_set_filter (image, CAIRO_FILTER_BEST);
  cairo_show_surface (cairo, image, width, height);

  cairo_restore (cairo);
  
  cairo_surface_destroy (image);
  free (buffer);
  delete imgStr;
}
