]>
Dogcows Code - chaz/openbox/blob - otk/rendercontrol.cc
a4de270a3ab6abe857fc43349624f8c1bb7185b2
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "rendercontrol.hh"
6 #include "truerendercontrol.hh"
7 #include "pseudorendercontrol.hh"
8 #include "rendertexture.hh"
9 #include "rendercolor.hh"
10 #include "renderstyle.hh"
12 #include "screeninfo.hh"
20 #endif // HAVE_STDLIB_H
22 #include "../src/gettext.h"
23 #define _(str) gettext(str)
28 RenderControl
*RenderControl::getRenderControl(int screen
)
30 // get the visual on the screen and return the correct type of RenderControl
31 int vclass
= display
->screenInfo(screen
)->visual()->c_class
;
34 return new TrueRenderControl(screen
);
37 return new PseudoRenderControl(screen
);
40 return new PseudoRenderControl(screen
);
42 printf(_("RenderControl: Unsupported visual %d specified. Aborting.\n"),
48 RenderControl::RenderControl(int screen
)
51 printf("Initializing RenderControl\n");
54 RenderControl::~RenderControl()
56 printf("Destroying RenderControl\n");
59 void RenderControl::drawRoot(const RenderColor
&color
) const
61 Window root
= display
->screenInfo(_screen
)->rootWindow();
62 XSetWindowBackground(**display
, root
, color
.pixel());
63 XClearWindow(**display
, root
);
66 void RenderControl::drawString(Surface
& sf
, const Font
&font
, int x
, int y
,
67 const RenderColor
&color
,
68 const ustring
&string
) const
70 assert(sf
._screen
== _screen
);
71 XftDraw
*d
= sf
._xftdraw
;
72 assert(d
); // this means that the background hasn't been rendered yet!
79 c
.color
.alpha
= font
._tint
| font
._tint
<< 8; // transparent shadow
80 c
.pixel
= BlackPixel(**display
, _screen
);
83 XftDrawStringUtf8(d
, &c
, font
._xftfont
, x
+ font
._offset
,
84 font
._xftfont
->ascent
+ y
+ font
._offset
,
85 (FcChar8
*)string
.c_str(), string
.bytes());
87 XftDrawString8(d
, &c
, font
._xftfont
, x
+ font
._offset
,
88 font
._xftfont
->ascent
+ y
+ font
._offset
,
89 (FcChar8
*)string
.c_str(), string
.bytes());
93 c
.color
.red
= color
.red() | color
.red() << 8;
94 c
.color
.green
= color
.green() | color
.green() << 8;
95 c
.color
.blue
= color
.blue() | color
.blue() << 8;
96 c
.pixel
= color
.pixel();
97 c
.color
.alpha
= 0xff | 0xff << 8; // no transparency in Color yet
100 XftDrawStringUtf8(d
, &c
, font
._xftfont
, x
, font
._xftfont
->ascent
+ y
,
101 (FcChar8
*)string
.c_str(), string
.bytes());
103 XftDrawString8(d
, &c
, font
._xftfont
, x
, font
._xftfont
->ascent
+ y
,
104 (FcChar8
*)string
.c_str(), string
.bytes());
108 void RenderControl::drawSolidBackground(Surface
& sf
,
109 const RenderTexture
& texture
) const
111 assert(_screen
== sf
._screen
);
112 assert(_screen
== texture
.color().screen());
114 if (texture
.parentRelative()) return;
116 sf
.setPixmap(texture
.color());
118 int width
= sf
.size().width(), height
= sf
.size().height();
119 int left
= 0, top
= 0, right
= width
- 1, bottom
= height
- 1;
121 if (texture
.interlaced())
122 for (int i
= 0; i
< height
; i
+= 2)
123 XDrawLine(**display
, sf
.pixmap(), texture
.interlaceColor().gc(),
126 switch (texture
.relief()) {
127 case RenderTexture::Raised
:
128 switch (texture
.bevel()) {
129 case RenderTexture::Bevel1
:
130 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
131 left
, bottom
, right
, bottom
);
132 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
133 right
, bottom
, right
, top
);
135 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
136 left
, top
, right
, top
);
137 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
138 left
, bottom
, left
, top
);
140 case RenderTexture::Bevel2
:
141 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
142 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
143 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
144 right
- 2, bottom
- 2, right
- 2, top
+ 1);
146 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
147 left
+ 1, top
+ 1, right
- 2, top
+ 1);
148 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
149 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
152 assert(false); // unhandled RenderTexture::BevelType
155 case RenderTexture::Sunken
:
156 switch (texture
.bevel()) {
157 case RenderTexture::Bevel1
:
158 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
159 left
, bottom
, right
, bottom
);
160 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
161 right
, bottom
, right
, top
);
163 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
164 left
, top
, right
, top
);
165 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
166 left
, bottom
, left
, top
);
168 case RenderTexture::Bevel2
:
169 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
170 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
171 XDrawLine(**display
, sf
.pixmap(), texture
.bevelLightColor().gc(),
172 right
- 2, bottom
- 2, right
- 2, top
+ 1);
174 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
175 left
+ 1, top
+ 1, right
- 2, top
+ 1);
176 XDrawLine(**display
, sf
.pixmap(), texture
.bevelDarkColor().gc(),
177 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
180 assert(false); // unhandled RenderTexture::BevelType
183 case RenderTexture::Flat
:
184 if (texture
.border())
185 XDrawRectangle(**display
, sf
.pixmap(), texture
.borderColor().gc(),
186 left
, top
, right
, bottom
);
189 assert(false); // unhandled RenderTexture::ReliefType
193 void RenderControl::drawMask(Surface
&sf
, const RenderColor
&color
,
194 const PixmapMask
&mask
) const
196 assert(_screen
== sf
._screen
);
197 assert(_screen
== color
.screen());
199 if (mask
.mask
== None
) return; // no mask given
201 int width
= sf
.size().width(), height
= sf
.size().height();
203 // set the clip region
204 int x
= (width
- mask
.w
) / 2, y
= (height
- mask
.h
) / 2;
205 XSetClipMask(**display
, color
.gc(), mask
.mask
);
206 XSetClipOrigin(**display
, color
.gc(), x
, y
);
208 // fill in the clipped region
209 XFillRectangle(**display
, sf
.pixmap(), color
.gc(), x
, y
,
210 x
+ mask
.w
, y
+ mask
.h
);
212 // unset the clip region
213 XSetClipMask(**display
, color
.gc(), None
);
214 XSetClipOrigin(**display
, color
.gc(), 0, 0);
217 void RenderControl::drawGradientBackground(
218 Surface
&sf
, const RenderTexture
&texture
) const
221 int w
= sf
.size().width(), h
= sf
.size().height();
224 const ScreenInfo
*info
= display
->screenInfo(_screen
);
225 XImage
*im
= XCreateImage(**display
, info
->visual(), info
->depth(),
226 ZPixmap
, 0, NULL
, w
, h
, 32, 0);
227 im
->byte_order
= endian
;
229 switch (texture
.gradient()) {
230 case RenderTexture::Vertical
:
231 verticalGradient(sf
, texture
);
233 case RenderTexture::Diagonal
:
234 diagonalGradient(sf
, texture
);
236 case RenderTexture::CrossDiagonal
:
237 crossDiagonalGradient(sf
, texture
);
240 printf("unhandled gradient\n");
243 pixel32
*data
= sf
.pixelData();
246 if (texture
.relief() == RenderTexture::Flat
&& texture
.border()) {
247 r
= texture
.borderColor().red();
248 g
= texture
.borderColor().green();
249 b
= texture
.borderColor().blue();
250 current
= (r
<< default_red_shift
)
251 + (g
<< default_green_shift
)
252 + (b
<< default_blue_shift
);
253 for (off
= 0, x
= 0; x
< w
; ++x
, off
++) {
254 *(data
+ off
) = current
;
255 *(data
+ off
+ ((h
-1) * w
)) = current
;
257 for (off
= 0, x
= 0; x
< h
; ++x
, off
++) {
258 *(data
+ (off
* w
)) = current
;
259 *(data
+ (off
* w
) + w
- 1) = current
;
263 if (texture
.relief() != RenderTexture::Flat
) {
264 if (texture
.bevel() == RenderTexture::Bevel1
) {
265 for (off
= 1, x
= 1; x
< w
- 1; ++x
, off
++)
266 highlight(data
+ off
,
267 data
+ off
+ (h
-1) * w
,
268 texture
.relief()==RenderTexture::Raised
);
269 for (off
= 0, x
= 0; x
< h
; ++x
, off
++)
270 highlight(data
+ off
* w
,
271 data
+ off
* w
+ w
- 1,
272 texture
.relief()==RenderTexture::Raised
);
275 if (texture
.bevel() == RenderTexture::Bevel2
) {
276 for (off
= 2, x
= 2; x
< w
- 2; ++x
, off
++)
277 highlight(data
+ off
+ w
,
278 data
+ off
+ (h
-2) * w
,
279 texture
.relief()==RenderTexture::Raised
);
280 for (off
= 1, x
= 1; x
< h
-1; ++x
, off
++)
281 highlight(data
+ off
* w
+ 1,
282 data
+ off
* w
+ w
- 2,
283 texture
.relief()==RenderTexture::Raised
);
292 void RenderControl::verticalGradient(Surface
&sf
,
293 const RenderTexture
&texture
) const
295 pixel32
*data
= sf
.pixelData();
299 int w
= sf
.size().width(), h
= sf
.size().height();
301 dr
= (float)(texture
.secondary_color().red() - texture
.color().red());
304 dg
= (float)(texture
.secondary_color().green() - texture
.color().green());
307 db
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
310 for (int y
= 0; y
< h
; ++y
) {
311 r
= texture
.color().red() + (int)(dr
* y
);
312 g
= texture
.color().green() + (int)(dg
* y
);
313 b
= texture
.color().blue() + (int)(db
* y
);
314 current
= (r
<< default_red_shift
)
315 + (g
<< default_green_shift
)
316 + (b
<< default_blue_shift
);
317 for (int x
= 0; x
< w
; ++x
, ++data
)
322 void RenderControl::diagonalGradient(Surface
&sf
,
323 const RenderTexture
&texture
) const
325 pixel32
*data
= sf
.pixelData();
327 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
329 int w
= sf
.size().width(), h
= sf
.size().height();
331 for (int y
= 0; y
< h
; ++y
) {
332 drx
= (float)(texture
.secondary_color().red() - texture
.color().red());
336 dgx
= (float)(texture
.secondary_color().green() - texture
.color().green());
340 dbx
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
343 for (int x
= 0; x
< w
; ++x
, ++data
) {
344 r
= texture
.color().red() + ((int)(drx
* x
) + (int)(dry
* y
))/2;
345 g
= texture
.color().green() + ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
346 b
= texture
.color().blue() + ((int)(dbx
* x
) + (int)(dby
* y
))/2;
347 current
= (r
<< default_red_shift
)
348 + (g
<< default_green_shift
)
349 + (b
<< default_blue_shift
);
355 void RenderControl::crossDiagonalGradient(
356 Surface
&sf
, const RenderTexture
&texture
) const
358 pixel32
*data
= sf
.pixelData();
360 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
362 int w
= sf
.size().width(), h
= sf
.size().height();
364 for (int y
= 0; y
< h
; ++y
) {
365 drx
= (float)(texture
.secondary_color().red() - texture
.color().red());
369 dgx
= (float)(texture
.secondary_color().green() - texture
.color().green());
373 dbx
= (float)(texture
.secondary_color().blue() - texture
.color().blue());
376 for (int x
= w
; x
> 0; --x
, ++data
) {
377 r
= texture
.color().red() + ((int)(drx
* (x
-1)) + (int)(dry
* y
))/2;
378 g
= texture
.color().green() + ((int)(dgx
* (x
-1)) + (int)(dgy
* y
))/2;
379 b
= texture
.color().blue() + ((int)(dbx
* (x
-1)) + (int)(dby
* y
))/2;
380 current
= (r
<< default_red_shift
)
381 + (g
<< default_green_shift
)
382 + (b
<< default_blue_shift
);
388 void RenderControl::highlight(pixel32
*x
, pixel32
*y
, bool raised
) const
400 r
= (*up
>> default_red_shift
) & 0xFF;
402 g
= (*up
>> default_green_shift
) & 0xFF;
404 b
= (*up
>> default_blue_shift
) & 0xFF;
406 if (r
> 255) r
= 255;
407 if (g
> 255) g
= 255;
408 if (b
> 255) b
= 255;
409 *up
= (r
<< default_red_shift
) + (g
<< default_green_shift
)
410 + (b
<< default_blue_shift
);
412 r
= (*down
>> default_red_shift
) & 0xFF;
413 r
= (r
>> 1) + (r
>> 2);
414 g
= (*down
>> default_green_shift
) & 0xFF;
415 g
= (g
>> 1) + (g
>> 2);
416 b
= (*down
>> default_blue_shift
) & 0xFF;
417 b
= (b
>> 1) + (b
>> 2);
418 *down
= (r
<< default_red_shift
) + (g
<< default_green_shift
)
419 + (b
<< default_blue_shift
);
422 void RenderControl::drawBackground(Surface
& sf
,
423 const RenderTexture
&texture
) const
425 assert(_screen
== sf
._screen
);
426 assert(_screen
== texture
.color().screen());
428 if (texture
.gradient() == RenderTexture::Solid
)
429 drawSolidBackground(sf
, texture
);
431 drawGradientBackground(sf
, texture
);
435 void RenderControl::drawImage(Surface
&sf
, int w
, int h
,
436 unsigned long *data
) const
438 pixel32
*bg
= sf
.pixelData();
439 int x
, y
, c
, sfw
, sfh
;
440 unsigned int i
, e
, bgi
;
441 sfw
= sf
.size().width();
442 sfh
= sf
.size().height();
449 // Reduce the image size if its too big to make it fit on the surface
450 int oldw
= w
, oldh
= h
;
451 unsigned long *olddata
= data
;
452 if (w
> sfw
) w
= sfw
;
453 if (h
> sfh
) h
= sfh
;
454 unsigned long newdata
[w
*h
];
455 if (w
< oldw
|| h
< oldh
) {
456 double dx
= oldw
/ (double)w
;
457 double dy
= oldh
/ (double)h
;
461 for (i
= 0, c
= 0, e
= w
*h
; i
< e
; ++i
) {
462 newdata
[i
] = olddata
[(int)px
+ iy
];
474 for (i
= 0, c
= 0, bgi
= y
* sfw
+ x
, e
= w
*h
; i
< e
; ++i
, ++bgi
) {
475 unsigned char alpha
= data
[i
] >> 24;
476 unsigned char r
= data
[i
] >> 16;
477 unsigned char g
= data
[i
] >> 8;
478 unsigned char b
= data
[i
];
481 unsigned char bgr
= bg
[bgi
] >> default_red_shift
;
482 unsigned char bgg
= bg
[bgi
] >> default_green_shift
;
483 unsigned char bgb
= bg
[bgi
] >> default_blue_shift
;
485 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
486 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
487 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
489 bg
[bgi
] = (r
<< default_red_shift
) | (g
<< default_green_shift
) |
490 (b
<< default_blue_shift
);
498 const ScreenInfo
*info
= display
->screenInfo(_screen
);
499 XImage
*im
= XCreateImage(**display
, info
->visual(), info
->depth(),
500 ZPixmap
, 0, NULL
, sf
.size().width(),
501 sf
.size().height(), 32, 0);
502 im
->byte_order
= endian
;
This page took 0.058402 seconds and 4 git commands to generate.