~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

Viewing changes to dock-rendering/src/rendering-curve.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
ImportĀ upstreamĀ versionĀ 2.0.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/******************************************************************************
 
21
 
 
22
This file is a part of the cairo-dock program, 
 
23
released under the terms of the GNU General Public License.
 
24
 
 
25
Written by Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
 
26
 
 
27
This rendering has been written by parAdOxxx_ZeRo (http://paradoxxx.zero.free.fr)
 
28
 and Fabounet.
 
29
 
 
30
******************************************************************************/
 
31
#include <math.h>
 
32
#include <string.h>
 
33
#include <stdio.h>
 
34
#include <stdlib.h>
 
35
 
 
36
#include <gtk/gtk.h>
 
37
 
 
38
#include <cairo.h>
 
39
 
 
40
#include "rendering-commons.h"
 
41
#include "rendering-curve.h"
 
42
#include "rendering-3D-plane.h"
 
43
 
 
44
 
 
45
static double *s_pReferenceCurveS = NULL;
 
46
static double *s_pReferenceCurveX = NULL;
 
47
static double *s_pReferenceCurveY = NULL;
 
48
int iVanishingPointY = 200;
 
49
 
 
50
extern cairo_surface_t *my_pFlatSeparatorSurface[2];
 
51
 
 
52
extern CDSpeparatorType my_curve_iDrawSeparator3D;
 
53
 
 
54
extern gdouble my_fCurveCurvature;
 
55
extern gint my_iCurveAmplitude;
 
56
 
 
57
//const guint curveOffsetX = 75;
 
58
// OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
 
59
// Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
 
60
 
 
61
#define xCurve(a, t) (t * (t * t + 1.5 * (1 - t) * (1 - a + 2 * a * t)))
 
62
#define yCurve(t) (3 * t * (1 - t))
 
63
#define XCurve(W, a, t) (W * xCurve (a, t))
 
64
#define YCurve(h, t) (h * yCurve (t))
 
65
 
 
66
void cd_rendering_calculate_max_dock_size_curve (CairoDock *pDock)
 
67
{
 
68
        static double fCurveCurvature= 0;
 
69
        if (s_pReferenceCurveS == NULL || my_fCurveCurvature != fCurveCurvature)
 
70
        {
 
71
                fCurveCurvature = my_fCurveCurvature;
 
72
                cd_rendering_calculate_reference_curve (my_fCurveCurvature);
 
73
        }
 
74
        
 
75
        pDock->pFirstDrawnElement = cairo_dock_calculate_icons_positions_at_rest_linear (pDock->icons, pDock->fFlatDockWidth, pDock->iScrollOffset);
 
76
        
 
77
        pDock->iDecorationsHeight = myBackground.iFrameMargin + my_iCurveAmplitude + .5 * pDock->iMaxIconHeight;  // de bas en haut.
 
78
        
 
79
        pDock->iMaxDockWidth = ceil (cairo_dock_calculate_max_dock_width (pDock, pDock->pFirstDrawnElement, pDock->fFlatDockWidth, 1., 0.));  // etendue max des icones, sans le cadre.
 
80
        //g_print ("iMaxDockWidth : %d\n", pDock->iMaxDockWidth);
 
81
        
 
82
        double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);  // hauteur de controle de la courbe de Bezier, de telle facon qu'elle atteigne 'iDecorationsHeight'.
 
83
        double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;  // hauteur de la courbe a la 1ere icone.
 
84
        double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0.01)));
 
85
        double xi = xCurve (my_fCurveCurvature, ti);
 
86
        double fDeltaX = pDock->iMaxDockWidth * xi / (1 - 2 * xi);  // abscisse de la 1ere icone pour satisfaire a la contrainte y=hi.
 
87
        //g_print ("ti = %.2f => xi = %.2f => fDeltaX = %.2f\n", ti, xi, fDeltaX);
 
88
        //g_print ("my_fCurveCurvature:%.2f\n", my_fCurveCurvature);
 
89
        pDock->iMaxDockWidth += 2*fDeltaX;
 
90
        double tan_theta = (my_fCurveCurvature != 1 ? h / ((1 - my_fCurveCurvature) * pDock->iMaxDockWidth / 2) : 1e6);  // la tangente a une courbe de Bezier en son origine est la droite reliant les deux premiers points de controle.
 
91
        double fDeltaTip = .5 * myBackground.iDockLineWidth * sqrt (1 + tan_theta * tan_theta) / tan_theta;  // prolongement de la pointe.
 
92
        pDock->iMaxDockWidth += 2 * fDeltaTip;
 
93
        pDock->iMaxDockWidth = ceil (cairo_dock_calculate_max_dock_width (pDock, pDock->pFirstDrawnElement, pDock->fFlatDockWidth, 1., 2*(fDeltaX+fDeltaTip)));
 
94
        //g_print ("fDeltaTip : %.2f\n", fDeltaTip);
 
95
        
 
96
        pDock->iMaxDockHeight = myBackground.iDockLineWidth + myBackground.iFrameMargin + my_iCurveAmplitude + (1 + g_fAmplitude) * pDock->iMaxIconHeight + myLabels.iLabelSize;  // de bas en haut.
 
97
        
 
98
        pDock->iDecorationsWidth = pDock->iMaxDockWidth - 4 * fDeltaTip;
 
99
        
 
100
        pDock->iMinDockWidth = pDock->fFlatDockWidth / (1 - 2 * xi) + 2 * fDeltaTip;
 
101
        //g_print ("pDock->fFlatDockWidth = %.2f => pDock->iMinDockWidth = %d\n", pDock->fFlatDockWidth, pDock->iMinDockWidth);
 
102
        
 
103
        pDock->iMinDockHeight = myBackground.iDockLineWidth + myBackground.iFrameMargin + my_iCurveAmplitude + pDock->iMaxIconHeight;  // de bas en haut.
 
104
        
 
105
        if (my_pFlatSeparatorSurface[0] == NULL && (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR))
 
106
                cd_rendering_load_flat_separator (CAIRO_CONTAINER (g_pMainDock));
 
107
        
 
108
        pDock->inputArea.x = fDeltaX+fDeltaTip;
 
109
        pDock->inputArea.y = 0;
 
110
        pDock->inputArea.width = pDock->iMinDockWidth - 2 * (fDeltaX+fDeltaTip);
 
111
        pDock->inputArea.height = pDock->iMinDockHeight;
 
112
}
 
113
 
 
114
 
 
115
static void cd_rendering_make_3D_curve_separator (Icon *icon, cairo_t *pCairoContext, CairoDock *pDock, gboolean bIncludeEdges, gboolean bBackGround)
 
116
{
 
117
        double fLineWidth = myBackground.iDockLineWidth;
 
118
        double fMargin = myBackground.iFrameMargin;
 
119
        double hi;
 
120
        
 
121
        Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
 
122
        if (pPrevIcon == NULL)
 
123
                pPrevIcon = icon;
 
124
        Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
 
125
        if (pNextIcon == NULL)
 
126
                pNextIcon = icon;
 
127
        
 
128
        double fVanishingDistanceLeft, fVanishingDistanceRight;
 
129
        double fDeltaInterIconLeft, fDeltaInterIconRight;
 
130
        if (pDock->bDirectionUp)
 
131
        {
 
132
                hi = pDock->iCurrentHeight - (icon->fDrawY + icon->fHeight * icon->fScale);
 
133
                fVanishingDistanceLeft = iVanishingPointY + pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale;
 
134
                fVanishingDistanceRight = iVanishingPointY + pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale;
 
135
                
 
136
                fDeltaInterIconLeft = (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale) - (icon->fDrawY + icon->fHeight * icon->fScale);
 
137
                fDeltaInterIconRight = (icon->fDrawY + icon->fHeight * icon->fScale) - (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale);
 
138
        }
 
139
        else
 
140
        {
 
141
                hi = icon->fDrawY;
 
142
                fVanishingDistanceLeft = iVanishingPointY + pDock->iCurrentHeight - pPrevIcon->fDrawY;
 
143
                fVanishingDistanceRight = iVanishingPointY + pDock->iCurrentHeight - pNextIcon->fDrawY;
 
144
                
 
145
                fDeltaInterIconLeft = (pPrevIcon->fDrawY) - (icon->fDrawY);
 
146
                fDeltaInterIconRight = (icon->fDrawY) - (pNextIcon->fDrawY);
 
147
        }
 
148
        double fLeftInclination = (icon->fDrawX - pDock->iCurrentWidth / 2) / fVanishingDistanceLeft;
 
149
        double fRightInclination = (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / fVanishingDistanceRight;
 
150
        
 
151
        if (bBackGround || ! bIncludeEdges)  // pour s'arreter sur la courbe, on realise un clippage.
 
152
        {
 
153
                //\________________ On se ramene au cas du dessin optimise.
 
154
                double x0, y0, xf, yf, w0, h0;
 
155
                if (pDock->bDirectionUp)
 
156
                {
 
157
                        x0 = icon->fDrawX - MAX (0, fLeftInclination * (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale));
 
158
                        xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale));
 
159
                }
 
160
                else
 
161
                {
 
162
                        x0 = icon->fDrawX - MAX (0, fLeftInclination * (pDock->iCurrentHeight - (pPrevIcon->fDrawY)));
 
163
                        xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pDock->iCurrentHeight - (pNextIcon->fDrawY)));
 
164
                }
 
165
                if (! bIncludeEdges)  // on prolonge jusqu'en bas.
 
166
                {
 
167
                        if (pDock->bDirectionUp)
 
168
                        {
 
169
                                x0 += MIN (0, fLeftInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
 
170
                                xf += MAX (0, fRightInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
 
171
                        }
 
172
                        else
 
173
                        {
 
174
                                x0 += MIN (0, fLeftInclination * (pPrevIcon->fDrawY));
 
175
                                xf += MAX (0, fRightInclination * (pNextIcon->fDrawY));
 
176
                        }
 
177
                }
 
178
                //g_print ("x0:%.2f -> xf:%.2f\n", x0, xf);
 
179
                y0 = 0;
 
180
                yf = icon->fDrawY;
 
181
                w0 = xf - x0;
 
182
                h0 = yf - y0;
 
183
                
 
184
                int sens;
 
185
                double fDockOffsetY;  // Offset du coin haut gauche du cadre.
 
186
                if (pDock->bDirectionUp)
 
187
                {
 
188
                        sens = 1;
 
189
                        fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
 
190
                }
 
191
                else
 
192
                {
 
193
                        sens = -1;
 
194
                        fDockOffsetY = .5 * fLineWidth;
 
195
                }
 
196
                
 
197
                double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
 
198
                
 
199
                double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
 
200
                double hi_ = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
201
                double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi_ / h, 0)));
 
202
                double xi = xCurve (my_fCurveCurvature, ti);
 
203
                double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
 
204
                
 
205
                Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
 
206
                double fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fDrawX - curveOffsetX : fLineWidth / 2);
 
207
                
 
208
                
 
209
                //\________________ On approche le morceau de courbe de Bezier par des trapezes.
 
210
                double x = (x0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
211
                double s = cd_rendering_interpol_curve_parameter (x);
 
212
                double y = yCurve (s);
 
213
                double x_ = (x0 + w0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
214
                double s_ = cd_rendering_interpol_curve_parameter (x_);
 
215
                double y_ = yCurve (s_);
 
216
                int i, iNbMidPoints = MAX (0, w0 / 20 - 1);  // nombre de points intermediaires a calculer.
 
217
                double *pMidPointCoord = g_new (double, 2 * (iNbMidPoints+2));
 
218
                pMidPointCoord[0] = x0 - fDockOffsetX;
 
219
                pMidPointCoord[1] = y * h;
 
220
                pMidPointCoord[2*(iNbMidPoints+1)] = x0 + w0 - fDockOffsetX;
 
221
                pMidPointCoord[2*(iNbMidPoints+1)+1] = y_ * h;
 
222
                double si=s, ds = (s_ - s) / (iNbMidPoints+1);
 
223
                for (i = 1; i < iNbMidPoints+1; i ++)
 
224
                {
 
225
                        si += ds;
 
226
                        pMidPointCoord[2*i] = (fDockWidth + 2 * curveOffsetX) * xCurve (my_fCurveCurvature, si);
 
227
                        pMidPointCoord[2*i+1] = h * yCurve (si);
 
228
                }
 
229
                
 
230
                cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
 
231
                cairo_save (pCairoContext);
 
232
                double fDeltaLineWidth = 0.;
 
233
                if (bIncludeEdges)
 
234
                {
 
235
                        double tan_theta = MAX (fabs (pMidPointCoord[1] - pMidPointCoord[3]) / (pMidPointCoord[2] - pMidPointCoord[0]), fabs (pMidPointCoord[2*iNbMidPoints+1] - pMidPointCoord[2*iNbMidPoints+3]) / (pMidPointCoord[2*iNbMidPoints+2] - pMidPointCoord[2*iNbMidPoints]));
 
236
                        fDeltaLineWidth = (fLineWidth / 2 + .1) * sqrt (1. + tan_theta*tan_theta);
 
237
                }
 
238
                if (pDock->bHorizontalDock)
 
239
                {
 
240
                        cairo_move_to (pCairoContext, x0, fDockOffsetY - sens * (y * h + fDeltaLineWidth));
 
241
                        for (i = 0; i < iNbMidPoints+1; i ++)
 
242
                                cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
 
243
                        cairo_rel_line_to (pCairoContext, 0, sens * (y_ * h + fDeltaLineWidth));
 
244
                        cairo_rel_line_to (pCairoContext, - w0, 0);
 
245
                        cairo_rel_line_to (pCairoContext, 0, - sens * (y * h + fDeltaLineWidth));
 
246
                }
 
247
                else
 
248
                {
 
249
                        cairo_move_to (pCairoContext, fDockOffsetY - sens * (y * h + fDeltaLineWidth), x0);
 
250
                        for (i = 0; i < iNbMidPoints+1; i ++)
 
251
                                cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
 
252
                        cairo_rel_line_to (pCairoContext, sens * (y_ * h + fDeltaLineWidth), 0);
 
253
                        cairo_rel_line_to (pCairoContext, 0, - w0);
 
254
                        cairo_rel_line_to (pCairoContext, - sens * (y * h + fDeltaLineWidth), 0);
 
255
                }
 
256
                
 
257
                g_free (pMidPointCoord);
 
258
                cairo_clip (pCairoContext);
 
259
        }
 
260
        
 
261
        
 
262
        double fHeight, fBigWidth, fLittleWidth;
 
263
        if (bIncludeEdges)
 
264
        {
 
265
                fHeight = (bBackGround ? pDock->iDecorationsHeight - hi : hi) + myBackground.iDockLineWidth;
 
266
                fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
 
267
                fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
 
268
        }
 
269
        else
 
270
        {
 
271
                fHeight = pDock->iDecorationsHeight - myBackground.iDockLineWidth;
 
272
                fBigWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi);
 
273
                fLittleWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi - fHeight);
 
274
        }
 
275
        double fDeltaXLeft = fHeight * fLeftInclination;
 
276
        double fDeltaXRight = fHeight * fRightInclination;
 
277
        //g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
 
278
        
 
279
        int sens;
 
280
        double fDockOffsetX, fDockOffsetY;
 
281
        if (pDock->bDirectionUp)
 
282
        {
 
283
                sens = 1;
 
284
                if (bIncludeEdges)
 
285
                        fDockOffsetY = pDock->iCurrentHeight - fHeight - (bBackGround ? myBackground.iDockLineWidth + hi : 0);
 
286
                else
 
287
                        fDockOffsetY = pDock->iCurrentHeight - fHeight - myBackground.iDockLineWidth;
 
288
        }
 
289
        else
 
290
        {
 
291
                sens = -1;
 
292
                if (bIncludeEdges)
 
293
                        fDockOffsetY = fHeight + (bBackGround ? myBackground.iDockLineWidth + hi : 0);
 
294
                else
 
295
                        fDockOffsetY = fHeight + myBackground.iDockLineWidth;
 
296
        }
 
297
        
 
298
        if (bIncludeEdges)
 
299
                fDockOffsetX = icon->fDrawX - (bBackGround ? fHeight * fLeftInclination : 0);
 
300
        else
 
301
                fDockOffsetX = (pDock->bDirectionUp ? icon->fDrawX - (fHeight - hi) * fLeftInclination : icon->fDrawX - (fHeight - hi) * fLeftInclination);
 
302
        fDockOffsetX -= fDeltaInterIconLeft * fLeftInclination*sens;
 
303
        
 
304
        if (pDock->bHorizontalDock)
 
305
        {
 
306
                cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY);  // coin haut gauche.
 
307
                cairo_move_to (pCairoContext, 0, 0);  // coin haut gauche.
 
308
                
 
309
                cairo_rel_line_to (pCairoContext, fLittleWidth, 0);
 
310
                cairo_rel_line_to (pCairoContext, fDeltaXRight, sens * fHeight);
 
311
                cairo_rel_line_to (pCairoContext, - fBigWidth, 0);
 
312
                cairo_rel_line_to (pCairoContext, - fDeltaXLeft, - sens * fHeight);
 
313
                
 
314
                if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
 
315
                {
 
316
                        if (! pDock->bDirectionUp)
 
317
                                cairo_scale (pCairoContext, 1, -1);
 
318
                        cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_HORIZONTAL], MIN (0, (fHeight + hi) * fLeftInclination), 0);
 
319
                }
 
320
        }
 
321
        else
 
322
        {
 
323
                cairo_translate (pCairoContext, fDockOffsetY, fDockOffsetX);  // coin haut gauche.
 
324
                cairo_move_to (pCairoContext, 0, 0);  // coin haut gauche.
 
325
                
 
326
                cairo_rel_line_to (pCairoContext, 0, fLittleWidth);
 
327
                cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXRight);
 
328
                cairo_rel_line_to (pCairoContext, 0, - fBigWidth);
 
329
                cairo_rel_line_to (pCairoContext, - sens * fHeight, - fDeltaXLeft);
 
330
                
 
331
                if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
 
332
                {
 
333
                        if (! pDock->bDirectionUp)
 
334
                                cairo_scale (pCairoContext, -1, 1);
 
335
                        cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_VERTICAL], 0, MIN (0, (fHeight + hi) * fLeftInclination));
 
336
                }
 
337
        }
 
338
}
 
339
 
 
340
static void cd_rendering_draw_3D_curve_separator_edge (Icon *icon, cairo_t *pCairoContext, CairoDock *pDock, gboolean bBackGround)
 
341
{
 
342
        Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
 
343
        if (pPrevIcon == NULL)
 
344
                pPrevIcon = icon;
 
345
        Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
 
346
        if (pNextIcon == NULL)
 
347
                pNextIcon = icon;
 
348
        
 
349
        double hi, fVanishingDistanceLeft, fVanishingDistanceRight;
 
350
        if (pDock->bDirectionUp)
 
351
        {
 
352
                hi = pDock->iCurrentHeight - (icon->fDrawY + icon->fHeight * icon->fScale);
 
353
                fVanishingDistanceLeft = iVanishingPointY + pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale;
 
354
                fVanishingDistanceRight = iVanishingPointY + pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale;
 
355
        }
 
356
        else
 
357
        {
 
358
                hi = icon->fDrawY;
 
359
                fVanishingDistanceLeft = iVanishingPointY + pDock->iCurrentHeight - pPrevIcon->fDrawY;
 
360
                fVanishingDistanceRight = iVanishingPointY + pDock->iCurrentHeight - pNextIcon->fDrawY;
 
361
        }
 
362
        double fLeftInclination = (icon->fDrawX - pDock->iCurrentWidth / 2) / fVanishingDistanceLeft;
 
363
        double fRightInclination = (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / fVanishingDistanceRight;
 
364
        
 
365
        
 
366
        double fHeight, fBigWidth, fLittleWidth;
 
367
        fHeight = (bBackGround ? pDock->iDecorationsHeight - hi - 0.5*myBackground.iDockLineWidth : hi + 1.5*myBackground.iDockLineWidth);
 
368
        fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
 
369
        fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
 
370
        
 
371
        double fDeltaXLeft = fHeight * fLeftInclination;
 
372
        double fDeltaXRight = fHeight * fRightInclination;
 
373
        //g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
 
374
        
 
375
        int sens;
 
376
        double fDockOffsetX, fDockOffsetY;
 
377
        if (pDock->bDirectionUp)
 
378
        {
 
379
                sens = 1;
 
380
                fDockOffsetY =  (bBackGround ? 0.5*myBackground.iDockLineWidth : - 1.*myBackground.iDockLineWidth);
 
381
        }
 
382
        else
 
383
        {
 
384
                sens = -1;
 
385
                fDockOffsetY =  (bBackGround ? - 0.5*myBackground.iDockLineWidth : 1.*myBackground.iDockLineWidth);
 
386
        }
 
387
        fDockOffsetX = (bBackGround ? .5*myBackground.iDockLineWidth * fLeftInclination + 1.*fLeftInclination : - 0.5 * myBackground.iDockLineWidth * fLeftInclination);
 
388
        //fDockOffsetX = -.5*myBackground.iDockLineWidth;
 
389
        
 
390
        if (pDock->bHorizontalDock)
 
391
        {
 
392
                cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY);  // coin haut droit.
 
393
                
 
394
                cairo_move_to (pCairoContext, fLittleWidth, 0);
 
395
                cairo_rel_line_to (pCairoContext, fDeltaXRight, sens * fHeight);
 
396
                
 
397
                cairo_move_to (pCairoContext, 0, 0);
 
398
                cairo_rel_line_to (pCairoContext, fDeltaXLeft, sens * fHeight);
 
399
        }
 
400
        else
 
401
        {
 
402
                cairo_translate (pCairoContext, fDockOffsetY, fDockOffsetX);  // coin haut droit.
 
403
                
 
404
                cairo_move_to (pCairoContext, 0, fLittleWidth);
 
405
                cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXRight);
 
406
                
 
407
                cairo_move_to (pCairoContext, 0, 0);
 
408
                cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXLeft);
 
409
        }
 
410
}
 
411
 
 
412
 
 
413
static void cd_rendering_draw_3D_curve_separator (Icon *icon, cairo_t *pCairoContext, CairoDock *pDock, gboolean bHorizontal, gboolean bBackGround)
 
414
{
 
415
        cd_rendering_make_3D_curve_separator (icon, pCairoContext, pDock, (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR), bBackGround);
 
416
        
 
417
        if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
418
        {
 
419
                cairo_set_operator (pCairoContext, CAIRO_OPERATOR_DEST_OUT);
 
420
                cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 1.0);
 
421
                cairo_fill (pCairoContext);
 
422
                
 
423
                cd_rendering_draw_3D_curve_separator_edge (icon, pCairoContext, pDock, bBackGround);
 
424
                
 
425
                cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
 
426
                cairo_set_line_width (pCairoContext, myBackground.iDockLineWidth);
 
427
                cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
 
428
                cairo_stroke (pCairoContext);
 
429
        }
 
430
        else
 
431
        {
 
432
                cairo_fill (pCairoContext);
 
433
        }
 
434
}
 
435
 
 
436
 
 
437
 
 
438
void cd_rendering_render_curve (cairo_t *pCairoContext, CairoDock *pDock)
 
439
{
 
440
        //\____________________ On trace le cadre.
 
441
        double fLineWidth = myBackground.iDockLineWidth;
 
442
        double fMargin = myBackground.iFrameMargin;
 
443
        double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
 
444
        
 
445
        double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
 
446
        double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
447
        double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
 
448
        double xi = xCurve (my_fCurveCurvature, ti);
 
449
        double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
 
450
        
 
451
        int sens;
 
452
        double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
 
453
        Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
 
454
        fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fDrawX - curveOffsetX : fLineWidth / 2);
 
455
        if (pDock->bDirectionUp)
 
456
        {
 
457
                sens = 1;
 
458
                fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
 
459
        }
 
460
        else
 
461
        {
 
462
                sens = -1;
 
463
                fDockOffsetY = .5 * fLineWidth;
 
464
        }
 
465
        
 
466
        cairo_save (pCairoContext);
 
467
        
 
468
        cairo_dock_draw_curved_frame (pCairoContext, fDockWidth + 2 * curveOffsetX, h, fDockOffsetX, fDockOffsetY, pDock->bHorizontalDock, sens);
 
469
        
 
470
        //\____________________ On dessine les decorations dedans.
 
471
        fDockOffsetY = (pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
 
472
        cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fDockOffsetX, fDockWidth + 2 * curveOffsetX);
 
473
        
 
474
        //\____________________ On dessine le cadre.
 
475
        if (fLineWidth > 0)
 
476
        {
 
477
                cairo_set_line_width (pCairoContext, fLineWidth);
 
478
                cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
 
479
                cairo_stroke (pCairoContext);
 
480
        }
 
481
        else
 
482
                cairo_new_path (pCairoContext);
 
483
        cairo_restore (pCairoContext);
 
484
        
 
485
        //\____________________ On dessine la ficelle qui les joint.
 
486
        if (myIcons.iStringLineWidth > 0)
 
487
                cairo_dock_draw_string (pCairoContext, pDock, myIcons.iStringLineWidth, FALSE, (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR));
 
488
        
 
489
        //\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
 
490
        GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
 
491
        if (pFirstDrawnElement == NULL)
 
492
                return;
 
493
        
 
494
        double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
 
495
        Icon *icon;
 
496
        GList *ic = pFirstDrawnElement;
 
497
        
 
498
        if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
499
        {
 
500
                cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
 
501
                do
 
502
                {
 
503
                        icon = ic->data;
 
504
                        
 
505
                        if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
 
506
                        {
 
507
                                cairo_save (pCairoContext);
 
508
                                cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, TRUE);
 
509
                                cairo_restore (pCairoContext);
 
510
                        }
 
511
                        
 
512
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
513
                } while (ic != pFirstDrawnElement);
 
514
                
 
515
                do
 
516
                {
 
517
                        icon = ic->data;
 
518
                        
 
519
                        if (icon->acFileName != NULL || ! CAIRO_DOCK_IS_SEPARATOR (icon))
 
520
                        {
 
521
                                cairo_save (pCairoContext);
 
522
                                cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
 
523
                                cairo_restore (pCairoContext);
 
524
                        }
 
525
                        
 
526
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
527
                } while (ic != pFirstDrawnElement);
 
528
                
 
529
                if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
530
                {
 
531
                        do
 
532
                        {
 
533
                                icon = ic->data;
 
534
                                
 
535
                                if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
 
536
                                {
 
537
                                        cairo_save (pCairoContext);
 
538
                                        cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, FALSE);
 
539
                                        cairo_restore (pCairoContext);
 
540
                                }
 
541
                                
 
542
                                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
543
                        } while (ic != pFirstDrawnElement);
 
544
                }
 
545
        }
 
546
        else
 
547
        {
 
548
                do
 
549
                {
 
550
                        icon = ic->data;
 
551
                        
 
552
                        cairo_save (pCairoContext);
 
553
                        cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
 
554
                        cairo_restore (pCairoContext);
 
555
                        
 
556
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
557
                } while (ic != pFirstDrawnElement);
 
558
        }
 
559
}
 
560
 
 
561
 
 
562
 
 
563
static gboolean _cd_separator_is_impacted (Icon *icon, CairoDock *pDock, double fXMin, double fXMax, gboolean bBackGround, gboolean bIncludeEdges)
 
564
{
 
565
        double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
566
        double fLeftInclination = fabs (icon->fDrawX - pDock->iCurrentWidth / 2) / iVanishingPointY;
 
567
        double fRightInclination = fabs (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / iVanishingPointY;
 
568
        
 
569
        double fHeight, fBigWidth, fLittleWidth;
 
570
        if (bIncludeEdges)
 
571
        {
 
572
                fHeight = (bBackGround ? pDock->iDecorationsHeight - hi : hi) + (bIncludeEdges ? myBackground.iDockLineWidth : 0);
 
573
                fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
 
574
                fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
 
575
        }
 
576
        else
 
577
        {
 
578
                fHeight = pDock->iDecorationsHeight;
 
579
                fBigWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + fHeight);
 
580
                fLittleWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY - fHeight);
 
581
        }
 
582
        double fDeltaXLeft = fHeight * fLeftInclination;
 
583
        double fDeltaXRight = fHeight * fRightInclination;
 
584
        double fDeltaX = MAX (fDeltaXLeft, fDeltaXRight);
 
585
        //g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
 
586
        
 
587
        int sens;
 
588
        double fDockOffsetX, fDockOffsetY;
 
589
        if (pDock->bDirectionUp)
 
590
        {
 
591
                sens = 1;
 
592
                if (bIncludeEdges)
 
593
                        fDockOffsetY =  pDock->iCurrentHeight - fHeight - (bBackGround ? myBackground.iDockLineWidth + hi : 0);
 
594
                else
 
595
                        fDockOffsetY =  pDock->iCurrentHeight - fHeight;
 
596
        }
 
597
        else
 
598
        {
 
599
                sens = -1;
 
600
                if (bIncludeEdges)
 
601
                        fDockOffsetY = fHeight + (bBackGround ? myBackground.iDockLineWidth + hi : 0);
 
602
                else
 
603
                        fDockOffsetY = fHeight;
 
604
        }
 
605
        
 
606
        if (bIncludeEdges)
 
607
                        fDockOffsetX = icon->fDrawX - (bBackGround ? fHeight * fLeftInclination : 0);
 
608
                else
 
609
                        fDockOffsetX = icon->fDrawX - (fHeight - hi) * fLeftInclination;
 
610
        double fXLeft, fXRight;
 
611
        if (icon->fDrawX + icon->fWidth * icon->fScale / 2 > pDock->iCurrentWidth / 2)  // on est a droite.
 
612
        {
 
613
                if (bIncludeEdges)
 
614
                {
 
615
                        if (bBackGround)
 
616
                        {
 
617
                                fXLeft = icon->fDrawX - fHeight * fLeftInclination;
 
618
                                fXRight = icon->fDrawX + icon->fWidth * icon->fScale;
 
619
                        }
 
620
                        else
 
621
                        {
 
622
                                fXLeft = icon->fDrawX;
 
623
                                fXRight = icon->fDrawX + icon->fWidth * icon->fScale + fHeight * fRightInclination;
 
624
                        }
 
625
                }
 
626
                else
 
627
                {
 
628
                        fXLeft = icon->fDrawX - (fHeight - hi) * fLeftInclination;
 
629
                        fXRight = icon->fDrawX + icon->fWidth * icon->fScale + hi * fRightInclination;
 
630
                }
 
631
        }
 
632
        else  // a gauche.
 
633
        {
 
634
                if (bIncludeEdges)
 
635
                {
 
636
                        if (bBackGround)
 
637
                        {
 
638
                                fXLeft = icon->fDrawX;
 
639
                                fXRight = icon->fDrawX + icon->fWidth * icon->fScale + fHeight * fRightInclination;
 
640
                        }
 
641
                        else
 
642
                        {
 
643
                                fXLeft = icon->fDrawX - fHeight * fLeftInclination;
 
644
                                fXRight = icon->fDrawX + icon->fWidth * icon->fScale;
 
645
                        }
 
646
                }
 
647
                else
 
648
                {
 
649
                        fXLeft = icon->fDrawX - hi * fLeftInclination;
 
650
                        fXRight = icon->fDrawX + icon->fWidth * icon->fScale +(fHeight - hi) * fRightInclination;
 
651
                }
 
652
        }
 
653
        
 
654
        return (fXLeft <= fXMax && floor (fXRight) > fXMin);
 
655
}
 
656
 
 
657
void cd_rendering_render_optimized_curve (cairo_t *pCairoContext, CairoDock *pDock, GdkRectangle *pArea)
 
658
{
 
659
        //\____________________ On trace le cadre.
 
660
        double fLineWidth = myBackground.iDockLineWidth;
 
661
        double fMargin = myBackground.iFrameMargin;
 
662
        double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
 
663
        
 
664
        double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
 
665
        double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
666
        double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
 
667
        double xi = xCurve (my_fCurveCurvature, ti);
 
668
        double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
 
669
        
 
670
        int sens;
 
671
        double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
 
672
        Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
 
673
        fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - curveOffsetX : fLineWidth / 2);
 
674
        int x0, y0, w0, h0;
 
675
        if (pDock->bHorizontalDock)
 
676
        {
 
677
                x0 = pArea->x;
 
678
                y0 = pArea->y;
 
679
                w0 = pArea->width;
 
680
                h0 = pArea->height;
 
681
        }
 
682
        else
 
683
        {
 
684
                x0 = pArea->y;
 
685
                y0 = pArea->x;
 
686
                w0 = pArea->height;
 
687
                h0 = pArea->width;
 
688
        }
 
689
        
 
690
        if (pDock->bDirectionUp)
 
691
        {
 
692
                sens = 1;
 
693
                fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
 
694
        }
 
695
        else
 
696
        {
 
697
                sens = -1;
 
698
                fDockOffsetY = .5 * fLineWidth;
 
699
        }
 
700
        
 
701
        //\________________ On approche le morceau de courbe de Bezier par des trapezes.
 
702
        double x = (x0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
703
        double s = cd_rendering_interpol_curve_parameter (x);
 
704
        double y = yCurve (s);
 
705
        double x_ = (x0 + w0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
706
        double s_ = cd_rendering_interpol_curve_parameter (x_);
 
707
        double y_ = yCurve (s_);
 
708
        int i, iNbMidPoints = MAX (0, w0 / 20 - 1);  // nombre de points intermediaires a calculer.
 
709
        double *pMidPointCoord = g_new (double, 2 * (iNbMidPoints+2));
 
710
        pMidPointCoord[0] = x0 - fDockOffsetX;
 
711
        pMidPointCoord[1] = y * h;
 
712
        pMidPointCoord[2*(iNbMidPoints+1)] = x0 + w0 - fDockOffsetX;
 
713
        pMidPointCoord[2*(iNbMidPoints+1)+1] = y_ * h;
 
714
        double si=s, ds = (s_ - s) / (iNbMidPoints+1);
 
715
        for (i = 1; i < iNbMidPoints+1; i ++)
 
716
        {
 
717
                si += ds;
 
718
                pMidPointCoord[2*i] = (fDockWidth + 2 * curveOffsetX) * xCurve (my_fCurveCurvature, si);
 
719
                pMidPointCoord[2*i+1] = h * yCurve (si);
 
720
        }
 
721
        
 
722
        cairo_save (pCairoContext);
 
723
        if (pDock->bHorizontalDock)
 
724
        {
 
725
                cairo_move_to (pCairoContext, pArea->x, fDockOffsetY - sens * y * h);
 
726
                for (i = 0; i < iNbMidPoints+1; i ++)
 
727
                        cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
 
728
                cairo_rel_line_to (pCairoContext, 0, sens * y_ * h);
 
729
                cairo_rel_line_to (pCairoContext, - pArea->width, 0);
 
730
                cairo_rel_line_to (pCairoContext, 0, - sens * y * h);
 
731
        }
 
732
        else
 
733
        {
 
734
                cairo_move_to (pCairoContext, fDockOffsetY - sens * y * h, pArea->y);
 
735
                for (i = 0; i < iNbMidPoints+1; i ++)
 
736
                        cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
 
737
                cairo_rel_line_to (pCairoContext, sens * y_ * h, 0);
 
738
                cairo_rel_line_to (pCairoContext, 0, - pArea->height);
 
739
                cairo_rel_line_to (pCairoContext, - sens * y * h, 0);
 
740
        }
 
741
        //\____________________ On dessine les decorations dedans.
 
742
        fDockOffsetY = (pDock->bDirectionUp ? pDock->iCurrentHeight - pDock->iDecorationsHeight - fLineWidth : fLineWidth);
 
743
        cairo_dock_render_decorations_in_frame (pCairoContext, pDock, fDockOffsetY, fDockOffsetX, fDockWidth + 2 * curveOffsetX);
 
744
        
 
745
        //\____________________ On dessine le cadre.
 
746
        cairo_new_path (pCairoContext);
 
747
        if (fLineWidth > 0)
 
748
        {
 
749
                cairo_set_line_width (pCairoContext, fLineWidth);
 
750
                cairo_set_source_rgba (pCairoContext, myBackground.fLineColor[0], myBackground.fLineColor[1], myBackground.fLineColor[2], myBackground.fLineColor[3]);
 
751
                
 
752
                fDockOffsetY = (pDock->bDirectionUp ? pDock->iCurrentHeight - .5 * fLineWidth : .5 * fLineWidth);
 
753
                
 
754
                if (pDock->bHorizontalDock)
 
755
                {
 
756
                        cairo_move_to (pCairoContext, pArea->x, fDockOffsetY - sens * y * h);
 
757
                        for (i = 0; i < iNbMidPoints+1; i ++)
 
758
                                cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
 
759
                        cairo_stroke (pCairoContext);
 
760
                        
 
761
                        cairo_new_path (pCairoContext);
 
762
                        cairo_move_to (pCairoContext, pArea->x, fDockOffsetY);
 
763
                        cairo_rel_line_to (pCairoContext, pArea->width, 0);
 
764
                }
 
765
                else
 
766
                {
 
767
                        cairo_move_to (pCairoContext, fDockOffsetY - sens * y * h, pArea->y);
 
768
                        for (i = 0; i < iNbMidPoints+1; i ++)
 
769
                                cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
 
770
                        cairo_stroke (pCairoContext);
 
771
                        
 
772
                        cairo_new_path (pCairoContext);
 
773
                        cairo_move_to (pCairoContext, fDockOffsetY, pArea->y);
 
774
                        cairo_rel_line_to (pCairoContext, 0, pArea->height);
 
775
                }
 
776
                cairo_stroke (pCairoContext);
 
777
        }
 
778
        g_free (pMidPointCoord);
 
779
        
 
780
        cairo_restore (pCairoContext);
 
781
        
 
782
        /*double x = (fDockOffsetX - pFirstIcon->fX + curveOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
783
        double a = - 1. / 3;
 
784
        double b = (1 - my_fCurveCurvature) / 3 / (1 - 3 * my_fCurveCurvature);
 
785
        double c = - x / (1 - 3 * my_fCurveCurvature);
 
786
        double a_ = a*a - b;
 
787
        double b_ = a*b - c;
 
788
        double c_ = b*b - a*c;
 
789
        double u = (-b_ + sqrt (b_*b_ - 4 * a_ * c_)) / (2 * a_);
 
790
        double v = (-b_ - sqrt (b_*b_ - 4 * a_ * c_)) / (2 * a_);
 
791
        double lambda = - (a + u) / (a + v);
 
792
        double t = v + (u - v) / (1 + pow (lambda, 1./3));
 
793
        //g_print ("x : %.2f => t : %.2f\n", x, t);*/
 
794
        
 
795
        //\____________________ On dessine les icones impactees.
 
796
        GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
 
797
        if (pFirstDrawnElement != NULL)
 
798
        {
 
799
                double fXMin = (pDock->bHorizontalDock ? pArea->x : pArea->y), fXMax = (pDock->bHorizontalDock ? pArea->x + pArea->width : pArea->y + pArea->height);
 
800
                double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
 
801
                double fXLeft, fXRight;
 
802
                Icon *icon;
 
803
                GList *ic = pFirstDrawnElement;
 
804
                
 
805
                if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
806
                {
 
807
                        cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
 
808
                        do
 
809
                        {
 
810
                                icon = ic->data;
 
811
                                
 
812
                                if (CAIRO_DOCK_IS_SEPARATOR (icon) && icon->acFileName == NULL)
 
813
                                {
 
814
                                        if (_cd_separator_is_impacted (icon, pDock, fXMin, fXMax, TRUE, (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)))
 
815
                                        {
 
816
                                                cairo_save (pCairoContext);
 
817
                                                cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, TRUE);
 
818
                                                cairo_restore (pCairoContext);
 
819
                                        }
 
820
                                }
 
821
                                
 
822
                                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
823
                        } while (ic != pFirstDrawnElement);
 
824
                        
 
825
                        do
 
826
                        {
 
827
                                icon = ic->data;
 
828
                                if (! CAIRO_DOCK_IS_SEPARATOR (icon) || icon->acFileName != NULL)
 
829
                                {
 
830
                                        fXLeft = icon->fDrawX + icon->fScale + 1;
 
831
                                        fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1;
 
832
                                        
 
833
                                        if (fXLeft <= fXMax && floor (fXRight) > fXMin)
 
834
                                        {
 
835
                                                if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth)
 
836
                                                        icon->fAlpha = 1;
 
837
                                                else
 
838
                                                        icon->fAlpha = .25;
 
839
                                                
 
840
                                                cairo_save (pCairoContext);
 
841
                                                
 
842
                                                cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
 
843
                                                
 
844
                                                cairo_restore (pCairoContext);
 
845
                                        }
 
846
                                }
 
847
                                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
848
                        } while (ic != pFirstDrawnElement);
 
849
                        
 
850
                        if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
851
                        {
 
852
                                do
 
853
                                {
 
854
                                        icon = ic->data;
 
855
                                        
 
856
                                        if (CAIRO_DOCK_IS_SEPARATOR (icon) && icon->acFileName == NULL)
 
857
                                        {
 
858
                                                if (_cd_separator_is_impacted (icon, pDock, fXMin, fXMax, FALSE, (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)))
 
859
                                                {
 
860
                                                        cairo_save (pCairoContext);
 
861
                                                        cd_rendering_draw_3D_curve_separator (icon, pCairoContext, pDock, pDock->bHorizontalDock, FALSE);
 
862
                                                        cairo_restore (pCairoContext);
 
863
                                                }
 
864
                                        }
 
865
                                        
 
866
                                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
867
                                } while (ic != pFirstDrawnElement);
 
868
                        }
 
869
                }
 
870
                else
 
871
                {
 
872
                        do
 
873
                        {
 
874
                                icon = ic->data;
 
875
                                fXLeft = icon->fDrawX + icon->fScale + 1;
 
876
                                fXRight = icon->fDrawX + (icon->fWidth - 1) * icon->fScale * icon->fWidthFactor - 1;
 
877
                                
 
878
                                if (fXLeft <= fXMax && floor (fXRight) > fXMin)
 
879
                                {
 
880
                                        if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth)
 
881
                                                icon->fAlpha = 1;
 
882
                                        else
 
883
                                                icon->fAlpha = .25;
 
884
                                        
 
885
                                        cairo_save (pCairoContext);
 
886
                                        
 
887
                                        cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
 
888
                                        
 
889
                                        cairo_restore (pCairoContext);
 
890
                                }
 
891
                                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
892
                        } while (ic != pFirstDrawnElement);
 
893
                }
 
894
        }
 
895
}
 
896
 
 
897
 
 
898
Icon *cd_rendering_calculate_icons_curve (CairoDock *pDock)
 
899
{
 
900
        Icon *pPointedIcon = cairo_dock_apply_wave_effect (pDock);
 
901
        
 
902
        cairo_dock_check_if_mouse_inside_linear (pDock);
 
903
        
 
904
        //\____________________ On calcule les position/etirements/alpha des icones.
 
905
        double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
 
906
        double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
907
        double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
 
908
        double xi = xCurve (my_fCurveCurvature, ti);
 
909
        double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
 
910
        double curveOffsetX = fDockWidth * xi;  // pDock->iMaxDockWidth
 
911
        
 
912
        gint sens, fDockOffsetY;
 
913
        sens = pDock->bDirectionUp ? 1 : -1;
 
914
        double fReflectionOffsetY = (pDock->bDirectionUp ? -1 : 1) * myIcons.fReflectSize;
 
915
        // On va calculer une parabole pour approcher la courbe de bĆ©zier : 
 
916
        // Soient A: (xa,ya) B: (xb,yb) C: (xc,yc) trois points qui appartiennent Ć  la parabole. xa, xb et xc sont distincts.
 
917
        // P1(x)=(x-xb)(x-xc)
 
918
        // P2(x)=(x-xa)(x-xc)
 
919
        // P3(x)=(x-xa)(x-xb)
 
920
        // p(x)=k1p1(x)+k2p2(x)+k3p3(x).
 
921
        // avec k1=ya/((xa-xb)(xa-xc)) car p(xa)=ya p2(xa)=p3(xa)=0
 
922
        
 
923
        // on calcule donc k1, k2, k3 : 
 
924
        gdouble xa, xb, xc, ya, yb, yc, k1, k2, k3;
 
925
        if(pDock->icons  == NULL)
 
926
                return NULL;
 
927
        Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
 
928
        Icon *pLastIcon = cairo_dock_get_last_drawn_icon (pDock);
 
929
        xa = 0 ; // icone de gauche
 
930
        ya = 0;
 
931
        xc = pLastIcon->fX - pFirstIcon->fX;  // icone de droite
 
932
        yc = 0;
 
933
        xb = (xc-xa)/2;
 
934
        yb = -my_iCurveAmplitude;
 
935
        
 
936
        if (xa != xb && xa != xc && xb != xc)
 
937
        {
 
938
                k1 = ya/((xa-xb)*(xa-xc));
 
939
                k2 = yb/((xb-xa)*(xb-xc));
 
940
                k3 = yc/((xc-xa)*(xc-xb));
 
941
        }
 
942
        else
 
943
        {
 
944
                k1 = k2 = k3 = 0;
 
945
        }
 
946
        
 
947
        
 
948
        Icon* icon;
 
949
        GList* ic;
 
950
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
951
        {
 
952
                icon = ic->data;
 
953
                double x = icon->fX - pFirstIcon->fX;
 
954
                double y = k1*(x-xb)*(x-xc) + k2*(x-xa)*(x-xc) + k3*(x-xa)*(x-xb);
 
955
                
 
956
                icon->fDrawX = icon->fX;
 
957
                icon->fDrawY = icon->fY + sens * y;
 
958
                //g_print ("y : %.2f -> fDrawY = %.2f\n", y, icon->fDrawY);
 
959
                icon->fWidthFactor = 1.;
 
960
                icon->fHeightFactor = 1.;
 
961
                ///icon->fDeltaYReflection = 0.;
 
962
                icon->fOrientation = 0.;
 
963
                if (icon->fDrawX >= 0 && icon->fDrawX + icon->fWidth * icon->fScale <= pDock->iCurrentWidth)
 
964
                        icon->fAlpha = 1;
 
965
                else
 
966
                        icon->fAlpha = .25;
 
967
                //g_print ("fDrawX:%.2f / %d (%.2f)\n", icon->fDrawX, pDock->iCurrentWidth, icon->fAlpha);
 
968
        }
 
969
        
 
970
        cairo_dock_check_can_drop_linear (pDock);
 
971
        
 
972
        return pPointedIcon;
 
973
}
 
974
 
 
975
void cd_rendering_register_curve_renderer (const gchar *cRendererName)
 
976
{
 
977
        CairoDockRenderer *pRenderer = g_new0 (CairoDockRenderer, 1);
 
978
        pRenderer->cReadmeFilePath = g_strdup_printf ("%s/readme-curve-view", MY_APPLET_SHARE_DATA_DIR);
 
979
        pRenderer->cPreviewFilePath = g_strdup_printf ("%s/preview-curve.jpg", MY_APPLET_SHARE_DATA_DIR);
 
980
        pRenderer->calculate_max_dock_size = cd_rendering_calculate_max_dock_size_curve;
 
981
        pRenderer->calculate_icons = cd_rendering_calculate_icons_curve;
 
982
        pRenderer->render = cd_rendering_render_curve;
 
983
        pRenderer->render_optimized = cd_rendering_render_optimized_curve;
 
984
        pRenderer->render_opengl = cd_rendering_render_curve_opengl;
 
985
        pRenderer->set_subdock_position = cairo_dock_set_subdock_position_linear;
 
986
        pRenderer->bUseReflect = TRUE;
 
987
        pRenderer->bUseStencil = TRUE;
 
988
        pRenderer->cDisplayedName = D_ (cRendererName);
 
989
        
 
990
        cairo_dock_register_renderer (cRendererName, pRenderer);
 
991
}
 
992
 
 
993
 
 
994
static void cairo_dock_draw_curved_frame_horizontal (cairo_t *pCairoContext, double fFrameWidth, double fControlHeight, double fDockOffsetX, double fDockOffsetY, int sens)
 
995
{
 
996
        cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
 
997
        cairo_rel_curve_to (pCairoContext,
 
998
                (1 - my_fCurveCurvature) * fFrameWidth / 2, -sens * fControlHeight,
 
999
                (1 + my_fCurveCurvature) * fFrameWidth / 2, -sens * fControlHeight,
 
1000
                fFrameWidth, 0);
 
1001
        
 
1002
        // on trace la ligne du bas
 
1003
        cairo_rel_line_to (pCairoContext, -fFrameWidth, 0);
 
1004
}
 
1005
static void cairo_dock_draw_curved_frame_vertical (cairo_t *pCairoContext, double fFrameWidth, double fControlHeight, double fDockOffsetX, double fDockOffsetY, int sens)
 
1006
{
 
1007
       cairo_move_to (pCairoContext, fDockOffsetY, fDockOffsetX);
 
1008
        cairo_rel_curve_to (pCairoContext,
 
1009
                -sens * fControlHeight, (1 - my_fCurveCurvature) * fFrameWidth / 2,
 
1010
                -sens * fControlHeight, (1 + my_fCurveCurvature) * fFrameWidth / 2,
 
1011
                0, fFrameWidth);
 
1012
        
 
1013
        // on trace la ligne du bas
 
1014
        cairo_rel_line_to (pCairoContext, 0, - fFrameWidth);
 
1015
}
 
1016
void cairo_dock_draw_curved_frame (cairo_t *pCairoContext, double fFrameWidth, double fControlHeight, double fDockOffsetX, double fDockOffsetY, gboolean bHorizontal, int sens)
 
1017
{
 
1018
        if (bHorizontal)
 
1019
                cairo_dock_draw_curved_frame_horizontal (pCairoContext, fFrameWidth, fControlHeight, fDockOffsetX, fDockOffsetY, sens);
 
1020
        else
 
1021
                cairo_dock_draw_curved_frame_vertical (pCairoContext, fFrameWidth, fControlHeight, fDockOffsetX, fDockOffsetY, sens);
 
1022
}
 
1023
 
 
1024
 
 
1025
void cd_rendering_calculate_reference_curve (double alpha)
 
1026
{
 
1027
        if (s_pReferenceCurveS == NULL)
 
1028
        {
 
1029
                s_pReferenceCurveS = g_new (double, RENDERING_INTERPOLATION_NB_PTS+1);
 
1030
        }
 
1031
        
 
1032
        if (s_pReferenceCurveX == NULL)
 
1033
        {
 
1034
                s_pReferenceCurveX = g_new (double, RENDERING_INTERPOLATION_NB_PTS+1);
 
1035
        }
 
1036
        
 
1037
        if (s_pReferenceCurveY == NULL)
 
1038
        {
 
1039
                s_pReferenceCurveY = g_new (double, RENDERING_INTERPOLATION_NB_PTS+1);
 
1040
        }
 
1041
        
 
1042
        double s, x, y;
 
1043
        int i;
 
1044
        for (i = 0; i < RENDERING_INTERPOLATION_NB_PTS+1; i ++)
 
1045
        {
 
1046
                s = (double) i / RENDERING_INTERPOLATION_NB_PTS;
 
1047
                
 
1048
                s_pReferenceCurveS[i] = s;
 
1049
                s_pReferenceCurveX[i] = xCurve (my_fCurveCurvature, s);
 
1050
                s_pReferenceCurveY[i] = yCurve (s);
 
1051
        }
 
1052
}
 
1053
 
 
1054
double cd_rendering_interpol_curve_parameter (double x)
 
1055
{
 
1056
        return cd_rendering_interpol (x, s_pReferenceCurveX, s_pReferenceCurveS);
 
1057
}
 
1058
 
 
1059
double cd_rendering_interpol_curve_height (double x)
 
1060
{
 
1061
        return cd_rendering_interpol (x, s_pReferenceCurveX, s_pReferenceCurveY);
 
1062
}
 
1063
 
 
1064
 
 
1065
 
 
1066
 
 
1067
 
 
1068
 
 
1069
void cd_rendering_render_curve_opengl (CairoDock *pDock)
 
1070
{
 
1071
        //\____________________ On genere le cadre.
 
1072
        double fLineWidth = myBackground.iDockLineWidth;
 
1073
        double fMargin = myBackground.iFrameMargin;
 
1074
        double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
 
1075
        
 
1076
        double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
 
1077
        double hi = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
1078
        double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi / h, 0)));
 
1079
        double xi = xCurve (my_fCurveCurvature, ti);
 
1080
        double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
 
1081
        
 
1082
        double fFrameHeight = pDock->iDecorationsHeight + fLineWidth;
 
1083
        double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
 
1084
        Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
 
1085
        fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - curveOffsetX : fLineWidth / 2);
 
1086
        if ((pDock->bHorizontalDock && ! pDock->bDirectionUp) || (! pDock->bHorizontalDock && pDock->bDirectionUp))
 
1087
                fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
 
1088
        else
 
1089
                fDockOffsetY = pDock->iDecorationsHeight + 1.5 * fLineWidth;
 
1090
        if (! pDock->bHorizontalDock)
 
1091
                fDockOffsetX = pDock->iCurrentWidth - fDockOffsetX + 0;
 
1092
        else
 
1093
                fDockOffsetX = fDockOffsetX-0;
 
1094
        
 
1095
        int iNbVertex;
 
1096
        GLfloat *pVertexTab = cairo_dock_generate_curve_path (4./3, &iNbVertex);
 
1097
        
 
1098
        //\________________ On met en place le clipping.
 
1099
        glDisable (GL_DEPTH_TEST);
 
1100
        glEnable (GL_STENCIL_TEST);  // active le tampon 'stencil'.
 
1101
        glClear (GL_STENCIL_BUFFER_BIT);  // on le remplit de 0.
 
1102
        glStencilFunc (GL_ALWAYS, 1, 1);  // valeur de reference = 1, et on ecrira un 1 sans condition.
 
1103
        glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);  // on remplace tout ce qui est dedans.
 
1104
        glColorMask (FALSE, FALSE, FALSE, FALSE);  // desactive l'ecriture dans toutes les composantes du Tampon Chromatique.
 
1105
        
 
1106
        double fEpsilon = (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR ? 2. : 0);  // erreur d'arrondi quand tu nous tiens.
 
1107
        glPushMatrix ();
 
1108
        cairo_dock_draw_frame_background_opengl (0, fDockWidth+2*curveOffsetX, fFrameHeight+fLineWidth+fEpsilon, fDockOffsetX, fDockOffsetY+(fLineWidth+fEpsilon)/2, pVertexTab, iNbVertex, pDock->bHorizontalDock, pDock->bDirectionUp, pDock->fDecorationsOffsetX);  // le cadre est trace au milieu de la ligne, donc on augmente de l la hauteur (et donc de l/2 pixels la hauteur du cadre, car [-.5, .5]), et pour compenser on se translate de l/2.
 
1109
        glPopMatrix ();
 
1110
        
 
1111
        glColorMask (TRUE, TRUE, TRUE, TRUE);
 
1112
        glStencilFunc (GL_EQUAL, 1, 1); /* draw if ==1 */
 
1113
        glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);  // read only.
 
1114
        glDisable (GL_STENCIL_TEST);
 
1115
        
 
1116
        //\____________________ On dessine les decorations dedans.
 
1117
        glPushMatrix ();
 
1118
        cairo_dock_draw_frame_background_opengl (g_iBackgroundTexture, fDockWidth+2*curveOffsetX, fFrameHeight, fDockOffsetX, fDockOffsetY, pVertexTab, iNbVertex, pDock->bHorizontalDock, pDock->bDirectionUp, pDock->fDecorationsOffsetX);
 
1119
        
 
1120
        //\____________________ On dessine le cadre.
 
1121
        if (fLineWidth > 0)
 
1122
                cairo_dock_draw_current_path_opengl (fLineWidth, myBackground.fLineColor, iNbVertex);
 
1123
        
 
1124
        glPopMatrix ();
 
1125
        
 
1126
        //\____________________ On dessine la ficelle qui les joint.
 
1127
        if (myIcons.iStringLineWidth > 0)
 
1128
                cairo_dock_draw_string_opengl (pDock, myIcons.iStringLineWidth, FALSE, (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR));
 
1129
        
 
1130
        //\____________________ On dessine les icones et les etiquettes, en tenant compte de l'ordre pour dessiner celles en arriere-plan avant celles en avant-plan.
 
1131
        GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
 
1132
        if (pFirstDrawnElement == NULL)
 
1133
                return;
 
1134
        
 
1135
        double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
 
1136
        Icon *icon;
 
1137
        GList *ic = pFirstDrawnElement;
 
1138
        
 
1139
        if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR || my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
1140
        {
 
1141
                do
 
1142
                {
 
1143
                        icon = ic->data;
 
1144
                        
 
1145
                        if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
 
1146
                        {
 
1147
                                glEnable (GL_STENCIL_TEST);
 
1148
                                glStencilFunc (GL_EQUAL, 1, 1);
 
1149
                                glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
 
1150
                                
 
1151
                                glPushMatrix ();
 
1152
                                if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
 
1153
                                        cd_rendering_draw_flat_separator_opengl (icon, pDock);
 
1154
                                else
 
1155
                                        cd_rendering_draw_physical_separator_opengl (icon, pDock, TRUE, (ic->prev ? ic->prev->data : NULL), (ic->next ? ic->next : NULL));
 
1156
                                glPopMatrix ();
 
1157
                                
 
1158
                                glDisable (GL_STENCIL_TEST);
 
1159
                        }
 
1160
                        
 
1161
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
1162
                } while (ic != pFirstDrawnElement);
 
1163
                
 
1164
                do
 
1165
                {
 
1166
                        icon = ic->data;
 
1167
                        
 
1168
                        if (icon->acFileName != NULL || ! CAIRO_DOCK_IS_SEPARATOR (icon))
 
1169
                        {
 
1170
                                glPushMatrix ();
 
1171
                                cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
 
1172
                                glPopMatrix ();
 
1173
                        }
 
1174
                        
 
1175
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
1176
                } while (ic != pFirstDrawnElement);
 
1177
                
 
1178
                if (my_curve_iDrawSeparator3D == CD_PHYSICAL_SEPARATOR)
 
1179
                {
 
1180
                        do
 
1181
                        {
 
1182
                                icon = ic->data;
 
1183
                                
 
1184
                                if (icon->acFileName == NULL && CAIRO_DOCK_IS_SEPARATOR (icon))
 
1185
                                {
 
1186
                                        glEnable (GL_STENCIL_TEST);
 
1187
                                        glStencilFunc (GL_EQUAL, 1, 1);
 
1188
                                        glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
 
1189
                                        
 
1190
                                        glPushMatrix ();
 
1191
                                        cd_rendering_draw_physical_separator_opengl (icon, pDock, FALSE, (ic->prev ? ic->prev->data : NULL), (ic->next ? ic->next : NULL));
 
1192
                                        glPopMatrix ();
 
1193
                                        
 
1194
                                        glDisable (GL_STENCIL_TEST);
 
1195
                                }
 
1196
                                
 
1197
                                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
1198
                        } while (ic != pFirstDrawnElement);
 
1199
                }
 
1200
        }
 
1201
        else
 
1202
        {
 
1203
                do
 
1204
                {
 
1205
                        icon = ic->data;
 
1206
                        
 
1207
                        glPushMatrix ();
 
1208
                        cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
 
1209
                        glPopMatrix ();
 
1210
                        
 
1211
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
 
1212
                } while (ic != pFirstDrawnElement);
 
1213
        }
 
1214
}
 
1215
 
 
1216
 
 
1217
#define DELTA_ROUND_DEGREE 1
 
1218
#define RADIAN (G_PI / 180.0)  // Conversion Radian/Degres
 
1219
#define P(t,p,q,r,s) (1-t) * (1-t) * (1-t) * p + 3 * t * (1-t) * (1 - t) * q + 3 * t * t * (1-t) * r + t * t * t * s
 
1220
GLfloat *cairo_dock_generate_curve_path (double fRelativeControlHeight, int *iNbPoints)
 
1221
{
 
1222
        //static GLfloat pVertexTab[((180/DELTA_ROUND_DEGREE+1)+1)*3];
 
1223
        _cairo_dock_define_static_vertex_tab ((180/DELTA_ROUND_DEGREE+1)+1);
 
1224
        
 
1225
        double w = 1. / 2;
 
1226
        double h = 1. / 2;
 
1227
        double xp = -w, xq = - (1 - my_fCurveCurvature) * w, xr = - xq, xs = - xp;
 
1228
        double yp = 0., yq = fRelativeControlHeight, yr = yq, ys = yp;
 
1229
        
 
1230
        //g_print ("%s (%.2f)\n", __func__, yq);
 
1231
        int iPrecision = DELTA_ROUND_DEGREE;
 
1232
        int i=0, t;
 
1233
        for (t = 0; t <= 180; t += iPrecision, i++)
 
1234
        {
 
1235
                _cairo_dock_set_vertex_xy (i,
 
1236
                        P (t/180., xp, xq, xr, xs),
 
1237
                        P (t/180., yp, yq, yr, ys) - h);
 
1238
                //vx(i) = P (t/180., xp, xq, xr, xs);
 
1239
                //vy(i) = P (t/180., yp, yq, yr, ys) - h;
 
1240
        }
 
1241
        
 
1242
        // on trace la ligne du bas.
 
1243
        _cairo_dock_close_path (i);  // on boucle.
 
1244
        //vx(i) = vx(0);  // on boucle.
 
1245
        //vy(i) = vy(0);
 
1246
        
 
1247
        *iNbPoints = i+1;
 
1248
        _cairo_dock_return_vertex_tab ();
 
1249
}
 
1250
 
 
1251
 
 
1252
 
 
1253
 
 
1254
 
 
1255
 
 
1256
 
 
1257
 
 
1258
/*static void cd_rendering_draw_curve_flat_separator_opengl (Icon *icon, CairoDock *pDock)
 
1259
{
 
1260
        double fLineWidth = myBackground.iDockLineWidth;
 
1261
        double fMargin = myBackground.iFrameMargin;
 
1262
        double hi;
 
1263
        
 
1264
        Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
 
1265
        if (pPrevIcon == NULL)
 
1266
                pPrevIcon = icon;
 
1267
        Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
 
1268
        if (pNextIcon == NULL)
 
1269
                pNextIcon = icon;
 
1270
        
 
1271
        double fVanishingDistanceLeft, fVanishingDistanceRight;
 
1272
        double fDeltaInterIconLeft, fDeltaInterIconRight;
 
1273
        if (pDock->bDirectionUp)
 
1274
        {
 
1275
                hi = pDock->iCurrentHeight - (icon->fDrawY + icon->fHeight * icon->fScale);
 
1276
                fVanishingDistanceLeft = iVanishingPointY + pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale;
 
1277
                fVanishingDistanceRight = iVanishingPointY + pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale;
 
1278
                
 
1279
                fDeltaInterIconLeft = (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale) - (icon->fDrawY + icon->fHeight * icon->fScale);
 
1280
                fDeltaInterIconRight = (icon->fDrawY + icon->fHeight * icon->fScale) - (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale);
 
1281
        }
 
1282
        else
 
1283
        {
 
1284
                hi = icon->fDrawY;
 
1285
                fVanishingDistanceLeft = iVanishingPointY + pDock->iCurrentHeight - pPrevIcon->fDrawY;
 
1286
                fVanishingDistanceRight = iVanishingPointY + pDock->iCurrentHeight - pNextIcon->fDrawY;
 
1287
                
 
1288
                fDeltaInterIconLeft = (pPrevIcon->fDrawY) - (icon->fDrawY);
 
1289
                fDeltaInterIconRight = (icon->fDrawY) - (pNextIcon->fDrawY);
 
1290
        }
 
1291
        double fLeftInclination = (icon->fDrawX - pDock->iCurrentWidth / 2) / fVanishingDistanceLeft;
 
1292
        double fRightInclination = (icon->fDrawX + icon->fWidth * icon->fScale - pDock->iCurrentWidth / 2) / fVanishingDistanceRight;
 
1293
        
 
1294
        if (bBackGround || ! bIncludeEdges)  // pour s'arreter sur la courbe, on realise un clippage.
 
1295
        {
 
1296
                //\________________ On se ramene au cas du dessin optimise.
 
1297
                double x0, y0, xf, yf, w0, h0;
 
1298
                if (pDock->bDirectionUp)
 
1299
                {
 
1300
                        x0 = icon->fDrawX - MAX (0, fLeftInclination * (pPrevIcon->fDrawY + pPrevIcon->fHeight * pPrevIcon->fScale));
 
1301
                        xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pNextIcon->fDrawY + pNextIcon->fHeight * pNextIcon->fScale));
 
1302
                }
 
1303
                else
 
1304
                {
 
1305
                        x0 = icon->fDrawX - MAX (0, fLeftInclination * (pDock->iCurrentHeight - (pPrevIcon->fDrawY)));
 
1306
                        xf = icon->fDrawX + icon->fWidth * icon->fScale - MIN (0, fRightInclination * (pDock->iCurrentHeight - (pNextIcon->fDrawY)));
 
1307
                }
 
1308
                if (! bIncludeEdges)  // on prolonge jusqu'en bas.
 
1309
                {
 
1310
                        if (pDock->bDirectionUp)
 
1311
                        {
 
1312
                                x0 += MIN (0, fLeftInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
 
1313
                                xf += MAX (0, fRightInclination * (pDock->iCurrentHeight - icon->fDrawY - icon->fHeight * icon->fScale));
 
1314
                        }
 
1315
                        else
 
1316
                        {
 
1317
                                x0 += MIN (0, fLeftInclination * (pPrevIcon->fDrawY));
 
1318
                                xf += MAX (0, fRightInclination * (pNextIcon->fDrawY));
 
1319
                        }
 
1320
                }
 
1321
                //g_print ("x0:%.2f -> xf:%.2f\n", x0, xf);
 
1322
                y0 = 0;
 
1323
                yf = icon->fDrawY;
 
1324
                w0 = xf - x0;
 
1325
                h0 = yf - y0;
 
1326
                
 
1327
                int sens;
 
1328
                double fDockOffsetY;  // Offset du coin haut gauche du cadre.
 
1329
                if (pDock->bDirectionUp)
 
1330
                {
 
1331
                        sens = 1;
 
1332
                        fDockOffsetY = pDock->iCurrentHeight - .5 * fLineWidth;
 
1333
                }
 
1334
                else
 
1335
                {
 
1336
                        sens = -1;
 
1337
                        fDockOffsetY = .5 * fLineWidth;
 
1338
                }
 
1339
                
 
1340
                double fDockWidth = cairo_dock_get_current_dock_width_linear (pDock) - 2 * myBackground.iFrameMargin;
 
1341
                
 
1342
                double h = 4./3 * (pDock->iDecorationsHeight + myBackground.iDockLineWidth);
 
1343
                double hi_ = .5 * pDock->iMaxIconHeight + myBackground.iFrameMargin - 1;
 
1344
                double ti = .5 * (1. - sqrt (MAX (1. - 4./3 * hi_ / h, 0)));
 
1345
                double xi = xCurve (my_fCurveCurvature, ti);
 
1346
                double curveOffsetX = fDockWidth * xi / (1 - 2 * xi);
 
1347
                
 
1348
                Icon *pFirstIcon = cairo_dock_get_first_drawn_icon (pDock);
 
1349
                double fDockOffsetX = (pFirstIcon != NULL ? pFirstIcon->fX - curveOffsetX : fLineWidth / 2);
 
1350
                
 
1351
                
 
1352
                //\________________ On approche le morceau de courbe de Bezier par des trapezes.
 
1353
                double x = (x0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
1354
                double s = cd_rendering_interpol_curve_parameter (x);
 
1355
                double y = yCurve (s);
 
1356
                double x_ = (x0 + w0 - fDockOffsetX) / (fDockWidth + 2 * curveOffsetX);
 
1357
                double s_ = cd_rendering_interpol_curve_parameter (x_);
 
1358
                double y_ = yCurve (s_);
 
1359
                int i, iNbMidPoints = MAX (0, w0 / 20 - 1);  // nombre de points intermediaires a calculer.
 
1360
                double *pMidPointCoord = g_new (double, 2 * (iNbMidPoints+2));
 
1361
                pMidPointCoord[0] = x0 - fDockOffsetX;
 
1362
                pMidPointCoord[1] = y * h;
 
1363
                pMidPointCoord[2*(iNbMidPoints+1)] = x0 + w0 - fDockOffsetX;
 
1364
                pMidPointCoord[2*(iNbMidPoints+1)+1] = y_ * h;
 
1365
                double si=s, ds = (s_ - s) / (iNbMidPoints+1);
 
1366
                for (i = 1; i < iNbMidPoints+1; i ++)
 
1367
                {
 
1368
                        si += ds;
 
1369
                        pMidPointCoord[2*i] = (fDockWidth + 2 * curveOffsetX) * xCurve (my_fCurveCurvature, si);
 
1370
                        pMidPointCoord[2*i+1] = h * yCurve (si);
 
1371
                }
 
1372
                
 
1373
                cairo_set_line_cap (pCairoContext, CAIRO_LINE_CAP_BUTT);
 
1374
                cairo_save (pCairoContext);
 
1375
                double fDeltaLineWidth = 0.;
 
1376
                if (bIncludeEdges)
 
1377
                {
 
1378
                        double tan_theta = MAX (fabs (pMidPointCoord[1] - pMidPointCoord[3]) / (pMidPointCoord[2] - pMidPointCoord[0]), fabs (pMidPointCoord[2*iNbMidPoints+1] - pMidPointCoord[2*iNbMidPoints+3]) / (pMidPointCoord[2*iNbMidPoints+2] - pMidPointCoord[2*iNbMidPoints]));
 
1379
                        fDeltaLineWidth = (fLineWidth / 2 + .1) * sqrt (1. + tan_theta*tan_theta);
 
1380
                }
 
1381
                if (pDock->bHorizontalDock)
 
1382
                {
 
1383
                        cairo_move_to (pCairoContext, x0, fDockOffsetY - sens * (y * h + fDeltaLineWidth));
 
1384
                        for (i = 0; i < iNbMidPoints+1; i ++)
 
1385
                                cairo_rel_line_to (pCairoContext, pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i], sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]));
 
1386
                        cairo_rel_line_to (pCairoContext, 0, sens * (y_ * h + fDeltaLineWidth));
 
1387
                        cairo_rel_line_to (pCairoContext, - w0, 0);
 
1388
                        cairo_rel_line_to (pCairoContext, 0, - sens * (y * h + fDeltaLineWidth));
 
1389
                }
 
1390
                else
 
1391
                {
 
1392
                        cairo_move_to (pCairoContext, fDockOffsetY - sens * (y * h + fDeltaLineWidth), x0);
 
1393
                        for (i = 0; i < iNbMidPoints+1; i ++)
 
1394
                                cairo_rel_line_to (pCairoContext, sens * (pMidPointCoord[2*i+1] - pMidPointCoord[2*i+3]), pMidPointCoord[2*(i+1)] - pMidPointCoord[2*i]);
 
1395
                        cairo_rel_line_to (pCairoContext, sens * (y_ * h + fDeltaLineWidth), 0);
 
1396
                        cairo_rel_line_to (pCairoContext, 0, - w0);
 
1397
                        cairo_rel_line_to (pCairoContext, - sens * (y * h + fDeltaLineWidth), 0);
 
1398
                }
 
1399
                
 
1400
                g_free (pMidPointCoord);
 
1401
                cairo_clip (pCairoContext);
 
1402
        }
 
1403
        
 
1404
        
 
1405
        double fHeight, fBigWidth, fLittleWidth;
 
1406
        if (bIncludeEdges)
 
1407
        {
 
1408
                fHeight = (bBackGround ? pDock->iDecorationsHeight - hi : hi) + myBackground.iDockLineWidth;
 
1409
                fBigWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY : iVanishingPointY + fHeight);
 
1410
                fLittleWidth = fabs (fRightInclination - fLeftInclination) * (bBackGround ? iVanishingPointY - fHeight : iVanishingPointY);
 
1411
        }
 
1412
        else
 
1413
        {
 
1414
                fHeight = pDock->iDecorationsHeight - myBackground.iDockLineWidth;
 
1415
                fBigWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi);
 
1416
                fLittleWidth = fabs (fRightInclination - fLeftInclination) * (iVanishingPointY + hi - fHeight);
 
1417
        }
 
1418
        double fDeltaXLeft = fHeight * fLeftInclination;
 
1419
        double fDeltaXRight = fHeight * fRightInclination;
 
1420
        //g_print ("fBigWidth : %.2f ; fLittleWidth : %.2f\n", fBigWidth, fLittleWidth);
 
1421
        
 
1422
        int sens;
 
1423
        double fDockOffsetX, fDockOffsetY;
 
1424
        if (pDock->bDirectionUp)
 
1425
        {
 
1426
                sens = 1;
 
1427
                if (bIncludeEdges)
 
1428
                        fDockOffsetY = pDock->iCurrentHeight - fHeight - (bBackGround ? myBackground.iDockLineWidth + hi : 0);
 
1429
                else
 
1430
                        fDockOffsetY = pDock->iCurrentHeight - fHeight - myBackground.iDockLineWidth;
 
1431
        }
 
1432
        else
 
1433
        {
 
1434
                sens = -1;
 
1435
                if (bIncludeEdges)
 
1436
                        fDockOffsetY = fHeight + (bBackGround ? myBackground.iDockLineWidth + hi : 0);
 
1437
                else
 
1438
                        fDockOffsetY = fHeight + myBackground.iDockLineWidth;
 
1439
        }
 
1440
        
 
1441
        if (bIncludeEdges)
 
1442
                fDockOffsetX = icon->fDrawX - (bBackGround ? fHeight * fLeftInclination : 0);
 
1443
        else
 
1444
                fDockOffsetX = (pDock->bDirectionUp ? icon->fDrawX - (fHeight - hi) * fLeftInclination : icon->fDrawX - (fHeight - hi) * fLeftInclination);
 
1445
        fDockOffsetX -= fDeltaInterIconLeft * fLeftInclination*sens;
 
1446
        
 
1447
        if (pDock->bHorizontalDock)
 
1448
        {
 
1449
                cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY);  // coin haut gauche.
 
1450
                cairo_move_to (pCairoContext, 0, 0);  // coin haut gauche.
 
1451
                
 
1452
                cairo_rel_line_to (pCairoContext, fLittleWidth, 0);
 
1453
                cairo_rel_line_to (pCairoContext, fDeltaXRight, sens * fHeight);
 
1454
                cairo_rel_line_to (pCairoContext, - fBigWidth, 0);
 
1455
                cairo_rel_line_to (pCairoContext, - fDeltaXLeft, - sens * fHeight);
 
1456
                
 
1457
                if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
 
1458
                {
 
1459
                        if (! pDock->bDirectionUp)
 
1460
                                cairo_scale (pCairoContext, 1, -1);
 
1461
                        cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_HORIZONTAL], MIN (0, (fHeight + hi) * fLeftInclination), 0);
 
1462
                }
 
1463
        }
 
1464
        else
 
1465
        {
 
1466
                cairo_translate (pCairoContext, fDockOffsetY, fDockOffsetX);  // coin haut gauche.
 
1467
                cairo_move_to (pCairoContext, 0, 0);  // coin haut gauche.
 
1468
                
 
1469
                cairo_rel_line_to (pCairoContext, 0, fLittleWidth);
 
1470
                cairo_rel_line_to (pCairoContext, sens * fHeight, fDeltaXRight);
 
1471
                cairo_rel_line_to (pCairoContext, 0, - fBigWidth);
 
1472
                cairo_rel_line_to (pCairoContext, - sens * fHeight, - fDeltaXLeft);
 
1473
                
 
1474
                if (my_curve_iDrawSeparator3D == CD_FLAT_SEPARATOR)
 
1475
                {
 
1476
                        if (! pDock->bDirectionUp)
 
1477
                                cairo_scale (pCairoContext, -1, 1);
 
1478
                        cairo_set_source_surface (pCairoContext, my_pFlatSeparatorSurface[CAIRO_DOCK_VERTICAL], 0, MIN (0, (fHeight + hi) * fLeftInclination));
 
1479
                }
 
1480
        }
 
1481
}*/