//========================================================================
//
// Splash.cc
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <stdlib.h>
#include <string.h>
#include "goo/gmem.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
#include "SplashBitmap.h"
#include "SplashState.h"
#include "SplashPath.h"
#include "SplashXPath.h"
#include "SplashXPathScanner.h"
#include "SplashPattern.h"
#include "SplashScreen.h"
#include "SplashClip.h"
#include "SplashFont.h"
#include "SplashGlyphBitmap.h"
#include "Splash.h"

//------------------------------------------------------------------------
// Splash
//------------------------------------------------------------------------

Splash::Splash(SplashBitmap *bitmapA) {
  bitmap = bitmapA;
  state = new SplashState(bitmap->width, bitmap->height);
  debugMode = gFalse;
}

Splash::~Splash() {
  while (state->next) {
    restoreState();
  }
  delete state;
}

//------------------------------------------------------------------------
// state read
//------------------------------------------------------------------------


SplashPattern *Splash::getStrokePattern() {
  return state->strokePattern;
}

SplashPattern *Splash::getFillPattern() {
  return state->fillPattern;
}

SplashScreen *Splash::getScreen() {
  return state->screen;
}

SplashCoord Splash::getLineWidth() {
  return state->lineWidth;
}

int Splash::getLineCap() {
  return state->lineCap;
}

int Splash::getLineJoin() {
  return state->lineJoin;
}

SplashCoord Splash::getMiterLimit() {
  return state->miterLimit;
}

SplashCoord Splash::getFlatness() {
  return state->flatness;
}

SplashCoord *Splash::getLineDash() {
  return state->lineDash;
}

int Splash::getLineDashLength() {
  return state->lineDashLength;
}

SplashCoord Splash::getLineDashPhase() {
  return state->lineDashPhase;
}

SplashClip *Splash::getClip() {
  return state->clip;
}

//------------------------------------------------------------------------
// state write
//------------------------------------------------------------------------

void Splash::setStrokePattern(SplashPattern *strokePattern) {
  state->setStrokePattern(strokePattern);
}

void Splash::setFillPattern(SplashPattern *fillPattern) {
  state->setFillPattern(fillPattern);
}

void Splash::setScreen(SplashScreen *screen) {
  state->setScreen(screen);
}

void Splash::setLineWidth(SplashCoord lineWidth) {
  state->lineWidth = lineWidth;
}

void Splash::setLineCap(int lineCap) {
  state->lineCap = lineCap;
}

void Splash::setLineJoin(int lineJoin) {
  state->lineJoin = lineJoin;
}

void Splash::setMiterLimit(SplashCoord miterLimit) {
  state->miterLimit = miterLimit;
}

void Splash::setFlatness(SplashCoord flatness) {
  if (flatness < 1) {
    state->flatness = 1;
  } else {
    state->flatness = flatness;
  }
}

void Splash::setLineDash(SplashCoord *lineDash, int lineDashLength,
			 SplashCoord lineDashPhase) {
  state->setLineDash(lineDash, lineDashLength, lineDashPhase);
}

void Splash::clipResetToRect(SplashCoord x0, SplashCoord y0,
			     SplashCoord x1, SplashCoord y1) {
  state->clip->resetToRect(x0, y0, x1, y1);
}

SplashError Splash::clipToRect(SplashCoord x0, SplashCoord y0,
			       SplashCoord x1, SplashCoord y1) {
  return state->clip->clipToRect(x0, y0, x1, y1);
}

SplashError Splash::clipToPath(SplashPath *path, GBool eo) {
  return state->clip->clipToPath(path, state->flatness, eo);
}

//------------------------------------------------------------------------
// state save/restore
//------------------------------------------------------------------------

void Splash::saveState() {
  SplashState *newState;

  newState = state->copy();
  newState->next = state;
  state = newState;
}

SplashError Splash::restoreState() {
  SplashState *oldState;

  if (!state->next) {
    return splashErrNoSave;
  }
  oldState = state;
  state = state->next;
  delete oldState;
  return splashOk;
}

//------------------------------------------------------------------------
// drawing operations
//------------------------------------------------------------------------

void Splash::clear(SplashColor color) {
  SplashMono1P *mono1;
  SplashMono8 *mono8;
  SplashRGB8 *rgb8;
  SplashRGB8P *rgb8pline, *rgb8p;
  SplashBGR8P *bgr8line, *bgr8;
  SplashMono1 data;
  int n, i, x, y;

  switch (bitmap->mode) {
  case splashModeMono1:
    n = ((bitmap->width + 7) >> 3) * bitmap->height;
    data = color.mono1 ? 0xff : 0x00;
    for (i = 0, mono1 = bitmap->data.mono1; i < n; ++i, ++mono1) {
      *mono1 = data;
    }
    break;
  case splashModeMono8:
    n = bitmap->width * bitmap->height;
    for (i = 0, mono8 = bitmap->data.mono8; i < n; ++i, ++mono8) {
      *mono8 = color.mono8;
    }
    break;
  case splashModeRGB8:
    n = bitmap->width * bitmap->height;
    for (i = 0, rgb8 = bitmap->data.rgb8; i < n; ++i, ++rgb8) {
      *rgb8 = color.rgb8;
    }
    break;
  case splashModeRGB8Packed:
    rgb8pline = bitmap->data.rgb8p;
    for (y = 0; y < bitmap->height; ++y) {
      rgb8p = rgb8pline;
      for (x = 0; x < bitmap->width; ++x) {
	rgb8p[0] = splashRGB8R(color.rgb8);
	rgb8p[1] = splashRGB8G(color.rgb8);
	rgb8p[2] = splashRGB8B(color.rgb8);
	rgb8p += 3;
      }
      rgb8pline += bitmap->rowSize;
    }
    break;
  case splashModeBGR8Packed:
    bgr8line = bitmap->data.bgr8;
    for (y = 0; y < bitmap->height; ++y) {
      bgr8 = bgr8line;
      for (x = 0; x < bitmap->width; ++x) {
	bgr8[2] = splashBGR8R(color.bgr8);
	bgr8[1] = splashBGR8G(color.bgr8);
	bgr8[0] = splashBGR8B(color.bgr8);
	bgr8 += 3;
      }
      bgr8line += bitmap->rowSize;
    }
    break;
  }
}

SplashError Splash::stroke(SplashPath *path) {
  SplashXPath *xPath, *xPath2;

  if (debugMode) {
    printf("stroke [dash:%d] [width:%.2f]:\n",
	   state->lineDashLength, state->lineWidth);
    dumpPath(path);
  }
  if (path->length == 0) {
    return splashErrEmptyPath;
  }
  xPath = new SplashXPath(path, state->flatness, gFalse);
  if (state->lineDashLength > 0) {
    xPath2 = makeDashedPath(xPath);
    delete xPath;
    xPath = xPath2;
  }
  if (state->lineWidth <= 1) {
    strokeNarrow(xPath);
  } else {
    strokeWide(xPath);
  }
  delete xPath;
  return splashOk;
}

void Splash::strokeNarrow(SplashXPath *xPath) {
  SplashXPathSeg *seg;
  int x0, x1, x2, x3, y0, y1, x, y, t;
  SplashCoord dx, dy, dxdy;
  SplashClipResult clipRes;
  int i;

  for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) {

    x0 = splashFloor(seg->x0);
    x1 = splashFloor(seg->x1);
    y0 = splashFloor(seg->y0);
    y1 = splashFloor(seg->y1);

    // horizontal segment
    if (y0 == y1) {
      if (x0 > x1) {
	t = x0; x0 = x1; x1 = t;
      }
      if ((clipRes = state->clip->testSpan(x0, x1, y0))
	  != splashClipAllOutside) {
	drawSpan(x0, x1, y0, state->strokePattern,
		 clipRes == splashClipAllInside);
      }

    // segment with |dx| > |dy|
    } else if (splashAbs(seg->dxdy) > 1) {
      dx = seg->x1 - seg->x0;
      dy = seg->y1 - seg->y0;
      dxdy = seg->dxdy;
      if (y0 > y1) {
	t = y0; y0 = y1; y1 = t;
	t = x0; x0 = x1; x1 = t;
	dx = -dx;
	dy = -dy;
      }
      if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,
					   x0 <= x1 ? x1 : x0, y1))
	  != splashClipAllOutside) {
	if (dx > 0) {
	  x2 = x0;
	  for (y = y0; y < y1; ++y) {
	    x3 = splashFloor(seg->x0 + (y + 1 - seg->y0) * dxdy);
	    drawSpan(x2, x3 - 1, y, state->strokePattern,
		     clipRes == splashClipAllInside);
	    x2 = x3;
	  }
	  drawSpan(x2, x1, y, state->strokePattern,
		   clipRes == splashClipAllInside);
	} else {
	  x2 = x0;
	  for (y = y0; y < y1; ++y) {
	    x3 = splashFloor(seg->x0 + (y + 1 - seg->y0) * dxdy);
	    drawSpan(x3 + 1, x2, y, state->strokePattern,
		     clipRes == splashClipAllInside);
	    x2 = x3;
	  }
	  drawSpan(x1, x2, y, state->strokePattern,
		   clipRes == splashClipAllInside);
	}
      }

    // segment with |dy| > |dx|
    } else {
      dxdy = seg->dxdy;
      if (y0 > y1) {
	t = y0; y0 = y1; y1 = t;
      }
      if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,
					   x0 <= x1 ? x1 : x0, y1))
	  != splashClipAllOutside) {
	for (y = y0; y <= y1; ++y) {
	  x = splashFloor(seg->x0 + (y - seg->y0) * dxdy);
	  drawPixel(x, y, state->strokePattern,
		    clipRes == splashClipAllInside);
	}
      }
    }
  }
}

void Splash::strokeWide(SplashXPath *xPath) {
  SplashXPathSeg *seg, *seg2;
  SplashPath *widePath;
  SplashCoord d, dx, dy, wdx, wdy, dxPrev, dyPrev, wdxPrev, wdyPrev;
  SplashCoord dotprod, miter;
  int i, j;

  dx = dy = wdx = wdy = 0; // make gcc happy
  dxPrev = dyPrev = wdxPrev = wdyPrev = 0; // make gcc happy

  for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) {

    // save the deltas for the previous segment; if this is the first
    // segment on a subpath, compute the deltas for the last segment
    // on the subpath (which may be used to draw a line join)
    if (seg->flags & splashXPathFirst) {
      for (j = i + 1, seg2 = &xPath->segs[j]; j < xPath->length; ++j, ++seg2) {
	if (seg2->flags & splashXPathLast) {
	  d = splashDist(seg2->x0, seg2->y0, seg2->x1, seg2->y1);
	  if (d == 0) {
	    //~ not clear what the behavior should be for joins with d==0
	    dxPrev = 0;
	    dyPrev = 1;
	  } else {
	    d = 1 / d;
	    dxPrev = d * (seg2->x1 - seg2->x0);
	    dyPrev = d * (seg2->y1 - seg2->y0);
	  }
	  wdxPrev = 0.5 * state->lineWidth * dxPrev;
	  wdyPrev = 0.5 * state->lineWidth * dyPrev;
	  break;
	}
      }
    } else {
      dxPrev = dx;
      dyPrev = dy;
      wdxPrev = wdx;
      wdyPrev = wdy;
    }

    // compute deltas for this line segment
    d = splashDist(seg->x0, seg->y0, seg->x1, seg->y1);
    if (d == 0) {
      // we need to draw end caps on zero-length lines
      //~ not clear what the behavior should be for splashLineCapButt with d==0
      dx = 0;
      dy = 1;
    } else {
      d = 1 / d;
      dx = d * (seg->x1 - seg->x0);
      dy = d * (seg->y1 - seg->y0);
    }
    wdx = 0.5 * state->lineWidth * dx;
    wdy = 0.5 * state->lineWidth * dy;

    // initialize the path (which will be filled)
    widePath = new SplashPath();
    widePath->moveTo(seg->x0 - wdy, seg->y0 + wdx);

    // draw the start cap
    if (seg->flags & splashXPathEnd0) {
      switch (state->lineCap) {
      case splashLineCapButt:
	widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
	break;
      case splashLineCapRound:
	widePath->arcCWTo(seg->x0 + wdy, seg->y0 - wdx, seg->x0, seg->y0);
	break;
      case splashLineCapProjecting:
	widePath->lineTo(seg->x0 - wdx - wdy, seg->y0 + wdx - wdy);
	widePath->lineTo(seg->x0 - wdx + wdy, seg->y0 - wdx - wdy);
	widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
	break;
      }
    } else {
      widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
    }

    // draw the left side of the segment
    widePath->lineTo(seg->x1 + wdy, seg->y1 - wdx);

    // draw the end cap
    if (seg->flags & splashXPathEnd1) {
      switch (state->lineCap) {
      case splashLineCapButt:
	widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx);
	break;
      case splashLineCapRound:
	widePath->arcCWTo(seg->x1 - wdy, seg->y1 + wdx, seg->x1, seg->y1);
	break;
      case splashLineCapProjecting:
	widePath->lineTo(seg->x1 + wdx + wdy, seg->y1 - wdx + wdy);
	widePath->lineTo(seg->x1 + wdx - wdy, seg->y1 + wdx + wdy);
	widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx);
	break;
      }
    } else {
      widePath->lineTo(seg->x1 - wdy, seg->y1 + wdx);
    }

    // draw the right side of the segment
    widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);

    // fill the segment
    fillWithPattern(widePath, gTrue, state->strokePattern);
    delete widePath;

    // draw the line join
    if (!(seg->flags & splashXPathEnd0)) {
      widePath = NULL;
      switch (state->lineJoin) {
      case splashLineJoinMiter:
	dotprod = -(dx * dxPrev + dy * dyPrev);
	if (dotprod != 1) {
	  widePath = new SplashPath();
	  widePath->moveTo(seg->x0, seg->y0);
	  miter = 2 / (1 - dotprod);
	  if (splashSqrt(miter) <= state->miterLimit) {
	    miter = splashSqrt(miter - 1);
	    if (dy * dxPrev > dx * dyPrev) {
	      widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev);
	      widePath->lineTo(seg->x0 + wdy - miter * wdx,
			       seg->y0 - wdx - miter * wdy);
	      widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
	    } else {
	      widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev);
	      widePath->lineTo(seg->x0 - wdy - miter * wdx,
			       seg->y0 + wdx - miter * wdy);
	      widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
	    }
	  } else {
	    if (dy * dxPrev > dx * dyPrev) {
	      widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev);
	      widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
	    } else {
	      widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev);
	      widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
	    }
	  }
	}
	break;
      case splashLineJoinRound:
	widePath = new SplashPath();
	widePath->moveTo(seg->x0 + wdy, seg->y0 - wdx);
	widePath->arcCWTo(seg->x0 + wdy, seg->y0 - wdx, seg->x0, seg->y0);
	break;
      case splashLineJoinBevel:
	widePath = new SplashPath();
	widePath->moveTo(seg->x0, seg->y0);
	if (dy * dxPrev > dx * dyPrev) {
	  widePath->lineTo(seg->x0 + wdyPrev, seg->y0 - wdxPrev);
	  widePath->lineTo(seg->x0 + wdy, seg->y0 - wdx);
	} else {
	  widePath->lineTo(seg->x0 - wdyPrev, seg->y0 + wdxPrev);
	  widePath->lineTo(seg->x0 - wdy, seg->y0 + wdx);
	}
	break;
      }
      if (widePath) {
	fillWithPattern(widePath, gTrue, state->strokePattern);
	delete widePath;
      }
    }
  }
}

SplashXPath *Splash::makeDashedPath(SplashXPath *xPath) {
  SplashXPath *dPath;
  GBool lineDashStartOn, lineDashOn;
  GBool atSegStart, atSegEnd, atDashStart, atDashEnd;
  int lineDashStartIdx, lineDashIdx, subpathStart;
  SplashCoord lineDashTotal, lineDashStartPhase, lineDashDist;
  int segIdx;
  SplashXPathSeg *seg;
  SplashCoord sx0, sy0, sx1, sy1, ax0, ay0, ax1, ay1, dist;
  int i;

  dPath = new SplashXPath();

  lineDashTotal = 0;
  for (i = 0; i < state->lineDashLength; ++i) {
    lineDashTotal += state->lineDash[i];
  }
  lineDashStartPhase = state->lineDashPhase;
  i = splashFloor(lineDashStartPhase / lineDashTotal);
  lineDashStartPhase -= i * lineDashTotal;
  lineDashStartOn = gTrue;
  lineDashStartIdx = 0;
  while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) {
    lineDashStartOn = !lineDashStartOn;
    lineDashStartPhase -= state->lineDash[lineDashStartIdx];
    ++lineDashStartIdx;
  }

  segIdx = 0;
  seg = xPath->segs;
  sx0 = seg->x0;
  sy0 = seg->y0;
  sx1 = seg->x1;
  sy1 = seg->y1;
  dist = splashDist(sx0, sy0, sx1, sy1);
  lineDashOn = lineDashStartOn;
  lineDashIdx = lineDashStartIdx;
  lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase;
  atSegStart = gTrue;
  atDashStart = gTrue;
  subpathStart = dPath->length;

  while (segIdx < xPath->length) {

    ax0 = sx0;
    ay0 = sy0;
    if (dist <= lineDashDist) {
      ax1 = sx1;
      ay1 = sy1;
      lineDashDist -= dist;
      dist = 0;
      atSegEnd = gTrue;
      atDashEnd = lineDashDist == 0 || (seg->flags & splashXPathLast);
    } else {
      ax1 = sx0 + (lineDashDist / dist) * (sx1 - sx0);
      ay1 = sy0 + (lineDashDist / dist) * (sy1 - sy0);
      sx0 = ax1;
      sy0 = ay1;
      dist -= lineDashDist;
      lineDashDist = 0;
      atSegEnd = gFalse;
      atDashEnd = gTrue;
    }

    if (lineDashOn) {
      dPath->addSegment(ax0, ay0, ax1, ay1,
			atDashStart, atDashEnd,
			atDashStart, atDashEnd);
      // end of closed subpath
      if (atSegEnd &&
	  (seg->flags & splashXPathLast) &&
	  !(seg->flags & splashXPathEnd1)) {
	dPath->segs[subpathStart].flags &= ~splashXPathEnd0;
	dPath->segs[dPath->length - 1].flags &= ~splashXPathEnd1;
      }
    }

    if (atDashEnd) {
      lineDashOn = !lineDashOn;
      if (++lineDashIdx == state->lineDashLength) {
	lineDashIdx = 0;
      }
      lineDashDist = state->lineDash[lineDashIdx];
      atDashStart = gTrue;
    } else {
      atDashStart = gFalse;
    }
    if (atSegEnd) {
      if (++segIdx < xPath->length) {
	++seg;
	sx0 = seg->x0;
	sy0 = seg->y0;
	sx1 = seg->x1;
	sy1 = seg->y1;
	dist = splashDist(sx0, sy0, sx1, sy1);
	if (seg->flags & splashXPathFirst) {
	  lineDashOn = lineDashStartOn;
	  lineDashIdx = lineDashStartIdx;
	  lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase;
	  atDashStart = gTrue;
	  subpathStart = dPath->length;
	}
      }
      atSegStart = gTrue;
    } else {
      atSegStart = gFalse;
    }
  }

  return dPath;
}

SplashError Splash::fill(SplashPath *path, GBool eo) {
  if (debugMode) {
    printf("fill [eo:%d]:\n", eo);
    dumpPath(path);
  }
  return fillWithPattern(path, eo, state->fillPattern);
}

SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
				    SplashPattern *pattern) {
  SplashXPath *xPath;
  SplashXPathScanner *scanner;
  int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
  SplashClipResult clipRes, clipRes2;

  if (path->length == 0 || path->length == 1) {
    return splashErrEmptyPath;
  }
  xPath = new SplashXPath(path, state->flatness, gTrue);
  xPath->sort();
  scanner = new SplashXPathScanner(xPath, eo);

  // get the min and max x and y values
  scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);

  // check clipping
  if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI))
      != splashClipAllOutside) {

    // draw the spans
    for (y = yMinI; y <= yMaxI; ++y) {
      while (scanner->getNextSpan(y, &x0, &x1)) {
	if (clipRes == splashClipAllInside) {
	  drawSpan(x0, x1, y, pattern, gTrue);
	} else {
	  clipRes2 = state->clip->testSpan(x0, x1, y);
	  drawSpan(x0, x1, y, pattern, clipRes2 == splashClipAllInside);
	}
      }
    }
  }

  delete scanner;
  delete xPath;
  return splashOk;
}

SplashError Splash::xorFill(SplashPath *path, GBool eo) {
  SplashXPath *xPath;
  SplashXPathScanner *scanner;
  int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
  SplashClipResult clipRes, clipRes2;

  if (path->length == 0) {
    return splashErrEmptyPath;
  }
  xPath = new SplashXPath(path, state->flatness, gTrue);
  xPath->sort();
  scanner = new SplashXPathScanner(xPath, eo);

  // get the min and max x and y values
  scanner->getBBox(&xMinI, &yMinI, &xMaxI, &yMaxI);

  // check clipping
  if ((clipRes = state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI))
      != splashClipAllOutside) {

    // draw the spans
    for (y = yMinI; y <= yMaxI; ++y) {
      while (scanner->getNextSpan(y, &x0, &x1)) {
	if (clipRes == splashClipAllInside) {
	  xorSpan(x0, x1, y, state->fillPattern, gTrue);
	} else {
	  clipRes2 = state->clip->testSpan(x0, x1, y);
	  xorSpan(x0, x1, y, state->fillPattern,
		  clipRes2 == splashClipAllInside);
	}
      }
    }
  }

  delete scanner;
  delete xPath;
  return splashOk;
}

void Splash::drawPixel(int x, int y, SplashColor *color, GBool noClip) {
  SplashMono1P *mono1;
  SplashRGB8P *rgb8p;
  SplashBGR8P *bgr8;

  if (noClip || state->clip->test(x, y)) {
    switch (bitmap->mode) {
    case splashModeMono1:
      mono1 = &bitmap->data.mono8[y * bitmap->rowSize + (x >> 3)];
      if (color->mono1) {
	*mono1 |= 0x80 >> (x & 7);
      } else {
	*mono1 &= ~(0x80 >> (x & 7));
      }
      break;
    case splashModeMono8:
      bitmap->data.mono8[y * bitmap->width + x] = color->mono8;
      break;
    case splashModeRGB8:
      bitmap->data.rgb8[y * bitmap->width + x] = color->rgb8;
      break;
    case splashModeRGB8Packed:
      rgb8p = &bitmap->data.rgb8p[y * bitmap->rowSize + 3 * x];
      rgb8p[0] = splashRGB8R(color->rgb8);
      rgb8p[1] = splashRGB8G(color->rgb8);
      rgb8p[2] = splashRGB8B(color->rgb8);
      break;
    case splashModeBGR8Packed:
      bgr8 = &bitmap->data.bgr8[y * bitmap->rowSize + 3 * x];
      bgr8[2] = splashBGR8R(color->bgr8);
      bgr8[1] = splashBGR8G(color->bgr8);
      bgr8[0] = splashBGR8B(color->bgr8);
      break;
    }
  }
}

void Splash::drawPixel(int x, int y, SplashPattern *pattern, GBool noClip) {
  SplashColor color;
  SplashMono1P *mono1;
  SplashRGB8P *rgb8p;
  SplashBGR8P *bgr8;

  if (noClip || state->clip->test(x, y)) {
    color = pattern->getColor(x, y);
    switch (bitmap->mode) {
    case splashModeMono1:
      mono1 = &bitmap->data.mono8[y * bitmap->rowSize + (x >> 3)];
      if (color.mono1) {
	*mono1 |= 0x80 >> (x & 7);
      } else {
	*mono1 &= ~(0x80 >> (x & 7));
      }
      break;
    case splashModeMono8:
      bitmap->data.mono8[y * bitmap->width + x] = color.mono8;
      break;
    case splashModeRGB8:
      bitmap->data.rgb8[y * bitmap->width + x] = color.rgb8;
      break;
    case splashModeRGB8Packed:
      rgb8p = &bitmap->data.rgb8p[y * bitmap->rowSize + 3 * x];
      rgb8p[0] = splashRGB8R(color.rgb8);
      rgb8p[1] = splashRGB8G(color.rgb8);
      rgb8p[2] = splashRGB8B(color.rgb8);
      break;
    case splashModeBGR8Packed:
      bgr8 = &bitmap->data.bgr8[y * bitmap->rowSize + 3 * x];
      bgr8[2] = splashBGR8R(color.bgr8);
      bgr8[1] = splashBGR8G(color.bgr8);
      bgr8[0] = splashBGR8B(color.bgr8);
      break;
    }
  }
}

void Splash::drawSpan(int x0, int x1, int y, SplashPattern *pattern,
		      GBool noClip) {
  SplashColor color;
  SplashMono1P *mono1;
  SplashMono8 *mono8;
  SplashRGB8 *rgb8;
  SplashRGB8P *rgb8p;
  SplashBGR8P *bgr8;
  SplashMono1 mask1;
  int i, j, n;

  n = x1 - x0 + 1;

  switch (bitmap->mode) {
  case splashModeMono1:
    mono1 = &bitmap->data.mono8[y * bitmap->rowSize + (x0 >> 3)];
    i = 0;
    if ((j = x0 & 7)) {
      mask1 = 0x80 >> j;
      for (j = x0 & 7; j < 8 && i < n; ++i, ++j) {
	if (noClip || state->clip->test(x0 + i, y)) {
	  color = pattern->getColor(x0 + i, y);
	  if (color.mono1) {
	    *mono1 |= mask1;
	  } else {
	    *mono1 &= ~mask1;
	  }
	}
	mask1 >>= 1;
      }
      ++mono1;
    }
    while (i < n) {
      mask1 = 0x80;
      for (j = 0; j < 8 && i < n; ++i, ++j) {
	if (noClip || state->clip->test(x0 + i, y)) {
	  color = pattern->getColor(x0 + i, y);
	  if (color.mono1) {
	    *mono1 |= mask1;
	  } else {
	    *mono1 &= ~mask1;
	  }
	}
	mask1 >>= 1;
      }
      ++mono1;
    }
    break;

  case splashModeMono8:
    mono8 = &bitmap->data.mono8[y * bitmap->width + x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	*mono8 = color.mono8;
      }
      ++mono8;
    }
    break;

  case splashModeRGB8:
    rgb8 = &bitmap->data.rgb8[y * bitmap->width + x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	*rgb8 = color.rgb8;
      }
      ++rgb8;
    }
    break;

  case splashModeRGB8Packed:
    rgb8p = &bitmap->data.rgb8p[y * bitmap->rowSize + 3 * x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	rgb8p[0] = splashRGB8R(color.rgb8);
	rgb8p[1] = splashRGB8G(color.rgb8);
	rgb8p[2] = splashRGB8B(color.rgb8);
      }
      rgb8p += 3;
    }
    break;

  case splashModeBGR8Packed:
    bgr8 = &bitmap->data.bgr8[y * bitmap->rowSize + 3 * x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	bgr8[2] = splashBGR8R(color.bgr8);
	bgr8[1] = splashBGR8G(color.bgr8);
	bgr8[0] = splashBGR8B(color.bgr8);
      }
      bgr8 += 3;
    }
    break;
  }
}

void Splash::xorSpan(int x0, int x1, int y, SplashPattern *pattern,
		     GBool noClip) {
  SplashColor color;
  SplashMono1P *mono1;
  SplashMono8 *mono8;
  SplashRGB8 *rgb8;
  SplashRGB8P *rgb8p;
  SplashBGR8P *bgr8;
  SplashMono1 mask1;
  int i, j, n;

  n = x1 - x0 + 1;

  switch (bitmap->mode) {
  case splashModeMono1:
    mono1 = &bitmap->data.mono8[y * bitmap->rowSize + (x0 >> 3)];
    i = 0;
    if ((j = x0 & 7)) {
      mask1 = 0x80 >> j;
      for (j = x0 & 7; j < 8 && i < n; ++i, ++j) {
	if (noClip || state->clip->test(x0 + i, y)) {
	  color = pattern->getColor(x0 + i, y);
	  if (color.mono1) {
	    *mono1 ^= mask1;
	  }
	}
	mask1 >>= 1;
      }
      ++mono1;
    }
    while (i < n) {
      mask1 = 0x80;
      for (j = 0; j < 8 && i < n; ++i, ++j) {
	if (noClip || state->clip->test(x0 + i, y)) {
	  color = pattern->getColor(x0 + i, y);
	  if (color.mono1) {
	    *mono1 ^= mask1;
	  }
	}
	mask1 >>= 1;
      }
      ++mono1;
    }
    break;

  case splashModeMono8:
    mono8 = &bitmap->data.mono8[y * bitmap->width + x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	*mono8 ^= color.mono8;
      }
      ++mono8;
    }
    break;

  case splashModeRGB8:
    rgb8 = &bitmap->data.rgb8[y * bitmap->width + x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	*rgb8 ^= color.rgb8;
      }
      ++rgb8;
    }
    break;

  case splashModeRGB8Packed:
    rgb8p = &bitmap->data.rgb8p[y * bitmap->rowSize + 3 * x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	rgb8p[0] ^= splashRGB8R(color.rgb8);
	rgb8p[1] ^= splashRGB8G(color.rgb8);
	rgb8p[2] ^= splashRGB8B(color.rgb8);
      }
      rgb8p += 3;
    }
    break;

  case splashModeBGR8Packed:
    bgr8 = &bitmap->data.bgr8[y * bitmap->rowSize + 3 * x0];
    for (i = 0; i < n; ++i) {
      if (noClip || state->clip->test(x0 + i, y)) {
	color = pattern->getColor(x0 + i, y);
	bgr8[2] ^= splashBGR8R(color.bgr8);
	bgr8[1] ^= splashBGR8G(color.bgr8);
	bgr8[0] ^= splashBGR8B(color.bgr8);
      }
      bgr8 += 3;
    }
    break;
  }
}

void Splash::getPixel(int x, int y, SplashColor *pixel) {
  SplashRGB8P *rgb8p;
  SplashBGR8P *bgr8;

  if (y < 0 || y >= bitmap->height || x < 0 || x >= bitmap->width) {
    return;
  }
  switch (bitmap->mode) {
  case splashModeMono1:
    pixel->mono1 = (bitmap->data.mono1[y * bitmap->rowSize + (x >> 3)]
		    >> (7 - (x & 7))) & 1;
    break;
  case splashModeMono8:
    pixel->mono8 = bitmap->data.mono8[y * bitmap->width + x];
    break;
  case splashModeRGB8:
    pixel->rgb8 = bitmap->data.rgb8[y * bitmap->width + x];
    break;
  case splashModeRGB8Packed:
    rgb8p = &bitmap->data.rgb8p[y * bitmap->rowSize + 3 * x];
    pixel->rgb8 = splashMakeRGB8(rgb8p[0], rgb8p[1], rgb8p[2]);
    break;
  case splashModeBGR8Packed:
    bgr8 = &bitmap->data.bgr8[y * bitmap->rowSize + 3 * x];
    pixel->bgr8 = splashMakeBGR8(bgr8[2], bgr8[1], bgr8[0]);
    break;
  }
}

SplashError Splash::fillChar(SplashCoord x, SplashCoord y,
			     int c, SplashFont *font) {
  SplashGlyphBitmap glyph;
  int x0, y0, xFrac, yFrac;
  SplashError err;

  if (debugMode) {
    printf("fillChar: x=%.2f y=%.2f c=%3d=0x%02x='%c'\n",
	   x, y, c, c, c);
  }
  x0 = splashFloor(x);
  xFrac = splashFloor((x - x0) * splashFontFraction);
  y0 = splashFloor(y);
  yFrac = splashFloor((y - y0) * splashFontFraction);
  if (!font->getGlyph(c, xFrac, yFrac, &glyph)) {
    return splashErrNoGlyph;
  }
  err = fillGlyph(x, y, &glyph);
  if (glyph.freeData) {
    gfree(glyph.data);
  }
  return err;
}

SplashError Splash::fillGlyph(SplashCoord x, SplashCoord y,
			      SplashGlyphBitmap *glyph) {
  int alpha, ialpha;
  Guchar *p;
  SplashColor fg;
  SplashMono1P *mono1Ptr;
  SplashMono8 *mono8Ptr;
  SplashRGB8 *rgb8Ptr;
  SplashRGB8P *rgb8pPtr;
  SplashBGR8P *bgr8Ptr;
  SplashMono8 bgMono8;
  int bgR, bgG, bgB;
  SplashClipResult clipRes;
  GBool noClip;
  int x0, y0, x1, y1, xx, xx1, yy;

  x0 = splashFloor(x);
  y0 = splashFloor(y);

  if ((clipRes = state->clip->testRect(x0 - glyph->x,
				       y0 - glyph->y,
				       x0 - glyph->x + glyph->w - 1,
				       y0 - glyph->y + glyph->h - 1))
      != splashClipAllOutside) {
    noClip = clipRes == splashClipAllInside;

    //~ optimize this
    if (glyph->aa) {
      p = glyph->data;
      for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) {
	for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; ++xx, ++x1) {
	  alpha = *p++;
	  if (alpha > 0) {
	    if (noClip || state->clip->test(x1, y1)) {
	      ialpha = 255 - alpha;
	      fg = state->fillPattern->getColor(x1, y1);
	      switch (bitmap->mode) {
	      case splashModeMono1:
		if (alpha >= 0x80) {
		  mono1Ptr = &bitmap->data.mono1[y1 * bitmap->rowSize +
						 (x1 >> 3)];
		  if (fg.mono1) {
		    *mono1Ptr |= 0x80 >> (x1 & 7);
		  } else {
		    *mono1Ptr &= ~(0x80 >> (x1 & 7));
		  }
		}
		break;
	      case splashModeMono8:
		mono8Ptr = &bitmap->data.mono8[y1 * bitmap->width + x1];
		bgMono8 = *mono8Ptr;
		// note: floor(x / 255) = x >> 8 (for 16-bit x)
		*mono8Ptr = (alpha * fg.mono8 + ialpha * bgMono8) >> 8;
		break;
	      case splashModeRGB8:
		rgb8Ptr = &bitmap->data.rgb8[y1 * bitmap->width + x1];
		bgR = splashRGB8R(*rgb8Ptr);
		bgG = splashRGB8G(*rgb8Ptr);
		bgB = splashRGB8B(*rgb8Ptr);
		*rgb8Ptr = splashMakeRGB8((alpha * splashRGB8R(fg.rgb8) +
					   ialpha * bgR) >> 8,
					  (alpha * splashRGB8G(fg.rgb8) +
					   ialpha * bgG) >> 8,
					  (alpha * splashRGB8B(fg.rgb8) +
					   ialpha * bgB) >> 8);
		break;
	      case splashModeRGB8Packed:
		rgb8pPtr = &bitmap->data.rgb8p[y1 * bitmap->rowSize + 3 * x1];
		rgb8pPtr[0] =
		    (alpha * splashRGB8R(fg.rgb8) + ialpha * rgb8pPtr[0]) >> 8;
		rgb8pPtr[1] =
		    (alpha * splashRGB8G(fg.rgb8) + ialpha * rgb8pPtr[1]) >> 8;
		rgb8pPtr[2] =
		    (alpha * splashRGB8B(fg.rgb8) + ialpha * rgb8pPtr[2]) >> 8;
		break;
	      case splashModeBGR8Packed:
		bgr8Ptr = &bitmap->data.bgr8[y1 * bitmap->rowSize + 3 * x1];
		bgr8Ptr[2] =
		    (alpha * splashBGR8R(fg.bgr8) + ialpha * bgr8Ptr[2]) >> 8;
		bgr8Ptr[1] =
		    (alpha * splashBGR8G(fg.bgr8) + ialpha * bgr8Ptr[1]) >> 8;
		bgr8Ptr[0] =
		    (alpha * splashBGR8B(fg.bgr8) + ialpha * bgr8Ptr[0]) >> 8;
		break;
	      }
	    }
	  }
	}
      }

    } else {
      p = glyph->data;
      for (yy = 0, y1 = y0 - glyph->y; yy < glyph->h; ++yy, ++y1) {
	for (xx = 0, x1 = x0 - glyph->x; xx < glyph->w; xx += 8) {
	  alpha = *p++;
	  for (xx1 = 0; xx1 < 8 && xx + xx1 < glyph->w; ++xx1, ++x1) {
	    if (alpha & 0x80) {
	      if (noClip || state->clip->test(x1, y1)) {
		fg = state->fillPattern->getColor(x1, y1);
		switch (bitmap->mode) {
		case splashModeMono1:
		  mono1Ptr = &bitmap->data.mono1[y1 * bitmap->rowSize +
						 (x1 >> 3)];
		  if (fg.mono1) {
		    *mono1Ptr |= 0x80 >> (x1 & 7);
		  } else {
		    *mono1Ptr &= ~(0x80 >> (x1 & 7));
		  }
		  break;
		case splashModeMono8:
		  bitmap->data.mono8[y1 * bitmap->width + x1] = fg.mono8;
		  break;
		case splashModeRGB8:
		  bitmap->data.rgb8[y1 * bitmap->width + x1] = fg.rgb8;
		  break;
		case splashModeRGB8Packed:
		  rgb8pPtr = &bitmap->data.rgb8p[y1 * bitmap->rowSize + 3 * x1];
		  rgb8pPtr[0] = splashRGB8R(fg.rgb8);
		  rgb8pPtr[1] = splashRGB8G(fg.rgb8);
		  rgb8pPtr[2] = splashRGB8B(fg.rgb8);
		  break;
		case splashModeBGR8Packed:
		  bgr8Ptr = &bitmap->data.bgr8[y1 * bitmap->rowSize + 3 * x1];
		  bgr8Ptr[2] = splashBGR8R(fg.bgr8);
		  bgr8Ptr[1] = splashBGR8G(fg.bgr8);
		  bgr8Ptr[0] = splashBGR8B(fg.bgr8);
		  break;
		}
	      }
	    }
	    alpha <<= 1;
	  }
	}
      }
    }
  }

  return splashOk;
}

SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
				  int w, int h, SplashCoord *mat) {
  GBool rot;
  SplashCoord xScale, yScale, xShear, yShear;
  int tx, ty, scaledWidth, scaledHeight, xSign, ySign;
  int ulx, uly, llx, lly, urx, ury, lrx, lry;
  int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1;
  int xMin, xMax, yMin, yMax;
  SplashClipResult clipRes, clipRes2;
  int yp, yq, yt, yStep, lastYStep;
  int xp, xq, xt, xStep, xSrc;
  int k1, spanXMin, spanXMax, spanY;
  SplashMono1 *pixBuf;
  SplashMono1 *p;
  int pixAcc;
  SplashCoord alpha;
  SplashColor fg, bg, pix;
  int x, y, x1, y1, x2, y2;
  int n, m, i, j;

  if (debugMode) {
    printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",
	   w, h, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
  }

  // check for singular matrix
  if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) {
    return splashErrSingularMatrix;
  }

  // compute scale, shear, rotation, translation parameters
  rot = splashAbs(mat[1]) > splashAbs(mat[0]);
  if (rot) {
    xScale = -mat[1];
    yScale = mat[2] - (mat[0] * mat[3]) / mat[1];
    xShear = -mat[3] / yScale;
    yShear = -mat[0] / mat[1];
  } else {
    xScale = mat[0];
    yScale = mat[3] - (mat[1] * mat[2]) / mat[0];
    xShear = mat[2] / yScale;
    yShear = mat[1] / mat[0];
  }
  tx = splashRound(mat[4]);
  ty = splashRound(mat[5]);
  scaledWidth = abs(splashRound(mat[4] + xScale) - tx) + 1;
  scaledHeight = abs(splashRound(mat[5] + yScale) - ty) + 1;
  xSign = (xScale < 0) ? -1 : 1;
  ySign = (yScale < 0) ? -1 : 1;

  // clipping
  ulx1 = 0;
  uly1 = 0;
  urx1 = xSign * (scaledWidth - 1);
  ury1 = splashRound(yShear * urx1);
  llx1 = splashRound(xShear * ySign * (scaledHeight - 1));
  lly1 = ySign * (scaledHeight - 1) + splashRound(yShear * llx1);
  lrx1 = xSign * (scaledWidth - 1) +
           splashRound(xShear * ySign * (scaledHeight - 1));
  lry1 = ySign * (scaledHeight - 1) + splashRound(yShear * lrx1);
  if (rot) {
    ulx = tx + uly1;    uly = ty - ulx1;
    urx = tx + ury1;    ury = ty - urx1;
    llx = tx + lly1;    lly = ty - llx1;
    lrx = tx + lry1;    lry = ty - lrx1;
  } else {
    ulx = tx + ulx1;    uly = ty + uly1;
    urx = tx + urx1;    ury = ty + ury1;
    llx = tx + llx1;    lly = ty + lly1;
    lrx = tx + lrx1;    lry = ty + lry1;
  }
  xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx
                                   : (llx < lrx) ? llx : lrx
		     : (urx < llx) ? (urx < lrx) ? urx : lrx
                                   : (llx < lrx) ? llx : lrx;
  xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx
                                   : (llx > lrx) ? llx : lrx
		     : (urx > llx) ? (urx > lrx) ? urx : lrx
                                   : (llx > lrx) ? llx : lrx;
  yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry
                                   : (lly < lry) ? lly : lry
		     : (ury < lly) ? (ury < lry) ? ury : lry
                                   : (lly < lry) ? lly : lry;
  yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry
                                   : (lly > lry) ? lly : lry
		     : (ury > lly) ? (ury > lry) ? ury : lry
                                   : (lly > lry) ? lly : lry;
  clipRes = state->clip->testRect(xMin, yMin, xMax, yMax);

  // compute Bresenham parameters for x and y scaling
  yp = h / scaledHeight;
  yq = h % scaledHeight;
  xp = w / scaledWidth;
  xq = w % scaledWidth;

  // allocate pixel buffer
  pixBuf = (SplashMono1 *)gmalloc((yp + 1) * w * sizeof(SplashMono1));

  // init y scale Bresenham
  yt = 0;
  lastYStep = 1;

  for (y = 0; y < scaledHeight; ++y) {

    // y scale Bresenham
    yStep = yp;
    yt += yq;
    if (yt >= scaledHeight) {
      yt -= scaledHeight;
      ++yStep;
    }

    // read row(s) from image
    n = (yp > 0) ? yStep : lastYStep;
    if (n > 0) {
      p = pixBuf;
      for (i = 0; i < n; ++i) {
	for (j = 0; j < w; ++j) {
	  (*src)(srcData, p++);
	}
      }
    }
    lastYStep = yStep;

    // loop-invariant constants
    k1 = splashRound(xShear * ySign * y);

    // clipping test
    if (clipRes != splashClipAllInside &&
	!rot &&
	splashRound(yShear * k1) ==
	  splashRound(yShear * (xSign * (scaledWidth - 1) + k1))) {
      if (xSign > 0) {
	spanXMin = tx + k1;
	spanXMax = spanXMin + (scaledWidth - 1);
      } else {
	spanXMax = tx + k1;
	spanXMin = spanXMax - (scaledWidth - 1);
      }
      spanY = ty + ySign * y + splashRound(xShear * ySign * y);
      clipRes2 = state->clip->testSpan(spanXMin, spanXMax, spanY);
      if (clipRes2 == splashClipAllOutside) {
	continue;
      }
    } else {
      clipRes2 = clipRes;
    }

    // init x scale Bresenham
    xt = 0;
    xSrc = 0;

    for (x = 0; x < scaledWidth; ++x) {

      // x scale Bresenham
      xStep = xp;
      xt += xq;
      if (xt >= scaledWidth) {
	xt -= scaledWidth;
	++xStep;
      }

      // x shear
      x1 = xSign * x + k1;

      // y shear
      y1 = ySign * y + splashRound(yShear * x1);

      // rotation
      if (rot) {
	x2 = y1;
	y2 = -x1;
      } else {
	x2 = x1;
	y2 = y1;
      }

      // compute the alpha value for (x,y) after the x and y scaling
      // operations
      n = yStep > 0 ? yStep : 1;
      m = xStep > 0 ? xStep : 1;
      p = pixBuf + xSrc;
      pixAcc = 0;
      for (i = 0; i < n; ++i) {
	for (j = 0; j < m; ++j) {
	  pixAcc += *p++;
	}
	p += w - m;
      }

      // blend fill color with background
      if (pixAcc != 0) {
	fg = state->fillPattern->getColor(tx + x2, ty + y2);
	if (pixAcc == n * m) {
	  pix = fg;
	} else {
	  getPixel(tx + x2, ty + y2, &bg);
	  alpha = (SplashCoord)pixAcc / (SplashCoord)(n * m);
	  switch (bitmap->mode) {
	  case splashModeMono1:
	    pix.mono1 = splashRound(alpha * fg.mono1 +
				    (1 - alpha) * bg.mono1);
	    break;
	  case splashModeMono8:
	    pix.mono8 = splashRound(alpha * fg.mono8 +
				    (1 - alpha) * bg.mono8);
	    break;
	  case splashModeRGB8:
	  case splashModeRGB8Packed:
	    pix.rgb8 = splashMakeRGB8(
			   splashRound(alpha * splashRGB8R(fg.rgb8) +
				       (1 - alpha) * splashRGB8R(bg.rgb8)),
			   splashRound(alpha * splashRGB8G(fg.rgb8) +
				       (1 - alpha) * splashRGB8G(bg.rgb8)),
			   splashRound(alpha * splashRGB8B(fg.rgb8) +
				       (1 - alpha) * splashRGB8B(bg.rgb8)));
	    break;
	  case splashModeBGR8Packed:
	    pix.bgr8 = splashMakeBGR8(
			   splashRound(alpha * splashBGR8R(fg.bgr8) +
				       (1 - alpha) * splashBGR8R(bg.bgr8)),
			   splashRound(alpha * splashBGR8G(fg.bgr8) +
				       (1 - alpha) * splashBGR8G(bg.bgr8)),
			   splashRound(alpha * splashBGR8B(fg.bgr8) +
				       (1 - alpha) * splashBGR8B(bg.bgr8)));
	    break;
	  }
	}
	drawPixel(tx + x2, ty + y2, &pix, clipRes2 == splashClipAllInside);
      }

      // x scale Bresenham
      xSrc += xStep;
    }
  }

  // free memory
  gfree(pixBuf);

  return splashOk;
}

SplashError Splash::drawImage(SplashImageSource src, void *srcData,
			      SplashColorMode srcMode,
			      int w, int h, SplashCoord *mat) {
  GBool ok, rot, halftone;
  SplashCoord xScale, yScale, xShear, yShear;
  int tx, ty, scaledWidth, scaledHeight, xSign, ySign;
  int ulx, uly, llx, lly, urx, ury, lrx, lry;
  int ulx1, uly1, llx1, lly1, urx1, ury1, lrx1, lry1;
  int xMin, xMax, yMin, yMax;
  SplashClipResult clipRes, clipRes2;
  int yp, yq, yt, yStep, lastYStep;
  int xp, xq, xt, xStep, xSrc;
  int k1, spanXMin, spanXMax, spanY;
  SplashColor *pixBuf, *p;
  Guchar *alphaBuf, *q;
  SplashColor pix;
  SplashCoord pixAcc[splashMaxColorComps];
  int alphaAcc;
  SplashCoord pixMul, alphaMul, alpha;
  int x, y, x1, y1, x2, y2;
  int n, m, i, j;

  if (debugMode) {
    printf("drawImage: srcMode=%d w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",
	   srcMode, w, h, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
  }

  // check color modes
  ok = gFalse; // make gcc happy
  switch (bitmap->mode) {
  case splashModeMono1:
    ok = srcMode == splashModeMono1 || srcMode == splashModeMono8;
    break;
  case splashModeMono8:
    ok = srcMode == splashModeMono8;
    break;
  case splashModeRGB8:
    ok = srcMode == splashModeRGB8;
    break;
  case splashModeRGB8Packed:
    ok = srcMode == splashModeRGB8Packed;
    break;
  case splashModeBGR8Packed:
    ok = srcMode == splashModeBGR8Packed;
    break;
  }
  if (!ok) {
    return splashErrModeMismatch;
  }
  halftone = bitmap->mode == splashModeMono1 && srcMode == splashModeMono8;

  // check for singular matrix
  if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.000001) {
    return splashErrSingularMatrix;
  }

  // compute scale, shear, rotation, translation parameters
  rot = splashAbs(mat[1]) > splashAbs(mat[0]);
  if (rot) {
    xScale = -mat[1];
    yScale = mat[2] - (mat[0] * mat[3]) / mat[1];
    xShear = -mat[3] / yScale;
    yShear = -mat[0] / mat[1];
  } else {
    xScale = mat[0];
    yScale = mat[3] - (mat[1] * mat[2]) / mat[0];
    xShear = mat[2] / yScale;
    yShear = mat[1] / mat[0];
  }
  tx = splashRound(mat[4]);
  ty = splashRound(mat[5]);
  scaledWidth = abs(splashRound(mat[4] + xScale) - tx) + 1;
  scaledHeight = abs(splashRound(mat[5] + yScale) - ty) + 1;
  xSign = (xScale < 0) ? -1 : 1;
  ySign = (yScale < 0) ? -1 : 1;

  // clipping
  ulx1 = 0;
  uly1 = 0;
  urx1 = xSign * (scaledWidth - 1);
  ury1 = splashRound(yShear * urx1);
  llx1 = splashRound(xShear * ySign * (scaledHeight - 1));
  lly1 = ySign * (scaledHeight - 1) + splashRound(yShear * llx1);
  lrx1 = xSign * (scaledWidth - 1) +
           splashRound(xShear * ySign * (scaledHeight - 1));
  lry1 = ySign * (scaledHeight - 1) + splashRound(yShear * lrx1);
  if (rot) {
    ulx = tx + uly1;    uly = ty - ulx1;
    urx = tx + ury1;    ury = ty - urx1;
    llx = tx + lly1;    lly = ty - llx1;
    lrx = tx + lry1;    lry = ty - lrx1;
  } else {
    ulx = tx + ulx1;    uly = ty + uly1;
    urx = tx + urx1;    ury = ty + ury1;
    llx = tx + llx1;    lly = ty + lly1;
    lrx = tx + lrx1;    lry = ty + lry1;
  }
  xMin = (ulx < urx) ? (ulx < llx) ? (ulx < lrx) ? ulx : lrx
                                   : (llx < lrx) ? llx : lrx
		     : (urx < llx) ? (urx < lrx) ? urx : lrx
                                   : (llx < lrx) ? llx : lrx;
  xMax = (ulx > urx) ? (ulx > llx) ? (ulx > lrx) ? ulx : lrx
                                   : (llx > lrx) ? llx : lrx
		     : (urx > llx) ? (urx > lrx) ? urx : lrx
                                   : (llx > lrx) ? llx : lrx;
  yMin = (uly < ury) ? (uly < lly) ? (uly < lry) ? uly : lry
                                   : (lly < lry) ? lly : lry
		     : (ury < lly) ? (ury < lry) ? ury : lry
                                   : (lly < lry) ? lly : lry;
  yMax = (uly > ury) ? (uly > lly) ? (uly > lry) ? uly : lry
                                   : (lly > lry) ? lly : lry
		     : (ury > lly) ? (ury > lry) ? ury : lry
                                   : (lly > lry) ? lly : lry;
  if ((clipRes = state->clip->testRect(xMin, yMin, xMax, yMax))
      == splashClipAllOutside) {
    return splashOk;
  }

  // compute Bresenham parameters for x and y scaling
  yp = h / scaledHeight;
  yq = h % scaledHeight;
  xp = w / scaledWidth;
  xq = w % scaledWidth;

  // allocate pixel buffer
  pixBuf = (SplashColor *)gmalloc((yp + 1) * w * sizeof(SplashColor));
  alphaBuf = (Guchar *)gmalloc((yp + 1) * w * sizeof(Guchar));

  // init y scale Bresenham
  yt = 0;
  lastYStep = 1;

  for (y = 0; y < scaledHeight; ++y) {

    // y scale Bresenham
    yStep = yp;
    yt += yq;
    if (yt >= scaledHeight) {
      yt -= scaledHeight;
      ++yStep;
    }

    // read row(s) from image
    n = (yp > 0) ? yStep : lastYStep;
    if (n > 0) {
      p = pixBuf;
      q = alphaBuf;
      for (i = 0; i < n; ++i) {
	for (j = 0; j < w; ++j) {
	  (*src)(srcData, p++, q++);
	}
      }
    }
    lastYStep = yStep;

    // loop-invariant constants
    k1 = splashRound(xShear * ySign * y);

    // clipping test
    if (clipRes != splashClipAllInside &&
	!rot &&
	splashRound(yShear * k1) ==
	  splashRound(yShear * (xSign * (scaledWidth - 1) + k1))) {
      if (xSign > 0) {
	spanXMin = tx + k1;
	spanXMax = spanXMin + (scaledWidth - 1);
      } else {
	spanXMax = tx + k1;
	spanXMin = spanXMax - (scaledWidth - 1);
      }
      spanY = ty + ySign * y + splashRound(xShear * ySign * y);
      clipRes2 = state->clip->testSpan(spanXMin, spanXMax, spanY);
      if (clipRes2 == splashClipAllOutside) {
	continue;
      }
    } else {
      clipRes2 = clipRes;
    }

    // init x scale Bresenham
    xt = 0;
    xSrc = 0;

    for (x = 0; x < scaledWidth; ++x) {

      // x scale Bresenham
      xStep = xp;
      xt += xq;
      if (xt >= scaledWidth) {
	xt -= scaledWidth;
	++xStep;
      }

      // x shear
      x1 = xSign * x + k1;

      // y shear
      y1 = ySign * y + splashRound(yShear * x1);

      // rotation
      if (rot) {
	x2 = y1;
	y2 = -x1;
      } else {
	x2 = x1;
	y2 = y1;
      }

      // compute the filtered pixel at (x,y) after the x and y scaling
      // operations
      n = yStep > 0 ? yStep : 1;
      m = xStep > 0 ? xStep : 1;
      p = pixBuf + xSrc;
      q = alphaBuf + xSrc;
      for (i = 0; i < splashMaxColorComps; ++i) {
	pixAcc[i] = 0;
      }
      alphaAcc = 0;
      for (i = 0; i < n; ++i) {
	for (j = 0; j < m; ++j) {
	  switch (srcMode) {
	  case splashModeMono1:
	    pixAcc[0] += p->mono1;
	    break;
	  case splashModeMono8:
	    pixAcc[0] += p->mono8;
	    break;
	  case splashModeRGB8:
	  case splashModeRGB8Packed:
	    pixAcc[0] += splashRGB8R(p->rgb8);
	    pixAcc[1] += splashRGB8G(p->rgb8);
	    pixAcc[2] += splashRGB8B(p->rgb8);
	    break;
	  case splashModeBGR8Packed:
	    pixAcc[0] += splashBGR8R(p->bgr8);
	    pixAcc[1] += splashBGR8G(p->bgr8);
	    pixAcc[2] += splashBGR8B(p->bgr8);
	    break;
	  }
	  ++p;
	  alphaAcc += *q++;
	}
	p += w - m;
	q += w - m;
      }
      alphaMul = 1 / (SplashCoord)(n * m);
      if (halftone) {
	pixMul = (SplashCoord)alphaMul / 256.0;
      } else {
	pixMul = alphaMul;
      }
      alpha = (SplashCoord)alphaAcc * alphaMul;

      //~ this should blend if 0 < alpha < 1
      if (alpha > 0.75) {

	// mono8 -> mono1 conversion, with halftoning
	if (halftone) {
	  pix.mono1 = state->screen->test(tx + x2, ty + y2,
					  pixAcc[0] * pixMul);

	// no conversion, no halftoning
	} else {
	  switch (bitmap->mode) {
	  case splashModeMono1:
	    pix.mono1 = splashRound(pixAcc[0] * pixMul);
	    break;
	  case splashModeMono8:
	    pix.mono8 = splashRound(pixAcc[0] * pixMul);
	    break;
	  case splashModeRGB8:
	  case splashModeRGB8Packed:
	    pix.rgb8 = splashMakeRGB8(splashRound(pixAcc[0] * pixMul),
				      splashRound(pixAcc[1] * pixMul),
				      splashRound(pixAcc[2] * pixMul));
	    break;
	  case splashModeBGR8Packed:
	    pix.bgr8 = splashMakeBGR8(splashRound(pixAcc[0] * pixMul),
				      splashRound(pixAcc[1] * pixMul),
				      splashRound(pixAcc[2] * pixMul));
	    break;
	  }
	}

	// set pixel
	drawPixel(tx + x2, ty + y2, &pix, clipRes2 == splashClipAllInside);
      }

      // x scale Bresenham
      xSrc += xStep;
    }
  }

  gfree(pixBuf);
  gfree(alphaBuf);

  return splashOk;
}

void Splash::dumpPath(SplashPath *path) {
  int i;

  for (i = 0; i < path->length; ++i) {
    printf("  %3d: x=%8.2f y=%8.2f%s%s%s%s%s\n",
	   i, path->pts[i].x, path->pts[i].y,
	   (path->flags[i] & splashPathFirst) ? " first" : "",
	   (path->flags[i] & splashPathLast) ? " last" : "",
	   (path->flags[i] & splashPathClosed) ? " closed" : "",
	   (path->flags[i] & splashPathCurve) ? " curve" : "",
	   (path->flags[i] & splashPathArcCW) ? " arcCW" : "");
  }
}
