كتابة نص عربي في محرك بيكو٨ – ArSpr – Pico8

جميع الرموز المتوافرة في الخط، ١٥٠ رمزاً

Read this article in English

ArSpr هي أداة تسمح لك بكتابة نص عربي في محرك Pico8 عبر إدخال نص لاتيني يترجم إلى العربية. صنعتها لأني أخطط بصنع ألعاب Pico8 معرّبة ولأني أردت التسلية ببرمجة راسم للخط العربي من صنعي.

يمكنكم تحميل الأداة من منتدى Pico8:
https://www.lexaloffle.com/bbs/?tid=35164

أو عن طريق تحميل الصورة التالية وفتحها في Pico8

arspr.p8.png

استخدام ArSpr بسيط لكن يختلف عن دالة ()Print المعتادة في Pico8، يجب أن تهيئ متغيراً ليحوي بيانات الخط ثم ترسمه. هنا مثال بسيط:

function _init()
  text1=create_ar_spr([string])
end

function _draw()
  cls()
  draw_ar(text1, [x], [y])
end
مثال بسيط

للخط ثلاث ألوان. لونٌ للحروف، ولونٌ للنقط، ولونٌ للتشكيل. يمكننا تغيير الألوان بهذا الشكل:

function _init()
  text1=create_ar_spr([string])
end

function _draw()
  cls()
  ar_col1=[1-16] --لون الحروف
  ar_col2=[1-16] --لون النقط
  ar_col3=[1-16] --لون التشكيل

  draw_ar
end
مثال لتغيير الألوان

[أترك حرية قراءة ما أسفل هذا السطر للقارئ. لكنه ليس ضرورياً]


معلومات تقنية عن AR_SPR

استوحيت فكرة المشروع من Tiny Text، وهو خط لاتيني لPico8 صنع بشكل مشابه.

مواصفات ArSpr:

2 sprites
510 out of 8192 tokens
~30% of compressed space
No dropped frames when filling the screen
لا تبطيئ في سرعة العرض عند ملئ الشاشة بالكتابة العربية

التّـصـمـيـم

ارتفاع كل حرف هو ٨ بكسلات كحدٍ أقصى. يختلف العرض بين حرف وآخر لكن عرض معظم الحروف هو ٥ بكسلات متضمنة ١ بكسل فارغ إلى يمين الرموز البادئة لكلمة والرموز المنفصلة.

لم أجعل العرض موحداً لأن بعض الحروف تحتاج ضعف عرض معظم الحروف الأخرى، مثل حرف الضاد:

ضـغط الخط

تستخرج جميع الرموز من رسمتين مضغوطتين في الذاكرة.

نقوم برسم الشكل النهائي عبر نسخ ولسق مناطق من الرسمتين المضغوطتين إلى الشاشة.

شمثال توضيحي: يمكننا رسم الرموز على اليمين عبر نسخ أجزاء من الرمز على اليسار

شفّرت بيانات الرسم في بعض من السلاسل strings لأن Pico8 لا يعدّ ما داخل السلاسل في حد الTokens. سنأخذ كمثال سلسلة بيانات “التشكيل” للخط العربي:

_ar_tash = ",^__121__,/__121_6,~_112__1,▥_22111_+__32____,❎_2211__+__221__1+__321___,🐱_2211__,ˇ_2211y_+__2211__,⬇️_2211_6,✽_2211y6+__2211_6"

تحتوي السلسلة ar_tash على مواقع وأحجام كلَّ الأجزاء في خريطة الرسم ليتم نسخها ولسقها على الشاشة. يتم تحويل كل محرف من السلسلة إلى حرف أو رقم على هذا النحو:

“[الحرف], [عرض الحرف عند الكتابة], [موقع بداية النسخ على X], [موقع بداية النسخ على Y], [عرض الجزء], [ارتفاع الجزء], [موقع اللسق على X], [موقع اللسق على Y], [إشارة على نهاية الرسم أو بداية جزء جديد للرسم]”

كل قسم بين قوسين يجب أن يحوي محرفاً واحداً فقط. الخط السفلي “_” يترجم إلى صفر أو عدم. كمثال حرف تنوين الكسر ” ٍ” :

"✽_2211y6+__2211_6,"

تترجم السلسلة إلى: المحرف ✽ يقدم السطر 0 بكسلات. يحوي جزءاً مرسوماً ينسخ من (x=2,y=2) حجمه (1,1) يلسق في (6, 2-)، ويحوي جزءاً آخر يبداً من (2, 2) حجمه (1, 1) يلسق في (6 ,0).

ضّـــم الحــروف

للحروف العربية أربع رموز مختلفة (أول الكلمة، منتصف الكلمة، آخر الكلمة، منفصلة). ضمّ الخط Arabic Shaping هو أن نختار الرمز المناسب لكل حرف حسب موقع الحرف في الكلمة مع العلم أن الحرف قد يكون منفصلاً أو متّصلاً.

الحروف المتصلة Dual-Joining Letters تلحق بالحرف السابق واللاحق، وتملك جميع أشكال الرموز الأربعة (أول الكلمة، منتصف الكلمة، آخر الكلمة، منفصلة) مثل حرف الباء.
ببب ب – بـ ـبـ ـب ب

الحروف المنفصلة Previous-Joining Letters تلحق بالحرف السابق فقط، وتحوي شكلين من الرموز (آخر الكلمة، منفصلة) مثل حرف الدال.
ددد بددد – ـد د

جميع حروف الأبجدية حسب تصنيف منفصلة أم متصلة

بقية المحارف مثل (الفراغ، الأرقام، علامات الترقيم) لا تلحق بالحروف وتحوي رمزاً وحيداً منفصلاً.

يتم تجاهل محارف التشكيل عند ضم الحروف ليتمكن الكاتب من وضع التشكيل في نفس موقع الحرف.

تقنية ضمّ الخط التي كتبتها هي مجرد مجموعة من الشروط البسيطة، هنا كود مختصر من الأداة:


function _get_font(previousChar,currentChar,nextChar)
	
	if currentChar is tashkeel
            return _ar_tashkeel_glyph

	elseif currentChar is (space, number, punctuation)
	     return _ar_nonletter_glyph
		
	elseif previousChar is any except dual-joining letter
	and currentChar is dual-joining letter
	and nextChar is any except (space, number, punctuation)
	     return _ar_init_glyph
		
	elseif previousChar is dual-joining
	and currentChar is dual-joining
	and nextChar is any except (space, number, punctuation)
	     return _ar_medial_glyph
		
	elseif previousChar is dual-joining 
	and currentChar is dual-joining
	and nextChar is (space, number, punctuation)
	     return _ar_final_glyph
	
	elseif previousChar is dual-joining letter
	and currentChar is previous-joining letter
	     return _ar_final_glyph
	
        -- all previous checks failed.
	else
	     return _ar_isolated_glyph
	end
end

إن أردتم قراءة تقنية ضمّ خط عربي أخرى يمكنكم قراءة MiniBidi من صنع أحمد خليفة.

تـحسينات مـمكنة

١- يمكننا التخلص من البيانات المكررة في سلسلة الرسم بسماح المحارف أن تحوي مرجع إليها بدلاً من تكرارها.
٢- يمكنني تجريب تقنية Caaz لضغط الرسوم في Pico8
٣- في نسخة سابقة، كنت أستخدم دالة printAr(str,x,y) لم تحتج لتهيئة المتغيرات لأنها كانت تخزن السلسة اللاتينية بعد رسمها أول مرة. أزلتها لتحرير بعض الtokens لكني أتمنى أن أعيدها.