تا نگارش 4x دات نت که فقط از ویندوز پشتیبانی میکند، از وابستگی System.Drawing.Common برای انجام امور روزمرهی گرافیکی استفاده میشد؛ چون در پشت صحنه، محصور کنندهی امکانات بومی گرافیکی ویندوز است. همچنین از زمان ارائهی دات نت Core چندسکویی، تا نگارش 5 دات نت، این وابستگی، در لینوکس، به کمک کتابخانهی جانبی به نام libgdiplus پشتیبانی میشد که البته هیچگاه پشتیبانی رسمی را از طرف مایکروسافت پیدا نکرد؛ چون libgdiplus متشکل از چند دههزار سطر کد نوشته شدهی به زبان C است که بهخوبی آزمایش نشده و همچنین برای کارکرد کامل آن نیز به کتابخانههای جانبی دیگری مانند pango نیاز است تا برای مثال از نمایش متون فارسی پشتیبانی کند. Libgdiplus در حقیقت بازماندهای از دوران Mono است که مایکروسافت در نگارش 6 دات نت، آنرا منسوخ شده اعلام کرد و در نگارش 7 دات نت، دیگر از آن پشتیبانی نمیکند. یعنی تمام برنامههایی که از وابستگی System.Drawing.Common استفاده میکنند، قابل انتقال به دات نت 7 چندسکویی نیستند؛ البته هنوز هم میتوان از System.Drawing.Common در ویندوز، بدون مشکل استفاده کرد. اما در صورت استفاده، برنامهی شما در لینوکس اجرا نخواهد شد و یک چنین برنامههایی با استثناهای TypeInitializationException و PlatformNotSupportedException در زمان اجرا، خاتمه خواهند یافت.
در حال حاضر
توصیهی مایکروسافت ، عدم استفادهی از System.Drawing.Common و جایگزینی آن با یکی از کتابخانههای زیر است:
-
SkiaSharp
-
Microsoft.Maui.Graphics
البته پیشتر در این لیست توصیه شده، کتابخانهی
SixLabors.ImageSharp.Drawing هم وجود داشت که به علت تغییر مجوز آن، به یک مجوز نیمه تجاری، نیمه سورس باز، از لیست فوق حذف شدهاست.
مشکل فارسی نویسی با SkiaSharp
اگر سعی کنیم با استفاده از
مثالهای متداول SkiaSharp، یک متن فارسی را نمایش دهیم، به خروجی زیر خواهیم رسید:
// crate a surface
var info = new SKImageInfo(256, 256);
using var surface = SKSurface.Create(info);
// the the canvas and properties
var canvas = surface.Canvas;
// make sure the canvas is blank
canvas.Clear(SKColors.White);
// draw some text
using var typeface = SKTypeface.FromFamilyName("Tahoma");
using var paint = new SKPaint
{
Color = SKColors.Black,
IsAntialias = true,
Style = SKPaintStyle.Fill,
TextAlign = SKTextAlign.Center,
TextSize = 24,
Typeface = typeface,
};
var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize) / 2);
canvas.DrawText("آزمایش", coord, paint);
// save the file
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
using var stream = File.OpenWrite("farsi-text-1.png");
data.SaveTo(stream);
قطعه کد فوق برای اجرا، نیاز به وابستگی زیر را دارد:
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="2.88.3" />
</ItemGroup>
که در آن، در ابتدا یک Canvas برای نقاشی ایجاد شده و سپس متنی بر روی آن نمایش داده میشود و در آخر این نتیجه را در یک فایل ذخیره میکنیم؛ با این خروجی:
همانطور که مشاهده میکنید، حروف فارسی در آن از هم جدا هستند و همچنین از چپ به راست نمایش داده شدهاست.
رفع مشکل فارسی نویسی با SkiaSharp
برای رفع مشکل فوق، نیاز است از افزونهی «حرف باز» این کتابخانه استفاده کرد که روش نصب آن به صورت زیر است:
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.3" />
</ItemGroup>
اینبار تنها تفاوت مورد نیاز جهت نمایش صحیح حروف فارسی، استفاده از SKShaper جهت شکل دادن به متن نهایی است و استفاده از متد DrawShapedText آن به صورت زیر:
// crate a surface
var info = new SKImageInfo(256, 256);
using var surface = SKSurface.Create(info);
// the the canvas and properties
var canvas = surface.Canvas;
// make sure the canvas is blank
canvas.Clear(SKColors.White);
// draw some text
using var typeface = SKTypeface.FromFamilyName("Tahoma");
using var shaper = new SKShaper(typeface);
using var paint = new SKPaint
{
Color = SKColors.Black,
IsAntialias = true,
Style = SKPaintStyle.Fill,
TextAlign = SKTextAlign.Center,
TextSize = 24,
Typeface = typeface,
};
var coord = new SKPoint(info.Width / 2, (info.Height + paint.TextSize) / 2);
canvas.DrawShapedText(shaper, "آزمایش", coord, paint);
// save the file
using var image = surface.Snapshot();
using var data = image.Encode(SKEncodedImageFormat.Png, 100);
using var stream = File.OpenWrite("farsi-text-2.png");
data.SaveTo(stream);
که خروجی صحیح زیر را تولید میکند: