diff -Nru beclock-kwin-fx-0.8~karmic~ppa1/beclock.cpp beclock-kwin-fx-0.9~karmic~ppa1/beclock.cpp --- beclock-kwin-fx-0.8~karmic~ppa1/beclock.cpp 2010-03-30 15:53:05.000000000 +0100 +++ beclock-kwin-fx-0.9~karmic~ppa1/beclock.cpp 2010-04-01 17:55:15.000000000 +0100 @@ -1,7 +1,7 @@ /******************************************************************** BeClock KWin - effect plugin -Copyright (C) 2009 Thomas Lübking +Copyright (C) 2009,2010 Thomas Lübking 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 @@ -174,7 +174,7 @@ p.drawArc( r, sta, swa ); w -= 1; - p.setCompositionMode( QPainter::CompositionMode_DestinationIn ); + p.setCompositionMode( QPainter::CompositionMode_DestinationOut ); p.setPen( QPen(Qt::black, w, Qt::SolidLine, Qt::RoundCap) ); p.drawArc( r, sta, swa ); @@ -183,142 +183,6 @@ p.drawArc( r, sta, swa ); } -void BeClock::drawClock( QPainter &p, const QRect &rect ) -{ - QDateTime dt = QDateTime::currentDateTime(); - const int h = dt.time().hour() % 12; - const int m = dt.time().minute(); - const int d = qMax( 2, rect.width()/24 ); - int d2 = 2*d; - QColor c = myForeground; - QColor bc = myBackground; - const int alpha = c.alpha(); - QRect r = rect; - - if ( iShowDigits ) - { - bc.setAlpha(128); -// if ( myElectricBorders.isEmpty() ) - { - QRadialGradient rg(r.center(), r.width()/2); - rg.setColorAt(0,bc); - bc.setAlpha(0); rg.setColorAt(1,bc); - p.setBrush(rg); - p.setPen(Qt::NoPen); - p.drawRect(r); - } -#if 0 - else - { - p.setBrush( bc ); - c.setAlpha( 96 ); - p.setPen( c ); -// p.setPen(Qt::NoPen); - p.setRenderHint( QPainter::Antialiasing ); - r.adjust(1,1,-1,-1); - p.drawEllipse( r ); - r.adjust(d/2,d/2,-d/2,-d/2); - } -#endif - } - - p.setRenderHint( QPainter::Antialiasing ); - - if ( iShowRings ) - { - // minutes - r.adjust(d,d,-d,-d); - c.setAlpha( alpha/3 ); - bc.setAlpha( 72 ); - drawOutlinedArc( p, r, 90*16, m*-96, d, c, bc ); // 96 = 360*16/60 - - // hours - r.adjust(d2,d2,-d2,-d2); - c.setAlpha( alpha*2/3 ); - bc.setAlpha( 128 ); - drawOutlinedArc( p, r, 90*16, h*-480, d, c, bc ); // 480 = 360*16/12 - - mySecond.bar.setHeight( r.height()/16 ); - } - - if ( !iShowDigits ) - return; - - // digits - d2 += d; - r.adjust(d2,d2,-d2,-d2); - if (r.width() > 32) - { - const QString time = QString("%1:%2").arg( iUse24h ? dt.time().hour() : (h?h:12), 2, 10, QLatin1Char('0') ) - .arg( m, 2, 10, QLatin1Char('0') ); - - QFont fnt = myFont; - QString underlay; - if ( iShowTheDay ) - underlay = QDate::shortDayName( dt.date().dayOfWeek() ).left(2); - else if ( !iUse24h ) - underlay = (h == dt.time().hour() ? "AM" : "PM"); - if ( !underlay.isEmpty() ) - { - fnt.setBold(true); - const QRect tr = QFontMetrics(fnt).tightBoundingRect(underlay); - const float f = qMin( (float)r.width()/tr.width(), (float)r.height()/tr.height() ); - fnt.setPointSize( fnt.pointSize()*f ); - p.setFont(fnt); - c.setAlpha( alpha/6 ); - p.setPen( c ); - p.drawText(rect, Qt::AlignCenter, underlay ); - } - if ( iShowTheDate ) - { - const QString date = QString("%1-%2-%3").arg( dt.date().year() ) - .arg( dt.date().month(), 2, 10, QLatin1Char('0') ) - .arg( dt.date().day(), 2, 10, QLatin1Char('0') ); - fnt = myFont; - fnt.setBold(false); - fnt.setPointSize( fnt.pointSize()*r.width()/QFontMetrics(fnt).width(date) ); - int dy = QFontMetrics(fnt).height(); - r.translate(0,4*dy/5); - p.setFont(fnt); - c.setAlpha( alpha/2 ); - p.setPen( c ); - p.drawText(r, Qt::AlignCenter, date ); - if (iShowTheSeconds) - { - mySecond.bar.setHeight( dy/3 ); - dy = 3*dy/2; - } - r.translate(0,-5*dy/4); - } - else if ( iShowTheSeconds ) - r.translate(0,-5*mySecond.bar.height()/4); -#if 1 - fnt = myFont; - fnt.setBold(false); - fnt.setPointSize( fnt.pointSize()*r.width()/QFontMetrics(fnt).width(time) ); - p.setFont(fnt); - c.setAlpha( alpha*2/3 ); - p.setPen( c ); - p.drawText(r, Qt::AlignCenter, time ); -#else - QPainterPath path; - fnt = myFont; - fnt.setBold(false); - fnt.setPointSize( fnt.pointSize()*r.width()/QFontMetrics(fnt).width(time) ); - QFontMetrics fm(fnt); - QRect tr = fm.boundingRect( time ); - path.addText( r.x() + (r.width()-tr.width())/2, - r.y() + (r.height() - tr.height())/2 + fm.ascent(), - fnt, time ); - - bc.setAlpha( 96 ); - c.setAlpha( alpha*2/3 ); - p.setPen( bc ); - p.setBrush( c ); - p.drawPath( path ); -#endif - } -} #if 0 QPainterPath path; @@ -483,10 +347,11 @@ effects->addRepaintFull(); } -float vanilla_matrix[16]; +static float vanilla_matrix[16]; void BeClock::prePaintScreen( ScreenPrePaintData& data, int time ) { + iHavePainted = false; // everyone else may go first, so we can check for transformations and save matrix storage on simple screens effects->prePaintScreen( data, time ); if ( imActive ) @@ -513,8 +378,9 @@ { effects->paintScreen( mask, region, data ); // paint normal screen - if ( !imActive ) + if ( !imActive || iHavePainted ) return; + iHavePainted = true; // and ourself above #ifdef KWIN_HAVE_OPENGL_COMPOSITING @@ -649,7 +515,7 @@ { imActive = !imActive; myLastUpdateTime = -1; - if( imActive ) + if (imActive) myClock = startTimer( 1000 ); else { @@ -659,14 +525,264 @@ effects->addRepaint( myGeometry ); } + +/* +// Exponential blur, Jani Huhtanen, 2006 ========================== +* 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 +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); +} + void -BeClock::updateBuffer() +expblur( QImage &img, int radius ) +{ + if(radius<1) + return; + + static const int aprec = 16; static const int zprec = 7; + + // 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); +} +// ====================================================== + +QImage * +BeClock::halo( QImage *img, int r ) { + QImage *halo = new QImage(*img); + QRgb *pixel = (QRgb*)halo->bits(); + int n = halo->width() * halo->height(); + + QColor bc = myBackground; + QRgb rgba = bc.rgba(); + bc.setAlpha(0); + QRgb trans = bc.rgba(); + +#define ALPHA qAlpha(pixel[i]) + for (int i = 0; i < n; ++i) + pixel[i] = ALPHA > 96 ? rgba : trans; +#undef ALPHA + expblur( *halo, r ); + QPainter p(halo); + int v = qMax(bc.red(), qMax(bc.green(), bc.blue())); + if ( v > 128 ) + p.drawImage(0,0, *halo); + p.setCompositionMode( QPainter::CompositionMode_DestinationOut ); + p.drawImage(0,0, *img); + p.end(); + return halo; +} + +QImage * +BeClock::digitImage( const QDateTime &dt, QRect r ) +{ + QFont fnt = myFont; + QColor c = myForeground; + const int alpha = c.alpha(); + + int h = dt.time().hour(); + if ( !iUse24h && h > 12 ) + h -= 12; + + QImage *img = new QImage(myGeometry.size(), QImage::Format_ARGB32); + img->fill( Qt::transparent ); + QPainter p(img); + + // THE "UNDERLAY" ============================================================================== + QString underlay; + if ( iShowTheDay ) + underlay = QDate::shortDayName( dt.date().dayOfWeek() ).left(2); + else if ( !iUse24h ) + underlay = (h == dt.time().hour() ? "AM" : "PM"); + if ( !underlay.isEmpty() ) + { + fnt.setBold(true); + const QRect tr = QFontMetrics(fnt).tightBoundingRect(underlay); + const float f = qMin( (float)r.width()/tr.width(), (float)r.height()/tr.height() ); + fnt.setPointSize( fnt.pointSize()*f ); + p.setFont(fnt); + c.setAlpha( alpha/6 ); + p.setPen( c ); + p.drawText(r.adjusted(-1000,-1000,1000,1000), Qt::AlignCenter, underlay ); + } + + // DATE ======================================================================================== + if ( iShowTheDate ) + { + const QString date = QString("%1-%2-%3").arg( dt.date().year() ) + .arg( dt.date().month(), 2, 10, QLatin1Char('0') ) + .arg( dt.date().day(), 2, 10, QLatin1Char('0') ); + fnt = myFont; + fnt.setBold(false); + fnt.setPointSize( fnt.pointSize()*r.width()/QFontMetrics(fnt).width(date) ); + int dy = QFontMetrics(fnt).height(); + r.translate(0,4*dy/5); + p.setFont(fnt); + c.setAlpha( alpha/2 ); + p.setPen( c ); + p.drawText(r.adjusted(-1000,-1000,1000,1000), Qt::AlignCenter, date ); + if (iShowTheSeconds) + { + mySecond.bar.setHeight( dy/3 ); + dy = 3*dy/2; + } + r.translate(0,-5*dy/4); + } + else if ( iShowTheSeconds ) + { + mySecond.bar.setHeight( r.height()/16 ); + r.translate(0,-9*mySecond.bar.height()/4); + } + + // TIME ======================================================================================== + const QString time = QString("%1:%2").arg( h, 2, 10, QLatin1Char('0') ).arg( dt.time().minute(), 2, 10, QLatin1Char('0') ); + fnt = myFont; + fnt.setBold(false); + fnt.setPointSize( fnt.pointSize()*r.width()/QFontMetrics(fnt).width(time) ); + p.setFont(fnt); + c.setAlpha( alpha*2/3 ); + p.setPen( c ); + p.drawText(r.adjusted(-1000,-1000,1000,1000), Qt::AlignCenter, time ); + + p.end(); + + QImage *hlo = halo( img, 9 ); + p.begin(hlo); + p.drawImage(0,0, *img); + p.end(); + delete img; + return hlo; +} + +QImage * +BeClock::clockImage() +{ + QDateTime dt = QDateTime::currentDateTime(); + QImage *img = new QImage(myGeometry.size(), QImage::Format_ARGB32); img->fill( Qt::transparent ); QPainter p( img ); - drawClock( p, img->rect() ); + + QRect rect = img->rect(); + const int d = qMax( 2, rect.width()/24 ); + int d2 = 2*d; + + if ( iShowDigits ) + { + int d3 = 9; + if (iShowRings) d3 = 2*(d2+d); + rect.adjust( d3, d3, -d3, -d3 ); + if (rect.width() > 32) + { + QImage *digits = digitImage( dt, rect ); + p.drawImage( 0,0, *digits ); + delete digits; + } + rect = img->rect(); + } + + if ( iShowRings ) + { + const int h = dt.time().hour() % 12; + const int m = dt.time().minute(); + QColor c = myForeground; + QColor bc = myBackground; + const int alpha = c.alpha(); + + p.setRenderHint( QPainter::Antialiasing ); + // minutes + rect.adjust(d,d,-d,-d); + c.setAlpha( alpha/3 ); + bc.setAlpha( 72 ); + drawOutlinedArc( p, rect, 90*16, m*-96, d, c, bc ); // 96 = 360*16/60 + + // hours + rect.adjust(d2,d2,-d2,-d2); + c.setAlpha( alpha*2/3 ); + bc.setAlpha( 128 ); + drawOutlinedArc( p, rect, 90*16, h*-480, d, c, bc ); // 480 = 360*16/12 + + if ( !iShowDigits ) + mySecond.bar.setHeight( rect.height()/16 ); + } + p.end(); + return img; +} + +void +BeClock::updateBuffer() +{ + QImage *img = clockImage(); #ifdef KWIN_HAVE_OPENGL_COMPOSITING if ( effects->compositingType() == OpenGLCompositing ) { @@ -684,8 +800,8 @@ #if 0 // NOTICE This does NOT work, as Qt stumbles on the antialiasing (apparently paintengine // switching even more broken :-( - // also it appears that calling antialiasing seems to force the caster engine and then performs - // a conversion??? - that's dull + // also it appears that calling antialiasing seems to force the raster engine and then performs + // a conversion??? - that's dull :-( myBufferXR->fill( Qt::transparent ); QPainter p( myBufferXR ); drawClock( p, myBufferXR->rect() ); diff -Nru beclock-kwin-fx-0.8~karmic~ppa1/beclock.desktop beclock-kwin-fx-0.9~karmic~ppa1/beclock.desktop --- beclock-kwin-fx-0.8~karmic~ppa1/beclock.desktop 2010-03-30 22:51:36.000000000 +0100 +++ beclock-kwin-fx-0.9~karmic~ppa1/beclock.desktop 2010-04-01 18:14:56.000000000 +0100 @@ -15,7 +15,7 @@ # Category of the effect, for config dialog X-KDE-PluginInfo-Category=Tools # Version and license -X-KDE-PluginInfo-Version=0.8 +X-KDE-PluginInfo-Version=0.9 X-KDE-PluginInfo-License=GPL # If the effect depends on any other effect(s) to be active, then internal # names of those effects can be given here diff -Nru beclock-kwin-fx-0.8~karmic~ppa1/beclock.h beclock-kwin-fx-0.9~karmic~ppa1/beclock.h --- beclock-kwin-fx-0.8~karmic~ppa1/beclock.h 2010-03-30 15:33:07.000000000 +0100 +++ beclock-kwin-fx-0.9~karmic~ppa1/beclock.h 2010-04-01 17:23:55.000000000 +0100 @@ -1,7 +1,7 @@ /******************************************************************** BeClock KWin - effect plugin - Copyright (C) 2009 Thomas Lübking + Copyright (C) 2009,2010 Thomas Lübking 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 @@ -46,6 +46,9 @@ private: QRect cornerRect( ElectricBorder border ); void drawClock( QPainter &p, const QRect &r ); + QImage *clockImage(); + QImage *digitImage( const QDateTime &dt, QRect r ); + QImage *halo( QImage *img, int r ); bool mouseIsInAciveCorner( const QPoint &pos ); int screen() const; void updateBuffer(); @@ -55,9 +58,9 @@ void toggle(); private: - bool imActive, iUse24h, iHideOnHover, iPollTheMouse; + bool imActive, iUse24h, iHideOnHover, iPollTheMouse, iHavePainted; bool iShowDigits, iShowRings, iShowTheDate, iShowTheDay, iShowTheSeconds; - int myClock, myAlign, myScreen; + int myClock, myAlign, myScreen, myFadeTimer; float myAlpha; ElectricBorder myCurrentCorner; QList myElectricBorders; diff -Nru beclock-kwin-fx-0.8~karmic~ppa1/debian/changelog beclock-kwin-fx-0.9~karmic~ppa1/debian/changelog --- beclock-kwin-fx-0.8~karmic~ppa1/debian/changelog 2010-03-31 07:53:00.000000000 +0100 +++ beclock-kwin-fx-0.9~karmic~ppa1/debian/changelog 2010-04-01 19:44:51.000000000 +0100 @@ -1,3 +1,9 @@ +beclock-kwin-fx (0.9~karmic~ppa1) karmic; urgency=low + + * New source, 0.9 + + -- Rog131 Thu, 01 Apr 2010 21:44:14 +0300 + beclock-kwin-fx (0.8~karmic~ppa1) karmic; urgency=low * New source, 0.8