~ubuntu-branches/ubuntu/oneiric/cairo-dock/oneiric

« back to all changes in this revision

Viewing changes to src/gldit/cairo-dock-draw.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: (18.1.1 cairo-dock) (19.1.1 cairo-dock)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

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
#include <math.h>
 
21
#include <string.h>
 
22
#include <stdlib.h>
 
23
#include <cairo.h>
 
24
#include <pango/pango.h>
 
25
#include <gtk/gtk.h>
 
26
 
 
27
#ifdef HAVE_GLITZ
 
28
#include <gdk/gdkx.h>
 
29
#include <glitz-glx.h>
 
30
#include <cairo-glitz.h>
 
31
#endif
 
32
 
 
33
#include "cairo-dock-icons.h"
 
34
#include "cairo-dock-dock-factory.h"
 
35
#include "cairo-dock-dock-facility.h"
 
36
#include "cairo-dock-callbacks.h"
 
37
#include "cairo-dock-animations.h"
 
38
#include "cairo-dock-log.h"
 
39
#include "cairo-dock-dock-manager.h"
 
40
#include "cairo-dock-applications-manager.h"
 
41
#include "cairo-dock-internal-system.h"
 
42
#include "cairo-dock-internal-taskbar.h"
 
43
#include "cairo-dock-internal-indicators.h"
 
44
#include "cairo-dock-internal-labels.h"
 
45
#include "cairo-dock-internal-icons.h"
 
46
#include "cairo-dock-internal-background.h"
 
47
#include "cairo-dock-internal-accessibility.h"
 
48
#include "cairo-dock-notifications.h"
 
49
#include "cairo-dock-backends-manager.h"
 
50
#include "cairo-dock-container.h"
 
51
#include "cairo-dock-load.h"
 
52
#include "cairo-dock-draw-opengl.h"  // pour cairo_dock_render_one_icon
 
53
#include "cairo-dock-draw.h"
 
54
 
 
55
extern CairoDockImageBuffer g_pIconBackgroundImageBuffer;
 
56
extern CairoDockImageBuffer g_pVisibleZoneBuffer;
 
57
 
 
58
extern CairoDockDesktopBackground *g_pFakeTransparencyDesktopBg;
 
59
extern gboolean g_bUseOpenGL;
 
60
 
 
61
 
 
62
cairo_t * cairo_dock_create_drawing_context_generic (CairoContainer *pContainer)
 
63
{
 
64
#ifdef HAVE_GLITZ
 
65
        if (pContainer->pGlitzDrawable)
 
66
        {
 
67
                //g_print ("creation d'un contexte lie a une surface glitz\n");
 
68
                glitz_surface_t* pGlitzSurface;
 
69
                cairo_surface_t* pCairoSurface;
 
70
                cairo_t* pCairoContext;
 
71
 
 
72
                pGlitzSurface = glitz_surface_create (pContainer->pGlitzDrawable,
 
73
                        pContainer->pGlitzFormat,
 
74
                        pContainer->iWidth,
 
75
                        pContainer->iHeight,
 
76
                        0,
 
77
                        NULL);
 
78
 
 
79
                if (pContainer->pDrawFormat->doublebuffer)
 
80
                        glitz_surface_attach (pGlitzSurface,
 
81
                                pContainer->pGlitzDrawable,
 
82
                                GLITZ_DRAWABLE_BUFFER_BACK_COLOR);
 
83
                else
 
84
                        glitz_surface_attach (pGlitzSurface,
 
85
                                pContainer->pGlitzDrawable,
 
86
                                GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
 
87
 
 
88
                pCairoSurface = cairo_glitz_surface_create (pGlitzSurface);
 
89
                pCairoContext = cairo_create (pCairoSurface);
 
90
 
 
91
                cairo_surface_destroy (pCairoSurface);
 
92
                glitz_surface_destroy (pGlitzSurface);
 
93
 
 
94
                return pCairoContext;
 
95
        }
 
96
#endif // HAVE_GLITZ
 
97
        return gdk_cairo_create (pContainer->pWidget->window);
 
98
}
 
99
 
 
100
cairo_t *cairo_dock_create_drawing_context_on_container (CairoContainer *pContainer)
 
101
{
 
102
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
 
103
        g_return_val_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS, FALSE);
 
104
        
 
105
        if (mySystem.bUseFakeTransparency)
 
106
        {
 
107
                if (g_pFakeTransparencyDesktopBg && g_pFakeTransparencyDesktopBg->pSurface)
 
108
                {
 
109
                        if (pContainer->bIsHorizontal)
 
110
                                cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionX, - pContainer->iWindowPositionY);
 
111
                        else
 
112
                                cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionY, - pContainer->iWindowPositionX);
 
113
                }
 
114
                else
 
115
                        cairo_set_source_rgba (pCairoContext, 0.8, 0.8, 0.8, 0.0);
 
116
        }
 
117
        else
 
118
                cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
 
119
        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
 
120
        cairo_paint (pCairoContext);
 
121
        
 
122
        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
 
123
        return pCairoContext;
 
124
}
 
125
 
 
126
cairo_t *cairo_dock_create_drawing_context_on_area (CairoContainer *pContainer, GdkRectangle *pArea, double *fBgColor)
 
127
{
 
128
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (pContainer);
 
129
        g_return_val_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS, pCairoContext);
 
130
        
 
131
        if (pArea != NULL && (pArea->x > 0 || pArea->y > 0))
 
132
        {
 
133
                cairo_rectangle (pCairoContext,
 
134
                        pArea->x,
 
135
                        pArea->y,
 
136
                        pArea->width,
 
137
                        pArea->height);
 
138
                cairo_clip (pCairoContext);
 
139
        }
 
140
        
 
141
        if (mySystem.bUseFakeTransparency)
 
142
        {
 
143
                if (g_pFakeTransparencyDesktopBg && g_pFakeTransparencyDesktopBg->pSurface)
 
144
                {
 
145
                        if (pContainer->bIsHorizontal)
 
146
                                cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionX, - pContainer->iWindowPositionY);
 
147
                        else
 
148
                                cairo_set_source_surface (pCairoContext, g_pFakeTransparencyDesktopBg->pSurface, - pContainer->iWindowPositionY, - pContainer->iWindowPositionX);
 
149
                }
 
150
                else
 
151
                        cairo_set_source_rgba (pCairoContext, 0.8, 0.8, 0.8, 0.0);
 
152
        }
 
153
        else if (fBgColor != NULL)
 
154
                cairo_set_source_rgba (pCairoContext, fBgColor[0], fBgColor[1], fBgColor[2], fBgColor[3]);
 
155
        else
 
156
                cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
 
157
        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
 
158
        cairo_paint (pCairoContext);
 
159
        
 
160
        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
 
161
        return pCairoContext;
 
162
}
 
163
 
 
164
 
 
165
 
 
166
 
 
167
double cairo_dock_calculate_extra_width_for_trapeze (double fFrameHeight, double fInclination, double fRadius, double fLineWidth)
 
168
{
 
169
        if (2 * fRadius > fFrameHeight + fLineWidth)
 
170
                fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
 
171
        double cosa = 1. / sqrt (1 + fInclination * fInclination);
 
172
        double sina = fInclination * cosa;
 
173
        
 
174
        double fExtraWidth = fInclination * (fFrameHeight - (FALSE ? 2 : 1-cosa) * fRadius) + fRadius * (FALSE ? 1 : sina);
 
175
        return (2 * fExtraWidth + fLineWidth);
 
176
        /**double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (myBackground.bRoundedBottomCorner ? 2 : 1) * fRadius);
 
177
        double fDeltaCornerForLoop = fRadius * cosa + (myBackground.bRoundedBottomCorner ? fRadius * (1 + sina) * fInclination : 0);
 
178
        
 
179
        return (2 * (fLineWidth/2 + fDeltaXForLoop + fDeltaCornerForLoop + myBackground.iFrameMargin));*/
 
180
}
 
181
 
 
182
void cairo_dock_draw_rounded_rectangle (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight)
 
183
{
 
184
        double fDockOffsetX = fRadius + fLineWidth/2;
 
185
        double fDockOffsetY = 0.;
 
186
        if (2*fRadius > fFrameHeight + fLineWidth)
 
187
                fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
 
188
        cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
 
189
        cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
 
190
        //\_________________ Coin haut droit.
 
191
        cairo_rel_curve_to (pCairoContext,
 
192
                0, 0,
 
193
                fRadius, 0,
 
194
                fRadius, fRadius);
 
195
        cairo_rel_line_to (pCairoContext, 0, (fFrameHeight + fLineWidth - fRadius * 2));
 
196
        //\_________________ Coin bas droit.
 
197
        cairo_rel_curve_to (pCairoContext,
 
198
                0, 0,
 
199
                0, fRadius,
 
200
                -fRadius, fRadius);
 
201
 
 
202
        cairo_rel_line_to (pCairoContext, - fFrameWidth, 0);
 
203
        //\_________________ Coin bas gauche.
 
204
        cairo_rel_curve_to (pCairoContext,
 
205
                0, 0,
 
206
                -fRadius, 0,
 
207
                -fRadius, - fRadius);
 
208
        cairo_rel_line_to (pCairoContext, 0, (- fFrameHeight - fLineWidth + fRadius * 2));
 
209
        //\_________________ Coin haut gauche.
 
210
        cairo_rel_curve_to (pCairoContext,
 
211
                0, 0,
 
212
                0, -fRadius,
 
213
                fRadius, -fRadius);
 
214
        if (fRadius < 1)
 
215
                cairo_close_path (pCairoContext);
 
216
}
 
217
 
 
218
static double cairo_dock_draw_frame_horizontal (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bRoundedBottomCorner)  // la largeur est donnee par rapport "au fond".
 
219
{
 
220
        if (2*fRadius > fFrameHeight + fLineWidth)
 
221
                fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
 
222
        double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (bRoundedBottomCorner ? 2 : 1) * fRadius);
 
223
        double cosa = 1. / sqrt (1 + fInclination * fInclination);
 
224
        double sina = cosa * fInclination;
 
225
 
 
226
        cairo_move_to (pCairoContext, fDockOffsetX, fDockOffsetY);
 
227
 
 
228
        cairo_rel_line_to (pCairoContext, fFrameWidth, 0);
 
229
        //\_________________ Coin haut droit.
 
230
        cairo_rel_curve_to (pCairoContext,
 
231
                0, 0,
 
232
                fRadius * (1. / cosa - fInclination), 0,
 
233
                fRadius * cosa, sens * fRadius * (1 - sina));
 
234
        cairo_rel_line_to (pCairoContext, fDeltaXForLoop, sens * (fFrameHeight + fLineWidth - fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)));
 
235
        //\_________________ Coin bas droit.
 
236
        if (bRoundedBottomCorner)
 
237
                cairo_rel_curve_to (pCairoContext,
 
238
                        0, 0,
 
239
                        fRadius * (1 + sina) * fInclination, sens * fRadius * (1 + sina),
 
240
                        -fRadius * cosa, sens * fRadius * (1 + sina));
 
241
 
 
242
        cairo_rel_line_to (pCairoContext, - fFrameWidth -  2 * fDeltaXForLoop - (bRoundedBottomCorner ? 0 : 2 * fRadius * cosa), 0);
 
243
        //\_________________ Coin bas gauche.
 
244
        if (bRoundedBottomCorner)
 
245
                cairo_rel_curve_to (pCairoContext,
 
246
                        0, 0,
 
247
                        -fRadius * (fInclination + 1. / cosa), 0,
 
248
                        -fRadius * cosa, -sens * fRadius * (1 + sina));
 
249
        cairo_rel_line_to (pCairoContext, fDeltaXForLoop, sens * (- fFrameHeight - fLineWidth + fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)));
 
250
        //\_________________ Coin haut gauche.
 
251
        cairo_rel_curve_to (pCairoContext,
 
252
                0, 0,
 
253
                fRadius * (1 - sina) * fInclination, -sens * fRadius * (1 - sina),
 
254
                fRadius * cosa, -sens * fRadius * (1 - sina));
 
255
        if (fRadius < 1)
 
256
                cairo_close_path (pCairoContext);
 
257
        //return fDeltaXForLoop + fRadius * cosa;
 
258
        return fInclination * (fFrameHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa);
 
259
}
 
260
static double cairo_dock_draw_frame_vertical (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bRoundedBottomCorner)
 
261
{
 
262
        if (2*fRadius > fFrameHeight + fLineWidth)
 
263
                fRadius = (fFrameHeight + fLineWidth) / 2 - 1;
 
264
        double fDeltaXForLoop = fInclination * (fFrameHeight + fLineWidth - (bRoundedBottomCorner ? 2 : 1) * fRadius);
 
265
        double cosa = 1. / sqrt (1 + fInclination * fInclination);
 
266
        double sina = cosa * fInclination;
 
267
 
 
268
        cairo_move_to (pCairoContext, fDockOffsetY, fDockOffsetX);
 
269
 
 
270
        cairo_rel_line_to (pCairoContext, 0, fFrameWidth);
 
271
        //\_________________ Coin haut droit.
 
272
        cairo_rel_curve_to (pCairoContext,
 
273
                0, 0,
 
274
                0, fRadius * (1. / cosa - fInclination),
 
275
                sens * fRadius * (1 - sina), fRadius * cosa);
 
276
        cairo_rel_line_to (pCairoContext, sens * (fFrameHeight + fLineWidth - fRadius * (bRoundedBottomCorner ? 2 : 1 - sina)), fDeltaXForLoop);
 
277
        //\_________________ Coin bas droit.
 
278
        if (bRoundedBottomCorner)
 
279
                cairo_rel_curve_to (pCairoContext,
 
280
                        0, 0,
 
281
                        sens * fRadius * (1 + sina), fRadius * (1 + sina) * fInclination,
 
282
                        sens * fRadius * (1 + sina), -fRadius * cosa);
 
283
 
 
284
        cairo_rel_line_to (pCairoContext, 0, - fFrameWidth -  2 * fDeltaXForLoop - (bRoundedBottomCorner ? 0 : 2 * fRadius * cosa));
 
285
        //\_________________ Coin bas gauche.
 
286
        if (bRoundedBottomCorner)
 
287
                cairo_rel_curve_to (pCairoContext,
 
288
                        0, 0,
 
289
                        0, -fRadius * (fInclination + 1. / cosa),
 
290
                        -sens * fRadius * (1 + sina), -fRadius * cosa);
 
291
        cairo_rel_line_to (pCairoContext, sens * (- fFrameHeight - fLineWidth + fRadius * (bRoundedBottomCorner ? 2 : 1)), fDeltaXForLoop);
 
292
        //\_________________ Coin haut gauche.
 
293
        cairo_rel_curve_to (pCairoContext,
 
294
                0, 0,
 
295
                -sens * fRadius * (1 - sina), fRadius * (1 - sina) * fInclination,
 
296
                -sens * fRadius * (1 - sina), fRadius * cosa);
 
297
        if (fRadius < 1)
 
298
                cairo_close_path (pCairoContext);
 
299
        //return fDeltaXForLoop + fRadius * cosa;
 
300
        return fInclination * (fFrameHeight - (FALSE ? 2 : 1-sina) * fRadius) + fRadius * (FALSE ? 1 : cosa);
 
301
}
 
302
double cairo_dock_draw_frame (cairo_t *pCairoContext, double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, int sens, double fInclination, gboolean bHorizontal, gboolean bRoundedBottomCorner)
 
303
{
 
304
        if (bHorizontal)
 
305
                return cairo_dock_draw_frame_horizontal (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclination, bRoundedBottomCorner);
 
306
        else
 
307
                return cairo_dock_draw_frame_vertical (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclination, bRoundedBottomCorner);
 
308
}
 
309
 
 
310
void cairo_dock_render_decorations_in_frame (cairo_t *pCairoContext, CairoDock *pDock, double fOffsetY, double fOffsetX, double fWidth)
 
311
{
 
312
        //g_print ("%.2f\n", pDock->fDecorationsOffsetX);
 
313
        if (pDock->backgroundBuffer.pSurface == NULL)
 
314
                return ;
 
315
        cairo_save (pCairoContext);
 
316
        
 
317
        if (pDock->container.bIsHorizontal)
 
318
        {
 
319
                cairo_translate (pCairoContext, /**pDock->fDecorationsOffsetX * myBackground.fDecorationSpeed */fOffsetX, fOffsetY);
 
320
                cairo_scale (pCairoContext, (double)fWidth / pDock->backgroundBuffer.iWidth, (double)pDock->iDecorationsHeight / pDock->backgroundBuffer.iHeight);  // pDock->container.iWidth
 
321
        }
 
322
        else
 
323
        {
 
324
                cairo_translate (pCairoContext, fOffsetY, /**pDock->fDecorationsOffsetX * myBackground.fDecorationSpeed + */fOffsetX);
 
325
                cairo_scale (pCairoContext, (double)pDock->iDecorationsHeight / pDock->backgroundBuffer.iHeight, (double)fWidth / pDock->backgroundBuffer.iWidth);
 
326
        }
 
327
        
 
328
        cairo_dock_draw_surface (pCairoContext, pDock->backgroundBuffer.pSurface, pDock->backgroundBuffer.iWidth, pDock->backgroundBuffer.iHeight, pDock->container.bDirectionUp, pDock->container.bIsHorizontal, -1.);  // -1 <=> fill_preserve
 
329
        
 
330
        cairo_restore (pCairoContext);
 
331
}
 
332
 
 
333
 
 
334
void cairo_dock_set_icon_scale_on_context (cairo_t *pCairoContext, Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
 
335
{
 
336
        if (bIsHorizontal)
 
337
        {
 
338
                if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
 
339
                {
 
340
                        cairo_translate (pCairoContext,
 
341
                                1 * icon->fWidthFactor * icon->fWidth * (icon->fScale - 1) / 2,
 
342
                                (bDirectionUp ? 1 * icon->fHeightFactor * icon->fHeight * (icon->fScale - 1) : 0));
 
343
                        cairo_scale (pCairoContext,
 
344
                                fRatio * icon->fWidthFactor / (1 + myIcons.fAmplitude),
 
345
                                fRatio * icon->fHeightFactor / (1 + myIcons.fAmplitude));
 
346
                }
 
347
                else
 
348
                        cairo_scale (pCairoContext,
 
349
                                fRatio * icon->fWidthFactor * icon->fScale / (1 + myIcons.fAmplitude) * icon->fGlideScale,
 
350
                                fRatio * icon->fHeightFactor * icon->fScale / (1 + myIcons.fAmplitude) * icon->fGlideScale);
 
351
        }
 
352
        else
 
353
        {
 
354
                if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
 
355
                {
 
356
                        cairo_translate (pCairoContext,
 
357
                                1 * icon->fHeightFactor * icon->fHeight * (icon->fScale - 1) / 2,
 
358
                                (bDirectionUp ? 1 * icon->fWidthFactor * icon->fWidth * (icon->fScale - 1) : 0));
 
359
                        cairo_scale (pCairoContext,
 
360
                                fRatio * icon->fHeightFactor / (1 + myIcons.fAmplitude),
 
361
                                fRatio * icon->fWidthFactor / (1 + myIcons.fAmplitude));
 
362
                }
 
363
                else
 
364
                        cairo_scale (pCairoContext,
 
365
                                fRatio * icon->fHeightFactor * icon->fScale / (1 + myIcons.fAmplitude) * icon->fGlideScale,
 
366
                                fRatio * icon->fWidthFactor * icon->fScale / (1 + myIcons.fAmplitude) * icon->fGlideScale);
 
367
                
 
368
        }
 
369
}
 
370
 
 
371
 
 
372
void cairo_dock_draw_icon_cairo (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext)
 
373
{
 
374
        double fRatio = pDock->container.fRatio;
 
375
        //\_____________________ On dessine l'icone.
 
376
        if (icon->pIconBuffer != NULL)
 
377
        {
 
378
                cairo_save (pCairoContext);
 
379
                
 
380
                cairo_dock_set_icon_scale_on_context (pCairoContext, icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
 
381
                cairo_set_source_surface (pCairoContext, icon->pIconBuffer, 0.0, 0.0);
 
382
                if (icon->fAlpha == 1)
 
383
                        cairo_paint (pCairoContext);
 
384
                else
 
385
                        cairo_paint_with_alpha (pCairoContext, icon->fAlpha);
 
386
 
 
387
                cairo_restore (pCairoContext);
 
388
        }
 
389
        //\_____________________ On dessine son reflet.
 
390
        if (pDock->container.bUseReflect && icon->pReflectionBuffer != NULL)  // on dessine les reflets.
 
391
        {
 
392
                cairo_save (pCairoContext);
 
393
                
 
394
                if (pDock->container.bIsHorizontal)
 
395
                {
 
396
                        if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
 
397
                                cairo_translate (pCairoContext, 0, (pDock->container.bDirectionUp ? icon->fDeltaYReflection + icon->fHeight : -icon->fDeltaYReflection - myIcons.fReflectSize * fRatio));
 
398
                        else
 
399
                                cairo_translate (pCairoContext, 0, (pDock->container.bDirectionUp ? icon->fDeltaYReflection + icon->fHeight * icon->fScale : -icon->fDeltaYReflection - myIcons.fReflectSize * icon->fScale * fRatio));
 
400
                }
 
401
                else
 
402
                {
 
403
                        if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
 
404
                                cairo_translate (pCairoContext, (pDock->container.bDirectionUp ? icon->fDeltaYReflection + icon->fHeight : -icon->fDeltaYReflection - myIcons.fReflectSize * fRatio), 0);
 
405
                        else
 
406
                                cairo_translate (pCairoContext, (pDock->container.bDirectionUp ? icon->fDeltaYReflection + icon->fHeight * icon->fScale : -icon->fDeltaYReflection - myIcons.fReflectSize * icon->fScale * fRatio), 0);
 
407
                }
 
408
                cairo_dock_set_icon_scale_on_context (pCairoContext, icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
 
409
                
 
410
                cairo_set_source_surface (pCairoContext, icon->pReflectionBuffer, 0.0, 0.0);
 
411
                
 
412
                if (mySystem.bDynamicReflection && icon->fScale > 1)  // on applique la surface avec un degrade en transparence, ou avec une transparence simple.
 
413
                {
 
414
                        cairo_pattern_t *pGradationPattern;
 
415
                        if (pDock->container.bIsHorizontal)
 
416
                        {
 
417
                                pGradationPattern = cairo_pattern_create_linear (0.,
 
418
                                        (pDock->container.bDirectionUp ? 0. : myIcons.fReflectSize / fRatio * (1 + myIcons.fAmplitude)),
 
419
                                        0.,
 
420
                                        (pDock->container.bDirectionUp ? myIcons.fReflectSize / fRatio * (1 + myIcons.fAmplitude) / icon->fScale : myIcons.fReflectSize / fRatio * (1 + myIcons.fAmplitude) * (1. - 1./ icon->fScale)));  // de haut en bas.
 
421
                                g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
 
422
                                
 
423
                                cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
 
424
                                cairo_pattern_add_color_stop_rgba (pGradationPattern,
 
425
                                        0.,
 
426
                                        0.,
 
427
                                        0.,
 
428
                                        0.,
 
429
                                        1.);
 
430
                                cairo_pattern_add_color_stop_rgba (pGradationPattern,
 
431
                                        1.,
 
432
                                        0.,
 
433
                                        0.,
 
434
                                        0.,
 
435
                                        1 - (icon->fScale - 1) / myIcons.fAmplitude);  // astuce pour ne pas avoir a re-creer la surface de la reflection.
 
436
                        }
 
437
                        else
 
438
                        {
 
439
                                pGradationPattern = cairo_pattern_create_linear ((pDock->container.bDirectionUp ? 0. : myIcons.fReflectSize / fRatio * (1 + myIcons.fAmplitude)),
 
440
                                        0.,
 
441
                                        (pDock->container.bDirectionUp ? myIcons.fReflectSize / fRatio * (1 + myIcons.fAmplitude) / icon->fScale : myIcons.fReflectSize / fRatio * (1 + myIcons.fAmplitude) * (1. - 1./ icon->fScale)),
 
442
                                        0.);
 
443
                                g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
 
444
                                
 
445
                                cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
 
446
                                cairo_pattern_add_color_stop_rgba (pGradationPattern,
 
447
                                        0.,
 
448
                                        0.,
 
449
                                        0.,
 
450
                                        0.,
 
451
                                        1.);
 
452
                                cairo_pattern_add_color_stop_rgba (pGradationPattern,
 
453
                                        1.,
 
454
                                        0.,
 
455
                                        0.,
 
456
                                        0.,
 
457
                                        1. - (icon->fScale - 1) / myIcons.fAmplitude);  // astuce pour ne pas avoir a re-creer la surface de la reflection.
 
458
                        }
 
459
                        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
 
460
                        cairo_translate (pCairoContext, 0, 0);
 
461
                        cairo_mask (pCairoContext, pGradationPattern);
 
462
 
 
463
                        cairo_pattern_destroy (pGradationPattern);
 
464
                }
 
465
                else
 
466
                {
 
467
                        if (icon->fAlpha == 1)
 
468
                                cairo_paint (pCairoContext);
 
469
                        else
 
470
                                cairo_paint_with_alpha (pCairoContext, icon->fAlpha);
 
471
                }
 
472
                cairo_restore (pCairoContext);
 
473
        }
 
474
}
 
475
 
 
476
gboolean cairo_dock_render_icon_notification (gpointer pUserData, Icon *icon, CairoDock *pDock, gboolean *bHasBeenRendered, cairo_t *pCairoContext)
 
477
{
 
478
        if (*bHasBeenRendered)
 
479
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
480
        if (pCairoContext != NULL)
 
481
        {
 
482
                if (icon->pIconBuffer != NULL)
 
483
                {
 
484
                        cairo_dock_draw_icon_cairo (icon, pDock, pCairoContext);
 
485
                }
 
486
        }
 
487
        else
 
488
        {
 
489
                if (icon->iIconTexture != 0)
 
490
                {
 
491
                        cairo_dock_draw_icon_opengl (icon, pDock);
 
492
                }
 
493
        }
 
494
        
 
495
        *bHasBeenRendered = TRUE;
 
496
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
497
}
 
498
 
 
499
void cairo_dock_render_one_icon (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext, double fDockMagnitude, gboolean bUseText)
 
500
{
 
501
        int iWidth = pDock->container.iWidth;
 
502
        double fRatio = pDock->container.fRatio;
 
503
        gboolean bDirectionUp = pDock->container.bDirectionUp;
 
504
        gboolean bIsHorizontal = pDock->container.bIsHorizontal;
 
505
        
 
506
        if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.fVisibleAppliAlpha != 0 && ! CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon) && !(icon->iBackingPixmap != 0 && icon->bIsHidden))
 
507
        {
 
508
                double fAlpha = (icon->bIsHidden ? MIN (1 - myTaskBar.fVisibleAppliAlpha, 1) : MIN (myTaskBar.fVisibleAppliAlpha + 1, 1));
 
509
                if (fAlpha != 1)
 
510
                        icon->fAlpha = fAlpha;  // astuce bidon pour pas multiplier 2 fois.
 
511
                /**if (icon->bIsHidden)
 
512
                        icon->fAlpha *= MIN (1 - myTaskBar.fVisibleAppliAlpha, 1);
 
513
                else
 
514
                        icon->fAlpha *= MIN (myTaskBar.fVisibleAppliAlpha + 1, 1);*/
 
515
                //g_print ("fVisibleAppliAlpha : %.2f & %d => %.2f\n", myTaskBar.fVisibleAppliAlpha, icon->bIsHidden, icon->fAlpha);
 
516
        }
 
517
        
 
518
        //\_____________________ On se place sur l'icone.
 
519
        double fGlideScale;
 
520
        if (icon->fGlideOffset != 0 && (! myIcons.bConstantSeparatorSize || ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon)))
 
521
        {
 
522
                double fPhase =  icon->fPhase + icon->fGlideOffset * icon->fWidth / fRatio / myIcons.iSinusoidWidth * G_PI;
 
523
                if (fPhase < 0)
 
524
                {
 
525
                        fPhase = 0;
 
526
                }
 
527
                else if (fPhase > G_PI)
 
528
                {
 
529
                        fPhase = G_PI;
 
530
                }
 
531
                fGlideScale = (1 + fDockMagnitude * pDock->fMagnitudeMax * myIcons.fAmplitude * sin (fPhase)) / icon->fScale;  // c'est un peu hacky ... il faudrait passer l'icone precedente en parametre ...
 
532
                if (bDirectionUp)
 
533
                {
 
534
                        if (bIsHorizontal)
 
535
                                cairo_translate (pCairoContext, 0., (1-fGlideScale)*icon->fHeight*icon->fScale);
 
536
                        else
 
537
                                cairo_translate (pCairoContext, (1-fGlideScale)*icon->fHeight*icon->fScale, 0.);
 
538
                }
 
539
        }
 
540
        else
 
541
                fGlideScale = 1;
 
542
        icon->fGlideScale = fGlideScale;
 
543
        
 
544
        if (bIsHorizontal)
 
545
                cairo_translate (pCairoContext, icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1), icon->fDrawY);
 
546
        else
 
547
                cairo_translate (pCairoContext, icon->fDrawY, icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1));
 
548
        
 
549
        cairo_save (pCairoContext);
 
550
        
 
551
        //\_____________________ On positionne l'icone.
 
552
        if (icon->fOrientation != 0)
 
553
                cairo_rotate (pCairoContext, icon->fOrientation);
 
554
        
 
555
        //\_____________________ On dessine l'icone.
 
556
        gboolean bIconHasBeenDrawn = FALSE;
 
557
        cairo_dock_notify (CAIRO_DOCK_PRE_RENDER_ICON, icon, pDock, pCairoContext);
 
558
        cairo_dock_notify (CAIRO_DOCK_RENDER_ICON, icon, pDock, &bIconHasBeenDrawn, pCairoContext);
 
559
        
 
560
        cairo_restore (pCairoContext);  // retour juste apres la translation (fDrawX, fDrawY).
 
561
        
 
562
        //\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
 
563
        if (bUseText && icon->pTextBuffer != NULL && (icon->fScale > 1.01 || myIcons.fAmplitude == 0 || pDock->fMagnitudeMax == 0) && (! myLabels.bLabelForPointedIconOnly || icon->bPointed))  // 1.01 car sin(pi) = 1+epsilon :-/  //  && icon->iAnimationState < CAIRO_DOCK_STATE_CLICKED
 
564
        {
 
565
                cairo_save (pCairoContext);
 
566
                
 
567
                cairo_identity_matrix (pCairoContext);  // on positionne les etiquettes sur un pixels entier, sinon ca floute.
 
568
                if (bIsHorizontal)
 
569
                        cairo_translate (pCairoContext, floor (icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1)), floor (icon->fDrawY));
 
570
                else
 
571
                        cairo_translate (pCairoContext, floor (icon->fDrawY), floor (icon->fDrawX + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1)));
 
572
                
 
573
                double fOffsetX = (/**icon->fWidthFactor * */icon->fWidth * icon->fScale - icon->iTextWidth) / 2;
 
574
                if (fOffsetX < - icon->fDrawX)
 
575
                        fOffsetX = - icon->fDrawX;
 
576
                else if (icon->fDrawX + fOffsetX + icon->iTextWidth > iWidth)
 
577
                        fOffsetX = iWidth - icon->iTextWidth - icon->fDrawX;
 
578
                
 
579
                if (icon->fOrientation != 0 && ! mySystem.bTextAlwaysHorizontal)
 
580
                        cairo_rotate (pCairoContext, icon->fOrientation);
 
581
                
 
582
                if (! bIsHorizontal && mySystem.bTextAlwaysHorizontal)
 
583
                {
 
584
                        if (fOffsetX < - icon->fDrawY)
 
585
                                fOffsetX = - icon->fDrawY;
 
586
                        cairo_set_source_surface (pCairoContext,
 
587
                                icon->pTextBuffer,
 
588
                                /**floor ((pDock->container.bDirectionUp ? -myLabels.iLabelSize : - (pDock->container.bUseReflect ? myIcons.fReflectSize : 0.)) - myLabels.iconTextDescription.iMargin + 1),*/
 
589
                                floor (fOffsetX),
 
590
                                0.);
 
591
                }
 
592
                else if (bIsHorizontal)
 
593
                        cairo_set_source_surface (pCairoContext,
 
594
                                icon->pTextBuffer,
 
595
                                floor (fOffsetX),
 
596
                                floor (bDirectionUp ? -myLabels.iLabelSize : icon->fHeight * icon->fScale/* - icon->fTextYOffset*/));
 
597
                else
 
598
                {
 
599
                        cairo_translate (pCairoContext, icon->iTextWidth/2, icon->iTextHeight/2);
 
600
                        cairo_rotate (pCairoContext, bDirectionUp ? - G_PI/2 : G_PI/2);
 
601
                        cairo_translate (pCairoContext, -icon->iTextWidth/2, -icon->iTextHeight/2);
 
602
                        cairo_set_source_surface (pCairoContext,
 
603
                                icon->pTextBuffer,
 
604
                                floor (bDirectionUp ? -myLabels.iLabelSize : icon->fHeight * icon->fScale/* - icon->fTextYOffset*/),
 
605
                                floor (fOffsetX));
 
606
                }
 
607
                double fMagnitude;
 
608
                if (myLabels.bLabelForPointedIconOnly || pDock->fMagnitudeMax == 0.)
 
609
                {
 
610
                        fMagnitude = fDockMagnitude;  // (icon->fScale - 1) / myIcons.fAmplitude / sin (icon->fPhase);  // sin (phi ) != 0 puisque fScale > 1.
 
611
                }
 
612
                else
 
613
                {
 
614
                        fMagnitude = (icon->fScale - 1) / myIcons.fAmplitude;  /// il faudrait diviser par pDock->fMagnitudeMax ...
 
615
                        fMagnitude = pow (fMagnitude, mySystem.fLabelAlphaThreshold);
 
616
                        ///fMagnitude *= (fMagnitude * mySystem.fLabelAlphaThreshold + 1) / (mySystem.fLabelAlphaThreshold + 1);
 
617
                }
 
618
                if (fMagnitude > .1)
 
619
                        cairo_paint_with_alpha (pCairoContext, fMagnitude);
 
620
                cairo_restore (pCairoContext);  // retour juste apres la translation (fDrawX, fDrawY).
 
621
        }
 
622
        
 
623
        //\_____________________ On dessine les infos additionnelles.
 
624
        if (icon->pQuickInfoBuffer != NULL)
 
625
        {
 
626
                cairo_translate (pCairoContext,
 
627
                        (- icon->iQuickInfoWidth * fRatio + icon->fWidthFactor * icon->fWidth) / 2 * icon->fScale,
 
628
                        (icon->fHeight - icon->iQuickInfoHeight * fRatio) * icon->fScale);
 
629
                
 
630
                cairo_scale (pCairoContext,
 
631
                        fRatio * icon->fScale / (1 + myIcons.fAmplitude) * 1,
 
632
                        fRatio * icon->fScale / (1 + myIcons.fAmplitude) * 1);
 
633
                
 
634
                cairo_set_source_surface (pCairoContext,
 
635
                        icon->pQuickInfoBuffer,
 
636
                        0,
 
637
                        0);
 
638
                if (icon->fAlpha == 1)
 
639
                        cairo_paint (pCairoContext);
 
640
                else
 
641
                        cairo_paint_with_alpha (pCairoContext, icon->fAlpha);
 
642
        }
 
643
}
 
644
 
 
645
 
 
646
void cairo_dock_render_one_icon_in_desklet (Icon *icon, cairo_t *pCairoContext, gboolean bUseReflect, gboolean bUseText, int iWidth)
 
647
{
 
648
        //\_____________________ On dessine l'icone en fonction de son placement, son angle, et sa transparence.
 
649
        //g_print ("%s (%.2f;%.2f x %.2f)\n", __func__, icon->fDrawX, icon->fDrawY, icon->fScale);
 
650
        cairo_translate (pCairoContext, icon->fDrawX, icon->fDrawY);
 
651
        cairo_save (pCairoContext);
 
652
        cairo_scale (pCairoContext, icon->fWidthFactor * icon->fScale, icon->fHeightFactor * icon->fScale);
 
653
        if (icon->fOrientation != 0)
 
654
                cairo_rotate (pCairoContext, icon->fOrientation);
 
655
        
 
656
        double fAlpha = icon->fAlpha;
 
657
        
 
658
        if (bUseReflect && icon->pReflectionBuffer != NULL)  // on dessine les reflets.
 
659
        {
 
660
                if (icon->pIconBuffer != NULL)
 
661
                        cairo_set_source_surface (pCairoContext, icon->pIconBuffer, 0.0, 0.0);
 
662
                if (fAlpha == 1)
 
663
                        cairo_paint (pCairoContext);
 
664
                else
 
665
                        cairo_paint_with_alpha (pCairoContext, fAlpha);
 
666
 
 
667
                cairo_restore (pCairoContext);  // retour juste apres la translation (fDrawX, fDrawY).
 
668
 
 
669
                cairo_save (pCairoContext);
 
670
                cairo_translate (pCairoContext, 0, - icon->fDeltaYReflection + icon->fHeight * icon->fScale);
 
671
                cairo_scale (pCairoContext, icon->fWidthFactor * icon->fScale, icon->fHeightFactor * icon->fScale);
 
672
                
 
673
                cairo_set_source_surface (pCairoContext, icon->pReflectionBuffer, 0.0, 0.0);
 
674
                
 
675
                if (mySystem.bDynamicReflection && icon->fScale != 1)
 
676
                {
 
677
                        cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0.,
 
678
                                0.,
 
679
                                0.,
 
680
                                myIcons.fReflectSize / icon->fScale);  // de haut en bas.
 
681
                        g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
 
682
                        
 
683
                        cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
 
684
                        cairo_pattern_add_color_stop_rgba (pGradationPattern,
 
685
                                0.,
 
686
                                0.,
 
687
                                0.,
 
688
                                0.,
 
689
                                1.);  // astuce pour ne pas avoir a re-creer la surface de la reflection.
 
690
                        cairo_pattern_add_color_stop_rgba (pGradationPattern,
 
691
                                1.,
 
692
                                0.,
 
693
                                0.,
 
694
                                0.,
 
695
                                0.);
 
696
                        
 
697
                        cairo_save (pCairoContext);
 
698
                        cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
 
699
                        cairo_translate (pCairoContext, 0, 0);
 
700
                        cairo_mask (pCairoContext, pGradationPattern);
 
701
                        cairo_restore (pCairoContext);
 
702
                        
 
703
                        cairo_pattern_destroy (pGradationPattern);
 
704
                }
 
705
                else
 
706
                {
 
707
                        if (fAlpha == 1)
 
708
                                cairo_paint (pCairoContext);
 
709
                        else
 
710
                                cairo_paint_with_alpha (pCairoContext, fAlpha);
 
711
                }
 
712
        }
 
713
        else  // on dessine l'icone tout simplement.
 
714
        {
 
715
                if (icon->pIconBuffer != NULL)
 
716
                        cairo_set_source_surface (pCairoContext, icon->pIconBuffer, 0.0, 0.0);
 
717
                if (fAlpha == 1)
 
718
                        cairo_paint (pCairoContext);
 
719
                else
 
720
                        cairo_paint_with_alpha (pCairoContext, fAlpha);
 
721
        }
 
722
        
 
723
        cairo_restore (pCairoContext);  // retour juste apres la translation (fDrawX, fDrawY).
 
724
        
 
725
        //\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
 
726
        if (bUseText && icon->pTextBuffer != NULL)
 
727
        {
 
728
                cairo_save (pCairoContext);
 
729
                double fOffsetX = (icon->fWidthFactor * icon->fWidth * icon->fScale - icon->iTextWidth) / 2;
 
730
                if (fOffsetX < - icon->fDrawX)
 
731
                        fOffsetX = - icon->fDrawX;
 
732
                else if (icon->fDrawX + fOffsetX + icon->iTextWidth > iWidth)
 
733
                        fOffsetX = iWidth - icon->iTextWidth - icon->fDrawX;
 
734
                if (icon->fOrientation != 0)
 
735
                {
 
736
                        cairo_rotate (pCairoContext, icon->fOrientation);
 
737
                }
 
738
                cairo_set_source_surface (pCairoContext,
 
739
                        icon->pTextBuffer,
 
740
                        fOffsetX,
 
741
                        -myLabels.iLabelSize);
 
742
                cairo_paint (pCairoContext);
 
743
                cairo_restore (pCairoContext);  // retour juste apres la translation (fDrawX, fDrawY).
 
744
        }
 
745
        
 
746
        ///if (icon->bHasIndicator)
 
747
        ///     _cairo_dock_draw_appli_indicator (icon, pCairoContext, TRUE, 1., TRUE);
 
748
        
 
749
        //\_____________________ On dessine les infos additionnelles.
 
750
        if (icon->pQuickInfoBuffer != NULL)
 
751
        {
 
752
                cairo_translate (pCairoContext,
 
753
                        //-icon->fQuickInfoXOffset + icon->fWidth / 2,
 
754
                        //icon->fHeight - icon->fQuickInfoYOffset);
 
755
                        (- icon->iQuickInfoWidth + icon->fWidth) / 2 * icon->fScale,
 
756
                        (icon->fHeight - icon->iQuickInfoHeight) * icon->fScale);
 
757
                
 
758
                cairo_scale (pCairoContext,
 
759
                        icon->fScale,
 
760
                        icon->fScale);
 
761
                
 
762
                cairo_set_source_surface (pCairoContext,
 
763
                        icon->pQuickInfoBuffer,
 
764
                        0,
 
765
                        0);
 
766
                cairo_paint (pCairoContext);
 
767
        }
 
768
}
 
769
 
 
770
 
 
771
 
 
772
void cairo_dock_draw_string (cairo_t *pCairoContext, CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
 
773
{
 
774
        bForceConstantSeparator = bForceConstantSeparator || myIcons.bConstantSeparatorSize;
 
775
        GList *ic, *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
 
776
        if (pFirstDrawnElement == NULL || fStringLineWidth <= 0)
 
777
                return ;
 
778
 
 
779
        cairo_save (pCairoContext);
 
780
        cairo_set_tolerance (pCairoContext, 0.5);
 
781
        Icon *prev_icon = NULL, *next_icon, *icon;
 
782
        double x, y, fCurvature = 0.3;
 
783
        if (bIsLoop)
 
784
        {
 
785
                ic = cairo_dock_get_previous_element (pFirstDrawnElement, pDock->icons);
 
786
                prev_icon = ic->data;
 
787
        }
 
788
        ic = pFirstDrawnElement;
 
789
        icon = ic->data;
 
790
        GList *next_ic;
 
791
        double x1, x2, x3;
 
792
        double y1, y2, y3;
 
793
        double dx, dy;
 
794
        x = icon->fDrawX + icon->fWidth * icon->fScale * icon->fWidthFactor / 2;
 
795
        y = icon->fDrawY + icon->fHeight * icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - 1) / 2 : 0);
 
796
        if (pDock->container.bIsHorizontal)
 
797
                cairo_move_to (pCairoContext, x, y);
 
798
        else
 
799
                cairo_move_to (pCairoContext, y, x);
 
800
        do
 
801
        {
 
802
                if (prev_icon != NULL)
 
803
                {
 
804
                        x1 = prev_icon->fDrawX + prev_icon->fWidth * prev_icon->fScale * prev_icon->fWidthFactor / 2;
 
805
                        y1 = prev_icon->fDrawY + prev_icon->fHeight * prev_icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (prev_icon) ? prev_icon->fHeight * (prev_icon->fScale - 1) / 2 : 0);
 
806
                }
 
807
                else
 
808
                {
 
809
                        x1 = x;
 
810
                        y1 = y;
 
811
                }
 
812
                prev_icon = icon;
 
813
 
 
814
                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
815
                if (ic == pFirstDrawnElement && ! bIsLoop)
 
816
                        break;
 
817
                icon = ic->data;
 
818
                x2 = icon->fDrawX + icon->fWidth * icon->fScale * icon->fWidthFactor / 2;
 
819
                y2 = icon->fDrawY + icon->fHeight * icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - 1) / 2 : 0);
 
820
 
 
821
                dx = x2 - x;
 
822
                dy = y2 - y;
 
823
 
 
824
                next_ic = cairo_dock_get_next_element (ic, pDock->icons);
 
825
                next_icon = (next_ic == pFirstDrawnElement && ! bIsLoop ? NULL : next_ic->data);
 
826
                if (next_icon != NULL)
 
827
                {
 
828
                        x3 = next_icon->fDrawX + next_icon->fWidth * next_icon->fScale * next_icon->fWidthFactor / 2;
 
829
                        y3 = next_icon->fDrawY + next_icon->fHeight * next_icon->fScale / 2 + (bForceConstantSeparator && CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (next_icon) ? next_icon->fHeight * (next_icon->fScale - 1) / 2 : 0);
 
830
                }
 
831
                else
 
832
                {
 
833
                        x3 = x2;
 
834
                        y3 = y2;
 
835
                }
 
836
 
 
837
                if (pDock->container.bIsHorizontal)
 
838
                        cairo_rel_curve_to (pCairoContext,
 
839
                                (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature : 0),
 
840
                                (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature * (y - y1) / (x - x1) : 0),
 
841
                                (fabs ((x3 - x2) / (y3 - y2)) > .35 ? dx * (1 - fCurvature) : dx),
 
842
                                (fabs ((x3 - x2) / (y3 - y2)) > .35 ? MAX (0, MIN (dy, dy - dx * fCurvature * (y3 - y2) / (x3 - x2))) : dy),
 
843
                                dx,
 
844
                                dy);
 
845
                else
 
846
                        cairo_rel_curve_to (pCairoContext,
 
847
                                (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature * (y - y1) / (x - x1) : 0),
 
848
                                (fabs ((x - x1) / (y - y1)) > .35 ? dx * fCurvature : 0),
 
849
                                (fabs ((x3 - x2) / (y3 - y2)) > .35 ? MAX (0, MIN (dy, dy - dx * fCurvature * (y3 - y2) / (x3 - x2))) : dy),
 
850
                                (fabs ((x3 - x2) / (y3 - y2)) > .35 ? dx * (1 - fCurvature) : dx),
 
851
                                dy,
 
852
                                dx);
 
853
                x = x2;
 
854
                y = y2;
 
855
        }
 
856
        while (ic != pFirstDrawnElement);
 
857
 
 
858
        cairo_set_line_width (pCairoContext, myIcons.iStringLineWidth);
 
859
        cairo_set_source_rgba (pCairoContext, myIcons.fStringColor[0], myIcons.fStringColor[1], myIcons.fStringColor[2], myIcons.fStringColor[3]);
 
860
        cairo_stroke (pCairoContext);
 
861
        cairo_restore (pCairoContext);
 
862
}
 
863
 
 
864
void cairo_dock_render_icons_linear (cairo_t *pCairoContext, CairoDock *pDock)
 
865
{
 
866
        //GList *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
 
867
        GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
 
868
        if (pFirstDrawnElement == NULL)
 
869
                return;
 
870
        
 
871
        double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);  // * pDock->fMagnitudeMax
 
872
        Icon *icon;
 
873
        GList *ic = pFirstDrawnElement;
 
874
        do
 
875
        {
 
876
                icon = ic->data;
 
877
 
 
878
                cairo_save (pCairoContext);
 
879
                cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
 
880
                cairo_restore (pCairoContext);
 
881
 
 
882
                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
883
        } while (ic != pFirstDrawnElement);
 
884
}
 
885
 
 
886
 
 
887
 
 
888
void cairo_dock_draw_surface (cairo_t *pCairoContext, cairo_surface_t *pSurface, int iWidth, int iHeight, gboolean bDirectionUp, gboolean bHorizontal, gdouble fAlpha)
 
889
{
 
890
        if (bDirectionUp)
 
891
        {
 
892
                if (bHorizontal)
 
893
                {
 
894
                        cairo_set_source_surface (pCairoContext, pSurface, 0., 0.);
 
895
                }
 
896
                else
 
897
                {
 
898
                        cairo_rotate (pCairoContext, - G_PI/2);
 
899
                        cairo_set_source_surface (pCairoContext, pSurface, - iWidth, 0.);
 
900
                }
 
901
        }
 
902
        else
 
903
        {
 
904
                if (bHorizontal)
 
905
                {
 
906
                        cairo_scale (pCairoContext, 1., -1.);
 
907
                        cairo_set_source_surface (pCairoContext, pSurface, 0., - iHeight);
 
908
                }
 
909
                else
 
910
                {
 
911
                        cairo_rotate (pCairoContext, G_PI/2);
 
912
                        cairo_set_source_surface (pCairoContext, pSurface, 0., - iHeight);
 
913
                }
 
914
        }
 
915
        if (fAlpha == -1)
 
916
                cairo_fill_preserve (pCairoContext);
 
917
        else if (fAlpha != 1)
 
918
                cairo_paint_with_alpha (pCairoContext, fAlpha);
 
919
        else
 
920
                cairo_paint (pCairoContext);
 
921
}
 
922
 
 
923
 
 
924
 
 
925
void cairo_dock_render_hidden_dock (cairo_t *pCairoContext, CairoDock *pDock)
 
926
{
 
927
        //\_____________________ on dessine la zone de rappel.
 
928
        if (g_pVisibleZoneBuffer.pSurface != NULL)
 
929
        {
 
930
                cairo_save (pCairoContext);
 
931
                int w = MIN (myAccessibility.iZoneWidth, pDock->container.iWidth);
 
932
                int h = MIN (myAccessibility.iZoneHeight, pDock->container.iHeight);
 
933
                
 
934
                if (pDock->container.bIsHorizontal)
 
935
                {
 
936
                        if (pDock->container.bDirectionUp)
 
937
                                cairo_translate (pCairoContext, (pDock->container.iWidth - w)/2, pDock->container.iHeight - h);
 
938
                        else
 
939
                                cairo_translate (pCairoContext, (pDock->container.iWidth - w)/2, 0.);
 
940
                }
 
941
                else
 
942
                {
 
943
                        if (pDock->container.bDirectionUp)
 
944
                                cairo_translate (pCairoContext, pDock->container.iHeight - h, (pDock->container.iWidth - w)/2);
 
945
                        else
 
946
                                cairo_translate (pCairoContext, 0., (pDock->container.iWidth - w)/2);
 
947
                }
 
948
                cairo_dock_draw_surface (pCairoContext, g_pVisibleZoneBuffer.pSurface,
 
949
                        w,
 
950
                        h,
 
951
                        (TRUE/**myBackground.bReverseVisibleImage*/ ? pDock->container.bDirectionUp : TRUE),
 
952
                        pDock->container.bIsHorizontal,
 
953
                        1./**myBackground.fVisibleZoneAlpha*/);
 
954
                cairo_restore (pCairoContext);
 
955
        }
 
956
        
 
957
        //\_____________________ on dessine les icones demandant l'attention.
 
958
        GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
 
959
        if (pFirstDrawnElement == NULL)
 
960
                return;
 
961
        double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
 
962
        
 
963
        double y;
 
964
        Icon *icon;
 
965
        GList *ic = pFirstDrawnElement;
 
966
        do
 
967
        {
 
968
                icon = ic->data;
 
969
                if (icon->bIsDemandingAttention || icon->bAlwaysVisible)
 
970
                {
 
971
                        y = icon->fDrawY;
 
972
                        icon->fDrawY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale : 0.);
 
973
                        cairo_save (pCairoContext);
 
974
                        icon->fAlpha = pDock->fPostHideOffset;
 
975
                        cairo_dock_render_one_icon (icon, pDock, pCairoContext, fDockMagnitude, TRUE);
 
976
                        cairo_restore (pCairoContext);
 
977
                        icon->fDrawY = y;
 
978
                }
 
979
                ic = cairo_dock_get_next_element (ic, pDock->icons);
 
980
        } while (ic != pFirstDrawnElement);
 
981
}