File indexing completed on 2024-05-19 04:26:08
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_default_bounds.h" 0012 #include "KisImageResolutionProxy.h" 0013 #include "kis_paint_device.h" 0014 #include "kis_selection.h" 0015 #include "KoColorSpace.h" 0016 #include "KoColor.h" 0017 0018 class KisCachedPaintDevice 0019 { 0020 public: 0021 KisPaintDeviceSP getDevice(KisPaintDeviceSP prototype) { 0022 KisPaintDeviceSP device; 0023 0024 if(!m_stack.pop(device)) { 0025 device = new KisPaintDevice(prototype->colorSpace()); 0026 } 0027 0028 device->prepareClone(prototype); 0029 return device; 0030 } 0031 0032 KisPaintDeviceSP getDevice(KisPaintDeviceSP prototype, const KoColorSpace *colorSpace) { 0033 KisPaintDeviceSP device; 0034 0035 if(!m_stack.pop(device)) { 0036 device = new KisPaintDevice(colorSpace); 0037 } else { 0038 device->convertTo(colorSpace); 0039 } 0040 0041 device->setDefaultPixel(KoColor(colorSpace)); 0042 device->setDefaultBounds(prototype->defaultBounds()); 0043 device->setX(prototype->x()); 0044 device->setY(prototype->y()); 0045 0046 return device; 0047 } 0048 0049 void putDevice(KisPaintDeviceSP device) { 0050 device->clear(); 0051 device->setDefaultBounds(new KisDefaultBounds()); 0052 m_stack.push(device); 0053 } 0054 0055 bool isEmpty() const { 0056 return m_stack.isEmpty(); 0057 } 0058 0059 struct Guard { 0060 Guard(KisPaintDeviceSP prototype, KisCachedPaintDevice &parent) 0061 : m_parent(parent) 0062 { 0063 m_device = m_parent.getDevice(prototype); 0064 } 0065 0066 Guard(KisPaintDeviceSP prototype, const KoColorSpace *cs, KisCachedPaintDevice &parent) 0067 : m_parent(parent) 0068 { 0069 m_device = m_parent.getDevice(prototype, cs); 0070 } 0071 0072 ~Guard() { 0073 m_parent.putDevice(m_device); 0074 } 0075 0076 KisPaintDeviceSP device() const { 0077 return m_device; 0078 } 0079 0080 private: 0081 KisCachedPaintDevice &m_parent; 0082 KisPaintDeviceSP m_device; 0083 }; 0084 0085 private: 0086 KisLocklessStack<KisPaintDeviceSP> m_stack; 0087 }; 0088 0089 class KisCachedSelection 0090 { 0091 public: 0092 KisSelectionSP getSelection() { 0093 KisSelectionSP selection; 0094 0095 if(!m_stack.pop(selection)) { 0096 selection = new KisSelection(new KisSelectionEmptyBounds(), KisImageResolutionProxy::identity()); 0097 } 0098 0099 return selection; 0100 } 0101 0102 void putSelection(KisSelectionSP selection) { 0103 selection->clear(); 0104 selection->setDefaultBounds(new KisSelectionEmptyBounds()); 0105 selection->setResolutionProxy(KisImageResolutionProxy::identity()); 0106 selection->pixelSelection()->moveTo(QPoint()); 0107 m_stack.push(selection); 0108 } 0109 0110 bool isEmpty() const { 0111 return m_stack.isEmpty(); 0112 } 0113 0114 struct Guard { 0115 Guard(KisCachedSelection &parent) 0116 : m_parent(parent) 0117 { 0118 m_selection = m_parent.getSelection(); 0119 } 0120 0121 ~Guard() { 0122 m_parent.putSelection(m_selection); 0123 } 0124 0125 KisSelectionSP selection() const { 0126 return m_selection; 0127 } 0128 0129 private: 0130 KisCachedSelection &m_parent; 0131 KisSelectionSP m_selection; 0132 }; 0133 0134 private: 0135 KisLocklessStack<KisSelectionSP> m_stack; 0136 }; 0137 0138 #endif /* __KIS_CACHED_PAINT_DEVICE_H */