diff --git a/effects/blur.cpp b/effects/blur.cpp new file mode 100644 index 000000000..7a4f16c6b --- /dev/null +++ b/effects/blur.cpp @@ -0,0 +1,130 @@ + +#include + +// Exponential blur, Jani Huhtanen, 2006 +// +template +static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha); + +template +static inline void blurrow( QImage & im, int line, int alpha); + +template +static inline void blurcol( QImage & im, int col, int alpha); + +/* +* expblur(QImage &img, int radius) +* +* In-place blur of image 'img' with kernel +* of approximate radius 'radius'. +* +* Blurs with two sided exponential impulse +* response. +* +* aprec = precision of alpha parameter +* in fixed-point format 0.aprec +* +* zprec = precision of state parameters +* zR,zG,zB and zA in fp format 8.zprec +*/ +template +void expblur( QImage &img, int radius ) +{ + if(radius<1) + return; + + /* Calculate the alpha such that 90% of + the kernel is within the radius. + (Kernel extends to infinity) + */ + int alpha = (int)((1<(img,row,alpha); + } + + for(int col=0;col(img,col,alpha); + } + return; +} + +template +static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha) +{ + int R,G,B,A; + R = *bptr; + G = *(bptr+1); + B = *(bptr+2); + A = *(bptr+3); + + zR += (alpha * ((R<>aprec; + zG += (alpha * ((G<>aprec; + zB += (alpha * ((B<>aprec; + zA += (alpha * ((A<>aprec; + + *bptr = zR>>zprec; + *(bptr+1) = zG>>zprec; + *(bptr+2) = zB>>zprec; + *(bptr+3) = zA>>zprec; +} + +template +static inline void blurrow( QImage & im, int line, int alpha) +{ + int zR,zG,zB,zA; + + QRgb *ptr = (QRgb *)im.scanLine(line); + + zR = *((unsigned char *)ptr )<((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha); + } + for(int index=im.width()-2; index>=0; index--) + { + blurinner((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha); + } + + +} + +template +static inline void blurcol( QImage & im, int col, int alpha) +{ + int zR,zG,zB,zA; + + QRgb *ptr = (QRgb *)im.bits(); + ptr+=col; + + zR = *((unsigned char *)ptr )<((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha); + } + + for(int index=(im.height()-2)*im.width(); index>=0; index-=im.width()) + { + blurinner((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha); + } + +} + +template +inline const T& qClamp(const T &x, const T &low, const T &high) +{ + if (x < low) return low; + else if (x > high) return high; + else return x; +} + diff --git a/widgets/icon.cpp b/widgets/icon.cpp index abe5b21b3..748142b0c 100644 --- a/widgets/icon.cpp +++ b/widgets/icon.cpp @@ -20,11 +20,15 @@ #include #include +#include +#include #include +#include #include #include "svg.h" +#include "blur.cpp" namespace Plasma { @@ -121,6 +125,22 @@ void Icon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid // QRectF rect = boundingRect(); + if (d->state != Private::PressedState && scene()) { + QList views = scene()->views(); + if (views.count() > 0) { + QPixmap* pix = static_cast(views[0]->windowSurface()->paintDevice()); + QImage image(boundingRect().size().toSize(), QImage::Format_ARGB32_Premultiplied); + { + QPainter p(&image); + p.drawPixmap(image.rect(), *pix, sceneBoundingRect()); + } + expblur<16,7>(image, 10); + painter->save(); + painter->drawImage(0, 0, image); + painter->restore(); + } + } + QString element; if (d->svgElements & Private::SvgBackground) { element = "background";