//========================================================================
//
// SplashClip.h
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2010, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef SPLASHCLIP_H
#define SPLASHCLIP_H

#include "SplashTypes.h"
#include "SplashMath.h"
#include "SplashXPathScanner.h"

class SplashPath;
class SplashXPath;
class SplashBitmap;

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

enum SplashClipResult {
  splashClipAllInside,
  splashClipAllOutside,
  splashClipPartial
};

//------------------------------------------------------------------------
// SplashClip
//------------------------------------------------------------------------

class SplashClip {
public:

  // Create a clip, for the given rectangle.
  SplashClip(SplashCoord x0, SplashCoord y0,
	     SplashCoord x1, SplashCoord y1,
	     GBool antialiasA);

  // Copy a clip.
  SplashClip *copy() { return new SplashClip(this); }

  ~SplashClip();

  SplashClip(const SplashClip &) = delete;
  SplashClip& operator=(const SplashClip &) = delete;

  // Reset the clip to a rectangle.
  void resetToRect(SplashCoord x0, SplashCoord y0,
		   SplashCoord x1, SplashCoord y1);

  // Intersect the clip with a rectangle.
  SplashError clipToRect(SplashCoord x0, SplashCoord y0,
			 SplashCoord x1, SplashCoord y1);

  // Interesect the clip with <path>.
  SplashError clipToPath(SplashPath *path, SplashCoord *matrix,
			 SplashCoord flatness, GBool eo);

  // Returns true if (<x>,<y>) is inside the clip.
  GBool test(int x, int y)
  {
    int i;

    // check the rectangle
    if (x < xMinI || x > xMaxI || y < yMinI || y > yMaxI) {
      return gFalse;
    }

    // check the paths
    if (antialias) {
      for (i = 0; i < length; ++i) {
        if (!scanners[i]->test(x * splashAASize, y * splashAASize)) {
	  return gFalse;
        }
      }
    } else {
      for (i = 0; i < length; ++i) {
        if (!scanners[i]->test(x, y)) {
	  return gFalse;
        }
      }
    }

    return gTrue;
  }

  // Tests a rectangle against the clipping region.  Returns one of:
  //   - splashClipAllInside if the entire rectangle is inside the
  //     clipping region, i.e., all pixels in the rectangle are
  //     visible
  //   - splashClipAllOutside if the entire rectangle is outside the
  //     clipping region, i.e., all the pixels in the rectangle are
  //     clipped
  //   - splashClipPartial if the rectangle is part inside and part
  //     outside the clipping region
  SplashClipResult testRect(int rectXMin, int rectYMin,
			    int rectXMax, int rectYMax);

  // Similar to testRect, but tests a horizontal span.
  SplashClipResult testSpan(int spanXMin, int spanXMax, int spanY);

  // Clips an anti-aliased line by setting pixels to zero.  On entry,
  // all non-zero pixels are between <x0> and <x1>.  This function
  // will update <x0> and <x1>.
  void clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y,
    GBool adjustVertLine = gFalse);

  // Get the rectangle part of the clip region.
  SplashCoord getXMin() { return xMin; }
  SplashCoord getXMax() { return xMax; }
  SplashCoord getYMin() { return yMin; }
  SplashCoord getYMax() { return yMax; }

  // Get the rectangle part of the clip region, in integer coordinates.
  int getXMinI() { return xMinI; }
  int getXMaxI() { return xMaxI; }
  int getYMinI() { return yMinI; }
  int getYMaxI() { return yMaxI; }

  // Get the number of arbitrary paths used by the clip region.
  int getNumPaths() { return length; }

protected:

  SplashClip(SplashClip *clip);
  void grow(int nPaths);

  GBool antialias;
  SplashCoord xMin, yMin, xMax, yMax;
  int xMinI, yMinI, xMaxI, yMaxI;
  SplashXPath **paths;
  Guchar *flags;
  SplashXPathScanner **scanners;
  int length, size;
};

#endif
