File indexing completed on 2024-12-22 04:07:28
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #define DEBUG_KP_TOOL_CROP 0 0030 0031 0032 #include "kpTransformCrop.h" 0033 #include "kpTransformCropPrivate.h" 0034 0035 #include "layers/selections/image/kpAbstractImageSelection.h" 0036 #include "environments/commands/kpCommandEnvironment.h" 0037 #include "commands/kpCommandHistory.h" 0038 #include "document/kpDocument.h" 0039 #include "imagelib/kpImage.h" 0040 #include "commands/kpMacroCommand.h" 0041 #include "mainWindow/kpMainWindow.h" 0042 #include "pixmapfx/kpPixmapFX.h" 0043 #include "commands/tools/selection/kpToolSelectionCreateCommand.h" 0044 #include "views/manager/kpViewManager.h" 0045 0046 0047 // See the "image selection" part of the kpTransformCrop() API Doc. 0048 // 0049 // REFACTOR: Move into commands/ 0050 class SetDocumentToSelectionImageCommand : public kpCommand 0051 { 0052 public: 0053 explicit SetDocumentToSelectionImageCommand (kpCommandEnvironment *environ); 0054 ~SetDocumentToSelectionImageCommand () override; 0055 0056 /* (uninteresting child of macro cmd) */ 0057 QString name () const override { return {}; } 0058 0059 kpCommandSize::SizeType size () const override 0060 { 0061 return ImageSize (m_oldImage) + 0062 SelectionSize (m_fromSelectionPtr) + 0063 ImageSize (m_imageIfFromSelectionDoesntHaveOne); 0064 } 0065 0066 // ASSUMPTION: Document has been resized to be the same size as the 0067 // selection. 0068 void execute () override; 0069 void unexecute () override; 0070 0071 protected: 0072 kpColor m_backgroundColor; 0073 kpImage m_oldImage; 0074 kpAbstractImageSelection *m_fromSelectionPtr; 0075 kpImage m_imageIfFromSelectionDoesntHaveOne; 0076 }; 0077 0078 0079 SetDocumentToSelectionImageCommand::SetDocumentToSelectionImageCommand (kpCommandEnvironment *environ) 0080 : kpCommand (environ), 0081 m_backgroundColor (environ->backgroundColor ()), 0082 m_fromSelectionPtr ( 0083 dynamic_cast <kpAbstractImageSelection *> ( 0084 environ->document ()->selection ()->clone ())) 0085 { 0086 Q_ASSERT (m_fromSelectionPtr); 0087 0088 if ( m_fromSelectionPtr ) // make coverity happy 0089 { 0090 m_imageIfFromSelectionDoesntHaveOne = 0091 m_fromSelectionPtr->hasContent () ? 0092 kpImage () : 0093 document ()->getSelectedBaseImage (); 0094 } 0095 } 0096 0097 //--------------------------------------------------------------------- 0098 0099 SetDocumentToSelectionImageCommand::~SetDocumentToSelectionImageCommand () 0100 { 0101 delete m_fromSelectionPtr; 0102 } 0103 0104 //--------------------------------------------------------------------- 0105 0106 // public virtual [base kpCommand] 0107 void SetDocumentToSelectionImageCommand::execute () 0108 { 0109 #if DEBUG_KP_TOOL_CROP 0110 qCDebug(kpLogImagelib) << "SetDocumentToSelectionImageCommand::execute()"; 0111 #endif 0112 0113 viewManager ()->setQueueUpdates (); 0114 { 0115 // kpTransformCrop_ImageSelection's <resizeDocCommand> has 0116 // executed, resizing the document to be the size of the selection 0117 // bounding rectangle. 0118 Q_ASSERT (document ()->width () == m_fromSelectionPtr->width ()); 0119 Q_ASSERT (document ()->height () == m_fromSelectionPtr->height ()); 0120 m_oldImage = document ()->image (); 0121 0122 0123 // 0124 // e.g. original elliptical selection: 0125 // 0126 // t/---\ T = original transparent selection pixel 0127 // | TT | t = outside the selection region 0128 // t\__/t [every other character] = original opaque selection pixel 0129 // 0130 // Afterwards, the _document_ image becomes: 0131 // 0132 // b/---\ T = [unchanged] 0133 // | TT | b = background color 0134 // b\__/b [every other character] = [unchanged] 0135 // 0136 // The selection is deleted. 0137 // 0138 // TODO: Do not introduce a mask if the result will not contain 0139 // any transparent pixels. 0140 // 0141 0142 QImage newDocImage(document()->width(), document()->height(), QImage::Format_ARGB32_Premultiplied); 0143 newDocImage.fill(m_backgroundColor.toQRgb()); 0144 0145 #if DEBUG_KP_TOOL_CROP 0146 qCDebug(kpLogImagelib) << "\tsel: rect=" << m_fromSelectionPtr->boundingRect () 0147 << " pm=" << m_fromSelectionPtr->hasContent (); 0148 #endif 0149 QImage setTransparentImage; 0150 0151 if (m_fromSelectionPtr->hasContent ()) 0152 { 0153 setTransparentImage = m_fromSelectionPtr->transparentImage (); 0154 0155 #if DEBUG_KP_TOOL_CROP 0156 qCDebug(kpLogImagelib) << "\thave pixmap; rect=" 0157 << setTransparentImage.rect (); 0158 #endif 0159 } 0160 else 0161 { 0162 setTransparentImage = m_imageIfFromSelectionDoesntHaveOne; 0163 #if DEBUG_KP_TOOL_CROP 0164 qCDebug(kpLogImagelib) << "\tno pixmap in sel - get it; rect=" 0165 << setTransparentImage.rect (); 0166 #endif 0167 } 0168 0169 kpPixmapFX::paintPixmapAt (&newDocImage, 0170 QPoint (0, 0), 0171 setTransparentImage); 0172 0173 0174 document ()->setImageAt (newDocImage, QPoint (0, 0)); 0175 document ()->selectionDelete (); 0176 0177 0178 environ ()->somethingBelowTheCursorChanged (); 0179 } 0180 viewManager ()->restoreQueueUpdates (); 0181 } 0182 0183 //--------------------------------------------------------------------- 0184 0185 // public virtual [base kpCommand] 0186 void SetDocumentToSelectionImageCommand::unexecute () 0187 { 0188 #if DEBUG_KP_TOOL_CROP 0189 qCDebug(kpLogImagelib) << "SetDocumentToSelectionImageCommand::unexecute()"; 0190 #endif 0191 0192 viewManager ()->setQueueUpdates (); 0193 { 0194 document ()->setImageAt (m_oldImage, QPoint (0, 0)); 0195 m_oldImage = kpImage (); 0196 0197 #if DEBUG_KP_TOOL_CROP 0198 qCDebug(kpLogImagelib) << "\tsel: rect=" << m_fromSelectionPtr->boundingRect () 0199 << " pm=" << m_fromSelectionPtr->hasContent (); 0200 #endif 0201 document ()->setSelection (*m_fromSelectionPtr); 0202 0203 environ ()->somethingBelowTheCursorChanged (); 0204 } 0205 viewManager ()->restoreQueueUpdates (); 0206 } 0207 0208 //--------------------------------------------------------------------- 0209 0210 0211 void kpTransformCrop_ImageSelection (kpMainWindow *mainWindow, 0212 const QString &commandName, kpCommand *resizeDocCommand) 0213 { 0214 // Save starting selection, minus the border. 0215 auto *borderImageSel = dynamic_cast <kpAbstractImageSelection *> ( 0216 mainWindow->document ()->selection ()->clone ()); 0217 0218 Q_ASSERT (borderImageSel); 0219 0220 if ( !borderImageSel ) { // make coverity happy 0221 return; 0222 } 0223 0224 // (only interested in border) 0225 borderImageSel->deleteContent (); 0226 borderImageSel->moveTo (QPoint (0, 0)); 0227 0228 auto *environ = mainWindow->commandEnvironment (); 0229 auto *macroCmd = new kpMacroCommand (commandName, environ); 0230 0231 // (must resize doc _before_ SetDocumentToSelectionImageCommand in case 0232 // doc needs to gets bigger - else selection image may not fit) 0233 macroCmd->addCommand (resizeDocCommand); 0234 0235 #if DEBUG_KP_TOOL_CROP 0236 qCDebug(kpLogImagelib) << "\tis pixmap sel"; 0237 qCDebug(kpLogImagelib) << "\tcreating SetImage cmd"; 0238 #endif 0239 macroCmd->addCommand (new SetDocumentToSelectionImageCommand (environ)); 0240 0241 0242 mainWindow->addImageOrSelectionCommand ( 0243 macroCmd, 0244 true/*add create cmd*/, 0245 false/*don't add pull cmd*/); 0246 0247 0248 // Add selection border back for convenience. 0249 mainWindow->commandHistory ()->addCommand ( 0250 new kpToolSelectionCreateCommand ( 0251 i18n ("Selection: Create"), 0252 *borderImageSel, 0253 mainWindow->commandEnvironment ())); 0254 0255 0256 delete borderImageSel; 0257 }