]> Dogcows Code - chaz/openbox/blob - render/gradient.c
rename pixel32/16 to RrPixel32/16
[chaz/openbox] / render / gradient.c
1 #include "render.h"
2 #include "gradient.h"
3 #include "color.h"
4 #include <glib.h>
5
6 void gradient_render(RrSurface *sf, int w, int h)
7 {
8 RrPixel32 *data = sf->RrPixel_data;
9 RrPixel32 current;
10 unsigned int r,g,b;
11 int off, x;
12
13 switch (sf->grad) {
14 case RR_SURFACE_SOLID: /* already handled */
15 return;
16 case RR_SURFACE_VERTICAL:
17 gradient_vertical(sf, w, h);
18 break;
19 case RR_SURFACE_HORIZONTAL:
20 gradient_horizontal(sf, w, h);
21 break;
22 case RR_SURFACE_DIAGONAL:
23 gradient_diagonal(sf, w, h);
24 break;
25 case RR_SURFACE_CROSS_DIAGONAL:
26 gradient_crossdiagonal(sf, w, h);
27 break;
28 case RR_SURFACE_PYRAMID:
29 gradient_pyramid(sf, w, h);
30 break;
31 case RR_SURFACE_PIPECROSS:
32 gradient_pipecross(sf, w, h);
33 break;
34 case RR_SURFACE_RECTANGLE:
35 gradient_rectangle(sf, w, h);
36 break;
37 default:
38 g_message("unhandled gradient");
39 return;
40 }
41
42 if (sf->relief == RR_RELIEF_FLAT && sf->border) {
43 r = sf->border_color->r;
44 g = sf->border_color->g;
45 b = sf->border_color->b;
46 current = (r << default_red_offset)
47 + (g << default_green_offset)
48 + (b << default_blue_offset);
49 for (off = 0, x = 0; x < w; ++x, off++) {
50 *(data + off) = current;
51 *(data + off + ((h-1) * w)) = current;
52 }
53 for (off = 0, x = 0; x < h; ++x, off++) {
54 *(data + (off * w)) = current;
55 *(data + (off * w) + w - 1) = current;
56 }
57 }
58
59 if (sf->relief != RR_RELIEF_FLAT) {
60 if (sf->bevel == RR_BEVEL_1) {
61 for (off = 1, x = 1; x < w - 1; ++x, off++)
62 highlight(data + off,
63 data + off + (h-1) * w,
64 sf->relief==RR_RELIEF_RAISED);
65 for (off = 0, x = 0; x < h; ++x, off++)
66 highlight(data + off * w,
67 data + off * w + w - 1,
68 sf->relief==RR_RELIEF_RAISED);
69 }
70
71 if (sf->bevel == RR_BEVEL_2) {
72 for (off = 2, x = 2; x < w - 2; ++x, off++)
73 highlight(data + off + w,
74 data + off + (h-2) * w,
75 sf->relief==RR_RELIEF_RAISED);
76 for (off = 1, x = 1; x < h-1; ++x, off++)
77 highlight(data + off * w + 1,
78 data + off * w + w - 2,
79 sf->relief==RR_RELIEF_RAISED);
80 }
81 }
82 }
83
84
85
86 void gradient_vertical(RrSurface *sf, int w, int h)
87 {
88 RrPixel32 *data = sf->RrPixel_data;
89 RrPixel32 current;
90 float dr, dg, db;
91 unsigned int r,g,b;
92 int x, y;
93
94 dr = (float)(sf->secondary->r - sf->primary->r);
95 dr/= (float)h;
96
97 dg = (float)(sf->secondary->g - sf->primary->g);
98 dg/= (float)h;
99
100 db = (float)(sf->secondary->b - sf->primary->b);
101 db/= (float)h;
102
103 for (y = 0; y < h; ++y) {
104 r = sf->primary->r + (int)(dr * y);
105 g = sf->primary->g + (int)(dg * y);
106 b = sf->primary->b + (int)(db * y);
107 current = (r << default_red_offset)
108 + (g << default_green_offset)
109 + (b << default_blue_offset);
110 for (x = 0; x < w; ++x, ++data)
111 *data = current;
112 }
113 }
114
115 void gradient_horizontal(RrSurface *sf, int w, int h)
116 {
117 RrPixel32 *data = sf->RrPixel_data;
118 RrPixel32 current;
119 float dr, dg, db;
120 unsigned int r,g,b;
121 int x, y;
122
123 dr = (float)(sf->secondary->r - sf->primary->r);
124 dr/= (float)w;
125
126 dg = (float)(sf->secondary->g - sf->primary->g);
127 dg/= (float)w;
128
129 db = (float)(sf->secondary->b - sf->primary->b);
130 db/= (float)w;
131
132 for (x = 0; x < w; ++x, ++data) {
133 r = sf->primary->r + (int)(dr * x);
134 g = sf->primary->g + (int)(dg * x);
135 b = sf->primary->b + (int)(db * x);
136 current = (r << default_red_offset)
137 + (g << default_green_offset)
138 + (b << default_blue_offset);
139 for (y = 0; y < h; ++y)
140 *(data + y*w) = current;
141 }
142 }
143
144 void gradient_diagonal(RrSurface *sf, int w, int h)
145 {
146 RrPixel32 *data = sf->RrPixel_data;
147 RrPixel32 current;
148 float drx, dgx, dbx, dry, dgy, dby;
149 unsigned int r,g,b;
150 int x, y;
151
152 for (y = 0; y < h; ++y) {
153 drx = (float)(sf->secondary->r -
154 sf->primary->r);
155 dry = drx/(float)h;
156 drx/= (float)w;
157
158 dgx = (float)(sf->secondary->g -
159 sf->primary->g);
160 dgy = dgx/(float)h;
161 dgx/= (float)w;
162
163 dbx = (float)(sf->secondary->b -
164 sf->primary->b);
165 dby = dbx/(float)h;
166 dbx/= (float)w;
167 for (x = 0; x < w; ++x, ++data) {
168 r = sf->primary->r +
169 ((int)(drx * x) + (int)(dry * y))/2;
170 g = sf->primary->g +
171 ((int)(dgx * x) + (int)(dgy * y))/2;
172 b = sf->primary->b +
173 ((int)(dbx * x) + (int)(dby * y))/2;
174 current = (r << default_red_offset)
175 + (g << default_green_offset)
176 + (b << default_blue_offset);
177 *data = current;
178 }
179 }
180 }
181
182 void gradient_crossdiagonal(RrSurface *sf, int w, int h)
183 {
184 RrPixel32 *data = sf->RrPixel_data;
185 RrPixel32 current;
186 float drx, dgx, dbx, dry, dgy, dby;
187 unsigned int r,g,b;
188 int x, y;
189
190 for (y = 0; y < h; ++y) {
191 drx = (float)(sf->secondary->r -
192 sf->primary->r);
193 dry = drx/(float)h;
194 drx/= (float)w;
195
196 dgx = (float)(sf->secondary->g -
197 sf->primary->g);
198 dgy = dgx/(float)h;
199 dgx/= (float)w;
200
201 dbx = (float)(sf->secondary->b -
202 sf->primary->b);
203 dby = dbx/(float)h;
204 dbx/= (float)w;
205 for (x = w; x > 0; --x, ++data) {
206 r = sf->primary->r +
207 ((int)(drx * (x-1)) + (int)(dry * y))/2;
208 g = sf->primary->g +
209 ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
210 b = sf->primary->b +
211 ((int)(dbx * (x-1)) + (int)(dby * y))/2;
212 current = (r << default_red_offset)
213 + (g << default_green_offset)
214 + (b << default_blue_offset);
215 *data = current;
216 }
217 }
218 }
219
220 void highlight(RrPixel32 *x, RrPixel32 *y, gboolean raised)
221 {
222 int r, g, b;
223
224 RrPixel32 *up, *down;
225 if (raised) {
226 up = x;
227 down = y;
228 } else {
229 up = y;
230 down = x;
231 }
232 r = (*up >> default_red_offset) & 0xFF;
233 r += r >> 1;
234 g = (*up >> default_green_offset) & 0xFF;
235 g += g >> 1;
236 b = (*up >> default_blue_offset) & 0xFF;
237 b += b >> 1;
238 if (r > 0xFF) r = 0xFF;
239 if (g > 0xFF) g = 0xFF;
240 if (b > 0xFF) b = 0xFF;
241 *up = (r << default_red_offset) + (g << default_green_offset)
242 + (b << default_blue_offset);
243
244 r = (*down >> default_red_offset) & 0xFF;
245 r = (r >> 1) + (r >> 2);
246 g = (*down >> default_green_offset) & 0xFF;
247 g = (g >> 1) + (g >> 2);
248 b = (*down >> default_blue_offset) & 0xFF;
249 b = (b >> 1) + (b >> 2);
250 *down = (r << default_red_offset) + (g << default_green_offset)
251 + (b << default_blue_offset);
252 }
253
254 static void create_bevel_colors(RrAppearance *l)
255 {
256 int r, g, b;
257
258 /* light color */
259 r = l->surface.primary->r;
260 r += r >> 1;
261 g = l->surface.primary->g;
262 g += g >> 1;
263 b = l->surface.primary->b;
264 b += b >> 1;
265 if (r > 0xFF) r = 0xFF;
266 if (g > 0xFF) g = 0xFF;
267 if (b > 0xFF) b = 0xFF;
268 g_assert(!l->surface.bevel_light);
269 l->surface.bevel_light = RrColorNew(l->inst, r, g, b);
270 color_allocate_gc(l->surface.bevel_light);
271
272 /* dark color */
273 r = l->surface.primary->r;
274 r = (r >> 1) + (r >> 2);
275 g = l->surface.primary->g;
276 g = (g >> 1) + (g >> 2);
277 b = l->surface.primary->b;
278 b = (b >> 1) + (b >> 2);
279 g_assert(!l->surface.bevel_dark);
280 l->surface.bevel_dark = RrColorNew(l->inst, r, g, b);
281 color_allocate_gc(l->surface.bevel_dark);
282 }
283
284 void gradient_solid(RrAppearance *l, int x, int y, int w, int h)
285 {
286 RrPixel32 pix;
287 int i, a, b;
288 RrSurface *sp = &l->surface;
289 int left = x, top = y, right = x + w - 1, bottom = y + h - 1;
290
291 if (sp->primary->gc == None)
292 color_allocate_gc(sp->primary);
293 pix = (sp->primary->r << default_red_offset)
294 + (sp->primary->g << default_green_offset)
295 + (sp->primary->b << default_blue_offset);
296
297 for (a = 0; a < w; a++)
298 for (b = 0; b < h; b++)
299 sp->RrPixel_data[a + b * w] = pix;
300
301 XFillRectangle(RrDisplay(l->inst), l->pixmap, sp->primary->gc,
302 x, y, w, h);
303
304 if (sp->interlaced) {
305 if (sp->secondary->gc == None)
306 color_allocate_gc(sp->secondary);
307 for (i = y; i < h; i += 2)
308 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->secondary->gc,
309 x, i, w, i);
310 }
311
312 switch (sp->relief) {
313 case RR_RELIEF_RAISED:
314 if (!sp->bevel_dark)
315 create_bevel_colors(l);
316
317 switch (sp->bevel) {
318 case RR_BEVEL_1:
319 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
320 left, bottom, right, bottom);
321 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
322 right, bottom, right, top);
323
324 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
325 left, top, right, top);
326 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
327 left, bottom, left, top);
328 break;
329 case RR_BEVEL_2:
330 XDrawLine(RrDisplay(l->inst), l->pixmap,
331 sp->bevel_dark->gc,
332 left + 1, bottom - 2, right - 2, bottom - 2);
333 XDrawLine(RrDisplay(l->inst), l->pixmap,
334 sp->bevel_dark->gc,
335 right - 2, bottom - 2, right - 2, top + 1);
336
337 XDrawLine(RrDisplay(l->inst), l->pixmap,
338 sp->bevel_light->gc,
339 left + 1, top + 1, right - 2, top + 1);
340 XDrawLine(RrDisplay(l->inst), l->pixmap,
341 sp->bevel_light->gc,
342 left + 1, bottom - 2, left + 1, top + 1);
343 break;
344 default:
345 g_assert_not_reached(); /* unhandled BevelType */
346 }
347 break;
348 case RR_RELIEF_SUNKEN:
349 if (!sp->bevel_dark)
350 create_bevel_colors(l);
351
352 switch (sp->bevel) {
353 case RR_BEVEL_1:
354 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
355 left, bottom, right, bottom);
356 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
357 right, bottom, right, top);
358
359 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
360 left, top, right, top);
361 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
362 left, bottom, left, top);
363 break;
364 case RR_BEVEL_2:
365 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
366 left + 1, bottom - 2, right - 2, bottom - 2);
367 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_light->gc,
368 right - 2, bottom - 2, right - 2, top + 1);
369
370 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
371 left + 1, top + 1, right - 2, top + 1);
372 XDrawLine(RrDisplay(l->inst), l->pixmap, sp->bevel_dark->gc,
373 left + 1, bottom - 2, left + 1, top + 1);
374
375 break;
376 default:
377 g_assert_not_reached(); /* unhandled BevelType */
378 }
379 break;
380 case RR_RELIEF_FLAT:
381 if (sp->border) {
382 if (sp->border_color->gc == None)
383 color_allocate_gc(sp->border_color);
384 XDrawRectangle(RrDisplay(l->inst), l->pixmap, sp->border_color->gc,
385 left, top, right, bottom);
386 }
387 break;
388 default:
389 g_assert_not_reached(); /* unhandled ReliefType */
390 }
391 }
392
393 void gradient_pyramid(RrSurface *sf, int inw, int inh)
394 {
395 RrPixel32 *data = sf->RrPixel_data;
396 RrPixel32 *end = data + inw*inh - 1;
397 RrPixel32 current;
398 float drx, dgx, dbx, dry, dgy, dby;
399 unsigned int r,g,b;
400 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
401
402 drx = (float)(sf->secondary->r -
403 sf->primary->r);
404 dry = drx/(float)h;
405 drx/= (float)w;
406
407 dgx = (float)(sf->secondary->g -
408 sf->primary->g);
409 dgy = dgx/(float)h;
410 dgx/= (float)w;
411
412 dbx = (float)(sf->secondary->b -
413 sf->primary->b);
414 dby = dbx/(float)h;
415 dbx/= (float)w;
416
417 for (y = 0; y < h; ++y) {
418 for (x = 0; x < w; ++x, data) {
419 r = sf->primary->r +
420 ((int)(drx * x) + (int)(dry * y))/2;
421 g = sf->primary->g +
422 ((int)(dgx * x) + (int)(dgy * y))/2;
423 b = sf->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);
428 *(data+x) = current;
429 *(data+inw-x) = current;
430 *(end-x) = current;
431 *(end-(inw-x)) = current;
432 }
433 data+=inw;
434 end-=inw;
435 }
436 }
437
438 void gradient_rectangle(RrSurface *sf, int inw, int inh)
439 {
440 RrPixel32 *data = sf->RrPixel_data;
441 RrPixel32 *end = data + inw*inh - 1;
442 RrPixel32 current;
443 float drx, dgx, dbx, dry, dgy, dby;
444 unsigned int r,g,b;
445 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
446
447 drx = (float)(sf->primary->r -
448 sf->secondary->r);
449 dry = drx/(float)h;
450 drx/= (float)w;
451
452 dgx = (float)(sf->primary->g -
453 sf->secondary->g);
454 dgy = dgx/(float)h;
455 dgx/= (float)w;
456
457 dbx = (float)(sf->primary->b -
458 sf->secondary->b);
459 dby = dbx/(float)h;
460 dbx/= (float)w;
461
462 for (y = 0; y < h; ++y) {
463 for (x = 0; x < w; ++x, data) {
464 if ((float)x/(float)w < (float)y/(float)h) {
465 r = sf->primary->r + (drx * x);
466 g = sf->primary->g + (dgx * x);
467 b = sf->primary->b + (dbx * x);
468 } else {
469 r = sf->primary->r + (dry * x);
470 g = sf->primary->g + (dgy * x);
471 b = sf->primary->b + (dby * x);
472 }
473 current = (r << default_red_offset)
474 + (g << default_green_offset)
475 + (b << default_blue_offset);
476 *(data+x) = current;
477 *(data+inw-x) = current;
478 *(end-x) = current;
479 *(end-(inw-x)) = current;
480 }
481 data+=inw;
482 end-=inw;
483 }
484 }
485
486 void gradient_pipecross(RrSurface *sf, int inw, int inh)
487 {
488 RrPixel32 *data = sf->RrPixel_data;
489 RrPixel32 *end = data + inw*inh - 1;
490 RrPixel32 current;
491 float drx, dgx, dbx, dry, dgy, dby;
492 unsigned int r,g,b;
493 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
494
495 drx = (float)(sf->secondary->r -
496 sf->primary->r);
497 dry = drx/(float)h;
498 drx/= (float)w;
499
500 dgx = (float)(sf->secondary->g -
501 sf->primary->g);
502 dgy = dgx/(float)h;
503 dgx/= (float)w;
504
505 dbx = (float)(sf->secondary->b -
506 sf->primary->b);
507 dby = dbx/(float)h;
508 dbx/= (float)w;
509
510 for (y = 0; y < h; ++y) {
511 for (x = 0; x < w; ++x, data) {
512 if ((float)x/(float)w > (float)y/(float)h) {
513 r = sf->primary->r + (drx * x);
514 g = sf->primary->g + (dgx * x);
515 b = sf->primary->b + (dbx * x);
516 } else {
517 r = sf->primary->r + (dry * x);
518 g = sf->primary->g + (dgy * x);
519 b = sf->primary->b + (dby * x);
520 }
521 current = (r << default_red_offset)
522 + (g << default_green_offset)
523 + (b << default_blue_offset);
524 *(data+x) = current;
525 *(data+inw-x) = current;
526 *(end-x) = current;
527 *(end-(inw-x)) = current;
528 }
529 data+=inw;
530 end-=inw;
531 }
532 }
This page took 0.059002 seconds and 5 git commands to generate.