مقدمة يعد .NET Compact Framework واجهة برمجة تطبيقات (API) ممتازة، إن لم تكن الأفضل، للأجهزة المحمولة. يتم خنق محرك الرسومات الخاص به بشكل كبير من أجل زيادة سرعة العرض وتقليل استهلاك الذاكرة. ومع ذلك، يبدو الأمر بعيدًا عن تلبية طلبات المستخدمين المتزايدة للحصول على تجربة رسومية أفضل. قد تكون محاولة الحصول على بعض إمكانيات عرض الرسومات المتجهة المتقدمة في .NET Compact Framework مهمة شاقة. لدى المطورين خياران:
1. انتقل إلى التعليمات البرمجية الأصلية. على سبيل المثال، قد تكون واجهة برمجة التطبيقات لألعاب كمبيوتر الجيب (Pocket PC Game API) خيارًا جيدًا. أدائها مثير للإعجاب. لمزيد من المعلومات، راجع مقالة شاملة للغاية على: http://msdn.microsoft.com/mobility/samples/default.aspx?pull=/library/en-us/dnnetcomp/html/gmangame asp . تكمن المشكلة في أن الكود الأصلي لا يدعم عرض الرسومات المتجهة وغير متوافق مع بعض الأجهزة. بالإضافة إلى ذلك، قد لا يعمل مع برامج محاكاة كمبيوتر الجيب. يمكنك أن تتخيل مدى صعوبة تصحيح مثل هذا البرنامج.
2. يرجى الانتظار حتى ظهور الجيل التالي من محرك الرسومات المحمول. بقدر ما أعرف، سيحتوي Windows CE 5 على محرك Direct3D Mobile قوي. هذه أخبار جيدة لمطوري ألعاب الهاتف المحمول، لكن Direct3D غير مناسب للرسومات ثنائية الأبعاد. إنه معقد جدًا بحيث لا يمكن استخدامه في التطبيقات العامة.
ما نحتاجه هو محرك رسومات ثنائي الأبعاد قوي وسهل الاستخدام مثل GDI+. لذلك، قمت بتطوير مشروع XrossOne GDI+ من الصفر. تمت كتابته بالكامل باستخدام التعليمات البرمجية المُدارة C# ولا يحتوي على أي تعليمات برمجية أصلية أو غير آمنة. وبعد أشهر من العمل الشاق، يمكنني أخيرًا توفير النسخة الأصلية القابلة للتنزيل في بداية هذه المقالة.
البدء منذ بداية هذا المشروع، كان دائمًا في ذهني أن محرك XrossOne GDI+ يجب أن يكون محايدًا عبر الأجهزة والمنصات المحمولة المختلفة. ونتيجة لذلك، فهو متوافق مع كمبيوتر الجيب، وWindows CE، والهواتف الذكية، وWindows .NET، وMono. يمكنك نسخ نفس وقت التشغيل إلى هدف مختلف وسيظل يعمل بشكل جيد.
يلخص الجدول التالي البنية الشاملة.
مساحة اسم الطبقةXrossOne GDI+ API XrossOne.Drawing
محرك رسومات ثنائي الأبعاد يعتمد على النقطة الثابتة XrossOne.DrawingFP
16.16 محرك حساب النقاط الثابتة XrossOne.FixedPoint
هناك ثلاث طبقات في XrossOne GDI+. المستوى الأدنى هو "محرك الحوسبة ذو النقطة الثابتة 16.16". إحدى الفئات الرئيسية — MathFP — مقتبسة من مكتبة Beartronics J2ME. تم تحسين العديد من الوظائف، بما في ذلك sqrt وatan وPointFP. حساب المسافة. ضمن مساحة الاسم XrossOne.FixedPoint، توجد ثلاث فئات أخرى: SingleFP وDoubleFP وMatrixFP. SingleFP هي فئة مساعدة لأرقام النقاط الثابتة 16.16. يوفر سهولة للتحويل بين أنواع النقاط الثابتة والأنواع القياسية (int، float، string). تمت كتابة MatrixFP للتحويلات ثنائية الأبعاد ذات النقاط الثابتة. نظرًا لأن حسابات النقاط الثابتة أقل دقة، فقد يتم فقدان بعض الدقة مع التحويلات المتتالية. على سبيل المثال، في معظم الحالات، لا يمكن لعمليتي انعكاس استعادة المصفوفة الأصلية. DoubleFP موجود لإكمال المكتبة، ولكن لم يتم استخدامه بعد.
"محرك الرسومات ثنائي الأبعاد القائم على النقاط الثابتة" هو جوهر XrossOne GDI+. وهو يطبق العديد من خوارزميات الرسومات المتجهة المعقدة، مثل الرسم المصقول، وزخرفة غطاء الخط/المفاصل، والتحويلات ثنائية الأبعاد، والتعبئة المتدرجة، وتركيب قناة ألفا، والمزيد. يمكن العثور على معظم الميزات المتقدمة في GDI+ الأصلي هنا. ومع ذلك، يجب عليك استخدامه مباشرة فقط في حالات قليلة لأن واجهته القائمة على النقاط الثابتة ليست صديقة للمبرمجين، ولكن لا تقلق كثيرًا بشأن هذا الموقف. تتوفر واجهة برمجة تطبيقات مغلفة جيدًا. يمكنك العثور عليها في مساحة الاسم XrossOne.Drawing. تشبه الفئات الموجودة في XrossOne.Drawing إلى حد كبير الفئات الموجودة في System.Drawing، فيما عدا أن كل فئة لها علامة "X" في النهاية. على سبيل المثال، فئة XrossOne.Drawing.PenX تعادل System.Drawing.Pen. هناك خدعة صغيرة لتحويل برامج GDI+ إلى XrossOne GDI+. في قسم الاستخدام، أعد تسمية فئات XrossOne GDI+ إلى الفئات المكافئة لها. على سبيل المثال:
استخدام Pen = XrossOne.Drawing.PenX؛
باستخدام LinearGradientBrush = XrossOne.Drawing.LinearGradientBrushX;
باستخدام Matrix = XrossOne.Drawing.MatrixX;
الميزات الرئيسية رسم الرسومات المتجهة المضادة للتعرج
يمكن عرض جميع أنواع الأشكال الهندسية ثنائية الأبعاد من خلال XrossOne Mobile GDI+، مثل مقاطع الخطوط والمستطيلات والمضلعات والأشكال الناقصية والقطاعات وخطوط بيزيير والخطوط الأساسية وما إلى ذلك. ومع ذلك، لا تتوفر القطاعات وشرائح Bezier وشرائح الجذر في .NET Compact Framework. بالإضافة إلى ذلك، يتم تنعيم كافة الرسومات تلقائيًا عند عرضها. وهذا يساعد على تحقيق جودة فائقة السلاسة. في .NET Compact Framework، يتم تثبيت عرض الفرشاة على 1 بكسل. هذا القيد غير موجود في XrossOne GDI+. يمكن تطبيق أحجام مختلفة من الفرش على الخطوط العريضة لجميع الأشكال، كما هو موضح في الشكل 1.
الشكل 1. رسم الرسومات المتجهة المصقولة
مثال الكود 1
// امسح الخلفية وأعد ضبط حالة التحويل
gx.Clear(Color.White);
gx.ResetTransform();
// ارسم شبكة منحرفة كخلفية
PenX pen = new PenX(Utils.FromArgb(0x40, Color.LightGray), 5);
لـ (int i = -Height; i < Width + Height; i+=20)
{
gx.DrawLine(pen, i, 0, i + Height, Height);
gx.DrawLine(pen, i, 0, i - Height, Height);
}
// ارسم مستطيل DarkMagenta بقلم 10.5 بكسل
Color c = Utils.FromArgb(0x80, Color.DarkMagenta);
pen = new PenX(c, 10.5f);
gx.DrawRectangle(pen, 50, 20, 150, 200);
// املأ المستطيل باللون الأخضر والأصفر
c = Utils.FromArgb(0xA0, Color.GreenYellow);
فرشاة BrushX = SolidBrushX(c);
gx.FillRectangle(brush, 120, 50, 90, 150);
// ارسم شكلًا بيضاويًا باللون الأزرق البنفسجي باستخدام قلم بحجم 10.5 بكسل
c = Utils.FromArgb(0x80, Color.BlueViolet);
pen = new PenX(c, 10.5f);
gx.DrawEllipse(pen, 50, 20, 150, 80);
// املأ القطع الناقص الأحمر
c = Utils.FromArgb(0xA0, Color.Red);
فرشاة = SolidBrushX جديد (ج)؛
gx.FillEllipse(brush, 20, 50, 80, 150);
// ارسم فطيرة HotPink من 156.5 درجة إلى -280.9 درجة
pen.Color = Utils.FromArgb(0xA0, Color.HotPink);
gx.DrawPie(pen, 3.6f, 120.3f, 200.8f, 130.1f, 156.5f, -280.9f);
// ارسم منحنيات بيزيير البرتقالية
c = Utils.FromArgb(0xA0, Color.Orange);
قلم = قلم جديد (ج، 16)؛
بداية النقطة = نقطة جديدة (70، 100)؛
التحكم في النقطة 1 = نقطة جديدة (100، 10)؛
التحكم في النقطة 2 = نقطة جديدة (150، 50)؛
Point end1 = new Point(200, 200);
التحكم بالنقطة3 = نقطة جديدة(100, 150);
التحكم في النقطة 4 = نقطة جديدة (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);
//ينعش
إبطال ()؛
إن مخرجات الرسومات المتجهة لـ XrossOne GDI+ وGDI+ الأصلي متطابقة، باستثناء خطوط الجذر. الخوارزمية الخاصة بي مأخوذة من مقالة تجانس الخوارزمية باستخدام منحنيات بيزييه بقلم جان إيف كوينيك. ولذلك، قد تجد بعض الاختلافات بين مخرجاتها، كما هو موضح في الشكل 2 أدناه.
الشكل 2. إخراج DrawCurve/DrawClosedCurve
على الرغم من أن معظم وظائف عرض الرسومات المتجهة قد تم تنفيذها، إلا أنه لا يزال هناك بعض العمل الذي يتعين القيام به. لن تكون بعض الوظائف (DrawString، DrawImage، DrawPath، وما إلى ذلك) متاحة حتى الإصدار التالي.
تعبئة متدرجة
توجد خمس فرش في GDI+ الأصلي — SolidBrush، وLinearGradientBrush، وPathGradientBrush، وTextureBrush، وHatchBrush. ومع ذلك، في هذا الإصدار، يتوفر فقط SolidBrush وLinearGradientBrush. يدعم XrossOne GDI+ RadialGradientBrush وليس PathGradientBrush. يوضح الشكل 5 أدناه تعبئة متدرجة.
الشكل 5. تعبئة متدرجة
مثال الكود 4
// امسح الخلفية وأعد ضبط حالة التحويل
gx.Clear(Color.White);
gx.ResetTransform();
// املأ المستطيل باستخدام LinearGradientBrushX باللونين الأسود والأبيض
Rectangle r = new Rectangle(20, 50, 300, 100);
اللون c1 = اللون.أسود؛
اللون c2 = اللون.أبيض؛
BrushX Brush1 = LinearGradientBrushX(r, c1, c2, 30F);
gx.FillRectangle(brush1, r);
// املأ المستطيل باستخدام LinearGradientBrushX ذو 7 ألوان
r = مستطيل جديد (90، 100، 150، 100)؛
LinearGradientBrushX br = new LinearGradientBrushX(r,Color.Black,Color.Black, 60F);
ColorBlendX cb = new ColorBlendX();
cb.Positions=new float[7];
كثافة العمليات ط = 0؛
ل(تعويم f=0;f<=1;f+=1.0f/6)
cb.Positions[i++]=f;
cb.Colors=لون جديد[]
{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);
// املأ المستطيل باستخدام RadialGradientBrushX ذو 7 ألوان
ص += 50;
RadialGradientBrushX Brush2 = جديد RadialGradientBrushX(r, Color.Black,Color.Black, 220F);
Brush2.InterpolationColors = cb;
gx.RotateTransform(-45F);
gx.TranslateTransform(-200, -170);
gx.FillRectangle(brush2, r);
//ينعش
إبطال ()؛
تركيب قناة ألفا
تتوفر بنية اللون في مساحة الاسم System.Drawing في كل من .NET Framework و.NET Compact Framework. والفرق هو أن مكون ألفا معطل وأن قيمة Hue-Saturation-Brightness (HSB) غير متوفرة في .NET Compact Framework. لحسن الحظ، يعمل تركيب قناة ألفا بشكل مثالي مع XrossOne GDI+ (كما قد تكون استنتجت من المثال الرسومي السابق).
أداء 3.505 مللي ثانية 1.602 مللي ثانية 118.8 ٪ DrawCurve 4.006 مللي ثانية 1.402 مللي ثانية 185.7% DrawPie 6.810 مللي ثانية 2.003 مللي ثانية 240.0% TranslateTransform 10.615 مللي ثانية 3.405 مللي ثانية 21 1.7% تحويل مقياس 4.106 مللي ثانية 0.801 مللي ثانية 412.6 مللي ثانية 1.803 مللي ثانية 333.2% التدرج الخطي (1) 9.013 مللي ثانية 2.103 مللي ثانية 328.6% التدرج الخطي (2) 8.012 مللي ثانية 1.803 مللي ثانية 344.4%
صحيح أن وحدات المعالجة المركزية للكمبيوتر الشخصي غالبًا ما تكون أقل قوة من وحدات المعالجة المركزية للكمبيوتر الشخصي القياسية. يمكن أن تؤدي الحسابات الثقيلة إلى جعل الأجهزة المحمولة أقل استجابة، مما قد يصبح محبطًا للمستخدمين. بمعنى آخر، يعد الأداء أمرًا بالغ الأهمية بالنسبة لبرامج الأجهزة المحمولة. لذلك، قبل استخدام XrossOne Mobile GDI+ في موقف كبير، قد ترغب في تحليل أدائه العام. نظرًا لأن معظم الوظائف المكافئة في GDI+ لـ .NET Compact Framework غير متوفرة، فقد تم إجراء الاختبارات بين XrossOne Mobile GDI+ وGDI+ لـ .NET Framework. تم إجراء الاختبارات في الفئات التالية: عرض الرسومات المتجهة، والتحويلات ثنائية الأبعاد، والتعبئة المتدرجة. تم تنفيذ سيناريوهات الاختبار في ظل نفس الظروف. يمكنك العثور على البرامج المعيارية في حزمة التنزيل، ويمكنك عرض مخرجاتها الرسومية بسرعة على http://www.xrossone.com/projects.php?menu=4.
تمت كتابة XrossOne Mobile GDI+ بالكامل باستخدام التعليمات البرمجية المُدارة C#، وأدائه العام مقبول (انظر الجدول أدناه)، على الرغم من أن التحويلات ثنائية الأبعاد والتعبئة المتدرجة ستحتاج إلى مزيد من التحسين في الإصدارات المستقبلية.
الحل 66.7 ٪ DrawBezier تحويل التدوير 7.811