//========================================================================
//
// 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 w;

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

  currentFont = fontEngine->getFont (state->getFont(), xref);

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

  LOG(printf ("font matrix: %f %f %f %f\n", m11, m12, m21, m22));

  w = currentFont->getSubstitutionCorrection(state->getFont());
  
  cairo_matrix_t *matrix = cairo_matrix_create ();
  cairo_matrix_set_affine (matrix,
			   m11, m21,
			   -m12*w, -m22*w,
			   0, 0);
  
  font = currentFont->getFont(matrix);
  if (font)
    cairo_set_font (cairo, font);
  cairo_matrix_destroy (matrix);
}

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