File indexing completed on 2024-05-12 15:58:07
0001 /* 0002 * SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2005 C. Boemann <cbo@boemann.dk> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kis_adjustment_layer.h" 0009 0010 #include <klocalizedstring.h> 0011 #include "kis_debug.h" 0012 0013 #include <KoIcon.h> 0014 #include <kis_icon.h> 0015 #include <KoCompositeOpRegistry.h> 0016 0017 #include "kis_image.h" 0018 #include "kis_selection.h" 0019 #include "filter/kis_filter_configuration.h" 0020 #include "filter/kis_filter_registry.h" 0021 #include "filter/kis_filter.h" 0022 #include "kis_node_visitor.h" 0023 #include "kis_processing_visitor.h" 0024 0025 0026 KisAdjustmentLayer::KisAdjustmentLayer(KisImageWSP image, 0027 const QString &name, 0028 KisFilterConfigurationSP kfc, 0029 KisSelectionSP selection) 0030 : KisSelectionBasedLayer(image.data(), name, selection, kfc) 0031 { 0032 // by default Adjustment Layers have a copy composition, 0033 // which is more natural for users 0034 // https://bugs.kde.org/show_bug.cgi?id=324505 0035 // https://bugs.kde.org/show_bug.cgi?id=294122 0036 // demand the opposite from each other... 0037 // 0038 // also see a comment in KisLayerUtils::mergeMultipleLayersImpl() 0039 0040 setCompositeOpId(COMPOSITE_COPY); 0041 setUseSelectionInProjection(false); 0042 } 0043 0044 KisAdjustmentLayer::KisAdjustmentLayer(const KisAdjustmentLayer& rhs) 0045 : KisSelectionBasedLayer(rhs) 0046 { 0047 } 0048 0049 0050 KisAdjustmentLayer::~KisAdjustmentLayer() 0051 { 0052 } 0053 0054 void KisAdjustmentLayer::setFilter(KisFilterConfigurationSP filterConfig, bool checkCompareConfig) 0055 { 0056 filterConfig->setChannelFlags(channelFlags()); 0057 KisSelectionBasedLayer::setFilter(filterConfig, checkCompareConfig); 0058 } 0059 0060 QRect KisAdjustmentLayer::incomingChangeRect(const QRect &rect) const 0061 { 0062 KisFilterConfigurationSP filterConfig = filter(); 0063 0064 QRect filteredRect = rect; 0065 0066 if (filterConfig) { 0067 KisFilterSP filter = KisFilterRegistry::instance()->value(filterConfig->name()); 0068 filteredRect = filter->changedRect(rect, filterConfig.data(), projection()->defaultBounds()->currentLevelOfDetail()); 0069 } 0070 0071 /** 0072 * After the change in the blending using 0073 * setUseSelectionInProjection(false) we should *not* crop the 0074 * change rect of the layer, because we pass contents through. 0075 * 0076 * //filteredRect = cropChangeRectBySelection(filteredRect); 0077 */ 0078 0079 return filteredRect; 0080 } 0081 0082 QRect KisAdjustmentLayer::needRect(const QRect& rect, PositionToFilthy pos) const 0083 { 0084 Q_UNUSED(pos); 0085 0086 KisFilterConfigurationSP filterConfig = filter(); 0087 if (!filterConfig) return rect; 0088 KisFilterSP filter = KisFilterRegistry::instance()->value(filterConfig->name()); 0089 0090 /** 0091 * If we need some additional pixels even outside of a selection 0092 * for accurate layer filtering, we'll get them! 0093 * And no KisSelectionBasedLayer::needRect will prevent us 0094 * from doing this! ;) 0095 * That's why simply we do not call 0096 * KisSelectionBasedLayer::needRect here :) 0097 */ 0098 QRect needRect = rect; 0099 needRect |= needRectForOriginal(needRect); 0100 needRect = filter->neededRect(needRect, filterConfig.data(), projection()->defaultBounds()->currentLevelOfDetail()); 0101 return needRect; 0102 } 0103 0104 bool KisAdjustmentLayer::accept(KisNodeVisitor & v) 0105 { 0106 return v.visit(this); 0107 } 0108 0109 void KisAdjustmentLayer::accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter) 0110 { 0111 return visitor.visit(this, undoAdapter); 0112 } 0113 0114 QIcon KisAdjustmentLayer::icon() const 0115 { 0116 return KisIconUtils::loadIcon("filterLayer"); 0117 } 0118 0119 KisBaseNode::PropertyList KisAdjustmentLayer::sectionModelProperties() const 0120 { 0121 KisFilterConfigurationSP filterConfig = filter(); 0122 KisBaseNode::PropertyList l = KisLayer::sectionModelProperties(); 0123 if (filterConfig) 0124 l << KisBaseNode::Property(KoID("filter", i18nc("property of a filter layer, noun", "Filter")), KisFilterRegistry::instance()->value(filterConfig->name())->name()); 0125 0126 return l; 0127 } 0128 0129 void KisAdjustmentLayer::setChannelFlags(const QBitArray & channelFlags) 0130 { 0131 KisFilterConfigurationSP filterConfig = filter(); 0132 0133 if (filterConfig) { 0134 filterConfig->setChannelFlags(channelFlags); 0135 } 0136 KisLayer::setChannelFlags(channelFlags); 0137 } 0138