]>
Dogcows Code - chaz/openbox/blob - render/gradient.c
4 #include "../kernel/openbox.h"
7 void gradient_render(Surface
*sf
, int w
, int h
)
9 pixel32
*data
= sf
->data
.planar
.pixel_data
;
14 switch (sf
->data
.planar
.grad
) {
15 case Background_Solid
: /* already handled */
17 case Background_Vertical
:
18 gradient_vertical(sf
, w
, h
);
20 case Background_Horizontal
:
21 gradient_horizontal(sf
, w
, h
);
23 case Background_Diagonal
:
24 gradient_diagonal(sf
, w
, h
);
26 case Background_CrossDiagonal
:
27 gradient_crossdiagonal(sf
, w
, h
);
29 case Background_Pyramid
:
30 gradient_pyramid(sf
, w
, h
);
32 case Background_PipeCross
:
33 gradient_pipecross(sf
, w
, h
);
35 case Background_Rectangle
:
36 gradient_rectangle(sf
, w
, h
);
39 g_message("unhandled gradient");
43 if (sf
->data
.planar
.relief
== Flat
&& sf
->data
.planar
.border
) {
44 r
= sf
->data
.planar
.border_color
->r
;
45 g
= sf
->data
.planar
.border_color
->g
;
46 b
= sf
->data
.planar
.border_color
->b
;
47 current
= (r
<< default_red_offset
)
48 + (g
<< default_green_offset
)
49 + (b
<< default_blue_offset
);
50 for (off
= 0, x
= 0; x
< w
; ++x
, off
++) {
51 *(data
+ off
) = current
;
52 *(data
+ off
+ ((h
-1) * w
)) = current
;
54 for (off
= 0, x
= 0; x
< h
; ++x
, off
++) {
55 *(data
+ (off
* w
)) = current
;
56 *(data
+ (off
* w
) + w
- 1) = current
;
60 if (sf
->data
.planar
.relief
!= Flat
) {
61 if (sf
->data
.planar
.bevel
== Bevel1
) {
62 for (off
= 1, x
= 1; x
< w
- 1; ++x
, off
++)
64 data
+ off
+ (h
-1) * w
,
65 sf
->data
.planar
.relief
==Raised
);
66 for (off
= 0, x
= 0; x
< h
; ++x
, off
++)
67 highlight(data
+ off
* w
,
68 data
+ off
* w
+ w
- 1,
69 sf
->data
.planar
.relief
==Raised
);
72 if (sf
->data
.planar
.bevel
== Bevel2
) {
73 for (off
= 2, x
= 2; x
< w
- 2; ++x
, off
++)
74 highlight(data
+ off
+ w
,
75 data
+ off
+ (h
-2) * w
,
76 sf
->data
.planar
.relief
==Raised
);
77 for (off
= 1, x
= 1; x
< h
-1; ++x
, off
++)
78 highlight(data
+ off
* w
+ 1,
79 data
+ off
* w
+ w
- 2,
80 sf
->data
.planar
.relief
==Raised
);
87 void gradient_vertical(Surface
*sf
, int w
, int h
)
89 pixel32
*data
= sf
->data
.planar
.pixel_data
;
95 dr
= (float)(sf
->data
.planar
.secondary
->r
- sf
->data
.planar
.primary
->r
);
98 dg
= (float)(sf
->data
.planar
.secondary
->g
- sf
->data
.planar
.primary
->g
);
101 db
= (float)(sf
->data
.planar
.secondary
->b
- sf
->data
.planar
.primary
->b
);
104 for (y
= 0; y
< h
; ++y
) {
105 r
= sf
->data
.planar
.primary
->r
+ (int)(dr
* y
);
106 g
= sf
->data
.planar
.primary
->g
+ (int)(dg
* y
);
107 b
= sf
->data
.planar
.primary
->b
+ (int)(db
* y
);
108 current
= (r
<< default_red_offset
)
109 + (g
<< default_green_offset
)
110 + (b
<< default_blue_offset
);
111 for (x
= 0; x
< w
; ++x
, ++data
)
116 void gradient_horizontal(Surface
*sf
, int w
, int h
)
118 pixel32
*data
= sf
->data
.planar
.pixel_data
;
124 dr
= (float)(sf
->data
.planar
.secondary
->r
- sf
->data
.planar
.primary
->r
);
127 dg
= (float)(sf
->data
.planar
.secondary
->g
- sf
->data
.planar
.primary
->g
);
130 db
= (float)(sf
->data
.planar
.secondary
->b
- sf
->data
.planar
.primary
->b
);
133 for (x
= 0; x
< w
; ++x
, ++data
) {
134 r
= sf
->data
.planar
.primary
->r
+ (int)(dr
* x
);
135 g
= sf
->data
.planar
.primary
->g
+ (int)(dg
* x
);
136 b
= sf
->data
.planar
.primary
->b
+ (int)(db
* x
);
137 current
= (r
<< default_red_offset
)
138 + (g
<< default_green_offset
)
139 + (b
<< default_blue_offset
);
140 for (y
= 0; y
< h
; ++y
)
141 *(data
+ y
*w
) = current
;
145 void gradient_diagonal(Surface
*sf
, int w
, int h
)
147 pixel32
*data
= sf
->data
.planar
.pixel_data
;
149 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
153 for (y
= 0; y
< h
; ++y
) {
154 drx
= (float)(sf
->data
.planar
.secondary
->r
-
155 sf
->data
.planar
.primary
->r
);
159 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
160 sf
->data
.planar
.primary
->g
);
164 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
165 sf
->data
.planar
.primary
->b
);
168 for (x
= 0; x
< w
; ++x
, ++data
) {
169 r
= sf
->data
.planar
.primary
->r
+
170 ((int)(drx
* x
) + (int)(dry
* y
))/2;
171 g
= sf
->data
.planar
.primary
->g
+
172 ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
173 b
= sf
->data
.planar
.primary
->b
+
174 ((int)(dbx
* x
) + (int)(dby
* y
))/2;
175 current
= (r
<< default_red_offset
)
176 + (g
<< default_green_offset
)
177 + (b
<< default_blue_offset
);
183 void gradient_crossdiagonal(Surface
*sf
, int w
, int h
)
185 pixel32
*data
= sf
->data
.planar
.pixel_data
;
187 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
191 for (y
= 0; y
< h
; ++y
) {
192 drx
= (float)(sf
->data
.planar
.secondary
->r
-
193 sf
->data
.planar
.primary
->r
);
197 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
198 sf
->data
.planar
.primary
->g
);
202 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
203 sf
->data
.planar
.primary
->b
);
206 for (x
= w
; x
> 0; --x
, ++data
) {
207 r
= sf
->data
.planar
.primary
->r
+
208 ((int)(drx
* (x
-1)) + (int)(dry
* y
))/2;
209 g
= sf
->data
.planar
.primary
->g
+
210 ((int)(dgx
* (x
-1)) + (int)(dgy
* y
))/2;
211 b
= sf
->data
.planar
.primary
->b
+
212 ((int)(dbx
* (x
-1)) + (int)(dby
* y
))/2;
213 current
= (r
<< default_red_offset
)
214 + (g
<< default_green_offset
)
215 + (b
<< default_blue_offset
);
221 void highlight(pixel32
*x
, pixel32
*y
, gboolean raised
)
233 r
= (*up
>> default_red_offset
) & 0xFF;
235 g
= (*up
>> default_green_offset
) & 0xFF;
237 b
= (*up
>> default_blue_offset
) & 0xFF;
239 if (r
> 0xFF) r
= 0xFF;
240 if (g
> 0xFF) g
= 0xFF;
241 if (b
> 0xFF) b
= 0xFF;
242 *up
= (r
<< default_red_offset
) + (g
<< default_green_offset
)
243 + (b
<< default_blue_offset
);
245 r
= (*down
>> default_red_offset
) & 0xFF;
246 r
= (r
>> 1) + (r
>> 2);
247 g
= (*down
>> default_green_offset
) & 0xFF;
248 g
= (g
>> 1) + (g
>> 2);
249 b
= (*down
>> default_blue_offset
) & 0xFF;
250 b
= (b
>> 1) + (b
>> 2);
251 *down
= (r
<< default_red_offset
) + (g
<< default_green_offset
)
252 + (b
<< default_blue_offset
);
255 static void create_bevel_colors(Appearance
*l
)
260 r
= l
->surface
.data
.planar
.primary
->r
;
262 g
= l
->surface
.data
.planar
.primary
->g
;
264 b
= l
->surface
.data
.planar
.primary
->b
;
266 if (r
> 0xFF) r
= 0xFF;
267 if (g
> 0xFF) g
= 0xFF;
268 if (b
> 0xFF) b
= 0xFF;
269 g_assert(!l
->surface
.data
.planar
.bevel_light
);
270 l
->surface
.data
.planar
.bevel_light
= color_new(r
, g
, b
);
271 color_allocate_gc(l
->surface
.data
.planar
.bevel_light
);
274 r
= l
->surface
.data
.planar
.primary
->r
;
275 r
= (r
>> 1) + (r
>> 2);
276 g
= l
->surface
.data
.planar
.primary
->g
;
277 g
= (g
>> 1) + (g
>> 2);
278 b
= l
->surface
.data
.planar
.primary
->b
;
279 b
= (b
>> 1) + (b
>> 2);
280 g_assert(!l
->surface
.data
.planar
.bevel_dark
);
281 l
->surface
.data
.planar
.bevel_dark
= color_new(r
, g
, b
);
282 color_allocate_gc(l
->surface
.data
.planar
.bevel_dark
);
285 void gradient_solid(Appearance
*l
, int x
, int y
, int w
, int h
)
289 PlanarSurface
*sp
= &l
->surface
.data
.planar
;
290 int left
= x
, top
= y
, right
= x
+ w
- 1, bottom
= y
+ h
- 1;
292 if (sp
->primary
->gc
== None
)
293 color_allocate_gc(sp
->primary
);
294 pix
= (sp
->primary
->r
<< default_red_offset
)
295 + (sp
->primary
->g
<< default_green_offset
)
296 + (sp
->primary
->b
<< default_blue_offset
);
298 for (a
= 0; a
< l
->area
.width
; a
++)
299 for (b
= 0; b
< l
->area
.height
; b
++)
300 sp
->pixel_data
[a
+ b
*l
->area
.width
] = pix
;
302 XFillRectangle(ob_display
, l
->pixmap
, sp
->primary
->gc
,
305 if (sp
->interlaced
) {
306 if (sp
->secondary
->gc
== None
)
307 color_allocate_gc(sp
->secondary
);
308 for (i
= y
; i
< h
; i
+= 2)
309 XDrawLine(ob_display
, l
->pixmap
, sp
->secondary
->gc
,
313 switch (sp
->relief
) {
316 create_bevel_colors(l
);
320 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
321 left
, bottom
, right
, bottom
);
322 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
323 right
, bottom
, right
, top
);
325 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
326 left
, top
, right
, top
);
327 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
328 left
, bottom
, left
, top
);
331 XDrawLine(ob_display
, l
->pixmap
,
333 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
334 XDrawLine(ob_display
, l
->pixmap
,
336 right
- 2, bottom
- 2, right
- 2, top
+ 1);
338 XDrawLine(ob_display
, l
->pixmap
,
340 left
+ 1, top
+ 1, right
- 2, top
+ 1);
341 XDrawLine(ob_display
, l
->pixmap
,
343 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
346 g_assert_not_reached(); /* unhandled BevelType */
351 create_bevel_colors(l
);
355 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
356 left
, bottom
, right
, bottom
);
357 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
358 right
, bottom
, right
, top
);
360 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
361 left
, top
, right
, top
);
362 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
363 left
, bottom
, left
, top
);
366 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
367 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
368 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
369 right
- 2, bottom
- 2, right
- 2, top
+ 1);
371 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
372 left
+ 1, top
+ 1, right
- 2, top
+ 1);
373 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
374 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
378 g_assert_not_reached(); /* unhandled BevelType */
383 if (sp
->border_color
->gc
== None
)
384 color_allocate_gc(sp
->border_color
);
385 XDrawRectangle(ob_display
, l
->pixmap
, sp
->border_color
->gc
,
386 left
, top
, right
, bottom
);
390 g_assert_not_reached(); /* unhandled ReliefType */
394 void gradient_pyramid(Surface
*sf
, int inw
, int inh
)
396 pixel32
*data
= sf
->data
.planar
.pixel_data
;
397 pixel32
*end
= data
+ inw
*inh
- 1;
399 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
401 int x
, y
, h
=(inh
/2) + 1, w
=(inw
/2) + 1;
402 for (y
= 0; y
< h
; ++y
) {
403 drx
= (float)(sf
->data
.planar
.secondary
->r
-
404 sf
->data
.planar
.primary
->r
);
408 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
409 sf
->data
.planar
.primary
->g
);
413 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
414 sf
->data
.planar
.primary
->b
);
417 for (x
= 0; x
< w
; ++x
, data
) {
418 r
= sf
->data
.planar
.primary
->r
+
419 ((int)(drx
* x
) + (int)(dry
* y
))/2;
420 g
= sf
->data
.planar
.primary
->g
+
421 ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
422 b
= sf
->data
.planar
.primary
->b
+
423 ((int)(dbx
* x
) + (int)(dby
* y
))/2;
424 current
= (r
<< default_red_offset
)
425 + (g
<< default_green_offset
)
426 + (b
<< default_blue_offset
);
428 *(data
+inw
-x
) = current
;
430 *(end
-(inw
-x
)) = current
;
437 void gradient_rectangle(Surface
*sf
, int inw
, int inh
)
439 pixel32
*data
= sf
->data
.planar
.pixel_data
;
440 pixel32
*end
= data
+ inw
*inh
- 1;
442 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
444 int x
, y
, h
=(inh
/2) + 1, w
=(inw
/2) + 1;
447 for (y
= 0; y
< h
; ++y
) {
448 drx
= (float)(sf
->data
.planar
.primary
->r
-
449 sf
->data
.planar
.secondary
->r
);
453 dgx
= (float)(sf
->data
.planar
.primary
->g
-
454 sf
->data
.planar
.secondary
->g
);
458 dbx
= (float)(sf
->data
.planar
.primary
->b
-
459 sf
->data
.planar
.secondary
->b
);
462 for (x
= 0; x
< w
; ++x
, data
) {
463 if ((float)x
/(float)w
< (float)y
/(float)h
) val
= (int)(drx
* x
);
464 else val
= (int)(dry
* y
);
466 r
= sf
->data
.planar
.secondary
->r
+ val
;
467 g
= sf
->data
.planar
.secondary
->g
+ val
;
468 b
= sf
->data
.planar
.secondary
->b
+ val
;
469 current
= (r
<< default_red_offset
)
470 + (g
<< default_green_offset
)
471 + (b
<< default_blue_offset
);
473 *(data
+inw
-x
) = current
;
475 *(end
-(inw
-x
)) = current
;
482 void gradient_pipecross(Surface
*sf
, int inw
, int inh
)
484 pixel32
*data
= sf
->data
.planar
.pixel_data
;
485 pixel32
*end
= data
+ inw
*inh
- 1;
487 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
489 int x
, y
, h
=(inh
/2) + 1, w
=(inw
/2) + 1;
492 for (y
= 0; y
< h
; ++y
) {
493 drx
= (float)(sf
->data
.planar
.secondary
->r
-
494 sf
->data
.planar
.primary
->r
);
498 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
499 sf
->data
.planar
.primary
->g
);
503 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
504 sf
->data
.planar
.primary
->b
);
507 for (x
= 0; x
< w
; ++x
, data
) {
508 if ((float)x
/(float)w
> (float)y
/(float)h
) val
= (int)(drx
* x
);
509 else val
= (int)(dry
* y
);
511 r
= sf
->data
.planar
.primary
->r
+ val
;
512 g
= sf
->data
.planar
.primary
->g
+ val
;
513 b
= sf
->data
.planar
.primary
->b
+ val
;
514 current
= (r
<< default_red_offset
)
515 + (g
<< default_green_offset
)
516 + (b
<< default_blue_offset
);
518 *(data
+inw
-x
) = current
;
520 *(end
-(inw
-x
)) = current
;
This page took 0.059792 seconds and 4 git commands to generate.