فونت
This content is not available in your language yet.
مرجع زنده. یکانبخ برای رابط، وزیرمتن برای چاپ و برای نویسههایی که یکانبخ ندارد. منبعِ همه در
tools/fonts/(نسخهٔ منتخبِ هر خانواده) و بستهٔ کاملِ سازنده درtools/fonts/packages/؛ ساختشانscripts/build-fonts.mjs.
چه و چرا
Section titled “چه و چرا”| سطح | فونت | پرونده | اندازه |
|---|---|---|---|
| رابط | Yekan Bakh 3.100، متغیر | apps/web/public/fonts/YekanBakh-var.woff2 |
۴۳ KB |
| پرکنندهٔ رابط | Vazirmatn، فقط ۸۶ نویسه | apps/web/public/fonts/Vazirmatn-gaps-var.woff2 |
۱۴ KB |
| چاپ، وب | Vazirmatn 33.003، متغیر | apps/web/public/fonts/Vazirmatn-print.woff2 — هنگامِ ساختِ سند جاسازی |
۶۷ KB |
| چاپ، خط فرمان | همان بایتها، base64 | packages/report/src/fonts.ts (@darzsaz/report/fonts) |
۶۷ KB |
پیش از این رابط هم وزیرمتن بود: ۶۷ KB. حالا ۴۳ KB برای همهٔ متن، و ۱۴ KB
که مرورگر فقط برای همان ۸۶ نویسه به کار میبرد. سرویسورکر هر سه را پیشانباشت میکند
(۱۲۴ KB)؛ تا نسل ششم فونتِ چاپ base64 درونِ جاوااسکریپتِ وب بود — ۶۸ KB (gzip) از بودجهٔ js
ِ هر کاربر، چاپ بکند یا نه — و حالا پروندهٔ جداست که apps/web/src/lib/print-font.ts یک بار در هر
نشست میخواند و درونِ هر سند مینشاند (نقشهٔ نسل ششم، ۰.۱). scripts/size-budget.mjs برگشتنِ base64
به تکههای js را خطا میگیرد. print-font.ts ِ گزارش (خانواده، بازهٔ وزن، نامِ پرونده، سازندهٔ
@font-face) و fonts.ts هر دو تولیدیاند.
چرا یکانبخ
Section titled “چرا یکانبخ”خواستهٔ اصلی: فارسی و انگلیسیِ کنارش با هم بخوانند. در این برنامه «چاپ برشکار (PDF)»، «نستینگ CNC»، «برونریزی JSON» و «Ctrl+S» وسط جملهٔ فارسیاند. هفت نامزدِ متنی از کتابخانه در کروم کشیده و اندازه گرفته شدند (۱۴۰۵/۰۶/۲۲):
| فونت | الف ÷ حرف بزرگ | ضخامت الف ÷ I (۴۰۰ / ۷۰۰) | تیرگی انگلیسی ÷ فارسی (۴۰۰ / ۷۰۰) | tnum |
زیرمجموعه |
|---|---|---|---|---|---|
| Yekan Bakh | 1.00 | 0.96 / 0.95 | 1.09 / 1.04 | ✅ | 43 KB |
| Dana | 0.93 | 1.25 / 1.13 | 1.11 / 1.09 | ❌ | 59 KB |
| Morabba | 0.88 | 0.91 / 0.92 | 1.15 / 1.05 | ❌ | 32 KB |
| IRANYekanX | 0.91 | 0.84 / 0.91 | 1.21 / 1.11 | ❌ | 69 KB |
| Anjoman Max | 1.00 | 0.91 / 0.86 | 1.22 / 1.16 | ❌ | 56 KB |
| Vazirmatn (پیشین) | 0.95 | 0.88 / 0.84 | 1.23 / 1.22 | ✅ | 66 KB |
| Peyda | 0.94 | 0.85 / 0.85 | 1.27 / 1.16 | ❌ | 71 KB |
- الف ÷ حرف بزرگ: ارتفاع الف به ارتفاع H. یک یعنی حرف بزرگ لاتین درست همقدِ الف است.
- ضخامت: پهنای الف به پهنای I در همان وزن. یک یعنی خط هر دو خط یکی است.
- تیرگی: جوهرِ یک جملهٔ انگلیسی به جوهرِ یک جملهٔ فارسی، هماندازه و هموزن، از عکسِ کروم. ۱٫۲۳ یعنی واژهٔ لاتین ۲۳٪ سیاهتر از فارسیِ دورش مینشیند و از جمله بیرون میزند.
وزیرمتن، ایرانیکانX و دانا اندازههای لاتینِ یکسان دارند: ارتفاع x 0.528 و حرف بزرگ 0.711 در هر سه — همان لاتینی که وزیرمتن از Roboto گرفته. لاتینِ یکانبخ (0.463 و 0.647) برای خودش کشیده شده، و در جدول همین پیداست.
tnum لازم است، نه تزئینی. رقمهای فارسیِ پیشفرض همعرض نیستند
(یکانبخ ۲۶۰ تا ۷۰۰ واحد)؛ ستونِ جدول برش بی tnum صاف نمیایستد و عددی که
زنده عوض میشود میرقصد. در یکانبخ tnum زیر خط arab هم ثبت شده و
رقم فارسی را ۷۰۰ و لاتین را ۵۵۰ میکند.
چرا نه بقیه
Section titled “چرا نه بقیه”- Peyda — جدیدترین (۲۰۲۵)، ولی بی
tnum: رقمهای هر دو خط متناسباند و «۱۱۱٬۱۱۱» در ستون جمع میشود. بدترین تیرگیِ لاتین در وزن ۴۰۰. - IRANYekanX و Dana —
fsType=256یعنی سازنده زیرمجموعهسازی را در خودِ فونت منع کرده؛ وtnumندارند. دانا ` و § و · را هم ندارد. - Morabba — فونت تیتر است: «۷» و «۸» اش شکلِ U و n دارند؛ برای برنامهای که همهاش اندازه است، خطرناک.
- Anjoman Max — ضخامت خوب، ولی لاتین ۲۲٪ تیرهتر.
فونت تیتر جدا نگرفتیم
Section titled “فونت تیتر جدا نگرفتیم”با فونت متغیر، وزن ۸۰۰ همان کنتراست تیتر را رایگان میدهد. در نمونهٔ «درزساز Darzsaz» با یکانبخ ۸۰۰ هر دو خط هموزناند؛ فونت دوم یعنی درخواست دوم و یک ناهماهنگیِ تازه بین تیتر و متن.
ضعفهای یکانبخ — و با هر کدام چه کردیم
Section titled “ضعفهای یکانبخ — و با هر کدام چه کردیم”| ضعف | اثر | کار |
|---|---|---|
| منهای ریاضی (U+2212) ندارد | Intl روی هر عدد منفیِ فارسی همین را مینویسد: «−۱۲» |
پرکنندهٔ وزیرمتن با unicode-range |
| ` ^ ~ § ² و لاتینِ تکیهدار ندارد | «~۵۰»، «m²»، نامِ «Café» ِ کاربر | همان پرکننده (۸۶ نویسه) |
| ارتفاع x ِ لاتین کمتر (0.463 در برابر 0.528) | رابط انگلیسی کمی ریزتر | سنجیده در ۱۲ تا ۱۴ پیکسل، DPR ۱: پهنای سطر برابرِ وزیرمتن، خوانا — تغییری نکرد |
| hinting ندارد | شاید لبههای نرمتر روی نمایشگرِ کمتراکمِ ویندوز | روی ویندوز سنجیده نشده. وزیرمتن هم فقط prep/gasp داشت؛ اگر آنجا نرم دیده شد، جای پیگیری همین ردیف است |
رقم فارسیِ tnum پهن است (۷۰۰) |
ستون عددی کمی باز | همان وضعِ وزیرمتن؛ tnum فقط روی ستون و عددِ زنده است، نه متن روان |
| تجاری است | مجوز | پایینتر |
چرا به خودِ یکانبخ نویسه اضافه نکردیم: افزودن گلیف یا نگاشت به cmap
یعنی ویرایشِ فونت، که مجوز fontiran اجازه نمیدهد. زیرمجموعهسازی ویرایش
نیست و fsType=8 ِ خودِ فونت اجازهاش را داده.
چرا چاپ وزیرمتن است
Section titled “چرا چاپ وزیرمتن است”سند چاپی از سایت بیرون میرود: دانلود HTML، اشتراک در واتساپ، و CLI روی
npm که @darzsaz/report را با فونتش در خود دارد (apps/cli/dist/darzsaz.mjs
همین base64 را دارد). فونتِ جاسازیشده یعنی پخشِ خودِ پروندهٔ فونت. مجوز
fontiran فقط استفاده روی سایتِ ثبتشده است؛ وزیرمتن SIL OFL و پخشش آزاد.
این مسیر عمداً پیکربندیپذیر نیست — پرچمی نیست که کسی روزی بزند و فونت تجاری را به npm بفرستد.
یکانبخ و بقیهٔ فونتهای tools/fonts/ جز وزیرمتن تجاریاند:
- فونتها را صاحبِ مخزن خریده؛
licenses.pdfوشرایط-استفاده.pdfکنار هر خانوادهاند (Peyda فقطشرایط-استفاده.pdf). - مجوز برای وبسایت و نرمافزار به نام همان محصول صادر میشود. انتشار
خودکار روی GitHub Pages خاموش است (
deploy.ymlفقط دستی)؛ روشن کردنش مجوزِ وبِ درزساز میخواهد. FontLicense.txtدر ۱۳ پوشه هست (یکانبخ ندارد)؛ ۱۱ تا جای کدِ ششرقمی را خالی دارند ((.....))، و درiran-markerوtitr-zebrجای کد نیست: متنشان استفادهٔ شخصیِ رایگان است، بی اجازهٔ فروش یا انتشار.- مخزن خصوصی است؛
apps/cliعمومی روی npm منتشر میشود و هیچ فونت تجاری در آن نیست.
pnpm format:fonts # هر سه خروجی + بلوک index.htmlnode scripts/build-fonts.mjs --check # در verify و CIpyftsubset از fontTools لازم است، با نسخهٔ دقیقِ scripts/requirements.txt (--check بایتبهبایت
میسنجد و نسخهٔ دیگر بایتِ دیگر میسازد) — وابستگی npm نیست: زیرمجموعهسازی کارِ گاهبهگاهِ ساخت است.
- بازهٔ وزن و
unicode-rangeاز خودِ فونت خوانده میشوند. بلوکِ@font-faceمیان<!-- fonts:start -->و<!-- fonts:end -->درapps/web/index.htmlتولیدی است و از prettier میگذرد تاformat:checkبا آن دعوا نکند. - پرکننده محاسبه میشود، نه فهرست دستی: نویسههای
UNICODESکه یکانبخ ندارد و وزیرمتن دارد. فونتِ رابط که عوض شود، پرکننده خودش عوض میشود. - پروندهای که دیگر ساخته نمیشود پاک میشود، و
--checkآن را خطا میداند: سرویسورکر هر woff2 ِ آن پوشه را پیشانباشت میکند، پس فونت مرده یعنی بایتِ مرده روی گوشیِ هر کاربر. - نام بدون کروشه.
Vazirmatn[wght].ttfنامِ قراردادیِ مبدأ است، ولی[و]در URL رزروشدهاند؛ سرور ایستای خودمان%5Bرا دیکد نمیکرد و پنج آزمون e2e با ۴۰۴ افتادند.
پوشش نویسه
Section titled “پوشش نویسه”scripts/font-coverage.mjs برای هر سطح با فونتِ خودش میسنجد که هر
نویسهٔ دیدنی گلیف دارد: رابط با یکانبخ + پرکننده، چاپ با وزیرمتنِ جاسازیشده.
«دیدنی» یعنی رشته. نسخهٔ اول همهٔ نویسههای پرونده را میشمرد. با
یکانبخ ۲۷۶ پرونده بهخاطر ِ template literal میافتادند، و ۹ تا از ۱۸ نویسهٔFALLBACK` (فلش و خطهای نمودار) فقط در کامنت بودند. حالا پارسرِ
خودِ TypeScript فقط رشته و متن JSX را میدهد، بهعلاوهٔ:
- JSONهای کاتالوگ — نام مصالح و یراق به رابط و چاپ میرسند و نسخهٔ اول اصلاً نمیخواندشان؛
- خروجیِ
Intlبرای هر زبانِLOCALES— منهای U+2212 در هیچ رشتهای نیست ولی روی هر عدد منفی دیده میشود؛ msgstrِ کاتالوگهای ترجمه وcontent:ِ CSS.
بی پرکننده، نگهبان − را در StatusBar و IssuesPanel، ~ را در قواعد یراق
و ² را در لیست برش نشان میدهد (امتحانشده).
۴ نویسه هنوز با فونت سامانهاند و در FALLBACK با دلیل فهرستاند:
← ↻ ⌀ ⌘ — هیچکدام از دو فونت ندارندشان؛ جای درستشان نقشِ SVG است.
apps/cli بیرون است: خروجیاش با فونتِ پایانهٔ کاربر کشیده میشود.
آزمونِ کشیدنِ واقعی
Section titled “آزمونِ کشیدنِ واقعی”apps/web/e2e/fonts.spec.ts از پروتکل کروم (CSS.getPlatformFontsForNode)
میپرسد هر گلیف را واقعاً کدام فونت کشیده:
- تیتر خانه و جملهٔ فارسیِ با PDF/CNC/Ctrl+S → همه یکانبخ؛
- «−۱٬۲۳۴» → رقمها یکانبخ، فقط یک گلیف (منها) وزیرمتن.
بی @font-face ِ پرکننده آزمون دوم میافتد و نام فونتِ مقصر را میگوید
(«Liberation Sans»، فونت سامانه). jsdom و axe هیچکدام این را نمیبینند.
ارقام همعرض
Section titled “ارقام همعرض”tabular-nums فقط روی ستونها و عددهای زنده است — جدولها، اندازههای
روی بوم، دلتای نوار وضعیت، فیلد عددی — نه روی ریشه. روی ریشه که بود، عددِ
داخلِ متنِ روان («۲ ورق») با فاصلههای باز چاپ میشد؛ با اجرای واقعیِ اپ
پیدا شد.