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 QFIXED_P_H
5#define QFIXED_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 for the convenience
12// of other Qt classes. 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/qdebug.h"
20#include "QtCore/qpoint.h"
21#include "QtCore/qnumeric.h"
22#include "QtCore/qsize.h"
23
24QT_BEGIN_NAMESPACE
25
26struct QFixed {
27private:
28 constexpr QFixed(int val, int) : val(val) {} // 2nd int is just a dummy for disambiguation
29public:
30 constexpr QFixed() : val(0) {}
31 constexpr QFixed(int i) : val(i * 64) {}
32 constexpr QFixed(long i) : val(i * 64) {}
33 constexpr QFixed(long long i) : val(i * 64) {}
34
35 constexpr static QFixed fromReal(qreal r) { return fromFixed(fixed: (int)(r*qreal(64))); }
36 constexpr static QFixed fromFixed(int fixed) { return QFixed(fixed,0); } // uses private ctor
37
38 constexpr inline int value() const { return val; }
39 inline void setValue(int value) { val = value; }
40
41 constexpr inline int toInt() const { return (((val)+32) & -64)>>6; }
42 constexpr inline qreal toReal() const { return ((qreal)val)/(qreal)64; }
43
44 constexpr inline int truncate() const { return val>>6; }
45 constexpr inline QFixed round() const { return fromFixed(fixed: ((val)+32) & -64); }
46 constexpr inline QFixed floor() const { return fromFixed(fixed: (val) & -64); }
47 constexpr inline QFixed ceil() const { return fromFixed(fixed: (val+63) & -64); }
48
49 constexpr inline QFixed operator+(int i) const { return fromFixed(fixed: val + i * 64); }
50 constexpr inline QFixed operator+(uint i) const { return fromFixed(fixed: (val + (i<<6))); }
51 constexpr inline QFixed operator+(QFixed other) const { return fromFixed(fixed: (val + other.val)); }
52 inline QFixed &operator+=(int i) { val += i * 64; return *this; }
53 inline QFixed &operator+=(uint i) { val += (i<<6); return *this; }
54 inline QFixed &operator+=(QFixed other) { val += other.val; return *this; }
55 constexpr inline QFixed operator-(int i) const { return fromFixed(fixed: val - i * 64); }
56 constexpr inline QFixed operator-(uint i) const { return fromFixed(fixed: (val - (i<<6))); }
57 constexpr inline QFixed operator-(QFixed other) const { return fromFixed(fixed: (val - other.val)); }
58 inline QFixed &operator-=(int i) { val -= i * 64; return *this; }
59 inline QFixed &operator-=(uint i) { val -= (i<<6); return *this; }
60 inline QFixed &operator-=(QFixed other) { val -= other.val; return *this; }
61 constexpr inline QFixed operator-() const { return fromFixed(fixed: -val); }
62
63#define REL_OP(op) \
64 friend constexpr bool operator op(QFixed lhs, QFixed rhs) noexcept \
65 { return lhs.val op rhs.val; }
66 REL_OP(==)
67 REL_OP(!=)
68 REL_OP(< )
69 REL_OP(> )
70 REL_OP(<=)
71 REL_OP(>=)
72#undef REL_OP
73
74 constexpr inline bool operator!() const { return !val; }
75
76 inline QFixed &operator/=(int x) { val /= x; return *this; }
77 inline QFixed &operator/=(QFixed o) {
78 if (o.val == 0) {
79 val = 0x7FFFFFFFL;
80 } else {
81 bool neg = false;
82 qint64 a = val;
83 qint64 b = o.val;
84 if (a < 0) { a = -a; neg = true; }
85 if (b < 0) { b = -b; neg = !neg; }
86
87 int res = (int)(((a << 6) + (b >> 1)) / b);
88
89 val = (neg ? -res : res);
90 }
91 return *this;
92 }
93 constexpr inline QFixed operator/(int d) const { return fromFixed(fixed: val/d); }
94 inline QFixed operator/(QFixed b) const { QFixed f = *this; return (f /= b); }
95 inline QFixed operator>>(int d) const { QFixed f = *this; f.val >>= d; return f; }
96 inline QFixed &operator*=(int i) { val *= i; return *this; }
97 inline QFixed &operator*=(uint i) { val *= i; return *this; }
98 inline QFixed &operator*=(QFixed o) {
99 bool neg = false;
100 qint64 a = val;
101 qint64 b = o.val;
102 if (a < 0) { a = -a; neg = true; }
103 if (b < 0) { b = -b; neg = !neg; }
104
105 int res = (int)((a * b + 0x20L) >> 6);
106 val = neg ? -res : res;
107 return *this;
108 }
109 constexpr inline QFixed operator*(int i) const { return fromFixed(fixed: val * i); }
110 constexpr inline QFixed operator*(uint i) const { return fromFixed(fixed: val * i); }
111 inline QFixed operator*(QFixed o) const { QFixed f = *this; return (f *= o); }
112
113private:
114 constexpr QFixed(qreal i) : val((int)(i*qreal(64))) {}
115 constexpr inline QFixed operator+(qreal i) const { return fromFixed(fixed: (val + (int)(i*qreal(64)))); }
116 inline QFixed &operator+=(qreal i) { val += (int)(i*64); return *this; }
117 constexpr inline QFixed operator-(qreal i) const { return fromFixed(fixed: (val - (int)(i*qreal(64)))); }
118 inline QFixed &operator-=(qreal i) { val -= (int)(i*64); return *this; }
119 inline QFixed &operator/=(qreal r) { val = (int)(val/r); return *this; }
120 constexpr inline QFixed operator/(qreal d) const { return fromFixed(fixed: (int)(val/d)); }
121 inline QFixed &operator*=(qreal d) { val = (int) (val*d); return *this; }
122 constexpr inline QFixed operator*(qreal d) const { return fromFixed(fixed: (int) (val*d)); }
123 int val;
124};
125Q_DECLARE_TYPEINFO(QFixed, Q_PRIMITIVE_TYPE);
126
127#define QFIXED_MAX (INT_MAX/256)
128
129constexpr inline int qRound(QFixed f) { return f.toInt(); }
130constexpr inline int qFloor(QFixed f) { return f.floor().truncate(); }
131
132constexpr inline QFixed operator*(int i, QFixed d) { return d*i; }
133constexpr inline QFixed operator+(int i, QFixed d) { return d+i; }
134constexpr inline QFixed operator-(int i, QFixed d) { return -(d-i); }
135constexpr inline QFixed operator*(uint i, QFixed d) { return d*i; }
136constexpr inline QFixed operator+(uint i, QFixed d) { return d+i; }
137constexpr inline QFixed operator-(uint i, QFixed d) { return -(d-i); }
138// constexpr inline QFixed operator*(qreal d, QFixed d2) { return d2*d; }
139
140inline bool qAddOverflow(QFixed v1, QFixed v2, QFixed *r)
141{
142 int val;
143 bool result = qAddOverflow(v1: v1.value(), v2: v2.value(), r: &val);
144 r->setValue(val);
145 return result;
146}
147
148inline bool qMulOverflow(QFixed v1, QFixed v2, QFixed *r)
149{
150 int val;
151 bool result = qMulOverflow(v1: v1.value(), v2: v2.value(), r: &val);
152 r->setValue(val);
153 return result;
154}
155
156#ifndef QT_NO_DEBUG_STREAM
157inline QDebug &operator<<(QDebug &dbg, QFixed f)
158{ return dbg << f.toReal(); }
159#endif
160
161struct QFixedPoint {
162 QFixed x;
163 QFixed y;
164 constexpr inline QFixedPoint() {}
165 constexpr inline QFixedPoint(QFixed _x, QFixed _y) : x(_x), y(_y) {}
166 constexpr QPointF toPointF() const { return QPointF(x.toReal(), y.toReal()); }
167 constexpr static QFixedPoint fromPointF(const QPointF &p) {
168 return QFixedPoint(QFixed::fromReal(r: p.x()), QFixed::fromReal(r: p.y()));
169 }
170 constexpr inline bool operator==(const QFixedPoint &other) const
171 {
172 return x == other.x && y == other.y;
173 }
174};
175Q_DECLARE_TYPEINFO(QFixedPoint, Q_PRIMITIVE_TYPE);
176
177constexpr inline QFixedPoint operator-(const QFixedPoint &p1, const QFixedPoint &p2)
178{ return QFixedPoint(p1.x - p2.x, p1.y - p2.y); }
179constexpr inline QFixedPoint operator+(const QFixedPoint &p1, const QFixedPoint &p2)
180{ return QFixedPoint(p1.x + p2.x, p1.y + p2.y); }
181
182struct QFixedSize {
183 QFixed width;
184 QFixed height;
185 constexpr QFixedSize() {}
186 constexpr QFixedSize(QFixed _width, QFixed _height) : width(_width), height(_height) {}
187 constexpr QSizeF toSizeF() const { return QSizeF(width.toReal(), height.toReal()); }
188 constexpr static QFixedSize fromSizeF(const QSizeF &s) {
189 return QFixedSize(QFixed::fromReal(r: s.width()), QFixed::fromReal(r: s.height()));
190 }
191};
192Q_DECLARE_TYPEINFO(QFixedSize, Q_PRIMITIVE_TYPE);
193
194QT_END_NAMESPACE
195
196#endif // QTEXTENGINE_P_H
197

source code of qtbase/src/gui/painting/qfixed_p.h