Feeling

              三人行,必有我師焉

             ::  :: 新隨筆 :: 聯系 ::  :: 管理 ::
            185 隨筆 :: 0 文章 :: 392 評論 :: 0 Trackbacks
          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 }

          特效截圖:

          posted on 2008-04-30 15:54 三人行,必有我師焉 閱讀(3550) 評論(3)  編輯  收藏

          評論

          # re: Vista Glossy 效果的實現 2008-04-30 17:46 BeanSoft
          不錯,已經開始深入Windows內核了,呵呵。支持下,Java做界面最后總得進入系統級,沒辦法。  回復  更多評論
            

          # re: Vista Glossy 效果的實現 2008-04-30 17:52 三人行,必有我師焉
          現在Linux GTK Extension也已經啟動了,雖然無法做到API一致,但是希望盡量擴大2個系統的交集。  回復  更多評論
            

          # re: Vista Glossy 效果的實現[未登錄] 2008-05-10 10:55 stonebow
          請問GC是什么呢?  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          GitHub |  開源中國社區 |  maven倉庫 |  文件格式轉換 
          主站蜘蛛池模板: 六安市| 太康县| 盘锦市| 司法| 稻城县| 社旗县| 运城市| 德阳市| 松滋市| 渭源县| 娄烦县| 睢宁县| 青川县| 漾濞| 长春市| 梁平县| 龙州县| 天峨县| 安乡县| 琼海市| 抚州市| 大安市| 曲阜市| 梧州市| 岳西县| 句容市| 镇巴县| 惠州市| 蛟河市| 金昌市| 仙游县| 贵德县| 象州县| 天镇县| 田阳县| 略阳县| 鸡西市| 莆田市| 宜城市| 麻江县| 孟村|