اجازه بدهید در این قسمت در مورد استاندارد Single-Byte یا ASCII کمی از منظر سطح پایین صحبت کنیم. همانطور که شما می دانید، وقتی در برنامهنویسی سی یک متغیر کاراکتری تعریف میکردیم، مانند char variable = 'A' علاوه بر نمایش کاراکتری، میتوانستیم در printf با استفاده از فرمت %d یک نمایش عدد صحیح هم از آن بگیریم.
آن نمایش عدد صحیح هم در حقیقت یک نمایش باینری هم داشت که منحصربفرد کاراکتر A هست. حال مسئله این است که سیستمعامل چطور میتواند این مجموعه از بیتها را مانند یک المان گرافیکی (کاراکتری) نمایش بدهد؟ برای اینکه این مورد را متوجه شوید، باید دانش توسعه کرنل و سیستمعامل داشته باشید. یکی از بخشهای مهم توسعه سیستمعامل رندر کردن همین Code Pageها یا همین Bitmapها است و این مسئله زمانی دشوارتر میشود که شما بخواهید کاراکترهای غیرلاتین مانند زبان پارسی و عربی را پارز و نمایش بدهید.
در هر صورت، این مسئله چندین مبحث دارد. اولین مبحث خود فونت است. در سادهترین مورد از یک فونت، اتفاقی که رخ میدهد، برای مثلا عدد 65 یک کاراکتر یا تصویر مانند A سیستمعامل ترسیم خواهد کرد. مثلا در سیستم عامل لینوکس اگر شما سورس کد بخش فونتها را مشاهده کنید، font_8x8.c در آنجا خواهید دید که مثلا یک کاراکتر مانند A دارای هشت بیتمپ است که سیستمعامل هنگام نمایش کاراکتر A به این جدول هشت عضوی رجوع خواهد کرد و مبتنی بر بیت پترنی که وجود دارد، پیکسلهای سفید و سیاه را فعالسازی میکند که این موجب نمایش مثلا کاراکتر A خواهد شد.
مثلا در مورد زیر، جدول نقشه بیت های کاراکتر علامت ؟ و @ آورده شده است که کرنل لینوکس از آن برای ترسیم این کاراکترها استفاده خواهد کرد.
/* 63 0x3f '?' */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
/* 64 0x40 '@' */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xc0, /* 11000000 */
0x78, /* 01111000 */
0x00, /* 00000000 */
مورد بالا برای مبحث Single Byte بود، موارد زیر برای مبحث Unicode است:
/* 63 0x3f '?' */
0x00, 0x00, /* 0000000000 */
0x0e, 0x00, /* 0000111000 */
0x1f, 0x00, /* 0001111100 */
0x3b, 0x80, /* 0011101110 */
0x21, 0x80, /* 0010000110 */
0x01, 0x80, /* 0000000110 */
0x03, 0x00, /* 0000001100 */
0x06, 0x00, /* 0000011000 */
0x06, 0x00, /* 0000011000 */
0x0c, 0x00, /* 0000110000 */
0x0c, 0x00, /* 0000110000 */
0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */
0x0c, 0x00, /* 0000110000 */
0x0c, 0x00, /* 0000110000 */
0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */
/* 64 0x40 '@' */
0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */
0x0e, 0x00, /* 0000111000 */
0x3f, 0x00, /* 0011111100 */
0x31, 0x80, /* 0011000110 */
0x65, 0x80, /* 0110010110 */
0x6d, 0x80, /* 0110110110 */
0x6d, 0x80, /* 0110110110 */
0x6d, 0x80, /* 0110110110 */
0x6d, 0x80, /* 0110110110 */
0x6f, 0x80, /* 0110111110 */
0x60, 0x00, /* 0110000000 */
0x31, 0x80, /* 0011000110 */
0x3f, 0x80, /* 0011111110 */
0x0f, 0x00, /* 0000111100 */
0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */
0x00, 0x00, /* 0000000000 */
حال این نمایش برای فونتهای مختلف متفاوت است، که دیگر وارد آن مسئله نخواهم شد. خلاصه اینکه پیچیدگی بسیار زیادی این مسئله فونتها در سیستم عامل دارد و ساده نیست. آیا در ویندوز هم داستان به این شکل است یا خیر؟ باید بگویم که نه در ویندوز داستان به این سادگیها نیست (اگرچه کل مباحث با هم دیگر شباهت دارد و یک معماری لایهبندی شده برای رندر و پارز فونتها در تمامی سیستمهای عامل تعبیه شده است).
@aioooir |
#lowlevel