blob: 88b9d8c9d300a3ce3e05e856272df345aadf578b [file] [log] [blame]
//========================================================================
//
// SplashXPathScanner.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) 2013, 2014 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2018 Stefan BrĂ¼ns <stefan.bruens@rwth-aachen.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 SPLASHXPATHSCANNER_H
#define SPLASHXPATHSCANNER_H
#include "SplashTypes.h"
#include <poppler-config.h>
#ifdef USE_BOOST_HEADERS
#include <boost/container/small_vector.hpp>
#endif
#include <vector>
class SplashXPath;
class SplashBitmap;
struct SplashIntersect {
int y;
int x0, x1; // intersection of segment with [y, y+1)
int count; // EO/NZWN counter increment
};
//------------------------------------------------------------------------
// SplashXPathScanner
//------------------------------------------------------------------------
class SplashXPathScanner {
public:
// Create a new SplashXPathScanner object. <xPathA> must be sorted.
SplashXPathScanner(SplashXPath *xPathA, bool eoA,
int clipYMin, int clipYMax);
~SplashXPathScanner();
SplashXPathScanner(const SplashXPathScanner&) = delete;
SplashXPathScanner& operator=(const SplashXPathScanner&) = delete;
// Return the path's bounding box.
void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA)
{ *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
// Return the path's bounding box.
void getBBoxAA(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA);
// Returns true if at least part of the path was outside the
// clipYMin/clipYMax bounds passed to the constructor.
bool hasPartialClip() { return partialClip; }
// Return the min/max x values for the span at <y>.
void getSpanBounds(int y, int *spanXMin, int *spanXMax);
// Returns true if (<x>,<y>) is inside the path.
bool test(int x, int y);
// Returns true if the entire span ([<x0>,<x1>], <y>) is inside the
// path.
bool testSpan(int x0, int x1, int y);
// Renders one anti-aliased line into <aaBuf>. Returns the min and
// max x coordinates with non-zero pixels in <x0> and <x1>.
void renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y,
bool adjustVertLine = false);
// 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);
private:
void computeIntersections();
bool addIntersection(double segYMin, double segYMax,
int y, int x0, int x1, int count);
SplashXPath *xPath;
bool eo;
int xMin, yMin, xMax, yMax;
bool partialClip;
#ifdef USE_BOOST_HEADERS
typedef boost::container::small_vector<SplashIntersect, 4> IntersectionLine;
#else
typedef std::vector<SplashIntersect> IntersectionLine;
#endif
std::vector<IntersectionLine> allIntersections;
friend class SplashXPathScanIterator;
};
class SplashXPathScanIterator {
public:
SplashXPathScanIterator(const SplashXPathScanner &scanner, int y);
// Returns the next span inside the path at the current y position
// Returns false if there are no more spans.
bool getNextSpan(int *x0, int *x1);
private:
#ifdef USE_BOOST_HEADERS
typedef boost::container::small_vector<SplashIntersect, 4> IntersectionLine;
#else
typedef std::vector<SplashIntersect> IntersectionLine;
#endif
const IntersectionLine &line;
size_t interIdx; // current index into <line>
int interCount; // current EO/NZWN counter
const bool eo;
};
#endif