1 | //======================================================================== |
2 | // |
3 | // SplashXPathScanner.h |
4 | // |
5 | //======================================================================== |
6 | |
7 | //======================================================================== |
8 | // |
9 | // Modified under the Poppler project - http://poppler.freedesktop.org |
10 | // |
11 | // All changes made under the Poppler project to this file are licensed |
12 | // under GPL version 2 or later |
13 | // |
14 | // Copyright (C) 2013, 2014, 2021 Thomas Freitag <Thomas.Freitag@alfa.de> |
15 | // Copyright (C) 2018, 2021 Albert Astals Cid <aacid@kde.org> |
16 | // Copyright (C) 2018 Stefan BrĂ¼ns <stefan.bruens@rwth-aachen.de> |
17 | // |
18 | // To see a description of the changes please see the Changelog file that |
19 | // came with your tarball or type make ChangeLog if you are building from git |
20 | // |
21 | //======================================================================== |
22 | |
23 | #ifndef SPLASHXPATHSCANNER_H |
24 | #define SPLASHXPATHSCANNER_H |
25 | |
26 | #include "SplashTypes.h" |
27 | |
28 | #include <poppler-config.h> |
29 | |
30 | #ifdef USE_BOOST_HEADERS |
31 | # include <boost/container/small_vector.hpp> |
32 | #endif |
33 | |
34 | #include <vector> |
35 | |
36 | class SplashXPath; |
37 | class SplashBitmap; |
38 | |
39 | struct SplashIntersect |
40 | { |
41 | int y; |
42 | int x0, x1; // intersection of segment with [y, y+1) |
43 | int count; // EO/NZWN counter increment |
44 | }; |
45 | |
46 | //------------------------------------------------------------------------ |
47 | // SplashXPathScanner |
48 | //------------------------------------------------------------------------ |
49 | |
50 | class SplashXPathScanner |
51 | { |
52 | public: |
53 | // Create a new SplashXPathScanner object. <xPathA> must be sorted. |
54 | SplashXPathScanner(const SplashXPath &xPath, bool eoA, int clipYMin, int clipYMax); |
55 | |
56 | ~SplashXPathScanner(); |
57 | |
58 | SplashXPathScanner(const SplashXPathScanner &) = delete; |
59 | SplashXPathScanner &operator=(const SplashXPathScanner &) = delete; |
60 | |
61 | // Return the path's bounding box. |
62 | void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) const |
63 | { |
64 | *xMinA = xMin; |
65 | *yMinA = yMin; |
66 | *xMaxA = xMax; |
67 | *yMaxA = yMax; |
68 | } |
69 | |
70 | // Return the path's bounding box. |
71 | void getBBoxAA(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) const; |
72 | |
73 | // Returns true if at least part of the path was outside the |
74 | // clipYMin/clipYMax bounds passed to the constructor. |
75 | bool hasPartialClip() const { return partialClip; } |
76 | |
77 | // Return the min/max x values for the span at <y>. |
78 | void getSpanBounds(int y, int *spanXMin, int *spanXMax) const; |
79 | |
80 | // Returns true if (<x>,<y>) is inside the path. |
81 | bool test(int x, int y) const; |
82 | |
83 | // Returns true if the entire span ([<x0>,<x1>], <y>) is inside the |
84 | // path. |
85 | bool testSpan(int x0, int x1, int y) const; |
86 | |
87 | // Renders one anti-aliased line into <aaBuf>. Returns the min and |
88 | // max x coordinates with non-zero pixels in <x0> and <x1>. |
89 | void renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y, bool adjustVertLine = false) const; |
90 | |
91 | // Clips an anti-aliased line by setting pixels to zero. On entry, |
92 | // all non-zero pixels are between <x0> and <x1>. This function |
93 | // will update <x0> and <x1>. |
94 | void clipAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y) const; |
95 | |
96 | private: |
97 | void computeIntersections(const SplashXPath &xPath); |
98 | bool addIntersection(double segYMin, double segYMax, int y, int x0, int x1, int count); |
99 | |
100 | bool eo; |
101 | int xMin, yMin, xMax, yMax; |
102 | bool partialClip; |
103 | |
104 | #ifdef USE_BOOST_HEADERS |
105 | typedef boost::container::small_vector<SplashIntersect, 4> IntersectionLine; |
106 | #else |
107 | typedef std::vector<SplashIntersect> IntersectionLine; |
108 | #endif |
109 | std::vector<IntersectionLine> allIntersections; |
110 | |
111 | friend class SplashXPathScanIterator; |
112 | }; |
113 | |
114 | class SplashXPathScanIterator |
115 | { |
116 | public: |
117 | SplashXPathScanIterator(const SplashXPathScanner &scanner, int y); |
118 | |
119 | // Returns the next span inside the path at the current y position |
120 | // Returns false if there are no more spans. |
121 | bool getNextSpan(int *x0, int *x1); |
122 | |
123 | private: |
124 | #ifdef USE_BOOST_HEADERS |
125 | typedef boost::container::small_vector<SplashIntersect, 4> IntersectionLine; |
126 | #else |
127 | typedef std::vector<SplashIntersect> IntersectionLine; |
128 | #endif |
129 | const IntersectionLine &line; |
130 | |
131 | size_t interIdx; // current index into <line> |
132 | int interCount; // current EO/NZWN counter |
133 | const bool eo; |
134 | }; |
135 | |
136 | #endif |
137 | |