Coverage Report

Created: 2026-03-31 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/splash/SplashXPathScanner.h
Line
Count
Source
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, 2025 Albert Astals Cid <aacid@kde.org>
16
// Copyright (C) 2018, 2025 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 <poppler-config.h>
27
28
#if USE_BOOST_HEADERS
29
#    include <boost/container/small_vector.hpp>
30
#endif
31
32
#include <vector>
33
34
class SplashXPath;
35
class SplashBitmap;
36
37
struct SplashIntersect
38
{
39
    int x0, x1; // intersection of segment with [y, y+1)
40
    int count; // EO/NZWN counter increment
41
};
42
43
//------------------------------------------------------------------------
44
// SplashXPathScanner
45
//------------------------------------------------------------------------
46
47
class SplashXPathScanner
48
{
49
public:
50
    // Create a new SplashXPathScanner object.  <xPathA> must be sorted.
51
    SplashXPathScanner(const SplashXPath &xPath, bool eoA, int clipYMin, int clipYMax);
52
53
    ~SplashXPathScanner();
54
55
    SplashXPathScanner(const SplashXPathScanner &) = delete;
56
    SplashXPathScanner &operator=(const SplashXPathScanner &) = delete;
57
58
    // Return the path's bounding box.
59
    void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) const
60
11.5M
    {
61
11.5M
        *xMinA = xMin;
62
11.5M
        *yMinA = yMin;
63
11.5M
        *xMaxA = xMax;
64
11.5M
        *yMaxA = yMax;
65
11.5M
    }
66
67
    // Return the path's bounding box.
68
    void getBBoxAA(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) const;
69
70
    // Returns true if (<x>,<y>) is inside the path.
71
    bool test(int x, int y) const;
72
73
    // Returns true if the entire span ([<x0>,<x1>], <y>) is inside the
74
    // path.
75
    bool testSpan(int x0, int x1, int y) const;
76
77
    // Renders one anti-aliased line into <aaBuf>.  Returns the min and
78
    // max x coordinates with non-zero pixels in <x0> and <x1>.
79
    void renderAALine(SplashBitmap *aaBuf, int *x0, int *x1, int y, bool adjustVertLine = false) const;
80
81
    // Clips an anti-aliased line by setting pixels to zero.  On entry,
82
    // all non-zero pixels are between <x0> and <x1>.  This function
83
    // will update <x0> and <x1>.
84
    void clipAALine(SplashBitmap *aaBuf, const int *x0, const int *x1, int y) const;
85
86
private:
87
    void computeIntersections(const SplashXPath &xPath);
88
    void addIntersection(double segYMin, int y, int x0, int x1, int count);
89
90
    const bool eo;
91
    int xMin = 1, yMin = 1, xMax = 0, yMax = 0;
92
93
#if USE_BOOST_HEADERS
94
    using IntersectionLine = boost::container::small_vector<SplashIntersect, 4>;
95
#else
96
    using IntersectionLine = std::vector<SplashIntersect>;
97
#endif
98
    std::vector<IntersectionLine> allIntersections;
99
100
    friend class SplashXPathScanIterator;
101
};
102
103
class SplashXPathScanIterator
104
{
105
public:
106
    SplashXPathScanIterator(const SplashXPathScanner &scanner, int y);
107
108
    // Returns the next span inside the path at the current y position
109
    // Returns false if there are no more spans.
110
    bool getNextSpan(int *x0, int *x1);
111
112
private:
113
#if USE_BOOST_HEADERS
114
    using IntersectionLine = boost::container::small_vector<SplashIntersect, 4>;
115
#else
116
    using IntersectionLine = std::vector<SplashIntersect>;
117
#endif
118
    const IntersectionLine &line;
119
120
    size_t interIdx = 0; // current index into <line>
121
    int interCount = 0; // current EO/NZWN counter
122
    const bool eo;
123
};
124
125
#endif