选择显示字体大小

.net compact framework的强大二维图形引擎

简介
  对于移动设备而言,.net compact framework 即使不是最佳的 api,也是极好的 api。它的图形引擎受到很大的限制,以便提高呈现速度和降低内存消耗。但是,它似乎远远无法满足用户日益增长的对更好的图形体验的要求。尝试去获得 .net compact framework 中的一些高级矢量图形呈现功能可能是一项乏味的任务。开发人员具有两个选择:

  1.求助于本机代码。例如,pocket pc game api 可能是一项不错的选择。它的性能令人印象深刻。有关详细信息,请参阅位于以下位置的一篇非常全面的文章:http://msdn.microsoft.com/mobility/samples/default.aspx?pull=/library/en-us/d.netcomp/html/gmangame.asp。问题在于本机代码不支持矢量图形呈现,并且与某些设备不兼容。此外,它可能无法与 pocket pc 仿真程序协同工作。您可以想象调试这样的程序有多么困难。

  2.请等待下一代移动图形引擎问世。据我所知,windows ce 5 中将包含一个强大的 direct3d mobile引擎。这对于移动游戏开发人员来说是一个好消息,但是 direct3d 不适合于二维图形。它太复杂了,因而无法在一般应用程序中应用。

  我们所需要的是像 gdi+ 这样强大而易于使用的二维图形引擎。因此,我从零开始开发 xrossone gdi+ 项目。它完全是用 c# 托管代码编写的,不包含任何本机代码或不安全的代码。经过几个月的艰苦工作之后,我终于可以在本文开头提供可下载的原始版本。

开始工作
  从该项目一开始,我就一直铭记 xrossone gdi+ 引擎应当对不同的手持设备和平台保持中立。结果,它可以与 pocket pc、windows ce、smartphones、windows .net 和 mono 兼容。您可以将同一个运行库复制到不同的目标,而它仍然可以正常工作。

下表概括了总体体系结构。

      层             命名空间
  xrossone gdi+ api       xrossone.drawing
  基于定点的二维图形引擎    xrossone.drawingfp
 16.16 定点计算引擎       xrossone.fixedpoint

  xrossone gdi+ 中有三个层。最低层为“16.16 定点计算引擎”。其中一个主类 — mathfp — 是从 beartronics j2me 库 改编而来的。一些函数已经进行了优化,其中包括 sqrt、atan 和 pointfp.distancecalculation。在命名空间 xrossone.fixedpoint 下面,有其他三个类:singlefp、doublefp 和 matrixfp。singlefp 是一个用于 16.16 定点数的 helper 类。它为在定点类型和标准类型(int、float、string)之间进行转换提供了方便。matrixfp 是为定点二维变换编写的。因为定点计算的精度较低,所以级联变换可能会损失一些精确性。例如,在大多数情况下,两次求逆运算无法还原原始矩阵。doublefp 的存在是为了使该库完备,但尚未使用。

  “基于定点的二维图形引擎”是 xrossone gdi+ 的内核。它实现了很多复杂的矢量图形算法,例如,反锯齿绘图、线帽/联接装饰、二维变换、渐变填充、alpha 通道合成等等。这里可以找到本机 gdi+ 中的大多数高级功能。但是,您只应在少数情况下直接使用它,因为它的基于定点的接口对于程序员而言不够友好,但是不必过分担心这种情况。有一个封装良好的 api 可供使用。您可以在 xrossone.drawing 命名空间中找到它们。xrossone.drawing 中的类非常类似于 system.drawing 中的类,不同之处在于每个类的末尾有一个字母“x”。例如,xrossone.drawing.penx 类等效于 system.drawing.pen。有一个用于将 gdi+ 程序转换到 xrossone gdi+ 的小窍门。在 using 节中,将 xrossone gdi+ 类重命名为它们的等效类。例如:

using pen = xrossone.drawing.penx;
using lineargradientbrush = xrossone.drawing. lineargradientbrushx;
using matrix = xrossone.drawing.matrixx;



主要功能
反锯齿矢量图形绘图

  通过 xrossone mobile gdi+ 可以呈现所有种类的二维几何图形,例如,线段、矩形、多边形、椭圆、扇形、贝塞尔样条曲线、基数样条曲线等等。但是,扇形、贝塞尔样条曲线和基数样条曲线在 .net compact framework 中不可用。此外,所有图形在呈现时都自动进行反锯齿处理。这有助于获得超级平滑质量。在 .net compact framework 中,画笔的宽度被固定为 1 个像素。这一限制在 xrossone gdi+ 中不存在。画笔的不同大小可以应用于所有图形的轮廓,如图 1 所示。


图 1. 反锯齿矢量图形绘图



  代码示例 1

//clear the background and reset the transform state
gx.clear(color.white);
gx.resettransform();
//draw skew grid as the background
penx pen = new penx(utils.fromargb(0x40, color.lightgray), 5);
for (int i = -height; i < width + height; i+=20)
{
gx.drawline(pen, i, 0, i + height, height);
gx.drawline(pen, i, 0, i - height, height);
}

//draw a darkmagenta rectangle with a 10.5-pixel pen
color c = utils.fromargb(0x80, color.darkmagenta);
pen = new penx(c, 10.5f);
gx.drawrectangle(pen, 50, 20, 150, 200);

//fill a greenyellow rectangle
c = utils.fromargb(0xa0, color.greenyellow);
brushx brush = new solidbrushx(c);
gx.fillrectangle(brush, 120, 50, 90, 150);

//draw a blueviolet ellipse with a 10.5-pixel pen
c = utils.fromargb(0x80, color.blueviolet);
pen = new penx(c, 10.5f);
gx.drawellipse(pen, 50, 20, 150, 80);

//fill a red ellipse
c = utils.fromargb(0xa0, color.red);
brush = new solidbrushx(c);
gx.fillellipse(brush, 20, 50, 80, 150);

//draw a hotpink pie from 156.5 degree to -280.9 degree
pen.color = utils.fromargb(0xa0, color.hotpink);
gx.drawpie(pen, 3.6f, 120.3f, 200.8f, 130.1f, 156.5f, -280.9f);

//draw orange bezier curves
c = utils.fromargb(0xa0, color.orange);
pen = new penx(c, 16);
point start = new point(70, 100);
point control1 = new point(100, 10);
point control2 = new point(150, 50);
point end1 = new point(200, 200);
point control3 = new point(100, 150);
point control4 = new point(50, 200);
point end2 = new point(10, 150);
point[] bezierpoints ={start, control1, control2, end1, control3, control4, end2};
pen.endcap = linecapx.round;
gx.drawbeziers(pen, bezierpoints);

//refresh
invalidate();



  xrossone gdi+ 和本机 gdi+ 的矢量图形输出是相同的,但基数样条曲线除外。我的算法取自 jean-yves queinec 撰写的文章 smoothing algorithm using bezier curves。因此,您可能发现在它们的输出之间存在一些差异,如下面的图 2 所示。


图 2. drawcurve/drawclosedcurve 的输出



  尽管大多数矢量图形呈现函数都已经得到实现,但仍然有一些工作需要完成。某些函数(drawstring、drawimage、drawpath 等等)直到下一个版本才可用。


线帽/联接装饰

  为了使 .net compact framework 保持紧凑,gdi+ 桌面版本中的很多功能在该精简版本中不可用。其中一项功能是线帽/联接装饰。当然,当轮廓的宽度为一个像素时,任何装饰都似乎是不必要的,但是在 xrossone gdi+ 中,线帽/联接装饰却是绘制不同大小的轮廓所必备的。xrossone gdi+ 中支持四个线帽(flat、round、triangle 和 square)和三个线段联接(bevel、miter 和 round)。上述装饰的示例如图 3 所示。


图 3. 线帽/联接装饰



  代码示例 2

//clear the background and reset the transform state
gx.clear(color.white);
gx.resettransform();

//draw a pentacle with miter line join and round line cap
penx pen = new penx(color.orange, 15);
point p1 = new point(150, 80);
point p2 = new point(100, 230);
point p3 = new point(240, 150);
point p4 = new point(60, 150);
point p5 = new point(200, 230);
point[] points ={p1,p2,p3,p4,p5};
matrixx m = new matrixx();
m.translate(-26, -70);
m.transformpoints(points);
pen.linejoin = linejoinx.miter;
pen.endcap = linecapx.round;
pen.startcap = linecapx.round;
gx.drawlines(pen, points);

//draw a pentacle with bevel line join and triangle line cap
pen = new penx(utils.fromargb(0x80, color.blue), 15);
point[] points2 ={p1,p2,p3,p4,p5};
m = new matrixx();
m.translate(-10, -30);
m.transformpoints(points2);
pen.linejoin = linejoinx.bevel;
pen.startcap = linecapx.triangle;
gx.drawlines(pen, points2);

//draw a pentacle with round line join and round line cap
pen = new penx(utils.fromargb(0x80, color.blueviolet), 20);
point[] points3 ={p1,p2,p3,p4,p5};
m = new matrixx();
m.translate(-40, 20);
m.transformpoints(points3);
pen.linejoin = linejoinx.round;
pen.endcap = linecapx.round;
gx.drawlines(pen, points3);

//refresh
invalidate();



二维变换

  变换功能在 .net compact framework 中不可用,这意味着,如果您要通过 30 度旋转来绘制椭圆,则您必须计算它的轮廓并且逐个像素地绘制它。在大多数情况下,这是乏味和低效的。幸运的是,xrossone gdi+ 提供了功能完善的二维变换。您可以移动、缩放和旋转您喜欢的任何图形,如图 4 所示。


图 4. 二维变换



  代码示例 3

//clear the background and reset the transform state
gx.clear(color.white);
gx.resettransform();

//draw a rectangle and apply scale transform to it
color c = utils.fromargb(0x80, color.orange);
penx pen = new penx(c, 7.5f);
pen.linejoin = linejoinx.miter;
gx.drawrectangle(pen, 10, 10, 50, 50);
gx.scaletransform(3, 3);
gx.drawrectangle(pen, 10, 10, 50, 50);

//draw a series of ellipses and rotate 10 degrees between the preceding and the successor
c = utils.fromargb(0x80, color.blueviolet);
pen = new penx(c, 5.5f);
gx.scaletransform(0.25f, 0.25f);
gx.rotatetransform(-40);
for (int j = 0; j < 10; j ++)
{
gx.rotatetransform(10);
gx.drawellipse(pen, 100, 50, 50, 130);
}

//draw a series of triangles and apply translate transform to them
pen = new penx(utils.fromargb(0x80, color.blue), 10);
point p1 = new point(120, 80);
point p2 = new point(100, 200);
point p3 = new point(140, 200);
point[] points ={p1,p2,p3};
gx.transform = new matrixx();
pen.linejoin = linejoinx.round;
for (int i = 0; i <= 40; i +=10)
{
gx.translatetransform(20, 10);
gx.drawpolygon(pen, points);
}

//refresh
invalidate();




渐变填充

  在本机 gdi+ 中有五种画刷 — solidbrush、lineargradientbrush、pathgradientbrush、texturebrush 和 hatchbrush。但是,在该版本中,只有 solidbrush 和 lineargradientbrush 可用。xrossone gdi+ 支持 radialgradientbrush 而不是 pathgradientbrush。下面的图 5 演示了渐变填充。


图 5. 渐变填充



  代码示例 4

//clear the background and reset the transform state
gx.clear(color.white);
gx.resettransform();

//fill a rectangle with a black-white lineargradientbrushx
rectangle r = new rectangle(20, 50, 300, 100);
color c1 = color.black;
color c2 = color.white;
brushx brush1 = new lineargradientbrushx(r, c1, c2, 30f);
gx.fillrectangle(brush1, r);

//fill a rectangle with a 7-color lineargradientbrushx
r = new rectangle(90, 100, 150, 100);
lineargradientbrushx br = new lineargradientbrushx(r,color.black,color.black, 60f);
colorblendx cb = new colorblendx();
cb.positions=new float[7];
int i=0;
for(float f=0;f<=1;f+=1.0f/6)
cb.positions[i++]=f;
cb.colors=new color[]
{color.red,color.orange,color.yellow,color.green,color.blue,color.indigo,color.violet};
br.interpolationcolors=cb;
gx.translatetransform(160, 10);
gx.rotatetransform(60f);
gx.fillrectangle(br, r);

//fill a rectangle with a 7-color radialgradientbrushx
r.y += 50;
radialgradientbrushx brush2 = new radialgradientbrushx(r, color.black,color.black, 220f);
brush2.interpolationcolors = cb;
gx.rotatetransform(-45f);
gx.translatetransform(-200, -170);
gx.fillrectangle(brush2, r);

//refresh
invalidate();



alpha 通道合成

  system.drawing 命名空间中的 color 结构在 .net framework 和 .net compact framework 中都可用。区别在于 .net compact framework 中禁用了 alpha 成分并且色调-饱和度-亮度 (hsb) 值不可用。幸运的是,alpha 通道合成可以完美地与 xrossone gdi+ 协同工作(您可能已经从前面的图形示例中推断出这一点)。



性能
  手持 pc 的 cpu 的功能确实通常要比标准 pc 的 cpu 差很多。繁重的计算可能使手持设备的响应速度降低,从而可能使用户变得不胜其烦。换句话说,性能对于手持设备软件而言至关重要。因此,在重大场合下使用 xrossone mobile gdi+ 之前,您可能希望分析它的总体性能。因为 gdi+ 中大多数对应于 .net compact framework 的等效函数都不可用,所以基准测试是针对 .net framework 在 xrossone mobile gdi+ 和 gdi+ 之间进行的。测试是在下列类别中执行的:矢量图形呈现、二维变换和渐变填充。测试方案在相同的条件下执行。您可以在下载软件包中找到基准测试程序,并且可以在 http://www.xrossone.com/projects.php?menu=4 快速查看它们的图形输出。

  xrossone mobile gdi+ 完全是用 c# 托管代码编写的,它的总体性能可以接受(参见下表),尽管二维变换和渐变填充需要在以后的版本中进一步优化。

方案xrossone mobile gdi+gdi+ for .net framework系统开销

drawline

2.604 ms

0.901 ms

189.0%

drawrect

3.705 ms

1.602 ms

131.3%

drawpolygon

3.205 ms

1.502 ms

113.4%

drawellipse

6.409 ms

2.403 ms

166.7%

drawbezier

3.505 ms

1.602 ms

118.8%

drawcurve

4.006 ms

1.402 ms

185.7%

drawpie

6.810 ms

2.003 ms

240.0%

translatetransform

10.615 ms

3.405 ms

211.7%

scaletransform

4.106 ms

0.801 ms

412.6%

rotatetransform

7.811 ms

1.803 ms

333.2%

lineargradient (1)

9.013 ms

2.103 ms

328.6%

lineargradient (2)

8.012 ms

1.803 ms

344.4%


缺少的功能
  在上述部分中,我们已经演示了 xrossone mobile gdi+ 的一些令人兴奋的功能。但是,该版本中仍然缺少一些功能:

  &#8226; 文本输出

  &#8226; 光栅输出

  &#8226; 虚线样式支持

  &#8226; hatchbrush、pathgradiantbrush、texturebrush

  &#8226; pen.customstartcap、pen.customendcap

小结
  我们相信 xrossone mobile gdi+ 可以帮助 .net compact framework 开发人员创建更加引人注目的图形接口。考虑到它的小内存足迹 (72kb),它的功能已经相当丰富了。而且,它的性能对于一般应用程序而言已经足够了。此外,多亏它的纯粹托管代码设计,xrossone gdi+ 是一个跨平台、跨设备的二维图形引擎。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons