File indexing completed on 2024-05-12 16:01:45

0001 /*
0002  *  SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisDecorationsWrapperLayer.h"
0008 
0009 #include "KisDocument.h"
0010 #include "kis_node_visitor.h"
0011 #include "kis_processing_visitor.h"
0012 #include "kis_grid_config.h"
0013 #include "kis_guides_config.h"
0014 #include "kis_painting_assistant.h"
0015 #include "kis_default_bounds.h"
0016 
0017 struct KisDecorationsWrapperLayer::Private
0018 {
0019     KisDocument *document = 0;
0020     KisPaintDeviceSP fakeOriginalDevice;
0021 };
0022 
0023 KisDecorationsWrapperLayer::KisDecorationsWrapperLayer(KisDocument *document)
0024     : KisExternalLayer(document->image(), "decorations-wrapper-layer", OPACITY_OPAQUE_U8),
0025       m_d(new Private)
0026 {
0027     m_d->document = document;
0028     m_d->fakeOriginalDevice = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8());
0029     m_d->fakeOriginalDevice->setDefaultBounds(new KisDefaultBounds(document->image()));
0030 }
0031 
0032 
0033 KisDecorationsWrapperLayer::KisDecorationsWrapperLayer(const KisDecorationsWrapperLayer &rhs)
0034     : KisExternalLayer(rhs.image(), "decorations-wrapper-layer", OPACITY_OPAQUE_U8),
0035       m_d(new Private)
0036 {
0037     m_d->document = rhs.m_d->document;
0038     m_d->fakeOriginalDevice = new KisPaintDevice(*rhs.m_d->fakeOriginalDevice);
0039 }
0040 
0041 KisDecorationsWrapperLayer::~KisDecorationsWrapperLayer()
0042 {
0043 }
0044 
0045 void KisDecorationsWrapperLayer::setDocument(KisDocument *document)
0046 {
0047     m_d->document = document;
0048     KIS_SAFE_ASSERT_RECOVER(image() == document->image()) {
0049         setImage(document->image());
0050     }
0051 }
0052 
0053 KisDocument *KisDecorationsWrapperLayer::document() const
0054 {
0055     return m_d->document;
0056 }
0057 
0058 bool KisDecorationsWrapperLayer::allowAsChild(KisNodeSP) const
0059 {
0060     return false;
0061 }
0062 
0063 bool KisDecorationsWrapperLayer::accept(KisNodeVisitor &visitor)
0064 {
0065     return visitor.visit(this);
0066 }
0067 
0068 void KisDecorationsWrapperLayer::accept(KisProcessingVisitor &visitor, KisUndoAdapter *undoAdapter)
0069 {
0070     visitor.visit(this, undoAdapter);
0071 }
0072 
0073 KisNodeSP KisDecorationsWrapperLayer::clone() const {
0074     return new KisDecorationsWrapperLayer(*this);
0075 }
0076 
0077 KisPaintDeviceSP KisDecorationsWrapperLayer::original() const
0078 {
0079     return m_d->fakeOriginalDevice;
0080 }
0081 
0082 KisPaintDeviceSP KisDecorationsWrapperLayer::paintDevice() const
0083 {
0084     return 0;
0085 }
0086 
0087 bool KisDecorationsWrapperLayer::isFakeNode() const
0088 {
0089     return true;
0090 }
0091 
0092 bool KisDecorationsWrapperLayer::supportsPerspectiveTransform() const
0093 {
0094     return false;
0095 }
0096 
0097 void KisDecorationsWrapperLayer::setImage(KisImageWSP image)
0098 {
0099     m_d->fakeOriginalDevice->setDefaultBounds(new KisDefaultBounds(image));
0100     KisExternalLayer::setImage(image);
0101 }
0102 
0103 KUndo2Command *KisDecorationsWrapperLayer::crop(const QRect &rect)
0104 {
0105     return transform(QTransform::fromTranslate(-rect.x(), -rect.y()));
0106 }
0107 
0108 KUndo2Command *KisDecorationsWrapperLayer::transform(const QTransform &transform)
0109 {
0110     KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(m_d->document, 0);
0111 
0112     struct UndoCommand : public KUndo2Command
0113     {
0114         UndoCommand(KisDocument *document, const QTransform &transform)
0115             : m_document(document),
0116               m_transform(transform)
0117         {}
0118 
0119         void undo() override {
0120             doTransform(m_transform.inverted());
0121         }
0122 
0123         void redo() override {
0124             doTransform(m_transform);
0125         }
0126 
0127     private:
0128         void doTransform(const QTransform &transform) {
0129             const QTransform imageToDocument =
0130                 QTransform::fromScale(1 / m_document->image()->xRes(),
0131                                       1 / m_document->image()->yRes());
0132 
0133             KisGridConfig gridConfig = m_document->gridConfig();
0134             if (gridConfig.showGrid()) {
0135                 gridConfig.transform(transform);
0136                 m_document->setGridConfig(gridConfig);
0137             }
0138 
0139             KisGuidesConfig guidesConfig = m_document->guidesConfig();
0140             if (guidesConfig.hasGuides()) {
0141                 guidesConfig.transform(imageToDocument.inverted() * transform * imageToDocument);
0142                 m_document->setGuidesConfig(guidesConfig);
0143             }
0144 
0145             QList<KisPaintingAssistantSP> assistants = m_document->assistants();
0146             Q_FOREACH(KisPaintingAssistantSP assistant, assistants) {
0147                 assistant->transform(imageToDocument.inverted() * transform * imageToDocument);
0148             }
0149             m_document->setAssistants(assistants);
0150         }
0151 
0152     private:
0153         KisDocument *m_document;
0154         QTransform m_transform;
0155     };
0156 
0157     return new UndoCommand(m_d->document, transform);
0158 }