//========================================================================
//
// 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 (xPath->segs == NULL)
  {
    delete xPath;
    return splashErrEmptyPath;
  }
  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();
  if (xPath->segs == NULL)
  {
    delete xPath;
    return splashErrEmptyPath;
  }
  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 ( (unsigned) x >= (unsigned) bitmap->getWidth() ||
       (unsigned) y >= (unsigned) bitmap->getHeight())
      return;

  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 ( (unsigned) x >= (unsigned) bitmap->getWidth() ||
       (unsigned) y >= (unsigned) bitmap->getHeight())
    return;

  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;

  if ((unsigned) x0 >= (unsigned) bitmap->getWidth() ||
      (unsigned) x1 >= (unsigned) bitmap->getWidth() ||
      (unsigned) y >= (unsigned) bitmap->getHeight())
      return;

  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;

  if ((unsigned) x0 >= (unsigned) bitmap->getWidth() ||
      (unsigned) x1 >= (unsigned) bitmap->getWidth() ||
      (unsigned) y >= (unsigned) bitmap->getHeight())
    return;

  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" : "");
  }
}
