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 }