[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Fwd: ksplash blurry icon clipping fix
From:       Allen Winter <winter () kde ! org>
Date:       2009-02-21 16:22:47
Message-ID: 200902211122.48650.winter () kde ! org
[Download RAW message or body]

----------  Forwarded Message  ----------

Subject: ksplash blurry icon clipping fix
Date: Saturday 21 February 2009
From: Roman Shtylman <shtylman@gmail.com>
To: kde-devel@kde.org

This is a fix for the icon clipping that happens when a user logs into
their computer and is presented with the splash screen and icons
fading in.

Currently, they get clipped because of the way drawing was done in the
past, this changed the drawing a bit to fix the clipping.

~Roman

-------------------------------------------------------

["ksplash.patch" (text/x-diff)]

=== modified file 'ksplash/ksplashx/pixmap.h'
--- ksplash/ksplashx/pixmap.h	2009-02-21 06:24:44 +0000
+++ ksplash/ksplashx/pixmap.h	2009-02-21 07:18:37 +0000
@@ -48,7 +48,7 @@
 
 #include "x11_defs.h"
 
-class QImage;
+#include "qimage.h"
 
 enum Optimization { DefaultOptim, NoOptim, MemoryOptim=NoOptim,
 			NormalOptim, BestOptim };
@@ -62,6 +62,7 @@
     int d;
     Optimization optim;
     XImage* ximage;
+    QImage orig;
     };
 
 class PP : public Qt // inherit from Qt to reduce needed code changes in the \
function

=== modified file 'ksplash/ksplashx/splash.cpp'
--- ksplash/ksplashx/splash.cpp	2009-02-21 06:24:44 +0000
+++ ksplash/ksplashx/splash.cpp	2009-02-21 07:52:09 +0000
@@ -458,7 +458,7 @@
     return img;
     }
 
-static PixmapData* imageAnimToPixmaps( const QImage& img, int frames )
+static PixmapData* imageAnimToPixmaps( const QImage& img, const QImage& orig, int \
frames )  {
     if( img.isNull())
         return NULL;
@@ -478,6 +478,9 @@
         ret[ frame ].w = framew;
         ret[ frame ].h = frameh;
         ret[ frame ].d = x11Depth();
+        ret[ frame ].orig = orig.copy(
+            ( frame % ANIM_IMAGES_ROW ) * framew, ( frame / ANIM_IMAGES_ROW ) * \
frameh, framew, frameh); +        
         }
     if( pix.hd != None )
         XFreePixmap( qt_xdisplay(), pix.hd );
@@ -508,10 +511,40 @@
         if( anim != NULL
             && area.intersects( QRect( anim->x, anim->y, frame->w, frame->h )))
             {
-            XCopyArea( qt_xdisplay(), frame->hd, pixmap, gc,
-                qMax( 0, area.x() - anim->x ), qMax( 0, area.y() - anim->y ),
-                area.x() - anim->x + area.width(), area.y() - anim->y + \
                area.height(),
-                qMax( 0, anim->x - area.x()), qMax( 0, anim->y - area.y()));
+                QRect rect = area.intersect(QRect( anim->x, anim->y, frame->w, \
frame->h)); +                rect.moveBy(-area.x(), -area.y());
+                
+                const int w = rect.width();
+                const int h = rect.height();
+                
+                XImage* img = XGetImage(qt_xdisplay(), pixmap, rect.x(), rect.y(), \
w, h, AllPlanes, ZPixmap); +                
+                const int h_off = frame->w - w;
+                int v_off = frame->h - h;
+                
+                QRgb* bg = (QRgb*)(img->data);
+                QRgb* fg = (QRgb*)frame->orig.bits();
+                fg += v_off * frame->w;
+                for (int y=0 ; y<h ; ++y)
+                {
+                    if (anim->x < area.x())
+                    {
+                        fg += h_off;
+                    }
+                    
+                    for (int x=0; x<w ; ++x, ++fg, ++bg)
+                    {
+                        *bg = blend(*fg, *bg);
+                    }
+                    
+                    if (anim->x > area.x())
+                    {
+                        fg += h_off;
+                    }
+                }
+                
+                XPutImage(qt_xdisplay(), pixmap, gc, img, 0, 0, rect.left(), \
rect.top(), w, h); +                XDestroyImage(img);
             }
         }
     XCopyArea( qt_xdisplay(), pixmap, window, gc, 0, 0, area.width(), area.height(), \
area.x(), area.y()); @@ -561,7 +594,7 @@
         fprintf( stderr, "No window contents\n" );
         exit( 3 );
         }
-    time_t test_time = time( NULL ) + 2;
+    time_t test_time = time( NULL ) + 1;
 #ifdef DEBUG
     fprintf( stderr,"AWATING STATE: %d (%s)\n", expected_state, states[ \
expected_state ] );  #endif
@@ -624,7 +657,7 @@
         if( test && time( NULL ) >= test_time )
             {
             ++state;
-            test_time = time( NULL ) + 2;
+            test_time = time( NULL ) + 1;
             }
         if( expected_state <= state )
             return false;
@@ -723,15 +756,6 @@
     return makeAbsolute( screen_ref[ 1 ], y_rel, image_ref[ 1 ], height, \
geometry.height());  }
 
-static inline QRgb blend( QRgb c, QRgb background )
-    {
-    if( qAlpha( c ) == 255 )
-        return c;
-    return qRgb( ( qRed( background ) * ( 255 - qAlpha( c ) ) + qRed( c ) * qAlpha( \
                c ) ) / 255,
-                 ( qGreen( background ) * ( 255 - qAlpha( c ) ) + qGreen( c ) * \
                qAlpha( c ) ) / 255,
-                 ( qBlue( background ) * ( 255 - qAlpha( c ) ) + qBlue( c ) * \
                qAlpha( c ) ) / 255 );
-    }
-
 static void blend( QImage& img, int x_pos, int y_pos, int x_img, int y_img, int \
w_img, int h_img )  {
     if( !img.hasAlphaBuffer())
@@ -1115,10 +1139,11 @@
             if( splash_image.isNull())
                 createSplashImage();
             QImage imgs = loadAnimImage( buf, frames );
+            QImage origs = loadAnimImage( buf, frames );
             if( !imgs.isNull())
                 {
                 blendAnim( imgs, x, y, frames );
-                PixmapData* pixs = imageAnimToPixmaps( imgs, frames );
+                PixmapData* pixs = imageAnimToPixmaps( imgs, origs, frames );
                 delete animations[ number ];
                 animations[ number ] = new AnimData( x, y, pixs, frames, delay, \
repeat );  }
@@ -1154,6 +1179,7 @@
             if( splash_image.isNull())
                 createSplashImage();
             QImage imgs = loadAnimImage( buf, frames );
+            QImage origs = loadAnimImage( buf, frames );
             if( !imgs.isNull())
                 {
                 int framew, frameh;
@@ -1161,7 +1187,7 @@
                 x = makeAbsoluteX( window_ref, x_rel, image_ref, framew );
                 y = makeAbsoluteY( window_ref, y_rel, image_ref, frameh );
                 blendAnim( imgs, x, y, frames );
-                PixmapData* pixs = imageAnimToPixmaps( imgs, frames );
+                PixmapData* pixs = imageAnimToPixmaps( imgs, origs, frames );
                 delete animations[ number ];
                 animations[ number ] = new AnimData( x, y, pixs, frames, delay, \
repeat );  }

=== modified file 'ksplash/ksplashx/splash.h'
--- ksplash/ksplashx/splash.h	2009-02-21 06:24:44 +0000
+++ ksplash/ksplashx/splash.h	2009-02-21 07:19:08 +0000
@@ -22,6 +22,16 @@
 #define _SPLASH_H
 
 #include <stdio.h>
+#include "qcolor.h"
+
+static inline QRgb blend(const QRgb& c, const QRgb& background )
+{
+    if( qAlpha( c ) == 255 )
+        return c;
+    return qRgb( ( qRed( background ) * ( 255 - qAlpha( c ) ) + qRed( c ) * qAlpha( \
c ) ) / 255, +                 ( qGreen( background ) * ( 255 - qAlpha( c ) ) + \
qGreen( c ) * qAlpha( c ) ) / 255, +                 ( qBlue( background ) * ( 255 - \
qAlpha( c ) ) + qBlue( c ) * qAlpha( c ) ) / 255 ); +}
 
 void runSplash( const char* theme, bool test, int pipe );
 



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic