Krita Source Code Documentation
Loading...
Searching...
No Matches
KisGapMap Class Reference

#include <kis_gap_map.h>

+ Inheritance diagram for KisGapMap:

Classes

struct  Data
 

Public Types

typedef std::function< bool(KisPaintDevice *devicePtr, const QRect &rectFillOpacityFunc)
 

Public Member Functions

ALWAYS_INLINE quint16 distance (int x, int y)
 
ALWAYS_INLINE int gapSize () const
 
template<bool BoundsCheck>
bool isOpaque (const QPoint &p)
 
template<bool BoundsCheck>
bool isOpaque (int x, int y)
 
 KisGapMap (int gapSize, const QRect &mapBounds, const FillOpacityFunc &fillOpacityFunc)
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Static Public Attributes

static constexpr quint16 DISTANCE_INFINITE = UINT16_MAX
 

Private Types

enum  TileFlagBits { TILE_DISTANCE_LOADED = 0x1 , TILE_OPACITY_LOADED = 0x2 , TILE_HAS_OPAQUE_PIXELS = 0x4 }
 
typedef quint8 TileFlags
 

Private Member Functions

ALWAYS_INLINE DatadataPtr (int x, int y)
 
void distanceSearchRowInnerLoop (bool boundsCheck, int y, int x1, int x2)
 
template<bool BoundsCheck, typename CoordinateTransform >
void gapDistanceSearch (int x, int y, CoordinateTransform op)
 
ALWAYS_INLINE bool isDistanceAvailable (int x, int y)
 
template<bool BoundsCheck>
ALWAYS_INLINE bool isOpaque (const QPoint &p)
 
template<bool BoundsCheck>
ALWAYS_INLINE bool isOpaque (int x, int y)
 
quint16 lazyDistance (int x, int y)
 
void loadDistanceTile (const QPoint &tile, const QRect &nearbyTilesRect, int guardBand)
 
void loadOpacityTiles (const QRect &tileRect)
 
 Q_DISABLE_COPY (KisGapMap)
 
ALWAYS_INLINE TileFlagstileFlagsPtr (int tileX, int tileY)
 
void updateDistance (const QPoint &globalPosition, quint16 newDistance)
 

Private Attributes

std::unique_ptr< KisTileOptimizedAccessorm_accessor
 An accessor for the paint device.
 
KisPaintDeviceSP m_deviceSp
 A 32-bit per pixel paint device that holds the distance and other data.
 
const FillOpacityFunc m_fillOpacityFunc
 A callback to get the opacity data from the fill class.
 
const int m_gapSize
 Gap size in pixels for this map.
 
const QSize m_numTiles
 Map size in tiles.
 
const QSize m_size
 Size in pixels of the opacity/gap map.
 
Datam_tileDataPtr
 The pointer to the currently computed tile data.
 
QPoint m_tilePosition
 The position of the currently computed tile compared to the whole region.
 

Static Private Attributes

static constexpr int TileSize = 64
 

Additional Inherited Members

- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Detailed Description

Creates a "gap map", which is a pixel map of distances from lineart gaps (discontinuities in opaque lines), that helps detect these gaps and stop a bucket fill before spilling.

Definition at line 80 of file kis_gap_map.h.

Member Typedef Documentation

◆ FillOpacityFunc

typedef std::function<bool(KisPaintDevice* devicePtr, const QRect& rect) KisGapMap::FillOpacityFunc)

A callback to request opacity data for pixels in the image. It can be called at any time distance() function is invoked.

Parameters
devicePtrour underlying paint device, it contains opacity among other data. For each pixel, the offset of opacity quint8 data is 2 bytes.
rectthe bounds within the fill region (image) that are requested.
Returns
true, if at least one pixel within the tile is opaque

Definition at line 94 of file kis_gap_map.h.

◆ TileFlags

typedef quint8 KisGapMap::TileFlags
private

Definition at line 150 of file kis_gap_map.h.

Member Enumeration Documentation

◆ TileFlagBits

Enumerator
TILE_DISTANCE_LOADED 

Distance data is available.

TILE_OPACITY_LOADED 

Opacity data is available.

TILE_HAS_OPAQUE_PIXELS 

Some pixels of the loaded tile are opaque.

Definition at line 151 of file kis_gap_map.h.

152 {
154 TILE_OPACITY_LOADED = 0x2,
156 };
@ TILE_OPACITY_LOADED
Opacity data is available.
@ TILE_HAS_OPAQUE_PIXELS
Some pixels of the loaded tile are opaque.
@ TILE_DISTANCE_LOADED
Distance data is available.

Constructor & Destructor Documentation

◆ KisGapMap()

KisGapMap::KisGapMap ( int gapSize,
const QRect & mapBounds,
const FillOpacityFunc & fillOpacityFunc )

Create a new gap distance map object and prepare it for lazy initialization. Some memory allocation will happen upfront, but most of the calculations are deferred until distance() function is called.

Parameters
gapSizemaximum size of lineart gap to look for.
mapBoundsmust begin in (0,0) and must have the same size as the filled region.
fillOpacityFunca callback to obtain the opacity of pixels

Definition at line 89 of file kis_gap_map.cpp.

93 , m_size(mapBounds.size())
94 , m_numTiles(qCeil(static_cast<float>(m_size.width()) / TileSize),
95 qCeil(static_cast<float>(m_size.height()) / TileSize))
96 , m_fillOpacityFunc(fillOpacityFunc)
98 , m_accessor(std::make_unique<KisTileOptimizedAccessor>(m_deviceSp))
99{
100 // Ensure the scanline fill uses the same coordinates.
101 KIS_ASSERT((mapBounds.x() == 0) && (mapBounds.y() == 0) &&
102 "Gap closing fill assumes x and y start at coordinate (0, 0)");
103
104 Data defaultPixel {};
105 defaultPixel.distance = DISTANCE_INFINITE;
106 defaultPixel.opacity = MAX_SELECTED; // here: max = transparent
107
108 KoColor color(reinterpret_cast<quint8*>(&defaultPixel), KoColorSpaceRegistry::instance()->rgb8());
110 m_deviceSp->fill(mapBounds, color);
111}
const QSize m_numTiles
Map size in tiles.
const FillOpacityFunc m_fillOpacityFunc
A callback to get the opacity data from the fill class.
std::unique_ptr< KisTileOptimizedAccessor > m_accessor
An accessor for the paint device.
const int m_gapSize
Gap size in pixels for this map.
const QSize m_size
Size in pixels of the opacity/gap map.
static constexpr quint16 DISTANCE_INFINITE
Definition kis_gap_map.h:84
static constexpr int TileSize
ALWAYS_INLINE int gapSize() const
KisPaintDeviceSP m_deviceSp
A 32-bit per pixel paint device that holds the distance and other data.
void setDefaultPixel(const KoColor &defPixel)
void fill(const QRect &rc, const KoColor &color)
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
const quint8 MAX_SELECTED
Definition kis_global.h:32
static KoColorSpaceRegistry * instance()

References KisGapMap::Data::distance, DISTANCE_INFINITE, KisPaintDevice::fill(), KoColorSpaceRegistry::instance(), KIS_ASSERT, m_deviceSp, MAX_SELECTED, and KisPaintDevice::setDefaultPixel().

Member Function Documentation

◆ dataPtr()

ALWAYS_INLINE Data * KisGapMap::dataPtr ( int x,
int y )
inlineprivate

Definition at line 186 of file kis_gap_map.h.

187 {
188 return reinterpret_cast<Data*>(m_accessor->rawData(x, y));
189 }

◆ distance()

ALWAYS_INLINE quint16 KisGapMap::distance ( int x,
int y )
inline

Query the gap distance at a pixel. (x, y) are the filled region's coordinates, always starting at (0, 0).

Important: This function is not thread-safe.

Definition at line 113 of file kis_gap_map.h.

114 {
115 if (isDistanceAvailable(x, y)) {
116 return dataPtr(x, y)->distance;
117 } else {
118 return lazyDistance(x, y);
119 }
120 }
ALWAYS_INLINE Data * dataPtr(int x, int y)
quint16 lazyDistance(int x, int y)
ALWAYS_INLINE bool isDistanceAvailable(int x, int y)

◆ distanceSearchRowInnerLoop()

void KisGapMap::distanceSearchRowInnerLoop ( bool boundsCheck,
int y,
int x1,
int x2 )
private

This is a part of loadDistanceTile() implementation.

Definition at line 147 of file kis_gap_map.cpp.

148{
149 if (boundsCheck) {
150 for (int x = x1; x <= x2; ++x) {
151 if (isOpaque<true>(x, y)) {
152 gapDistanceSearch<true>(x, y, TransformNone);
153 gapDistanceSearch<true>(x, y, TransformRotateClockwiseMirrorHorizontally);
154 gapDistanceSearch<true>(x, y, TransformRotateClockwise);
155 gapDistanceSearch<true>(x, y, TransformMirrorHorizontally);
156 }
157 }
158 } else {
159 for (int x = x1; x <= x2; ++x) {
160 if (isOpaque<false>(x, y)) {
161 gapDistanceSearch<false>(x, y, TransformNone);
162 gapDistanceSearch<false>(x, y, TransformRotateClockwiseMirrorHorizontally);
163 gapDistanceSearch<false>(x, y, TransformRotateClockwise);
164 gapDistanceSearch<false>(x, y, TransformMirrorHorizontally);
165 }
166 }
167 }
168}

◆ gapDistanceSearch()

template<bool BoundsCheck, typename CoordinateTransform >
void KisGapMap::gapDistanceSearch ( int x,
int y,
CoordinateTransform op )
private

Update the distance map in an octant (a 45-degree sector of a half-circle) originating from the (x, y) point.

Important: The radius of the right half-circle is equal to the (gap size) for distance map, and the (gap size + 1) for the opacity map.

Which octant is used depends on the transform function. With 0 degrees being the -y axis (up): 0-45 deg - TransformNone 45-90 deg - TransformRotateClockwiseMirrorHorizontally 90-135 deg - TransformRotateClockwise 135-180 deg - TransformMirrorHorizontally

This function is a bit tricky to reason about:

  • Calling it for a point at (x, y) will modify the RIGHT half-circle of the distance map, excluding the point.
  • Conversely, to fully determine the distance at any specific point (mx, my) in the map, this function must be called for all points in the LEFT half-circle, that is the rect (mx - gap, my - gap, gap + 1, gap + 1).
  • Lastly, only some points in the half circle will be modified, it depends on the opacity checks.

Definition at line 281 of file kis_gap_map.cpp.

282{
283 if (isOpaque<BoundsCheck>(op(x, y, 0, -1)) ||
284 isOpaque<BoundsCheck>(op(x, y, 1, -1))) {
285 return;
286 }
287
288 for (int yoffs = 2; yoffs < m_gapSize + 2; ++yoffs) {
289 const int yDistanceSq = (yoffs - 1) * (yoffs - 1);
290
291 for (int xoffs = 0; xoffs <= yoffs; ++xoffs) {
292 const int offsetDistance = yDistanceSq + xoffs * xoffs;
293
294 if (offsetDistance >= 1 + m_gapSize * m_gapSize) {
295 break;
296 }
297
298 if (isOpaque<BoundsCheck>(op(x, y, xoffs, -yoffs))) {
299 const float dx = static_cast<float>(xoffs) / (yoffs - 1);
300 float tx = 0;
301 int cx = 0;
302
303 for (int cy = 1; cy < yoffs; ++cy) {
304 updateDistance(op(x, y, cx, -cy), offsetDistance);
305
306 tx += dx;
307 if (static_cast<int>(tx) > cx) {
308 cx++;
309 updateDistance(op(x, y, cx, -cy), offsetDistance);
310 }
311
312 updateDistance(op(x, y, cx + 1, -cy), offsetDistance);
313 }
314 }
315 }
316 }
317}
void updateDistance(const QPoint &globalPosition, quint16 newDistance)

References m_gapSize, and updateDistance().

◆ gapSize()

ALWAYS_INLINE int KisGapMap::gapSize ( ) const
inline

Definition at line 122 of file kis_gap_map.h.

123 {
124 return m_gapSize;
125 }

◆ isDistanceAvailable()

ALWAYS_INLINE bool KisGapMap::isDistanceAvailable ( int x,
int y )
inlineprivate

Definition at line 181 of file kis_gap_map.h.

182 {
183 return (*tileFlagsPtr(x / TileSize, y / TileSize) & TILE_DISTANCE_LOADED) != 0;
184 }
ALWAYS_INLINE TileFlags * tileFlagsPtr(int tileX, int tileY)

◆ isOpaque() [1/4]

template<bool BoundsCheck>
bool KisGapMap::isOpaque ( const QPoint & p)

Definition at line 84 of file kis_gap_map.cpp.

85{
86 return isOpaque<BoundsCheck>(p.x(), p.y());
87}
const Params2D p

References p.

◆ isOpaque() [2/4]

template<bool BoundsCheck>
ALWAYS_INLINE bool KisGapMap::isOpaque ( const QPoint & p)
private

◆ isOpaque() [3/4]

template<bool BoundsCheck>
bool KisGapMap::isOpaque ( int x,
int y )

Definition at line 63 of file kis_gap_map.cpp.

64{
65#if KIS_GAP_MAP_DEBUG_LOGGING_AND_ASSERTS
66 const TileFlags flags = *tileFlagsPtr(x / TileSize, y / TileSize);
68 qDebug() << "ERROR: opacity at (" << x << "," << y << ") not loaded";
69 return false;
70 }
71#endif
72 if (BoundsCheck) {
73 if ((x >= 0) && (x < m_size.width()) && (y >= 0) && (y < m_size.height())) {
74 return dataPtr(x, y)->opacity == MIN_SELECTED;
75 } else {
76 return false;
77 }
78 } else {
79 return dataPtr(x, y)->opacity == MIN_SELECTED;
80 }
81}
quint8 TileFlags
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
const quint8 MIN_SELECTED
Definition kis_global.h:33

References dataPtr(), KIS_SAFE_ASSERT_RECOVER, m_size, MIN_SELECTED, KisGapMap::Data::opacity, TILE_OPACITY_LOADED, tileFlagsPtr(), and TileSize.

◆ isOpaque() [4/4]

template<bool BoundsCheck>
ALWAYS_INLINE bool KisGapMap::isOpaque ( int x,
int y )
private

◆ lazyDistance()

quint16 KisGapMap::lazyDistance ( int x,
int y )
private

Load the required tiles and return pixel's distance data.

Definition at line 334 of file kis_gap_map.cpp.

335{
336#if KIS_GAP_MAP_DEBUG_LOGGING_AND_ASSERTS
337 qDebug() << "lazyDistance() at (" << x << "," << y << ")";
338#endif
339
340 const int tx = x / TileSize;
341 const int ty = y / TileSize;
342
343 // Clamped tile neighborhood.
344 const QPoint topLeft(qMax(0, tx - 1),
345 qMax(0, ty - 1));
346 const QPoint bottomRight(qMin(tx + 1, m_numTiles.width() - 1),
347 qMin(ty + 1, m_numTiles.height() - 1));
348 const QRect nearbyTiles = QRect(topLeft, bottomRight);
349
350 // For opacity data, we always load all the adjacent tiles (up to 9 tiles in total).
351 loadOpacityTiles(nearbyTiles);
352
353 // For distance data, we always load a single tile.
354 loadDistanceTile(QPoint(tx, ty), nearbyTiles, m_gapSize);
355
356 // The data is now ready to be returned.
357 return dataPtr(x, y)->distance;
358}
void loadOpacityTiles(const QRect &tileRect)
void loadDistanceTile(const QPoint &tile, const QRect &nearbyTilesRect, int guardBand)

References dataPtr(), KisGapMap::Data::distance, loadDistanceTile(), loadOpacityTiles(), m_gapSize, m_numTiles, and TileSize.

◆ loadDistanceTile()

void KisGapMap::loadDistanceTile ( const QPoint & tile,
const QRect & nearbyTilesRect,
int guardBand )
private

Calculate the gap distance data in the specified rect. NOTE: Opacity data must have been loaded already.

See also
gapDistanceSearch() for an explanation of which distance map pixels are be affected by this operation.

If the rect is smaller than the whole fill region, then the guardBand is needed and must be at least equal to the gap size. We need to do calculations in a larger region in order to compute correct distances within the requested rect.

Definition at line 180 of file kis_gap_map.cpp.

181{
182#if KIS_GAP_MAP_MEASURE_ELAPSED_TIME
183 QElapsedTimer timer;
184 timer.start();
185#endif
186
187 TileFlags* const pFlags = tileFlagsPtr(tile.x(), tile.y());
188
189 // This tile is now considered loaded.
190 *pFlags |= TILE_DISTANCE_LOADED;
191
192 // Optimization: If a tile is completely transparent (TILE_HAS_OPAQUE_PIXELS == 0), then
193 // we can skip the distance calculation for it. Unfortunately, with the guard bands we need
194 // to check the flags of the neighboring tiles as well.
195
196 const bool tileOpaque = (*pFlags & TILE_HAS_OPAQUE_PIXELS) != 0;
197 const bool tileOpaqueLeft = (nearbyTilesRect.left() == tile.x()) ? false : (*tileFlagsPtr(tile.x() - 1, tile.y()) & TILE_HAS_OPAQUE_PIXELS) != 0;
198 const bool tileOpaqueTopLeft = (nearbyTilesRect.left() == tile.x()) || (nearbyTilesRect.top() == tile.y()) ? false : (*tileFlagsPtr(tile.x() - 1, tile.y() - 1) & TILE_HAS_OPAQUE_PIXELS) != 0;
199 const bool tileOpaqueBottomLeft = (nearbyTilesRect.left() == tile.x()) || (nearbyTilesRect.bottom() == tile.y()) ? false : (*tileFlagsPtr(tile.x() - 1, tile.y() + 1) & TILE_HAS_OPAQUE_PIXELS) != 0;
200 const bool tileOpaqueTop = (nearbyTilesRect.top() == tile.y()) ? false : (*tileFlagsPtr(tile.x(), tile.y() - 1) & TILE_HAS_OPAQUE_PIXELS) != 0;
201 const bool tileOpaqueBottom = (nearbyTilesRect.bottom() == tile.y()) ? false : (*tileFlagsPtr(tile.x(), tile.y() + 1) & TILE_HAS_OPAQUE_PIXELS) != 0;
202
203 if (! (tileOpaqueTopLeft || tileOpaqueTop || tileOpaqueLeft || tileOpaque || tileOpaqueBottomLeft || tileOpaqueBottom)) {
204 // This tile as well as its surroundings are transparent.
205 // We can simply exit without explicitly initializing the tile. The paint device's default pixel is DISTANCE_INFINITE.
206
207#if KIS_GAP_MAP_MEASURE_ELAPSED_TIME
208 m_distanceElapsedNanos += timer.nsecsElapsed();
209#endif
210 return;
211 }
212
213 // The area of the image covered only by this tile.
214 QRect rect(tile.x() * TileSize, tile.y() * TileSize, TileSize, TileSize);
215 rect.setRight(qMin(rect.right(), m_size.width() - 1));
216 rect.setBottom(qMin(rect.bottom(), m_size.height() - 1));
217
218 // Compromise: At the tile size 64 px and the gap size 32 px, the guard band must be
219 // 31 px at most, because opacity is sampled in gap size + 1 radius, which could be two tiles
220 // away and that tile might not have been loaded yet. To avoid loading one row of that tile,
221 // we can clamp the guard band to 31. The error introduced by it should not be noticeable.
222
223 const int guardBandVertical = qMin(guardBand, 31);
224 const int y1 = tileOpaqueTopLeft || tileOpaqueTop ? qMax(0, rect.top() - guardBandVertical) : rect.top();
225 const int y2 = tileOpaqueBottomLeft || tileOpaqueBottom ? qMin(rect.bottom() + guardBandVertical, m_size.height() - 1) : rect.bottom();
226 const int x1Top = tileOpaqueTopLeft ? qMax(0, rect.left() - guardBand) : rect.left();
227 const int x1Middle = tileOpaqueLeft ? qMax(0, rect.left() - guardBand) : rect.left();
228 const int x1Bottom = tileOpaqueBottomLeft ? qMax(0, rect.left() - guardBand) : rect.left();
229 const int x2Top = tileOpaqueTop ? rect.right() : rect.left() - 1;
230 const int x2Middle = tileOpaque ? rect.right() : rect.left() - 1;
231 const int x2Bottom = tileOpaqueBottom ? rect.right() : rect.left() - 1;
232
233 // Apply conservative bounds checking. +1 for opacity.
234 const bool boundsCheck =
235 (rect.right() + (m_gapSize + 1) >= m_size.width()) || // no risk of accessing x<0
236 (y1 - (m_gapSize + 1) < 0) || (y2 + (m_gapSize + 1) >= m_size.height());
237
238 m_tilePosition = rect.topLeft();
239 m_tileDataPtr = reinterpret_cast<Data*>(m_accessor->tileRawData(tile.x(), tile.y()));
240
241 // Process the tile and its neighborhood in three passes:
242 // Top (the top guard bands)
243 for (int y = y1; y <= rect.top() - 1; ++y) {
244 distanceSearchRowInnerLoop(boundsCheck, y, x1Top, x2Top);
245 }
246 // Middle (the left guard band and the tile)
247 for (int y = rect.top(); y <= rect.bottom(); ++y) {
248 distanceSearchRowInnerLoop(boundsCheck, y, x1Middle, x2Middle);
249 }
250 // Bottom (the bottom guard bands)
251 for (int y = rect.bottom() + 1; y <= y2; ++y) {
252 distanceSearchRowInnerLoop(boundsCheck, y, x1Bottom, x2Bottom);
253 }
254
255#if KIS_GAP_MAP_MEASURE_ELAPSED_TIME
256 m_distanceElapsedNanos += timer.nsecsElapsed();
257#endif
258}
void distanceSearchRowInnerLoop(bool boundsCheck, int y, int x1, int x2)
QPoint m_tilePosition
The position of the currently computed tile compared to the whole region.
Data * m_tileDataPtr
The pointer to the currently computed tile data.

References distanceSearchRowInnerLoop(), m_accessor, m_gapSize, m_size, m_tileDataPtr, m_tilePosition, TILE_DISTANCE_LOADED, TILE_HAS_OPAQUE_PIXELS, tileFlagsPtr(), and TileSize.

◆ loadOpacityTiles()

void KisGapMap::loadOpacityTiles ( const QRect & tileRect)
private

Definition at line 113 of file kis_gap_map.cpp.

114{
115#if KIS_GAP_MAP_MEASURE_ELAPSED_TIME
116 QElapsedTimer timer;
117 timer.start();
118#endif
119
120 for (int ty = tileRect.top(); ty <= tileRect.bottom(); ++ty) {
121 for (int tx = tileRect.left(); tx <= tileRect.right(); ++tx) {
122 TileFlags* const pFlags = tileFlagsPtr(tx, ty);
123 if ((*pFlags & TILE_OPACITY_LOADED) == 0) {
124 // Resize and clamp to image bounds.
125 QRect rect(tx * TileSize, ty * TileSize, TileSize, TileSize);
126 rect.setRight(qMin(rect.right(), m_size.width() - 1));
127 rect.setBottom(qMin(rect.bottom(), m_size.height() - 1));
128
129#if KIS_GAP_MAP_DEBUG_LOGGING_AND_ASSERTS
130 qDebug() << "loadOpacityTiles()" << rect;
131#endif
132 // It's not too elegant to pass the device, but this performs the best for now.
133 const bool hasOpaquePixels = m_fillOpacityFunc(m_deviceSp.data(), rect);
134
135 // This tile is now loaded.
136 *pFlags |= TILE_OPACITY_LOADED | (hasOpaquePixels ? TILE_HAS_OPAQUE_PIXELS : 0);
137 }
138 }
139 }
140
141#if KIS_GAP_MAP_MEASURE_ELAPSED_TIME
142 m_opacityElapsedNanos += timer.nsecsElapsed();
143#endif
144}

References KisSharedPtr< T >::data(), m_deviceSp, m_fillOpacityFunc, m_size, TILE_HAS_OPAQUE_PIXELS, TILE_OPACITY_LOADED, tileFlagsPtr(), and TileSize.

◆ Q_DISABLE_COPY()

KisGapMap::Q_DISABLE_COPY ( KisGapMap )
private

◆ tileFlagsPtr()

ALWAYS_INLINE TileFlags * KisGapMap::tileFlagsPtr ( int tileX,
int tileY )
inlineprivate

Definition at line 191 of file kis_gap_map.h.

192 {
193 return reinterpret_cast<TileFlags*>(
194 m_accessor->tileRawData(tileX, tileY) + offsetof(Data, flags));
195 }

◆ updateDistance()

void KisGapMap::updateDistance ( const QPoint & globalPosition,
quint16 newDistance )
private

Definition at line 319 of file kis_gap_map.cpp.

320{
321 const QPoint p = globalPosition - m_tilePosition;
322
323 if ((p.x() < 0) || (p.x() >= TileSize) || (p.y() < 0) || (p.y() >= TileSize)) {
324 return;
325 }
326
327 Data* ptr = m_tileDataPtr + p.x() + TileSize * p.y();
328 if (ptr->distance > newDistance) {
329 ptr->distance = newDistance;
330 }
331}

References KisGapMap::Data::distance, m_tileDataPtr, m_tilePosition, p, and TileSize.

Member Data Documentation

◆ DISTANCE_INFINITE

constexpr quint16 KisGapMap::DISTANCE_INFINITE = UINT16_MAX
staticconstexpr

A magic number to express a pixel that is very far from any gaps.

Definition at line 84 of file kis_gap_map.h.

◆ m_accessor

std::unique_ptr<KisTileOptimizedAccessor> KisGapMap::m_accessor
private

An accessor for the paint device.

Definition at line 206 of file kis_gap_map.h.

◆ m_deviceSp

KisPaintDeviceSP KisGapMap::m_deviceSp
private

A 32-bit per pixel paint device that holds the distance and other data.

Definition at line 205 of file kis_gap_map.h.

◆ m_fillOpacityFunc

const FillOpacityFunc KisGapMap::m_fillOpacityFunc
private

A callback to get the opacity data from the fill class.

Definition at line 200 of file kis_gap_map.h.

◆ m_gapSize

const int KisGapMap::m_gapSize
private

Gap size in pixels for this map.

Definition at line 197 of file kis_gap_map.h.

◆ m_numTiles

const QSize KisGapMap::m_numTiles
private

Map size in tiles.

Definition at line 199 of file kis_gap_map.h.

◆ m_size

const QSize KisGapMap::m_size
private

Size in pixels of the opacity/gap map.

Definition at line 198 of file kis_gap_map.h.

◆ m_tileDataPtr

Data* KisGapMap::m_tileDataPtr
private

The pointer to the currently computed tile data.

Definition at line 203 of file kis_gap_map.h.

◆ m_tilePosition

QPoint KisGapMap::m_tilePosition
private

The position of the currently computed tile compared to the whole region.

Definition at line 202 of file kis_gap_map.h.

◆ TileSize

constexpr int KisGapMap::TileSize = 64
staticconstexprprivate

For the purpose of lazy loading, the data is fetched in tile increments.

Definition at line 148 of file kis_gap_map.h.


The documentation for this class was generated from the following files: