-rw-r--r-- | noncore/styles/theme/ogfxeffect.cpp | 22 | ||||
-rw-r--r-- | noncore/styles/theme/othemestyle.cpp | 6 |
2 files changed, 17 insertions, 11 deletions
diff --git a/noncore/styles/theme/ogfxeffect.cpp b/noncore/styles/theme/ogfxeffect.cpp index 2071a67..90b45fe 100644 --- a/noncore/styles/theme/ogfxeffect.cpp +++ b/noncore/styles/theme/ogfxeffect.cpp @@ -1,128 +1,129 @@ /* This file is part of the KDE libraries Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org> (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> */ // $Id$ #include <qimage.h> #include <qpainter.h> #include <qpe/qmath.h> #include "ogfxeffect.h" #include <cstdlib> #include <cmath> //====================================================================== // // Gradient effects // //====================================================================== QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca, const QColor &cb, GradientType eff, int ncols) { - QImage image = gradient(pixmap.size(), ca, cb, eff, ncols); - pixmap.convertFromImage(image); - + if ( !pixmap. isNull ( )) { + QImage image = gradient(pixmap.size(), ca, cb, eff, ncols); + pixmap.convertFromImage(image); + } return pixmap; } QImage OGfxEffect::gradient(const QSize &size, const QColor &ca, const QColor &cb, GradientType eff, int /*ncols*/) { int rDiff, gDiff, bDiff; int rca, gca, bca, rcb, gcb, bcb; QImage image(size, 32); if (size.width() == 0 || size.height() == 0) { qDebug ( "WARNING: OGfxEffect::gradient: invalid image" ); return image; } register int x, y; rDiff = (rcb = cb.red()) - (rca = ca.red()); gDiff = (gcb = cb.green()) - (gca = ca.green()); bDiff = (bcb = cb.blue()) - (bca = ca.blue()); if( eff == VerticalGradient || eff == HorizontalGradient ){ uint *p; uint rgb; register int rl = rca << 16; register int gl = gca << 16; register int bl = bca << 16; if( eff == VerticalGradient ) { int rcdelta = ((1<<16) / size.height()) * rDiff; int gcdelta = ((1<<16) / size.height()) * gDiff; int bcdelta = ((1<<16) / size.height()) * bDiff; for ( y = 0; y < size.height(); y++ ) { p = (uint *) image.scanLine(y); rl += rcdelta; gl += gcdelta; bl += bcdelta; rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); for( x = 0; x < size.width(); x++ ) { *p = rgb; p++; } } } else { // must be HorizontalGradient unsigned int *o_src = (unsigned int *)image.scanLine(0); unsigned int *src = o_src; int rcdelta = ((1<<16) / size.width()) * rDiff; int gcdelta = ((1<<16) / size.width()) * gDiff; int bcdelta = ((1<<16) / size.width()) * bDiff; for( x = 0; x < size.width(); x++) { rl += rcdelta; gl += gcdelta; bl += bcdelta; *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16)); } src = o_src; // Believe it or not, manually copying in a for loop is faster // than calling memcpy for each scanline (on the order of ms...). // I think this is due to the function call overhead (mosfet). for (y = 1; y < size.height(); ++y) { p = (unsigned int *)image.scanLine(y); src = o_src; for(x=0; x < size.width(); ++x) *p++ = *src++; } } } else { float rfd, gfd, bfd; float rd = rca, gd = gca, bd = bca; unsigned char *xtable[3]; unsigned char *ytable[3]; unsigned int w = size.width(), h = size.height(); @@ -187,201 +188,202 @@ QImage OGfxEffect::gradient(const QSize &size, const QColor &ca, gd = (float)gDiff/2; bd = (float)bDiff/2; for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd) { xtable[0][x] = (unsigned char) abs((int)rd); xtable[1][x] = (unsigned char) abs((int)gd); xtable[2][x] = (unsigned char) abs((int)bd); } rfd = (float)rDiff/size.height(); gfd = (float)gDiff/size.height(); bfd = (float)bDiff/size.height(); rd = (float)rDiff/2; gd = (float)gDiff/2; bd = (float)bDiff/2; for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) { ytable[0][y] = (unsigned char) abs((int)rd); ytable[1][y] = (unsigned char) abs((int)gd); ytable[2][y] = (unsigned char) abs((int)bd); } unsigned int rgb; int h = (size.height()+1)>>1; for (y = 0; y < h; y++) { unsigned int *sl1 = (unsigned int *)image.scanLine(y); unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); int w = (size.width()+1)>>1; int x2 = size.width()-1; for (x = 0; x < w; x++, x2--) { rgb = 0; if (eff == PyramidGradient) { rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), gcb-gSign*(xtable[1][x]+ytable[1][y]), bcb-bSign*(xtable[2][x]+ytable[2][y])); } if (eff == RectangleGradient) { rgb = qRgb(rcb - rSign * QMAX(xtable[0][x], ytable[0][y]) * 2, gcb - gSign * QMAX(xtable[1][x], ytable[1][y]) * 2, bcb - bSign * QMAX(xtable[2][x], ytable[2][y]) * 2); } if (eff == PipeCrossGradient) { rgb = qRgb(rcb - rSign * QMIN(xtable[0][x], ytable[0][y]) * 2, gcb - gSign * QMIN(xtable[1][x], ytable[1][y]) * 2, bcb - bSign * QMIN(xtable[2][x], ytable[2][y]) * 2); } if (eff == EllipticGradient) { rgb = qRgb(rcb - rSign * (int)sqrt((xtable[0][x]*xtable[0][x] + ytable[0][y]*ytable[0][y])*2.0), gcb - gSign * (int)sqrt((xtable[1][x]*xtable[1][x] + ytable[1][y]*ytable[1][y])*2.0), bcb - bSign * (int)sqrt((xtable[2][x]*xtable[2][x] + ytable[2][y]*ytable[2][y])*2.0)); } sl1[x] = sl2[x] = rgb; sl1[x2] = sl2[x2] = rgb; } } } delete [] xtable[0]; delete [] xtable[1]; delete [] xtable[2]; delete [] ytable[0]; delete [] ytable[1]; delete [] ytable[2]; } return image; } //====================================================================== // // Blend effects // //====================================================================== QPixmap& OGfxEffect::blend(QPixmap &pixmap, float initial_intensity, const QColor &bgnd, GradientType eff, bool anti_dir, int /*ncols*/) { - QImage image = pixmap.convertToImage(); - OGfxEffect::blend(image, initial_intensity, bgnd, eff, anti_dir); - - if ( pixmap. depth ( ) <= 8 ) - image. convertDepth ( pixmap. depth ( )); + if ( !pixmap. isNull ( )) { + QImage image = pixmap.convertToImage(); + OGfxEffect::blend(image, initial_intensity, bgnd, eff, anti_dir); - pixmap.convertFromImage(image); + if ( pixmap. depth ( ) <= 8 ) + image. convertDepth ( pixmap. depth ( )); - return pixmap; + pixmap.convertFromImage(image); + } + return pixmap; } QImage& OGfxEffect::blend(QImage &image, float initial_intensity, const QColor &bgnd, GradientType eff, bool anti_dir) { if (image.width() == 0 || image.height() == 0) { qDebug ( "Invalid image\n" ); return image; } int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue(); int r, g, b; int ind; unsigned int xi, xf, yi, yf; unsigned int a; // check the boundaries of the initial intesity param float unaffected = 1; if (initial_intensity > 1) initial_intensity = 1; if (initial_intensity < -1) initial_intensity = -1; if (initial_intensity < 0) { unaffected = 1. + initial_intensity; initial_intensity = 0; } float intensity = initial_intensity; float var = 1. - initial_intensity; if (anti_dir) { initial_intensity = intensity = 1.; var = -var; } register int x, y; unsigned int *data = (unsigned int *)image.bits(); if( eff == VerticalGradient || eff == HorizontalGradient ) { // set the image domain to apply the effect to xi = 0, xf = image.width(); yi = 0, yf = image.height(); if (eff == VerticalGradient) { if (anti_dir) yf = (int)(image.height() * unaffected); else yi = (int)(image.height() * (1 - unaffected)); } else { if (anti_dir) xf = (int)(image.width() * unaffected); else xi = (int)(image.height() * (1 - unaffected)); } var /= (eff == VerticalGradient?yf-yi:xf-xi); for (y = yi; y < (int)yf; y++) { intensity = eff == VerticalGradient? intensity + var : initial_intensity; for (x = xi; x < (int)xf ; x++) { if (eff == HorizontalGradient) intensity += var; ind = x + image.width() * y ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; a = qAlpha(data[ind]); data[ind] = qRgba(r, g, b, a); } } } else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) { float xvar = var / 2 / image.width(); // / unaffected; float yvar = var / 2 / image.height(); // / unaffected; float tmp; for (x = 0; x < image.width() ; x++) { tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1); for (y = 0; y < image.height() ; y++) { intensity = initial_intensity + tmp + yvar * y; ind = x + image.width() * y ; r = qRed (data[ind]) + (int)(intensity * (r_bgnd - qRed (data[ind]))); g = qGreen(data[ind]) + (int)(intensity * (g_bgnd - qGreen(data[ind]))); b = qBlue (data[ind]) + (int)(intensity * (b_bgnd - qBlue (data[ind]))); if (r > 255) r = 255; if (r < 0 ) r = 0; if (g > 255) g = 255; if (g < 0 ) g = 0; if (b > 255) b = 255; if (b < 0 ) b = 0; diff --git a/noncore/styles/theme/othemestyle.cpp b/noncore/styles/theme/othemestyle.cpp index a820efb..98e7253 100644 --- a/noncore/styles/theme/othemestyle.cpp +++ b/noncore/styles/theme/othemestyle.cpp @@ -156,233 +156,237 @@ void OThemeStyle::polish( QWidget *w ) if ( w->inherits( "QLabel" ) || w->inherits( "QSlider" ) || w->inherits( "QButton" ) || w->inherits( "QProgressBar" ) ) { w->setBackgroundOrigin( QWidget::ParentOrigin ); } } if ( w->inherits( "QPopupMenu" ) ) { popupPalette = w->palette(); if ( isColor( MenuItem ) || isColor( MenuItemDown ) ) { QPalette newPal( w->palette() ); w->setPalettePropagation( QWidget::SamePalette ); if ( isColor( MenuItem ) ) { newPal.setNormal( *colorGroup( newPal.normal(), MenuItem ) ); newPal.setDisabled( *colorGroup( newPal.normal(), MenuItem ) ); } if ( isColor( MenuItemDown ) ) newPal.setActive( *colorGroup( newPal.active(), MenuItemDown ) ); w->setPalette( newPal ); } } else if ( w->inherits( "QCheckBox" ) ) { if ( isColor( IndicatorOff ) || isColor( IndicatorOn ) ) { QPalette newPal( w->palette() ); w->setPalettePropagation( QWidget::SamePalette ); if ( isColor( IndicatorOff ) ) { newPal.setNormal( *colorGroup( newPal.normal(), IndicatorOff ) ); newPal.setDisabled( *colorGroup( newPal.normal(), IndicatorOff ) ); } if ( isColor( IndicatorOn ) ) newPal.setActive( *colorGroup( newPal.active(), IndicatorOn ) ); w->setPalette( newPal ); } } else if ( w->inherits( "QRadioButton" ) ) { if ( isColor( ExIndicatorOff ) || isColor( ExIndicatorOn ) ) { QPalette newPal( w->palette() ); w->setPalettePropagation( QWidget::SamePalette ); if ( isColor( ExIndicatorOff ) ) { newPal.setNormal( *colorGroup( newPal.normal(), ExIndicatorOff ) ); newPal.setDisabled( *colorGroup( newPal.normal(), ExIndicatorOff ) ); } if ( isColor( ExIndicatorOn ) ) newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOn ) ); w->setPalette( newPal ); } } else if ( w-> inherits ( "QProgressBar" ) ) { w-> installEventFilter ( this ); } } void OThemeStyle::unPolish( QWidget* w ) { if ( !w->isTopLevel() ) { if ( w->inherits( "QGroupBox" ) || w->inherits( "QTabWidget" ) ) { w->setAutoMask( FALSE ); return ; } if ( w->inherits( "QLabel" ) || w->inherits( "QSlider" ) || w->inherits( "QButton" ) || w->inherits( "QProgressBar" ) ) { w->setBackgroundOrigin( QWidget::WidgetOrigin ); } } if ( w->inherits( "QPopupMenu" ) ) w->unsetPalette(); else if ( w->inherits( "QCheckBox" ) ) w->unsetPalette(); else if ( w->inherits( "QRadioButton" ) ) w->unsetPalette(); else if ( w-> inherits ( "QProgressBar" ) ) w-> removeEventFilter ( this ); } bool OThemeStyle::eventFilter ( QObject *obj, QEvent *ev ) { // only QProgressBar so far if ( ev-> type ( ) == QEvent::Paint ) { HackProgressBar *pb = (HackProgressBar *) obj; pb-> paint ((QPaintEvent *) ev, this ); return true; } return false; } void OThemeStyle::drawBaseButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool rounded, WidgetType type, const QBrush * ) { + if ( w <= 0 || h <= 0 ) + return; + int offset = borderPixmap( type ) ? 0 : decoWidth( type ); QPen oldPen = p->pen(); // handle reverse bevel here since it uses decowidth differently if ( gradientHint( type ) == GrReverseBevel ) { int i; bitBlt( p->device(), x, y, scalePixmap( w, h, type ), 0, 0, w, h, Qt::CopyROP, true ); p->setPen( g.text() ); for ( i = 0; i < borderWidth( type ); ++i, ++x, ++y, w -= 2, h -= 2 ) p->drawRect( x, y, w, h ); } // same with KDE style borders else if ( !borderPixmap( type ) && shade() == KDE ) { qDrawWinButton( p, x, y, w, h, g, sunken ); if ( isPixmap( type ) ) p->drawTiledPixmap( x + 4, y + 4, w - 6, h - 6, *scalePixmap( w - 6, h - 6, type ) ); else p->fillRect( x + 4, y + 4, w - 6, h - offset * 6, g.brush( QColorGroup::Button ) ); } else { if ( ( w - offset * 2 ) > 0 && ( h - offset * 2 ) > 0 ) { if ( isPixmap( type ) ) if ( rounded ) p->drawTiledPixmap( x, y, w, h, *scalePixmap( w, h, type ) ); else p->drawTiledPixmap( x + offset, y + offset, w - offset * 2, h - offset * 2, *scalePixmap( w - offset * 2, h - offset * 2, type ) ); else p->fillRect( x + offset, y + offset, w - offset * 2, h - offset * 2, g.brush( QColorGroup::Button ) ); } - if ( borderPixmap( type ) ) + if ( borderPixmap( type ) ) { bitBlt( p->device(), x, y, scaleBorder( w, h, type ), 0, 0, w, h, Qt::CopyROP, false ); + } else drawShade( p, x, y, w, h, g, sunken, rounded, highlightWidth( type ), borderWidth( type ), shade() ); } p->setPen( oldPen ); } void OThemeStyle::drawButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush *fill ) { drawBaseButton( p, x, y, w, h, g, sunken, roundButton(), sunken ? PushButtonDown : PushButton, fill ); } void OThemeStyle::drawPushButton( QPushButton* btn, QPainter *p ) { bool sunken = btn->isOn() || btn->isDown(); int diw = buttonDefaultIndicatorWidth(); drawBaseButton( p, diw, diw, btn->width() - 2 * diw, btn->height() - 2 * diw, *colorGroup( btn->colorGroup(), sunken ? PushButtonDown : PushButton ), sunken, roundButton(), sunken ? PushButtonDown : PushButton, NULL ); // TODO if diw, draw fancy default button indicator } void OThemeStyle::drawBaseMask( QPainter *p, int x, int y, int w, int h, bool round ) { // round edge fills static const QCOORD btm_left_fill[] = { 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 2, 3, 3, 3, 4, 3, 3, 4, 4, 4 }; static const QCOORD btm_right_fill[] = { 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 0, 4, 1, 4 }; static const QCOORD top_left_fill[] = { 3, 0, 4, 0, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4 }; static const QCOORD top_right_fill[] = { 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4 }; QBrush fillBrush( color1, SolidPattern ); p->setPen( color1 ); if ( round && w > 19 && h > 19 ) { int x2 = x + w - 1; int y2 = y + h - 1; QPointArray a( QCOORDARRLEN( top_left_fill ), top_left_fill ); a.translate( 1, 1 ); p->drawPoints( a ); a.setPoints( QCOORDARRLEN( btm_left_fill ), btm_left_fill ); a.translate( 1, h - 6 ); p->drawPoints( a ); a.setPoints( QCOORDARRLEN( top_right_fill ), top_right_fill ); a.translate( w - 6, 1 ); p->drawPoints( a ); a.setPoints( QCOORDARRLEN( btm_right_fill ), btm_right_fill ); a.translate( w - 6, h - 6 ); p->drawPoints( a ); p->fillRect( x + 6, y, w - 12, h, fillBrush ); p->fillRect( x, y + 6, x + 6, h - 12, fillBrush ); p->fillRect( x2 - 6, y + 6, x2, h - 12, fillBrush ); p->drawLine( x + 6, y, x2 - 6, y ); p->drawLine( x + 6, y2, x2 - 6, y2 ); p->drawLine( x, y + 6, x, y2 - 6 ); p->drawLine( x2, y + 6, x2, y2 - 6 ); } else p->fillRect( x, y, w, h, fillBrush ); } void OThemeStyle::drawButtonMask( QPainter *p, int x, int y, int w, int h ) { drawBaseMask( p, x, y, w, h, roundButton() ); } void OThemeStyle::drawComboButtonMask( QPainter *p, int x, int y, int w, int h ) { drawBaseMask( p, x, y, w, h, roundComboBox() ); } void OThemeStyle::drawBevelButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, const QBrush * ) { WidgetType type = sunken ? BevelDown : Bevel; |