6 static void highlight(RrPixel32 *x, RrPixel32 *y, gboolean raised);
7 static void gradient_solid(RrAppearance *l, int w, int h);
8 static void gradient_vertical(RrSurface *sf, int w, int h);
9 static void gradient_horizontal(RrSurface *sf, int w, int h);
10 static void gradient_diagonal(RrSurface *sf, int w, int h);
11 static void gradient_crossdiagonal(RrSurface *sf, int w, int h);
12 static void gradient_pyramid(RrSurface *sf, int inw, int inh);
13 static void gradient_rectangle(RrSurface *sf, int inw, int inh);
14 static void gradient_pipecross(RrSurface *sf, int inw, int inh);
16 void RrRender(RrAppearance *a, int w, int h)
18 RrPixel32 *data = a->surface.RrPixel_data;
23 switch (a->surface.grad) {
24 case RR_SURFACE_SOLID:
25 gradient_solid(a, w, h);
27 case RR_SURFACE_VERTICAL:
28 gradient_vertical(&a->surface, w, h);
30 case RR_SURFACE_HORIZONTAL:
31 gradient_horizontal(&a->surface, w, h);
33 case RR_SURFACE_DIAGONAL:
34 gradient_diagonal(&a->surface, w, h);
36 case RR_SURFACE_CROSS_DIAGONAL:
37 gradient_crossdiagonal(&a->surface, w, h);
39 case RR_SURFACE_PYRAMID:
40 gradient_pyramid(&a->surface, w, h);
42 case RR_SURFACE_PIPECROSS:
43 gradient_pipecross(&a->surface, w, h);
45 case RR_SURFACE_RECTANGLE:
46 gradient_rectangle(&a->surface, w, h);
49 g_message("unhandled gradient");
53 if (a->surface.relief == RR_RELIEF_FLAT && a->surface.border) {
54 r = a->surface.border_color->r;
55 g = a->surface.border_color->g;
56 b = a->surface.border_color->b;
57 current = (r << RrDefaultRedOffset)
58 + (g << RrDefaultGreenOffset)
59 + (b << RrDefaultBlueOffset);
60 for (off = 0, x = 0; x < w; ++x, off++) {
61 *(data + off) = current;
62 *(data + off + ((h-1) * w)) = current;
64 for (off = 0, x = 0; x < h; ++x, off++) {
65 *(data + (off * w)) = current;
66 *(data + (off * w) + w - 1) = current;
70 if (a->surface.relief != RR_RELIEF_FLAT) {
71 if (a->surface.bevel == RR_BEVEL_1) {
72 for (off = 1, x = 1; x < w - 1; ++x, off++)
74 data + off + (h-1) * w,
75 a->surface.relief==RR_RELIEF_RAISED);
76 for (off = 0, x = 0; x < h; ++x, off++)
77 highlight(data + off * w,
78 data + off * w + w - 1,
79 a->surface.relief==RR_RELIEF_RAISED);
82 if (a->surface.bevel == RR_BEVEL_2) {
83 for (off = 2, x = 2; x < w - 2; ++x, off++)
84 highlight(data + off + w,
85 data + off + (h-2) * w,
86 a->surface.relief==RR_RELIEF_RAISED);
87 for (off = 1, x = 1; x < h-1; ++x, off++)
88 highlight(data + off * w + 1,
89 data + off * w + w - 2,
90 a->surface.relief==RR_RELIEF_RAISED);
95 static void highlight(RrPixel32 *x, RrPixel32 *y, gboolean raised)
107 r = (*up >> RrDefaultRedOffset) & 0xFF;
109 g = (*up >> RrDefaultGreenOffset) & 0xFF;
111 b = (*up >> RrDefaultBlueOffset) & 0xFF;
113 if (r > 0xFF) r = 0xFF;
114 if (g > 0xFF) g = 0xFF;
115 if (b > 0xFF) b = 0xFF;
116 *up = (r << RrDefaultRedOffset) + (g << RrDefaultGreenOffset)
117 + (b << RrDefaultBlueOffset);
119 r = (*down >> RrDefaultRedOffset) & 0xFF;
120 r = (r >> 1) + (r >> 2);
121 g = (*down >> RrDefaultGreenOffset) & 0xFF;
122 g = (g >> 1) + (g >> 2);
123 b = (*down >> RrDefaultBlueOffset) & 0xFF;
124 b = (b >> 1) + (b >> 2);
125 *down = (r << RrDefaultRedOffset) + (g << RrDefaultGreenOffset)
126 + (b << RrDefaultBlueOffset);
129 static void create_bevel_colors(RrAppearance *l)
134 r = l->surface.primary->r;
136 g = l->surface.primary->g;
138 b = l->surface.primary->b;
140 if (r > 0xFF) r = 0xFF;
141 if (g > 0xFF) g = 0xFF;
142 if (b > 0xFF) b = 0xFF;
143 g_assert(!l->surface.bevel_light);
144 l->surface.bevel_light = RrColorNew(l->inst, r, g, b);
145 RrColorAllocateGC(l->surface.bevel_light);
148 r = l->surface.primary->r;
149 r = (r >> 1) + (r >> 2);
150 g = l->surface.primary->g;
151 g = (g >> 1) + (g >> 2);
152 b = l->surface.primary->b;
153 b = (b >> 1) + (b >> 2);
154 g_assert(!l->surface.bevel_dark);
155 l->surface.bevel_dark = RrColorNew(l->inst, r, g, b);
156 RrColorAllocateGC(l->surface.bevel_dark);
159 static void gradient_solid(RrAppearance *l, int w, int h)
163 RrSurface *sp = &l->surface;
164 int left = 0, top = 0, right = w - 1, bottom = h - 1;
166 if (sp->primary->gc == None)
167 RrColorAllocateGC(sp->primary);
168 pix = (sp->primary->r << RrDefaultRedOffset)
169 + (sp->primary->g << RrDefaultGreenOffset)
170 + (sp->primary->b << RrDefaultBlueOffset);
172 for (a = 0; a < w; a++)
173 for (b = 0; b < h; b++)
174 sp->RrPixel_data[a + b * w] = pix;
176 XFillRectangle(RrDisplay(l->inst), l->pixmap, sp->primary->gc,
179 if (sp->interlaced) {
180 if (sp->secondary->gc == None)
181 RrColorAllocateGC(sp->secondary);
182 for (i = 0; i < h; i += 2)
183 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->secondary->gc,
187 switch (sp->relief) {
188 case RR_RELIEF_RAISED:
190 create_bevel_colors(l);
194 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
195 left, bottom, right, bottom);
196 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
197 right, bottom, right, top);
199 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
200 left, top, right, top);
201 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
202 left, bottom, left, top);
205 XDrawLine(RrDisplay(l->inst), l->pixmap,
207 left + 1, bottom - 2, right - 2, bottom - 2);
208 XDrawLine(RrDisplay(l->inst), l->pixmap,
210 right - 2, bottom - 2, right - 2, top + 1);
212 XDrawLine(RrDisplay(l->inst), l->pixmap,
214 left + 1, top + 1, right - 2, top + 1);
215 XDrawLine(RrDisplay(l->inst), l->pixmap,
217 left + 1, bottom - 2, left + 1, top + 1);
220 g_assert_not_reached(); /* unhandled BevelType */
223 case RR_RELIEF_SUNKEN:
225 create_bevel_colors(l);
229 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
230 left, bottom, right, bottom);
231 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
232 right, bottom, right, top);
234 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
235 left, top, right, top);
236 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
237 left, bottom, left, top);
240 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
241 left + 1, bottom - 2, right - 2, bottom - 2);
242 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
243 right - 2, bottom - 2, right - 2, top + 1);
245 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
246 left + 1, top + 1, right - 2, top + 1);
247 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
248 left + 1, bottom - 2, left + 1, top + 1);
252 g_assert_not_reached(); /* unhandled BevelType */
257 if (sp->border_color->gc == None)
258 RrColorAllocateGC(sp->border_color);
259 XDrawRectangle(RrDisplay(l->inst), l->pixmap, sp->border_color->gc,
260 left, top, right, bottom);
264 g_assert_not_reached(); /* unhandled ReliefType */
268 /* * * * * * * * * * * * * * GRADIENT MAGIC WOOT * * * * * * * * * * * * * * */
271 unsigned int color##x[3]; \
272 int len##x, cdelta##x[3], error##x[3] = { 0, 0, 0 }, inc##x[3]; \
273 gboolean bigslope##x[3] /* color slope > 1 */
275 #define SETUP(x, from, to, w) \
278 color##x[0] = from->r; \
279 color##x[1] = from->g; \
280 color##x[2] = from->b; \
282 cdelta##x[0] = to->r - from->r; \
283 cdelta##x[1] = to->g - from->g; \
284 cdelta##x[2] = to->b - from->b; \
286 if (cdelta##x[0] < 0) { \
287 cdelta##x[0] = -cdelta##x[0]; \
291 if (cdelta##x[1] < 0) { \
292 cdelta##x[1] = -cdelta##x[1]; \
296 if (cdelta##x[2] < 0) { \
297 cdelta##x[2] = -cdelta##x[2]; \
301 bigslope##x[0] = cdelta##x[0] > w;\
302 bigslope##x[1] = cdelta##x[1] > w;\
303 bigslope##x[2] = cdelta##x[2] > w
305 #define COLOR_RR(x, c) \
306 c->r = color##x[0]; \
307 c->g = color##x[1]; \
311 ((color##x[0] << RrDefaultRedOffset) + \
312 (color##x[1] << RrDefaultGreenOffset) + \
313 (color##x[2] << RrDefaultBlueOffset))
318 for (i = 2; i >= 0; --i) { \
319 if (!cdelta##x[i]) continue; \
321 if (!bigslope##x[i]) { \
322 /* Y (color) is dependant on X */ \
323 error##x[i] += cdelta##x[i]; \
324 if ((error##x[i] << 1) >= len##x) { \
325 color##x[i] += inc##x[i]; \
326 error##x[i] -= len##x; \
329 /* X is dependant on Y (color) */ \
331 color##x[i] += inc##x[i]; \
332 error##x[i] += len##x; \
333 if ((error##x[i] << 1) >= cdelta##x[i]) { \
334 error##x[i] -= cdelta##x[i]; \
342 static void gradient_horizontal(RrSurface *sf, int w, int h)
345 RrPixel32 *data = sf->RrPixel_data;
349 SETUP(x, sf->primary, sf->secondary, w);
351 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
353 for (y = h - 1; y >= 0; --y) /* 0 -> h */
354 *(data + y * w) = current;
360 for (y = h - 1; y >= 0; --y) /* 0 -> h */
361 *(data + y * w) = current;
364 static void gradient_vertical(RrSurface *sf, int w, int h)
367 RrPixel32 *data = sf->RrPixel_data;
371 SETUP(y, sf->primary, sf->secondary, h);
373 for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
375 for (x = w - 1; x >= 0; --x) /* 0 -> w */
381 for (x = w - 1; x >= 0; --x) /* 0 -> w */
386 static void gradient_diagonal(RrSurface *sf, int w, int h)
389 RrPixel32 *data = sf->RrPixel_data;
397 extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
398 extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
399 extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
401 SETUP(lefty, sf->primary, (&extracorner), h);
402 SETUP(righty, (&extracorner), sf->secondary, h);
404 for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
405 COLOR_RR(lefty, (&left));
406 COLOR_RR(righty, (&right));
408 SETUP(x, (&left), (&right), w);
410 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
411 *(data++) = COLOR(x);
415 *(data++) = COLOR(x);
420 COLOR_RR(lefty, (&left));
421 COLOR_RR(righty, (&right));
423 SETUP(x, (&left), (&right), w);
425 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
426 *(data++) = COLOR(x);
433 static void gradient_crossdiagonal(RrSurface *sf, int w, int h)
436 RrPixel32 *data = sf->RrPixel_data;
444 extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
445 extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
446 extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
448 SETUP(lefty, (&extracorner), sf->secondary, h);
449 SETUP(righty, sf->primary, (&extracorner), h);
451 for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
452 COLOR_RR(lefty, (&left));
453 COLOR_RR(righty, (&right));
455 SETUP(x, (&left), (&right), w);
457 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
458 *(data++) = COLOR(x);
462 *(data++) = COLOR(x);
467 COLOR_RR(lefty, (&left));
468 COLOR_RR(righty, (&right));
470 SETUP(x, (&left), (&right), w);
472 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
473 *(data++) = COLOR(x);
480 static void gradient_pyramid(RrSurface *sf, int inw, int inh)
482 int x, y, w = (inw >> 1) + 1, h = (inh >> 1) + 1;
483 RrPixel32 *data = sf->RrPixel_data;
484 RrPixel32 *end = data + inw*inh - 1;
493 extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
494 extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
495 extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
497 SETUP(lefty, (&extracorner), sf->secondary, h);
498 SETUP(righty, sf->primary, (&extracorner), h);
500 for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
501 COLOR_RR(lefty, (&left));
502 COLOR_RR(righty, (&right));
504 SETUP(x, (&left), (&right), w);
506 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
509 *(data+inw-x) = current;
511 *(end-(inw-x)) = current;
517 *(data+inw-x) = current;
519 *(end-(inw-x)) = current;
527 COLOR_RR(lefty, (&left));
528 COLOR_RR(righty, (&right));
530 SETUP(x, (&left), (&right), w);
532 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
535 *(data+inw-x) = current;
537 *(end-(inw-x)) = current;
542 *(data+inw-x) = current;
544 *(end-(inw-x)) = current;
547 static void gradient_rectangle(RrSurface *sf, int inw, int inh)
549 int x, y, w = (inw >> 1) + 1, h = (inh >> 1) + 1;
550 RrPixel32 *data = sf->RrPixel_data;
551 RrPixel32 *end = data + inw*inh - 1;
560 extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
561 extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
562 extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
564 SETUP(lefty, (&extracorner), sf->secondary, h);
565 SETUP(righty, sf->primary, (&extracorner), h);
567 for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
568 COLOR_RR(lefty, (&left));
569 COLOR_RR(righty, (&right));
571 SETUP(x, (&left), (&right), w);
573 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
576 *(data+inw-x) = current;
578 *(end-(inw-x)) = current;
584 *(data+inw-x) = current;
586 *(end-(inw-x)) = current;
594 COLOR_RR(lefty, (&left));
595 COLOR_RR(righty, (&right));
597 SETUP(x, (&left), (&right), w);
599 for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
602 *(data+inw-x) = current;
604 *(end-(inw-x)) = current;
609 *(data+inw-x) = current;
611 *(end-(inw-x)) = current;
614 static void gradient_pipecross(RrSurface *sf, int inw, int inh)
616 RrPixel32 *data = sf->RrPixel_data;
617 RrPixel32 *end = data + inw*inh - 1;
619 float drx, dgx, dbx, dry, dgy, dby;
621 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
623 drx = (float)(sf->secondary->r -
628 dgx = (float)(sf->secondary->g -
633 dbx = (float)(sf->secondary->b -
638 for (y = 0; y < h; ++y) {
639 for (x = 0; x < w; ++x, data) {
640 if ((float)x/(float)w > (float)y/(float)h) {
641 r = sf->primary->r + (drx * x);
642 g = sf->primary->g + (dgx * x);
643 b = sf->primary->b + (dbx * x);
645 r = sf->primary->r + (dry * x);
646 g = sf->primary->g + (dgy * x);
647 b = sf->primary->b + (dby * x);
649 current = (r << RrDefaultRedOffset)
650 + (g << RrDefaultGreenOffset)
651 + (b << RrDefaultBlueOffset);
653 *(data+inw-x) = current;
655 *(end-(inw-x)) = current;