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