]> icculus.org git repositories - dana/openbox.git/blob - render2/planar.c
improve expose handling for alpha children
[dana/openbox.git] / render2 / planar.c
1 #include "planar.h"
2 #include "surface.h"
3 #include "texture.h"
4 #include "color.h"
5 #include "debug.h"
6 #include "font.h"
7 #include <string.h>
8 #include <assert.h>
9 #include <GL/glx.h>
10
11 void RrPlanarSet(struct RrSurface *sur,
12                  enum RrSurfaceColorType type,
13                  enum RrBevelType bevel,
14                  struct RrColor *primary,
15                  struct RrColor *secondary,
16                  int borderwidth,
17                  struct RrColor *border)
18 {
19     sur->data.planar.colortype = type;
20     sur->data.planar.bevel = bevel;
21     sur->data.planar.primary = *primary;
22     if (!(type == RR_PLANAR_NONE || type == RR_PLANAR_SOLID))
23         sur->data.planar.secondary = *secondary;
24     assert(borderwidth >= 0);
25     sur->data.planar.borderwidth = borderwidth >= 0 ? borderwidth : 0;
26     if (borderwidth)
27         sur->data.planar.border = *border;
28 }
29
30 int RrPlanarHasAlpha(struct RrSurface *sur)
31 {
32     if (RrColorHasAlpha(RrPlanarPrimaryColor(sur))) return 1;
33     if (!(RrPlanarColorType(sur) == RR_PLANAR_NONE ||
34           RrPlanarColorType(sur) == RR_PLANAR_SOLID))
35         if (RrColorHasAlpha(RrPlanarSecondaryColor(sur))) return 1;
36     return 0;
37 }
38
39 static void copy_parent(struct RrSurface *sur)
40 {
41     int ncols;
42     int copy;
43
44     switch (RrPlanarColorType(sur)) {
45     case RR_PLANAR_NONE:
46         return;
47     case RR_PLANAR_SOLID:
48         ncols = 1;
49         break;
50     case RR_PLANAR_HORIZONTAL:
51         ncols = 2;
52         break;
53     case RR_PLANAR_VERTICAL:
54         ncols = 2;
55         break;
56     case RR_PLANAR_DIAGONAL:
57         ncols = 2;
58         break;
59     case RR_PLANAR_CROSSDIAGONAL:
60         ncols = 2;
61         break;
62     case RR_PLANAR_PYRAMID:
63         ncols = 2;
64         break;
65     case RR_PLANAR_PIPECROSS:
66         ncols = 2;
67         break;
68     case RR_PLANAR_RECTANGLE:
69         ncols = 2;
70         break;
71     }
72
73     copy = 0;
74     if (ncols >= 1 && RrColorHasAlpha(RrPlanarPrimaryColor(sur)))
75         copy = 1;
76     if (ncols >= 1 && RrColorHasAlpha(RrPlanarSecondaryColor(sur)))
77         copy = 1;
78     if (copy) {
79         /*
80         struct RrSurface *parent = RrSurfaceParent(sur);
81
82         XXX COPY PARENT PLS
83         */
84         RrDebug("copy parent here pls\n");
85     }
86 }
87
88 static void RrBevelPaint(int x, int y, int w, int h, int bwidth,
89                          int inset, int raise)
90 {
91     int offset = bwidth + inset;
92     h--; w--;
93
94     if (raise)
95         glColor4f(1.0, 1.0, 1.0, 0.25);
96     else
97         glColor4f(0.0, 0.0, 0.0, 0.25);
98
99     glBegin(GL_LINES);
100     glVertex2i(x + offset, y + offset);
101     glVertex2i(x + offset, y + h - offset);
102
103     glVertex2i(x + offset, y + h - offset);
104     glVertex2i(x + w - offset, y + h - offset);
105
106     if (!raise)
107         glColor4f(1.0, 1.0, 1.0, 0.25);
108     else
109         glColor4f(0.0, 0.0, 0.0, 0.25);
110
111     glVertex2i(x + w - offset, y + h - offset);
112     glVertex2i(x + w - offset,  y + offset);
113                
114     glVertex2i(x + w - offset, y + offset);
115     glVertex2i(x + offset, y + offset);
116     glEnd();
117 }
118
119 static void RrBorderPaint(int x, int y, int w, int h, int bwidth,
120                           struct RrColor *color)
121 {
122     int offset = bwidth / 2;
123     h--; w--;
124
125     RrColor4f(color);
126
127     glBegin(GL_LINE_LOOP);
128     glLineWidth(bwidth);
129     glVertex2i(x + offset, y + offset);
130     glVertex2i(x + offset, y + h - offset);
131     glVertex2i(x + w - offset, y + h - offset);
132     glVertex2i(x + w - offset, y + offset);
133     glLineWidth(1.0); /* XXX is this needed? */
134     glEnd();
135 }
136
137 void RrPlanarPaint(struct RrSurface *sur, int absx, int absy)
138 {   
139     struct RrColor *pri, *sec, avg;
140     int x, y, w, h;
141
142     copy_parent(sur);
143
144     pri = &RrPlanarPrimaryColor(sur);
145     sec = &RrPlanarSecondaryColor(sur);
146
147     x = RrSurfaceX(sur);
148     y = RrSurfaceY(sur);
149     w = RrSurfaceWidth(sur);
150     h = RrSurfaceHeight(sur);
151
152     switch (RrPlanarColorType(sur)) {
153     case RR_PLANAR_NONE:
154         return;
155     case RR_PLANAR_SOLID:
156         glBegin(GL_TRIANGLES);
157         RrColor3f(pri);
158         glVertex2i(x, y);
159         glVertex2i(x+w, y);
160         glVertex2i(x+w, y+h);
161
162         glVertex2i(x+w, y+h);
163         glVertex2i(x, y+h);
164         glVertex2i(x, y);
165         glEnd();
166         break;
167     case RR_PLANAR_HORIZONTAL:
168         glBegin(GL_TRIANGLES);
169         RrColor3f(pri);
170         glVertex2i(x, y);
171         RrColor3f(sec);
172         glVertex2i(x+w, y);
173         glVertex2i(x+w, y+h);
174
175         glVertex2i(x+w, y+h);
176         RrColor3f(pri);
177         glVertex2i(x, y+h);
178         glVertex2i(x, y);
179         glEnd();
180         break;
181     case RR_PLANAR_VERTICAL:
182         glBegin(GL_TRIANGLES);
183         RrColor3f(pri);
184         glVertex2i(x, y);
185         glVertex2i(x+w, y);
186         RrColor3f(sec);
187         glVertex2i(x+w, y+h);
188
189         glVertex2i(x+w, y+h);
190         glVertex2i(x, y+h);
191         RrColor3f(pri);
192         glVertex2i(x, y);
193         glEnd();
194         break;
195     case RR_PLANAR_DIAGONAL:
196         RrColorAvg(&avg, pri, sec);
197         glBegin(GL_TRIANGLES);
198         RrColor3f(&avg);
199         glVertex2i(x, y);
200         RrColor3f(pri);
201         glVertex2i(x+w, y);
202         RrColor3f(&avg);
203         glVertex2i(x+w, y+h);
204
205         RrColor3f(&avg);
206         glVertex2i(x+w, y+h);
207         RrColor3f(sec);
208         glVertex2i(x, y+h);
209         RrColor3f(&avg);
210         glVertex2i(x, y);
211         glEnd();
212         break;
213     case RR_PLANAR_CROSSDIAGONAL:
214         RrColorAvg(&avg, pri, sec);
215         glBegin(GL_TRIANGLES);
216         RrColor3f(pri);
217         glVertex2i(x, y);
218         RrColor3f(&avg);
219         glVertex2i(x+w, y);
220         RrColor3f(sec);
221         glVertex2i(x+w, y+h);
222
223         RrColor3f(sec);
224         glVertex2i(x+w, y+h);
225         RrColor3f(&avg);
226         glVertex2i(x, y+h);
227         RrColor3f(pri);
228         glVertex2i(x, y);
229         glEnd();
230         break;
231     case RR_PLANAR_PYRAMID:
232         RrColorAvg(&avg, pri, sec);
233         glBegin(GL_TRIANGLES);
234         RrColor3f(pri);
235         glVertex2i(x, y);
236         RrColor3f(sec);
237         glVertex2i(x+w/2, y+h/2);
238         RrColor3f(&avg);
239         glVertex2i(x, y+h/2);
240
241         glVertex2i(x, y+h/2);
242         RrColor3f(sec);
243         glVertex2i(x+w/2, y+h/2);
244         RrColor3f(pri);
245         glVertex2i(x, y+h);
246
247         glVertex2i(x, y+h);
248         RrColor3f(sec);
249         glVertex2i(x+w/2, y+h/2);
250         RrColor3f(&avg);
251         glVertex2i(x+w/2, y+h);
252
253         glVertex2i(x+w/2, y+h);
254         RrColor3f(sec);
255         glVertex2i(x+w/2, y+h/2);
256         RrColor3f(pri);
257         glVertex2i(x+w, y+h);
258
259         glVertex2i(x+w, y+h);
260         RrColor3f(sec);
261         glVertex2i(x+w/2, y+h/2);
262         RrColor3f(&avg);
263         glVertex2i(x+w, y+h/2);
264
265         glVertex2i(x+w, y+h/2);
266         RrColor3f(sec);
267         glVertex2i(x+w/2, y+h/2);
268         RrColor3f(pri);
269         glVertex2i(x+w, y);
270
271         glVertex2i(x+w, y);
272         RrColor3f(sec);
273         glVertex2i(x+w/2, y+h/2);
274         RrColor3f(&avg);
275         glVertex2i(x+w/2, y);
276
277         glVertex2i(x+w/2, y);
278         RrColor3f(sec);
279         glVertex2i(x+w/2, y+h/2);
280         RrColor3f(pri);
281         glVertex2i(x, y);
282         glEnd();
283         break;
284     case RR_PLANAR_PIPECROSS:
285         glBegin(GL_TRIANGLES);
286         RrColor3f(pri);
287         glVertex2i(x, y);
288         RrColor3f(sec);
289         glVertex2i(x+w/2, y+h/2);
290         glVertex2i(x, y+h/2);
291
292         glVertex2i(x, y+h/2);
293         glVertex2i(x+w/2, y+h/2);
294         RrColor3f(pri);
295         glVertex2i(x, y+h);
296
297         glVertex2i(x, y+h);
298         RrColor3f(sec);
299         glVertex2i(x+w/2, y+h/2);
300         glVertex2i(x+w/2, y+h);
301
302         glVertex2i(x+w/2, y+h);
303         glVertex2i(x+w/2, y+h/2);
304         RrColor3f(pri);
305         glVertex2i(x+w, y+h);
306
307         glVertex2i(x+w, y+h);
308         RrColor3f(sec);
309         glVertex2i(x+w/2, y+h/2);
310         glVertex2i(x+w, y+h/2);
311
312         glVertex2i(x+w, y+h/2);
313         glVertex2i(x+w/2, y+h/2);
314         RrColor3f(pri);
315         glVertex2i(x+w, y);
316
317         glVertex2i(x+w, y);
318         RrColor3f(sec);
319         glVertex2i(x+w/2, y+h/2);
320         glVertex2i(x+w/2, y);
321
322         glVertex2i(x+w/2, y);
323         glVertex2i(x+w/2, y+h/2);
324         RrColor3f(pri);
325         glVertex2i(x, y);
326         glEnd();
327         break;
328     case RR_PLANAR_RECTANGLE:
329         glBegin(GL_TRIANGLES);
330         RrColor3f(pri);
331         glVertex2i(x, y);
332         RrColor3f(sec);
333         glVertex2i(x+w/2, y+h/2);
334         RrColor3f(pri);
335         glVertex2i(x, y+h);
336
337         glVertex2i(x, y+h);
338         RrColor3f(sec);
339         glVertex2i(x+w/2, y+h/2);
340         RrColor3f(pri);
341         glVertex2i(x+w, y+h);
342
343         glVertex2i(x+w, y+h);
344         RrColor3f(sec);
345         glVertex2i(x+w/2, y+h/2);
346         RrColor3f(pri);
347         glVertex2i(x+w, y);
348
349         glVertex2i(x+w, y);
350         RrColor3f(sec);
351         glVertex2i(x+w/2, y+h/2);
352         RrColor3f(pri);
353         glVertex2i(x, y);
354
355         glEnd();
356         break;
357     }
358
359     switch (RrPlanarBevelType(sur)) {
360     case RR_SUNKEN_OUTER:
361         RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
362                      RrSurfaceWidth(sur), RrSurfaceHeight(sur),
363                      RrPlanarBorderWidth(sur), 0, 0);
364         break;
365     case RR_SUNKEN_INNER:
366         RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
367                      RrSurfaceWidth(sur), RrSurfaceHeight(sur),
368                      RrPlanarBorderWidth(sur), 1, 0);
369         break;
370     case RR_RAISED_OUTER:
371         RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
372                      RrSurfaceWidth(sur), RrSurfaceHeight(sur),
373                      RrPlanarBorderWidth(sur), 0, 1);
374         break;
375     case RR_RAISED_INNER:
376         RrBevelPaint(RrSurfaceX(sur), RrSurfaceY(sur),
377                      RrSurfaceWidth(sur), RrSurfaceHeight(sur),
378                      RrPlanarBorderWidth(sur), 1, 1);
379         break;
380     case RR_BEVEL_NONE:
381         break;
382     }
383
384     if (RrPlanarBorderWidth(sur))
385         RrBorderPaint(RrSurfaceX(sur), RrSurfaceY(sur),
386                       RrSurfaceWidth(sur), RrSurfaceHeight(sur),
387                       RrPlanarBorderWidth(sur), &RrPlanarBorderColor(sur));
388 }
389
390 void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h)
391 {
392     *w = *h = RrPlanarBorderWidth(sur);
393     switch (RrPlanarBevelType(sur)) {
394     case RR_SUNKEN_OUTER:
395         (*w)++;
396         (*h)++;
397         break;
398     case RR_SUNKEN_INNER:
399         (*w)+=2;
400         (*h)+=2;
401         break;
402     case RR_RAISED_OUTER:
403         (*w)++;
404         (*h)++;
405         break;
406     case RR_RAISED_INNER:
407         (*w)+=2;
408         (*h)+=2;
409         break;
410     case RR_BEVEL_NONE:
411         break;
412     }
413 }