]>
Dogcows Code - chaz/openbox/blob - render/gradient.c
3a963406c33b0385165cac42fbdd3cdea7173c8b
5 #include "../kernel/openbox.h"
8 void gradient_render(Surface
*sf
, int w
, int h
)
10 pixel32
*data
= sf
->data
.planar
.pixel_data
;
15 switch (sf
->data
.planar
.grad
) {
16 case Background_Solid
: /* already handled */
18 case Background_Vertical
:
19 gradient_vertical(sf
, w
, h
);
21 case Background_Horizontal
:
22 gradient_horizontal(sf
, w
, h
);
24 case Background_Diagonal
:
25 gradient_diagonal(sf
, w
, h
);
27 case Background_CrossDiagonal
:
28 gradient_crossdiagonal(sf
, w
, h
);
30 case Background_Pyramid
:
31 gradient_pyramid(sf
, w
, h
);
33 case Background_PipeCross
:
34 gradient_pipecross(sf
, w
, h
);
36 case Background_Rectangle
:
37 gradient_rectangle(sf
, w
, h
);
40 g_message("unhandled gradient");
44 if (sf
->data
.planar
.relief
== Flat
&& sf
->data
.planar
.border
) {
45 r
= sf
->data
.planar
.border_color
->r
;
46 g
= sf
->data
.planar
.border_color
->g
;
47 b
= sf
->data
.planar
.border_color
->b
;
48 current
= (r
<< default_red_offset
)
49 + (g
<< default_green_offset
)
50 + (b
<< default_blue_offset
);
51 for (off
= 0, x
= 0; x
< w
; ++x
, off
++) {
52 *(data
+ off
) = current
;
53 *(data
+ off
+ ((h
-1) * w
)) = current
;
55 for (off
= 0, x
= 0; x
< h
; ++x
, off
++) {
56 *(data
+ (off
* w
)) = current
;
57 *(data
+ (off
* w
) + w
- 1) = current
;
61 if (sf
->data
.planar
.relief
!= Flat
) {
62 if (sf
->data
.planar
.bevel
== Bevel1
) {
63 for (off
= 1, x
= 1; x
< w
- 1; ++x
, off
++)
65 data
+ off
+ (h
-1) * w
,
66 sf
->data
.planar
.relief
==Raised
);
67 for (off
= 0, x
= 0; x
< h
; ++x
, off
++)
68 highlight(data
+ off
* w
,
69 data
+ off
* w
+ w
- 1,
70 sf
->data
.planar
.relief
==Raised
);
73 if (sf
->data
.planar
.bevel
== Bevel2
) {
74 for (off
= 2, x
= 2; x
< w
- 2; ++x
, off
++)
75 highlight(data
+ off
+ w
,
76 data
+ off
+ (h
-2) * w
,
77 sf
->data
.planar
.relief
==Raised
);
78 for (off
= 1, x
= 1; x
< h
-1; ++x
, off
++)
79 highlight(data
+ off
* w
+ 1,
80 data
+ off
* w
+ w
- 2,
81 sf
->data
.planar
.relief
==Raised
);
88 void gradient_vertical(Surface
*sf
, int w
, int h
)
90 pixel32
*data
= sf
->data
.planar
.pixel_data
;
96 dr
= (float)(sf
->data
.planar
.secondary
->r
- sf
->data
.planar
.primary
->r
);
99 dg
= (float)(sf
->data
.planar
.secondary
->g
- sf
->data
.planar
.primary
->g
);
102 db
= (float)(sf
->data
.planar
.secondary
->b
- sf
->data
.planar
.primary
->b
);
105 for (y
= 0; y
< h
; ++y
) {
106 r
= sf
->data
.planar
.primary
->r
+ (int)(dr
* y
);
107 g
= sf
->data
.planar
.primary
->g
+ (int)(dg
* y
);
108 b
= sf
->data
.planar
.primary
->b
+ (int)(db
* y
);
109 current
= (r
<< default_red_offset
)
110 + (g
<< default_green_offset
)
111 + (b
<< default_blue_offset
);
112 for (x
= 0; x
< w
; ++x
, ++data
)
117 void gradient_horizontal(Surface
*sf
, int w
, int h
)
119 pixel32
*data
= sf
->data
.planar
.pixel_data
;
125 dr
= (float)(sf
->data
.planar
.secondary
->r
- sf
->data
.planar
.primary
->r
);
128 dg
= (float)(sf
->data
.planar
.secondary
->g
- sf
->data
.planar
.primary
->g
);
131 db
= (float)(sf
->data
.planar
.secondary
->b
- sf
->data
.planar
.primary
->b
);
134 for (x
= 0; x
< w
; ++x
, ++data
) {
135 r
= sf
->data
.planar
.primary
->r
+ (int)(dr
* x
);
136 g
= sf
->data
.planar
.primary
->g
+ (int)(dg
* x
);
137 b
= sf
->data
.planar
.primary
->b
+ (int)(db
* x
);
138 current
= (r
<< default_red_offset
)
139 + (g
<< default_green_offset
)
140 + (b
<< default_blue_offset
);
141 for (y
= 0; y
< h
; ++y
)
142 *(data
+ y
*w
) = current
;
146 void gradient_diagonal(Surface
*sf
, int w
, int h
)
148 pixel32
*data
= sf
->data
.planar
.pixel_data
;
150 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
154 for (y
= 0; y
< h
; ++y
) {
155 drx
= (float)(sf
->data
.planar
.secondary
->r
-
156 sf
->data
.planar
.primary
->r
);
160 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
161 sf
->data
.planar
.primary
->g
);
165 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
166 sf
->data
.planar
.primary
->b
);
169 for (x
= 0; x
< w
; ++x
, ++data
) {
170 r
= sf
->data
.planar
.primary
->r
+
171 ((int)(drx
* x
) + (int)(dry
* y
))/2;
172 g
= sf
->data
.planar
.primary
->g
+
173 ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
174 b
= sf
->data
.planar
.primary
->b
+
175 ((int)(dbx
* x
) + (int)(dby
* y
))/2;
176 current
= (r
<< default_red_offset
)
177 + (g
<< default_green_offset
)
178 + (b
<< default_blue_offset
);
184 void gradient_crossdiagonal(Surface
*sf
, int w
, int h
)
186 pixel32
*data
= sf
->data
.planar
.pixel_data
;
188 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
192 for (y
= 0; y
< h
; ++y
) {
193 drx
= (float)(sf
->data
.planar
.secondary
->r
-
194 sf
->data
.planar
.primary
->r
);
198 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
199 sf
->data
.planar
.primary
->g
);
203 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
204 sf
->data
.planar
.primary
->b
);
207 for (x
= w
; x
> 0; --x
, ++data
) {
208 r
= sf
->data
.planar
.primary
->r
+
209 ((int)(drx
* (x
-1)) + (int)(dry
* y
))/2;
210 g
= sf
->data
.planar
.primary
->g
+
211 ((int)(dgx
* (x
-1)) + (int)(dgy
* y
))/2;
212 b
= sf
->data
.planar
.primary
->b
+
213 ((int)(dbx
* (x
-1)) + (int)(dby
* y
))/2;
214 current
= (r
<< default_red_offset
)
215 + (g
<< default_green_offset
)
216 + (b
<< default_blue_offset
);
222 void highlight(pixel32
*x
, pixel32
*y
, gboolean raised
)
234 r
= (*up
>> default_red_offset
) & 0xFF;
236 g
= (*up
>> default_green_offset
) & 0xFF;
238 b
= (*up
>> default_blue_offset
) & 0xFF;
240 if (r
> 0xFF) r
= 0xFF;
241 if (g
> 0xFF) g
= 0xFF;
242 if (b
> 0xFF) b
= 0xFF;
243 *up
= (r
<< default_red_offset
) + (g
<< default_green_offset
)
244 + (b
<< default_blue_offset
);
246 r
= (*down
>> default_red_offset
) & 0xFF;
247 r
= (r
>> 1) + (r
>> 2);
248 g
= (*down
>> default_green_offset
) & 0xFF;
249 g
= (g
>> 1) + (g
>> 2);
250 b
= (*down
>> default_blue_offset
) & 0xFF;
251 b
= (b
>> 1) + (b
>> 2);
252 *down
= (r
<< default_red_offset
) + (g
<< default_green_offset
)
253 + (b
<< default_blue_offset
);
256 static void create_bevel_colors(Appearance
*l
)
261 r
= l
->surface
.data
.planar
.primary
->r
;
263 g
= l
->surface
.data
.planar
.primary
->g
;
265 b
= l
->surface
.data
.planar
.primary
->b
;
267 if (r
> 0xFF) r
= 0xFF;
268 if (g
> 0xFF) g
= 0xFF;
269 if (b
> 0xFF) b
= 0xFF;
270 g_assert(!l
->surface
.data
.planar
.bevel_light
);
271 l
->surface
.data
.planar
.bevel_light
= color_new(r
, g
, b
);
272 color_allocate_gc(l
->surface
.data
.planar
.bevel_light
);
275 r
= l
->surface
.data
.planar
.primary
->r
;
276 r
= (r
>> 1) + (r
>> 2);
277 g
= l
->surface
.data
.planar
.primary
->g
;
278 g
= (g
>> 1) + (g
>> 2);
279 b
= l
->surface
.data
.planar
.primary
->b
;
280 b
= (b
>> 1) + (b
>> 2);
281 g_assert(!l
->surface
.data
.planar
.bevel_dark
);
282 l
->surface
.data
.planar
.bevel_dark
= color_new(r
, g
, b
);
283 color_allocate_gc(l
->surface
.data
.planar
.bevel_dark
);
286 void gradient_solid(Appearance
*l
, int x
, int y
, int w
, int h
)
290 PlanarSurface
*sp
= &l
->surface
.data
.planar
;
291 int left
= x
, top
= y
, right
= x
+ w
- 1, bottom
= y
+ h
- 1;
293 if (sp
->primary
->gc
== None
)
294 color_allocate_gc(sp
->primary
);
295 pix
= (sp
->primary
->r
<< default_red_offset
)
296 + (sp
->primary
->g
<< default_green_offset
)
297 + (sp
->primary
->b
<< default_blue_offset
);
299 for (a
= 0; a
< l
->area
.width
; a
++)
300 for (b
= 0; b
< l
->area
.height
; b
++)
301 sp
->pixel_data
[a
+ b
*l
->area
.width
] = pix
;
303 XFillRectangle(ob_display
, l
->pixmap
, sp
->primary
->gc
,
306 if (sp
->interlaced
) {
307 if (sp
->secondary
->gc
== None
)
308 color_allocate_gc(sp
->secondary
);
309 for (i
= y
; i
< h
; i
+= 2)
310 XDrawLine(ob_display
, l
->pixmap
, sp
->secondary
->gc
,
314 switch (sp
->relief
) {
317 create_bevel_colors(l
);
321 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
322 left
, bottom
, right
, bottom
);
323 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
324 right
, bottom
, right
, top
);
326 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
327 left
, top
, right
, top
);
328 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
329 left
, bottom
, left
, top
);
332 XDrawLine(ob_display
, l
->pixmap
,
334 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
335 XDrawLine(ob_display
, l
->pixmap
,
337 right
- 2, bottom
- 2, right
- 2, top
+ 1);
339 XDrawLine(ob_display
, l
->pixmap
,
341 left
+ 1, top
+ 1, right
- 2, top
+ 1);
342 XDrawLine(ob_display
, l
->pixmap
,
344 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
347 g_assert_not_reached(); /* unhandled BevelType */
352 create_bevel_colors(l
);
356 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
357 left
, bottom
, right
, bottom
);
358 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
359 right
, bottom
, right
, top
);
361 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
362 left
, top
, right
, top
);
363 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
364 left
, bottom
, left
, top
);
367 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
368 left
+ 1, bottom
- 2, right
- 2, bottom
- 2);
369 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_light
->gc
,
370 right
- 2, bottom
- 2, right
- 2, top
+ 1);
372 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
373 left
+ 1, top
+ 1, right
- 2, top
+ 1);
374 XDrawLine(ob_display
, l
->pixmap
, sp
->bevel_dark
->gc
,
375 left
+ 1, bottom
- 2, left
+ 1, top
+ 1);
379 g_assert_not_reached(); /* unhandled BevelType */
384 if (sp
->border_color
->gc
== None
)
385 color_allocate_gc(sp
->border_color
);
386 XDrawRectangle(ob_display
, l
->pixmap
, sp
->border_color
->gc
,
387 left
, top
, right
, bottom
);
391 g_assert_not_reached(); /* unhandled ReliefType */
395 void gradient_pyramid(Surface
*sf
, int inw
, int inh
)
397 pixel32
*data
= sf
->data
.planar
.pixel_data
;
398 pixel32
*end
= data
+ inw
*inh
- 1;
400 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
402 int x
, y
, h
=(inh
/2) + 1, w
=(inw
/2) + 1;
403 for (y
= 0; y
< h
; ++y
) {
404 drx
= (float)(sf
->data
.planar
.secondary
->r
-
405 sf
->data
.planar
.primary
->r
);
409 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
410 sf
->data
.planar
.primary
->g
);
414 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
415 sf
->data
.planar
.primary
->b
);
418 for (x
= 0; x
< w
; ++x
, data
) {
419 r
= sf
->data
.planar
.primary
->r
+
420 ((int)(drx
* x
) + (int)(dry
* y
))/2;
421 g
= sf
->data
.planar
.primary
->g
+
422 ((int)(dgx
* x
) + (int)(dgy
* y
))/2;
423 b
= sf
->data
.planar
.primary
->b
+
424 ((int)(dbx
* x
) + (int)(dby
* y
))/2;
425 current
= (r
<< default_red_offset
)
426 + (g
<< default_green_offset
)
427 + (b
<< default_blue_offset
);
429 *(data
+inw
-x
) = current
;
431 *(end
-(inw
-x
)) = current
;
438 void gradient_rectangle(Surface
*sf
, int inw
, int inh
)
440 pixel32
*data
= sf
->data
.planar
.pixel_data
;
441 pixel32
*end
= data
+ inw
*inh
- 1;
443 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
445 int x
, y
, h
=(inh
/2) + 1, w
=(inw
/2) + 1;
448 for (y
= 0; y
< h
; ++y
) {
449 drx
= (float)(sf
->data
.planar
.primary
->r
-
450 sf
->data
.planar
.secondary
->r
);
454 dgx
= (float)(sf
->data
.planar
.primary
->g
-
455 sf
->data
.planar
.secondary
->g
);
459 dbx
= (float)(sf
->data
.planar
.primary
->b
-
460 sf
->data
.planar
.secondary
->b
);
463 for (x
= 0; x
< w
; ++x
, data
) {
464 if ((float)x
/(float)w
< (float)y
/(float)h
) val
= (int)(drx
* x
);
465 else val
= (int)(dry
* y
);
467 r
= sf
->data
.planar
.secondary
->r
+ val
;
468 g
= sf
->data
.planar
.secondary
->g
+ val
;
469 b
= sf
->data
.planar
.secondary
->b
+ val
;
470 current
= (r
<< default_red_offset
)
471 + (g
<< default_green_offset
)
472 + (b
<< default_blue_offset
);
474 *(data
+inw
-x
) = current
;
476 *(end
-(inw
-x
)) = current
;
483 void gradient_pipecross(Surface
*sf
, int inw
, int inh
)
485 pixel32
*data
= sf
->data
.planar
.pixel_data
;
486 pixel32
*end
= data
+ inw
*inh
- 1;
488 float drx
, dgx
, dbx
, dry
, dgy
, dby
;
490 int x
, y
, h
=(inh
/2) + 1, w
=(inw
/2) + 1;
493 for (y
= 0; y
< h
; ++y
) {
494 drx
= (float)(sf
->data
.planar
.secondary
->r
-
495 sf
->data
.planar
.primary
->r
);
499 dgx
= (float)(sf
->data
.planar
.secondary
->g
-
500 sf
->data
.planar
.primary
->g
);
504 dbx
= (float)(sf
->data
.planar
.secondary
->b
-
505 sf
->data
.planar
.primary
->b
);
508 for (x
= 0; x
< w
; ++x
, data
) {
509 if ((float)x
/(float)w
> (float)y
/(float)h
) val
= (int)(drx
* x
);
510 else val
= (int)(dry
* y
);
512 r
= sf
->data
.planar
.primary
->r
+ val
;
513 g
= sf
->data
.planar
.primary
->g
+ val
;
514 b
= sf
->data
.planar
.primary
->b
+ val
;
515 current
= (r
<< default_red_offset
)
516 + (g
<< default_green_offset
)
517 + (b
<< default_blue_offset
);
519 *(data
+inw
-x
) = current
;
521 *(end
-(inw
-x
)) = current
;
528 void render_gl_gradient(Surface
*sf
, int x
, int y
, int w
, int h
)
533 pr
= (float)sf
->data
.planar
.primary
->r
/255.0;
534 pg
= (float)sf
->data
.planar
.primary
->g
/255.0;
535 pb
= (float)sf
->data
.planar
.primary
->b
/255.0;
536 if (sf
->data
.planar
.secondary
) {
537 sr
= (float)sf
->data
.planar
.secondary
->r
/255.0;
538 sg
= (float)sf
->data
.planar
.secondary
->g
/255.0;
539 sb
= (float)sf
->data
.planar
.secondary
->b
/255.0;
541 switch (sf
->data
.planar
.grad
) {
542 case Background_Solid
: /* already handled */
543 glBegin(GL_TRIANGLES
);
544 glColor3f(pr
, pg
, pb
);
546 glVertex3i(x
+w
, y
, 0);
547 glVertex3i(x
+w
, y
+h
, 0);
549 glVertex3i(x
+w
, y
+h
, 0);
550 glVertex3i(x
, y
+h
, 0);
554 case Background_Vertical
:
555 glBegin(GL_TRIANGLES
);
556 glColor3f(pr
, pg
, pb
);
558 glColor3f(sr
, sg
, sb
);
559 glVertex3i(x
+w
, y
, 0);
560 glVertex3i(x
+w
, y
+h
, 0);
562 glVertex3i(x
+w
, y
+h
, 0);
563 glColor3f(pr
, pg
, pb
);
564 glVertex3i(x
, y
+h
, 0);
568 case Background_Horizontal
:
569 glBegin(GL_TRIANGLES
);
570 glColor3f(pr
, pg
, pb
);
572 glVertex3i(x
+w
, y
, 0);
573 glColor3f(sr
, sg
, sb
);
574 glVertex3i(x
+w
, y
+h
, 0);
576 glVertex3i(x
+w
, y
+h
, 0);
577 glVertex3i(x
, y
+h
, 0);
578 glColor3f(pr
, pg
, pb
);
582 case Background_Diagonal
:
583 printf("diagonal\n");
585 case Background_CrossDiagonal
:
586 printf("crossdiagonal\n");
588 case Background_Pyramid
:
591 case Background_PipeCross
:
592 printf("pipecross\n");
594 case Background_Rectangle
:
598 g_message("unhandled gradient");
This page took 0.096553 seconds and 4 git commands to generate.