1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <math.h>
21 #include <GL/gl.h>
22
23 #include "cairo-dock-struct.h"
24 #include "cairo-dock-icon-facility.h" // cairo_dock_generate_string_path_opengl
25 #include "cairo-dock-dock-factory.h"
26 #include "cairo-dock-separator-manager.h"
27 #include "cairo-dock-opengl-path.h"
28
29 #define _CD_PATH_DIM 2
30 #define _cd_gl_path_set_nth_vertex_x(pPath, _x, i) pPath->pVertices[_CD_PATH_DIM*(i)] = _x
31 #define _cd_gl_path_set_nth_vertex_y(pPath, _y, i) pPath->pVertices[_CD_PATH_DIM*(i)+1] = _y
32 #define _cd_gl_path_set_vertex_x(pPath, _x) _cd_gl_path_set_nth_vertex_x (pPath, _x, pPath->iCurrentPt)
33 #define _cd_gl_path_set_vertex_y(pPath, _y) _cd_gl_path_set_nth_vertex_y (pPath, _y, pPath->iCurrentPt)
34 #define _cd_gl_path_set_current_vertex(pPath, _x, _y) do {\
35 _cd_gl_path_set_vertex_x(pPath, _x);\
36 _cd_gl_path_set_vertex_y(pPath, _y); } while (0)
37 #define _cd_gl_path_get_nth_vertex_x(pPath, i) pPath->pVertices[_CD_PATH_DIM*(i)]
38 #define _cd_gl_path_get_nth_vertex_y(pPath, i) pPath->pVertices[_CD_PATH_DIM*(i)+1]
39 #define _cd_gl_path_get_current_vertex_x(pPath) _cd_gl_path_get_nth_vertex_x (pPath, pPath->iCurrentPt-1)
40 #define _cd_gl_path_get_current_vertex_y(pPath) _cd_gl_path_get_nth_vertex_y (pPath, pPath->iCurrentPt-1)
41
cairo_dock_new_gl_path(int iNbVertices,double x0,double y0,int iWidth,int iHeight)42 CairoDockGLPath *cairo_dock_new_gl_path (int iNbVertices, double x0, double y0, int iWidth, int iHeight)
43 {
44 CairoDockGLPath *pPath = g_new0 (CairoDockGLPath, 1);
45 pPath->pVertices = g_new0 (GLfloat, (iNbVertices+1) * _CD_PATH_DIM); // +1 = securite
46 pPath->iNbPoints = iNbVertices;
47 _cd_gl_path_set_current_vertex (pPath, x0, y0);
48 pPath->iCurrentPt ++;
49 pPath->iWidth = iWidth;
50 pPath->iHeight = iHeight;
51 return pPath;
52 }
53
cairo_dock_free_gl_path(CairoDockGLPath * pPath)54 void cairo_dock_free_gl_path (CairoDockGLPath *pPath)
55 {
56 if (!pPath)
57 return;
58 g_free (pPath->pVertices);
59 g_free (pPath);
60 }
61
cairo_dock_gl_path_move_to(CairoDockGLPath * pPath,double x0,double y0)62 void cairo_dock_gl_path_move_to (CairoDockGLPath *pPath, double x0, double y0)
63 {
64 pPath->iCurrentPt = 0;
65 _cd_gl_path_set_current_vertex (pPath, x0, y0);
66 pPath->iCurrentPt ++;
67 }
68
cairo_dock_gl_path_set_extent(CairoDockGLPath * pPath,int iWidth,int iHeight)69 void cairo_dock_gl_path_set_extent (CairoDockGLPath *pPath, int iWidth, int iHeight)
70 {
71 pPath->iWidth = iWidth;
72 pPath->iHeight = iHeight;
73 }
74
cairo_dock_gl_path_line_to(CairoDockGLPath * pPath,GLfloat x,GLfloat y)75 void cairo_dock_gl_path_line_to (CairoDockGLPath *pPath, GLfloat x, GLfloat y)
76 {
77 g_return_if_fail (pPath->iCurrentPt < pPath->iNbPoints);
78 _cd_gl_path_set_current_vertex (pPath, x, y);
79 pPath->iCurrentPt ++;
80 }
81
cairo_dock_gl_path_rel_line_to(CairoDockGLPath * pPath,GLfloat dx,GLfloat dy)82 void cairo_dock_gl_path_rel_line_to (CairoDockGLPath *pPath, GLfloat dx, GLfloat dy)
83 {
84 cairo_dock_gl_path_line_to (pPath,
85 _cd_gl_path_get_current_vertex_x (pPath) + dx,
86 _cd_gl_path_get_current_vertex_y (pPath) + dy);
87 }
88
89 // OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
90 // Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
91 #define B0(t) (1-t)*(1-t)*(1-t)
92 #define B1(t) 3*t*(1-t)*(1-t)
93 #define B2(t) 3*t*t*(1-t)
94 #define B3(t) t*t*t
95 #define Bezier(x0,x1,x2,x3,t) (B0(t)*x0 + B1(t)*x1 + B2(t)*x2 + B3(t)*x3)
cairo_dock_gl_path_curve_to(CairoDockGLPath * pPath,int iNbPoints,GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2,GLfloat x3,GLfloat y3)96 void cairo_dock_gl_path_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3)
97 {
98 g_return_if_fail (pPath->iCurrentPt + iNbPoints <= pPath->iNbPoints);
99 GLfloat x0, y0;
100 x0 = _cd_gl_path_get_current_vertex_x (pPath);
101 y0 = _cd_gl_path_get_current_vertex_y (pPath);
102 double t;
103 int i;
104 for (i = 0; i < iNbPoints; i ++)
105 {
106 t = (double)(i+1)/iNbPoints; // [0;1]
107 _cd_gl_path_set_nth_vertex_x (pPath, Bezier (x0, x1, x2, x3, t), pPath->iCurrentPt + i);
108 _cd_gl_path_set_nth_vertex_y (pPath, Bezier (y0, y1, y2, y3, t), pPath->iCurrentPt + i);
109 }
110 pPath->iCurrentPt += iNbPoints;
111 }
112
cairo_dock_gl_path_rel_curve_to(CairoDockGLPath * pPath,int iNbPoints,GLfloat dx1,GLfloat dy1,GLfloat dx2,GLfloat dy2,GLfloat dx3,GLfloat dy3)113 void cairo_dock_gl_path_rel_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat dx1, GLfloat dy1, GLfloat dx2, GLfloat dy2, GLfloat dx3, GLfloat dy3)
114 {
115 GLfloat x0, y0;
116 x0 = _cd_gl_path_get_current_vertex_x (pPath);
117 y0 = _cd_gl_path_get_current_vertex_y (pPath);
118 cairo_dock_gl_path_curve_to (pPath, iNbPoints, x0 + dx1, y0 + dy1, x0 + dx2, y0 + dy2, x0 + dx3, y0 + dy3);
119 }
120
121 #define Bezier2(p,q,s,t) ((1-t) * (1-t) * p + 2 * t * (1-t) * q + t * t * s)
cairo_dock_gl_path_simple_curve_to(CairoDockGLPath * pPath,int iNbPoints,GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)122 void cairo_dock_gl_path_simple_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
123 {
124 g_return_if_fail (pPath->iCurrentPt + iNbPoints <= pPath->iNbPoints);
125 GLfloat x0, y0;
126 x0 = _cd_gl_path_get_current_vertex_x (pPath);
127 y0 = _cd_gl_path_get_current_vertex_y (pPath);
128 double t;
129 int i;
130 for (i = 0; i < iNbPoints; i ++)
131 {
132 t = (double)(i+1)/iNbPoints; // [0;1]
133 _cd_gl_path_set_nth_vertex_x (pPath, Bezier2 (x0, x1, x2, t), pPath->iCurrentPt + i);
134 _cd_gl_path_set_nth_vertex_y (pPath, Bezier2 (y0, y1, y2, t), pPath->iCurrentPt + i);
135 }
136 pPath->iCurrentPt += iNbPoints;
137 }
138
cairo_dock_gl_path_rel_simple_curve_to(CairoDockGLPath * pPath,int iNbPoints,GLfloat dx1,GLfloat dy1,GLfloat dx2,GLfloat dy2)139 void cairo_dock_gl_path_rel_simple_curve_to (CairoDockGLPath *pPath, int iNbPoints, GLfloat dx1, GLfloat dy1, GLfloat dx2, GLfloat dy2)
140 {
141 GLfloat x0, y0;
142 x0 = _cd_gl_path_get_current_vertex_x (pPath);
143 y0 = _cd_gl_path_get_current_vertex_y (pPath);
144 cairo_dock_gl_path_simple_curve_to (pPath, iNbPoints, x0 + dx1, y0 + dy1, x0 + dx2, y0 + dy2);
145 }
146
cairo_dock_gl_path_arc(CairoDockGLPath * pPath,int iNbPoints,GLfloat xc,GLfloat yc,double r,double teta0,double cone)147 void cairo_dock_gl_path_arc (CairoDockGLPath *pPath, int iNbPoints, GLfloat xc, GLfloat yc, double r, double teta0, double cone)
148 {
149 g_return_if_fail (pPath->iCurrentPt + iNbPoints <= pPath->iNbPoints);
150 double t;
151 int i;
152 for (i = 0; i < iNbPoints; i ++)
153 {
154 t = teta0 + (double)i/(iNbPoints-1) * cone; // [teta0, teta0+cone]
155 _cd_gl_path_set_nth_vertex_x (pPath, xc + r * cos (t), pPath->iCurrentPt + i);
156 _cd_gl_path_set_nth_vertex_y (pPath, yc + r * sin (t), pPath->iCurrentPt + i);
157 }
158 pPath->iCurrentPt += iNbPoints;
159 }
160
_draw_current_path(int iNbPoints,gboolean bClosePath)161 static inline void _draw_current_path (int iNbPoints, gboolean bClosePath)
162 {
163 //\__________________ On active l'antialiasing.
164 glPolygonMode (GL_FRONT, GL_LINE);
165 glEnable (GL_LINE_SMOOTH);
166 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
167 glEnable (GL_BLEND); // On active le blend pour l'antialiasing.
168 //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
169 //glLineWidth(fLineWidth);
170 //glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]); // Et sa couleur.
171
172 //\__________________ On dessine le cadre.
173 glEnableClientState (GL_VERTEX_ARRAY);
174 glDrawArrays (bClosePath ? GL_LINE_LOOP : GL_LINE_STRIP, 0, iNbPoints);
175 glDisableClientState (GL_VERTEX_ARRAY);
176
177 //\__________________ On desactive l'antialiasing.
178 glDisable (GL_LINE_SMOOTH);
179 glDisable (GL_BLEND);
180 }
cairo_dock_stroke_gl_path(const CairoDockGLPath * pPath,gboolean bClosePath)181 void cairo_dock_stroke_gl_path (const CairoDockGLPath *pPath, gboolean bClosePath)
182 {
183 glVertexPointer (_CD_PATH_DIM, GL_FLOAT, 0, pPath->pVertices);
184 _draw_current_path (pPath->iCurrentPt, bClosePath);
185 }
186
cairo_dock_fill_gl_path(const CairoDockGLPath * pPath,GLuint iTexture)187 void cairo_dock_fill_gl_path (const CairoDockGLPath *pPath, GLuint iTexture)
188 {
189 //\__________________ On active l'antialiasing.
190 glPolygonMode (GL_FRONT, GL_FILL);
191 //glEnable (GL_POLYGON_SMOOTH); // makes horrible white lines where the triangles overlaps :-/
192 //glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
193 glEnable (GL_BLEND); // On active le blend pour l'antialiasing.
194
195 //\__________________ On mappe la texture dans le cadre.
196 if (iTexture != 0)
197 {
198 // on active le texturing.
199 glColor4f(1., 1., 1., 1.); // Couleur a fond
200 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
201 glEnable(GL_TEXTURE_2D); // Je veux de la texture
202 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
203 glBindTexture(GL_TEXTURE_2D, iTexture); // allez on bind la texture
204 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); // ok la on selectionne le type de generation des coordonnees de la texture
205 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
206 glEnable(GL_TEXTURE_GEN_S); // oui je veux une generation en S
207 glEnable(GL_TEXTURE_GEN_T); // Et en T aussi
208 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
209 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
210
211 // on met la texture a sa place.
212 glMatrixMode(GL_TEXTURE);
213 glPushMatrix ();
214 glTranslatef (.5, .5, 0.);
215 if (pPath->iWidth != 0 && pPath->iHeight != 0)
216 glScalef (1./pPath->iWidth, -1./pPath->iHeight, 1.);
217 glMatrixMode (GL_MODELVIEW);
218
219 }
220
221 //\__________________ On dessine le cadre.
222 glEnableClientState (GL_VERTEX_ARRAY);
223 glVertexPointer (_CD_PATH_DIM, GL_FLOAT, 0, pPath->pVertices);
224 glDrawArrays (GL_TRIANGLE_FAN, 0, pPath->iCurrentPt); // GL_POLYGON / GL_TRIANGLE_FAN
225 glDisableClientState (GL_VERTEX_ARRAY);
226
227 //\__________________ On desactive l'antialiasing et la texture.
228 if (iTexture != 0)
229 {
230 glDisable(GL_TEXTURE_GEN_S);
231 glDisable(GL_TEXTURE_GEN_T);
232 glDisable(GL_TEXTURE_2D); // Plus de texture merci
233
234 glMatrixMode(GL_TEXTURE);
235 glPopMatrix ();
236 glMatrixMode (GL_MODELVIEW);
237 }
238 //glDisable (GL_POLYGON_SMOOTH);
239 glDisable (GL_BLEND);
240 }
241
242
243 // HELPER FUNCTIONS //
244
245 #define DELTA_ROUND_DEGREE 3
cairo_dock_generate_rectangle_path(double fFrameWidth,double fTotalHeight,double fRadius,gboolean bRoundedBottomCorner)246 const CairoDockGLPath *cairo_dock_generate_rectangle_path (double fFrameWidth, double fTotalHeight, double fRadius, gboolean bRoundedBottomCorner)
247 {
248 static CairoDockGLPath *pPath = NULL;
249 double fTotalWidth = fFrameWidth + 2 * fRadius;
250 double fFrameHeight = MAX (0, fTotalHeight - 2 * fRadius);
251 double w = fFrameWidth / 2;
252 double h = fFrameHeight / 2;
253 double r = fRadius;
254
255 int iNbPoins1Round = 90/10;
256 if (pPath == NULL)
257 {
258 pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*4+1, w+r, h, fTotalWidth, fTotalHeight); // on commence au centre droit pour avoir une bonne triangulation du polygone, et en raisonnant par rapport au centre du rectangle.
259 ///pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*4+1, 0, 0, fTotalWidth, fTotalHeight); // on commence au centre pour avoir une bonne triangulation
260 }
261 else
262 {
263 cairo_dock_gl_path_move_to (pPath, w+r, h);
264 ///cairo_dock_gl_path_move_to (pPath, 0, 0);
265 cairo_dock_gl_path_set_extent (pPath, fTotalWidth, fTotalHeight);
266 }
267 //cairo_dock_gl_path_move_to (pPath, 0., h+r);
268 //cairo_dock_gl_path_rel_line_to (pPath, -w, 0.);
269
270 cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, 0., +G_PI/2); // coin haut droit.
271
272 cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, h, r, G_PI/2, +G_PI/2); // coin haut gauche.
273
274 if (bRoundedBottomCorner)
275 {
276 cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, -h, r, G_PI, +G_PI/2); // coin bas gauche.
277
278 cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, -h, r, -G_PI/2, +G_PI/2); // coin bas droit.
279 }
280 else
281 {
282 cairo_dock_gl_path_rel_line_to (pPath, 0., - (fFrameHeight + r));
283 cairo_dock_gl_path_rel_line_to (pPath, fTotalWidth, 0.);
284 }
285 //cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, 0., +G_PI/2); // coin haut droit.
286
287 return pPath;
288 }
289
290
cairo_dock_generate_trapeze_path(double fUpperFrameWidth,double fTotalHeight,double fRadius,gboolean bRoundedBottomCorner,double fInclination,double * fExtraWidth)291 const CairoDockGLPath *cairo_dock_generate_trapeze_path (double fUpperFrameWidth, double fTotalHeight, double fRadius, gboolean bRoundedBottomCorner, double fInclination, double *fExtraWidth)
292 {
293 static CairoDockGLPath *pPath = NULL;
294
295 double a = atan (fInclination); // /|
296 double cosa = 1. / sqrt (1 + fInclination * fInclination);
297 double sina = cosa * fInclination;
298
299 double fFrameHeight = MAX (0, fTotalHeight - 2 * fRadius);
300 *fExtraWidth = fInclination * (fTotalHeight - (bRoundedBottomCorner ? 2 : 1-sina) * fRadius) + fRadius * (bRoundedBottomCorner ? 1 : cosa);
301 double fTotalWidth = fUpperFrameWidth + 2*(*fExtraWidth);
302 double dw = *fExtraWidth;
303 double r = fRadius;
304 double w = fUpperFrameWidth / 2;
305 double h = fFrameHeight / 2;
306 double w_ = w + dw - (bRoundedBottomCorner ? r : 0);
307
308 int iNbPoins1Round = 70/DELTA_ROUND_DEGREE; // pour une inclinaison classique (~30deg), les coins du haut feront moins d'1/4 de tour.
309 int iNbPoins1Curve = 10;
310 if (pPath == NULL)
311 pPath = cairo_dock_new_gl_path ((iNbPoins1Round+1)*2 + (iNbPoins1Curve+1)*2 + 1, 0., fTotalHeight/2, fTotalWidth, fTotalHeight);
312 else
313 {
314 cairo_dock_gl_path_move_to (pPath, 0., fTotalHeight/2);
315 cairo_dock_gl_path_set_extent (pPath, fTotalWidth, fTotalHeight);
316 }
317 cairo_dock_gl_path_arc (pPath, iNbPoins1Round, -w, h, r, G_PI/2, G_PI/2 - a); // coin haut gauche. 90 -> 180-a
318
319 if (bRoundedBottomCorner)
320 {
321 double t = G_PI-a;
322 double x0 = -w_ + r * cos (t);
323 double y0 = -h + r * sin (t);
324 double x1 = x0 - fInclination * r * (1+sina);
325 double y1 = -h - r;
326 double x2 = -w_;
327 double y2 = y1;
328 cairo_dock_gl_path_line_to (pPath, x0, y0);
329 cairo_dock_gl_path_simple_curve_to (pPath, iNbPoins1Curve, x1, y1, x2, y2); // coin bas gauche.
330
331 double x3 = x0, y3 = y0; // temp.
332 x0 = - x2;
333 y0 = y2;
334 x1 = - x1;
335 x2 = - x3;
336 y2 = y3;
337 cairo_dock_gl_path_line_to (pPath, x0, y0);
338 cairo_dock_gl_path_simple_curve_to (pPath, iNbPoins1Curve, x1, y1, x2, y2); // coin bas droit.
339 }
340 else
341 {
342 cairo_dock_gl_path_line_to (pPath,
343 -w_,
344 -h - r); // bas gauche.
345 cairo_dock_gl_path_line_to (pPath,
346 w_,
347 -h - r); // bas droit.
348 }
349
350 cairo_dock_gl_path_arc (pPath, iNbPoins1Round, w, h, r, a, G_PI/2 - a); // coin haut droit. a -> 90
351
352 return pPath;
353 }
354
355
356 #define _get_icon_center_x(icon) (icon->fDrawX + icon->fWidth * icon->fScale/2)
357 #define _get_icon_center_y(icon) (icon->fDrawY + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - .5) : icon->fHeight * icon->fScale/2))
358 #define _get_icon_center(icon,x,y) do {\
359 if (pDock->container.bIsHorizontal) {\
360 x = _get_icon_center_x (icon);\
361 y = pDock->container.iHeight - _get_icon_center_y (icon); }\
362 else {\
363 y = _get_icon_center_x (icon);\
364 x = pDock->container.iWidth - _get_icon_center_y (icon); } } while (0)
365 #define _calculate_slope(x0,y0,x1,y1,dx,dy) do {\
366 dx = x1 - x0;\
367 dy = y1 - y0;\
368 norme = sqrt (dx*dx + dy*dy);\
369 dx /= norme;\
370 dy /= norme; } while (0)
371 #define NB_VERTEX_PER_ICON_PAIR 10
cairo_dock_generate_string_path_opengl(CairoDock * pDock,gboolean bIsLoop,gboolean bForceConstantSeparator)372 const CairoDockGLPath *cairo_dock_generate_string_path_opengl (CairoDock *pDock, gboolean bIsLoop, gboolean bForceConstantSeparator)
373 {
374 static CairoDockGLPath *pPath = NULL;
375 if (pPath == NULL)
376 pPath = cairo_dock_new_gl_path (100*NB_VERTEX_PER_ICON_PAIR + 1, 0., 0., 0., 0.);
377
378 GList *ic, *next_ic, *next2_ic, *pFirstDrawnElement = pDock->icons;
379 Icon *pIcon, *pNextIcon, *pNext2Icon;
380 double x0,y0, x1,y1, x2,y2; // centres des icones P0, P1, P2, en coordonnees opengl.
381 double norme; // pour normaliser les pentes.
382 double dx, dy; // direction au niveau de l'icone courante P0.
383 double dx_, dy_; // direction au niveau de l'icone suivante P1.
384 double x0_,y0_, x1_,y1_; // points de controle entre P0 et P1.
385 if (pFirstDrawnElement == NULL)
386 {
387 return pPath;
388 }
389
390 // direction initiale.
391 ic = pFirstDrawnElement;
392 pIcon = ic->data;
393 _get_icon_center (pIcon,x0,y0);
394 next_ic = cairo_dock_get_next_element (ic, pDock->icons);
395 pNextIcon = next_ic->data;
396 _get_icon_center (pNextIcon,x1,y1);
397 if (! bIsLoop)
398 {
399 _calculate_slope (x0,y0, x1,y1, dx,dy);
400 }
401 else
402 {
403 next2_ic = cairo_dock_get_previous_element (ic, pDock->icons); // icone precedente dans la boucle.
404 pNext2Icon = next2_ic->data;
405 _get_icon_center (pNext2Icon,x2,y2);
406 _calculate_slope (x2,y2, x0,y0, dx,dy);
407 }
408 // point suivant.
409 next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
410 pNext2Icon = next2_ic->data;
411 _get_icon_center (pNext2Icon,x2,y2);
412
413 cairo_dock_gl_path_move_to (pPath, x0, y0);
414 if (pDock->container.bIsHorizontal)
415 cairo_dock_gl_path_set_extent (pPath, pDock->container.iWidth, pDock->container.iHeight);
416 else
417 cairo_dock_gl_path_set_extent (pPath, pDock->container.iHeight, pDock->container.iWidth);
418
419 // on parcourt les icones.
420 do
421 {
422 // l'icone courante, la suivante, et celle d'apres.
423 pIcon = ic->data;
424 pNextIcon = next_ic->data;
425 pNext2Icon = next2_ic->data;
426
427 // on va tracer de (x0,y0) a (x1,y1)
428 _get_icon_center (pIcon,x0,y0);
429 _get_icon_center (pNextIcon,x1,y1);
430 _get_icon_center (pNext2Icon,x2,y2);
431
432 // la pente au point (x1,y1)
433 _calculate_slope (x0,y0, x2,y2, dx_,dy_);
434
435 // points de controle.
436 norme = sqrt ((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0))/2; // distance de prolongation suivant la pente.
437 x0_ = x0 + dx * norme;
438 y0_ = y0 + dy * norme;
439 x1_ = x1 - dx_ * norme;
440 y1_ = y1 - dy_ * norme;
441
442 cairo_dock_gl_path_curve_to (pPath, NB_VERTEX_PER_ICON_PAIR,
443 x0_, y0_,
444 x1_, y1_,
445 x1, y1);
446
447 // on decale tout d'un cran.
448 ic = next_ic;
449 next_ic = next2_ic;
450 next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
451 dx = dx_;
452 dy = dy_;
453 if (next_ic == pFirstDrawnElement && ! bIsLoop)
454 break ;
455 }
456 while (ic != pFirstDrawnElement);
457
458 return pPath;
459 }
460
461
cairo_dock_draw_current_path_opengl(double fLineWidth,double * fLineColor,int iNbVertex)462 void cairo_dock_draw_current_path_opengl (double fLineWidth, double *fLineColor, int iNbVertex)
463 {
464 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
465 glLineWidth(fLineWidth); // Ici on choisit l'epaisseur du contour du polygone.
466 if (fLineColor != NULL)
467 glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]); // Et sa couleur.
468
469 _draw_current_path (iNbVertex, FALSE);
470 }
471
472
cairo_dock_draw_rounded_rectangle_opengl(double fFrameWidth,double fFrameHeight,double fRadius,double fLineWidth,double * fLineColor)473 void cairo_dock_draw_rounded_rectangle_opengl (double fFrameWidth, double fFrameHeight, double fRadius, double fLineWidth, double *fLineColor)
474 {
475 const CairoDockGLPath *pPath = cairo_dock_generate_rectangle_path (fFrameWidth, fFrameHeight, fRadius, TRUE);
476
477 if (fLineColor != NULL)
478 glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]);
479 if (fLineWidth == 0)
480 {
481 cairo_dock_fill_gl_path (pPath, 0);
482 }
483 else
484 {
485 glLineWidth (fLineWidth);
486 cairo_dock_stroke_gl_path (pPath, TRUE);
487 }
488 }
489
cairo_dock_draw_string_opengl(CairoDock * pDock,double fStringLineWidth,gboolean bIsLoop,gboolean bForceConstantSeparator)490 void cairo_dock_draw_string_opengl (CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
491 {
492 const CairoDockGLPath *pPath = cairo_dock_generate_string_path_opengl (pDock, bIsLoop, bForceConstantSeparator);
493 if (pPath == NULL || pPath->iCurrentPt < 2)
494 return;
495
496 glLineWidth (fStringLineWidth);
497 ///glColor4f (myIconsParam.fStringColor[0], myIconsParam.fStringColor[1], myIconsParam.fStringColor[2], myIconsParam.fStringColor[3]);
498 cairo_dock_stroke_gl_path (pPath, FALSE);
499 }
500