From 698569f8428ca088f764d704034a1330517b98c0 Mon Sep 17 00:00:00 2001 From: tpearson Date: Sun, 26 Jun 2011 00:41:16 +0000 Subject: Finish rebranding of Krita as Chalk git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1238363 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- chalk/plugins/viewplugins/dropshadow/Makefile.am | 31 + .../viewplugins/dropshadow/chalkdropshadow.desktop | 39 ++ .../viewplugins/dropshadow/dlg_dropshadow.cc | 117 ++++ .../viewplugins/dropshadow/dlg_dropshadow.h | 60 ++ chalk/plugins/viewplugins/dropshadow/dropshadow.rc | 11 + .../viewplugins/dropshadow/kis_dropshadow.cc | 758 +++++++++++++++++++++ .../viewplugins/dropshadow/kis_dropshadow.h | 72 ++ .../dropshadow/kis_dropshadow_plugin.cc | 91 +++ .../viewplugins/dropshadow/kis_dropshadow_plugin.h | 46 ++ .../viewplugins/dropshadow/wdg_dropshadow.ui | 235 +++++++ 10 files changed, 1460 insertions(+) create mode 100644 chalk/plugins/viewplugins/dropshadow/Makefile.am create mode 100644 chalk/plugins/viewplugins/dropshadow/chalkdropshadow.desktop create mode 100644 chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc create mode 100644 chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h create mode 100644 chalk/plugins/viewplugins/dropshadow/dropshadow.rc create mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc create mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h create mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc create mode 100644 chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h create mode 100644 chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui (limited to 'chalk/plugins/viewplugins/dropshadow') diff --git a/chalk/plugins/viewplugins/dropshadow/Makefile.am b/chalk/plugins/viewplugins/dropshadow/Makefile.am new file mode 100644 index 00000000..98ba3550 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/Makefile.am @@ -0,0 +1,31 @@ +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = dropshadow.rc +EXTRA_DIST = $(chalkrc_DATA) + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../colorspaces/rgb_u8 \ + -I$(srcdir)/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + + +kde_module_LTLIBRARIES = chalkdropshadow.la + +chalkdropshadow_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 + +chalkdropshadow_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkdropshadow_la_LIBADD = ../../../libchalkcommon.la ../../../colorspaces/rgb_u8/libchalkrgb.la + +kde_services_DATA = chalkdropshadow.desktop + +chalkdropshadow_la_METASOURCES = AUTO + +KDE_OPTIONS = nofinal diff --git a/chalk/plugins/viewplugins/dropshadow/chalkdropshadow.desktop b/chalk/plugins/viewplugins/dropshadow/chalkdropshadow.desktop new file mode 100644 index 00000000..a48a477e --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/chalkdropshadow.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=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkdropshadow +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc new file mode 100644 index 00000000..797fc098 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.cc @@ -0,0 +1,117 @@ +/* + * dlg_dropshadow.cc - part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2005 Michael Thaler + * Copyright (c) 2006 Cyrille Berger + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dlg_dropshadow.h" +#include "wdg_dropshadow.h" + +DlgDropshadow::DlgDropshadow( const TQString & /*imageCS*/, + const TQString & /*layerCS*/, + TQWidget * tqparent, + const char * name) + : super (tqparent, 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->tqsizeHint()); + + 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) ); + TQColor 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, TQT_SIGNAL(okClicked()), + this, TQT_SLOT(okClicked())); +} + +DlgDropshadow::~DlgDropshadow() +{ + delete m_page; +} + +TQ_INT32 DlgDropshadow::getXOffset() +{ + return m_page->xOffsetSpinBox->value(); +} + +TQ_INT32 DlgDropshadow::getYOffset() +{ + return m_page->yOffsetSpinBox->value(); +} + +TQ_INT32 DlgDropshadow::getBlurRadius() +{ + return m_page->blurRadiusSpinBox->value(); +} + +TQ_UINT8 DlgDropshadow::getShadowOpacity() +{ + double opacity = (double)m_page->opacitySpinBox->value(); + //convert percent to a 8 bit opacity value + return (TQ_UINT8)(opacity / 100 * 255); +} + +TQColor 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/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h new file mode 100644 index 00000000..9f3ca469 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dlg_dropshadow.h @@ -0,0 +1,60 @@ +/* + * dlg_dropshadow.h -- part of KimageShop^WKrayon^WChalk + * + * Copyright (c) 2005 Michael Thaler + * + * 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 +#include + +class WdgDropshadow; +class TQColor; + +/** + * 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 + TQ_OBJECT + +public: + + DlgDropshadow(const TQString & imageCS, const TQString & layerCS, TQWidget * tqparent = 0, + const char* name = 0); + ~DlgDropshadow(); + +public: + + TQ_INT32 getXOffset(); + TQ_INT32 getYOffset(); + TQ_INT32 getBlurRadius(); + TQ_UINT8 getShadowOpacity(); + TQColor getShadowColor(); + bool allowResizingChecked(); +private slots: + void okClicked(); + +private: + + WdgDropshadow * m_page; +}; + +#endif // DLG_DROPSHADOW diff --git a/chalk/plugins/viewplugins/dropshadow/dropshadow.rc b/chalk/plugins/viewplugins/dropshadow/dropshadow.rc new file mode 100644 index 00000000..fcd0be0e --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/dropshadow.rc @@ -0,0 +1,11 @@ + + + + La&yer + + Layer Effects + + + + + diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc new file mode 100644 index 00000000..207c86c3 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.cc @@ -0,0 +1,758 @@ +/* + * This file is part of Chalk + * + * Copyright (c) 2005 Michael Thaler + * + * 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 + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "kis_meta_registry.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, TQ_INT32 xoffset, TQ_INT32 yoffset, TQ_INT32 blurradius, TQColor color, TQ_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(shadowDev->colorSpace()); + + TQRect rect = dev->exactBounds(); + + for (TQ_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 + TQ_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 tqparent = image->rootLayer(); + if (image->activeLayer()) + tqparent = image->activeLayer()->tqparent().data(); + + KisPaintLayerSP l = new KisPaintLayer(image, i18n("Drop Shadow"), opacity, shadowDev); + image->addLayer( l.data(), tqparent, src->siblingBelow() ); + + if (allowResize) + { + TQRect shadowBounds = shadowDev->exactBounds(); + + if (!image->bounds().tqcontains(shadowBounds)) { + + TQRect newImageSize = image->bounds() | shadowBounds; + image->resize(newImageSize.width(), newImageSize.height()); + + if (shadowBounds.left() < 0 || shadowBounds.top() < 0) { + + TQ_INT32 newRootX = image->rootLayer()->x(); + TQ_INT32 newRootY = image->rootLayer()->y(); + + if (shadowBounds.left() < 0) { + newRootX += -shadowBounds.left(); + } + if (shadowBounds.top() < 0) { + newRootY += -shadowBounds.top(); + } + + KCommand *moveCommand = image->rootLayer()->moveCommand(TQPoint(image->rootLayer()->x(), image->rootLayer()->y()), + TQPoint(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, TQRect& rect, double horz, double vert, BlurMethod method, KisProgressDisplayInterface *) +{ + TQ_INT32 width, height; + TQ_INT32 bytes; + TQ_UINT8 *dest, *dp; + TQ_UINT8 *src, *sp, *sp_p, *sp_m; + TQ_INT32 *buf = NULL; + TQ_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; + TQ_INT32 x1, y1, x2, y2; + TQ_INT32 i, j; + TQ_INT32 row, col, b; + TQ_INT32 terms; + double progress, max_progress; + TQ_INT32 initial_p[4]; + TQ_INT32 initial_m[4]; + double std_dev; + TQ_INT32 pixels; + TQ_INT32 total = 1; + TQ_INT32 start, end; + TQ_INT32 *curve; + TQ_INT32 *sum = NULL; + TQ_INT32 val; + TQ_INT32 length; + TQ_INT32 initial_pp, initial_mm; + + x1 = (TQ_INT32)(rect.x() - horz); + y1 = (TQ_INT32)(rect.y() - vert); + width = (TQ_INT32)(rect.width() + 2 * horz); + height = (TQ_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 TQ_INT32[MAX (width, height) * 2]; + break; + } + + src = new TQ_UINT8[MAX (width, height) * bytes]; + dest = new TQ_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 TQ_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( (TQ_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 TQ_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( (TQ_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) +{ + TQ_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, TQ_UINT8 *dest, TQ_INT32 bytes, TQ_INT32 width) +{ + TQ_INT32 b; + TQ_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++ = (TQ_UINT8) sum; + } +} + +//The equations: g(r) = exp (- r^2 / (2 * sigma^2)), r = sqrt (x^2 + y ^2) +TQ_INT32 * KisDropshadow::make_curve(double sigma, TQ_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 TQ_INT32[n]; + + *length = n / 2; + curve += *length; + curve[0] = 255; + + for (i = 1; i <= *length; i++) + { + temp = (TQ_INT32) (exp (- (i * i) / sigma2) * 255); + curve[-i] = temp; + curve[i] = temp; + } + + return curve; +} + +void KisDropshadow::run_length_encode (TQ_UINT8 *src, TQ_INT32 *dest, TQ_INT32 bytes, TQ_INT32 width) +{ + TQ_INT32 start; + TQ_INT32 i; + TQ_INT32 j; + TQ_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 (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) +{ + TQ_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] = (TQ_UINT8)a; + } + } +} + +void KisDropshadow::separate_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes) +{ + TQ_INT32 i, j; + TQ_UINT8 alpha; + double recip_alpha; + TQ_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 = (TQ_UINT32)(buf[i + j] * recip_alpha); + buf[i + j] = MIN (255, new_val); + } + } + } +} + +#include "kis_dropshadow.moc" diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h new file mode 100644 index 00000000..94c6decc --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow.h @@ -0,0 +1,72 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) Michael Thaler + * + * 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 +#include + +typedef enum +{ + BLUR_IIR, + BLUR_RLE +} BlurMethod; + + +class TQColor; +class KisView; +class KisProgressDisplayInterface; + +class KisDropshadow : public KisProgressSubject { + + Q_OBJECT + TQ_OBJECT + +public: + + KisDropshadow(KisView * view); + virtual ~KisDropshadow() {}; + + void dropshadow(KisProgressDisplayInterface * progress, TQ_INT32 xoffset, TQ_INT32 yoffset, TQ_INT32 blurradius, TQColor color, TQ_UINT8 opacity, bool allowResize); + +public: // Implement KisProgressSubject + virtual void cancel() { m_cancelRequested = true; } + +private: + void gaussianblur (KisPaintDeviceSP src, KisPaintDeviceSP dst, + TQRect& 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, TQ_UINT8 *dest, TQ_INT32 bytes, TQ_INT32 width); + TQ_INT32* make_curve(double sigma, TQ_INT32 *length); + void run_length_encode (TQ_UINT8 *src, TQ_INT32 *dest, TQ_INT32 bytes, TQ_INT32 width); + void multiply_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes); + void separate_alpha (TQ_UINT8 *buf, TQ_INT32 width, TQ_INT32 bytes); + +private: + KisView * m_view; + bool m_cancelRequested; + +}; + +#endif diff --git a/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc new file mode 100644 index 00000000..5dc190f1 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.cc @@ -0,0 +1,91 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Michael Thaler + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "kis_dropshadow_plugin.h" +#include "kis_dropshadow.h" +#include "dlg_dropshadow.h" + +K_EXPORT_COMPONENT_FACTORY( chalkdropshadow, KGenericFactory( "chalk" ) ) + +KisDropshadowPlugin::KisDropshadowPlugin(TQObject *tqparent, const char *name, const TQStringList &) + : KParts::Plugin(tqparent, name) +{ + if ( tqparent->inherits("KisView") ) { + + setInstance(KGenericFactory::instance()); + setXMLFile(locate("data","chalkplugins/dropshadow.rc"), true); + + m_view = (KisView*) tqparent; + (void) new KAction(i18n("Add Drop Shadow..."), 0, 0, this, TQT_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() == TQDialog::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/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h new file mode 100644 index 00000000..e2641ed2 --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/kis_dropshadow_plugin.h @@ -0,0 +1,46 @@ +/* + * This file is part of Chalk + * + * Copyright (c) Michael Thaler + * + * 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 + +class KisView; + + + +class KisDropshadowPlugin : public KParts::Plugin +{ + Q_OBJECT + TQ_OBJECT +public: + KisDropshadowPlugin(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~KisDropshadowPlugin(); + +private slots: + + void slotDropshadow(); + +private: + + KisView * m_view; +}; + +#endif diff --git a/chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui b/chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui new file mode 100644 index 00000000..4bd2f38c --- /dev/null +++ b/chalk/plugins/viewplugins/dropshadow/wdg_dropshadow.ui @@ -0,0 +1,235 @@ + +WdgDropshadow + + + WdgDropshadow + + + + 0 + 0 + 403 + 258 + + + + + unnamed + + + + textLabel1 + + + Offset X: + + + + + textLabel1_2 + + + Offset Y: + + + + + textLabel2 + + + Blur radius: + + + + + textLabel3 + + + Color: + + + + + textLabel4 + + + Opacity: + + + + + opacitySlider + + + 100 + + + 80 + + + Horizontal + + + + + opacitySpinBox + + + % + + + 100 + + + 80 + + + + + allowResizingCheckBox + + + Allow resizing + + + true + + + + + xOffsetSpinBox + + + -99 + + + 8 + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + yOffsetSpinBox + + + -99 + + + 8 + + + + + spacer8 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + blurRadiusSpinBox + + + 5 + + + + + spacer9 + + + Horizontal + + + Expanding + + + + 190 + 20 + + + + + + shadowColorButton + + + + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 120 + 31 + + + + + + + + + + opacitySpinBox + valueChanged(int) + opacitySlider + setValue(int) + + + opacitySlider + valueChanged(int) + opacitySpinBox + setValue(int) + + + + xOffsetSpinBox + yOffsetSpinBox + blurRadiusSpinBox + shadowColorButton + opacitySlider + opacitySpinBox + allowResizingCheckBox + + + + kcolorbutton.h + + -- cgit v1.2.1