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. getBBox(int * xMinA,int * yMinA,int * xMaxA,int * yMaxA)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. hasPartialClip()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