summaryrefslogtreecommitdiffstats
path: root/krita/plugins/viewplugins/dropshadow
diff options
context:
space:
mode:
Diffstat (limited to 'krita/plugins/viewplugins/dropshadow')
-rw-r--r--krita/plugins/viewplugins/dropshadow/Makefile.am30
-rw-r--r--krita/plugins/viewplugins/dropshadow/dlg_dropshadow.cc117
-rw-r--r--krita/plugins/viewplugins/dropshadow/dlg_dropshadow.h59
-rw-r--r--krita/plugins/viewplugins/dropshadow/dropshadow.rc11
-rw-r--r--krita/plugins/viewplugins/dropshadow/kis_dropshadow.cc758
-rw-r--r--krita/plugins/viewplugins/dropshadow/kis_dropshadow.h71
-rw-r--r--krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc91
-rw-r--r--krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h45
-rw-r--r--krita/plugins/viewplugins/dropshadow/kritadropshadow.desktop39
-rw-r--r--krita/plugins/viewplugins/dropshadow/wdg_dropshadow.ui235
10 files changed, 1456 insertions, 0 deletions
diff --git a/krita/plugins/viewplugins/dropshadow/Makefile.am b/krita/plugins/viewplugins/dropshadow/Makefile.am
new file mode 100644
index 00000000..c339627e
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/Makefile.am
@@ -0,0 +1,30 @@
+kritarcdir = $(kde_datadir)/kritaplugins
+kritarc_DATA = dropshadow.rc
+EXTRA_DIST = $(kritarc_DATA)
+
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../kritacolor/ \
+ -I$(srcdir)/../../../colorspaces/rgb_u8 \
+ -I$(srcdir)/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+
+kde_module_LTLIBRARIES = kritadropshadow.la
+
+kritadropshadow_la_SOURCES = wdg_dropshadow.ui \
+ kis_dropshadow.cc dlg_dropshadow.cc \
+ kis_dropshadow_plugin.cc
+
+noinst_HEADERS = wdg_dropshadow.h kis_dropshadow_plugin.h \
+ kis_dropshadow.h dlg_dropshadow.h
+
+kritadropshadow_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
+kritadropshadow_la_LIBADD = ../../../libkritacommon.la ../../../colorspaces/rgb_u8/libkritargb.la
+
+kde_services_DATA = kritadropshadow.desktop
+
+kritadropshadow_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
diff --git a/krita/plugins/viewplugins/dropshadow/dlg_dropshadow.cc b/krita/plugins/viewplugins/dropshadow/dlg_dropshadow.cc
new file mode 100644
index 00000000..545f886f
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/dlg_dropshadow.cc
@@ -0,0 +1,117 @@
+/*
+ * dlg_dropshadow.cc - part of KimageShop^WKrayon^WKrita
+ *
+ * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qbutton.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qcolor.h>
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qslider.h>
+
+#include <kcolorbutton.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+#include "dlg_dropshadow.h"
+#include "wdg_dropshadow.h"
+
+DlgDropshadow::DlgDropshadow( const QString & /*imageCS*/,
+ const QString & /*layerCS*/,
+ QWidget * parent,
+ const char * name)
+ : super (parent, name, true, i18n("Drop Shadow"), Ok | Cancel, Ok)
+{
+ m_page = new WdgDropshadow(this, "dropshadow");
+ Q_CHECK_PTR(m_page);
+ setMainWidget(m_page);
+ resize(m_page->sizeHint());
+
+ KConfig * cfg = KGlobal::config();
+ m_page->xOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_x", 8) );
+ m_page->yOffsetSpinBox->setValue( cfg->readNumEntry("dropshadow_y", 8) );
+ m_page->blurRadiusSpinBox->setValue( cfg->readNumEntry("dropshadow_blurRadius", 5) );
+ QColor black(0,0,0);
+ m_page->shadowColorButton->setColor( cfg->readColorEntry("dropshadow_color", &black) );
+ m_page->opacitySlider->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) );
+ m_page->opacitySpinBox->setValue( cfg->readNumEntry("dropshadow_opacity", 80 ) );
+ m_page->allowResizingCheckBox->setChecked( cfg->readBoolEntry("dropshadow_resizing", true ) );
+
+ connect(this, SIGNAL(okClicked()),
+ this, SLOT(okClicked()));
+}
+
+DlgDropshadow::~DlgDropshadow()
+{
+ delete m_page;
+}
+
+Q_INT32 DlgDropshadow::getXOffset()
+{
+ return m_page->xOffsetSpinBox->value();
+}
+
+Q_INT32 DlgDropshadow::getYOffset()
+{
+ return m_page->yOffsetSpinBox->value();
+}
+
+Q_INT32 DlgDropshadow::getBlurRadius()
+{
+ return m_page->blurRadiusSpinBox->value();
+}
+
+Q_UINT8 DlgDropshadow::getShadowOpacity()
+{
+ double opacity = (double)m_page->opacitySpinBox->value();
+ //convert percent to a 8 bit opacity value
+ return (Q_UINT8)(opacity / 100 * 255);
+}
+
+QColor DlgDropshadow::getShadowColor()
+{
+ return m_page->shadowColorButton->color();
+}
+
+bool DlgDropshadow::allowResizingChecked()
+{
+ return m_page->allowResizingCheckBox->isChecked();
+}
+
+// SLOTS
+
+void DlgDropshadow::okClicked()
+{
+ KConfig * cfg = KGlobal::config();
+ cfg->writeEntry("dropshadow_x", m_page->xOffsetSpinBox->value());
+ cfg->writeEntry("dropshadow_y", m_page->yOffsetSpinBox->value());
+ cfg->writeEntry("dropshadow_blurRadius", m_page->blurRadiusSpinBox->value());
+ cfg->writeEntry("dropshadow_color", m_page->shadowColorButton->color());
+ cfg->writeEntry("dropshadow_opacity", m_page->opacitySpinBox->value());
+ cfg->writeEntry("dropshadow_resizing", m_page->allowResizingCheckBox->isChecked());
+
+ accept();
+}
+
+#include "dlg_dropshadow.moc"
diff --git a/krita/plugins/viewplugins/dropshadow/dlg_dropshadow.h b/krita/plugins/viewplugins/dropshadow/dlg_dropshadow.h
new file mode 100644
index 00000000..8e514658
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/dlg_dropshadow.h
@@ -0,0 +1,59 @@
+/*
+ * dlg_dropshadow.h -- part of KimageShop^WKrayon^WKrita
+ *
+ * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef DLG_DROPSHADOW
+#define DLG_DROPSHADOW
+
+#include <kdialogbase.h>
+#include <kis_dropshadow.h>
+
+class WdgDropshadow;
+class QColor;
+
+/**
+ * This dialog allows the user to configure the decomposition of an image
+ * into layers: one layer for each color channel.
+ */
+class DlgDropshadow: public KDialogBase {
+ typedef KDialogBase super;
+ Q_OBJECT
+
+public:
+
+ DlgDropshadow(const QString & imageCS, const QString & layerCS, QWidget * parent = 0,
+ const char* name = 0);
+ ~DlgDropshadow();
+
+public:
+
+ Q_INT32 getXOffset();
+ Q_INT32 getYOffset();
+ Q_INT32 getBlurRadius();
+ Q_UINT8 getShadowOpacity();
+ QColor getShadowColor();
+ bool allowResizingChecked();
+private slots:
+ void okClicked();
+
+private:
+
+ WdgDropshadow * m_page;
+};
+
+#endif // DLG_DROPSHADOW
diff --git a/krita/plugins/viewplugins/dropshadow/dropshadow.rc b/krita/plugins/viewplugins/dropshadow/dropshadow.rc
new file mode 100644
index 00000000..e5a446b2
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/dropshadow.rc
@@ -0,0 +1,11 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui library="kritadropshadow" version="6">
+<MenuBar>
+ <Menu name="Layer"><text>La&amp;yer</text>
+ <Separator/>
+ <Menu name="layerEffects"><text>Layer Effects</text>
+ <Action name="dropshadow"/>
+ </Menu>
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/krita/plugins/viewplugins/dropshadow/kis_dropshadow.cc b/krita/plugins/viewplugins/dropshadow/kis_dropshadow.cc
new file mode 100644
index 00000000..7881f568
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/kis_dropshadow.cc
@@ -0,0 +1,758 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * The gaussian blur algoithm is ported from gimo
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <limits.h>
+
+#include <stdlib.h>
+#include <vector>
+
+#include <qcolor.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+#include <knuminput.h>
+
+#include <kis_doc.h>
+#include <kis_image.h>
+#include <kis_iterators_pixel.h>
+#include <kis_layer.h>
+#include <kis_paint_layer.h>
+#include <kis_group_layer.h>
+#include "kis_meta_registry.h"
+#include <kis_transaction.h>
+#include <kis_undo_adapter.h>
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_progress_subject.h>
+#include <kis_progress_display_interface.h>
+#include <kis_colorspace.h>
+#include <kis_colorspace_factory_registry.h>
+#include <kis_view.h>
+#include <kis_paint_device.h>
+#include <kis_channelinfo.h>
+#include <kis_convolution_painter.h>
+#include "kis_rgb_colorspace.h"
+
+#include "kis_dropshadow.h"
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+KisDropshadow::KisDropshadow(KisView * view)
+ : m_view(view)
+{
+}
+
+void KisDropshadow::dropshadow(KisProgressDisplayInterface * progress, Q_INT32 xoffset, Q_INT32 yoffset, Q_INT32 blurradius, QColor color, Q_UINT8 opacity, bool allowResize)
+{
+ KisImageSP image = m_view->canvasSubject()->currentImg();
+ if (!image) return;
+
+ KisLayerSP src = image->activeLayer();
+ if (!src) return;
+
+ KisPaintDeviceSP dev = image->activeDevice();
+ if (!dev) return;
+
+ m_cancelRequested = false;
+ if ( progress )
+ progress->setSubject(this, true, true);
+ emit notifyProgressStage(i18n("Add drop shadow..."), 0);
+
+ if (image->undo()) {
+ image->undoAdapter()->beginMacro(i18n("Add Drop Shadow"));
+ }
+
+ KisPaintDeviceSP shadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "Shadow");
+ KisPaintDeviceSP bShadowDev;
+ KisRgbColorSpace *rgb8cs = static_cast<KisRgbColorSpace *>(shadowDev->colorSpace());
+
+ QRect rect = dev->exactBounds();
+
+ for (Q_INT32 row = 0; row < rect.height(); ++row)
+ {
+ KisHLineIteratorPixel srcIt = dev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), false);
+ KisHLineIteratorPixel dstIt = shadowDev->createHLineIterator(rect.x(), rect.y() + row, rect.width(), true);
+ while( ! srcIt.isDone() )
+ {
+ if (srcIt.isSelected())
+ {
+ //set the shadow color
+ Q_UINT8 alpha = dev->colorSpace()->getAlpha(srcIt.rawData());
+ rgb8cs->setPixel(dstIt.rawData(), color.red(), color.green(), color.blue(), alpha);
+ }
+ ++srcIt;
+ ++dstIt;
+ }
+ emit notifyProgress((row * 100) / rect.height() );
+ }
+
+ if( blurradius > 0 )
+ {
+ bShadowDev = new KisPaintDevice( KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA",""),"" ), "bShadow");
+ gaussianblur(shadowDev, bShadowDev, rect, blurradius, blurradius, BLUR_RLE, progress);
+ shadowDev = bShadowDev;
+ }
+
+ if (!m_cancelRequested) {
+ shadowDev->move (xoffset,yoffset);
+
+ KisGroupLayerSP parent = image->rootLayer();
+ if (image->activeLayer())
+ parent = image->activeLayer()->parent().data();
+
+ KisPaintLayerSP l = new KisPaintLayer(image, i18n("Drop Shadow"), opacity, shadowDev);
+ image->addLayer( l.data(), parent, src->siblingBelow() );
+
+ if (allowResize)
+ {
+ QRect shadowBounds = shadowDev->exactBounds();
+
+ if (!image->bounds().contains(shadowBounds)) {
+
+ QRect newImageSize = image->bounds() | shadowBounds;
+ image->resize(newImageSize.width(), newImageSize.height());
+
+ if (shadowBounds.left() < 0 || shadowBounds.top() < 0) {
+
+ Q_INT32 newRootX = image->rootLayer()->x();
+ Q_INT32 newRootY = image->rootLayer()->y();
+
+ if (shadowBounds.left() < 0) {
+ newRootX += -shadowBounds.left();
+ }
+ if (shadowBounds.top() < 0) {
+ newRootY += -shadowBounds.top();
+ }
+
+ KCommand *moveCommand = image->rootLayer()->moveCommand(QPoint(image->rootLayer()->x(), image->rootLayer()->y()),
+ QPoint(newRootX, newRootY));
+ Q_ASSERT(moveCommand != 0);
+
+ if (moveCommand) {
+ moveCommand->execute();
+ if (image->undo()) {
+ image->undoAdapter()->addCommand(moveCommand);
+ } else {
+ delete moveCommand;
+ }
+ }
+ }
+ }
+ }
+ m_view->canvasSubject()->document()->setModified(true);
+ }
+
+ if (image->undo()) {
+ image->undoAdapter()->endMacro();
+ }
+
+ emit notifyProgressDone();
+}
+
+void KisDropshadow::gaussianblur (KisPaintDeviceSP srcDev, KisPaintDeviceSP dstDev, QRect& rect, double horz, double vert, BlurMethod method, KisProgressDisplayInterface *)
+{
+ Q_INT32 width, height;
+ Q_INT32 bytes;
+ Q_UINT8 *dest, *dp;
+ Q_UINT8 *src, *sp, *sp_p, *sp_m;
+ Q_INT32 *buf = NULL;
+ Q_INT32 *bb;
+ double n_p[5], n_m[5];
+ double d_p[5], d_m[5];
+ double bd_p[5], bd_m[5];
+ double *val_p = NULL;
+ double *val_m = NULL;
+ double *vp, *vm;
+ Q_INT32 x1, y1, x2, y2;
+ Q_INT32 i, j;
+ Q_INT32 row, col, b;
+ Q_INT32 terms;
+ double progress, max_progress;
+ Q_INT32 initial_p[4];
+ Q_INT32 initial_m[4];
+ double std_dev;
+ Q_INT32 pixels;
+ Q_INT32 total = 1;
+ Q_INT32 start, end;
+ Q_INT32 *curve;
+ Q_INT32 *sum = NULL;
+ Q_INT32 val;
+ Q_INT32 length;
+ Q_INT32 initial_pp, initial_mm;
+
+ x1 = (Q_INT32)(rect.x() - horz);
+ y1 = (Q_INT32)(rect.y() - vert);
+ width = (Q_INT32)(rect.width() + 2 * horz);
+ height = (Q_INT32)(rect.height() + 2 * vert);
+ x2 = x1 + width;
+ y2 = y1 + height;
+
+ if (width < 1 || height < 1) return;
+
+ emit notifyProgressStage(i18n("Blur..."), 0);
+
+ bytes = srcDev->pixelSize();
+
+ switch (method)
+ {
+ case BLUR_IIR:
+ val_p = new double[MAX (width, height) * bytes];
+ val_m = new double[MAX (width, height) * bytes];
+ break;
+
+ case BLUR_RLE:
+ buf = new Q_INT32[MAX (width, height) * 2];
+ break;
+ }
+
+ src = new Q_UINT8[MAX (width, height) * bytes];
+ dest = new Q_UINT8[MAX (width, height) * bytes];
+
+ progress = 0.0;
+ max_progress = (horz <= 0.0 ) ? 0 : width * height * horz;
+ max_progress += (vert <= 0.0 ) ? 0 : width * height * vert;
+
+
+ /* First the vertical pass */
+ if (vert > 0.0)
+ {
+ vert = fabs (vert) + 1.0;
+ std_dev = sqrt (-(vert * vert) / (2 * log (1.0 / 255.0)));
+
+ switch (method)
+ {
+ case BLUR_IIR:
+ /* derive the constants for calculating the gaussian
+ * from the std dev
+ */
+ find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
+ break;
+
+ case BLUR_RLE:
+ curve = make_curve (std_dev, &length);
+ sum = new Q_INT32[2 * length + 1];
+
+ sum[0] = 0;
+
+ for (i = 1; i <= length*2; i++)
+ sum[i] = curve[i-length-1] + sum[i-1];
+ sum += length;
+
+ total = sum[length] - sum[-length];
+ break;
+ }
+
+ for (col = 0; col < width; col++)
+ {
+ switch (method)
+ {
+ case BLUR_IIR:
+ memset (val_p, 0, height * bytes * sizeof (double));
+ memset (val_m, 0, height * bytes * sizeof (double));
+ break;
+
+ case BLUR_RLE:
+ break;
+ }
+
+ //gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, height);
+ srcDev->readBytes(src, col+x1, y1, 1, height);
+
+ multiply_alpha (src, height, bytes);
+
+ switch (method)
+ {
+ case BLUR_IIR:
+ sp_p = src;
+ sp_m = src + (height - 1) * bytes;
+ vp = val_p;
+ vm = val_m + (height - 1) * bytes;
+
+ /* Set up the first vals */
+ for (i = 0; i < bytes; i++)
+ {
+ initial_p[i] = sp_p[i];
+ initial_m[i] = sp_m[i];
+ }
+
+ for (row = 0; row < height; row++)
+ {
+ double *vpptr, *vmptr;
+ terms = (row < 4) ? row : 4;
+
+ for (b = 0; b < bytes; b++)
+ {
+ vpptr = vp + b; vmptr = vm + b;
+ for (i = 0; i <= terms; i++)
+ {
+ *vpptr += n_p[i] * sp_p[(-i * bytes) + b] -
+ d_p[i] * vp[(-i * bytes) + b];
+ *vmptr += n_m[i] * sp_m[(i * bytes) + b] -
+ d_m[i] * vm[(i * bytes) + b];
+ }
+ for (j = i; j <= 4; j++)
+ {
+ *vpptr += (n_p[j] - bd_p[j]) * initial_p[b];
+ *vmptr += (n_m[j] - bd_m[j]) * initial_m[b];
+ }
+ }
+
+ sp_p += bytes;
+ sp_m -= bytes;
+ vp += bytes;
+ vm -= bytes;
+ }
+
+ transfer_pixels (val_p, val_m, dest, bytes, height);
+ break;
+
+ case BLUR_RLE:
+ sp = src;
+ dp = dest;
+
+ for (b = 0; b < bytes; b++)
+ {
+ initial_pp = sp[b];
+ initial_mm = sp[(height-1) * bytes + b];
+
+ /* Determine a run-length encoded version of the row */
+ run_length_encode (sp + b, buf, bytes, height);
+
+ for (row = 0; row < height; row++)
+ {
+ start = (row < length) ? -row : -length;
+ end = (height <= (row + length) ?
+ (height - row - 1) : length);
+
+ val = 0;
+ i = start;
+ bb = buf + (row + i) * 2;
+
+ if (start != -length)
+ val += initial_pp * (sum[start] - sum[-length]);
+
+ while (i < end)
+ {
+ pixels = bb[0];
+ i += pixels;
+ if (i > end)
+ i = end;
+ val += bb[1] * (sum[i] - sum[start]);
+ bb += (pixels * 2);
+ start = i;
+ }
+
+ if (end != length)
+ val += initial_mm * (sum[length] - sum[end]);
+
+ dp[row * bytes + b] = val / total;
+ }
+ }
+ break;
+ }
+
+ separate_alpha (src, height, bytes);
+
+ dstDev->writeBytes(dest, col + x1, y1, 1, height);
+
+ progress += height * vert;
+ if ((col % 5) == 0) emit notifyProgress( (Q_UINT32)((progress * 100) / max_progress));
+ }
+ }
+
+ /* Now the horizontal pass */
+ if (horz > 0.0)
+ {
+ horz = fabs (horz) + 1.0;
+
+ if (horz != vert)
+ {
+ std_dev = sqrt (-(horz * horz) / (2 * log (1.0 / 255.0)));
+
+ switch (method)
+ {
+ case BLUR_IIR:
+ /* derive the constants for calculating the gaussian
+ * from the std dev
+ */
+ find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
+ break;
+
+ case BLUR_RLE:
+ curve = make_curve (std_dev, &length);
+ sum = new Q_INT32[2 * length + 1];
+
+ sum[0] = 0;
+
+ for (i = 1; i <= length*2; i++)
+ sum[i] = curve[i-length-1] + sum[i-1];
+ sum += length;
+
+ total = sum[length] - sum[-length];
+ break;
+ }
+ }
+
+ for (row = 0; row < height; row++)
+ {
+ switch (method)
+ {
+ case BLUR_IIR:
+ memset (val_p, 0, width * bytes * sizeof (double));
+ memset (val_m, 0, width * bytes * sizeof (double));
+ break;
+
+ case BLUR_RLE:
+ break;
+ }
+
+
+ //gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, width);
+ dstDev->readBytes(src, x1, row + y1, width, 1);
+
+ multiply_alpha (dest, width, bytes);
+
+ switch (method)
+ {
+ case BLUR_IIR:
+ sp_p = src;
+ sp_m = src + (width - 1) * bytes;
+ vp = val_p;
+ vm = val_m + (width - 1) * bytes;
+
+ /* Set up the first vals */
+ for (i = 0; i < bytes; i++)
+ {
+ initial_p[i] = sp_p[i];
+ initial_m[i] = sp_m[i];
+ }
+
+ for (col = 0; col < width; col++)
+ {
+ double *vpptr, *vmptr;
+ terms = (col < 4) ? col : 4;
+
+ for (b = 0; b < bytes; b++)
+ {
+ vpptr = vp + b; vmptr = vm + b;
+ for (i = 0; i <= terms; i++)
+ {
+ *vpptr += n_p[i] * sp_p[(-i * bytes) + b] -
+ d_p[i] * vp[(-i * bytes) + b];
+ *vmptr += n_m[i] * sp_m[(i * bytes) + b] -
+ d_m[i] * vm[(i * bytes) + b];
+ }
+ for (j = i; j <= 4; j++)
+ {
+ *vpptr += (n_p[j] - bd_p[j]) * initial_p[b];
+ *vmptr += (n_m[j] - bd_m[j]) * initial_m[b];
+ }
+ }
+
+ sp_p += bytes;
+ sp_m -= bytes;
+ vp += bytes;
+ vm -= bytes;
+ }
+
+ transfer_pixels (val_p, val_m, dest, bytes, width);
+ break;
+
+ case BLUR_RLE:
+ sp = src;
+ dp = dest;
+
+ for (b = 0; b < bytes; b++)
+ {
+ initial_pp = sp[b];
+ initial_mm = sp[(width-1) * bytes + b];
+
+ /* Determine a run-length encoded version of the row */
+ run_length_encode (sp + b, buf, bytes, width);
+
+ for (col = 0; col < width; col++)
+ {
+ start = (col < length) ? -col : -length;
+ end = (width <= (col + length)) ? (width - col - 1) : length;
+
+ val = 0;
+ i = start;
+ bb = buf + (col + i) * 2;
+
+ if (start != -length)
+ val += initial_pp * (sum[start] - sum[-length]);
+
+ while (i < end)
+ {
+ pixels = bb[0];
+ i += pixels;
+ if (i > end)
+ i = end;
+ val += bb[1] * (sum[i] - sum[start]);
+ bb += (pixels * 2);
+ start = i;
+ }
+
+ if (end != length)
+ val += initial_mm * (sum[length] - sum[end]);
+
+ dp[col * bytes + b] = val / total;
+ }
+ }
+ break;
+ }
+
+ separate_alpha (dest, width, bytes);
+
+ //gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, width);
+ dstDev->writeBytes(dest, x1, row + y1, width, 1);
+
+ progress += width * horz;
+ //if ((row % 5) == 0) gimp_progress_update (progress / max_progress);
+ if ((row % 5) == 0) emit notifyProgress( (Q_UINT32)((progress * 100) / max_progress ));
+ }
+ }
+
+ /* free up buffers */
+ switch (method)
+ {
+ case BLUR_IIR:
+ delete[] val_p;
+ delete[] val_m;
+ break;
+
+ case BLUR_RLE:
+ delete[] buf;
+ break;
+ }
+
+ delete[] src;
+ delete[] dest;
+}
+
+void KisDropshadow::find_constants (double n_p[], double n_m[], double d_p[], double d_m[], double bd_p[], double bd_m[], double std_dev)
+{
+ Q_INT32 i;
+ double constants [8];
+ double div;
+
+ /* The constants used in the implemenation of a casual sequence
+ * using a 4th order approximation of the gaussian operator
+ */
+
+ div = sqrt(2 * M_PI) * std_dev;
+ constants [0] = -1.783 / std_dev;
+ constants [1] = -1.723 / std_dev;
+ constants [2] = 0.6318 / std_dev;
+ constants [3] = 1.997 / std_dev;
+ constants [4] = 1.6803 / div;
+ constants [5] = 3.735 / div;
+ constants [6] = -0.6803 / div;
+ constants [7] = -0.2598 / div;
+
+ n_p [0] = constants[4] + constants[6];
+ n_p [1] = exp (constants[1]) *
+ (constants[7] * sin (constants[3]) -
+ (constants[6] + 2 * constants[4]) * cos (constants[3])) +
+ exp (constants[0]) *
+ (constants[5] * sin (constants[2]) -
+ (2 * constants[6] + constants[4]) * cos (constants[2]));
+ n_p [2] = 2 * exp (constants[0] + constants[1]) *
+ ((constants[4] + constants[6]) * cos (constants[3]) * cos (constants[2]) -
+ constants[5] * cos (constants[3]) * sin (constants[2]) -
+ constants[7] * cos (constants[2]) * sin (constants[3])) +
+ constants[6] * exp (2 * constants[0]) +
+ constants[4] * exp (2 * constants[1]);
+ n_p [3] = exp (constants[1] + 2 * constants[0]) *
+ (constants[7] * sin (constants[3]) - constants[6] * cos (constants[3])) +
+ exp (constants[0] + 2 * constants[1]) *
+ (constants[5] * sin (constants[2]) - constants[4] * cos (constants[2]));
+ n_p [4] = 0.0;
+
+ d_p [0] = 0.0;
+ d_p [1] = -2 * exp (constants[1]) * cos (constants[3]) -
+ 2 * exp (constants[0]) * cos (constants[2]);
+ d_p [2] = 4 * cos (constants[3]) * cos (constants[2]) * exp (constants[0] + constants[1]) +
+ exp (2 * constants[1]) + exp (2 * constants[0]);
+ d_p [3] = -2 * cos (constants[2]) * exp (constants[0] + 2 * constants[1]) -
+ 2 * cos (constants[3]) * exp (constants[1] + 2 * constants[0]);
+ d_p [4] = exp (2 * constants[0] + 2 * constants[1]);
+
+ for (i = 0; i <= 4; i++)
+ d_m [i] = d_p [i];
+
+ n_m[0] = 0.0;
+ for (i = 1; i <= 4; i++)
+ n_m [i] = n_p[i] - d_p[i] * n_p[0];
+
+ {
+ double sum_n_p, sum_n_m, sum_d;
+ double a, b;
+
+ sum_n_p = 0.0;
+ sum_n_m = 0.0;
+ sum_d = 0.0;
+ for (i = 0; i <= 4; i++)
+ {
+ sum_n_p += n_p[i];
+ sum_n_m += n_m[i];
+ sum_d += d_p[i];
+ }
+
+ a = sum_n_p / (1.0 + sum_d);
+ b = sum_n_m / (1.0 + sum_d);
+
+ for (i = 0; i <= 4; i++)
+ {
+ bd_p[i] = d_p[i] * a;
+ bd_m[i] = d_m[i] * b;
+ }
+ }
+}
+
+
+void KisDropshadow::transfer_pixels (double *src1, double *src2, Q_UINT8 *dest, Q_INT32 bytes, Q_INT32 width)
+{
+ Q_INT32 b;
+ Q_INT32 bend = bytes * width;
+ double sum;
+
+ for(b = 0; b < bend; b++)
+ {
+ sum = *src1++ + *src2++;
+ if (sum > 255) sum = 255;
+ else if(sum < 0) sum = 0;
+
+ *dest++ = (Q_UINT8) sum;
+ }
+}
+
+//The equations: g(r) = exp (- r^2 / (2 * sigma^2)), r = sqrt (x^2 + y ^2)
+Q_INT32 * KisDropshadow::make_curve(double sigma, Q_INT32 *length)
+{
+ int *curve;
+ double sigma2;
+ double l;
+ int temp;
+ int i, n;
+
+ sigma2 = 2 * sigma * sigma;
+ l = sqrt (-sigma2 * log (1.0 / 255.0));
+
+ n = (int)(ceil (l) * 2);
+ if ((n % 2) == 0)
+ n += 1;
+
+ curve = new Q_INT32[n];
+
+ *length = n / 2;
+ curve += *length;
+ curve[0] = 255;
+
+ for (i = 1; i <= *length; i++)
+ {
+ temp = (Q_INT32) (exp (- (i * i) / sigma2) * 255);
+ curve[-i] = temp;
+ curve[i] = temp;
+ }
+
+ return curve;
+}
+
+void KisDropshadow::run_length_encode (Q_UINT8 *src, Q_INT32 *dest, Q_INT32 bytes, Q_INT32 width)
+{
+ Q_INT32 start;
+ Q_INT32 i;
+ Q_INT32 j;
+ Q_UINT8 last;
+
+ last = *src;
+ src += bytes;
+ start = 0;
+
+ for (i = 1; i < width; i++)
+ {
+ if (*src != last)
+ {
+ for (j = start; j < i; j++)
+ {
+ *dest++ = (i - j);
+ *dest++ = last;
+ }
+ start = i;
+ last = *src;
+ }
+ src += bytes;
+ }
+
+ for (j = start; j < i; j++)
+ {
+ *dest++ = (i - j);
+ *dest++ = last;
+ }
+}
+
+void KisDropshadow::multiply_alpha (Q_UINT8 *buf, Q_INT32 width, Q_INT32 bytes)
+{
+ Q_INT32 i, j;
+ double alpha;
+
+ for (i = 0; i < width * bytes; i += bytes)
+ {
+ alpha = buf[i + bytes - 1] * (1.0 / 255.0);
+ for (j = 0; j < bytes - 1; j++) {
+ double a = (double)(buf[i + j]) * alpha;
+ buf[i + j] = (Q_UINT8)a;
+ }
+ }
+}
+
+void KisDropshadow::separate_alpha (Q_UINT8 *buf, Q_INT32 width, Q_INT32 bytes)
+{
+ Q_INT32 i, j;
+ Q_UINT8 alpha;
+ double recip_alpha;
+ Q_UINT32 new_val;
+
+ for (i = 0; i < width * bytes; i += bytes)
+ {
+ alpha = buf[i + bytes - 1];
+ if (alpha != 0 && alpha != 255)
+ {
+ recip_alpha = 255.0 / alpha;
+ for (j = 0; j < bytes - 1; j++)
+ {
+ new_val = (Q_UINT32)(buf[i + j] * recip_alpha);
+ buf[i + j] = MIN (255, new_val);
+ }
+ }
+ }
+}
+
+#include "kis_dropshadow.moc"
diff --git a/krita/plugins/viewplugins/dropshadow/kis_dropshadow.h b/krita/plugins/viewplugins/dropshadow/kis_dropshadow.h
new file mode 100644
index 00000000..3aca424f
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/kis_dropshadow.h
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the KDE project
+ *
+ * Copyright (c) Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _KIS_DROPSHADOW_H_
+#define _KIS_DROPSHADOW_H_
+
+#include <kis_progress_subject.h>
+#include <kis_paint_device.h>
+
+typedef enum
+{
+ BLUR_IIR,
+ BLUR_RLE
+} BlurMethod;
+
+
+class QColor;
+class KisView;
+class KisProgressDisplayInterface;
+
+class KisDropshadow : public KisProgressSubject {
+
+ Q_OBJECT
+
+public:
+
+ KisDropshadow(KisView * view);
+ virtual ~KisDropshadow() {};
+
+ void dropshadow(KisProgressDisplayInterface * progress, Q_INT32 xoffset, Q_INT32 yoffset, Q_INT32 blurradius, QColor color, Q_UINT8 opacity, bool allowResize);
+
+public: // Implement KisProgressSubject
+ virtual void cancel() { m_cancelRequested = true; }
+
+private:
+ void gaussianblur (KisPaintDeviceSP src, KisPaintDeviceSP dst,
+ QRect& rect, double horz, double vert,
+ BlurMethod method,
+ KisProgressDisplayInterface * progressDisplay);
+ //gaussian blur helper functions
+ void find_constants(double n_p[], double n_m[], double d_p[], double d_m[], double bd_p[], double bd_m[], double std_dev);
+ void transfer_pixels(double *src1, double *src2, Q_UINT8 *dest, Q_INT32 bytes, Q_INT32 width);
+ Q_INT32* make_curve(double sigma, Q_INT32 *length);
+ void run_length_encode (Q_UINT8 *src, Q_INT32 *dest, Q_INT32 bytes, Q_INT32 width);
+ void multiply_alpha (Q_UINT8 *buf, Q_INT32 width, Q_INT32 bytes);
+ void separate_alpha (Q_UINT8 *buf, Q_INT32 width, Q_INT32 bytes);
+
+private:
+ KisView * m_view;
+ bool m_cancelRequested;
+
+};
+
+#endif
diff --git a/krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc b/krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc
new file mode 100644
index 00000000..efe01a95
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the KDE project
+ *
+ * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_view.h>
+#include <kis_types.h>
+#include <kis_image.h>
+#include <kis_paint_device.h>
+#include <kis_layer.h>
+
+#include "kis_dropshadow_plugin.h"
+#include "kis_dropshadow.h"
+#include "dlg_dropshadow.h"
+
+K_EXPORT_COMPONENT_FACTORY( kritadropshadow, KGenericFactory<KisDropshadowPlugin>( "krita" ) )
+
+KisDropshadowPlugin::KisDropshadowPlugin(QObject *parent, const char *name, const QStringList &)
+ : KParts::Plugin(parent, name)
+{
+ if ( parent->inherits("KisView") ) {
+
+ setInstance(KGenericFactory<KisDropshadowPlugin>::instance());
+ setXMLFile(locate("data","kritaplugins/dropshadow.rc"), true);
+
+ m_view = (KisView*) parent;
+ (void) new KAction(i18n("Add Drop Shadow..."), 0, 0, this, SLOT(slotDropshadow()), actionCollection(), "dropshadow");
+ }
+}
+
+KisDropshadowPlugin::~KisDropshadowPlugin()
+{
+}
+
+void KisDropshadowPlugin::slotDropshadow()
+{
+ KisImageSP image = m_view->canvasSubject()->currentImg();
+ if (!image) return;
+
+ KisPaintDeviceSP dev = image->activeDevice();
+ if (!dev) return;
+
+ DlgDropshadow * dlgDropshadow = new DlgDropshadow(dev->colorSpace()->id().name(),
+ image->colorSpace()->id().name(),
+ m_view, "Dropshadow");
+ Q_CHECK_PTR(dlgDropshadow);
+
+ dlgDropshadow->setCaption(i18n("Drop Shadow"));
+
+ if (dlgDropshadow->exec() == QDialog::Accepted) {
+
+ KisDropshadow dropshadow(m_view);
+ dropshadow.dropshadow(m_view->canvasSubject()->progressDisplay(),
+ dlgDropshadow->getXOffset(),
+ dlgDropshadow->getYOffset(),
+ dlgDropshadow->getBlurRadius(),
+ dlgDropshadow->getShadowColor(),
+ dlgDropshadow->getShadowOpacity(),
+ dlgDropshadow->allowResizingChecked());
+
+ }
+
+ delete dlgDropshadow;
+
+}
+
+#include "kis_dropshadow_plugin.moc"
diff --git a/krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h b/krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h
new file mode 100644
index 00000000..fd64acdb
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of Krita
+ *
+ * Copyright (c) Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _KIS_DROPSHADOW_PLUGIN_H_
+#define _KIS_DROPSHADOW_PLUGIN_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+
+
+class KisDropshadowPlugin : public KParts::Plugin
+{
+ Q_OBJECT
+public:
+ KisDropshadowPlugin(QObject *parent, const char *name, const QStringList &);
+ virtual ~KisDropshadowPlugin();
+
+private slots:
+
+ void slotDropshadow();
+
+private:
+
+ KisView * m_view;
+};
+
+#endif
diff --git a/krita/plugins/viewplugins/dropshadow/kritadropshadow.desktop b/krita/plugins/viewplugins/dropshadow/kritadropshadow.desktop
new file mode 100644
index 00000000..cec20727
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/kritadropshadow.desktop
@@ -0,0 +1,39 @@
+[Desktop Entry]
+Name=Dropshadow
+Name[bg]=Сянка
+Name[ca]=Gota d'ombra
+Name[da]=Faldskygge
+Name[de]=Schattenwurf
+Name[el]=Ρίψη σκιάς
+Name[et]=Varju heitmine
+Name[fa]=سایۀ قطره
+Name[fr]=Jet d'ombre
+Name[fy]=Skaad sette
+Name[gl]=Sombreado
+Name[hu]=Ejtett árnyék
+Name[is]=Undirskuggi
+Name[it]=Getta ombra
+Name[ja]=影付け
+Name[km]=ទម្លាក់​ស្រមោល
+Name[nb]=Skygge
+Name[nds]=Schaddeneffekt
+Name[ne]=छायाँ छोड्नुहोस्
+Name[nl]=Schaduw plaatsen
+Name[pl]=Dodaj cień
+Name[pt]=Sombreado
+Name[pt_BR]=Sombreado
+Name[ru]=Тень
+Name[se]=Suoivvan
+Name[sk]=Tieň
+Name[sl]=Senca
+Name[sr]=Падајућа сенка
+Name[sr@Latn]=Padajuća senka
+Name[sv]=Fallskugga
+Name[uk]=Тінь
+Name[uz]=Soya tushirish
+Name[uz@cyrillic]=Соя тушириш
+Name[zh_CN]=阴影
+ServiceTypes=Krita/ViewPlugin
+Type=Service
+X-KDE-Library=kritadropshadow
+X-Krita-Version=2
diff --git a/krita/plugins/viewplugins/dropshadow/wdg_dropshadow.ui b/krita/plugins/viewplugins/dropshadow/wdg_dropshadow.ui
new file mode 100644
index 00000000..d78999c8
--- /dev/null
+++ b/krita/plugins/viewplugins/dropshadow/wdg_dropshadow.ui
@@ -0,0 +1,235 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>WdgDropshadow</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>WdgDropshadow</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>403</width>
+ <height>258</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Offset X:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Offset Y:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Blur radius:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Color:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Opacity:</string>
+ </property>
+ </widget>
+ <widget class="QSlider" row="4" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>opacitySlider</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>80</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="4" column="3">
+ <property name="name">
+ <cstring>opacitySpinBox</cstring>
+ </property>
+ <property name="suffix">
+ <string>%</string>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>80</number>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>allowResizingCheckBox</cstring>
+ </property>
+ <property name="text">
+ <string>Allow resizing</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>xOffsetSpinBox</cstring>
+ </property>
+ <property name="minValue">
+ <number>-99</number>
+ </property>
+ <property name="value">
+ <number>8</number>
+ </property>
+ </widget>
+ <spacer row="0" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>200</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>yOffsetSpinBox</cstring>
+ </property>
+ <property name="minValue">
+ <number>-99</number>
+ </property>
+ <property name="value">
+ <number>8</number>
+ </property>
+ </widget>
+ <spacer row="1" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>200</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>blurRadiusSpinBox</cstring>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ </widget>
+ <spacer row="2" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>190</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KColorButton" row="3" column="1">
+ <property name="name">
+ <cstring>shadowColorButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer row="3" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>120</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>opacitySpinBox</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>opacitySlider</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+ <connection>
+ <sender>opacitySlider</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>opacitySpinBox</receiver>
+ <slot>setValue(int)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>xOffsetSpinBox</tabstop>
+ <tabstop>yOffsetSpinBox</tabstop>
+ <tabstop>blurRadiusSpinBox</tabstop>
+ <tabstop>shadowColorButton</tabstop>
+ <tabstop>opacitySlider</tabstop>
+ <tabstop>opacitySpinBox</tabstop>
+ <tabstop>allowResizingCheckBox</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcolorbutton.h</includehint>
+</includehints>
+</UI>