]>
Dogcows Code - chaz/openbox/blob - otk/truerendercontrol.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
7 #include "truerendercontrol.hh"
9 #include "screeninfo.hh"
11 #include "rendertexture.hh"
16 #endif // HAVE_STDLIB_H
18 #include "../src/gettext.h"
19 #define _(str) gettext(str)
24 TrueRenderControl::TrueRenderControl(int screen
)
25 : RenderControl(screen
),
30 printf("Initializing TrueColor RenderControl\n");
32 Visual
*visual
= display
->screenInfo(_screen
)->visual();
33 unsigned long red_mask
, green_mask
, blue_mask
;
35 // find the offsets for each color in the visual's masks
36 red_mask
= visual
->red_mask
;
37 green_mask
= visual
->green_mask
;
38 blue_mask
= visual
->blue_mask
;
40 while (! (red_mask
& 1)) { _red_offset
++; red_mask
>>= 1; }
41 while (! (green_mask
& 1)) { _green_offset
++; green_mask
>>= 1; }
42 while (! (blue_mask
& 1)) { _blue_offset
++; blue_mask
>>= 1; }
44 _red_shift
= _green_shift
= _blue_shift
= 8;
45 while (red_mask
) { red_mask
>>= 1; _red_shift
--; }
46 while (green_mask
) { green_mask
>>= 1; _green_shift
--; }
47 while (blue_mask
) { blue_mask
>>= 1; _blue_shift
--; }
50 TrueRenderControl::~TrueRenderControl()
52 printf("Destroying TrueColor RenderControl\n");
58 static inline void renderPixel(XImage
*im
, unsigned char *dp
,
61 unsigned int bpp
= im
->bits_per_pixel
+ (im
->byte_order
== MSBFirst
? 1 : 0);
98 assert(false); // wtf?
102 void TrueRenderControl::drawGradientBackground(
103 Surface
&sf
, const RenderTexture
&texture
) const
106 int w
= sf
.width(), h
= sf
.height(), off
, x
;
108 const ScreenInfo
*info
= display
->screenInfo(_screen
);
109 XImage
*im
= XCreateImage(**display
, info
->visual(), info
->depth(),
110 ZPixmap
, 0, NULL
, w
, h
, 32, 0);
112 pixel32
*data
= new pixel32
[sf
.height()*sf
.width()];
115 switch (texture
.gradient()) {
116 case RenderTexture::Vertical
:
117 verticalGradient(sf
, texture
, data
);
119 case RenderTexture::Diagonal
:
120 diagonalGradient(sf
, texture
, data
);
122 case RenderTexture::CrossDiagonal
:
123 crossDiagonalGradient(sf
, texture
, data
);
126 printf("unhandled gradient\n");
129 if (texture
.relief() == RenderTexture::Flat
&& texture
.border()) {
130 r
= texture
.borderColor().red();
131 g
= texture
.borderColor().green();
132 b
= texture
.borderColor().blue();
133 current
= (r
<< default_red_shift
)
134 + (g
<< default_green_shift
)
135 + (b
<< default_blue_shift
);
136 for (off
= 0, x
= 0; x
< w
; ++x
, off
++) {
137 *(data
+ off
) = current
;
138 *(data
+ off
+ ((h
-1) * w
)) = current
;
140 for (off
= 0, x
= 0; x
< h
; ++x
, off
++) {
141 *(data
+ (off
* w
)) = current
;
142 *(data
+ (off
* w
) + w
- 1) = current
;
146 if (texture
.relief() != RenderTexture::Flat
) {
147 if (texture
.bevel() == RenderTexture::Bevel1
) {
148 for (off
= 1, x
= 1; x
< w
- 1; ++x
, off
++)
149 highlight(data
+ off
,
150 data
+ off
+ (h
-1) * w
,
151 texture
.relief()==RenderTexture::Raised
);
152 for (off
= 0, x
= 0; x
< h
; ++x
, off
++)
153 highlight(data
+ off
* w
,
154 data
+ off
* w
+ w
- 1,
155 texture
.relief()==RenderTexture::Raised
);
158 if (texture
.bevel() == RenderTexture::Bevel2
) {
159 for (off
= 2, x
= 2; x
< w
- 2; ++x
, off
++)
160 highlight(data
+ off
+ w
,
161 data
+ off
+ (h
-2) * w
,
162 texture
.relief()==RenderTexture::Raised
);
163 for (off
= 1, x
= 1; x
< h
-1; ++x
, off
++)
164 highlight(data
+ off
* w
+ 1,
165 data
+ off
* w
+ w
- 2,
166 texture
.relief()==RenderTexture::Raised
);
170 reduceDepth(im
, data
);
172 im
->data
= (char*) data
;
181 void TrueRenderControl::verticalGradient(Surface
&sf
,
182 const RenderTexture
&texture
,
189 dr
= (float)(texture
.secondary_color().red() - texture
.color().red());
190 dr
/= (float)sf
.height();
192 dg
= (float)(texture
.secondary_color().green() - texture
.color().green());
193 dg
/= (float)sf
.height();
195 db
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
196 db
/= (float)sf
.height();
198 for (int y
= 0; y
< sf
.height(); ++y
) {
199 r
= texture
.color().red() + (int)(dr
* y
);
200 g
= texture
.color().green() + (int)(dg
* y
);
201 b
= texture
.color().blue() + (int)(db
* y
);
202 current
= (r
<< default_red_shift
)
203 + (g
<< default_green_shift
)
204 + (b
<< default_blue_shift
);
205 for (int x
= 0; x
< sf
.width(); ++x
, ++data
)
210 void TrueRenderControl::diagonalGradient(Surface
&sf
,
211 const RenderTexture
&texture
,
215 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
219 for (int y
= 0; y
< sf
.height(); ++y
) {
220 drx
= (float)(texture
.secondary_color().red() - texture
.color().red());
221 dry
= drx
/(float)sf
.height();
222 drx
/= (float)sf
.width();
224 dgx
= (float)(texture
.secondary_color().green() - texture
.color().green());
225 dgy
= dgx
/(float)sf
.height();
226 dgx
/= (float)sf
.width();
228 dbx
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
229 dby
= dbx
/(float)sf
.height();
230 dbx
/= (float)sf
.width();
231 for (int x
= 0; x
< sf
.width(); ++x
, ++data
) {
232 r
= texture
.color().red() + ((int)(drx
* x
) + (int)(dry
* y
))/2;
233 g
= texture
.color().green() + ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
234 b
= texture
.color().blue() + ((int)(dbx
* x
) + (int)(dby
* y
))/2;
235 current
= (r
<< default_red_shift
)
236 + (g
<< default_green_shift
)
237 + (b
<< default_blue_shift
);
243 void TrueRenderControl::crossDiagonalGradient(Surface
&sf
,
244 const RenderTexture
&texture
,
248 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
251 for (int y
= 0; y
< sf
.height(); ++y
) {
252 drx
= (float)(texture
.secondary_color().red() - texture
.color().red());
253 dry
= drx
/(float)sf
.height();
254 drx
/= (float)sf
.width();
256 dgx
= (float)(texture
.secondary_color().green() - texture
.color().green());
257 dgy
= dgx
/(float)sf
.height();
258 dgx
/= (float)sf
.width();
260 dbx
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
261 dby
= dbx
/(float)sf
.height();
262 dbx
/= (float)sf
.width();
263 for (int x
= sf
.width(); x
> 0; --x
, ++data
) {
264 r
= texture
.color().red() + ((int)(drx
* (x
-1)) + (int)(dry
* y
))/2;
265 g
= texture
.color().green() + ((int)(dgx
* (x
-1)) + (int)(dgy
* y
))/2;
266 b
= texture
.color().blue() + ((int)(dbx
* (x
-1)) + (int)(dby
* y
))/2;
267 current
= (r
<< default_red_shift
)
268 + (g
<< default_green_shift
)
269 + (b
<< default_blue_shift
);
274 void TrueRenderControl::reduceDepth(XImage
*im
, pixel32
*data
) const
276 // since pixel32 is the largest possible pixel size, we can share the array
279 pixel16
*p
= (pixel16
*)data
;
280 switch (im
->bits_per_pixel
) {
284 for (y
= 0; y
< im
->height
; y
++) {
285 for (x
= 0; x
< im
->width
; x
++) {
286 r
= (data
[x
] >> default_red_shift
) & 0xFF;
288 g
= (data
[x
] >> default_green_shift
) & 0xFF;
289 g
= g
>> _green_shift
;
290 b
= (data
[x
] >> default_blue_shift
) & 0xFF;
291 b
= b
>> _blue_shift
;
292 p
[x
] = (r
<< _red_offset
) + (g
<< _green_offset
) + (b
<< _blue_offset
);
295 p
+= im
->bytes_per_line
/2;
299 printf("your bit depth is currently unhandled\n");
303 void TrueRenderControl::highlight(pixel32
*x
, pixel32
*y
, bool raised
) const
315 r
= (*up
>> default_red_shift
) & 0xFF;
317 g
= (*up
>> default_green_shift
) & 0xFF;
319 b
= (*up
>> default_blue_shift
) & 0xFF;
321 if (r
> 255) r
= 255;
322 if (g
> 255) g
= 255;
323 if (b
> 255) b
= 255;
324 *up
= (r
<< default_red_shift
) + (g
<< default_green_shift
)
325 + (b
<< default_blue_shift
);
327 r
= (*down
>> default_red_shift
) & 0xFF;
328 r
= (r
>> 1) + (r
>> 2);
329 g
= (*down
>> default_green_shift
) & 0xFF;
330 g
= (g
>> 1) + (g
>> 2);
331 b
= (*down
>> default_blue_shift
) & 0xFF;
332 b
= (b
>> 1) + (b
>> 2);
333 *down
= (r
<< default_red_shift
) + (g
<< default_green_shift
)
334 + (b
<< default_blue_shift
);
336 void TrueRenderControl::drawBackground(Surface
& sf
,
337 const RenderTexture
&texture
) const
339 assert(_screen
== sf
._screen
);
340 assert(_screen
== texture
.color().screen());
342 if (texture
.gradient() == RenderTexture::Solid
) {
343 drawSolidBackground(sf
, texture
);
345 drawGradientBackground(sf
, texture
);
This page took 0.055425 seconds and 4 git commands to generate.