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