File indexing completed on 2024-06-09 04:21:58
0001 /* 0002 * SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "KisLayerStyleKnockoutBlower.h" 0007 0008 #include "kis_painter.h" 0009 #include "KoCompositeOpRegistry.h" 0010 #include "kis_default_bounds.h" 0011 #include "KisImageResolutionProxy.h" 0012 0013 0014 KisLayerStyleKnockoutBlower::KisLayerStyleKnockoutBlower() 0015 { 0016 } 0017 0018 KisLayerStyleKnockoutBlower::KisLayerStyleKnockoutBlower(const KisLayerStyleKnockoutBlower &rhs) 0019 : m_knockoutSelection(rhs.m_knockoutSelection ? new KisSelection(*rhs.m_knockoutSelection) : nullptr) 0020 { 0021 } 0022 0023 KisSelectionSP KisLayerStyleKnockoutBlower::knockoutSelectionLazy() 0024 { 0025 { 0026 QReadLocker l(&m_lock); 0027 if (m_knockoutSelection) { 0028 return m_knockoutSelection; 0029 } 0030 } 0031 0032 { 0033 QWriteLocker l(&m_lock); 0034 if (m_knockoutSelection) { 0035 return m_knockoutSelection; 0036 } else { 0037 m_knockoutSelection = new KisSelection(new KisSelectionEmptyBounds(), 0038 KisImageResolutionProxy::identity()); 0039 return m_knockoutSelection; 0040 } 0041 } 0042 } 0043 0044 void KisLayerStyleKnockoutBlower::setKnockoutSelection(KisSelectionSP selection) 0045 { 0046 QWriteLocker l(&m_lock); 0047 m_knockoutSelection = selection; 0048 } 0049 0050 void KisLayerStyleKnockoutBlower::resetKnockoutSelection() 0051 { 0052 QWriteLocker l(&m_lock); 0053 m_knockoutSelection = 0; 0054 } 0055 0056 void KisLayerStyleKnockoutBlower::apply(KisPainter *painter, KisPaintDeviceSP mergedStyle, const QRect &rect) const 0057 { 0058 QReadLocker l(&m_lock); 0059 0060 KIS_SAFE_ASSERT_RECOVER_NOOP(m_knockoutSelection); 0061 0062 painter->setOpacity(OPACITY_OPAQUE_U8); 0063 painter->setChannelFlags(QBitArray()); 0064 painter->setCompositeOpId(COMPOSITE_COPY); 0065 painter->setSelection(m_knockoutSelection); 0066 painter->bitBlt(rect.topLeft(), mergedStyle, rect); 0067 painter->setSelection(0); 0068 } 0069 0070 bool KisLayerStyleKnockoutBlower::isEmpty() const 0071 { 0072 QReadLocker l(&m_lock); 0073 return !m_knockoutSelection; 0074 }