4 #include "../kernel/openbox.h"
7 void gradient_render(Surface *sf, int w, int h)
9 pixel32 *data = sf->pixel_data;
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->relief == Flat && sf->border) {
44 r = sf->border_color->r;
45 g = sf->border_color->g;
46 b = sf->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->relief != Flat) {
61 if (sf->bevel == Bevel1) {
62 for (off = 1, x = 1; x < w - 1; ++x, off++)
64 data + off + (h-1) * w,
66 for (off = 0, x = 0; x < h; ++x, off++)
67 highlight(data + off * w,
68 data + off * w + w - 1,
72 if (sf->bevel == Bevel2) {
73 for (off = 2, x = 2; x < w - 2; ++x, off++)
74 highlight(data + off + w,
75 data + off + (h-2) * w,
77 for (off = 1, x = 1; x < h-1; ++x, off++)
78 highlight(data + off * w + 1,
79 data + off * w + w - 2,
87 void gradient_vertical(Surface *sf, int w, int h)
89 pixel32 *data = sf->pixel_data;
95 dr = (float)(sf->secondary->r - sf->primary->r);
98 dg = (float)(sf->secondary->g - sf->primary->g);
101 db = (float)(sf->secondary->b - sf->primary->b);
104 for (y = 0; y < h; ++y) {
105 r = sf->primary->r + (int)(dr * y);
106 g = sf->primary->g + (int)(dg * y);
107 b = sf->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->pixel_data;
124 dr = (float)(sf->secondary->r - sf->primary->r);
127 dg = (float)(sf->secondary->g - sf->primary->g);
130 db = (float)(sf->secondary->b - sf->primary->b);
133 for (x = 0; x < w; ++x, ++data) {
134 r = sf->primary->r + (int)(dr * x);
135 g = sf->primary->g + (int)(dg * x);
136 b = sf->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->pixel_data;
149 float drx, dgx, dbx, dry, dgy, dby;
153 for (y = 0; y < h; ++y) {
154 drx = (float)(sf->secondary->r -
159 dgx = (float)(sf->secondary->g -
164 dbx = (float)(sf->secondary->b -
168 for (x = 0; x < w; ++x, ++data) {
170 ((int)(drx * x) + (int)(dry * y))/2;
172 ((int)(dgx * x) + (int)(dgy * y))/2;
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->pixel_data;
187 float drx, dgx, dbx, dry, dgy, dby;
191 for (y = 0; y < h; ++y) {
192 drx = (float)(sf->secondary->r -
197 dgx = (float)(sf->secondary->g -
202 dbx = (float)(sf->secondary->b -
206 for (x = w; x > 0; --x, ++data) {
208 ((int)(drx * (x-1)) + (int)(dry * y))/2;
210 ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
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.primary->r;
262 g = l->surface.primary->g;
264 b = l->surface.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.bevel_light);
270 l->surface.bevel_light = color_new(r, g, b);
271 color_allocate_gc(l->surface.bevel_light);
274 r = l->surface.primary->r;
275 r = (r >> 1) + (r >> 2);
276 g = l->surface.primary->g;
277 g = (g >> 1) + (g >> 2);
278 b = l->surface.primary->b;
279 b = (b >> 1) + (b >> 2);
280 g_assert(!l->surface.bevel_dark);
281 l->surface.bevel_dark = color_new(r, g, b);
282 color_allocate_gc(l->surface.bevel_dark);
285 void gradient_solid(Appearance *l, int x, int y, int w, int h)
289 Surface *sp = &l->surface;
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->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;
403 drx = (float)(sf->secondary->r -
408 dgx = (float)(sf->secondary->g -
413 dbx = (float)(sf->secondary->b -
418 for (y = 0; y < h; ++y) {
419 for (x = 0; x < w; ++x, data) {
421 ((int)(drx * x) + (int)(dry * y))/2;
423 ((int)(dgx * x) + (int)(dgy * y))/2;
425 ((int)(dbx * x) + (int)(dby * y))/2;
426 current = (r << default_red_offset)
427 + (g << default_green_offset)
428 + (b << default_blue_offset);
430 *(data+inw-x) = current;
432 *(end-(inw-x)) = current;
439 void gradient_rectangle(Surface *sf, int inw, int inh)
441 pixel32 *data = sf->pixel_data;
442 pixel32 *end = data + inw*inh - 1;
444 float drx, dgx, dbx, dry, dgy, dby;
446 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
448 drx = (float)(sf->primary->r -
453 dgx = (float)(sf->primary->g -
458 dbx = (float)(sf->primary->b -
463 for (y = 0; y < h; ++y) {
464 for (x = 0; x < w; ++x, data) {
465 if ((float)x/(float)w < (float)y/(float)h) {
466 r = sf->primary->r + (drx * x);
467 g = sf->primary->g + (dgx * x);
468 b = sf->primary->b + (dbx * x);
470 r = sf->primary->r + (dry * x);
471 g = sf->primary->g + (dgy * x);
472 b = sf->primary->b + (dby * x);
474 current = (r << default_red_offset)
475 + (g << default_green_offset)
476 + (b << default_blue_offset);
478 *(data+inw-x) = current;
480 *(end-(inw-x)) = current;
487 void gradient_pipecross(Surface *sf, int inw, int inh)
489 pixel32 *data = sf->pixel_data;
490 pixel32 *end = data + inw*inh - 1;
492 float drx, dgx, dbx, dry, dgy, dby;
494 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
496 drx = (float)(sf->secondary->r -
501 dgx = (float)(sf->secondary->g -
506 dbx = (float)(sf->secondary->b -
511 for (y = 0; y < h; ++y) {
512 for (x = 0; x < w; ++x, data) {
513 if ((float)x/(float)w > (float)y/(float)h) {
514 r = sf->primary->r + (drx * x);
515 g = sf->primary->g + (dgx * x);
516 b = sf->primary->b + (dbx * x);
518 r = sf->primary->r + (dry * x);
519 g = sf->primary->g + (dgy * x);
520 b = sf->primary->b + (dby * x);
522 current = (r << default_red_offset)
523 + (g << default_green_offset)
524 + (b << default_blue_offset);
526 *(data+inw-x) = current;
528 *(end-(inw-x)) = current;