4 #include "../kernel/openbox.h"
7 void gradient_render(Surface *sf, int w, int h)
9 pixel32 *data = sf->data.planar.pixel_data;
14 switch (sf->data.planar.grad) {
15 case Background_Solid: /* already handled */
17 case Background_Vertical:
18 gradient_vertical(sf, w, h);
20 case Background_Horizontal:
21 gradient_horizontal(sf, w, h);
23 case Background_Diagonal:
24 gradient_diagonal(sf, w, h);
26 case Background_CrossDiagonal:
27 gradient_crossdiagonal(sf, w, h);
29 case Background_Pyramid:
30 gradient_pyramid(sf, w, h);
32 case Background_PipeCross:
33 gradient_pipecross(sf, w, h);
35 case Background_Rectangle:
36 gradient_rectangle(sf, w, h);
39 g_message("unhandled gradient");
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;
54 for (off = 0, x = 0; x < h; ++x, off++) {
55 *(data + (off * w)) = current;
56 *(data + (off * w) + w - 1) = current;
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++)
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);
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);
87 void gradient_vertical(Surface *sf, int w, int h)
89 pixel32 *data = sf->data.planar.pixel_data;
95 dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
98 dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
101 db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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)
116 void gradient_horizontal(Surface *sf, int w, int h)
118 pixel32 *data = sf->data.planar.pixel_data;
124 dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
127 dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
130 db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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;
145 void gradient_diagonal(Surface *sf, int w, int h)
147 pixel32 *data = sf->data.planar.pixel_data;
149 float drx, dgx, dbx, dry, dgy, dby;
153 for (y = 0; y < h; ++y) {
154 drx = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
158 dgx = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
162 dbx = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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);
177 void gradient_crossdiagonal(Surface *sf, int w, int h)
179 pixel32 *data = sf->data.planar.pixel_data;
181 float drx, dgx, dbx, dry, dgy, dby;
185 for (y = 0; y < h; ++y) {
186 drx = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
190 dgx = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
194 dbx = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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);
209 void highlight(pixel32 *x, pixel32 *y, gboolean raised)
221 r = (*up >> default_red_offset) & 0xFF;
223 g = (*up >> default_green_offset) & 0xFF;
225 b = (*up >> default_blue_offset) & 0xFF;
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);
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);
243 void gradient_solid(Appearance *l, int x, int y, int w, int h)
247 PlanarSurface *sp = &l->surface.data.planar;
248 int left = x, top = y, right = w - 1, bottom = h - 1;
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);
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;
260 XFillRectangle(ob_display, l->pixmap, sp->primary->gc
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,
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);
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);
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);
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);
297 assert(false); // unhandled RenderTexture::BevelType
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);
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);
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);
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);
326 assert(false); // unhandled RenderTexture::BevelType
329 case RenderTexture::Flat:
330 if (texture.border())
331 XDrawRectangle(**display, sf.pixmap(), texture.borderColor().gc(),
332 left, top, right, bottom);
335 assert(false); // unhandled RenderTexture::ReliefType
340 void gradient_pyramid(Surface *sf, int inw, int inh)
342 pixel32 *data = sf->data.planar.pixel_data;
343 pixel32 *end = data + inw*inh;
345 float drx, dgx, dbx, dry, dgy, dby;
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);
353 dgx = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
357 dbx = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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);
368 *(data+inw-x) = current;
370 *(end-(inw-x)) = current;
377 void gradient_rectangle(Surface *sf, int inw, int inh)
379 pixel32 *data = sf->data.planar.pixel_data;
380 pixel32 *end = data + inw*inh;
382 float drx, dgx, dbx, dry, dgy, dby;
384 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
387 for (y = 0; y < h; ++y) {
388 drx = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
392 dgx = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
396 dbx = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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);
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);
410 *(data+inw-x) = current;
412 *(end-(inw-x)) = current;
419 void gradient_pipecross(Surface *sf, int inw, int inh)
421 pixel32 *data = sf->data.planar.pixel_data;
422 pixel32 *end = data + inw*inh;
424 float drx, dgx, dbx, dry, dgy, dby;
426 int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
429 for (y = 0; y < h; ++y) {
430 drx = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
434 dgx = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
438 dbx = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
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);
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);
452 *(data+inw-x) = current;
454 *(end-(inw-x)) = current;