summaryrefslogtreecommitdiffstats
path: root/kolourpaint/pixmapfx/kpeffectinvert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kolourpaint/pixmapfx/kpeffectinvert.cpp')
-rw-r--r--kolourpaint/pixmapfx/kpeffectinvert.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/kolourpaint/pixmapfx/kpeffectinvert.cpp b/kolourpaint/pixmapfx/kpeffectinvert.cpp
new file mode 100644
index 00000000..b9bb00a8
--- /dev/null
+++ b/kolourpaint/pixmapfx/kpeffectinvert.cpp
@@ -0,0 +1,315 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <[email protected]>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_EFFECT_INVERT 0
+
+
+#include <kpeffectinvert.h>
+
+#include <qcheckbox.h>
+#include <qimage.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kppixmapfx.h>
+
+
+//
+// kpEffectInvertCommand
+//
+
+kpEffectInvertCommand::kpEffectInvertCommand (int channels,
+ bool actOnSelection,
+ kpMainWindow *mainWindow)
+ : kpColorEffectCommand (channels == RGB ?
+ i18n ("Invert Colors") : i18n ("Invert"),
+ actOnSelection, mainWindow),
+ m_channels (channels)
+{
+}
+
+kpEffectInvertCommand::kpEffectInvertCommand (bool actOnSelection,
+ kpMainWindow *mainWindow)
+ : kpColorEffectCommand (i18n ("Invert Colors"), actOnSelection, mainWindow),
+ m_channels (RGB)
+{
+}
+
+kpEffectInvertCommand::~kpEffectInvertCommand ()
+{
+}
+
+
+// public static
+void kpEffectInvertCommand::apply (QPixmap *destPixmapPtr, int channels)
+{
+ QImage image = kpPixmapFX::convertToImage (*destPixmapPtr);
+ apply (&image, channels);
+ *destPixmapPtr = kpPixmapFX::convertToPixmap (image);
+}
+
+// public static
+QPixmap kpEffectInvertCommand::apply (const QPixmap &pm, int channels)
+{
+ QImage image = kpPixmapFX::convertToImage (pm);
+ apply (&image, channels);
+ return kpPixmapFX::convertToPixmap (image);
+}
+
+// public static
+void kpEffectInvertCommand::apply (QImage *destImagePtr, int channels)
+{
+ QRgb mask = qRgba ((channels & Red) ? 0xFF : 0,
+ (channels & Green) ? 0xFF : 0,
+ (channels & Blue) ? 0xFF : 0,
+ 0/*don't invert alpha*/);
+#if DEBUG_KP_EFFECT_INVERT
+ kdDebug () << "kpEffectInvertCommand::apply(channels=" << channels
+ << ") mask=" << (int *) mask
+ << endl;
+#endif
+
+ if (destImagePtr->depth () > 8)
+ {
+ #if 0
+ // SYNC: TODO: Qt BUG - invertAlpha argument is inverted!!!
+ destImagePtr->invertPixels (true/*no invert alpha (Qt 3.2)*/);
+ #else
+ // Above version works for Qt 3.2 at least.
+ // But this version will always work (slower, though) and supports
+ // inverting particular channels.
+ for (int y = 0; y < destImagePtr->height (); y++)
+ {
+ for (int x = 0; x < destImagePtr->width (); x++)
+ {
+ destImagePtr->setPixel (x, y, destImagePtr->pixel (x, y) ^ mask);
+ }
+ }
+ #endif
+ }
+ else
+ {
+ for (int i = 0; i < destImagePtr->numColors (); i++)
+ {
+ destImagePtr->setColor (i, destImagePtr->color (i) ^ mask);
+ }
+ }
+}
+
+// public static
+QImage kpEffectInvertCommand::apply (const QImage &img, int channels)
+{
+ QImage retImage = img;
+ apply (&retImage, channels);
+ return retImage;
+}
+
+
+//
+// kpEffectInvertCommand implements kpColorEffectCommand interface
+//
+
+// protected virtual [base kpColorEffectCommand]
+QPixmap kpEffectInvertCommand::applyColorEffect (const QPixmap &pixmap)
+{
+ return apply (pixmap, m_channels);
+}
+
+
+//
+// kpEffectInvertWidget
+//
+
+kpEffectInvertWidget::kpEffectInvertWidget (bool actOnSelection,
+ kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name)
+ : kpColorEffectWidget (actOnSelection, mainWindow, parent, name)
+{
+ QVBoxLayout *topLevelLay = new QVBoxLayout (this, marginHint (), spacingHint ());
+
+
+ QWidget *centerWidget = new QWidget (this);
+ topLevelLay->addWidget (centerWidget, 0/*stretch*/, Qt::AlignCenter);
+
+
+ QVBoxLayout *centerWidgetLay = new QVBoxLayout (centerWidget,
+ 0/*margin*/,
+ spacingHint ());
+
+
+ m_redCheckBox = new QCheckBox (i18n ("&Red"), centerWidget);
+ m_greenCheckBox = new QCheckBox (i18n ("&Green"), centerWidget);
+ m_blueCheckBox = new QCheckBox (i18n ("&Blue"), centerWidget);
+
+ QWidget *spaceWidget = new QWidget (centerWidget);
+ spaceWidget->setFixedSize (1, spacingHint ());
+
+ m_allCheckBox = new QCheckBox (i18n ("&All"), centerWidget);
+
+
+ m_redCheckBox->setChecked (false);
+ m_greenCheckBox->setChecked (false);
+ m_blueCheckBox->setChecked (false);
+
+ m_allCheckBox->setChecked (false);
+
+
+ centerWidgetLay->addWidget (m_redCheckBox);
+ centerWidgetLay->addWidget (m_greenCheckBox);
+ centerWidgetLay->addWidget (m_blueCheckBox);
+
+ centerWidgetLay->addWidget (spaceWidget);
+
+ centerWidgetLay->addWidget (m_allCheckBox);
+
+
+ m_inSignalHandler = false;
+ connect (m_redCheckBox, SIGNAL (toggled (bool)),
+ this, SLOT (slotRGBCheckBoxToggled ()));
+ connect (m_greenCheckBox, SIGNAL (toggled (bool)),
+ this, SLOT (slotRGBCheckBoxToggled ()));
+ connect (m_blueCheckBox, SIGNAL (toggled (bool)),
+ this, SLOT (slotRGBCheckBoxToggled ()));
+
+ connect (m_allCheckBox, SIGNAL (toggled (bool)),
+ this, SLOT (slotAllCheckBoxToggled ()));
+}
+
+kpEffectInvertWidget::~kpEffectInvertWidget ()
+{
+}
+
+
+// public
+int kpEffectInvertWidget::channels () const
+{
+#if DEBUG_KP_EFFECT_INVERT
+ kdDebug () << "kpEffectInvertWidget::channels()"
+ << " isChecked: r=" << m_redCheckBox->isChecked ()
+ << " g=" << m_greenCheckBox->isChecked ()
+ << " b=" << m_blueCheckBox->isChecked ()
+ << endl;
+#endif
+
+ int channels = 0;
+
+
+ if (m_redCheckBox->isChecked ())
+ channels |= kpEffectInvertCommand::Red;
+
+ if (m_greenCheckBox->isChecked ())
+ channels |= kpEffectInvertCommand::Green;
+
+ if (m_blueCheckBox->isChecked ())
+ channels |= kpEffectInvertCommand::Blue;
+
+
+#if DEBUG_KP_EFFECT_INVERT
+ kdDebug () << "\treturning channels=" << (int *) channels << endl;
+#endif
+ return channels;
+}
+
+
+//
+// kpEffectInvertWidget implements kpColorEffectWidget interface
+//
+
+// public virtual [base kpColorEffectWidget]
+QString kpEffectInvertWidget::caption () const
+{
+ return i18n ("Channels");
+}
+
+
+// public virtual [base kpColorEffectWidget]
+bool kpEffectInvertWidget::isNoOp () const
+{
+ return (channels () == kpEffectInvertCommand::None);
+}
+
+// public virtual [base kpColorEffectWidget]
+QPixmap kpEffectInvertWidget::applyColorEffect (const QPixmap &pixmap)
+{
+ return kpEffectInvertCommand::apply (pixmap, channels ());
+}
+
+
+// public virtual [base kpColorEffectWidget]
+kpColorEffectCommand *kpEffectInvertWidget::createCommand () const
+{
+ return new kpEffectInvertCommand (channels (),
+ m_actOnSelection,
+ m_mainWindow);
+}
+
+
+// protected slots
+void kpEffectInvertWidget::slotRGBCheckBoxToggled ()
+{
+ if (m_inSignalHandler)
+ return;
+
+ m_inSignalHandler = true;
+
+ //blockSignals (true);
+ m_allCheckBox->setChecked (m_redCheckBox->isChecked () &&
+ m_blueCheckBox->isChecked () &&
+ m_greenCheckBox->isChecked ());
+ //blockSignals (false);
+
+ emit settingsChanged ();
+
+ m_inSignalHandler = false;
+}
+
+// protected slot
+void kpEffectInvertWidget::slotAllCheckBoxToggled ()
+{
+ if (m_inSignalHandler)
+ return;
+
+ m_inSignalHandler = true;
+
+ //blockSignals (true);
+ m_redCheckBox->setChecked (m_allCheckBox->isChecked ());
+ m_greenCheckBox->setChecked (m_allCheckBox->isChecked ());
+ m_blueCheckBox->setChecked (m_allCheckBox->isChecked ());
+ //blockSignals (false);
+
+ emit settingsChanged ();
+
+ m_inSignalHandler = false;
+}
+
+
+#include <kpeffectinvert.moc>
+