7 #include "../kernel/openbox.h"
10 void gradient_render(Surface *sf, int w, int h)
12 pixel32 *data = sf->data.planar.pixel_data;
17 switch (sf->data.planar.grad) {
18 case Background_Solid: /* already handled */
20 case Background_Vertical:
21 gradient_vertical(sf, w, h);
23 case Background_Horizontal:
24 gradient_horizontal(sf, w, h);
26 case Background_Diagonal:
27 gradient_diagonal(sf, w, h);
29 case Background_CrossDiagonal:
30 gradient_crossdiagonal(sf, w, h);
32 case Background_Pyramid:
33 gradient_pyramid(sf, w, h);
35 case Background_PipeCross:
36 gradient_pipecross(sf, w, h);
38 case Background_Rectangle:
39 gradient_rectangle(sf, w, h);
42 g_message("unhandled gradient");
46 if (sf->data.planar.relief == Flat && sf->data.planar.border) {
47 r = sf->data.planar.border_color->r;
48 g = sf->data.planar.border_color->g;
49 b = sf->data.planar.border_color->b;
50 current = (r << default_red_offset)
51 + (g << default_green_offset)
52 + (b << default_blue_offset);
53 for (off = 0, x = 0; x < w; ++x, off++) {
54 *(data + off) = current;
55 *(data + off + ((h-1) * w)) = current;
57 for (off = 0, x = 0; x < h; ++x, off++) {
58 *(data + (off * w)) = current;
59 *(data + (off * w) + w - 1) = current;
63 if (sf->data.planar.relief != Flat) {
64 if (sf->data.planar.bevel == Bevel1) {
65 for (off = 1, x = 1; x < w - 1; ++x, off++)
67 data + off + (h-1) * w,
68 sf->data.planar.relief==Raised);
69 for (off = 0, x = 0; x < h; ++x, off++)
70 highlight(data + off * w,
71 data + off * w + w - 1,
72 sf->data.planar.relief==Raised);
75 if (sf->data.planar.bevel == Bevel2) {
76 for (off = 2, x = 2; x < w - 2; ++x, off++)
77 highlight(data + off + w,
78 data + off + (h-2) * w,
79 sf->data.planar.relief==Raised);
80 for (off = 1, x = 1; x < h-1; ++x, off++)
81 highlight(data + off * w + 1,
82 data + off * w + w - 2,
83 sf->data.planar.relief==Raised);
90 void gradient_vertical(Surface *sf, int w, int h)
92 pixel32 *data = sf->data.planar.pixel_data;
98 dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
101 dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
104 db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
107 for (y = 0; y < h; ++y) {
108 r = sf->data.planar.primary->r + (int)(dr * y);
109 g = sf->data.planar.primary->g + (int)(dg * y);
110 b = sf->data.planar.primary->b + (int)(db * y);
111 current = (r << default_red_offset)
112 + (g << default_green_offset)
113 + (b << default_blue_offset);
114 for (x = 0; x < w; ++x, ++data)
119 void gradient_horizontal(Surface *sf, int w, int h)
121 pixel32 *data = sf->data.planar.pixel_data;
127 dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
130 dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
133 db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
136 for (x = 0; x < w; ++x, ++data) {
137 r = sf->data.planar.primary->r + (int)(dr * x);
138 g = sf->data.planar.primary->g + (int)(dg * x);
139 b = sf->data.planar.primary->b + (int)(db * x);
140 current = (r << default_red_offset)
141 + (g << default_green_offset)
142 + (b << default_blue_offset);
143 for (y = 0; y < h; ++y)
144 *(data + y*w) = current;
148 void gradient_diagonal(Surface *sf, int w, int h)
150 pixel32 *data = sf->data.planar.pixel_data;
152 float drx, dgx, dbx, dry, dgy, dby;
156 for (y = 0; y < h; ++y) {
157 drx = (float)(sf->data.planar.secondary->r -
158 sf->data.planar.primary->r);
162 dgx = (float)(sf->data.planar.secondary->g -
163 sf->data.planar.primary->g);
167 dbx = (float)(sf->data.planar.secondary->b -
168 sf->data.planar.primary->b);
171 for (x = 0; x < w; ++x, ++data) {
172 r = sf->data.planar.primary->r +
173 ((int)(drx * x) + (int)(dry * y))/2;
174 g = sf->data.planar.primary->g +
175 ((int)(dgx * x) + (int)(dgy * y))/2;
176 b = sf->data.planar.primary->b +
177 ((int)(dbx * x) + (int)(dby * y))/2;
178 current = (r << default_red_offset)
179 + (g << default_green_offset)
180 + (b << default_blue_offset);
186 void gradient_crossdiagonal(Surface *sf, int w, int h)
188 pixel32 *data = sf->data.planar.pixel_data;
190 float drx, dgx, dbx, dry, dgy, dby;
194 for (y = 0; y < h; ++y) {
195 drx = (float)(sf->data.planar.secondary->r -
196 sf->data.planar.primary->r);
200 dgx = (float)(sf->data.planar.secondary->g -
201 sf->data.planar.primary->g);
205 dbx = (float)(sf->data.planar.secondary->b -
206 sf->data.planar.primary->b);
209 for (x = w; x > 0; --x, ++data) {
210 r = sf->data.planar.primary->r +
211 ((int)(drx * (x-1)) + (int)(dry * y))/2;
212 g = sf->data.planar.primary->g +
213 ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
214 b = sf->data.planar.primary->b +
215 ((int)(dbx * (x-1)) + (int)(dby * y))/2;
216 current = (r << default_red_offset)
217 + (g << default_green_offset)
218 + (b << default_blue_offset);
224 void highlight(pixel32 *x, pixel32 *y, gboolean raised)
236 r = (*up >> default_red_offset) & 0xFF;
238 g = (*up >> default_green_offset) & 0xFF;
240 b = (*up >> default_blue_offset) & 0xFF;
242 if (r > 0xFF) r = 0xFF;
243 if (g > 0xFF) g = 0xFF;
244 if (b > 0xFF) b = 0xFF;
245 *up = (r << default_red_offset) + (g << default_green_offset)
246 + (b << default_blue_offset);
248 r = (*down >> default_red_offset) & 0xFF;
249 r = (r >> 1) + (r >> 2);
250 g = (*down >> default_green_offset) & 0xFF;
251 g = (g >> 1) + (g >> 2);
252 b = (*down >> default_blue_offset) & 0xFF;
253 b = (b >> 1) + (b >> 2);
254 *down = (r << default_red_offset) + (g << default_green_offset)
255 + (b << default_blue_offset);
258 static void create_bevel_colors(Appearance *l)
263 r = l->surface.data.planar.primary->r;
265 g = l->surface.data.planar.primary->g;
267 b = l->surface.data.planar.primary->b;
269 if (r > 0xFF) r = 0xFF;
270 if (g > 0xFF) g = 0xFF;
271 if (b > 0xFF) b = 0xFF;
272 g_assert(!l->surface.data.planar.bevel_light);
273 l->surface.data.planar.bevel_light = color_new(r, g, b);
274 color_allocate_gc(l->surface.data.planar.bevel_light);
277 r = l->surface.data.planar.primary->r;
278 r = (r >> 1) + (r >> 2);
279 g = l->surface.data.planar.primary->g;
280 g = (g >> 1) + (g >> 2);
281 b = l->surface.data.planar.primary->b;
282 b = (b >> 1) + (b >> 2);
283 g_assert(!l->surface.data.planar.bevel_dark);
284 l->surface.data.planar.bevel_dark = color_new(r, g, b);
285 color_allocate_gc(l->surface.data.planar.bevel_dark);
288 void gradient_solid(Appearance *l, int x, int y, int w, int h)
292 PlanarSurface *sp = &l->surface.data.planar;
293 int left = x, top = y, right = x + w - 1, bottom = y + h - 1;
295 if (sp->primary->gc == None)
296 color_allocate_gc(sp->primary);
297 pix = (sp->primary->r << default_red_offset)
298 + (sp->primary->g << default_green_offset)
299 + (sp->primary->b << default_blue_offset);
301 for (a = 0; a < l->area.width; a++)
302 for (b = 0; b < l->area.height; b++)
303 sp->pixel_data[a + b*l->area.width] = pix;
305 XFillRectangle(ob_display, l->pixmap, sp->primary->gc,
308 if (sp->interlaced) {
309 if (sp->secondary->gc == None)
310 color_allocate_gc(sp->secondary);
311 for (i = y; i < h; i += 2)
312 XDrawLine(ob_display, l->pixmap, sp->secondary->gc,
316 switch (sp->relief) {
319 create_bevel_colors(l);
323 XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
324 left, bottom, right, bottom);
325 XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
326 right, bottom, right, top);
328 XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
329 left, top, right, top);
330 XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
331 left, bottom, left, top);
334 XDrawLine(ob_display, l->pixmap,
336 left + 1, bottom - 2, right - 2, bottom - 2);
337 XDrawLine(ob_display, l->pixmap,
339 right - 2, bottom - 2, right - 2, top + 1);
341 XDrawLine(ob_display, l->pixmap,
343 left + 1, top + 1, right - 2, top + 1);
344 XDrawLine(ob_display, l->pixmap,
346 left + 1, bottom - 2, left + 1, top + 1);
349 g_assert_not_reached(); /* unhandled BevelType */
354 create_bevel_colors(l);
358 XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
359 left, bottom, right, bottom);
360 XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
361 right, bottom, right, top);
363 XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
364 left, top, right, top);
365 XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
366 left, bottom, left, top);
369 XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
370 left + 1, bottom - 2, right - 2, bottom - 2);
371 XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
372 right - 2, bottom - 2, right - 2, top + 1);
374 XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
375 left + 1, top + 1, right - 2, top + 1);
376 XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
377 left + 1, bottom - 2, left + 1, top + 1);
381 g_assert_not_reached(); /* unhandled BevelType */
386 if (sp->border_color->gc == None)
387 color_allocate_gc(sp->border_color);
388 XDrawRectangle(ob_display, l->pixmap, sp->border_color->gc,
389 left, top, right, bottom);
393 g_assert_not_reached(); /* unhandled ReliefType */
397 void gradient_pyramid(Surface *sf, int inw, int inh)
399 pixel32 *data = sf->data.planar.pixel_data;
400 pixel32 *end = data + inw*inh - 1;
402 float drx, dgx, dbx, dry, dgy, dby;
404 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
405 for (y = 0; y < h; ++y) {
406 drx = (float)(sf->data.planar.secondary->r -
407 sf->data.planar.primary->r);
411 dgx = (float)(sf->data.planar.secondary->g -
412 sf->data.planar.primary->g);
416 dbx = (float)(sf->data.planar.secondary->b -
417 sf->data.planar.primary->b);
420 for (x = 0; x < w; ++x, data) {
421 r = sf->data.planar.primary->r +
422 ((int)(drx * x) + (int)(dry * y))/2;
423 g = sf->data.planar.primary->g +
424 ((int)(dgx * x) + (int)(dgy * y))/2;
425 b = sf->data.planar.primary->b +
426 ((int)(dbx * x) + (int)(dby * y))/2;
427 current = (r << default_red_offset)
428 + (g << default_green_offset)
429 + (b << default_blue_offset);
431 *(data+inw-x) = current;
433 *(end-(inw-x)) = current;
440 void gradient_rectangle(Surface *sf, int inw, int inh)
442 pixel32 *data = sf->data.planar.pixel_data;
443 pixel32 *end = data + inw*inh - 1;
445 float drx, dgx, dbx, dry, dgy, dby;
447 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
450 for (y = 0; y < h; ++y) {
451 drx = (float)(sf->data.planar.primary->r -
452 sf->data.planar.secondary->r);
456 dgx = (float)(sf->data.planar.primary->g -
457 sf->data.planar.secondary->g);
461 dbx = (float)(sf->data.planar.primary->b -
462 sf->data.planar.secondary->b);
465 for (x = 0; x < w; ++x, data) {
466 if ((float)x/(float)w < (float)y/(float)h) val = (int)(drx * x);
467 else val = (int)(dry * y);
469 r = sf->data.planar.secondary->r + val;
470 g = sf->data.planar.secondary->g + val;
471 b = sf->data.planar.secondary->b + val;
472 current = (r << default_red_offset)
473 + (g << default_green_offset)
474 + (b << default_blue_offset);
476 *(data+inw-x) = current;
478 *(end-(inw-x)) = current;
485 void gradient_pipecross(Surface *sf, int inw, int inh)
487 pixel32 *data = sf->data.planar.pixel_data;
488 pixel32 *end = data + inw*inh - 1;
490 float drx, dgx, dbx, dry, dgy, dby;
492 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
495 for (y = 0; y < h; ++y) {
496 drx = (float)(sf->data.planar.secondary->r -
497 sf->data.planar.primary->r);
501 dgx = (float)(sf->data.planar.secondary->g -
502 sf->data.planar.primary->g);
506 dbx = (float)(sf->data.planar.secondary->b -
507 sf->data.planar.primary->b);
510 for (x = 0; x < w; ++x, data) {
511 if ((float)x/(float)w > (float)y/(float)h) val = (int)(drx * x);
512 else val = (int)(dry * y);
514 r = sf->data.planar.primary->r + val;
515 g = sf->data.planar.primary->g + val;
516 b = sf->data.planar.primary->b + val;
517 current = (r << default_red_offset)
518 + (g << default_green_offset)
519 + (b << default_blue_offset);
521 *(data+inw-x) = current;
523 *(end-(inw-x)) = current;
530 void render_gl_gradient(Surface *sf, int x, int y, int w, int h)
536 pr = (float)sf->data.planar.primary->r/255.0;
537 pg = (float)sf->data.planar.primary->g/255.0;
538 pb = (float)sf->data.planar.primary->b/255.0;
539 if (sf->data.planar.secondary) {
540 sr = (float)sf->data.planar.secondary->r/255.0;
541 sg = (float)sf->data.planar.secondary->g/255.0;
542 sb = (float)sf->data.planar.secondary->b/255.0;
544 switch (sf->data.planar.grad) {
545 case Background_Solid: /* already handled */
546 glBegin(GL_TRIANGLES);
547 glColor3f(pr, pg, pb);
550 glVertex2i(x+w, y+h);
552 glVertex2i(x+w, y+h);
557 case Background_Horizontal:
558 glBegin(GL_TRIANGLES);
559 glColor3f(pr, pg, pb);
561 glColor3f(sr, sg, sb);
563 glVertex2i(x+w, y+h);
565 glVertex2i(x+w, y+h);
566 glColor3f(pr, pg, pb);
571 case Background_Vertical:
572 glBegin(GL_TRIANGLES);
573 glColor3f(pr, pg, pb);
576 glColor3f(sr, sg, sb);
577 glVertex2i(x+w, y+h);
579 glVertex2i(x+w, y+h);
581 glColor3f(pr, pg, pb);
585 case Background_Diagonal:
586 ar = (pr + sr) / 2.0;
587 ag = (pg + sg) / 2.0;
588 ab = (pb + sb) / 2.0;
589 glBegin(GL_TRIANGLES);
590 glColor3f(ar, ag, ab);
592 glColor3f(pr, pg, pb);
594 glColor3f(ar, ag, ab);
595 glVertex2i(x+w, y+h);
597 glColor3f(ar, ag, ab);
598 glVertex2i(x+w, y+h);
599 glColor3f(sr, sg, sb);
601 glColor3f(ar, ag, ab);
605 case Background_CrossDiagonal:
606 ar = (pr + sr) / 2.0;
607 ag = (pg + sg) / 2.0;
608 ab = (pb + sb) / 2.0;
609 glBegin(GL_TRIANGLES);
610 glColor3f(pr, pg, pb);
612 glColor3f(ar, ag, ab);
614 glColor3f(sr, sg, sb);
615 glVertex2i(x+w, y+h);
617 glColor3f(sr, sg, sb);
618 glVertex2i(x+w, y+h);
619 glColor3f(ar, ag, ab);
621 glColor3f(pr, pg, pb);
625 case Background_Pyramid:
626 ar = (pr + sr) / 2.0;
627 ag = (pg + sg) / 2.0;
628 ab = (pb + sb) / 2.0;
629 glBegin(GL_TRIANGLES);
630 glColor3f(pr, pg, pb);
632 glColor3f(sr, sg, sb);
633 glVertex2i(x+w/2, y+h/2);
634 glColor3f(ar, ag, ab);
635 glVertex2i(x, y+h/2);
637 glVertex2i(x, y+h/2);
638 glColor3f(sr, sg, sb);
639 glVertex2i(x+w/2, y+h/2);
640 glColor3f(pr, pg, pb);
644 glColor3f(sr, sg, sb);
645 glVertex2i(x+w/2, y+h/2);
646 glColor3f(ar, ag, ab);
647 glVertex2i(x+w/2, y+h);
649 glVertex2i(x+w/2, y+h);
650 glColor3f(sr, sg, sb);
651 glVertex2i(x+w/2, y+h/2);
652 glColor3f(pr, pg, pb);
653 glVertex2i(x+w, y+h);
655 glVertex2i(x+w, y+h);
656 glColor3f(sr, sg, sb);
657 glVertex2i(x+w/2, y+h/2);
658 glColor3f(ar, ag, ab);
659 glVertex2i(x+w, y+h/2);
661 glVertex2i(x+w, y+h/2);
662 glColor3f(sr, sg, sb);
663 glVertex2i(x+w/2, y+h/2);
664 glColor3f(pr, pg, pb);
668 glColor3f(sr, sg, sb);
669 glVertex2i(x+w/2, y+h/2);
670 glColor3f(ar, ag, ab);
671 glVertex2i(x+w/2, y);
673 glVertex2i(x+w/2, y);
674 glColor3f(sr, sg, sb);
675 glVertex2i(x+w/2, y+h/2);
676 glColor3f(pr, pg, pb);
680 case Background_PipeCross:
681 glBegin(GL_TRIANGLES);
682 glColor3f(pr, pg, pb);
684 glColor3f(sr, sg, sb);
685 glVertex2i(x+w/2, y+h/2);
686 glVertex2i(x, y+h/2);
688 glVertex2i(x, y+h/2);
689 glVertex2i(x+w/2, y+h/2);
690 glColor3f(pr, pg, pb);
694 glColor3f(sr, sg, sb);
695 glVertex2i(x+w/2, y+h/2);
696 glVertex2i(x+w/2, y+h);
698 glVertex2i(x+w/2, y+h);
699 glVertex2i(x+w/2, y+h/2);
700 glColor3f(pr, pg, pb);
701 glVertex2i(x+w, y+h);
703 glVertex2i(x+w, y+h);
704 glColor3f(sr, sg, sb);
705 glVertex2i(x+w/2, y+h/2);
706 glVertex2i(x+w, y+h/2);
708 glVertex2i(x+w, y+h/2);
709 glVertex2i(x+w/2, y+h/2);
710 glColor3f(pr, pg, pb);
714 glColor3f(sr, sg, sb);
715 glVertex2i(x+w/2, y+h/2);
716 glVertex2i(x+w/2, y);
718 glVertex2i(x+w/2, y);
719 glVertex2i(x+w/2, y+h/2);
720 glColor3f(pr, pg, pb);
724 case Background_Rectangle:
725 glBegin(GL_TRIANGLES);
726 glColor3f(pr, pg, pb);
728 glColor3f(sr, sg, sb);
729 glVertex2i(x+w/2, y+h/2);
730 glColor3f(pr, pg, pb);
734 glColor3f(sr, sg, sb);
735 glVertex2i(x+w/2, y+h/2);
736 glColor3f(pr, pg, pb);
737 glVertex2i(x+w, y+h);
739 glVertex2i(x+w, y+h);
740 glColor3f(sr, sg, sb);
741 glVertex2i(x+w/2, y+h/2);
742 glColor3f(pr, pg, pb);
746 glColor3f(sr, sg, sb);
747 glVertex2i(x+w/2, y+h/2);
748 glColor3f(pr, pg, pb);
754 g_message("unhandled gradient");