Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_lod_transform_base.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef KIS_LOD_TRANSFORM_BASE_H
8#define KIS_LOD_TRANSFORM_BASE_H
9
10
11#include <QtCore/qmath.h>
12#include <QTransform>
13
14
15#include <kritaglobal_export.h>
16
17class KRITAGLOBAL_EXPORT KisLodTransformBase {
18public:
19 KisLodTransformBase(int levelOfDetail) {
20 qreal scale = lodToScale(levelOfDetail);
21 m_transform = QTransform::fromScale(scale, scale);
22 m_levelOfDetail = levelOfDetail;
23 }
24
25
26
27 static int scaleToLod(qreal scale, int maxLod) {
28 return qMin(maxLod, qMax(0, qFloor(std::log2(1.0 / scale))));
29 }
30
31 static qreal lodToScale(int levelOfDetail) {
32 return levelOfDetail > 0 ? 1.0 / (1 << qMax(0, levelOfDetail)) : 1.0;
33 }
34
35 static qreal lodToInvScale(int levelOfDetail) {
36 return 1 << qMax(0, levelOfDetail);
37 }
38
39 template <class PaintDeviceTypeSP>
40 static qreal lodToScale(PaintDeviceTypeSP device) {
41 return lodToScale(device->defaultBounds()->currentLevelOfDetail());
42 }
43
44 QRectF map(const QRectF &rc) const {
45 return m_transform.mapRect(rc);
46 }
47
48 QRect map(const QRect &rc) const {
49 return m_transform.mapRect(rc);
50 }
51
52 QRectF mapInverted(const QRectF &rc) const {
53 return m_transform.inverted().mapRect(rc);
54 }
55
56 QRect mapInverted(const QRect &rc) const {
57 return m_transform.inverted().mapRect(rc);
58 }
59
60
61
62 template <class T>
63 T map(const T &object) const {
64 return m_transform.map(object);
65 }
66
67 static inline QRect alignedRect(const QRect &srcRect, int lod)
68 {
69 qint32 alignment = 1 << lod;
70
71 qint32 x1, y1, x2, y2;
72 srcRect.getCoords(&x1, &y1, &x2, &y2);
73
74 alignByPow2Lo(x1, alignment);
75 alignByPow2Lo(y1, alignment);
76
82 alignByPow2ButOneHi(x2, alignment);
83 alignByPow2ButOneHi(y2, alignment);
84
85 QRect rect;
86 rect.setCoords(x1, y1, x2, y2);
87
88 return rect;
89 }
90
91 static inline QRect scaledRect(const QRect &srcRect, int lod) {
92 qint32 x1, y1, x2, y2;
93 srcRect.getCoords(&x1, &y1, &x2, &y2);
94
95 KIS_ASSERT_RECOVER_NOOP(!(x1 & 1));
96 KIS_ASSERT_RECOVER_NOOP(!(y1 & 1));
97 KIS_ASSERT_RECOVER_NOOP(!((x2 + 1) & 1));
98 KIS_ASSERT_RECOVER_NOOP(!((y2 + 1) & 1));
99
100 x1 = divideSafe(x1, lod);
101 y1 = divideSafe(y1, lod);
102 x2 = divideSafe(x2 + 1, lod) - 1;
103 y2 = divideSafe(y2 + 1, lod) - 1;
104
105 QRect rect;
106 rect.setCoords(x1, y1, x2, y2);
107
108 return rect;
109 }
110
111 static QRect upscaledRect(const QRect &srcRect, int lod) {
112 qint32 x1, y1, x2, y2;
113 srcRect.getCoords(&x1, &y1, &x2, &y2);
114
115 x2++;
116 y2++;
117
118 x1 <<= lod;
119 y1 <<= lod;
120 x2 <<= lod;
121 y2 <<= lod;
122
123 x2--;
124 y2--;
125
126 QRect rect;
127 rect.setCoords(x1, y1, x2, y2);
128
129 return rect;
130 }
131
132 static inline int coordToLodCoord(int x, int lod) {
133 return divideSafe(x, lod);
134 }
135
136 QTransform transform() const {
137 return m_transform;
138 }
139
140private:
141 friend class KisRectsGrid;
146 static inline void alignByPow2ButOneHi(qint32 &value, qint32 alignment)
147 {
148 qint32 mask = alignment - 1;
149 value |= mask;
150 }
151
156 static inline void alignByPow2Lo(qint32 &value, qint32 alignment)
157 {
158 qint32 mask = alignment - 1;
159 value &= ~mask;
160 }
161
162 static inline int divideSafe(int x, int lod) {
163 return x > 0 ? x >> lod : -( -x >> lod);
164 }
165
166protected:
167 QTransform m_transform;
169};
170
172public:
176
177 template <class PaintDeviceTypeSP>
178 KisLodTransformScalar(PaintDeviceTypeSP device) {
179 m_scale = KisLodTransformBase::lodToScale(device->defaultBounds()->currentLevelOfDetail());
180 }
181
182 qreal scale(qreal value) const {
183 return m_scale * value;
184 }
185
186private:
187 qreal m_scale;
188};
189
190#endif // KIS_LOD_TRANSFORM_BASE_H
float value(const T *src, size_t ch)
static int scaleToLod(qreal scale, int maxLod)
static int coordToLodCoord(int x, int lod)
QRect mapInverted(const QRect &rc) const
QTransform transform() const
QRect map(const QRect &rc) const
static QRect alignedRect(const QRect &srcRect, int lod)
KisLodTransformBase(int levelOfDetail)
static qreal lodToScale(PaintDeviceTypeSP device)
QRectF map(const QRectF &rc) const
static QRect scaledRect(const QRect &srcRect, int lod)
T map(const T &object) const
static void alignByPow2ButOneHi(qint32 &value, qint32 alignment)
QRectF mapInverted(const QRectF &rc) const
static void alignByPow2Lo(qint32 &value, qint32 alignment)
static int divideSafe(int x, int lod)
static qreal lodToInvScale(int levelOfDetail)
static QRect upscaledRect(const QRect &srcRect, int lod)
static qreal lodToScale(int levelOfDetail)
KisLodTransformScalar(PaintDeviceTypeSP device)
qreal scale(qreal value) const
A utility class to maintain a sparse grid of loaded/unloaded rects.
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
void alignByPow2Lo(qint32 &value, qint32 alignment)
void alignByPow2ButOneHi(qint32 &value, qint32 alignment)