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 }