Vista Glossy 效果的实现

Vista Glossy 效果的实现
Glossy 效果,顾名思义,就是玻璃质的光泽透明的效果,在Windows平台下的应用越来越广泛,从Media Player10开始,它的button已经运用上了此效果。现在但凡是微软新发布的软件,十有八九都带有glossy特效。Glossy 效果使用了Gdi Plus的API,因此在Win98和Win2000下,必须安装gdiplus.dll才能使用,此动态链接库不大,只有700多K,但是想要在自己的应用程序中画出绚丽多彩的效果,那是少不了这个小东西的。关于Glossy效果的描述,可以参见CodeProject上的一片文章 WindowsVistaRenderer,http://www.codeproject.com/KB/vista/WindowsVistaRenderer.aspx

Glossy特效有一个重要的组成部分,就是椭圆的光晕,此效果在Linux下可能并没有实现(并未下定论,我还没有深入研究过Linux下的图形库), 所以SWT的Gdip并没有将其公开出来,而是放入custom的API里,也就是说,你可以自行调用此效果的API,但是SWT并不负责为你提供封装, 因此你并不能使用GC来实现该特效,这对我们的界面开发极为不利,自己调用Gdip的API,繁琐不说,还很容易导致JVM退出。

为了能够方便的使用GC来画出此特效,我们不得不采用一些非常规的手段:反射。利用反射我们可以拿到GC的一些内部数据,在这个地方,我们只需要拿到GCData就可以,它包含了画图所需要具备的元素。Glossy效果需要使用PathGradientBrush,我们把这个刷子赋给GCData,就可以使用GC来画出glossy特效了。
 1  public   class  GCExtension {
 2 
 3       private  GC gc;
 4 
 5       private  GCData data;
 6 
 7       public  GCExtension(GC gc) {
 8           this .gc  =  gc;
 9          data  =  getGCData(gc);
10      }
11 
12       public   void  fillGradientPath(Path path,  float [] centerPoint,
13              Color centerColor,  int  centerColorAlpha, Color[] surroundColors,
14               int [] surroundColorAlphas) {
15           if  (gc  ==   null   ||  gc.handle  ==   0 )
16              SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
17           if  (path  ==   null   ||  centerPoint  ==   null   ||  centerColor  ==   null
18                   ||  surroundColorAlphas  ==   null )
19              SWT.error(SWT.ERROR_NULL_ARGUMENT);
20           if  (path.handle  ==   0   ||  centerPoint.length  <   2
21                   ||  centerColor.handle  ==   0
22                   ||  surroundColors.length  !=  surroundColorAlphas.length)
23              SWT.error(SWT.ERROR_INVALID_ARGUMENT);
24           for  ( int  i  =   0 ; i  <  surroundColors.length; i ++ ) {
25               if  (surroundColors[i]  ==   null   ||  surroundColors[i].handle  ==   0 )
26                  SWT.error(SWT.ERROR_INVALID_ARGUMENT);
27          }
28 
29           int  brush  =  Gdip.PathGradientBrush_new(path.handle);
30           if  (brush  ==   0 )
31              SWT.error(SWT.ERROR_NO_HANDLES);
32          PointF point  =   new  PointF();
33          point.X  =  centerPoint[ 0 ];
34          point.Y  =  centerPoint[ 1 ];
35          Gdip.PathGradientBrush_SetCenterPoint(brush, point);
36 
37           int  colorRef  =  centerColor.handle;
38           int  rgb  =  ((colorRef  >>   16 &   0xFF |  (colorRef  &   0xFF00 )
39                   |  ((colorRef  &   0xFF <<   16 );
40           int  color  =  Gdip.Color_new(centerColorAlpha  <<   24   |  rgb);
41           if  (color  ==   0 )
42              SWT.error(SWT.ERROR_NO_HANDLES);
43          Gdip.PathGradientBrush_SetCenterColor(brush, color);
44          Gdip.Color_delete(color);
45 
46           int [] colors  =   new   int [surroundColors.length];
47           for  ( int  i  =   0 ; i  <  surroundColors.length; i ++ ) {
48              colorRef  =  surroundColors[i].handle;
49              rgb  =  ((colorRef  >>   16 &   0xFF |  (colorRef  &   0xFF00 )
50                       |  ((colorRef  &   0xFF <<   16 );
51              colors[i]  =  Gdip.Color_new(surroundColorAlphas[i]  <<   24   |  rgb);
52               if  (colors[i]  ==   0 )
53                  SWT.error(SWT.ERROR_NO_HANDLES);
54          }
55          Gdip.PathGradientBrush_SetSurroundColors(brush, colors,
56                   new   int [] { colors.length });
57           for  ( int  i  =   0 ; i  <  surroundColors.length; i ++ ) {
58              Gdip.Color_delete(colors[i]);
59          }
60          data.gdipBrush  =  brush;
61           boolean  advanced  =  gc.getAdvanced();
62           if  ( ! advanced)
63              gc.setAdvanced( true );
64           int  mode  =  Extension.GetPolyFillMode(gc.handle)  ==  Extension.WINDING  ?  Gdip.FillModeWinding
65                  : Gdip.FillModeAlternate;
66          Gdip.GraphicsPath_SetFillMode(path.handle, mode);
67          Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, path.handle);
68           if  ( ! advanced)
69              gc.setAdvanced( false );
70           if  (data.gdipBrush  !=   0 ) {
71              Gdip.PathGradientBrush_delete(data.gdipBrush);
72              data.gdipBrush  =   0 ;
73          }
74      }
75 
76       private  GCData getGCData(GC gc) {
77          GCData data  =   null ;
78           try  {
79              Object obj  =   null ;
80              Field field  =  gc.getClass().getDeclaredField( " data " );
81               if  (field  !=   null ) {
82                  field.setAccessible( true );
83                  obj  =  field.get(gc);
84              }
85               if  (obj  !=   null   &&  obj  instanceof  GCData)
86                  data  =  (GCData) obj;
87          }  catch  (Exception e) {
88 
89          }
90           return  data;
91      }
92  }

特效截图:

你可能感兴趣的:(Vista Glossy 效果的实现)