1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#ifndef PATHCOMPARE_H
29#define PATHCOMPARE_H
30
31#include <qmath.h>
32
33namespace QPathCompare {
34
35static const int precision = 8;
36static const qreal epsilon = qPow(x: 0.1, y: precision);
37
38static inline bool fuzzyIsZero(qreal x, qreal relative)
39{
40 if (qAbs(t: relative) < epsilon)
41 return qAbs(t: x) < epsilon;
42 else
43 return qAbs(t: x / relative) < epsilon;
44}
45
46static bool fuzzyCompare(const QPointF &a, const QPointF &b)
47{
48 const QPointF delta = a - b;
49
50 const qreal x = qMax(a: qAbs(t: a.x()), b: qAbs(t: b.x()));
51 const qreal y = qMax(a: qAbs(t: a.y()), b: qAbs(t: b.y()));
52
53 return fuzzyIsZero(x: delta.x(), relative: x) && fuzzyIsZero(x: delta.y(), relative: y);
54}
55
56static bool isClosed(const QPainterPath &path)
57{
58 if (path.elementCount() == 0)
59 return false;
60
61 QPointF first = path.elementAt(i: 0);
62 QPointF last = path.elementAt(i: path.elementCount() - 1);
63
64 return fuzzyCompare(a: first, b: last);
65}
66
67// rotation and direction independent path comparison
68// allows paths to be shifted or reversed relative to each other
69static bool comparePaths(const QPainterPath &actual, const QPainterPath &expected)
70{
71 const int endActual = isClosed(path: actual) ? actual.elementCount() - 1 : actual.elementCount();
72 const int endExpected = isClosed(path: expected) ? expected.elementCount() - 1 : expected.elementCount();
73
74 if (endActual != endExpected)
75 return false;
76
77 for (int i = 0; i < endActual; ++i) {
78 int k = 0;
79 for (k = 0; k < endActual; ++k) {
80 int i1 = k;
81 int i2 = (i + k) % endActual;
82
83 QPointF a = actual.elementAt(i: i1);
84 QPointF b = expected.elementAt(i: i2);
85
86 if (!fuzzyCompare(a, b))
87 break;
88 }
89
90 if (k == endActual)
91 return true;
92
93 for (k = 0; k < endActual; ++k) {
94 int i1 = k;
95 int i2 = (i + endActual - k) % endActual;
96
97 QPointF a = actual.elementAt(i: i1);
98 QPointF b = expected.elementAt(i: i2);
99
100 if (!fuzzyCompare(a, b))
101 break;
102 }
103
104 if (k == endActual)
105 return true;
106 }
107
108 return false;
109}
110
111}
112
113#endif
114

source code of qtbase/tests/auto/gui/painting/qpathclipper/pathcompare.h