summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/styles/theme/ogfxeffect.cpp249
-rw-r--r--noncore/styles/theme/ogfxeffect.h3
-rw-r--r--noncore/styles/theme/othemestyle.cpp7
3 files changed, 223 insertions, 36 deletions
diff --git a/noncore/styles/theme/ogfxeffect.cpp b/noncore/styles/theme/ogfxeffect.cpp
index 55f3c1f..cc5bbcd 100644
--- a/noncore/styles/theme/ogfxeffect.cpp
+++ b/noncore/styles/theme/ogfxeffect.cpp
@@ -18,74 +18,257 @@
18//====================================================================== 18//======================================================================
19// 19//
20// Gradient effects 20// Gradient effects
21// 21//
22//====================================================================== 22//======================================================================
23 23
24 24
25QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca, 25QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca,
26 const QColor &cb, GradientType eff, int /*ncols*/) 26 const QColor &cb, GradientType eff, int ncols)
27{ 27{
28 if(pixmap.depth() > 8 && 28 QImage image = gradient(pixmap.size(), ca, cb, eff, ncols);
29 (eff == VerticalGradient || eff == HorizontalGradient)) { 29 pixmap.convertFromImage(image);
30 30
31 int rDiff, gDiff, bDiff; 31 return pixmap;
32 int rca, gca, bca /*, rcb, gcb, bcb*/; 32}
33
34QImage OGfxEffect::gradient(const QSize &size, const QColor &ca,
35 const QColor &cb, GradientType eff, int /*ncols*/)
36{
37 int rDiff, gDiff, bDiff;
38 int rca, gca, bca, rcb, gcb, bcb;
39
40 QImage image(size, 32);
41
42 if (size.width() == 0 || size.height() == 0) {
43 qDebug ( "WARNING: OGfxEffect::gradient: invalid image" );
44 return image;
45 }
46
47 register int x, y;
33 48
34 register int x, y; 49 rDiff = (rcb = cb.red()) - (rca = ca.red());
50 gDiff = (gcb = cb.green()) - (gca = ca.green());
51 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
35 52
36 rDiff = (/*rcb = */ cb.red()) - (rca = ca.red()); 53 if( eff == VerticalGradient || eff == HorizontalGradient ){
37 gDiff = (/*gcb = */ cb.green()) - (gca = ca.green()); 54
38 bDiff = (/*bcb = */ cb.blue()) - (bca = ca.blue()); 55 uint *p;
56 uint rgb;
39 57
40 register int rl = rca << 16; 58 register int rl = rca << 16;
41 register int gl = gca << 16; 59 register int gl = gca << 16;
42 register int bl = bca << 16; 60 register int bl = bca << 16;
43 61
44 int rcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * rDiff; 62 if( eff == VerticalGradient ) {
45 int gcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * gDiff; 63
46 int bcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * bDiff; 64 int rcdelta = ((1<<16) / size.height()) * rDiff;
65 int gcdelta = ((1<<16) / size.height()) * gDiff;
66 int bcdelta = ((1<<16) / size.height()) * bDiff;
47 67
48 QPainter p(&pixmap); 68 for ( y = 0; y < size.height(); y++ ) {
69 p = (uint *) image.scanLine(y);
49 70
50 // these for-loops could be merged, but the if's in the inner loop
51 // would make it slow
52 switch(eff) {
53 case VerticalGradient:
54 for ( y = 0; y < pixmap.height(); y++ ) {
55 rl += rcdelta; 71 rl += rcdelta;
56 gl += gcdelta; 72 gl += gcdelta;
57 bl += bcdelta; 73 bl += bcdelta;
58 74
59 p.setPen(QColor(rl>>16, gl>>16, bl>>16)); 75 rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) );
60 p.drawLine(0, y, pixmap.width()-1, y); 76
77 for( x = 0; x < size.width(); x++ ) {
78 *p = rgb;
79 p++;
80 }
61 } 81 }
62 break; 82
63 case HorizontalGradient: 83 }
64 for( x = 0; x < pixmap.width(); x++) { 84 else { // must be HorizontalGradient
85
86 unsigned int *o_src = (unsigned int *)image.scanLine(0);
87 unsigned int *src = o_src;
88
89 int rcdelta = ((1<<16) / size.width()) * rDiff;
90 int gcdelta = ((1<<16) / size.width()) * gDiff;
91 int bcdelta = ((1<<16) / size.width()) * bDiff;
92
93 for( x = 0; x < size.width(); x++) {
94
65 rl += rcdelta; 95 rl += rcdelta;
66 gl += gcdelta; 96 gl += gcdelta;
67 bl += bcdelta; 97 bl += bcdelta;
68 98
69 p.setPen(QColor(rl>>16, gl>>16, bl>>16)); 99 *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16));
70 p.drawLine(x, 0, x, pixmap.height()-1); 100 }
101
102 src = o_src;
103
104 // Believe it or not, manually copying in a for loop is faster
105 // than calling memcpy for each scanline (on the order of ms...).
106 // I think this is due to the function call overhead (mosfet).
107
108 for (y = 1; y < size.height(); ++y) {
109
110 p = (unsigned int *)image.scanLine(y);
111 src = o_src;
112 for(x=0; x < size.width(); ++x)
113 *p++ = *src++;
71 } 114 }
72 break;
73 default:
74 ;
75 } 115 }
76 } 116 }
117
77 else { 118 else {
78// QImage image = OGfxEffect::gradient(pixmap.size(), ca, cb,
79// (OGfxEffect::GradientType) eff, ncols);
80// pixmap.convertFromImage(image);
81 }
82 119
83 return pixmap; 120 float rfd, gfd, bfd;
121 float rd = rca, gd = gca, bd = bca;
122
123 unsigned char *xtable[3];
124 unsigned char *ytable[3];
125
126 unsigned int w = size.width(), h = size.height();
127 xtable[0] = new unsigned char[w];
128 xtable[1] = new unsigned char[w];
129 xtable[2] = new unsigned char[w];
130 ytable[0] = new unsigned char[h];
131 ytable[1] = new unsigned char[h];
132 ytable[2] = new unsigned char[h];
133 w*=2, h*=2;
134
135 if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) {
136 // Diagonal dgradient code inspired by BlackBox (mosfet)
137 // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and
138 // Mike Cole <mike@mydot.com>.
139
140 rfd = (float)rDiff/w;
141 gfd = (float)gDiff/w;
142 bfd = (float)bDiff/w;
143
144 int dir;
145 for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) {
146 dir = eff == DiagonalGradient? x : size.width() - x - 1;
147 xtable[0][dir] = (unsigned char) rd;
148 xtable[1][dir] = (unsigned char) gd;
149 xtable[2][dir] = (unsigned char) bd;
150 }
151 rfd = (float)rDiff/h;
152 gfd = (float)gDiff/h;
153 bfd = (float)bDiff/h;
154 rd = gd = bd = 0;
155 for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) {
156 ytable[0][y] = (unsigned char) rd;
157 ytable[1][y] = (unsigned char) gd;
158 ytable[2][y] = (unsigned char) bd;
159 }
160
161 for (y = 0; y < size.height(); y++) {
162 unsigned int *scanline = (unsigned int *)image.scanLine(y);
163 for (x = 0; x < size.width(); x++) {
164 scanline[x] = qRgb(xtable[0][x] + ytable[0][y],
165 xtable[1][x] + ytable[1][y],
166 xtable[2][x] + ytable[2][y]);
167 }
168 }
169 }
170
171 else if (eff == RectangleGradient ||
172 eff == PyramidGradient ||
173 eff == PipeCrossGradient ||
174 eff == EllipticGradient)
175 {
176 int rSign = rDiff>0? 1: -1;
177 int gSign = gDiff>0? 1: -1;
178 int bSign = bDiff>0? 1: -1;
179
180 rfd = (float)rDiff / size.width();
181 gfd = (float)gDiff / size.width();
182 bfd = (float)bDiff / size.width();
183
184 rd = (float)rDiff/2;
185 gd = (float)gDiff/2;
186 bd = (float)bDiff/2;
187
188 for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd)
189 {
190 xtable[0][x] = (unsigned char) abs((int)rd);
191 xtable[1][x] = (unsigned char) abs((int)gd);
192 xtable[2][x] = (unsigned char) abs((int)bd);
193 }
194
195 rfd = (float)rDiff/size.height();
196 gfd = (float)gDiff/size.height();
197 bfd = (float)bDiff/size.height();
198
199 rd = (float)rDiff/2;
200 gd = (float)gDiff/2;
201 bd = (float)bDiff/2;
202
203 for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd)
204 {
205 ytable[0][y] = (unsigned char) abs((int)rd);
206 ytable[1][y] = (unsigned char) abs((int)gd);
207 ytable[2][y] = (unsigned char) abs((int)bd);
208 }
209 unsigned int rgb;
210 int h = (size.height()+1)>>1;
211 for (y = 0; y < h; y++) {
212 unsigned int *sl1 = (unsigned int *)image.scanLine(y);
213 unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y));
214
215 int w = (size.width()+1)>>1;
216 int x2 = size.width()-1;
217
218 for (x = 0; x < w; x++, x2--) {
219 rgb = 0;
220 if (eff == PyramidGradient) {
221 rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]),
222 gcb-gSign*(xtable[1][x]+ytable[1][y]),
223 bcb-bSign*(xtable[2][x]+ytable[2][y]));
224 }
225 if (eff == RectangleGradient) {
226 rgb = qRgb(rcb - rSign *
227 QMAX(xtable[0][x], ytable[0][y]) * 2,
228 gcb - gSign *
229 QMAX(xtable[1][x], ytable[1][y]) * 2,
230 bcb - bSign *
231 QMAX(xtable[2][x], ytable[2][y]) * 2);
232 }
233 if (eff == PipeCrossGradient) {
234 rgb = qRgb(rcb - rSign *
235 QMIN(xtable[0][x], ytable[0][y]) * 2,
236 gcb - gSign *
237 QMIN(xtable[1][x], ytable[1][y]) * 2,
238 bcb - bSign *
239 QMIN(xtable[2][x], ytable[2][y]) * 2);
240 }
241 if (eff == EllipticGradient) {
242 rgb = qRgb(rcb - rSign *
243 (int)sqrt((xtable[0][x]*xtable[0][x] +
244 ytable[0][y]*ytable[0][y])*2.0),
245 gcb - gSign *
246 (int)sqrt((xtable[1][x]*xtable[1][x] +
247 ytable[1][y]*ytable[1][y])*2.0),
248 bcb - bSign *
249 (int)sqrt((xtable[2][x]*xtable[2][x] +
250 ytable[2][y]*ytable[2][y])*2.0));
251 }
252
253 sl1[x] = sl2[x] = rgb;
254 sl1[x2] = sl2[x2] = rgb;
255 }
256 }
257 }
258
259 delete [] xtable[0];
260 delete [] xtable[1];
261 delete [] xtable[2];
262 delete [] ytable[0];
263 delete [] ytable[1];
264 delete [] ytable[2];
265 }
266 return image;
84} 267}
85 268
86 269
87//====================================================================== 270//======================================================================
88// 271//
89// Blend effects 272// Blend effects
90// 273//
91//====================================================================== 274//======================================================================
diff --git a/noncore/styles/theme/ogfxeffect.h b/noncore/styles/theme/ogfxeffect.h
index 45a8482..755537f 100644
--- a/noncore/styles/theme/ogfxeffect.h
+++ b/noncore/styles/theme/ogfxeffect.h
@@ -43,16 +43,19 @@ public:
43 * @param ncols The number of colors to use when not running on a 43 * @param ncols The number of colors to use when not running on a
44 * truecolor display. The gradient will be dithered to this number of 44 * truecolor display. The gradient will be dithered to this number of
45 * colors. Pass 0 to prevent dithering. 45 * colors. Pass 0 to prevent dithering.
46 * @return Returns the generated pixmap, for convenience. 46 * @return Returns the generated pixmap, for convenience.
47 */ 47 */
48 static QPixmap& gradient(QPixmap& pixmap, const QColor &ca, const QColor &cb, 48 static QPixmap& gradient(QPixmap& pixmap, const QColor &ca, const QColor &cb,
49 GradientType type, int ncols=3); 49 GradientType type, int ncols=3);
50 50
51 static QImage gradient (const QSize &size, const QColor &ca, const QColor &cb,
52 GradientType type, int ncols=3);
53
51 54
52 /** 55 /**
53 * Blend the provided pixmap into a background of the indicated color 56 * Blend the provided pixmap into a background of the indicated color
54 * 57 *
55 * @param pixmap The pixmap to process. 58 * @param pixmap The pixmap to process.
56 * @param initial_intensity this parameter takes values from -1 to 1: 59 * @param initial_intensity this parameter takes values from -1 to 1:
57 * @li If positive, it tells how much to fade the image in its 60 * @li If positive, it tells how much to fade the image in its
58 * less affected spot. 61 * less affected spot.
diff --git a/noncore/styles/theme/othemestyle.cpp b/noncore/styles/theme/othemestyle.cpp
index d97b026..8c7a71b 100644
--- a/noncore/styles/theme/othemestyle.cpp
+++ b/noncore/styles/theme/othemestyle.cpp
@@ -1205,25 +1205,26 @@ void OThemeStyle::drawPopupMenuItem( QPainter* p, bool checkable, int maxpmw,
1205 if ( act ) { 1205 if ( act ) {
1206 drawBaseButton( p, x, y, w, h, g, true, false, MenuItemDown ); 1206 drawBaseButton( p, x, y, w, h, g, true, false, MenuItemDown );
1207 } 1207 }
1208 else { 1208 else {
1209 drawShade( p, x, y, w, h, *colorGroup( g, MenuItem ), false, false, 1209 drawShade( p, x, y, w, h, *colorGroup( g, MenuItem ), false, false,
1210 highlightWidth( MenuItem ), borderWidth( MenuItem ), 1210 highlightWidth( MenuItem ), borderWidth( MenuItem ),
1211 shade() ); 1211 shade() );
1212 int dw = decoWidth( MenuItem ); 1212 int dw = decoWidth( MenuItem );
1213 if ( !isPixmap( MenuItem ) ) 1213 if ( !isPixmap( MenuItem ) ) {
1214 p->fillRect( x + dw, y + dw, w - dw * 2, h - dw * 2, 1214 p->fillRect( x + dw, y + dw, w - dw * 2, h - dw * 2,
1215 colorGroup( g, MenuItem ) -> 1215 colorGroup( g, MenuItem ) ->
1216 brush( QColorGroup::Background ) ); 1216 brush( QColorGroup::Background ) );
1217 }
1217 else { 1218 else {
1218 // process inactive item pixmaps as one large item 1219 // process inactive item pixmaps as one large item
1219 p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap 1220 p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap
1220 // (w, p->window().height(), MenuItem), 1221 (w, ((QWidget *)p->device())->height(), MenuItem),
1221 ( w, p->clipRegion().boundingRect().height(), MenuItem ), 1222 //( w, p->clipRegion().boundingRect().height(), MenuItem ), // cliping does not work in Qt/E
1222 x, y ); 1223 x, y );
1223 } 1224 }
1224 1225
1225 if ( checkable && mi && mi->isChecked() ) { 1226 if ( checkable && mi && mi->isChecked() ) {
1226 // draw 'pressed' border around checkable items 1227 // draw 'pressed' border around checkable items
1227 // This is extremely important for items that have an iconset 1228 // This is extremely important for items that have an iconset
1228 // because the checkmark isn't drawn in that case 1229 // because the checkmark isn't drawn in that case
1229 // An alternative would be superimposing the checkmark over 1230 // An alternative would be superimposing the checkmark over