summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/styles/theme/ogfxeffect.cpp22
-rw-r--r--noncore/styles/theme/othemestyle.cpp6
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;