]> Dogcows Code - chaz/openbox/blob - render/gradient.c
more namespacing with Rr*
[chaz/openbox] / render / gradient.c
1 #include "render.h"
2 #include "gradient.h"
3 #include "color.h"
4 #include <glib.h>
5
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);
15
16 void RrRender(RrAppearance *a, int w, int h)
17 {
18 RrPixel32 *data = a->surface.RrPixel_data;
19 RrPixel32 current;
20 unsigned int r,g,b;
21 int off, x;
22
23 switch (a->surface.grad) {
24 case RR_SURFACE_SOLID:
25 gradient_solid(a, w, h);
26 return;
27 case RR_SURFACE_VERTICAL:
28 gradient_vertical(&a->surface, w, h);
29 break;
30 case RR_SURFACE_HORIZONTAL:
31 gradient_horizontal(&a->surface, w, h);
32 break;
33 case RR_SURFACE_DIAGONAL:
34 gradient_diagonal(&a->surface, w, h);
35 break;
36 case RR_SURFACE_CROSS_DIAGONAL:
37 gradient_crossdiagonal(&a->surface, w, h);
38 break;
39 case RR_SURFACE_PYRAMID:
40 gradient_pyramid(&a->surface, w, h);
41 break;
42 case RR_SURFACE_PIPECROSS:
43 gradient_pipecross(&a->surface, w, h);
44 break;
45 case RR_SURFACE_RECTANGLE:
46 gradient_rectangle(&a->surface, w, h);
47 break;
48 default:
49 g_message("unhandled gradient");
50 return;
51 }
52
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;
63 }
64 for (off = 0, x = 0; x < h; ++x, off++) {
65 *(data + (off * w)) = current;
66 *(data + (off * w) + w - 1) = current;
67 }
68 }
69
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++)
73 highlight(data + 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);
80 }
81
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);
91 }
92 }
93 }
94
95
96
97 static void gradient_vertical(RrSurface *sf, int w, int h)
98 {
99 RrPixel32 *data = sf->RrPixel_data;
100 RrPixel32 current;
101 float dr, dg, db;
102 unsigned int r,g,b;
103 int x, y;
104
105 dr = (float)(sf->secondary->r - sf->primary->r);
106 dr/= (float)h;
107
108 dg = (float)(sf->secondary->g - sf->primary->g);
109 dg/= (float)h;
110
111 db = (float)(sf->secondary->b - sf->primary->b);
112 db/= (float)h;
113
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)
122 *data = current;
123 }
124 }
125
126 static void gradient_horizontal(RrSurface *sf, int w, int h)
127 {
128 RrPixel32 *data = sf->RrPixel_data;
129 RrPixel32 current;
130 float dr, dg, db;
131 unsigned int r,g,b;
132 int x, y;
133
134 dr = (float)(sf->secondary->r - sf->primary->r);
135 dr/= (float)w;
136
137 dg = (float)(sf->secondary->g - sf->primary->g);
138 dg/= (float)w;
139
140 db = (float)(sf->secondary->b - sf->primary->b);
141 db/= (float)w;
142
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;
152 }
153 }
154
155 static void gradient_diagonal(RrSurface *sf, int w, int h)
156 {
157 RrPixel32 *data = sf->RrPixel_data;
158 RrPixel32 current;
159 float drx, dgx, dbx, dry, dgy, dby;
160 unsigned int r,g,b;
161 int x, y;
162
163 for (y = 0; y < h; ++y) {
164 drx = (float)(sf->secondary->r -
165 sf->primary->r);
166 dry = drx/(float)h;
167 drx/= (float)w;
168
169 dgx = (float)(sf->secondary->g -
170 sf->primary->g);
171 dgy = dgx/(float)h;
172 dgx/= (float)w;
173
174 dbx = (float)(sf->secondary->b -
175 sf->primary->b);
176 dby = dbx/(float)h;
177 dbx/= (float)w;
178 for (x = 0; x < w; ++x, ++data) {
179 r = sf->primary->r +
180 ((int)(drx * x) + (int)(dry * y))/2;
181 g = sf->primary->g +
182 ((int)(dgx * x) + (int)(dgy * y))/2;
183 b = sf->primary->b +
184 ((int)(dbx * x) + (int)(dby * y))/2;
185 current = (r << RrDefaultRedOffset)
186 + (g << RrDefaultGreenOffset)
187 + (b << RrDefaultBlueOffset);
188 *data = current;
189 }
190 }
191 }
192
193 static void gradient_crossdiagonal(RrSurface *sf, int w, int h)
194 {
195 RrPixel32 *data = sf->RrPixel_data;
196 RrPixel32 current;
197 float drx, dgx, dbx, dry, dgy, dby;
198 unsigned int r,g,b;
199 int x, y;
200
201 for (y = 0; y < h; ++y) {
202 drx = (float)(sf->secondary->r -
203 sf->primary->r);
204 dry = drx/(float)h;
205 drx/= (float)w;
206
207 dgx = (float)(sf->secondary->g -
208 sf->primary->g);
209 dgy = dgx/(float)h;
210 dgx/= (float)w;
211
212 dbx = (float)(sf->secondary->b -
213 sf->primary->b);
214 dby = dbx/(float)h;
215 dbx/= (float)w;
216 for (x = w; x > 0; --x, ++data) {
217 r = sf->primary->r +
218 ((int)(drx * (x-1)) + (int)(dry * y))/2;
219 g = sf->primary->g +
220 ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
221 b = sf->primary->b +
222 ((int)(dbx * (x-1)) + (int)(dby * y))/2;
223 current = (r << RrDefaultRedOffset)
224 + (g << RrDefaultGreenOffset)
225 + (b << RrDefaultBlueOffset);
226 *data = current;
227 }
228 }
229 }
230
231 static void highlight(RrPixel32 *x, RrPixel32 *y, gboolean raised)
232 {
233 int r, g, b;
234
235 RrPixel32 *up, *down;
236 if (raised) {
237 up = x;
238 down = y;
239 } else {
240 up = y;
241 down = x;
242 }
243 r = (*up >> RrDefaultRedOffset) & 0xFF;
244 r += r >> 1;
245 g = (*up >> RrDefaultGreenOffset) & 0xFF;
246 g += g >> 1;
247 b = (*up >> RrDefaultBlueOffset) & 0xFF;
248 b += b >> 1;
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);
254
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);
263 }
264
265 static void create_bevel_colors(RrAppearance *l)
266 {
267 int r, g, b;
268
269 /* light color */
270 r = l->surface.primary->r;
271 r += r >> 1;
272 g = l->surface.primary->g;
273 g += g >> 1;
274 b = l->surface.primary->b;
275 b += b >> 1;
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);
282
283 /* dark color */
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);
293 }
294
295 static void gradient_solid(RrAppearance *l, int w, int h)
296 {
297 RrPixel32 pix;
298 int i, a, b;
299 RrSurface *sp = &l->surface;
300 int left = 0, top = 0, right = w - 1, bottom = h - 1;
301
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);
307
308 for (a = 0; a < w; a++)
309 for (b = 0; b < h; b++)
310 sp->RrPixel_data[a + b * w] = pix;
311
312 XFillRectangle(RrDisplay(l->inst), l->pixmap, sp->primary->gc,
313 0, 0, w, h);
314
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,
320 0, i, w, i);
321 }
322
323 switch (sp->relief) {
324 case RR_RELIEF_RAISED:
325 if (!sp->bevel_dark)
326 create_bevel_colors(l);
327
328 switch (sp->bevel) {
329 case RR_BEVEL_1:
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);
334
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);
339 break;
340 case RR_BEVEL_2:
341 XDrawLine(RrDisplay(l->inst), l->pixmap,
342 sp->bevel_dark->gc,
343 left + 1, bottom - 2, right - 2, bottom - 2);
344 XDrawLine(RrDisplay(l->inst), l->pixmap,
345 sp->bevel_dark->gc,
346 right - 2, bottom - 2, right - 2, top + 1);
347
348 XDrawLine(RrDisplay(l->inst), l->pixmap,
349 sp->bevel_light->gc,
350 left + 1, top + 1, right - 2, top + 1);
351 XDrawLine(RrDisplay(l->inst), l->pixmap,
352 sp->bevel_light->gc,
353 left + 1, bottom - 2, left + 1, top + 1);
354 break;
355 default:
356 g_assert_not_reached(); /* unhandled BevelType */
357 }
358 break;
359 case RR_RELIEF_SUNKEN:
360 if (!sp->bevel_dark)
361 create_bevel_colors(l);
362
363 switch (sp->bevel) {
364 case RR_BEVEL_1:
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);
369
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);
374 break;
375 case RR_BEVEL_2:
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);
380
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);
385
386 break;
387 default:
388 g_assert_not_reached(); /* unhandled BevelType */
389 }
390 break;
391 case RR_RELIEF_FLAT:
392 if (sp->border) {
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);
397 }
398 break;
399 default:
400 g_assert_not_reached(); /* unhandled ReliefType */
401 }
402 }
403
404 static void gradient_pyramid(RrSurface *sf, int inw, int inh)
405 {
406 RrPixel32 *data = sf->RrPixel_data;
407 RrPixel32 *end = data + inw*inh - 1;
408 RrPixel32 current;
409 float drx, dgx, dbx, dry, dgy, dby;
410 unsigned int r,g,b;
411 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
412
413 drx = (float)(sf->secondary->r -
414 sf->primary->r);
415 dry = drx/(float)h;
416 drx/= (float)w;
417
418 dgx = (float)(sf->secondary->g -
419 sf->primary->g);
420 dgy = dgx/(float)h;
421 dgx/= (float)w;
422
423 dbx = (float)(sf->secondary->b -
424 sf->primary->b);
425 dby = dbx/(float)h;
426 dbx/= (float)w;
427
428 for (y = 0; y < h; ++y) {
429 for (x = 0; x < w; ++x, data) {
430 r = sf->primary->r +
431 ((int)(drx * x) + (int)(dry * y))/2;
432 g = sf->primary->g +
433 ((int)(dgx * x) + (int)(dgy * y))/2;
434 b = sf->primary->b +
435 ((int)(dbx * x) + (int)(dby * y))/2;
436 current = (r << RrDefaultRedOffset)
437 + (g << RrDefaultGreenOffset)
438 + (b << RrDefaultBlueOffset);
439 *(data+x) = current;
440 *(data+inw-x) = current;
441 *(end-x) = current;
442 *(end-(inw-x)) = current;
443 }
444 data+=inw;
445 end-=inw;
446 }
447 }
448
449 static void gradient_rectangle(RrSurface *sf, int inw, int inh)
450 {
451 RrPixel32 *data = sf->RrPixel_data;
452 RrPixel32 *end = data + inw*inh - 1;
453 RrPixel32 current;
454 float drx, dgx, dbx, dry, dgy, dby;
455 unsigned int r,g,b;
456 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
457
458 drx = (float)(sf->primary->r -
459 sf->secondary->r);
460 dry = drx/(float)h;
461 drx/= (float)w;
462
463 dgx = (float)(sf->primary->g -
464 sf->secondary->g);
465 dgy = dgx/(float)h;
466 dgx/= (float)w;
467
468 dbx = (float)(sf->primary->b -
469 sf->secondary->b);
470 dby = dbx/(float)h;
471 dbx/= (float)w;
472
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);
479 } else {
480 r = sf->primary->r + (dry * x);
481 g = sf->primary->g + (dgy * x);
482 b = sf->primary->b + (dby * x);
483 }
484 current = (r << RrDefaultRedOffset)
485 + (g << RrDefaultGreenOffset)
486 + (b << RrDefaultBlueOffset);
487 *(data+x) = current;
488 *(data+inw-x) = current;
489 *(end-x) = current;
490 *(end-(inw-x)) = current;
491 }
492 data+=inw;
493 end-=inw;
494 }
495 }
496
497 static void gradient_pipecross(RrSurface *sf, int inw, int inh)
498 {
499 RrPixel32 *data = sf->RrPixel_data;
500 RrPixel32 *end = data + inw*inh - 1;
501 RrPixel32 current;
502 float drx, dgx, dbx, dry, dgy, dby;
503 unsigned int r,g,b;
504 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
505
506 drx = (float)(sf->secondary->r -
507 sf->primary->r);
508 dry = drx/(float)h;
509 drx/= (float)w;
510
511 dgx = (float)(sf->secondary->g -
512 sf->primary->g);
513 dgy = dgx/(float)h;
514 dgx/= (float)w;
515
516 dbx = (float)(sf->secondary->b -
517 sf->primary->b);
518 dby = dbx/(float)h;
519 dbx/= (float)w;
520
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);
527 } else {
528 r = sf->primary->r + (dry * x);
529 g = sf->primary->g + (dgy * x);
530 b = sf->primary->b + (dby * x);
531 }
532 current = (r << RrDefaultRedOffset)
533 + (g << RrDefaultGreenOffset)
534 + (b << RrDefaultBlueOffset);
535 *(data+x) = current;
536 *(data+inw-x) = current;
537 *(end-x) = current;
538 *(end-(inw-x)) = current;
539 }
540 data+=inw;
541 end-=inw;
542 }
543 }
This page took 0.061198 seconds and 5 git commands to generate.