summaryrefslogtreecommitdiff
path: root/splash/SplashXPathScanner.h
blob: 88b9d8c9d300a3ce3e05e856272df345aadf578b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//========================================================================
//
// 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