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