File indexing completed on 2024-05-19 04:26:19
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_layer_projection_plane.h" 0008 0009 #include <QBitArray> 0010 #include <KoColorSpace.h> 0011 #include <KoChannelInfo.h> 0012 #include <KoCompositeOpRegistry.h> 0013 #include "kis_painter.h" 0014 #include "kis_projection_leaf.h" 0015 #include "kis_cached_paint_device.h" 0016 #include "kis_sequential_iterator.h" 0017 0018 0019 struct KisLayerProjectionPlane::Private 0020 { 0021 KisLayer *layer; 0022 KisCachedPaintDevice cachedDevice; 0023 }; 0024 0025 0026 KisLayerProjectionPlane::KisLayerProjectionPlane(KisLayer *layer) 0027 : m_d(new Private) 0028 { 0029 m_d->layer = layer; 0030 } 0031 0032 KisLayerProjectionPlane::~KisLayerProjectionPlane() 0033 { 0034 } 0035 0036 QRect KisLayerProjectionPlane::recalculate(const QRect& rect, KisNodeSP filthyNode) 0037 { 0038 return m_d->layer->updateProjection(rect, filthyNode); 0039 } 0040 0041 void KisLayerProjectionPlane::applyImpl(KisPainter *painter, const QRect &rect, KritaUtils::ThresholdMode thresholdMode) 0042 { 0043 KisPaintDeviceSP device = m_d->layer->projection(); 0044 if (!device) return; 0045 0046 QRect needRect = rect; 0047 0048 if (m_d->layer->compositeOpId() != COMPOSITE_COPY && 0049 m_d->layer->compositeOpId() != COMPOSITE_DESTINATION_IN && 0050 m_d->layer->compositeOpId() != COMPOSITE_DESTINATION_ATOP) { 0051 0052 needRect &= device->extent(); 0053 } 0054 0055 if(needRect.isEmpty()) return; 0056 0057 const QBitArray channelFlags = m_d->layer->projectionLeaf()->channelFlags(); 0058 0059 QScopedPointer<KisCachedPaintDevice::Guard> d1; 0060 0061 if (thresholdMode != KritaUtils::ThresholdNone) { 0062 d1.reset(new KisCachedPaintDevice::Guard(device, m_d->cachedDevice)); 0063 KisPaintDeviceSP tmp = d1->device(); 0064 tmp->makeCloneFromRough(device, needRect); 0065 0066 KritaUtils::thresholdOpacity(tmp, needRect, thresholdMode); 0067 0068 device = tmp; 0069 } 0070 0071 painter->setChannelFlags(channelFlags); 0072 painter->setCompositeOpId(m_d->layer->compositeOpId()); 0073 painter->setOpacity(m_d->layer->projectionLeaf()->opacity()); 0074 painter->bitBlt(needRect.topLeft(), device, needRect); 0075 } 0076 0077 void KisLayerProjectionPlane::apply(KisPainter *painter, const QRect &rect) 0078 { 0079 applyImpl(painter, rect, KritaUtils::ThresholdNone); 0080 } 0081 0082 void KisLayerProjectionPlane::applyMaxOutAlpha(KisPainter *painter, const QRect &rect, KritaUtils::ThresholdMode thresholdMode) 0083 { 0084 applyImpl(painter, rect, thresholdMode); 0085 } 0086 0087 KisPaintDeviceList KisLayerProjectionPlane::getLodCapableDevices() const 0088 { 0089 return KisPaintDeviceList() << m_d->layer->projection(); 0090 } 0091 0092 QRect KisLayerProjectionPlane::needRect(const QRect &rect, KisLayer::PositionToFilthy pos) const 0093 { 0094 return m_d->layer->needRect(rect, pos); 0095 } 0096 0097 QRect KisLayerProjectionPlane::changeRect(const QRect &rect, KisLayer::PositionToFilthy pos) const 0098 { 0099 return m_d->layer->changeRect(rect, pos); 0100 } 0101 0102 QRect KisLayerProjectionPlane::accessRect(const QRect &rect, KisLayer::PositionToFilthy pos) const 0103 { 0104 return m_d->layer->accessRect(rect, pos); 0105 } 0106 0107 QRect KisLayerProjectionPlane::needRectForOriginal(const QRect &rect) const 0108 { 0109 return m_d->layer->needRectForOriginal(rect); 0110 } 0111 0112 QRect KisLayerProjectionPlane::tightUserVisibleBounds() const 0113 { 0114 return m_d->layer->tightUserVisibleBounds(); 0115 } 0116