File indexing completed on 2024-05-19 04:26:21
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef __KIS_LOD_CAPABLE_LAYER_OFFSET_H 0008 #define __KIS_LOD_CAPABLE_LAYER_OFFSET_H 0009 0010 #include <QScopedPointer> 0011 #include "kritaimage_export.h" 0012 #include "kis_default_bounds_base.h" 0013 0014 0015 namespace KisLodSwitchingWrapperDetail 0016 { 0017 /** 0018 * By default forward the syncing request to the wrapped 0019 * object itself. 0020 */ 0021 template <typename T> 0022 inline T syncLodNValue(const T &value, int lod) { 0023 return value.syncLodNValue(lod); 0024 } 0025 0026 /** 0027 * Otherwise just use specialized functions for that 0028 */ 0029 KRITAIMAGE_EXPORT 0030 QPoint syncLodNValue(const QPoint &value, int lod); 0031 0032 } // namespace KisLodSwitchingWrapperDetail 0033 0034 template <typename T> 0035 class KisLodSwitchingWrapper 0036 { 0037 public: 0038 KisLodSwitchingWrapper(T &&initialValue, KisDefaultBoundsBaseSP defaultBounds) 0039 : m_defaultBounds(defaultBounds), 0040 m_data(std::forward<T>(initialValue)), 0041 m_lodNData(KisLodSwitchingWrapperDetail::syncLodNValue(m_data, defaultBounds->currentLevelOfDetail())) 0042 { 0043 } 0044 0045 KisLodSwitchingWrapper(KisDefaultBoundsBaseSP defaultBounds) 0046 : m_defaultBounds(defaultBounds) 0047 { 0048 } 0049 0050 KisLodSwitchingWrapper(const KisLodSwitchingWrapper &rhs) 0051 : m_defaultBounds(rhs.m_defaultBounds) 0052 , m_data(rhs.m_data) 0053 , m_lodNData(rhs.m_lodNData) 0054 { 0055 } 0056 0057 KisLodSwitchingWrapper& operator=(const KisLodSwitchingWrapper &rhs) 0058 { 0059 if (this != &rhs) { 0060 m_defaultBounds = rhs.m_defaultBounds; 0061 m_data = rhs.m_data; 0062 m_lodNData = rhs.m_lodNData; 0063 } 0064 0065 return *this; 0066 } 0067 0068 0069 KisDefaultBoundsBaseSP defaultBounds() const { 0070 return m_defaultBounds; 0071 } 0072 0073 void setDefaultBounds(KisDefaultBoundsBaseSP defaultBounds) { 0074 m_defaultBounds = defaultBounds; 0075 } 0076 0077 const T *operator->() const noexcept 0078 { 0079 return m_defaultBounds->currentLevelOfDetail() > 0 ? &m_lodNData : &m_data; 0080 } 0081 0082 T *operator->() noexcept 0083 { 0084 return m_defaultBounds->currentLevelOfDetail() > 0 ? &m_lodNData : &m_data; 0085 } 0086 0087 const T& operator*() const noexcept 0088 { 0089 return m_defaultBounds->currentLevelOfDetail() > 0 ? m_lodNData : m_data; 0090 } 0091 0092 T& operator*() noexcept 0093 { 0094 return m_defaultBounds->currentLevelOfDetail() > 0 ? m_lodNData : m_data; 0095 } 0096 0097 void syncLodCache() { 0098 m_lodNData = 0099 KisLodSwitchingWrapperDetail::syncLodNValue( 0100 m_data, m_defaultBounds->currentLevelOfDetail()); 0101 } 0102 0103 using LodState = std::pair<int, T>; 0104 0105 void setLodState(const LodState &state) { 0106 (state.first > 0 ? m_lodNData : m_data) = state.second; 0107 } 0108 0109 LodState lodState() const { 0110 return std::make_pair(m_defaultBounds->currentLevelOfDetail(), *(*this)); 0111 } 0112 0113 operator LodState() const { 0114 return lodState(); 0115 } 0116 0117 KisLodSwitchingWrapper& operator=(const LodState &rhs) 0118 { 0119 setLodState(rhs); 0120 return *this; 0121 } 0122 0123 0124 private: 0125 KisDefaultBoundsBaseSP m_defaultBounds; 0126 T m_data; 0127 T m_lodNData; 0128 }; 0129 0130 using KisLodCapableLayerOffset = KisLodSwitchingWrapper<QPoint>; 0131 0132 #endif /* __KIS_LOD_CAPABLE_LAYER_OFFSET_H */