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);
97 static void gradient_vertical(RrSurface *sf, int w, int h)
99 RrPixel32 *data = sf->RrPixel_data;
105 dr = (float)(sf->secondary->r - sf->primary->r);
108 dg = (float)(sf->secondary->g - sf->primary->g);
111 db = (float)(sf->secondary->b - sf->primary->b);
114 for (y = 0; y < h; ++y) {
115 r = sf->primary->r + (int)(dr * y);
116 g = sf->primary->g + (int)(dg * y);
117 b = sf->primary->b + (int)(db * y);
118 current = (r << RrDefaultRedOffset)
119 + (g << RrDefaultGreenOffset)
120 + (b << RrDefaultBlueOffset);
121 for (x = 0; x < w; ++x, ++data)
126 static void gradient_horizontal(RrSurface *sf, int w, int h)
128 RrPixel32 *data = sf->RrPixel_data;
134 dr = (float)(sf->secondary->r - sf->primary->r);
137 dg = (float)(sf->secondary->g - sf->primary->g);
140 db = (float)(sf->secondary->b - sf->primary->b);
143 for (x = 0; x < w; ++x, ++data) {
144 r = sf->primary->r + (int)(dr * x);
145 g = sf->primary->g + (int)(dg * x);
146 b = sf->primary->b + (int)(db * x);
147 current = (r << RrDefaultRedOffset)
148 + (g << RrDefaultGreenOffset)
149 + (b << RrDefaultBlueOffset);
150 for (y = 0; y < h; ++y)
151 *(data + y*w) = current;
155 static void gradient_diagonal(RrSurface *sf, int w, int h)
157 RrPixel32 *data = sf->RrPixel_data;
159 float drx, dgx, dbx, dry, dgy, dby;
163 for (y = 0; y < h; ++y) {
164 drx = (float)(sf->secondary->r -
169 dgx = (float)(sf->secondary->g -
174 dbx = (float)(sf->secondary->b -
178 for (x = 0; x < w; ++x, ++data) {
180 ((int)(drx * x) + (int)(dry * y))/2;
182 ((int)(dgx * x) + (int)(dgy * y))/2;
184 ((int)(dbx * x) + (int)(dby * y))/2;
185 current = (r << RrDefaultRedOffset)
186 + (g << RrDefaultGreenOffset)
187 + (b << RrDefaultBlueOffset);
193 static void gradient_crossdiagonal(RrSurface *sf, int w, int h)
195 RrPixel32 *data = sf->RrPixel_data;
197 float drx, dgx, dbx, dry, dgy, dby;
201 for (y = 0; y < h; ++y) {
202 drx = (float)(sf->secondary->r -
207 dgx = (float)(sf->secondary->g -
212 dbx = (float)(sf->secondary->b -
216 for (x = w; x > 0; --x, ++data) {
218 ((int)(drx * (x-1)) + (int)(dry * y))/2;
220 ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
222 ((int)(dbx * (x-1)) + (int)(dby * y))/2;
223 current = (r << RrDefaultRedOffset)
224 + (g << RrDefaultGreenOffset)
225 + (b << RrDefaultBlueOffset);
231 static void highlight(RrPixel32 *x, RrPixel32 *y, gboolean raised)
235 RrPixel32 *up, *down;
243 r = (*up >> RrDefaultRedOffset) & 0xFF;
245 g = (*up >> RrDefaultGreenOffset) & 0xFF;
247 b = (*up >> RrDefaultBlueOffset) & 0xFF;
249 if (r > 0xFF) r = 0xFF;
250 if (g > 0xFF) g = 0xFF;
251 if (b > 0xFF) b = 0xFF;
252 *up = (r << RrDefaultRedOffset) + (g << RrDefaultGreenOffset)
253 + (b << RrDefaultBlueOffset);
255 r = (*down >> RrDefaultRedOffset) & 0xFF;
256 r = (r >> 1) + (r >> 2);
257 g = (*down >> RrDefaultGreenOffset) & 0xFF;
258 g = (g >> 1) + (g >> 2);
259 b = (*down >> RrDefaultBlueOffset) & 0xFF;
260 b = (b >> 1) + (b >> 2);
261 *down = (r << RrDefaultRedOffset) + (g << RrDefaultGreenOffset)
262 + (b << RrDefaultBlueOffset);
265 static void create_bevel_colors(RrAppearance *l)
270 r = l->surface.primary->r;
272 g = l->surface.primary->g;
274 b = l->surface.primary->b;
276 if (r > 0xFF) r = 0xFF;
277 if (g > 0xFF) g = 0xFF;
278 if (b > 0xFF) b = 0xFF;
279 g_assert(!l->surface.bevel_light);
280 l->surface.bevel_light = RrColorNew(l->inst, r, g, b);
281 RrColorAllocateGC(l->surface.bevel_light);
284 r = l->surface.primary->r;
285 r = (r >> 1) + (r >> 2);
286 g = l->surface.primary->g;
287 g = (g >> 1) + (g >> 2);
288 b = l->surface.primary->b;
289 b = (b >> 1) + (b >> 2);
290 g_assert(!l->surface.bevel_dark);
291 l->surface.bevel_dark = RrColorNew(l->inst, r, g, b);
292 RrColorAllocateGC(l->surface.bevel_dark);
295 static void gradient_solid(RrAppearance *l, int w, int h)
299 RrSurface *sp = &l->surface;
300 int left = 0, top = 0, right = w - 1, bottom = h - 1;
302 if (sp->primary->gc == None)
303 RrColorAllocateGC(sp->primary);
304 pix = (sp->primary->r << RrDefaultRedOffset)
305 + (sp->primary->g << RrDefaultGreenOffset)
306 + (sp->primary->b << RrDefaultBlueOffset);
308 for (a = 0; a < w; a++)
309 for (b = 0; b < h; b++)
310 sp->RrPixel_data[a + b * w] = pix;
312 XFillRectangle(RrDisplay(l->inst), l->pixmap, sp->primary->gc,
315 if (sp->interlaced) {
316 if (sp->secondary->gc == None)
317 RrColorAllocateGC(sp->secondary);
318 for (i = 0; i < h; i += 2)
319 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->secondary->gc,
323 switch (sp->relief) {
324 case RR_RELIEF_RAISED:
326 create_bevel_colors(l);
330 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
331 left, bottom, right, bottom);
332 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
333 right, bottom, right, top);
335 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
336 left, top, right, top);
337 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
338 left, bottom, left, top);
341 XDrawLine(RrDisplay(l->inst), l->pixmap,
343 left + 1, bottom - 2, right - 2, bottom - 2);
344 XDrawLine(RrDisplay(l->inst), l->pixmap,
346 right - 2, bottom - 2, right - 2, top + 1);
348 XDrawLine(RrDisplay(l->inst), l->pixmap,
350 left + 1, top + 1, right - 2, top + 1);
351 XDrawLine(RrDisplay(l->inst), l->pixmap,
353 left + 1, bottom - 2, left + 1, top + 1);
356 g_assert_not_reached(); /* unhandled BevelType */
359 case RR_RELIEF_SUNKEN:
361 create_bevel_colors(l);
365 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
366 left, bottom, right, bottom);
367 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
368 right, bottom, right, top);
370 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
371 left, top, right, top);
372 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
373 left, bottom, left, top);
376 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
377 left + 1, bottom - 2, right - 2, bottom - 2);
378 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
379 right - 2, bottom - 2, right - 2, top + 1);
381 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
382 left + 1, top + 1, right - 2, top + 1);
383 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
384 left + 1, bottom - 2, left + 1, top + 1);
388 g_assert_not_reached(); /* unhandled BevelType */
393 if (sp->border_color->gc == None)
394 RrColorAllocateGC(sp->border_color);
395 XDrawRectangle(RrDisplay(l->inst), l->pixmap, sp->border_color->gc,
396 left, top, right, bottom);
400 g_assert_not_reached(); /* unhandled ReliefType */
404 static void gradient_pyramid(RrSurface *sf, int inw, int inh)
406 RrPixel32 *data = sf->RrPixel_data;
407 RrPixel32 *end = data + inw*inh - 1;
409 float drx, dgx, dbx, dry, dgy, dby;
411 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
413 drx = (float)(sf->secondary->r -
418 dgx = (float)(sf->secondary->g -
423 dbx = (float)(sf->secondary->b -
428 for (y = 0; y < h; ++y) {
429 for (x = 0; x < w; ++x, data) {
431 ((int)(drx * x) + (int)(dry * y))/2;
433 ((int)(dgx * x) + (int)(dgy * y))/2;
435 ((int)(dbx * x) + (int)(dby * y))/2;
436 current = (r << RrDefaultRedOffset)
437 + (g << RrDefaultGreenOffset)
438 + (b << RrDefaultBlueOffset);
440 *(data+inw-x) = current;
442 *(end-(inw-x)) = current;
449 static void gradient_rectangle(RrSurface *sf, int inw, int inh)
451 RrPixel32 *data = sf->RrPixel_data;
452 RrPixel32 *end = data + inw*inh - 1;
454 float drx, dgx, dbx, dry, dgy, dby;
456 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
458 drx = (float)(sf->primary->r -
463 dgx = (float)(sf->primary->g -
468 dbx = (float)(sf->primary->b -
473 for (y = 0; y < h; ++y) {
474 for (x = 0; x < w; ++x, data) {
475 if ((float)x/(float)w < (float)y/(float)h) {
476 r = sf->primary->r + (drx * x);
477 g = sf->primary->g + (dgx * x);
478 b = sf->primary->b + (dbx * x);
480 r = sf->primary->r + (dry * x);
481 g = sf->primary->g + (dgy * x);
482 b = sf->primary->b + (dby * x);
484 current = (r << RrDefaultRedOffset)
485 + (g << RrDefaultGreenOffset)
486 + (b << RrDefaultBlueOffset);
488 *(data+inw-x) = current;
490 *(end-(inw-x)) = current;
497 static void gradient_pipecross(RrSurface *sf, int inw, int inh)
499 RrPixel32 *data = sf->RrPixel_data;
500 RrPixel32 *end = data + inw*inh - 1;
502 float drx, dgx, dbx, dry, dgy, dby;
504 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
506 drx = (float)(sf->secondary->r -
511 dgx = (float)(sf->secondary->g -
516 dbx = (float)(sf->secondary->b -
521 for (y = 0; y < h; ++y) {
522 for (x = 0; x < w; ++x, data) {
523 if ((float)x/(float)w > (float)y/(float)h) {
524 r = sf->primary->r + (drx * x);
525 g = sf->primary->g + (dgx * x);
526 b = sf->primary->b + (dbx * x);
528 r = sf->primary->r + (dry * x);
529 g = sf->primary->g + (dgy * x);
530 b = sf->primary->b + (dby * x);
532 current = (r << RrDefaultRedOffset)
533 + (g << RrDefaultGreenOffset)
534 + (b << RrDefaultBlueOffset);
536 *(data+inw-x) = current;
538 *(end-(inw-x)) = current;