Coverage Report

Created: 2026-03-31 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/painting/qvectorpath_p.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#ifndef QVECTORPATH_P_H
6
#define QVECTORPATH_P_H
7
8
//
9
//  W A R N I N G
10
//  -------------
11
//
12
// This file is not part of the Qt API.  It exists purely as an
13
// implementation detail.  This header file may change from version to
14
// version without notice, or even be removed.
15
//
16
// We mean it.
17
//
18
19
#include <QtGui/private/qtguiglobal_p.h>
20
#include <QtGui/qpaintengine.h>
21
22
#include <private/qpaintengine_p.h>
23
#include <private/qstroker_p.h>
24
#include <private/qpainter_p.h>
25
26
27
QT_BEGIN_NAMESPACE
28
29
30
class QPaintEngineEx;
31
32
typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data);
33
34
struct QRealRect {
35
    qreal x1, y1, x2, y2;
36
};
37
38
class Q_GUI_EXPORT QVectorPath
39
{
40
public:
41
    enum Hint {
42
        // Shape hints, in 0x000000ff, access using shape()
43
        AreaShapeMask           = 0x0001,       // shape covers an area
44
        NonConvexShapeMask      = 0x0002,       // shape is not convex
45
        CurvedShapeMask         = 0x0004,       // shape contains curves...
46
        LinesShapeMask          = 0x0008,
47
        RectangleShapeMask      = 0x0010,
48
        ShapeMask               = 0x001f,
49
50
        // Shape hints merged into basic shapes..
51
        LinesHint               = LinesShapeMask,
52
        RectangleHint           = AreaShapeMask | RectangleShapeMask,
53
        EllipseHint             = AreaShapeMask | CurvedShapeMask,
54
        ConvexPolygonHint       = AreaShapeMask,
55
        PolygonHint             = AreaShapeMask | NonConvexShapeMask,
56
        RoundedRectHint         = AreaShapeMask | CurvedShapeMask,
57
        ArbitraryShapeHint      = AreaShapeMask | NonConvexShapeMask | CurvedShapeMask,
58
59
        // Other hints
60
        IsCachedHint            = 0x0100, // Set if the cache hint is set
61
        ShouldUseCacheHint      = 0x0200, // Set if the path should be cached when possible..
62
        ControlPointRect        = 0x0400, // Set if the control point rect has been calculated...
63
64
        // Shape rendering specifiers...
65
        OddEvenFill             = 0x1000,
66
        WindingFill             = 0x2000,
67
        ImplicitClose           = 0x4000,
68
        ExplicitOpen            = 0x8000
69
    };
70
71
    // ### Falcon: introduca a struct XY for points so lars is not so confused...
72
    QVectorPath(const qreal *points,
73
                int count,
74
                const QPainterPath::ElementType *elements = nullptr,
75
                uint hints = ArbitraryShapeHint)
76
12.3k
        : m_elements(elements),
77
12.3k
          m_points(points),
78
12.3k
          m_count(count),
79
12.3k
          m_hints(hints)
80
12.3k
    {
81
12.3k
    }
82
83
    ~QVectorPath();
84
85
    QRectF controlPointRect() const;
86
87
0
    inline Hint shape() const { return (Hint) (m_hints & ShapeMask); }
88
0
    inline bool isConvex() const { return (m_hints & NonConvexShapeMask) == 0; }
89
0
    inline bool isCurved() const { return m_hints & CurvedShapeMask; }
90
91
0
    inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; }
92
24.7k
    inline bool hasImplicitClose() const { return m_hints & ImplicitClose; }
93
0
    inline bool hasExplicitOpen() const { return m_hints & ExplicitOpen; }
94
0
    inline bool hasWindingFill() const { return m_hints & WindingFill; }
95
96
0
    inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = nullptr; }
97
0
    inline uint hints() const { return m_hints; }
98
99
12.3k
    inline const QPainterPath::ElementType *elements() const { return m_elements; }
100
12.3k
    inline const qreal *points() const { return m_points; }
101
12.3k
    inline bool isEmpty() const { return m_points == nullptr; }
102
103
12.3k
    inline int elementCount() const { return m_count; }
104
    inline const QPainterPath convertToPainterPath() const;
105
106
    static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode)
107
0
    {
108
0
        switch (mode) {
109
0
        case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose;
110
0
        case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose;
111
0
        case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose;
112
0
        case QPaintEngine::PolylineMode: return PolygonHint | ExplicitOpen;
113
0
        default: return 0;
114
0
        }
115
0
    }
116
117
    struct CacheEntry {
118
        QPaintEngineEx *engine;
119
        void *data;
120
        qvectorpath_cache_cleanup cleanup;
121
        CacheEntry *next;
122
    };
123
124
    CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup) const;
125
0
    inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const {
126
0
        Q_ASSERT(m_hints & ShouldUseCacheHint);
127
0
        CacheEntry *e = m_cache;
128
0
        while (e) {
129
0
            if (e->engine == engine)
130
0
                return e;
131
0
            e = e->next;
132
0
        }
133
0
        return nullptr;
134
0
    }
135
136
0
    template <typename T> static inline bool isRect(const T *pts, int elementCount) {
137
0
        return (elementCount == 5 // 5-point polygon, check for closed rect
138
0
                && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
139
0
                && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
140
0
                && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
141
0
                && pts[0] < pts[4] && pts[1] < pts[5]
142
0
                ) ||
143
0
               (elementCount == 4 // 4-point polygon, check for unclosed rect
144
0
                && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
145
0
                && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
146
0
                && pts[0] < pts[4] && pts[1] < pts[5]
147
0
                );
148
0
    }
Unexecuted instantiation: bool QVectorPath::isRect<double>(double const*, int)
Unexecuted instantiation: bool QVectorPath::isRect<int>(int const*, int)
149
150
    inline bool isRect() const
151
0
    {
152
0
        const QPainterPath::ElementType * const types = elements();
153
154
0
        return (shape() == QVectorPath::RectangleHint)
155
0
                || (isRect(points(), elementCount())
156
0
                    && (!types || (types[0] == QPainterPath::MoveToElement
157
0
                                   && types[1] == QPainterPath::LineToElement
158
0
                                   && types[2] == QPainterPath::LineToElement
159
0
                                   && types[3] == QPainterPath::LineToElement)));
160
0
    }
161
162
163
private:
164
    Q_DISABLE_COPY_MOVE(QVectorPath)
165
166
    const QPainterPath::ElementType *m_elements;
167
    const qreal *m_points;
168
    const int m_count;
169
170
    mutable uint m_hints;
171
    mutable QRealRect m_cp_rect;
172
173
    mutable CacheEntry *m_cache;
174
};
175
176
Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path);
177
178
QT_END_NAMESPACE
179
180
#endif