1 ضمیمه
سيستم فارسي نويس NTL_font
سلام به همگي،
اول از همه ميخواستم از يكي از مديرها خواهش كنم، اگر امكان داره اين بحث رو در قسمت اول تالار J2ME قرار بدن تا به صفحات ديگه نره.
چون يك پروژه اوپن سورس رو ميخوام توصيف كنم و فكر كنم خيلي از دوستان ميخوان اطلاعاتي در موردش كسب كنن.
خوب، خيلي از دوستان خواستار سيستم فارسي نويس NTL_font شدن. من هم به عنوان كسي كه اين سيستم رو طراحي كرده ميخوام اون رو به صورت متن باز در اختيار همه دوستان قرار بدم. البته نه اون نسخه مبتدي رو، اين نسخه باحاله رو ميخوام اينجا بذارم.
اول از همه بياين امتحانش كنين و بعد از اون در مورد روش كار با سيستم توضيح ميدم.
راستي من 2 سال روي اين سيستم كار كردم تا به اينجا رسيده، اگر كسي با اين سيستم حال كرد و خوشش اومد و پول در آورد، و خواست تشكر كنه، به وبلاگم يه سري بزنه. :خجالت:
اصول فونت هاي NTL_font و نحوه ايجاد يك شي از كلاس font
سلام،
چه كار كردين، امتحان كردينش؟
در پوشه Type writer يه فايل Doc است كه كار با نرم افزار رو توضيح داده.
يه كمي با هاش ور برين ميفهمين چي به چيه. ولي اگر هم متوجه نشديد، مشكلتون رو توي همين تاپيك بپرسيد، يا ايميل بزنيد. اگر هم ايميل بزنيد و هم اينجا مشكلتون رو مطرح كنيد كه خيلي بهتر ميشه.
خلاصه من ايميلم رو روزي 3-4 بار ميچكم.
خوب و اما خود كلاس نازنين font.
در اين سيستم قبل از هر چيز مهمه بدونيد كه هر متني در يك كادر چاپ ميشه و هر كادري هم خوب مسلما يك X ,Y,Width,height داره.
هر متني هم دراي رنگ هست كه چنين قالبي داره: 0xRRGGBB
و اين بايد بدونيد كه كلاس font در هر لحظه از يك مجموعه كاراكتر استفاده ميكنه.
اين مجموعه كاراكتر ها در داخل يك تصوير قرار دارند و يك آرايه bound معرف هر كدام از كاراكتر هاست، به اين صورت:
با فرض اينكه آرايه از 1 تا n باشد:
- اعداد ي كه در خانه هاي فرد هستند موقعيت X كاراكتر در تصوير مشخص مي كنند.
- اعدادي كه در خانه هاي زوج هستند طول آن كاراكتر را مشخص مي كنند.
كلاس font در هنگام فراخواني شدن، ابتدا از روي هر كاراكتر نمونه برداري مي كند و اطلاعات مربوط به پيكسل هاي سياه را در حافظه نگه داري مي دارد.
اين كار كه همان روش Indexing است، تقريبا 7 ثانيه زمان مي برد. البته يك الگوريتم رو دارم طراحي ميكنم كه فقط در اولين باري كه نرم افزار كارش رو شروع ميكنه 7 ثانيه زمان ببره و در دفعه هاي بعدي فقط 2 ثانيه زمان ببره.
خوب پس در اولين اقدام بايد يك object از كلاس font بسازيم.
چه جوري؟ اين جوري:
int character_bounds[] = {4,14,27,14,49,10,66,10,84,14,107,...,5663,5,3670, 4,3676,6,3686,7,3695,5,3703,3};
font ft = new font("/1.png", character_bounds);
همون طور كه ميبينيد اولين پارامتر نام فايل تصوير كاراكتر هاست و دوميش هم يه آرايه از نوع int براي معرفي مجموعه كاراكتر هاست.
نوشتن متن با استفاده از كلاس font
سلام،
نوشتن متن با استفاده از اين كلاس مثل نوشيدن يك قورت، يا شايد هم غورت، ايستك اناره!
اول از همه بايد بدوني كه در اولين باري كه NTL_font بار گذاري ميشه، رنگ فونت سياهه. ولي اگر تغييرش دادي، ديگه سياه نيست.
و از اونجايي كه تغيير رنگ در اين سيستم كوچك ترين تاثيري روي سرعت نوشتن كاراكتر ها نداره، چون از Indexing استفاده شده، پس با خيال راحت، قبل از هر متن كوچك يا بزرگي كه ميخواهيد بنويسيد رنگ متن رو تعييد كنيد.
متن رو اينجوري بنويسيد:
/**
* The text that will be show on the LCD.
*/
char[] text ={231,82,65,68,231,231,82,84,76,231,57,...,3,230,7 0,61,79};
//------- Determines the color of the text.
ft.setColor(colors[colors_idx]);
//------- Writes the main text in a frame.
NTL_prop = ft.write(g, 0, 0, getWidth(), getHeight(),true,0,text,false);
اما پارامتر هاي متد تابع write:
1- يك شي از نوع Graphics كه در واقع همون شي Graphics اي است كه در قسمت پارامتر متد paint در داخل Canvas است.
2- موقعيت X كادر متن.
3- موقعيت Y كادر متن.
4- طول كادر متن.
5- عرض كادر متن.
6- مشخص ميكند كه آيا متن از انتهاي كادر مي تواند بيرون بزند يا نه. از نوع Boolean
7- تعداد خطوطي كه بايد نشان داده نشوند تا خطوط پايين تر نشان داده شوند. از اين پارامتر براي اسكرول كردن استفاده خواهيم كرد. براي اطلاعات بيشتر پست مربوط به NTL_writer_properties را بخوانيد.
8-متن مورد نظر در قالب آرايه اي تك بعدي از نوع char و با استانداردU بي` پايه و اساس و افشين ( درنقش "من") در آوردي NTL_font
9- آخري رو هرچي ميخواي بزني بزن. ولي اگر false بزني بهتره. در اصل كاراييش زمانيه كه امكان خفن تغييره رنگ در داخل متن رو بهش اضافه كنم.
تابع setColor هم كه معلومه ديگه، يك پارامتر از نوع int و با استاندارد RRGGB دريافت ميكنه. باز نرين AARRGGBB بزنين و بعد بياين هي پست بدين كه چرا كار نميكنه.
شي NTL_prop چيه؟ پست مربوطه رو بخونيد!
NTL_writer_properties چيست؟
سلام،
اگر با كلاس فارسي ساز قبلي كار كرده باشيد متوجه مي شين كه اين NTL_writer_properties عجب كلاسه با كلاسيه و چقدر كار هايه اسكرول كردن متن رو دقيق و راحت ميكنه.
اين كلاس داراي field هاي زير است:
1- last_Y_pos آخرين موقعيت Y را در زمان نوشتن آخرين كاراكتر بر مي گرداند. مورد استفاده برنامه نويس نيست.
2- last_X_pos مثل همون بالايي فقط در مورد X كار ميكنه، اينم به برنامه نويس دخلي نداره!
3- Line_Quantity: تعداد كل خطوطي كه كاراكتر هاي داده شده< در اندازه عرض كادر و ارتفاع بينهايت مي سازند. خيلي كاري ندارد.
4- Rest_lines: تعداد خطوطي كه از ارتفاع كادر زدن بيرون. بازم شما خيلي باهاش سرو كار نداريد مگر اينكه بخواهيد از اين اسكرولر هاي خطي بسازيد كه موقعيت متن را نمايش ميدهند.
6- Frame_line_capacity: تعداد خطوطي كه ميتونند داخل فريم نمايش داده بشن. خيلي با هاش كاري ندارين.
7- need_to_scroll_down: آها اينه! يك مقدار boolean كه اگر True باشه يعني نياز است كه به سمت پايين اسكرول بشه و اگر false بود يعني احتياجي نيست. وقتي ميگوييم بايد به سمت پايين اسكرول بشه يعني يه تعداد خط در زير كادر قرار گرفته اند و بايد بيان بالا.
8- need_to_scroll_up: همون حرف هايي رو كه در بالا (7) زدم رو چپه كنيد، كارايي اين معلوم ميشه.
روش استفاده:
NTL_writer_properties NTL_prop = new NTL_writer_properties();
//------- Writes the main text in a frame.
NTL_prop = ft.write(g, 0, 0, getWidth(), getHeight() - ft.calcHeight() - 7,true,text_ignored_lines,text,false);
//------ Checks the NTL_prop to draws the UP or DOWN arrow.
if(NTL_prop.need_to_scroll_up)
g.drawImage(ArrUp, 0, 10, Graphics.LEFT|Graphics.TOP);
if(NTL_prop.need_to_scroll_down)
g.drawImage(ArrDn, 0, getHeight()-ArrDn.getHeight()-30, Graphics.LEFT|Graphics.TOP);
حالا به متد write نگاه كنيد!
پارامتر هفتم به يك متغير تغيير داده شده. كار اين پارامتر اين است:
اگر شما 10 تا سيب داشته باشي و بخواهي روي ميزي قرار بدي كه فقط جايه 8 تا سيبه، اون وقت مجبوري، 8 تا سيب رو روي ميز و بقيه رو خارج ميز بذاري. حالا اگر بخواي سيب نهم رو روي ميز بياري، بايد يك سيب از اول ميز برداري، و اگه بخواي دهمين سيب رو بذاري روي ميز بايد 2 سيب از اول ميز برداري تا سيب نهم و دهم بيان روي ميز قرار بگيرن.
پس داريم:
public void keyPressed(int keyCode)
{
int Game_Act = getGameAction(keyCode);
if(Game_Act == Canvas.DOWN && NTL_prop.need_to_scroll_down)
{
text_ignored_lines ++;
}
else if(Game_Act == Canvas.UP && NTL_prop.need_to_scroll_up)
{
text_ignored_lines --;
}
if(keyCode == Canvas.KEY_STAR)
{
colors_idx = (colors_idx > colors.length-2 ? 0:colors_idx+1);
}
repaint();
}
از كليد ستاره و فشردن سريع و پشت سره هم، ميتونيد سرعت تغييره رنگ رو ببينيد.
:لبخند:
1 ضمیمه
براي NTL_font فونت طراحي كنيد!
سلام،
يكي از خصوصيات NTL_font اينه كه هر فونتي، با هر اندازه اي كه بهش بدي، براي كلاس font فرقي نداره.
پس لطفا با استفاده از اين Application فونت هاي مورد علاقه خودتون رو بسازيد و اگر دوست داشتيد اون ها رو اينجا upload كنيد تا بقيه هم فيض ببرند!
البته قبل از هر چيز بايد بگم كه اين برنامه دقيق كار نميكنه، ولي با استفاده از photoshop بايد با خط هاي قرمز، سرو ته هر character رو مشخص كنيد. بعد با استفاده از يك برنامه كمكي كه يكي از دوستان زحمتش رو ميكشه، اين خط ها رو بخونيد. به اين صورت كه خط اول از چپ به راست، موقعيت X و بعد خط دوم رو بخونيد، بعد خط اول رو از موقعيت خط دوم كم كنيد تا طول character به دست بياد. بعد هر دو رو در قالبي مشخص ذخيره كنيد.
درواقع نرم افزار پايين هم همين كار و ميكنه ولي بايد يه كمي روش كار كنم تا تصوير ورودي هم بگيره. ولي قضيه "آب هندوانه" يه كمي مشكل سازه!:قهقهه:
مرسي
روش كار با نرم افزار NTL_font maker
سلام،
استفاده از اين نرم افزار خيلي راحت و ساده است.
نرم افزار رو باز كنيد. در قسمت Option يك جعبه متن با نام Collection وجود دارد، نيازي نيست به محتواي آن دست بزنيد، ولي در كل براي تعيين كردن كاراكتر هايي است كه بايد در تصوير قرار گيرند.
از ImageHeight هم براي تعيين اندازه PictureBox استفاده كنيد، اگر ديديد كه فونت از ارتفاع pictureBox بيشتر شده، مقدار اين آيتم را افزايش بدهيد.
در كنار جعبه متن font family يك دكمه وجود دارد، با كليك آن فونت و اندازه مورد نظر خود را انتخاب نماييد.
با افزايش مقدار Pre tolerance كاراكتر ها را از جلو به هم نزديك تر كنيد.
با افزايش مقدار Post tolerance كاراكتر ها را از عقب به هم نزديكتر مي نماييد.
با تيك دار كردن گزينه Draw red guide lines نحوه تقسيم بندي كاراكتر ها را نمايش ميدهد تا با دستكاري كردن دو آيتم pre tolerance و post tolerance اندازه كاراكتر ها را دقيق تر مشخص نماييد.
گزينه Draw double line به شما اين امكان را مي دهد تا دقيقترين حالت ممكن را براي هر كاراكتر مشخص نماييد. كه بهتر است اين گزينه را نيز تيك دار كنيد.
گزينه english and farsi numbers تعيين مي كند كه آيا اعداد به صورت فارسي و انگليسي در تصوير درج شوند يا فقط انگليسي.
پس از اين كه تنظيمات رو انجام داديد دكمه MAKE را بزنيد تا تصوير كاراكتر ها در PictureBox ضاهر شود.
با فشردن دكمه Save نيز ابتدا فايل متني حاوي معرف فونت را ذخيره ميكنيد كه به صورت يك آرايه عددي است و در قسمت intialize كردن كلاس font مورد استفاده قرار ميگيرد. و بعد از آن فايل تصوير كاراكتر ها را با فرمت png ذخيره مي نماييد.
اما نكته مهم:
هر كاراكتر در زبان فارسي ممكن است بيش از يك حالت داشته باشد.
در هر حال 4 حالت كلي وجود دارد:
1 - حالت تنها، (alone)
2- كاراكتري كه از عقب مي چسبد به كاراكتر جلويي (prefix)
3- كاراكتري كه از جلو مي چسبد به كاراكتر عقبي (postfix)
4- كاراكتري كه از هر دو طرف به كاراكتر هاي عقب و جلو مي چسبد (midfix)
در حالت اول خطوط قرمز از سمت راست بايد كاملا روي اولين خط پيكسل كاراكتر باشد و خط دوم در سمت چپ بايد حدود 2 يا 3 پيكسل از آخرين خط پيكسلي كاراكتر فاصله داشته باشد.
در حالت دوم اوليم خط قرمز از سمت راستبايد كاملا روي اولين خط پيكسلي قرار گيرد و خط دوم نيز بايد دقيقا روي آخرين نقطه پيكسلي در سمت چپ باشد.
در حالت سوم اولين خط قرمز بايد دقيقا روي اولين نقطه پيكسلي كاراكتر در سمت راست قرار گيرد و خط قرمز بعدي بايد 2 يا 3 پيكسل از آخرين خط پيكسلي فاصله بگيرد.
در حالت چهارم خطوط قرمز بايد دقيقا روي نقطه هاي اول و آخر كاراكتر قرار بگيرند.
موفق باشيد!
با استفاده از NTL_font دكمه يا تيتر طراحي كنيد
سلام،
حتما در زمان كار با Canvas مجبور شديد كه از مختصات نسبي هم استفاده كنيد.
مثلا يك تصوير، هميشه از در وسط صفحه قرار بگيرد، يا متني در گوشه سمت چپ قرار بگيرد.
اين هم همينه، فقط بايد x و Y فريم رو منتقل كنيد به محلي كه ميخواهيد و مقدار خطوط Ignore شده را 0 كنيد و همين طور ارتفاع رو به اندازه يك خط يا هر چقدر كه نياز داريد تنظيم كنيد.
به هر حال از اين توابع استفاده خواهيد كرد:
calcHeight()
calcWidth(int char)
Text_width(char[] text)
1- براي بدست آوردن ارتفاع كاراكتر.
2- طول پيكسلي يك كاراكتر مشخص را باز ميگرداند
3- متن خود را به عنوان پارامتر بدهيد و طول پيكسلي آن را در ارتفاع يك خط بگيريد. از اين متد براي تعيين اندازه يك تيتر يا دكمه استفاده مي شود. يعني هر متني كه فقط يك خط است.
4- از متد write براي تعيين ارتفاع يك متن چند خطي و با عرض كادر معيين استفاده نماييد. به اين شكل كه به جاي پارامتر اول كه از نوع Graphics است، مقدار Null بذاريد و از NTL_writer_properties اي كه بر ميگرداند، تعداد كل خطول را بخوانيد.
مسلما براي تعيين مقدار پيكسلي ارتفاع متن بايد تعداد خطوط را در اندازه ارتفاع يك كاراكتر، يعني متد اول، ضرب شود.
اينم از NTL_font
حالا برين پولدار بشين و حال كنيد. براي منم ايستك بخرين :چشمک:
من اين تاپيك رو سر ميزنم، ايميلم هم روزي 2 بار چك ميشه، كاري داشتين سعي كنيد كه ايميل بزنيد. mic_r_c@yahoo.com
موفق باشيد
1 ضمیمه
NTL_font با سرعت بارگذاري بالا!
سلام،
براي بعضي از كارها كه انيميشن و ندارند و سرعت نوشتن خيلي مهم نيست و فقط سرعت بارگذاري مهمه، مثل كتابهاي الكترونيكي ساده، ميشه از اين كلاس استفاده نمود.
نقل قول: NTL_font با سرعت بارگذاري بالا!
سلام به همه برنامه نویس ها
دوستانی که قصد دارن از این کلاس برای بار گذاری سریع استفاده کنند توجه کنند که هرجا از ft.calcHeight()
استفاده شده باید عدد 0 رو به عنوان پارامتر بهش بدن یعنی اینجوری ft.calcHeight(0)
اینم نکته ای بود که تو استفاده از این کلاس باید دقت کنیم.
از آقا افشین بابت راهنمائیشون ممنونم.
نقل قول: سيستم فارسي نويس NTL_font
خیلی ممنون به خاطر اینکه علم و تجربیات خودتون رو رایگان در اختیار دیگران قرار میدین:لبخندساده: واقعا تحسین برانگیزه :تشویق:
من همین امروز این مطالب رو خوندم. می خواستم بدونم با این روش میشه متن ورودی کاربر رو هم به صورت فارسی و با فونت دلخواه و بدون ایراد دریافت کرد؟ یعنی داخل TextField هم میشه این فونت رو اعمال کرد؟
ممنونم
نقل قول: سيستم فارسي نويس NTL_font
بله چرا نشه!
در چند پست بالا تر، کلاس های مبدلی رو جهت همین کارهاقرار دادم. این کلاس ها unicode رو به ntl_code و بلعکس تبدیل میکنند.