Coverage Report

Created: 2025-11-16 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qt/qtbase/src/gui/painting/qoutlinemapper_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
4
#ifndef QOUTLINEMAPPER_P_H
5
#define QOUTLINEMAPPER_P_H
6
7
//
8
//  W A R N I N G
9
//  -------------
10
//
11
// This file is not part of the Qt API.  It exists purely as an
12
// implementation detail.  This header file may change from version to
13
// version without notice, or even be removed.
14
//
15
// We mean it.
16
//
17
18
#include <QtGui/private/qtguiglobal_p.h>
19
#include <QtCore/qrect.h>
20
21
#include <QtGui/qtransform.h>
22
#include <QtGui/qpainterpath.h>
23
24
#define QT_FT_BEGIN_HEADER
25
#define QT_FT_END_HEADER
26
27
#include <private/qrasterdefs_p.h>
28
#include <private/qdatabuffer_p.h>
29
#include "qpaintengineex_p.h"
30
31
QT_BEGIN_NAMESPACE
32
33
// These limitations comes from qrasterizer.cpp, qcosmeticstroker.cpp, and qgrayraster.c.
34
// Any higher and rasterization of shapes will produce incorrect results.
35
#if Q_PROCESSOR_WORDSIZE == 8
36
constexpr int QT_RASTER_COORD_LIMIT = ((1<<23) - 1); // F24dot8 in qgrayraster.c
37
#else
38
constexpr int QT_RASTER_COORD_LIMIT = ((1<<15) - 1); // F16dot16 in qrasterizer.cpp and qcosmeticstroker.cpp
39
#endif
40
//#define QT_DEBUG_CONVERT
41
42
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
43
44
/********************************************************************************
45
 * class QOutlineMapper
46
 *
47
 * Used to map between QPainterPath and the QT_FT_Outline structure used by the
48
 * freetype scanconverter.
49
 *
50
 * The outline mapper uses a path iterator to get points from the path,
51
 * so that it is possible to transform the points as they are converted. The
52
 * callback can be a noop, translate or full-fledged xform. (Tests indicated
53
 * that using a C callback was low cost).
54
 */
55
class QOutlineMapper
56
{
57
public:
58
    QOutlineMapper() :
59
90.7k
        m_element_types(0),
60
90.7k
        m_elements(0),
61
90.7k
        m_points(0),
62
90.7k
        m_tags(0),
63
90.7k
        m_contours(0),
64
90.7k
        m_in_clip_elements(false)
65
90.7k
    {
66
90.7k
    }
67
68
    /*!
69
      Sets up the matrix to be used for conversion. This also
70
      sets up the qt_path_iterator function that is used as a callback
71
      to get points.
72
    */
73
    void setMatrix(const QTransform &m)
74
311k
    {
75
311k
        m_transform = m;
76
77
311k
        qreal scale;
78
311k
        qt_scaleForTransform(m, &scale);
79
311k
        m_curve_threshold = scale == 0 ? qreal(0.25) : (qreal(0.25) / scale);
80
311k
    }
81
82
    void setClipRect(QRect clipRect);
83
84
    void beginOutline(Qt::FillRule fillRule)
85
173k
    {
86
#ifdef QT_DEBUG_CONVERT
87
        printf("QOutlineMapper::beginOutline rule=%d\n", fillRule);
88
#endif
89
173k
        m_valid = true;
90
173k
        m_elements.reset();
91
173k
        m_element_types.reset();
92
173k
        m_points.reset();
93
173k
        m_tags.reset();
94
173k
        m_contours.reset();
95
173k
        m_outline.flags = fillRule == Qt::WindingFill
96
173k
                          ? QT_FT_OUTLINE_NONE
97
173k
                          : QT_FT_OUTLINE_EVEN_ODD_FILL;
98
173k
        m_subpath_start = 0;
99
173k
    }
100
101
    void endOutline();
102
103
    void clipElements(const QPointF *points, const QPainterPath::ElementType *types, int count);
104
105
    void convertElements(const QPointF *points, const QPainterPath::ElementType *types, int count);
106
107
3.71M
    inline void moveTo(const QPointF &pt) {
108
#ifdef QT_DEBUG_CONVERT
109
        printf("QOutlineMapper::moveTo() (%f, %f)\n", pt.x(), pt.y());
110
#endif
111
3.71M
        closeSubpath();
112
3.71M
        m_subpath_start = m_elements.size();
113
3.71M
        m_elements << pt;
114
3.71M
        m_element_types << QPainterPath::MoveToElement;
115
3.71M
    }
116
117
24.8M
    inline void lineTo(const QPointF &pt) {
118
#ifdef QT_DEBUG_CONVERT
119
        printf("QOutlineMapper::lineTo() (%f, %f)\n", pt.x(), pt.y());
120
#endif
121
24.8M
        m_elements.add(pt);
122
24.8M
        m_element_types << QPainterPath::LineToElement;
123
24.8M
    }
124
125
    void curveTo(const QPointF &cp1, const QPointF &cp2, const QPointF &ep);
126
127
3.88M
    inline void closeSubpath() {
128
3.88M
        int element_count = m_elements.size();
129
3.88M
        if (element_count > 0) {
130
3.80M
            if (m_elements.at(element_count-1) != m_elements.at(m_subpath_start)) {
131
#ifdef QT_DEBUG_CONVERT
132
                printf(" - implicitly closing\n");
133
#endif
134
                // Put the object on the stack to avoid the odd case where
135
                // lineTo reallocs the databuffer and the QPointF & will
136
                // be invalidated.
137
112k
                QPointF pt = m_elements.at(m_subpath_start);
138
139
                // only do lineTo if we have element_type array...
140
112k
                if (m_element_types.size())
141
31.9k
                    lineTo(pt);
142
80.5k
                else
143
80.5k
                    m_elements << pt;
144
145
112k
            }
146
3.80M
        }
147
3.88M
    }
148
149
173k
    QT_FT_Outline *outline() {
150
173k
        if (m_valid)
151
114k
            return &m_outline;
152
58.1k
        return nullptr;
153
173k
    }
154
155
    QT_FT_Outline *convertPath(const QPainterPath &path);
156
    QT_FT_Outline *convertPath(const QVectorPath &path);
157
158
173k
    inline QPainterPath::ElementType *elementTypes() const { return m_element_types.size() == 0 ? nullptr : m_element_types.data(); }
159
160
public:
161
    QDataBuffer<QPainterPath::ElementType> m_element_types;
162
    QDataBuffer<QPointF> m_elements;
163
    QDataBuffer<QT_FT_Vector> m_points;
164
    QDataBuffer<char> m_tags;
165
    QDataBuffer<int> m_contours;
166
167
    QRect m_clip_rect;
168
    QRectF m_clip_trigger_rect;
169
    QRectF controlPointRect; // only valid after endOutline()
170
171
    QT_FT_Outline m_outline;
172
173
    int m_subpath_start;
174
175
    QTransform m_transform;
176
177
    qreal m_curve_threshold;
178
179
    bool m_valid;
180
    bool m_in_clip_elements;
181
};
182
183
QT_END_NAMESPACE
184
185
#endif // QOUTLINEMAPPER_P_H