2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
26
#include <glib/gstdio.h>
31
#include <pango/pango.h>
32
#include <librsvg/rsvg.h>
33
#include <librsvg/rsvg-cairo.h>
36
#include <glitz-glx.h>
37
#include <cairo-glitz.h>
40
#include <X11/extensions/Xrender.h>
42
#include <GL/glxext.h>
44
#include "cairo-dock-load.h"
45
#include "cairo-dock-surface-factory.h"
46
#include "cairo-dock-icons.h"
47
#include "cairo-dock-load.h"
48
#include "cairo-dock-draw.h"
49
#include "cairo-dock-notifications.h"
50
#include "cairo-dock-applications-manager.h"
51
#include "cairo-dock-renderer-manager.h"
52
#include "cairo-dock-internal-system.h"
53
#include "cairo-dock-internal-taskbar.h"
54
#include "cairo-dock-internal-indicators.h"
55
#include "cairo-dock-internal-labels.h"
56
#include "cairo-dock-internal-icons.h"
57
#include "cairo-dock-internal-background.h"
58
#include "cairo-dock-internal-accessibility.h"
59
#include "cairo-dock-log.h"
60
#include "cairo-dock-X-utilities.h"
61
#include "cairo-dock-container.h"
62
#include "cairo-dock-dock-facility.h"
63
#include "cairo-dock-dock-manager.h"
64
#include "cairo-dock-animations.h"
65
#include "cairo-dock-draw-opengl.h"
67
#include "texture-gradation.h"
68
#define RADIAN (G_PI / 180.0) // Conversion Radian/Degres
69
#define DELTA_ROUND_DEGREE 3
71
extern GLuint g_pGradationTexture[2];
73
extern CairoDock *g_pMainDock;
75
extern CairoDockImageBuffer g_pIndicatorBuffer;
76
extern CairoDockImageBuffer g_pActiveIndicatorBuffer;
77
extern CairoDockImageBuffer g_pClassIndicatorBuffer;
78
extern CairoDockImageBuffer g_pIconBackgroundImageBuffer;
79
extern CairoDockImageBuffer g_pVisibleZoneBuffer;
81
extern gboolean g_bUseOpenGL;
82
extern CairoDockGLConfig g_openglConfig;
84
extern gboolean g_bEasterEggs;
86
static void _cairo_dock_draw_appli_indicator_opengl (Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
88
if (! myIndicators.bRotateWithDock)
89
bDirectionUp = bIsHorizontal = TRUE;
91
//\__________________ On place l'indicateur.
92
if (icon->fOrientation != 0)
94
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
95
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
96
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
98
double z = 1 + myIcons.fAmplitude;
99
double w = g_pIndicatorBuffer.iWidth;
100
double h = g_pIndicatorBuffer.iHeight;
101
double dy = myIndicators.iIndicatorDeltaY / z;
103
if (myIndicators.bLinkIndicatorWithIcon) // il se deforme et rebondit avec l'icone.
107
fY = - icon->fHeight * icon->fScale/2
108
+ (h/2 - dy) * fRatio * icon->fScale;
114
glTranslatef (0., fY, 0.);
115
glScalef (w * fRatio * icon->fScale * icon->fWidthFactor, (bDirectionUp ? 1:-1) * h * fRatio * icon->fScale * icon->fHeightFactor, 1.);
121
glTranslatef (fY, 0., 0.);
122
glRotatef (90, 0., 0., 1.);
123
glScalef (w * fRatio * icon->fScale * icon->fWidthFactor, (bDirectionUp ? 1:-1) * h * fRatio * icon->fScale * icon->fHeightFactor, 1.);
127
else // il est fixe, en bas de l'icone.
129
fY = - icon->fHeight * icon->fScale/2
130
+ (h/2 - dy) * fRatio;
135
glTranslatef (0., fY, 1.);
136
glScalef (w * fRatio * 1., (bDirectionUp ? 1:-1) * h * fRatio * 1., 1.);
142
glTranslatef (fY, 0., 1.);
143
glRotatef (90, 0., 0., 1.);
144
glScalef (w * fRatio * 1., (bDirectionUp ? 1:-1) * h * fRatio * 1., 1.);
148
//\__________________ On dessine l'indicateur.
149
cairo_dock_draw_texture_with_alpha (g_pIndicatorBuffer.iTexture, 1., 1., 1.);
151
static void _cairo_dock_draw_active_window_indicator_opengl (Icon *icon, CairoDock *pDock, double fRatio)
153
if (icon->fOrientation != 0)
155
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
156
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
157
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
160
cairo_dock_set_icon_scale (icon, CAIRO_CONTAINER (pDock), 1.);
162
_cairo_dock_enable_texture ();
164
_cairo_dock_set_blend_pbuffer (); // rend mieux que les 2 autres.
166
_cairo_dock_apply_texture_at_size_with_alpha (g_pActiveIndicatorBuffer.iTexture, 1., 1., 1.);
168
_cairo_dock_disable_texture ();
171
static void _cairo_dock_draw_class_indicator_opengl (Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
173
if (icon->fOrientation != 0)
175
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
176
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
177
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
180
if (myIndicators.bZoomClassIndicator)
181
fRatio *= icon->fScale;
182
double w = g_pClassIndicatorBuffer.iWidth;
183
double h = g_pClassIndicatorBuffer.iHeight;
186
glRotatef (90., 0., 0., 1.);
188
glScalef (1., -1., 1.);
189
glTranslatef (icon->fWidth * icon->fScale/2 - w * fRatio/2,
190
icon->fHeight * icon->fScale/2 - h * fRatio/2,
193
cairo_dock_draw_texture_with_alpha (g_pClassIndicatorBuffer.iTexture,
199
void cairo_dock_set_icon_scale (Icon *pIcon, CairoContainer *pContainer, double fZoomFactor)
201
double fSizeX, fSizeY;
202
cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
203
glScalef (fSizeX * fZoomFactor, fSizeY * fZoomFactor, fSizeY * fZoomFactor);
207
void cairo_dock_combine_argb_argb (void) // taken from glitz 0.5.6
210
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
212
glActiveTexture (GL_TEXTURE0);
213
glEnable(GL_TEXTURE_2D);
214
glColor4f(0., 0., 0., 1.);
215
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
217
glActiveTexture (GL_TEXTURE1);
218
glEnable(GL_TEXTURE_2D);
219
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
221
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
222
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
223
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
224
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
225
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
227
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
228
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
229
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
230
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
231
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
234
void cairo_dock_draw_icon_opengl (Icon *pIcon, CairoDock *pDock)
236
//\_____________________ On dessine l'icone.
237
double fSizeX, fSizeY;
238
cairo_dock_get_current_icon_size (pIcon, CAIRO_CONTAINER (pDock), &fSizeX, &fSizeY);
240
_cairo_dock_enable_texture ();
241
if (pIcon->fAlpha == 1)
242
_cairo_dock_set_blend_over ();
244
_cairo_dock_set_blend_alpha ();
246
_cairo_dock_apply_texture_at_size_with_alpha (pIcon->iIconTexture, fSizeX, fSizeY, pIcon->fAlpha);
248
//\_____________________ On dessine son reflet.
249
if (pDock->container.bUseReflect)
251
if (pDock->pRenderer->bUseStencil)
253
glEnable (GL_STENCIL_TEST);
254
glStencilFunc (GL_EQUAL, 1, 1);
255
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
258
double x0, y0, x1, y1;
259
double fScale = ((myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (pIcon)) ? 1. : pIcon->fScale);
260
double fReflectSize = MIN (myIcons.fReflectSize, pIcon->fHeight/pDock->container.fRatio*fScale);
261
double fReflectRatio = fReflectSize * pDock->container.fRatio / pIcon->fHeight / fScale / pIcon->fHeightFactor;
262
double fOffsetY = pIcon->fHeight * fScale/2 + fReflectSize * pDock->container.fRatio/2 + pIcon->fDeltaYReflection;
263
if (pDock->container.bIsHorizontal)
265
if (pDock->container.bDirectionUp)
267
glTranslatef (0., - fOffsetY, 0.);
268
glScalef (pIcon->fWidth * pIcon->fWidthFactor * fScale, - fReflectSize * pDock->container.fRatio, 1.); // taille du reflet et on se retourne.
270
y0 = 1. - fReflectRatio;
276
glTranslatef (0., fOffsetY, 0.);
277
glScalef (pIcon->fWidth * pIcon->fWidthFactor * fScale, fReflectSize * pDock->container.fRatio, 1.);
286
if (pDock->container.bDirectionUp)
288
glTranslatef (fOffsetY, 0., 0.);
289
glScalef (- fReflectSize * pDock->container.fRatio, pIcon->fWidth * pIcon->fWidthFactor * fScale, 1.);
290
x0 = 1. - fReflectRatio;
297
glTranslatef (- fOffsetY, 0., 0.);
298
glScalef (fReflectSize * pDock->container.fRatio, pIcon->fWidth * pIcon->fWidthFactor * fScale, 1.);
306
glEnable(GL_TEXTURE_2D);
307
glBindTexture(GL_TEXTURE_2D, pIcon->iIconTexture);
309
_cairo_dock_set_blend_alpha ();
310
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
312
//glBlendColor(1., 1., 1., 1.); // utile ?
314
glPolygonMode (GL_FRONT, GL_FILL);
315
glColor4f(1., 1., 1., 1.);
319
double fReflectAlpha = myIcons.fAlbedo * pIcon->fAlpha;
320
if (pDock->container.bIsHorizontal)
322
glTexCoord2f (x0, y0);
323
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
324
glVertex3f (-.5, .5, 0.); // Bottom Left Of The Texture and Quad
326
glTexCoord2f (x1, y0);
327
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
328
glVertex3f (.5, .5, 0.); // Bottom Right Of The Texture and Quad
330
glTexCoord2f (x1, y1);
331
glColor4f (1., 1., 1., fReflectAlpha);
332
glVertex3f (.5, -.5, 0.); // Top Right Of The Texture and Quad
334
glTexCoord2f (x0, y1);
335
glColor4f (1., 1., 1., fReflectAlpha);
336
glVertex3f (-.5, -.5, 0.); // Top Left Of The Texture and Quad
340
glTexCoord2f (x0, y0);
341
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
342
glVertex3f (-.5, .5, 0.); // Bottom Left Of The Texture and Quad
344
glTexCoord2f (x1, y0);
345
glColor4f (1., 1., 1., fReflectAlpha);
346
glVertex3f (.5, .5, 0.); // Bottom Right Of The Texture and Quad
348
glTexCoord2f (x1, y1);
349
glColor4f (1., 1., 1., fReflectAlpha);
350
glVertex3f (.5, -.5, 0.); // Top Right Of The Texture and Quad
352
glTexCoord2f (x0, y1);
353
glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
354
glVertex3f (-.5, -.5, 0.); // Top Left Of The Texture and Quad
359
if (pDock->pRenderer->bUseStencil)
361
glDisable (GL_STENCIL_TEST);
365
_cairo_dock_disable_texture ();
369
static inline void _compute_icon_coordinate (Icon *icon, CairoContainer *pContainer, double fDockMagnitude, double *pX, double *pY)
372
double fRatio = pContainer->fRatio;
374
if (icon->fGlideOffset != 0)
376
double fPhase = icon->fPhase + icon->fGlideOffset * icon->fWidth / fRatio / myIcons.iSinusoidWidth * G_PI;
381
else if (fPhase > G_PI)
385
fGlideScale = (1 + fDockMagnitude * myIcons.fAmplitude * sin (fPhase)) / icon->fScale; // c'est un peu hacky ... il faudrait passer l'icone precedente en parametre ...
386
if (! pContainer->bDirectionUp)
387
if (pContainer->bIsHorizontal)
388
fY = (1-fGlideScale)*icon->fHeight*icon->fScale;
390
fX = (1-fGlideScale)*icon->fHeight*icon->fScale;
394
icon->fGlideScale = fGlideScale;
396
if (pContainer->bIsHorizontal)
398
fY += pContainer->iHeight - icon->fDrawY; // ordonnee du haut de l'icone.
399
fX += icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1); // abscisse du milieu de l'icone.
403
fY += icon->fDrawY; // ordonnee du haut de l'icone.
404
fX += pContainer->iWidth - (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1));
410
void cairo_dock_translate_on_icon_opengl (Icon *icon, CairoContainer *pContainer, double fDockMagnitude)
413
_compute_icon_coordinate (icon, pContainer, fDockMagnitude, &fX, &fY);
415
if (pContainer->bIsHorizontal)
416
glTranslatef (floor (fX), floor (fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), - icon->fHeight * (1+myIcons.fAmplitude));
418
glTranslatef (floor (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), floor (fX), - icon->fHeight * (1+myIcons.fAmplitude));
421
void cairo_dock_render_one_icon_opengl (Icon *icon, CairoDock *pDock, double fDockMagnitude, gboolean bUseText)
423
if (icon->iIconTexture == 0)
425
double fRatio = pDock->container.fRatio;
427
if (g_pGradationTexture[pDock->container.bIsHorizontal] == 0)
429
//g_pGradationTexture[pDock->container.bIsHorizontal] = cairo_dock_load_local_texture (pDock->container.bIsHorizontal ? "texture-gradation-vert.png" : "texture-gradation-horiz.png", CAIRO_DOCK_SHARE_DATA_DIR);
430
g_pGradationTexture[pDock->container.bIsHorizontal] = cairo_dock_load_texture_from_raw_data (gradationTex,
431
pDock->container.bIsHorizontal ? 1:48,
432
pDock->container.bIsHorizontal ? 48:1);
433
cd_debug ("g_pGradationTexture(%d) <- %d", pDock->container.bIsHorizontal, g_pGradationTexture[pDock->container.bIsHorizontal]);
435
if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.fVisibleAppliAlpha != 0 && ! CAIRO_DOCK_IS_APPLET (icon) && !(icon->iBackingPixmap != 0 && icon->bIsHidden))
437
double fAlpha = (icon->bIsHidden ? MIN (1 - myTaskBar.fVisibleAppliAlpha, 1) : MIN (myTaskBar.fVisibleAppliAlpha + 1, 1));
439
icon->fAlpha = fAlpha; // astuce bidon pour pas multiplier 2 fois.
442
//\_____________________ On se place au centre de l'icone.
444
_compute_icon_coordinate (icon, CAIRO_CONTAINER (pDock), fDockMagnitude, &fX, &fY);
447
if (pDock->container.bIsHorizontal)
448
glTranslatef (fX, fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2), - icon->fHeight * (1+myIcons.fAmplitude));
450
glTranslatef (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2), fX, - icon->fHeight * (1+myIcons.fAmplitude));
452
//\_____________________ On dessine les indicateur derriere.
453
if (icon->bHasIndicator && ! myIndicators.bIndicatorAbove /*&& g_iIndicatorTexture != 0*/)
456
_cairo_dock_draw_appli_indicator_opengl (icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
459
gboolean bIsActive = FALSE;
460
Window xActiveId = cairo_dock_get_current_active_window ();
461
if (xActiveId != 0 && g_pActiveIndicatorBuffer.pSurface != NULL)
463
bIsActive = (icon->Xid == xActiveId);
464
if (!bIsActive && icon->pSubDock != NULL)
468
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
471
if (subicon->Xid == xActiveId)
479
if (bIsActive && ! myIndicators.bActiveIndicatorAbove)
482
_cairo_dock_draw_active_window_indicator_opengl (icon, pDock, fRatio);
486
//\_____________________ On positionne l'icone.
488
if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (icon))
490
if (pDock->container.bIsHorizontal)
492
glTranslatef (0., (pDock->container.bDirectionUp ? icon->fHeight * (- icon->fScale + 1)/2 : icon->fHeight * (icon->fScale - 1)/2), 0.);
496
glTranslatef ((!pDock->container.bDirectionUp ? icon->fHeight * (- icon->fScale + 1)/2 : icon->fHeight * (icon->fScale - 1)/2), 0., 0.);
499
glTranslatef (0., 0., - icon->fHeight * (1+myIcons.fAmplitude));
500
if (icon->fOrientation != 0)
502
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
503
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
504
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
506
if (icon->iRotationX != 0)
507
glRotatef (icon->iRotationX, 1., 0., 0.);
508
if (icon->iRotationY != 0)
509
glRotatef (icon->iRotationY, 0., 1., 0.);
511
//\_____________________ On dessine l'icone.
512
gboolean bIconHasBeenDrawn = FALSE;
513
cairo_dock_notify (CAIRO_DOCK_PRE_RENDER_ICON, icon, pDock);
514
cairo_dock_notify (CAIRO_DOCK_RENDER_ICON, icon, pDock, &bIconHasBeenDrawn, NULL);
516
glPopMatrix (); // retour juste apres la translation au milieu de l'icone.
518
//\_____________________ On dessine les indicateurs devant.
519
if (icon->bHasIndicator && myIndicators.bIndicatorAbove/* && g_iIndicatorTexture != 0*/)
522
glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1); // avant-plan
523
_cairo_dock_draw_appli_indicator_opengl (icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
526
if (bIsActive && myIndicators.bActiveIndicatorAbove)
529
glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1); // avant-plan
530
_cairo_dock_draw_active_window_indicator_opengl (icon, pDock, fRatio);
533
if (icon->pSubDock != NULL && icon->cClass != NULL && g_pClassIndicatorBuffer.pSurface != NULL && icon->Xid == 0) // le dernier test est de la paranoia.
536
glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1); // avant-plan
537
_cairo_dock_draw_class_indicator_opengl (icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
541
//\_____________________ On dessine les infos additionnelles.
542
if (icon->iQuickInfoTexture != 0)
545
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
546
glTranslatef (0., (- icon->fHeight + icon->iQuickInfoHeight * fRatio) * icon->fScale/2, 0.);
548
cairo_dock_draw_texture_with_alpha (icon->iQuickInfoTexture,
549
icon->iQuickInfoWidth * fRatio * icon->fScale,
550
icon->iQuickInfoHeight * fRatio * icon->fScale,
556
//\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
557
glPopMatrix (); // retour au debut de la fonction.
558
if (bUseText && icon->iLabelTexture != 0 && (icon->fScale > 1.01 || myIcons.fAmplitude == 0) && (! myLabels.bLabelForPointedIconOnly || icon->bPointed)) // 1.01 car sin(pi) = 1+epsilon :-/ // && icon->iAnimationState < CAIRO_DOCK_STATE_CLICKED
561
if (pDock->container.bIsHorizontal)
562
glTranslatef (floor (fX), floor (fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), - icon->fHeight * (1+myIcons.fAmplitude));
564
glTranslatef (floor (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), floor (fX), - icon->fHeight * (1+myIcons.fAmplitude));
566
double fOffsetX = 0.;
567
if (icon->fDrawX + icon->fWidth * icon->fScale/2 - icon->iTextWidth/2 < 0)
568
fOffsetX = icon->iTextWidth/2 - (icon->fDrawX + icon->fWidth * icon->fScale/2);
569
else if (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->iTextWidth/2 > pDock->container.iWidth)
570
fOffsetX = pDock->container.iWidth - (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->iTextWidth/2);
571
if (icon->fOrientation != 0 && ! mySystem.bTextAlwaysHorizontal)
573
glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
574
glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
575
glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
578
double dx = .5 * (icon->iTextWidth & 1); // on decale la texture pour la coller sur la grille des coordonnees entieres.
579
if (! pDock->container.bIsHorizontal && mySystem.bTextAlwaysHorizontal)
581
glTranslatef (ceil (-icon->fHeight * icon->fScale/2 - (pDock->container.bDirectionUp ? myLabels.iLabelSize : (pDock->container.bUseReflect ? myIcons.fReflectSize : 0.)) + icon->iTextWidth / 2 - myLabels.iconTextDescription.iMargin + 1) + dx,
582
floor ((icon->fWidth * icon->fScale + icon->iTextHeight) / 2) + dx,
585
else if (pDock->container.bIsHorizontal)
587
glTranslatef (floor (fOffsetX) + dx, floor ((pDock->container.bDirectionUp ? 1:-1) * (icon->fHeight * icon->fScale/2 + myLabels.iLabelSize - icon->iTextHeight / 2)) + dx, 0.);
591
glTranslatef (floor ((pDock->container.bDirectionUp ? -.5:.5) * (icon->fHeight * icon->fScale + icon->iTextHeight)) + dx,
592
floor (fOffsetX) + dx,
594
glRotatef (pDock->container.bDirectionUp ? 90 : -90, 0., 0., 1.);
598
if (myLabels.bLabelForPointedIconOnly)
600
fMagnitude = fDockMagnitude; // (icon->fScale - 1) / myIcons.fAmplitude / sin (icon->fPhase); // sin (phi ) != 0 puisque fScale > 1.
604
fMagnitude = (icon->fScale - 1) / myIcons.fAmplitude; /// il faudrait diviser par pDock->fMagnitudeMax ...
605
fMagnitude = pow (fMagnitude, mySystem.fLabelAlphaThreshold);
606
///fMagnitude *= (fMagnitude * mySystem.fLabelAlphaThreshold + 1) / (mySystem.fLabelAlphaThreshold + 1);
609
cairo_dock_draw_texture_with_alpha (icon->iLabelTexture,
619
void cairo_dock_render_hidden_dock_opengl (CairoDock *pDock)
621
//g_print ("%s (%d, %x)\n", __func__, pDock->bIsMainDock, g_pVisibleZoneSurface);
622
//\_____________________ on dessine la zone de rappel.
623
glLoadIdentity (); // annule l'offset de cachage.
624
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (pDock->pRenderer->bUseStencil ? GL_STENCIL_BUFFER_BIT : 0));
625
cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDock));
627
if (g_pVisibleZoneBuffer.iTexture != 0)
629
_cairo_dock_enable_texture ();
630
_cairo_dock_set_blend_over ();
631
_cairo_dock_set_alpha (myBackground.fVisibleZoneAlpha);
632
int w = MIN (myAccessibility.iVisibleZoneWidth, pDock->container.iWidth);
633
int h = MIN (myAccessibility.iVisibleZoneHeight, pDock->container.iHeight);
634
cd_debug ("%s (%dx%d)", __func__, w, h);
636
if (pDock->container.bIsHorizontal)
638
if (pDock->container.bDirectionUp)
639
glTranslatef ((pDock->container.iWidth)/2, h/2, 0.);
641
glTranslatef ((pDock->container.iWidth)/2, pDock->container.iHeight - h/2, 0.);
645
if (!pDock->container.bDirectionUp)
646
glTranslatef (h/2, (pDock->container.iWidth)/2, 0.);
648
glTranslatef (pDock->container.iHeight - h/2, (pDock->container.iWidth)/2, 0.);
651
if (! pDock->container.bIsHorizontal)
652
glRotatef (90., 0, 0, 1);
653
if (! pDock->container.bDirectionUp && myBackground.bReverseVisibleImage)
654
glScalef (1., -1., 1.);
656
_cairo_dock_apply_texture_at_size (g_pVisibleZoneBuffer.iTexture, w, h);
658
_cairo_dock_disable_texture ();
661
//\_____________________ on dessine les icones demandant l'attention.
662
//if (myTaskBar.cAnimationOnDemandsAttention)
664
GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
665
if (pFirstDrawnElement == NULL)
667
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
671
GList *ic = pFirstDrawnElement;
675
if (icon->bIsDemandingAttention)
677
//g_print ("%s : %d (%d)\n", icon->cName, icon->bIsDemandingAttention, icon->Xid);
679
icon->fDrawY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale : 0.);
681
cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
685
ic = cairo_dock_get_next_element (ic, pDock->icons);
686
} while (ic != pFirstDrawnElement);
692
GLuint cairo_dock_create_texture_from_surface (cairo_surface_t *pImageSurface)
694
if (! g_bUseOpenGL || pImageSurface == NULL)
697
int w = cairo_image_surface_get_width (pImageSurface);
698
int h = cairo_image_surface_get_height (pImageSurface);
700
cairo_surface_t *pPowerOfwoSurface = pImageSurface;
702
int iMaxTextureWidth = 4096, iMaxTextureHeight = 4096; // il faudrait le recuperer de glInfo ...
703
if (! g_openglConfig.bNonPowerOfTwoAvailable) // cas des vieilles cartes comme la GeForce5.
705
double log2_w = log (w) / log (2);
706
double log2_h = log (h) / log (2);
707
int w_ = MIN (iMaxTextureWidth, pow (2, ceil (log2_w)));
708
int h_ = MIN (iMaxTextureHeight, pow (2, ceil (log2_h)));
709
cd_debug ("%dx%d --> %dx%d", w, h, w_, h_);
711
if (w != w_ || h != h_)
713
pPowerOfwoSurface = _cairo_dock_create_blank_surface (NULL, w_, h_);
714
cairo_t *pCairoContext = cairo_create (pPowerOfwoSurface);
715
cairo_scale (pCairoContext, (double) w_ / w, (double) h_ / h);
716
cairo_set_source_surface (pCairoContext, pImageSurface, 0., 0.);
717
cairo_paint (pCairoContext);
718
cairo_destroy (pCairoContext);
724
glEnable(GL_TEXTURE_2D);
725
glGenTextures (1, &iTexture);
726
cd_debug ("+ texture %d generee (%x, %dx%d)", iTexture, cairo_image_surface_get_data (pImageSurface), w, h);
727
glBindTexture (GL_TEXTURE_2D, iTexture);
728
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
729
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
731
gluBuild2DMipmaps (GL_TEXTURE_2D,
737
cairo_image_surface_get_data (pPowerOfwoSurface));
739
glTexImage2D (GL_TEXTURE_2D,
741
4, // GL_ALPHA / GL_BGRA
745
GL_BGRA, // GL_ALPHA / GL_BGRA
747
cairo_image_surface_get_data (pPowerOfwoSurface));
748
if (pPowerOfwoSurface != pImageSurface)
749
cairo_surface_destroy (pPowerOfwoSurface);
750
glDisable(GL_TEXTURE_2D);
754
GLuint cairo_dock_load_texture_from_raw_data (const guchar *pTextureRaw, int iWidth, int iHeight)
756
/*g_print ("%dx%d\n", iWidth, iHeight);
758
guint pixel, alpha, red, green, blue;
760
guint *pPixelBuffer = (guint *) pTextureRaw;
761
guint *pPixelBuffer2 = g_new (guint, iHeight * iWidth);
762
for (i = 0; i < iHeight * iWidth; i ++)
764
pixel = (gint) pPixelBuffer[i];
765
alpha = (pixel & 0xFF000000) >> 24;
766
red = (pixel & 0x00FF0000) >> 16;
767
green = (pixel & 0x0000FF00) >> 8;
768
blue = (pixel & 0x000000FF);
769
fAlphaFactor = (float) alpha / 255.;
771
green *= fAlphaFactor;
772
blue *= fAlphaFactor;
773
pPixelBuffer2[i] = (pixel & 0xFF000000) + (red << 16) + (green << 8) + (blue << 0);
774
g_print ("\\%o\\%o\\%o\\%o", red, green, blue, alpha);
776
pTextureRaw = pPixelBuffer2;*/
779
glEnable (GL_TEXTURE_2D);
780
glGenTextures(1, &iTexture);
781
glBindTexture(GL_TEXTURE_2D, iTexture);
783
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
784
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
786
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTextureRaw);
787
glBindTexture (GL_TEXTURE_2D, 0);
788
glDisable(GL_TEXTURE_2D);
792
GLuint cairo_dock_create_texture_from_image_full (const gchar *cImageFile, double *fImageWidth, double *fImageHeight)
794
g_return_val_if_fail (GTK_WIDGET_REALIZED (g_pMainDock->container.pWidget), 0);
795
double fWidth=0, fHeight=0;
796
if (cImageFile == NULL)
799
if (*cImageFile == '/')
800
cImagePath = (gchar *)cImageFile;
802
cImagePath = cairo_dock_generate_file_path (cImageFile);
804
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
805
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image (cImagePath,
809
CAIRO_DOCK_KEEP_RATIO,
813
//cd_debug ("texture genere (%x, %.2fx%.2f)", pSurface, fWidth, fHeight);
814
cairo_destroy (pCairoContext);
816
if (fImageWidth != NULL)
817
*fImageWidth = fWidth;
818
if (fImageHeight != NULL)
819
*fImageHeight = fHeight;
820
GLuint iTexture = cairo_dock_create_texture_from_surface (pSurface);
821
cairo_surface_destroy (pSurface);
822
if (cImagePath != cImageFile)
828
void cairo_dock_update_icon_texture (Icon *pIcon)
830
if (pIcon != NULL && pIcon->pIconBuffer != NULL)
832
glEnable (GL_TEXTURE_2D);
833
if (pIcon->iIconTexture == 0)
834
glGenTextures (1, &pIcon->iIconTexture);
835
int w = cairo_image_surface_get_width (pIcon->pIconBuffer);
836
int h = cairo_image_surface_get_height (pIcon->pIconBuffer);
837
glBindTexture (GL_TEXTURE_2D, pIcon->iIconTexture);
838
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
839
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
841
glTexImage2D (GL_TEXTURE_2D,
843
4, // GL_ALPHA / GL_BGRA
847
GL_BGRA, // GL_ALPHA / GL_BGRA
849
cairo_image_surface_get_data (pIcon->pIconBuffer));
850
glDisable (GL_TEXTURE_2D);
854
void cairo_dock_update_label_texture (Icon *pIcon)
856
if (pIcon->iLabelTexture != 0)
858
_cairo_dock_delete_texture (pIcon->iLabelTexture);
859
pIcon->iLabelTexture = 0;
861
if (pIcon != NULL && pIcon->pTextBuffer != NULL)
863
glEnable (GL_TEXTURE_2D);
864
glGenTextures (1, &pIcon->iLabelTexture);
865
int w = cairo_image_surface_get_width (pIcon->pTextBuffer);
866
int h = cairo_image_surface_get_height (pIcon->pTextBuffer);
867
glBindTexture (GL_TEXTURE_2D, pIcon->iLabelTexture);
868
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
869
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
870
glTexImage2D (GL_TEXTURE_2D,
872
4, // GL_ALPHA / GL_BGRA
876
GL_BGRA, // GL_ALPHA / GL_BGRA
878
cairo_image_surface_get_data (pIcon->pTextBuffer));
879
glDisable (GL_TEXTURE_2D);
883
void cairo_dock_update_quick_info_texture (Icon *pIcon)
885
if (pIcon->iQuickInfoTexture != 0)
887
_cairo_dock_delete_texture (pIcon->iQuickInfoTexture);
888
pIcon->iQuickInfoTexture = 0;
890
if (pIcon != NULL && pIcon->pQuickInfoBuffer != NULL)
892
glEnable (GL_TEXTURE_2D);
893
glGenTextures (1, &pIcon->iQuickInfoTexture);
894
int w = cairo_image_surface_get_width (pIcon->pQuickInfoBuffer);
895
int h = cairo_image_surface_get_height (pIcon->pQuickInfoBuffer);
896
glBindTexture (GL_TEXTURE_2D, pIcon->iQuickInfoTexture);
897
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
898
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
899
glTexImage2D (GL_TEXTURE_2D,
901
4, // GL_ALPHA / GL_BGRA
905
GL_BGRA, // GL_ALPHA / GL_BGRA
907
cairo_image_surface_get_data (pIcon->pQuickInfoBuffer));
908
glDisable (GL_TEXTURE_2D);
914
void cairo_dock_draw_texture_with_alpha (GLuint iTexture, int iWidth, int iHeight, double fAlpha)
916
_cairo_dock_enable_texture ();
918
_cairo_dock_set_blend_over ();
920
_cairo_dock_set_blend_alpha ();
921
//_cairo_dock_set_blend_alpha ();
923
_cairo_dock_apply_texture_at_size_with_alpha (iTexture, iWidth, iHeight, fAlpha);
925
_cairo_dock_disable_texture ();
928
void cairo_dock_draw_texture (GLuint iTexture, int iWidth, int iHeight)
930
cairo_dock_draw_texture_with_alpha (iTexture, iWidth, iHeight, 1.);
933
void cairo_dock_apply_icon_texture_at_current_size (Icon *pIcon, CairoContainer *pContainer)
935
double fSizeX, fSizeY;
936
cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
938
_cairo_dock_apply_texture_at_size (pIcon->iIconTexture, fSizeX, fSizeY);
941
void cairo_dock_draw_icon_texture (Icon *pIcon, CairoContainer *pContainer)
943
double fSizeX, fSizeY;
944
cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
946
cairo_dock_draw_texture_with_alpha (pIcon->iIconTexture,
952
static inline void _draw_icon_bent_backwards (Icon *pIcon, CairoContainer *pContainer, GLuint iOriginalTexture, double f)
955
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
956
cairo_dock_set_perspective_view (iWidth, iHeight);
957
glScalef (1., -1., 1.);
958
glTranslatef (0., -iHeight/2, 0.); // rotation de 50Ā° sur l'axe des X a la base de l'icone.
959
glRotatef (-50.*f, 1., 0., 0.);
960
glTranslatef (0., iHeight/2, 0.);
962
_cairo_dock_enable_texture ();
963
_cairo_dock_set_blend_source ();
964
glBindTexture (GL_TEXTURE_2D, iOriginalTexture);
965
_cairo_dock_apply_current_texture_at_size_with_offset (iWidth*(1+.1*f),
968
iHeight*(.25/2*f)); // on elargit un peu la texture, car avec l'effet de profondeur elle parait trop petite.
969
_cairo_dock_disable_texture ();
970
cairo_dock_set_ortho_view (iWidth, iHeight);
972
static gboolean _transition_step (Icon *pIcon, gpointer data)
974
CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
978
GLuint iOriginalTexture = GPOINTER_TO_INT (data);
979
double f = cairo_dock_get_transition_fraction (pIcon);
980
if (!pIcon->bIsHidden)
983
_draw_icon_bent_backwards (pIcon, CAIRO_CONTAINER (pDock), iOriginalTexture, f);
986
static void _free_transition_data (gpointer data)
988
GLuint iOriginalTexture = GPOINTER_TO_INT (data);
989
_cairo_dock_delete_texture (iOriginalTexture);
991
void cairo_dock_draw_hidden_appli_icon (Icon *pIcon, CairoContainer *pContainer, gboolean bStateChanged)
995
cairo_dock_remove_transition_on_icon (pIcon);
998
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
1000
GLuint iOriginalTexture;
1001
if (pIcon->bIsHidden)
1003
iOriginalTexture = pIcon->iIconTexture;
1004
pIcon->iIconTexture = cairo_dock_create_texture_from_surface (pIcon->pIconBuffer);
1005
/// Using FBOs copies the texture data (pixels) within VRAM only:
1006
/// - setup & bind FBO
1007
/// - setup destination texture (using glTexImage() w/ pixels = 0)
1008
/// - add (blank but sized) destination texture as color attachment
1009
/// - bind source texture to texture target
1010
/// - draw quad w/ glTexCoors describing src area, projection/modelview matrices & glVertexes describing dst area
1014
iOriginalTexture = cairo_dock_create_texture_from_surface (pIcon->pIconBuffer);
1017
cairo_dock_set_transition_on_icon (pIcon, pContainer, NULL,
1018
(CairoDockTransitionRenderFunc) NULL,
1019
(CairoDockTransitionGLRenderFunc) _transition_step,
1022
TRUE, // remove when finished
1023
GINT_TO_POINTER (iOriginalTexture),
1024
_free_transition_data);
1026
else if (pIcon->bIsHidden)
1028
if (!cairo_dock_begin_draw_icon (pIcon, pContainer))
1030
_draw_icon_bent_backwards (pIcon, pContainer, pIcon->iIconTexture, 1.);
1031
cairo_dock_end_draw_icon (pIcon, pContainer);
1038
const GLfloat *cairo_dock_generate_rectangle_path (double fDockWidth, double fFrameHeight, double fRadius, gboolean bRoundedBottomCorner, int *iNbPoints)
1040
//static GLfloat pVertexTab[((90/DELTA_ROUND_DEGREE+1)*4+1)*_CAIRO_DOCK_PATH_DIM];
1041
_cairo_dock_define_static_vertex_tab ((90/DELTA_ROUND_DEGREE+1)*4+1);
1043
double fTotalWidth = fDockWidth + 2 * fRadius;
1044
double w = fDockWidth / fTotalWidth / 2;
1045
double h = MAX (0, fFrameHeight - 2 * fRadius) / fFrameHeight / 2;
1046
double rw = fRadius / fTotalWidth;
1047
double rh = fRadius / fFrameHeight;
1049
int iPrecision = DELTA_ROUND_DEGREE;
1050
for (t = 0;t <= 90;t += iPrecision, i++) // cote haut droit.
1052
_cairo_dock_set_vertex_xy (i,
1053
w + rw * cos (t*RADIAN),
1054
h + rh * sin (t*RADIAN));
1055
//vx(i) = w + rw * cos (t*RADIAN);
1056
//vy(i) = h + rh * sin (t*RADIAN);
1058
for (t = 90;t <= 180;t += iPrecision, i++) // haut gauche.
1060
_cairo_dock_set_vertex_xy (i,
1061
-w + rw * cos (t*RADIAN),
1062
h + rh * sin (t*RADIAN));
1063
//vx(i) = -w + rw * cos (t*RADIAN);
1064
//vy(i) = h + rh * sin (t*RADIAN);
1066
if (bRoundedBottomCorner)
1068
for (t = 180;t <= 270;t += iPrecision, i++) // bas gauche.
1070
_cairo_dock_set_vertex_xy (i,
1071
-w + rw * cos (t*RADIAN),
1072
-h + rh * sin (t*RADIAN));
1073
//vx(i) = -w + rw * cos (t*RADIAN);
1074
//vy(i) = -h + rh * sin (t*RADIAN);
1076
for (t = 270;t <= 360;t += iPrecision, i++) // bas droit.
1078
_cairo_dock_set_vertex_xy (i,
1079
w + rw * cos (t*RADIAN),
1080
-h + rh * sin (t*RADIAN));
1081
//vx(i) = w + rw * cos (t*RADIAN);
1082
//vy(i) = -h + rh * sin (t*RADIAN);
1087
_cairo_dock_set_vertex_xy (i,
1089
-h - rh); // bas gauche.
1090
//vx(i) = -w - rw; // bas gauche.
1093
_cairo_dock_set_vertex_xy (i,
1095
-h - rh); // bas droit.
1096
//vx(i) = w + rw; // bas droit.
1100
_cairo_dock_close_path (i); // on boucle.
1101
//vx(i) = w + rw; // on boucle.
1105
_cairo_dock_return_vertex_tab ();
1108
#define P(t,p,q,s) ((1-t) * (1-t) * p + 2 * t * (1-t) * q + t * t * s)
1109
void cairo_dock_add_simple_curved_subpath_opengl (GLfloat *pVertexTab, int iNbPts, double x0, double y0, double x1, double y1, double x2, double y2)
1113
for (i = 0; i < iNbPts; i ++)
1115
t = 1.*i/iNbPts; // [0;1[
1116
_cairo_dock_set_vertex_xy (i,
1119
//vx(i) = P(t, x0, x1, x2);
1120
//vy(i) = P(t, y0, y1, y2);
1123
#define NB_PTS_SIMPLE_CURVE 20
1124
GLfloat *cairo_dock_generate_trapeze_path (double fDockWidth, double fFrameHeight, double fRadius, gboolean bRoundedBottomCorner, double fInclination, double *fExtraWidth, int *iNbPoints)
1126
//static GLfloat pVertexTab[((90/DELTA_ROUND_DEGREE+1+20+1)*2+1)*_CAIRO_DOCK_PATH_DIM];
1127
_cairo_dock_define_static_vertex_tab ((90/DELTA_ROUND_DEGREE+1+NB_PTS_SIMPLE_CURVE+1)*2+1);
1129
double a = atan (fInclination)/G_PI*180.;
1130
double cosa = 1. / sqrt (1 + fInclination * fInclination);
1131
double sina = cosa * fInclination;
1133
*fExtraWidth = fInclination * (fFrameHeight - (bRoundedBottomCorner ? 2 : 1-cosa) * fRadius) + fRadius * (bRoundedBottomCorner ? 1 : sina);
1134
double fTotalWidth = fDockWidth + 2*(*fExtraWidth);
1135
double dw = (bRoundedBottomCorner ? fInclination * (fFrameHeight - 2 * fRadius) : *fExtraWidth) / fTotalWidth;
1136
double w = fDockWidth / fTotalWidth / 2;
1137
double h = MAX (0, fFrameHeight - 2 * fRadius) / fFrameHeight / 2;
1138
double rw = fRadius / fTotalWidth;
1139
double rh = fRadius / fFrameHeight;
1140
double w_ = w + dw + (bRoundedBottomCorner ? 0 : 0*rw * cosa);
1143
int iPrecision = DELTA_ROUND_DEGREE;
1144
for (t = a;t <= 90;t += iPrecision, i++) // cote haut droit.
1146
_cairo_dock_set_vertex_xy (i,
1147
w + rw * cos (t*RADIAN),
1148
h + rh * sin (t*RADIAN));
1149
//vx(i) = w + rw * cos (t*RADIAN);
1150
//vy(i) = h + rh * sin (t*RADIAN);
1152
for (t = 90;t <= 180-a;t += iPrecision, i++) // haut gauche.
1154
_cairo_dock_set_vertex_xy (i,
1155
-w + rw * cos (t*RADIAN),
1156
h + rh * sin (t*RADIAN));
1157
//vx(i) = -w + rw * cos (t*RADIAN);
1158
//vy(i) = h + rh * sin (t*RADIAN);
1160
if (bRoundedBottomCorner)
1162
// OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
1163
// Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
1165
double x0 = -w_ + rw * cos (t*RADIAN);
1166
double y0 = -h + rh * sin (t*RADIAN);
1167
double x1 = x0 - fInclination * rw * (1+sina);
1168
double y1 = -h - rh;
1171
for (t=0; t<=1; t+=.05, i++) // bas gauche.
1173
_cairo_dock_set_vertex_xy (i,
1176
//vx(i) = P(t, x0, x1, x2);
1177
//vy(i) = P(t, y0, y1, y2);
1180
double x3 = x0, y3 = y0;
1186
for (t=0; t<=1; t+=.05, i++) // bas gauche.
1188
_cairo_dock_set_vertex_xy (i,
1191
//vx(i) = P(t, x0, x1, x2);
1192
//vy(i) = P(t, y0, y1, y2);
1197
_cairo_dock_set_vertex_xy (i,
1199
-h - rh); // bas gauche.
1200
//vx(i) = -w_; // bas gauche.
1203
_cairo_dock_set_vertex_xy (i,
1205
-h - rh); // bas droit.
1206
//vx(i) = w_; // bas droit.
1210
_cairo_dock_close_path (i); // on boucle.
1211
//vx(i) = vx(0); // on boucle.
1215
_cairo_dock_return_vertex_tab ();
1218
// OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
1219
// Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
1220
#define B0(t) (1-t)*(1-t)*(1-t)
1221
#define B1(t) 3*t*(1-t)*(1-t)
1222
#define B2(t) 3*t*t*(1-t)
1224
#define Bezier(x0,x1,x2,x3,t) (B0(t)*x0 + B1(t)*x1 + B2(t)*x2 + B3(t)*x3)
1226
#define _get_icon_center_x(icon) (icon->fDrawX + icon->fWidth * icon->fScale/2)
1227
#define _get_icon_center_y(icon) (icon->fDrawY + (bForceConstantSeparator && CAIRO_DOCK_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - .5) : icon->fHeight * icon->fScale/2))
1228
#define _get_icon_center(icon,x,y) do {\
1229
if (pDock->container.bIsHorizontal) {\
1230
x = _get_icon_center_x (icon);\
1231
y = pDock->container.iHeight - _get_icon_center_y (icon); }\
1233
y = _get_icon_center_x (icon);\
1234
x = pDock->container.iWidth - _get_icon_center_y (icon); } } while (0)
1235
#define _calculate_slope(x0,y0,x1,y1,dx,dy) do {\
1238
norme = sqrt (dx*dx + dy*dy);\
1240
dy /= norme; } while (0)
1241
#define NB_VERTEX_PER_ICON_PAIR 10
1242
GLfloat *cairo_dock_generate_string_path_opengl (CairoDock *pDock, gboolean bIsLoop, gboolean bForceConstantSeparator, int *iNbPoints)
1244
//static GLfloat pVertexTab[100*NB_VERTEX_PER_ICON_PAIR*3];
1245
_cairo_dock_define_static_vertex_tab (100*NB_VERTEX_PER_ICON_PAIR);
1247
bForceConstantSeparator = bForceConstantSeparator || myIcons.bConstantSeparatorSize;
1248
GList *ic, *next_ic, *next2_ic, *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
1249
Icon *pIcon, *pNextIcon, *pNext2Icon;
1250
double x0,y0, x1,y1, x2,y2; // centres des icones P0, P1, P2, en coordonnees opengl.
1251
double norme; // pour normaliser les pentes.
1252
double dx, dy; // direction au niveau de l'icone courante P0.
1253
double dx_, dy_; // direction au niveau de l'icone suivante P1.
1254
double x0_,y0_, x1_,y1_; // points de controle entre P0 et P1.
1255
if (pFirstDrawnElement == NULL)
1258
_cairo_dock_return_vertex_tab ();
1261
// direction initiale.
1262
ic = pFirstDrawnElement;
1264
_get_icon_center (pIcon,x0,y0);
1265
next_ic = cairo_dock_get_next_element (ic, pDock->icons);
1266
pNextIcon = next_ic->data;
1267
_get_icon_center (pNextIcon,x1,y1);
1270
_calculate_slope (x0,y0, x1,y1, dx,dy);
1274
next2_ic = cairo_dock_get_previous_element (ic, pDock->icons); // icone precedente dans la boucle.
1275
pNext2Icon = next2_ic->data;
1276
_get_icon_center (pNext2Icon,x2,y2);
1277
_calculate_slope (x2,y2, x0,y0, dx,dy);
1280
next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
1281
pNext2Icon = next2_ic->data;
1282
_get_icon_center (pNext2Icon,x2,y2);
1284
// on parcourt les icones.
1289
// l'icone courante, la suivante, et celle d'apres.
1291
pNextIcon = next_ic->data;
1292
pNext2Icon = next2_ic->data;
1294
// on va tracer de (x0,y0) a (x1,y1)
1295
_get_icon_center (pIcon,x0,y0);
1296
_get_icon_center (pNextIcon,x1,y1);
1297
_get_icon_center (pNext2Icon,x2,y2);
1299
// la pente au point (x1,y1)
1300
_calculate_slope (x0,y0, x2,y2, dx_,dy_);
1302
// points de controle.
1303
norme = sqrt ((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0))/2; // distance de prolongation suivant la pente.
1304
x0_ = x0 + dx * norme;
1305
y0_ = y0 + dy * norme;
1306
x1_ = x1 - dx_ * norme;
1307
y1_ = y1 - dy_ * norme;
1309
for (i = 0; i < NB_VERTEX_PER_ICON_PAIR; i ++, n++)
1311
t = 1.*i/NB_VERTEX_PER_ICON_PAIR; // [0;1[
1312
_cairo_dock_set_vertex_xy (n,
1313
Bezier (x0,x0_,x1_,x1,t),
1314
Bezier (y0,y0_,y1_,y1,t));
1315
//vx(n) = Bezier (x0,x0_,x1_,x1,t);
1316
//vy(n) = Bezier (y0,y0_,y1_,y1,t);
1319
// on decale tout d'un cran.
1322
next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
1325
if (next_ic == pFirstDrawnElement && ! bIsLoop)
1328
while (ic != pFirstDrawnElement && n < 100*NB_VERTEX_PER_ICON_PAIR);
1331
_cairo_dock_return_vertex_tab ();
1335
void cairo_dock_draw_frame_background_opengl (GLuint iBackgroundTexture, double fDockWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, const GLfloat *pVertexTab, int iNbVertex, CairoDockTypeHorizontality bHorizontal, gboolean bDirectionUp, double fDecorationsOffsetX)
1337
//\__________________ On mappe la texture dans le cadre.
1338
glEnable(GL_BLEND); // On active le blend
1340
glPolygonMode(GL_FRONT, GL_FILL);
1342
if (iBackgroundTexture != 0)
1344
glColor4f(1., 1., 1., 1.); // Couleur a fond
1345
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1346
glEnable(GL_TEXTURE_2D); // Je veux de la texture
1347
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1348
glBindTexture(GL_TEXTURE_2D, iBackgroundTexture); // allez on bind la texture
1349
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); // ok la on selectionne le type de generation des coordonnees de la texture
1350
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
1351
glEnable(GL_TEXTURE_GEN_S); // oui je veux une generation en S
1352
glEnable(GL_TEXTURE_GEN_T); // Et en T aussi
1353
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1354
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1356
//\__________________ bidouille de la texture.
1357
glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures
1359
glLoadIdentity(); // On la reset
1360
glTranslatef(0.5f - fDecorationsOffsetX * myBackground.fDecorationSpeed / (fDockWidth), 0.5f, 0.);
1361
glScalef (1., -1., 1.);
1362
glMatrixMode(GL_MODELVIEW);
1365
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1366
//\__________________ On place le cadre.
1367
///glLoadIdentity();
1370
glTranslatef ((int) (fDockOffsetX + fDockWidth/2), (int) (fDockOffsetY - fFrameHeight/2), -100); // (int) -pDock->iMaxIconHeight * (1 + myIcons.fAmplitude) + 1
1371
glScalef (fDockWidth, fFrameHeight, 1.);
1375
glTranslatef ((int) (fDockOffsetY - fFrameHeight/2), (int) (fDockOffsetX - fDockWidth/2), -100);
1376
glScalef (fFrameHeight, fDockWidth, 1.);
1380
glRotatef (bDirectionUp ? 90 : -90, 0., 0., 1.);
1385
glScalef (1., -1., 1.);
1390
glScalef (-1., 1., 1.);
1393
//\__________________ On dessine le cadre.
1394
glEnableClientState(GL_VERTEX_ARRAY);
1395
_cairo_dock_set_vertex_pointer (pVertexTab);
1396
glDrawArrays(GL_POLYGON, 0, iNbVertex); // GL_TRIANGLE_FAN
1397
glDisableClientState(GL_VERTEX_ARRAY);
1399
//\__________________ fini la texture.
1400
if (iBackgroundTexture != 0)
1402
glDisable(GL_BLEND);
1403
glDisable(GL_TEXTURE_GEN_S);
1404
glDisable(GL_TEXTURE_GEN_T);
1405
glDisable(GL_TEXTURE_2D); // Plus de texture merci
1407
glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures
1409
glMatrixMode(GL_MODELVIEW);
1413
void cairo_dock_draw_current_path_opengl (double fLineWidth, double *fLineColor, /*const GLfloat *pVertexTab, */int iNbVertex)
1415
glPolygonMode(GL_FRONT, GL_LINE);
1416
glEnable (GL_LINE_SMOOTH);
1417
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
1418
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1421
glLineWidth(fLineWidth); // Ici on choisit l'epaisseur du contour du polygone
1422
if (fLineColor != NULL)
1423
glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]); // Et sa couleur.
1425
glEnableClientState(GL_VERTEX_ARRAY);
1426
///glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
1427
glDrawArrays(GL_LINE_STRIP, 0, iNbVertex);
1428
glDisableClientState(GL_VERTEX_ARRAY);
1430
glDisable(GL_LINE_SMOOTH);
1431
glDisable(GL_BLEND);
1435
void cairo_dock_draw_string_opengl (CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
1438
GLfloat *pVertexTab = cairo_dock_generate_string_path_opengl (pDock, bIsLoop, bForceConstantSeparator, &iNbVertex);
1441
//glVertexPointer(_CAIRO_DOCK_PATH_DIM, GL_FLOAT, 0, pVertexTab);
1442
_cairo_dock_set_vertex_pointer (pVertexTab);
1443
cairo_dock_draw_current_path_opengl (fStringLineWidth, myIcons.fStringColor, iNbVertex);
1446
void cairo_dock_draw_rounded_rectangle_opengl (double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fOffsetX, double fOffsetY, double *fLineColor)
1449
const GLfloat *pVertexTab = cairo_dock_generate_rectangle_path (fFrameWidth, fFrameHeight, fRadius, TRUE, &iNbVertex);
1451
if (fLineWidth == 0)
1453
if (fLineColor != NULL)
1454
glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]);
1455
cairo_dock_draw_frame_background_opengl (0, fFrameWidth+2*fRadius, fFrameHeight, fOffsetX, fOffsetY, pVertexTab, iNbVertex, CAIRO_DOCK_HORIZONTAL, TRUE, 0.);
1459
_cairo_dock_set_vertex_pointer (pVertexTab);
1460
glTranslatef ((int) (fOffsetX + fFrameWidth/2), (int) (fOffsetY - fFrameHeight/2), -1);
1461
glScalef (fFrameHeight, fFrameWidth, 1.);
1462
cairo_dock_draw_current_path_opengl (fLineWidth, fLineColor, iNbVertex);
1467
// A utiliser un jour.
1469
typedef struct _CairoAnimatedImage {
1470
cairo_surface_t *pSurface;
1472
gint iFrameWidth, iFrameHeight;
1475
} CairoAnimatedImage;
1477
void cairo_dock_load_animated_image (const gchar *cImageFile, int iNbFrames, int iFrameWidth, int iFrameHeight, cairo_t *pSourceContext, CairoAnimatedImage *pAnimatedImage)
1479
pAnimatedImage->iNbFrames = iNbFrames;
1480
pAnimatedImage->iCurrentFrame = 0;
1482
pAnimatedImage->iFrameWidth = iFrameWidth * iNbFrames;
1483
pAnimatedImage->iFrameHeight = iFrameHeight;
1484
pAnimatedImage->pSurface = cairo_dock_create_surface_from_image_simple (cImageFile,
1486
pAnimatedImage->iFrameWidth,
1487
pAnimatedImage->iFrameHeight);
1489
if (g_bUseOpenGL && pAnimatedImage->pSurface != NULL)
1491
pAnimatedImage->iTexture = cairo_dock_create_texture_from_surface (pAnimatedImage->pSurface);
1495
CairoAnimatedImage *cairo_dock_create_animated_image (const gchar *cImageFile, int iNbFrames, int iFrameWidth, int iFrameHeight, cairo_t *pSourceContext)
1497
CairoAnimatedImage *pAnimatedImage = g_new0 (CairoAnimatedImage, 1);
1499
cairo_dock_load_animated_image (cImageFile, iNbFrames, iFrameWidth, iFrameHeight, pSourceContext, pAnimatedImage);
1501
return pAnimatedImage;
1504
#define cairo_dock_update_animated_image_state(pAnimatedImage) do {\
1505
(pAnimatedImage)->iCurrentFrame ++;\
1506
if ((pAnimatedImage)->iCurrentFrame == (pAnimatedImage)->iNbFrames)\
1507
(pAnimatedImage)->iCurrentFrame = 0; } while (0)
1509
void cairo_dock_update_animated_image_cairo (CairoAnimatedImage *pAnimatedImage, cairo_t *pCairoContext)
1511
cairo_dock_update_animated_image_state (pAnimatedImage);
1512
cairo_save (pCairoContext);
1513
cairo_rectangle (pCairoContext, 0., 0., pAnimatedImage->iFrameWidth, pAnimatedImage->iFrameHeight);
1514
cairo_clip (pCairoContext);
1515
cairo_set_source_surface (pCairoContext,
1516
pAnimatedImage->pSurface,
1517
- pAnimatedImage->iFrameWidth * pAnimatedImage->iCurrentFrame,
1519
cairo_restore (pCairoContext);
1522
void cairo_dock_update_animated_image_opengl (CairoAnimatedImage *pAnimatedImage)
1524
cairo_dock_update_animated_image_state (pAnimatedImage);
1525
_cairo_dock_apply_current_texture_portion_at_size_with_offset (1.*pAnimatedImage->iCurrentFrame/pAnimatedImage->iNbFrames, 0.,
1526
1. / pAnimatedImage->iNbFrames, 1.,
1527
pAnimatedImage->iFrameWidth, pAnimatedImage->iFrameHeight,
1537
typedef struct _CairoDockOpenglPath {
1539
GLfloat *pVertexTab;
1542
gint iWidthExtent, iHeightExtent;
1543
} CairoDockOpenglPath;
1545
#define _cairo_dock_ith_vertex_x(pVertexPath, i) (pVertexPath)->pVertexTab[i*_CAIRO_DOCK_PATH_DIM]
1546
#define _cairo_dock_ith_vertex_y(pVertexPath, i) (pVertexPath)->pVertexTab[i*_CAIRO_DOCK_PATH_DIM+1]
1547
#define _cairo_dock_set_ith_vertex_x(pVertexPath, i, x) _cairo_dock_ith_vertex_x(pVertexPath, i) = x
1548
#define _cairo_dock_set_ith_vertex_y(pVertexPath, i, y) _cairo_dock_ith_vertex_y(pVertexPath, i) = y
1549
#define cairo_dock_get_current_vertex_x(pVertexPath) _cairo_dock_ith_vertex_x(pVertexPath, pVertexPath->iCurrentIndex-1)
1550
#define cairo_dock_get_current_vertex_y(pVertexPath) _cairo_dock_ith_vertex_y(pVertexPath, pVertexPath->iCurrentIndex-1)
1551
#define cairo_dock_add_vertex(pVertexPath, x, y) do {\
1552
_cairo_dock_set_ith_vertex_x (pVertexPath, (pVertexPath)->iCurrentIndex, x);\
1553
_cairo_dock_set_ith_vertex_y (pVertexPath, (pVertexPath)->iCurrentIndex, y);\
1554
(pVertexPath)->iCurrentIndex ++; } while (0)
1556
void cairo_dock_add_curved_subpath_opengl (CairoDockOpenglPath *pVertexPath, int iNbPts, double x1, double y1, double x2, double y2, double x3, double y3)
1558
double x0 = cairo_dock_get_current_vertex_x (pVertexPath); // doit avoir ete initialise.
1559
double y0 = cairo_dock_get_current_vertex_y (pVertexPath);
1562
for (i = 1; i < iNbPts+1; i ++)
1564
t = 1.*i/iNbPts; // ]0;1]
1565
cairo_dock_add_vertex(pVertexPath,
1566
Bezier (x0,x1,x2,x3,t),
1567
Bezier (y0,y1,y2,y3,t));
1568
//vx(i) = Bezier (x0,x1,x2,x3,t);
1569
//vy(i) = Bezier (y0,y1,y2,y3,t);
1575
GLuint cairo_dock_create_texture_from_text_simple (const gchar *cText, const gchar *cFontDescription, cairo_t* pSourceContext, int *iWidth, int *iHeight)
1577
g_return_val_if_fail (cText != NULL && cFontDescription != NULL, 0);
1579
//\_________________ On ecrit le texte dans un calque Pango.
1580
PangoLayout *pLayout = pango_cairo_create_layout (pSourceContext);
1582
PangoFontDescription *fd = pango_font_description_from_string (cFontDescription);
1583
pango_layout_set_font_description (pLayout, fd);
1584
pango_font_description_free (fd);
1586
pango_layout_set_text (pLayout, cText, -1);
1588
//\_________________ On cree une surface aux dimensions du texte.
1589
PangoRectangle ink, log;
1590
pango_layout_get_pixel_extents (pLayout, &ink, &log);
1591
cairo_surface_t* pNewSurface = _cairo_dock_create_blank_surface (pSourceContext,
1594
*iWidth = log.width;
1595
*iHeight = log.height;
1597
//\_________________ On dessine le texte.
1598
cairo_t* pCairoContext = cairo_create (pNewSurface);
1599
cairo_translate (pCairoContext, -log.x, -log.y);
1600
cairo_set_source_rgb (pCairoContext, 1., 1., 1.);
1601
cairo_move_to (pCairoContext, 0, 0);
1602
pango_cairo_show_layout (pCairoContext, pLayout);
1603
cairo_destroy (pCairoContext);
1605
g_object_unref (pLayout);
1607
//\_________________ On cree la texture.
1608
GLuint iTexture = cairo_dock_create_texture_from_surface (pNewSurface);
1609
cairo_surface_destroy (pNewSurface);
1614
CairoDockGLFont *cairo_dock_load_bitmap_font (const gchar *cFontDescription, int first, int count)
1616
g_return_val_if_fail (cFontDescription != NULL && count > 0, NULL);
1618
GLuint iListBase = glGenLists (count);
1619
g_return_val_if_fail (iListBase != 0, NULL);
1621
CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
1622
pFont->iListBase = iListBase;
1623
pFont->iNbChars = count;
1624
pFont->iCharBase = first;
1626
PangoFontDescription *fd = pango_font_description_from_string (cFontDescription);
1627
PangoFont *font = gdk_gl_font_use_pango_font (fd,
1631
g_return_val_if_fail (font != NULL, NULL);
1633
PangoFontMetrics* metrics = pango_font_get_metrics (font, NULL);
1634
pFont->iCharWidth = pango_font_metrics_get_approximate_char_width (metrics) / PANGO_SCALE;
1635
pFont->iCharHeight = (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE;
1636
pango_font_metrics_unref(metrics);
1638
pango_font_description_free (fd);
1642
CairoDockGLFont *cairo_dock_load_textured_font (const gchar *cFontDescription, int first, int count)
1644
g_return_val_if_fail (g_pMainDock != NULL && count > 0, NULL);
1645
if (first < 32) // 32 = ' '
1647
count -= (32 - first);
1650
gchar *cPool = g_new0 (gchar, 4*count + 1);
1653
for (i = 0; i < count; i ++)
1661
if ((c > 126 && c < 126 + 37) || (c == 173)) // le 173 est un caractere bizarre (sa taille est nulle).
1667
j += MAX (0, sprintf (cPool+j, "%lc", c)); // les caracteres ASCII >128 doivent etre convertis en multi-octets.
1670
cd_debug ("%s (%d + %d -> '%s')", __func__, first, count, cPool);
1671
/*iconv_t cd = iconv_open("UTF-8", "ISO-8859-1");
1672
gchar *outbuf = g_new0 (gchar, count*4+1);
1673
gchar *outbuf0 = outbuf, *inbuf0 = cPool;
1674
size_t inbytesleft = count;
1675
size_t outbytesleft = count*4;
1676
size_t size = iconv (cd,
1677
&cPool, &inbytesleft,
1678
&outbuf, &outbytesleft);
1679
g_print ("%d bytes left, %d bytes written => '%s'\n", inbytesleft, outbytesleft, outbuf0);
1684
int iWidth, iHeight;
1685
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
1686
GLuint iTexture = cairo_dock_create_texture_from_text_simple (cPool, cFontDescription, pCairoContext, &iWidth, &iHeight);
1687
cairo_destroy (pCairoContext);
1690
CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
1691
pFont->iTexture = iTexture;
1692
pFont->iNbChars = count;
1693
pFont->iCharBase = first;
1695
pFont->iNbColumns = count;
1696
pFont->iCharWidth = (double)iWidth / count;
1697
pFont->iCharHeight = iHeight;
1699
cd_debug ("%d char / %d pixels => %.3f", count, iWidth, (double)iWidth / count);
1703
CairoDockGLFont *cairo_dock_load_textured_font_from_image (const gchar *cImagePath)
1705
double fImageWidth, fImageHeight;
1706
GLuint iTexture = cairo_dock_create_texture_from_image_full (cImagePath, &fImageWidth, &fImageHeight);
1707
g_return_val_if_fail (iTexture != 0, NULL);
1709
CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
1710
pFont->iTexture = iTexture;
1711
pFont->iNbChars = 256;
1712
pFont->iCharBase = 0;
1713
pFont->iNbRows = 16;
1714
pFont->iNbColumns = 16;
1715
pFont->iCharWidth = fImageWidth / pFont->iNbColumns;
1716
pFont->iCharHeight = fImageHeight / pFont->iNbRows;
1720
void cairo_dock_free_gl_font (CairoDockGLFont *pFont)
1724
if (pFont->iListBase != 0)
1725
glDeleteLists (pFont->iListBase, pFont->iNbChars);
1726
if (pFont->iTexture != 0)
1727
_cairo_dock_delete_texture (pFont->iTexture);
1732
void cairo_dock_get_gl_text_extent (const gchar *cText, CairoDockGLFont *pFont, int *iWidth, int *iHeight)
1734
if (pFont == NULL || cText == NULL)
1740
int i, w=0, wmax=0, h=pFont->iCharHeight;
1741
for (i = 0; cText[i] != '\0'; i ++)
1743
if (cText[i] == '\n')
1745
h += pFont->iCharHeight + 1;
1746
wmax = MAX (wmax, w);
1750
w += pFont->iCharWidth;
1753
*iWidth = MAX (wmax, w);
1758
void cairo_dock_draw_gl_text (const guchar *cText, CairoDockGLFont *pFont)
1760
int n = strlen (cText);
1761
if (pFont->iListBase != 0)
1763
if (pFont->iCharBase == 0 && strchr (cText, '\n') == NULL) // version optimisee ou on a charge tous les caracteres.
1765
glDisable (GL_TEXTURE_2D);
1766
glListBase (pFont->iListBase);
1767
glCallLists (n, GL_UNSIGNED_BYTE, (unsigned char *)cText);
1773
for (i = 0; i < n; i ++)
1775
if (cText[i] == '\n')
1778
glGetFloatv (GL_CURRENT_RASTER_POSITION, rpos);
1779
glRasterPos2f (rpos[0], rpos[1] + pFont->iCharHeight + 1);
1782
if (cText[i] < pFont->iCharBase || cText[i] >= pFont->iCharBase + pFont->iNbChars)
1784
j = cText[i] - pFont->iCharBase;
1785
glCallList (pFont->iListBase + j);
1789
else if (pFont->iTexture != 0)
1791
_cairo_dock_enable_texture ();
1792
glBindTexture (GL_TEXTURE_2D, pFont->iTexture);
1793
double u, v, du=1./pFont->iNbColumns, dv=1./pFont->iNbRows, w=pFont->iCharWidth, h=pFont->iCharHeight, x=.5*w, y=.5*h;
1795
for (i = 0; i < n; i ++)
1797
if (cText[i] == '\n')
1799
x = .5*pFont->iCharWidth;
1800
y += pFont->iCharHeight + 1;
1803
if (cText[i] < pFont->iCharBase || cText[i] >= pFont->iCharBase + pFont->iNbChars)
1806
j = cText[i] - pFont->iCharBase;
1807
u = (double) (j%pFont->iNbColumns) / pFont->iNbColumns;
1808
v = (double) (j/pFont->iNbColumns) / pFont->iNbRows;
1809
_cairo_dock_apply_current_texture_portion_at_size_with_offset (u, v, du, dv, w, h, x, y);
1810
x += pFont->iCharWidth;
1812
_cairo_dock_disable_texture ();
1816
void cairo_dock_draw_gl_text_in_area (const guchar *cText, CairoDockGLFont *pFont, int iWidth, int iHeight, gboolean bCentered)
1818
g_return_if_fail (pFont != NULL && cText != NULL);
1819
if (pFont->iListBase != 0) // marche po sur du raster.
1821
cd_warning ("can't resize raster ! use a textured font inside.");
1825
int n = strlen (cText);
1827
cairo_dock_get_gl_text_extent (cText, pFont, &w, &h);
1830
if (fabs ((double)iWidth/w) < fabs ((double)iHeight/h)) // on autorise les dimensions negatives pour pouvoir retourner le texte.
1832
zx = (double)iWidth/w;
1833
zy = (iWidth*iHeight > 0 ? zx : -zx);
1837
zy = (double)iHeight/h;
1838
zx = (iWidth*iHeight > 0 ? zy : -zy);
1841
glScalef (zx, zy, 1.);
1843
glTranslatef (-w/2, -h/2, 0.);
1844
cairo_dock_draw_gl_text (cText, pFont);
1848
void cairo_dock_draw_gl_text_at_position (const guchar *cText, CairoDockGLFont *pFont, int x, int y)
1850
g_return_if_fail (pFont != NULL && cText != NULL);
1851
if (pFont->iListBase != 0)
1853
glRasterPos2f (x, y);
1857
glTranslatef (x, y, 0);
1859
cairo_dock_draw_gl_text (cText, pFont);
1862
void cairo_dock_draw_gl_text_at_position_in_area (const guchar *cText, CairoDockGLFont *pFont, int x, int y, int iWidth, int iHeight, gboolean bCentered)
1864
g_return_if_fail (pFont != NULL && cText != NULL);
1865
if (pFont->iListBase != 0) // marche po sur du raster.
1867
cd_warning ("can't resize raster ! use a textured font inside.");
1871
glTranslatef (x, y, 0);
1872
cairo_dock_draw_gl_text_in_area (cText, pFont, iWidth, iHeight, bCentered);
1878
typedef void (*GLXBindTexImageProc) (Display *display, GLXDrawable drawable, int buffer, int *attribList);
1879
typedef void (*GLXReleaseTexImageProc) (Display *display, GLXDrawable drawable, int buffer);
1881
// Bind redirected window to texture:
1882
GLuint cairo_dock_texture_from_pixmap (Window Xid, Pixmap iBackingPixmap)
1884
return 0; /// ca ne marche pas. :-(
1886
if (! g_openglConfig.bTextureFromPixmapAvailable)
1889
Display *display = gdk_x11_get_default_xdisplay ();
1890
XWindowAttributes attrib;
1891
XGetWindowAttributes (display, Xid, &attrib);
1893
VisualID visualid = XVisualIDFromVisual (attrib.visual);
1897
GLXFBConfig *fbconfigs = glXGetFBConfigs (display, screen, &nfbconfigs);
1899
GLfloat top=0., bottom=0.;
1900
XVisualInfo *visinfo;
1903
for (i = 0; i < nfbconfigs; i++)
1905
visinfo = glXGetVisualFromFBConfig (display, fbconfigs[i]);
1906
if (!visinfo || visinfo->visualid != visualid)
1909
glXGetFBConfigAttrib (display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
1910
if (!(value & GLX_PIXMAP_BIT))
1913
glXGetFBConfigAttrib (display, fbconfigs[i],
1914
GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1916
if (!(value & GLX_TEXTURE_2D_BIT_EXT))
1919
glXGetFBConfigAttrib (display, fbconfigs[i],
1920
GLX_BIND_TO_TEXTURE_RGBA_EXT,
1924
glXGetFBConfigAttrib (display, fbconfigs[i],
1925
GLX_BIND_TO_TEXTURE_RGB_EXT,
1931
glXGetFBConfigAttrib (display, fbconfigs[i],
1948
if (i == nfbconfigs)
1950
cd_warning ("No FB Config found");
1954
int pixmapAttribs[5] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
1955
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
1957
GLXPixmap glxpixmap = glXCreatePixmap (display, fbconfigs[i], iBackingPixmap, pixmapAttribs);
1958
g_return_val_if_fail (glxpixmap != 0, 0);
1961
glEnable (GL_TEXTURE_2D);
1962
glGenTextures (1, &texture);
1963
glBindTexture (GL_TEXTURE_2D, texture);
1965
g_openglConfig.bindTexImage (display, glxpixmap, GLX_FRONT_LEFT_EXT, NULL);
1967
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1968
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1970
// draw using iBackingPixmap as texture
1973
glTexCoord2d (0.0f, bottom);
1974
glVertex2d (0.0f, 0.0f);
1976
glTexCoord2d (0.0f, top);
1977
glVertex2d (0.0f, 1.0f);
1979
glTexCoord2d (1.0f, top);
1980
glVertex2d (1.0f, 1.0f);
1982
glTexCoord2d (1.0f, bottom);
1983
glVertex2d (1.0f, 0.0f);
1986
glDisable (GL_TEXTURE_2D);
1988
g_openglConfig.releaseTexImage (display, glxpixmap, GLX_FRONT_LEFT_EXT);
1989
glXDestroyGLXPixmap (display, glxpixmap);