File indexing completed on 2024-05-12 15:58:11

0001 /*
0002  *  SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_CACHED_PAINT_DEVICE_H
0008 #define __KIS_CACHED_PAINT_DEVICE_H
0009 
0010 #include "kis_lockless_stack.h"
0011 #include "kis_paint_device.h"
0012 #include "kis_selection.h"
0013 #include "KoColorSpace.h"
0014 #include "KoColor.h"
0015 
0016 class KisCachedPaintDevice
0017 {
0018 public:
0019     KisPaintDeviceSP getDevice(KisPaintDeviceSP prototype) {
0020         KisPaintDeviceSP device;
0021 
0022         if(!m_stack.pop(device)) {
0023             device = new KisPaintDevice(prototype->colorSpace());
0024         }
0025 
0026         device->prepareClone(prototype);
0027         return device;
0028     }
0029 
0030     KisPaintDeviceSP getDevice(KisPaintDeviceSP prototype, const KoColorSpace *colorSpace) {
0031         KisPaintDeviceSP device;
0032 
0033         if(!m_stack.pop(device)) {
0034             device = new KisPaintDevice(colorSpace);
0035         } else {
0036             device->convertTo(colorSpace);
0037         }
0038 
0039         device->setDefaultPixel(KoColor(colorSpace));
0040         device->setDefaultBounds(prototype->defaultBounds());
0041         device->setX(prototype->x());
0042         device->setY(prototype->y());
0043 
0044         return device;
0045     }
0046 
0047     void putDevice(KisPaintDeviceSP device) {
0048         device->clear();
0049         device->setDefaultBounds(new KisDefaultBounds());
0050         m_stack.push(device);
0051     }
0052 
0053     bool isEmpty() const {
0054         return m_stack.isEmpty();
0055     }
0056 
0057     struct Guard {
0058         Guard(KisPaintDeviceSP prototype, KisCachedPaintDevice &parent)
0059             : m_parent(parent)
0060         {
0061             m_device = m_parent.getDevice(prototype);
0062         }
0063 
0064         Guard(KisPaintDeviceSP prototype, const KoColorSpace *cs, KisCachedPaintDevice &parent)
0065             : m_parent(parent)
0066         {
0067             m_device = m_parent.getDevice(prototype, cs);
0068         }
0069 
0070         ~Guard() {
0071             m_parent.putDevice(m_device);
0072         }
0073 
0074         KisPaintDeviceSP device() const {
0075             return m_device;
0076         }
0077 
0078         private:
0079         KisCachedPaintDevice &m_parent;
0080         KisPaintDeviceSP m_device;
0081     };
0082 
0083 private:
0084     KisLocklessStack<KisPaintDeviceSP> m_stack;
0085 };
0086 
0087 class KisCachedSelection
0088 {
0089 public:
0090     KisSelectionSP getSelection() {
0091         KisSelectionSP selection;
0092 
0093         if(!m_stack.pop(selection)) {
0094             selection = new KisSelection(new KisSelectionEmptyBounds(0));
0095         }
0096 
0097         return selection;
0098     }
0099 
0100     void putSelection(KisSelectionSP selection) {
0101         selection->clear();
0102         selection->setDefaultBounds(new KisSelectionEmptyBounds(0));
0103         selection->pixelSelection()->moveTo(QPoint());
0104         m_stack.push(selection);
0105     }
0106 
0107     bool isEmpty() const {
0108         return m_stack.isEmpty();
0109     }
0110 
0111     struct Guard {
0112         Guard(KisCachedSelection &parent)
0113             : m_parent(parent)
0114         {
0115             m_selection = m_parent.getSelection();
0116         }
0117 
0118         ~Guard() {
0119             m_parent.putSelection(m_selection);
0120         }
0121 
0122         KisSelectionSP selection() const {
0123             return m_selection;
0124         }
0125 
0126         private:
0127         KisCachedSelection &m_parent;
0128         KisSelectionSP m_selection;
0129     };
0130 
0131 private:
0132     KisLocklessStack<KisSelectionSP> m_stack;
0133 };
0134 
0135 #endif /* __KIS_CACHED_PAINT_DEVICE_H */