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");