JibayAi commited on
Commit
8e21c5e
·
verified ·
1 Parent(s): fb5df89

Upload 5 files

Browse files
Files changed (5) hide show
  1. README.md +140 -0
  2. config.json +14 -0
  3. fonts.json +406 -0
  4. index.php +622 -0
  5. tokens.json +177 -0
README.md ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Jimage-L1
2
+
3
+ **مولد متن به تصویر پیشرفته**
4
+ *طراحی و توسعه شده توسط تیم JibayAi - ساخته شده از پایه بدون کپی‌برداری*
5
+
6
+ ## 🚀 معرفی
7
+
8
+ مدل Jimage-L1 یک سیستم قدرتمند تولید تصویر از متن با پشتیبانی کامل از زبان فارسی و انگلیسی می‌باشد. این سیستم به صورت کاملاً بومی و بدون استفاده از کتابخانه‌های خارجی توسعه یافته است.
9
+
10
+ ## ✨ قابلیت‌های اصلی
11
+
12
+ ### 📝 پردازش متن
13
+ - پشتیبانی کامل از حروف فارسی و انگلیسی
14
+ - اعتبارسنجی کاراکترها با سیستم Token-Based
15
+ - تشخیص خودکار زبان متن (فارسی/انگلیسی)
16
+ - نمایش دقیق متن بدون جابجایی یا جدا شدن حروف
17
+
18
+ ### 🎨 مدیریت فونت
19
+ - انتخاب خودکار فونت بر اساس زبان متن
20
+ - پشتیبانی از ۴۷ فونت انگلیسی در پوشه `EnglishFonts`
21
+ - پشتیبانی از ۶۳ فونت فارسی در پوشه `PersianFonts`
22
+ - انتخاب رندوم فونت مناسب برای هر درخواست
23
+
24
+ ### 🖼️ نسبت‌های تصویر
25
+ - **1:1** (مربعی)
26
+ - **4:3** (افقی)
27
+ - **3:4** (عمودی)
28
+
29
+ ### 🌈 سیستم رنگ‌آمیزی
30
+ **پس‌زمینه:**
31
+ - رنگ ساده رندوم
32
+ - گرادیانت ۲ یا ۴ رنگ با هارمونی رنگی
33
+ - گرادیانت عمودی، افقی و مورب
34
+ - رنگ‌های نزدیک به هم در گرادیانت
35
+
36
+ **متن:**
37
+ - ۵۰٪ احتمال رنگ سفید برای متن
38
+ - ۵۰٪ احتمال رنگ‌های رندوم
39
+ - تضمین تضاد رنگی با پس‌زمینه
40
+ - قابلیت گرادیانت روی متن
41
+
42
+ ### ✨ افکت‌های ویژه
43
+ - **سایه متن:** رندوم (بدون سایه، ساده، عمیق)
44
+ - **حاشیه متن:** رندوم با رنگ‌های ساده یا گرادیانت
45
+ - **گرادیانت متن:** قابلیت فعال شدن رندوم
46
+
47
+ ## 📁 ساختار فایل‌ها
48
+
49
+ ```
50
+ project/
51
+ ├── tokens.jmdl # دیکشنری کاراکترهای مجاز
52
+ ├── fonts.jmdl # لیست فونت‌های موجود
53
+ ├── EnglishFonts/ # پوشه فونت‌های انگلیسی
54
+ ├── PersianFonts/ # پوشه فونت‌های فارسی
55
+ └── jimage.php # فایل اصلی
56
+ ```
57
+
58
+ ## 🛠️ نصب و راه‌اندازی
59
+
60
+ ### نیازمندی‌ها
61
+ - PHP 7.4 یا بالاتر
62
+ - اکستنشن GD
63
+ - هاست لینوکس با سی پنل
64
+
65
+ ### مراحل نصب
66
+ 1. آپلود تمام فایل‌ها در هاست
67
+ 2. اطمینان از وجود پوشه‌های `EnglishFonts` و `PersianFonts`
68
+ 3. قرار دادن فونت‌ها در پوشه‌های مربوطه
69
+ 4. تنظیم permission مناسب (755)
70
+
71
+ ## 📡 روش استفاده
72
+
73
+ ### درخواست پایه
74
+ ```
75
+ https://example.com/jimage.php?text=متن مورد نظر
76
+ ```
77
+
78
+ ### مثال‌های کاربردی
79
+ ```
80
+ https://example.com/jimage.php?text=سلام دنیا
81
+ https://example.com/jimage.php?text=Hello World
82
+ https://example.com/jimage.php?text=پویا
83
+ ```
84
+
85
+ ## ⚡ ویژگی‌های فنی
86
+
87
+ ### بهینه‌سازی
88
+ - زمان اجرا: حداکثر ۱۰ ثانیه
89
+ - مدیریت حافظه بهینه
90
+ - سازگار با هاست‌های اشتراکی
91
+ - بدون نیاز به دسترسی ترمینال
92
+
93
+ ### امنیت
94
+ - اعتبارسنجی کامل ورودی
95
+ - بررسی کاراکترهای مجاز
96
+ - مدیریت خطاهای مختلف
97
+ - جلوگیری از حملات احتمالی
98
+
99
+ ### کیفیت
100
+ - سایز تصاویر متعادل (۴۰۰px پایه)
101
+ - محاسبه خودکار سایز فونت
102
+ - قرارگیری متن در مرکز تصویر
103
+ - کیفیت بالا در خروجی PNG
104
+
105
+ ## 🎯 پارامترهای خروجی
106
+
107
+ - **فرمت:** PNG
108
+ - **کیفیت:** بالا
109
+ - **Header-Type:** image/png
110
+ - **سایز:** پویا بر اساس نسبت انتخابی
111
+
112
+ ## ⚠️ مدیریت خطا
113
+
114
+ سیستم در صورت مواجهه با خطا، تصویر خطای مناسب تولید می‌کند:
115
+
116
+ - متن ورودی خالی است
117
+ - کاراکترهای غیرمجاز در متن
118
+ - خطا در بارگذاری tokens
119
+ - خطا در بارگذاری فونت‌ها
120
+ - فونت مناسب یافت نشد
121
+ - timeout پس از ۱۰ ثانیه
122
+
123
+ ## 🔧 توسعه و سفارشی‌سازی
124
+
125
+ این سیستم کاملاً ماژولار طراحی شده و قابلیت‌های زیر برای توسعه موجود است:
126
+
127
+ - افزودن فونت‌های جدید
128
+ - اضافه کردن زبان‌های بیشتر
129
+ - ایجاد افکت‌های جدید
130
+ - تغییر الگوریتم‌های رندوم
131
+
132
+ ## 📞 پشتیبانی
133
+
134
+ **توسعه‌دهنده:** تیم JibayAi
135
+ **نسخه:** Jimage-L1
136
+ **وضعیت:** Stable
137
+
138
+ ---
139
+
140
+ *این پروژه به طور کامل از پایه و بدون استفاده از کدهای موجود توسعه یافته است. تمام حقوق برای تیم JibayAi محفوظ می‌باشد.*
config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "files": "tokens.json",
4
+ "ok": "true",
5
+ "created-by": "JibayAi",
6
+ "model-name": "Jimage-L2"
7
+ },
8
+ {
9
+ "files": "fonts.json",
10
+ "ok": "true",
11
+ "created-by": "JibayAi",
12
+ "model-name": "Jimage-L2"
13
+ }
14
+ ]
fonts.json ADDED
@@ -0,0 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {"font-name": "AGENCYB.TTF", "lang": "en"},
3
+ {"font-name": "AGENCYR.TTF", "lang": "en"},
4
+ {"font-name": "Almost Outlines.ttf", "lang": "en"},
5
+ {"font-name": "Ara.Asmaa.Beltajie-Regular.otf", "lang": "en"},
6
+ {"font-name": "Array-Bold.otf", "lang": "en"},
7
+ {"font-name": "Array-BoldWide.otf", "lang": "en"},
8
+ {"font-name": "Array-Regular.otf", "lang": "en"},
9
+ {"font-name": "Array-Semibold.otf", "lang": "en"},
10
+ {"font-name": "Array-SemiboldWide.otf", "lang": "en"},
11
+ {"font-name": "Array-Wide.otf", "lang": "en"},
12
+ {"font-name": "b5.TTF", "lang": "en"},
13
+ {"font-name": "Bac.TTF", "lang": "en"},
14
+ {"font-name": "bgothl.ttf", "lang": "en"},
15
+ {"font-name": "bgothm.ttf", "lang": "en"},
16
+ {"font-name": "BOD_CB.TTF", "lang": "en"},
17
+ {"font-name": "BOD_CBI.TTF", "lang": "en"},
18
+ {"font-name": "BOD_CI.TTF", "lang": "en"},
19
+ {"font-name": "BOD_CR.TTF", "lang": "en"},
20
+ {"font-name": "BROADW.TTF", "lang": "en"},
21
+ {"font-name": "brooklyn.ttf", "lang": "en"},
22
+ {"font-name": "Chillax-Variable.ttf", "lang": "en"},
23
+ {"font-name": "FELIXTI.TTF", "lang": "en"},
24
+ {"font-name": "FerroRosso.ttf", "lang": "en"},
25
+ {"font-name": "Hoover-Variable.ttf", "lang": "en"},
26
+ {"font-name": "Kola-Regular.otf", "lang": "en"},
27
+ {"font-name": "Melodrama-Variable.ttf", "lang": "en"},
28
+ {"font-name": "Miraculous&Christmas.ttf", "lang": "en"},
29
+ {"font-name": "Montserrat-Variable.ttf", "lang": "en"},
30
+ {"font-name": "Montserrat-VariableItalic.ttf", "lang": "en"},
31
+ {"font-name": "NIAGENG.TTF", "lang": "en"},
32
+ {"font-name": "NIAGSOL.TTF", "lang": "en"},
33
+ {"font-name": "ONYX.TTF", "lang": "en"},
34
+ {"font-name": "Outfit-Variable.ttf", "lang": "en"},
35
+ {"font-name": "Pencerio-Hairline.otf", "lang": "en"},
36
+ {"font-name": "playstation.ttf", "lang": "en"},
37
+ {"font-name": "playstation2.ttf", "lang": "en"},
38
+ {"font-name": "pricedow.ttf", "lang": "en"},
39
+ {"font-name": "PRISTINA.TTF", "lang": "en"},
40
+ {"font-name": "QLI.TTF", "lang": "en"},
41
+ {"font-name": "QLM.TTF", "lang": "en"},
42
+ {"font-name": "QLRG.TTF", "lang": "en"},
43
+ {"font-name": "RedHatDisplay-Variable.ttf", "lang": "en"},
44
+ {"font-name": "RedHatDisplay-VariableItalic.ttf", "lang": "en"},
45
+ {"font-name": "Rosaline-Regular.otf", "lang": "en"},
46
+ {"font-name": "Sharpie-Variable.ttf", "lang": "en"},
47
+ {"font-name": "Stardom-Regular.otf", "lang": "en"},
48
+ {"font-name": "Styro-Variable.ttf", "lang": "en"},
49
+ {"font-name": "x-files.ttf", "lang": "en"},
50
+ {"font-name": "A Iranian Sans Regular.ttf", "lang": "fa"},
51
+ {"font-name": "A.Afsaneh_p30download.com.ttf", "lang": "fa"},
52
+ {"font-name": "A.Armita.Light_p30download.com.ttf", "lang": "fa"},
53
+ {"font-name": "A.Banoo Light_www.p30download.com.ttf", "lang": "fa"},
54
+ {"font-name": "A.Banoo Thin_www.p30download.com.ttf", "lang": "fa"},
55
+ {"font-name": "A.Mashin.Tahrir.Bold_p30download.com.ttf", "lang": "fa"},
56
+ {"font-name": "A.Mashin.Tahrir.Old_p30download.com.ttf", "lang": "fa"},
57
+ {"font-name": "A.Mashin.Tahrir_p30download.com.ttf", "lang": "fa"},
58
+ {"font-name": "A.Mitra.01_www.p30download.com.ttf", "lang": "fa"},
59
+ {"font-name": "A.Mitra.02_www.p30download.com.ttf", "lang": "fa"},
60
+ {"font-name": "A.Mitra.03_www.p30download.com.ttf", "lang": "fa"},
61
+ {"font-name": "A.Mitra.04_www.p30download.com.ttf", "lang": "fa"},
62
+ {"font-name": "A.Piramooz.B1_p30download.com.ttf", "lang": "fa"},
63
+ {"font-name": "A.Piramooz.Text.B2_p30download.com.ttf", "lang": "fa"},
64
+ {"font-name": "B Nazanin Bold_p30download.com.ttf", "lang": "fa"},
65
+ {"font-name": "B Nazanin_p30download.com.ttf", "lang": "fa"},
66
+ {"font-name": "Dima Shekasteh.ttf", "lang": "fa"},
67
+ {"font-name": "Dima Yekan.ttf", "lang": "fa"},
68
+ {"font-name": "DimaBarf.ttf", "lang": "fa"},
69
+ {"font-name": "DiodrumArabic.Bold_p30download.com.ttf", "lang": "fa"},
70
+ {"font-name": "DiodrumArabic.Extralight_p30download.com.ttf", "lang": "fa"},
71
+ {"font-name": "DiodrumArabic.Light_p30download.com.ttf", "lang": "fa"},
72
+ {"font-name": "DiodrumArabic.Medium_p30download.com.ttf", "lang": "fa"},
73
+ {"font-name": "DiodrumArabic.Regular_p30download.com.ttf", "lang": "fa"},
74
+ {"font-name": "DiodrumArabic.Semibold_p30download.com.ttf", "lang": "fa"},
75
+ {"font-name": "Entezar.v1.00_p30download.com.ttf", "lang": "fa"},
76
+ {"font-name": "Entezar1_v2.0.1_p30download.com.ttf", "lang": "fa"},
77
+ {"font-name": "Entezar2_v2.0.1_p30download.com.ttf", "lang": "fa"},
78
+ {"font-name": "Entezar3_v2.0.1_p30download.com.ttf", "lang": "fa"},
79
+ {"font-name": "Entezar4_v2.0.1_p30download.com.ttf", "lang": "fa"},
80
+ {"font-name": "Entezar5_v2.0.1_p30download.com.ttf", "lang": "fa"},
81
+ {"font-name": "Entezar6_v2.0.1_p30download.com.ttf", "lang": "fa"},
82
+ {"font-name": "EntezarB3_v2.0.1_p30download.com.ttf", "lang": "fa"},
83
+ {"font-name": "EntezarB4_v2.0.1_p30download.com.ttf", "lang": "fa"},
84
+ {"font-name": "EntezarB4_v2.0.1_p30download.com_.ttf", "lang": "fa"},
85
+ {"font-name": "EntezarC3_v2.0.1_p30download.com.ttf", "lang": "fa"},
86
+ {"font-name": "EntezarC_v2.0.1_p30download.com.ttf", "lang": "fa"},
87
+ {"font-name": "EntezarD3_v2.0.1_p30download.com.ttf", "lang": "fa"},
88
+ {"font-name": "EntezarD5_v2.0.1_p30download.com.ttf", "lang": "fa"},
89
+ {"font-name": "EntezarD6_v2.0.1_p30download.com.ttf", "lang": "fa"},
90
+ {"font-name": "EntezarD8_v2.0.1_p30download.com.ttf", "lang": "fa"},
91
+ {"font-name": "EntezarD_v2.0.1_p30download.com.ttf", "lang": "fa"},
92
+ {"font-name": "EntezarE2_v2.0.1_p30download.com.ttf", "lang": "fa"},
93
+ {"font-name": "EntezarE3_v2.0.1_p30download.com.ttf", "lang": "fa"},
94
+ {"font-name": "EntezarF2_v2.0.1_p30download.com.ttf", "lang": "fa"},
95
+ {"font-name": "IranNastaliq_1.ttf", "lang": "fa"},
96
+ {"font-name": "IRRoyaBold_p30download.com.ttf", "lang": "fa"},
97
+ {"font-name": "IRRoya_p30download.com.ttf", "lang": "fa"},
98
+ {"font-name": "Lalezar-Regular.ttf", "lang": "fa"},
99
+ {"font-name": "Mj_Casablanca Heavy.ttf", "lang": "fa"},
100
+ {"font-name": "Mj_Casablanca Heavy_ufont.ir.ttf", "lang": "fa"},
101
+ {"font-name": "Mj_Casablanca Light.ttf", "lang": "fa"},
102
+ {"font-name": "Mj_Casablanca Light_ufont.ir.ttf", "lang": "fa"},
103
+ {"font-name": "Mj_Casablanca.ttf", "lang": "fa"},
104
+ {"font-name": "Mj_Casablanca_ufont.ir.ttf", "lang": "fa"},
105
+ {"font-name": "Nazanin Mazar_p30download.com.ttf", "lang": "fa"},
106
+ {"font-name": "Persian Sols.ttf", "lang": "fa"},
107
+ {"font-name": "Rawaj Heavy Transitional.otf", "lang": "fa"},
108
+ {"font-name": "Rawaj Heavy.otf", "lang": "fa"},
109
+ {"font-name": "Rawaj Outlined.otf", "lang": "fa"},
110
+ {"font-name": "SGKara-Light.ttf", "lang": "fa"},
111
+ {"font-name": "SGKara-Regular.ttf", "lang": "fa"},
112
+ {"font-name": "SGKara-SemiBold.ttf", "lang": "fa"},
113
+ {"font-name": "Shekasteh V2.001.ttf", "lang": "fa"},
114
+ {"font-name": "W_vafa_p30download.com.ttf", "lang": "fa"},
115
+ {"font-name": "autoradiographic rg it.otf", "lang": "en"},
116
+ {"font-name": "autoradiographic rg.otf", "lang": "en"},
117
+ {"font-name": "axaxax bd.otf", "lang": "en"},
118
+ {"font-name": "bench grinder titling.otf", "lang": "en"},
119
+ {"font-name": "bitcrusher condensed bd.otf", "lang": "en"},
120
+ {"font-name": "breamcatcher rg.otf", "lang": "en"},
121
+ {"font-name": "budmo jiggler.otf", "lang": "en"},
122
+ {"font-name": "budmo jigglish.otf", "lang": "en"},
123
+ {"font-name": "built titling bd it.otf", "lang": "en"},
124
+ {"font-name": "built titling bd.otf", "lang": "en"},
125
+ {"font-name": "built titling el it.otf", "lang": "en"},
126
+ {"font-name": "built titling el.otf", "lang": "en"},
127
+ {"font-name": "built titling lt it.otf", "lang": "en"},
128
+ {"font-name": "built titling lt.otf", "lang": "en"},
129
+ {"font-name": "built titling rg it.otf", "lang": "en"},
130
+ {"font-name": "built titling rg.otf", "lang": "en"},
131
+ {"font-name": "built titling sb it.otf", "lang": "en"},
132
+ {"font-name": "built titling sb.otf", "lang": "en"},
133
+ {"font-name": "bullpen 3d.otf", "lang": "en"},
134
+ {"font-name": "bullpen hv it.otf", "lang": "en"},
135
+ {"font-name": "bullpen hv.otf", "lang": "en"},
136
+ {"font-name": "carbon bl.otf", "lang": "en"},
137
+ {"font-name": "carbon phyber.otf", "lang": "en"},
138
+ {"font-name": "Cardigan Titling Bd It.otf", "lang": "en"},
139
+ {"font-name": "Cardigan Titling Bd.otf", "lang": "en"},
140
+ {"font-name": "Cardigan Titling It.otf", "lang": "en"},
141
+ {"font-name": "Cardigan Titling Rg.otf", "lang": "en"},
142
+ {"font-name": "Cardigan Titling Sb It.otf", "lang": "en"},
143
+ {"font-name": "Cardigan Titling Sb.otf", "lang": "en"},
144
+ {"font-name": "chickweed titling.otf", "lang": "en"},
145
+ {"font-name": "chinese rocks rg.otf", "lang": "en"},
146
+ {"font-name": "Conthrax-SemiBold.otf", "lang": "en"},
147
+ {"font-name": "Coolvetica Hv Comp.otf", "lang": "en"},
148
+ {"font-name": "Coolvetica Rg Cond.otf", "lang": "en"},
149
+ {"font-name": "Coolvetica Rg Cram.otf", "lang": "en"},
150
+ {"font-name": "Coolvetica Rg It.otf", "lang": "en"},
151
+ {"font-name": "Coolvetica Rg.otf", "lang": "en"},
152
+ {"font-name": "dealerplate california.otf", "lang": "en"},
153
+ {"font-name": "densmore.otf", "lang": "en"},
154
+ {"font-name": "Dirty Bakers Dozen.otf", "lang": "en"},
155
+ {"font-name": "dream orphanage rg.otf", "lang": "en"},
156
+ {"font-name": "duality.otf", "lang": "en"},
157
+ {"font-name": "earwig factory rg.otf", "lang": "en"},
158
+ {"font-name": "Ethnocentric Rg It.otf", "lang": "en"},
159
+ {"font-name": "Ethnocentric Rg.otf", "lang": "en"},
160
+ {"font-name": "evensong hollow.otf", "lang": "en"},
161
+ {"font-name": "expressway rg.otf", "lang": "en"},
162
+ {"font-name": "Fenwick Outline.otf", "lang": "en"},
163
+ {"font-name": "fledgling-sb.otf", "lang": "en"},
164
+ {"font-name": "Forgotten Futurist Bd It.otf", "lang": "en"},
165
+ {"font-name": "Forgotten Futurist Bd.otf", "lang": "en"},
166
+ {"font-name": "Forgotten Futurist Rg It.otf", "lang": "en"},
167
+ {"font-name": "Forgotten Futurist Rg.otf", "lang": "en"},
168
+ {"font-name": "Galderglynn Titling Bd It.otf", "lang": "en"},
169
+ {"font-name": "Galderglynn Titling Bd.otf", "lang": "en"},
170
+ {"font-name": "Galderglynn Titling Bl It.otf", "lang": "en"},
171
+ {"font-name": "Galderglynn Titling Bl.otf", "lang": "en"},
172
+ {"font-name": "Galderglynn Titling El It.otf", "lang": "en"},
173
+ {"font-name": "Galderglynn Titling El.otf", "lang": "en"},
174
+ {"font-name": "Galderglynn Titling Hl It.otf", "lang": "en"},
175
+ {"font-name": "Galderglynn Titling Hl.otf", "lang": "en"},
176
+ {"font-name": "Galderglynn Titling Lt It.otf", "lang": "en"},
177
+ {"font-name": "Galderglynn Titling Lt.otf", "lang": "en"},
178
+ {"font-name": "Galderglynn Titling Rg It.otf", "lang": "en"},
179
+ {"font-name": "Galderglynn Titling Rg.otf", "lang": "en"},
180
+ {"font-name": "Galderglynn Titling Th It.otf", "lang": "en"},
181
+ {"font-name": "Galderglynn Titling Th.otf", "lang": "en"},
182
+ {"font-name": "Geoparody Hv.otf", "lang": "en"},
183
+ {"font-name": "Geoparody Rg.otf", "lang": "en"},
184
+ {"font-name": "Gnuolane Rg.otf", "lang": "en"},
185
+ {"font-name": "Good Times Rg.otf", "lang": "en"},
186
+ {"font-name": "good timing bd.otf", "lang": "en"},
187
+ {"font-name": "Gravtrac Bd Comp.otf", "lang": "en"},
188
+ {"font-name": "gunplay 3d.otf", "lang": "en"},
189
+ {"font-name": "gunplay rg.otf", "lang": "en"},
190
+ {"font-name": "Gymkhana Lt.otf", "lang": "en"},
191
+ {"font-name": "heavy heap rg.otf", "lang": "en"},
192
+ {"font-name": "Hemi Head Bd It.otf", "lang": "en"},
193
+ {"font-name": "Jesaya Lt.otf", "lang": "en"},
194
+ {"font-name": "joystix monospace.otf", "lang": "en"},
195
+ {"font-name": "junegull rg.otf", "lang": "en"},
196
+ {"font-name": "Kenyan Coffee Bd It.otf", "lang": "en"},
197
+ {"font-name": "Kenyan Coffee Bd.otf", "lang": "en"},
198
+ {"font-name": "Kenyan Coffee Rg It.otf", "lang": "en"},
199
+ {"font-name": "Kenyan Coffee Rg.otf", "lang": "en"},
200
+ {"font-name": "Kenyan Coffee Stencil Sb.otf", "lang": "en"},
201
+ {"font-name": "Kimberley Bl.otf", "lang": "en"},
202
+ {"font-name": "kingsbridge bd it.otf", "lang": "en"},
203
+ {"font-name": "kingsbridge bd.otf", "lang": "en"},
204
+ {"font-name": "kingsbridge bk it.otf", "lang": "en"},
205
+ {"font-name": "kingsbridge bk.otf", "lang": "en"},
206
+ {"font-name": "kingsbridge cd bd it.otf", "lang": "en"},
207
+ {"font-name": "kingsbridge cd bd.otf", "lang": "en"},
208
+ {"font-name": "kingsbridge cd bk it.otf", "lang": "en"},
209
+ {"font-name": "kingsbridge cd bk.otf", "lang": "en"},
210
+ {"font-name": "kingsbridge cd el it.otf", "lang": "en"},
211
+ {"font-name": "kingsbridge cd el.otf", "lang": "en"},
212
+ {"font-name": "kingsbridge cd lt it.otf", "lang": "en"},
213
+ {"font-name": "kingsbridge cd lt.otf", "lang": "en"},
214
+ {"font-name": "kingsbridge cd rg it.otf", "lang": "en"},
215
+ {"font-name": "kingsbridge cd rg.otf", "lang": "en"},
216
+ {"font-name": "kingsbridge cd sb it.otf", "lang": "en"},
217
+ {"font-name": "kingsbridge cd sb.otf", "lang": "en"},
218
+ {"font-name": "kingsbridge cd ul it.otf", "lang": "en"},
219
+ {"font-name": "kingsbridge cd ul.otf", "lang": "en"},
220
+ {"font-name": "kingsbridge el it.otf", "lang": "en"},
221
+ {"font-name": "kingsbridge el.otf", "lang": "en"},
222
+ {"font-name": "kingsbridge ex bd it.otf", "lang": "en"},
223
+ {"font-name": "kingsbridge ex bd.otf", "lang": "en"},
224
+ {"font-name": "kingsbridge ex bk it.otf", "lang": "en"},
225
+ {"font-name": "kingsbridge ex bk.otf", "lang": "en"},
226
+ {"font-name": "kingsbridge ex el it.otf", "lang": "en"},
227
+ {"font-name": "kingsbridge ex el.otf", "lang": "en"},
228
+ {"font-name": "kingsbridge ex lt it.otf", "lang": "en"},
229
+ {"font-name": "kingsbridge ex lt.otf", "lang": "en"},
230
+ {"font-name": "kingsbridge ex rg it.otf", "lang": "en"},
231
+ {"font-name": "kingsbridge ex rg.otf", "lang": "en"},
232
+ {"font-name": "kingsbridge ex sb it.otf", "lang": "en"},
233
+ {"font-name": "kingsbridge ex sb.otf", "lang": "en"},
234
+ {"font-name": "kingsbridge ex ul it.otf", "lang": "en"},
235
+ {"font-name": "kingsbridge ex ul.otf", "lang": "en"},
236
+ {"font-name": "kingsbridge lt it.otf", "lang": "en"},
237
+ {"font-name": "kingsbridge lt.otf", "lang": "en"},
238
+ {"font-name": "kingsbridge rg it.otf", "lang": "en"},
239
+ {"font-name": "kingsbridge rg.otf", "lang": "en"},
240
+ {"font-name": "kingsbridge sb it.otf", "lang": "en"},
241
+ {"font-name": "kingsbridge sb.otf", "lang": "en"},
242
+ {"font-name": "kingsbridge sc bd it.otf", "lang": "en"},
243
+ {"font-name": "kingsbridge sc bd.otf", "lang": "en"},
244
+ {"font-name": "kingsbridge sc bk it.otf", "lang": "en"},
245
+ {"font-name": "kingsbridge sc bk.otf", "lang": "en"},
246
+ {"font-name": "kingsbridge sc el it.otf", "lang": "en"},
247
+ {"font-name": "kingsbridge sc el.otf", "lang": "en"},
248
+ {"font-name": "kingsbridge sc lt it.otf", "lang": "en"},
249
+ {"font-name": "kingsbridge sc lt.otf", "lang": "en"},
250
+ {"font-name": "kingsbridge sc rg it.otf", "lang": "en"},
251
+ {"font-name": "kingsbridge sc rg.otf", "lang": "en"},
252
+ {"font-name": "kingsbridge sc sb it.otf", "lang": "en"},
253
+ {"font-name": "kingsbridge sc sb.otf", "lang": "en"},
254
+ {"font-name": "kingsbridge sc ul it.otf", "lang": "en"},
255
+ {"font-name": "kingsbridge sc ul.otf", "lang": "en"},
256
+ {"font-name": "kingsbridge ul it.otf", "lang": "en"},
257
+ {"font-name": "kingsbridge ul.otf", "lang": "en"},
258
+ {"font-name": "Kirsty Bd It.otf", "lang": "en"},
259
+ {"font-name": "Kirsty Bd.otf", "lang": "en"},
260
+ {"font-name": "Kirsty Rg It.otf", "lang": "en"},
261
+ {"font-name": "Kirsty Rg.otf", "lang": "en"},
262
+ {"font-name": "kleptocracy titling bd.otf", "lang": "en"},
263
+ {"font-name": "kleptocracy titling cd bd.otf", "lang": "en"},
264
+ {"font-name": "kleptocracy titling cd lt.otf", "lang": "en"},
265
+ {"font-name": "kleptocracy titling cd rg.otf", "lang": "en"},
266
+ {"font-name": "kleptocracy titling ex bd.otf", "lang": "en"},
267
+ {"font-name": "kleptocracy titling ex lt.otf", "lang": "en"},
268
+ {"font-name": "kleptocracy titling ex rg.otf", "lang": "en"},
269
+ {"font-name": "kleptocracy titling lt.otf", "lang": "en"},
270
+ {"font-name": "kleptocracy titling rg.otf", "lang": "en"},
271
+ {"font-name": "Larabiefont Rg.otf", "lang": "en"},
272
+ {"font-name": "Libel Suit Suit Rg.otf", "lang": "en"},
273
+ {"font-name": "Meloche Lt.otf", "lang": "en"},
274
+ {"font-name": "Mexcellent 3d.otf", "lang": "en"},
275
+ {"font-name": "Mexcellent Rg.otf", "lang": "en"},
276
+ {"font-name": "Mixolydian Titling Bd It.otf", "lang": "en"},
277
+ {"font-name": "Mixolydian Titling Bd.otf", "lang": "en"},
278
+ {"font-name": "Mixolydian Titling El It.otf", "lang": "en"},
279
+ {"font-name": "Mixolydian Titling El.otf", "lang": "en"},
280
+ {"font-name": "Mixolydian Titling Hl It.otf", "lang": "en"},
281
+ {"font-name": "Mixolydian Titling Hl.otf", "lang": "en"},
282
+ {"font-name": "Mixolydian Titling Lt It.otf", "lang": "en"},
283
+ {"font-name": "Mixolydian Titling Lt.otf", "lang": "en"},
284
+ {"font-name": "Mixolydian Titling Rg It.otf", "lang": "en"},
285
+ {"font-name": "Mixolydian Titling Rg.otf", "lang": "en"},
286
+ {"font-name": "Mixolydian Titling Th It.otf", "lang": "en"},
287
+ {"font-name": "Mixolydian Titling Th.otf", "lang": "en"},
288
+ {"font-name": "monofonto rg.otf", "lang": "en"},
289
+ {"font-name": "Mufferaw Rg.otf", "lang": "en"},
290
+ {"font-name": "Nasalization Rg.otf", "lang": "en"},
291
+ {"font-name": "Negotiate Rg.otf", "lang": "en"},
292
+ {"font-name": "Neuropol X Rg.otf", "lang": "en"},
293
+ {"font-name": "Neuropolitical Rg.otf", "lang": "en"},
294
+ {"font-name": "Nulshock Bd.otf", "lang": "en"},
295
+ {"font-name": "Octin College Rg.otf", "lang": "en"},
296
+ {"font-name": "Octin Prison Rg.otf", "lang": "en"},
297
+ {"font-name": "Octin Sports Rg.otf", "lang": "en"},
298
+ {"font-name": "Octin Spraypaint A Rg.otf", "lang": "en"},
299
+ {"font-name": "Octin Stencil Rg.otf", "lang": "en"},
300
+ {"font-name": "Octin Vintage B Rg.otf", "lang": "en"},
301
+ {"font-name": "pakenham rg.otf", "lang": "en"},
302
+ {"font-name": "Palamecia Titling.otf", "lang": "en"},
303
+ {"font-name": "Pirulen Rg.otf", "lang": "en"},
304
+ {"font-name": "Pricedown Bl.otf", "lang": "en"},
305
+ {"font-name": "Pupcat Rg.otf", "lang": "en"},
306
+ {"font-name": "quasix titling.otf", "lang": "en"},
307
+ {"font-name": "Rakesly Bd It.otf", "lang": "en"},
308
+ {"font-name": "Rakesly Bd.otf", "lang": "en"},
309
+ {"font-name": "Rakesly El It.otf", "lang": "en"},
310
+ {"font-name": "Rakesly El.otf", "lang": "en"},
311
+ {"font-name": "Rakesly Hl It.otf", "lang": "en"},
312
+ {"font-name": "Rakesly Hl.otf", "lang": "en"},
313
+ {"font-name": "Rakesly Lt It.otf", "lang": "en"},
314
+ {"font-name": "Rakesly Lt.otf", "lang": "en"},
315
+ {"font-name": "Rakesly Rg It.otf", "lang": "en"},
316
+ {"font-name": "Rakesly Rg.otf", "lang": "en"},
317
+ {"font-name": "Rakesly Th It.otf", "lang": "en"},
318
+ {"font-name": "Rakesly Th.otf", "lang": "en"},
319
+ {"font-name": "read-this.html", "lang": "en"},
320
+ {"font-name": "Recharge Bd.otf", "lang": "en"},
321
+ {"font-name": "Remissis Sb.otf", "lang": "en"},
322
+ {"font-name": "Rexlia Rg.otf", "lang": "en"},
323
+ {"font-name": "rimouski sb.otf", "lang": "en"},
324
+ {"font-name": "shlop rg.otf", "lang": "en"},
325
+ {"font-name": "Sofachrome Rg It.otf", "lang": "en"},
326
+ {"font-name": "Sofachrome Rg.otf", "lang": "en"},
327
+ {"font-name": "Steelfish Bd It.otf", "lang": "en"},
328
+ {"font-name": "Steelfish Bd.otf", "lang": "en"},
329
+ {"font-name": "Steelfish Eb It.otf", "lang": "en"},
330
+ {"font-name": "Steelfish Eb.otf", "lang": "en"},
331
+ {"font-name": "Steelfish Outline.otf", "lang": "en"},
332
+ {"font-name": "Steelfish Rg It.otf", "lang": "en"},
333
+ {"font-name": "Steelfish Rg.otf", "lang": "en"},
334
+ {"font-name": "Steelfish Rounded Bd.otf", "lang": "en"},
335
+ {"font-name": "Strenuous 3d.otf", "lang": "en"},
336
+ {"font-name": "Strenuous Bl.otf", "lang": "en"},
337
+ {"font-name": "Sui Generis Rg.otf", "lang": "en"},
338
+ {"font-name": "toxigenesis bd.otf", "lang": "en"},
339
+ {"font-name": "Venus Rising Rg.otf", "lang": "en"},
340
+ {"font-name": "Vinque Rg.otf", "lang": "en"},
341
+ {"font-name": "Vipnagorgialla Bd It.otf", "lang": "en"},
342
+ {"font-name": "Vipnagorgialla Bd.otf", "lang": "en"},
343
+ {"font-name": "Vipnagorgialla Rg It.otf", "lang": "en"},
344
+ {"font-name": "Vipnagorgialla Rg.otf", "lang": "en"},
345
+ {"font-name": "wheaton capitals.otf", "lang": "en"},
346
+ {"font-name": "Zekton Rg.otf", "lang": "en"},
347
+ {"font-name": "zrnic rg.otf", "lang": "en"},
348
+ {"font-name": "IRAban.ttf", "lang": "fa"},
349
+ {"font-name": "IRAmir.ttf", "lang": "fa"},
350
+ {"font-name": "IRArshia.ttf", "lang": "fa"},
351
+ {"font-name": "IRBadr.ttf", "lang": "fa"},
352
+ {"font-name": "IRBadrBold.ttf", "lang": "fa"},
353
+ {"font-name": "IRBadrIranic.ttf", "lang": "fa"},
354
+ {"font-name": "IRCompset.ttf", "lang": "fa"},
355
+ {"font-name": "IRCompsetBold.ttf", "lang": "fa"},
356
+ {"font-name": "IRCompsetIra.ttf", "lang": "fa"},
357
+ {"font-name": "IRDastNevis.ttf", "lang": "fa"},
358
+ {"font-name": "IRDavat.ttf", "lang": "fa"},
359
+ {"font-name": "IRElham.ttf", "lang": "fa"},
360
+ {"font-name": "IREntezar.ttf", "lang": "fa"},
361
+ {"font-name": "IRFarnaz.ttf", "lang": "fa"},
362
+ {"font-name": "IRFerdosi.ttf", "lang": "fa"},
363
+ {"font-name": "IRHoma.ttf", "lang": "fa"},
364
+ {"font-name": "IRJadid.ttf", "lang": "fa"},
365
+ {"font-name": "IRKamran.ttf", "lang": "fa"},
366
+ {"font-name": "IRKhorasan.ttf", "lang": "fa"},
367
+ {"font-name": "IRKoodak.ttf", "lang": "fa"},
368
+ {"font-name": "IRLotus.ttf", "lang": "fa"},
369
+ {"font-name": "IRLotusBold.ttf", "lang": "fa"},
370
+ {"font-name": "IRLotusIranic.ttf", "lang": "fa"},
371
+ {"font-name": "IRMaryam.ttf", "lang": "fa"},
372
+ {"font-name": "IRMashhad.ttf", "lang": "fa"},
373
+ {"font-name": "IRMehr.ttf", "lang": "fa"},
374
+ {"font-name": "IRMitra.ttf", "lang": "fa"},
375
+ {"font-name": "IRMitraBold.ttf", "lang": "fa"},
376
+ {"font-name": "IRMitraIranic_.ttf", "lang": "fa"},
377
+ {"font-name": "IRMomtaz.ttf", "lang": "fa"},
378
+ {"font-name": "IRNarges.ttf", "lang": "fa"},
379
+ {"font-name": "IRNaskh.ttf", "lang": "fa"},
380
+ {"font-name": "IRNazanin.ttf", "lang": "fa"},
381
+ {"font-name": "IRNazaninBold.ttf", "lang": "fa"},
382
+ {"font-name": "IRNazaninIrani.ttf", "lang": "fa"},
383
+ {"font-name": "IRNazli.ttf", "lang": "fa"},
384
+ {"font-name": "IRNazliBold.ttf", "lang": "fa"},
385
+ {"font-name": "IRPooya.ttf", "lang": "fa"},
386
+ {"font-name": "IRRoya.ttf", "lang": "fa"},
387
+ {"font-name": "IRRoyaBold.ttf", "lang": "fa"},
388
+ {"font-name": "IRRoyaIranic.ttf", "lang": "fa"},
389
+ {"font-name": "IRShiraz.ttf", "lang": "fa"},
390
+ {"font-name": "IRSina.ttf", "lang": "fa"},
391
+ {"font-name": "IRTabassom.ttf", "lang": "fa"},
392
+ {"font-name": "IRTehran.ttf", "lang": "fa"},
393
+ {"font-name": "IRTerafik.ttf", "lang": "fa"},
394
+ {"font-name": "IRTerafikBold.ttf", "lang": "fa"},
395
+ {"font-name": "IRTerafikIranic.ttf", "lang": "fa"},
396
+ {"font-name": "IRTitr.ttf", "lang": "fa"},
397
+ {"font-name": "IRYakout.ttf", "lang": "fa"},
398
+ {"font-name": "IRYakoutBold.ttf", "lang": "fa"},
399
+ {"font-name": "IRYakoutIranic.ttf", "lang": "fa"},
400
+ {"font-name": "IRYekan.ttf", "lang": "fa"},
401
+ {"font-name": "IRYekanBold.ttf", "lang": "fa"},
402
+ {"font-name": "IRZar.ttf", "lang": "fa"},
403
+ {"font-name": "IRZarBold.ttf", "lang": "fa"},
404
+ {"font-name": "IRZarIranic.ttf", "lang": "fa"},
405
+ {"font-name": "IRZeytoon.ttf", "lang": "fa"}
406
+ ]
index.php ADDED
@@ -0,0 +1,622 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ header('Content-Type: text/html; charset=utf-8');
4
+ mb_internal_encoding('UTF-8');
5
+
6
+ function convertToUnicode($text) {
7
+ $persianChars = [
8
+ 'آ' => '\u0622',
9
+ 'ا' => '\u0627',
10
+ 'ب' => '\u0628',
11
+ 'پ' => '\u067e',
12
+ 'ت' => '\u062a',
13
+ 'ث' => '\u062b',
14
+ 'ج' => '\u062c',
15
+ 'چ' => '\u0686',
16
+ 'ح' => '\u062d',
17
+ 'خ' => '\u062e',
18
+ 'د' => '\u062f',
19
+ 'ذ' => '\u0630',
20
+ 'ر' => '\u0631',
21
+ 'ز' => '\u0632',
22
+ 'ژ' => '\u0698',
23
+ 'س' => '\u0633',
24
+ 'ش' => '\u0634',
25
+ 'ص' => '\u0635',
26
+ 'ض' => '\u0636',
27
+ 'ط' => '\u0637',
28
+ 'ظ' => '\u0638',
29
+ 'ع' => '\u0639',
30
+ 'غ' => '\u063a',
31
+ 'ف' => '\u0641',
32
+ 'ق' => '\u0642',
33
+ 'ک' => '\u06a9',
34
+ 'گ' => '\u06af',
35
+ 'ل' => '\u0644',
36
+ 'م' => '\u0645',
37
+ 'ن' => '\u0646',
38
+ 'و' => '\u0648',
39
+ 'ه' => '\u0647',
40
+ 'ی' => '\u06cc',
41
+ ' ' => '\u0020',
42
+ '۰' => '\u06f0',
43
+ '۱' => '\u06f1',
44
+ '۲' => '\u06f2',
45
+ '۳' => '\u06f3',
46
+ '۴' => '\u06f4',
47
+ '۵' => '\u06f5',
48
+ '۶' => '\u06f6',
49
+ '۷' => '\u06f7',
50
+ '۸' => '\u06f8',
51
+ '۹' => '\u06f9'
52
+ ];
53
+
54
+ $unicodeText = '';
55
+ $chars = mb_str_split($text);
56
+
57
+ foreach ($chars as $char) {
58
+ if (isset($persianChars[$char])) {
59
+ $unicodeText .= $persianChars[$char];
60
+ } else {
61
+ $unicodeText .= $char;
62
+ }
63
+ }
64
+
65
+ return $unicodeText;
66
+ }
67
+
68
+ function generateTextImage() {
69
+ $text = $_GET['text'] ?? '';
70
+ $image_url = $_GET['image_url'] ?? '';
71
+
72
+ if (empty($text)) {
73
+ createErrorImage('text is empty');
74
+ return;
75
+ }
76
+
77
+ $tokensFile = __DIR__ . '/tokens.json';
78
+ $fontsFile = __DIR__ . '/fonts.json';
79
+
80
+ if (!file_exists($tokensFile)) {
81
+ createErrorImage('tokens not found');
82
+ return;
83
+ }
84
+
85
+ if (!file_exists($fontsFile)) {
86
+ createErrorImage('fonts not found');
87
+ return;
88
+ }
89
+
90
+ $tokensContent = file_get_contents($tokensFile);
91
+ $fontsContent = file_get_contents($fontsFile);
92
+
93
+ $tokens = json_decode($tokensContent, true);
94
+ $fonts = json_decode($fontsContent, true);
95
+
96
+ if ($tokens === null) {
97
+ createErrorImage('error in read tokens');
98
+ return;
99
+ }
100
+
101
+ if ($fonts === null) {
102
+ createErrorImage('error in read font');
103
+ return;
104
+ }
105
+
106
+ foreach (mb_str_split($text) as $char) {
107
+ $found = false;
108
+ foreach ($tokens as $token) {
109
+ if ($token['word'] === $char) {
110
+ $found = true;
111
+ break;
112
+ }
113
+ }
114
+ if (!$found) {
115
+ createErrorImage('Illegal characters in text');
116
+ return;
117
+ }
118
+ }
119
+
120
+ $lang = 'en';
121
+ foreach (mb_str_split($text) as $char) {
122
+ foreach ($tokens as $token) {
123
+ if ($token['word'] === $char && $token['language'] === 'persian/farsi/iran') {
124
+ $lang = 'fa';
125
+ break 2;
126
+ } elseif ($token['word'] === $char && $token['language'] === 'English') {
127
+ $lang = 'en';
128
+ break 2;
129
+ }
130
+ }
131
+ }
132
+
133
+ $langFonts = array_filter($fonts, function($font) use ($lang) {
134
+ return $font['lang'] === $lang;
135
+ });
136
+ $langFonts = array_values($langFonts);
137
+
138
+ if (empty($langFonts)) {
139
+ createErrorImage('font not found for this language');
140
+ return;
141
+ }
142
+
143
+ $selectedFont = $langFonts[array_rand($langFonts)];
144
+
145
+ $fontPath = __DIR__ . '/' . ($lang === 'fa' ? 'PersianFonts/' : 'EnglishFonts/') . $selectedFont['font-name'];
146
+ if (!file_exists($fontPath)) {
147
+ createErrorImage('font selected . not found');
148
+ return;
149
+ }
150
+
151
+ $ratios = [
152
+ [1, 1],
153
+ [1, 1],
154
+ [1, 1]
155
+ ];
156
+ $ratio = $ratios[array_rand($ratios)];
157
+ $baseSize = 2000;
158
+ $width = $ratio[0] * ($baseSize / 2);
159
+ $height = $ratio[1] * ($baseSize / 2);
160
+
161
+ $image = imagecreatetruecolor($width, $height);
162
+ imagesavealpha($image, true);
163
+ $transparent = imagecolorallocatealpha($image, 0, 0, 0, 127);
164
+ imagefill($image, 0, 0, $transparent);
165
+
166
+ $externalImage = null;
167
+ if (!empty($image_url)) {
168
+ $externalImage = loadExternalImage($image_url);
169
+ }
170
+
171
+ if ($externalImage) {
172
+ $extW = imagesx($externalImage);
173
+ $extH = imagesy($externalImage);
174
+ $scale = max($width / $extW, $height / $extH);
175
+ $newW = (int)($extW * $scale);
176
+ $newH = (int)($extH * $scale);
177
+ $bg = imagecreatetruecolor($width, $height);
178
+ imagesavealpha($bg, true);
179
+ $transparent = imagecolorallocatealpha($bg, 0, 0, 0, 127);
180
+ imagefill($bg, 0, 0, $transparent);
181
+ imagecopyresampled($bg, $externalImage, (int)(($width - $newW)/2), (int)(($height - $newH)/2), 0, 0, $newW, $newH, $extW, $extH);
182
+ imagecopy($image, $bg, 0, 0, 0, 0, $width, $height);
183
+ imagedestroy($bg);
184
+ } else {
185
+ $bgType = mt_rand(0, 1);
186
+ if ($bgType === 0) {
187
+ do {
188
+ $bgColor = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
189
+ } while ($bgColor === false);
190
+ imagefill($image, 0, 0, $bgColor);
191
+ } else {
192
+ $gradientColors = mt_rand(0, 1) ? 2 : 4;
193
+ $baseHue = mt_rand(0, 360);
194
+ $colors = [];
195
+ for ($i = 0; $i < $gradientColors; $i++) {
196
+ $hue = $baseHue + mt_rand(-15, 15);
197
+ $hue = max(0, min(360, $hue));
198
+ $colors[] = hslToRgb($hue / 360, mt_rand(80, 100) / 100, mt_rand(50, 80) / 100);
199
+ }
200
+ $directions = ['horizontal', 'vertical', 'diagonal', 'radial'];
201
+ $direction = $directions[array_rand($directions)];
202
+ createUltraGradient($image, $colors, $direction, $width, $height);
203
+ }
204
+ }
205
+
206
+ $hasCircles = (mt_rand(1, 10) === 1);
207
+ if ($hasCircles) {
208
+ $circleCount = mt_rand(3, 8);
209
+ for ($i = 0; $i < $circleCount; $i++) {
210
+ $circleColor = imagecolorallocatealpha($image, mt_rand(150, 255), mt_rand(150, 255), mt_rand(150, 255), mt_rand(30, 70));
211
+ $circleSize = mt_rand(40, min($width, $height) / 4);
212
+ $circleX = mt_rand(-$circleSize, $width + $circleSize);
213
+ $circleY = mt_rand(-$circleSize, $height + $circleSize);
214
+ imagefilledellipse($image, $circleX, $circleY, $circleSize, $circleSize, $circleColor);
215
+ }
216
+ }
217
+
218
+ $hasPattern = mt_rand(0, 3) === 0;
219
+ if ($hasPattern && !$externalImage) {
220
+ createGeometricPattern($image, $width, $height);
221
+ }
222
+
223
+ $processedText = $text;
224
+ if ($lang === 'fa') {
225
+ $chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY);
226
+ $reversed = array_reverse($chars);
227
+ $processedText = implode('', $reversed);
228
+ $rtlMarkers = "";
229
+ $processedText = $rtlMarkers . $processedText . $rtlMarkers;
230
+ }
231
+
232
+ $fontSize = calculateOptimalFontSize($processedText, $fontPath, $width, $height, $externalImage);
233
+ $angle = 0;
234
+ $bbox = imagettfbbox($fontSize, $angle, $fontPath, $processedText);
235
+ if ($bbox === false) {
236
+ createErrorImage('Error in calculating text size');
237
+ return;
238
+ }
239
+ $textWidth = $bbox[2] - $bbox[0];
240
+ $textHeight = $bbox[1] - $bbox[7];
241
+ $margin = 40;
242
+ if ($textWidth + $margin * 2 > $width) {
243
+ $scale = ($width - $margin * 2) / $textWidth;
244
+ $fontSize = max(12, (int)($fontSize * $scale));
245
+ $bbox = imagettfbbox($fontSize, $angle, $fontPath, $processedText);
246
+ $textWidth = $bbox[2] - $bbox[0];
247
+ $textHeight = $bbox[1] - $bbox[7];
248
+ }
249
+ $textX = ($width - $textWidth) / 2;
250
+ $textY = ($height - $textHeight) / 2 + $textHeight;
251
+
252
+ $textColor = null;
253
+ if ($externalImage) {
254
+ $avg = estimateAverageColor($image);
255
+ $lum = ($avg[0] * 0.299 + $avg[1] * 0.587 + $avg[2] * 0.114);
256
+ $textColor = $lum > 128 ? imagecolorallocate($image, 0, 0, 0) : imagecolorallocate($image, 255, 255, 255);
257
+ } else {
258
+ $textColor = imagecolorallocate($image, 255, 255, 255);
259
+ }
260
+
261
+ $hasShadow = false;
262
+ $hasGlow = false;
263
+ $hasBorder = false;
264
+ $hasTextGradient = false;
265
+
266
+ if ($hasShadow) {
267
+ $shadowIntensity = mt_rand(2, 4);
268
+ $shadowColor = imagecolorallocatealpha($image, 0, 0, 0, mt_rand(30, 60));
269
+ for ($i = 1; $i <= $shadowIntensity; $i++) {
270
+ imagettftext($image, $fontSize, $angle, $textX + $i, $textY + $i, $shadowColor, $fontPath, $processedText);
271
+ }
272
+ }
273
+
274
+ if ($hasGlow) {
275
+ $glowColor = imagecolorallocatealpha($image, mt_rand(100, 255), mt_rand(100, 255), mt_rand(100, 255), mt_rand(20, 40));
276
+ $glowSize = mt_rand(3, 6);
277
+ for ($i = -$glowSize; $i <= $glowSize; $i++) {
278
+ for ($j = -$glowSize; $j <= $glowSize; $j++) {
279
+ if (abs($i) + abs($j) <= $glowSize) {
280
+ imagettftext($image, $fontSize, $angle, $textX + $i, $textY + $j, $glowColor, $fontPath, $processedText);
281
+ }
282
+ }
283
+ }
284
+ }
285
+
286
+ if ($hasBorder) {
287
+ $borderColor = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
288
+ $borderThickness = mt_rand(1, 3);
289
+ for ($i = -$borderThickness; $i <= $borderThickness; $i++) {
290
+ for ($j = -$borderThickness; $j <= $borderThickness; $j++) {
291
+ if (abs($i) + abs($j) <= $borderThickness * 1.5) {
292
+ imagettftext($image, $fontSize, $angle, $textX + $i, $textY + $j, $borderColor, $fontPath, $processedText);
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ imagettftext($image, $fontSize, $angle, (int)$textX, (int)$textY, $textColor, $fontPath, $processedText);
299
+
300
+ header('Content-Type: image/png');
301
+ imagepng($image, null, 9);
302
+ imagedestroy($image);
303
+ }
304
+
305
+ function calculateOptimalFontSize($text, $fontPath, $width, $height, $externalImage) {
306
+ $maxSize = min($width, $height) / 3;
307
+ $minSize = 24;
308
+ if ($externalImage) {
309
+ $maxSize = min($width, $height) / 5;
310
+ }
311
+ for ($size = $maxSize; $size >= $minSize; $size -= 1) {
312
+ $bbox = imagettfbbox($size, 0, $fontPath, $text);
313
+ if ($bbox === false) continue;
314
+ $textWidth = $bbox[2] - $bbox[0];
315
+ $textHeight = $bbox[1] - $bbox[7];
316
+ if ($textWidth < $width * 0.85 && $textHeight < $height * 0.6) {
317
+ return $size;
318
+ }
319
+ }
320
+ return $minSize;
321
+ }
322
+
323
+ function loadExternalImage($url) {
324
+ $ch = curl_init();
325
+ curl_setopt($ch, CURLOPT_URL, $url);
326
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
327
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
328
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
329
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
330
+ curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
331
+ curl_setopt($ch, CURLOPT_ENCODING, '');
332
+ $imageData = curl_exec($ch);
333
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
334
+ curl_close($ch);
335
+ if (!$imageData || $httpCode !== 200) {
336
+ return null;
337
+ }
338
+ $image = @imagecreatefromstring($imageData);
339
+ if (!$image) {
340
+ return null;
341
+ }
342
+ return $image;
343
+ }
344
+
345
+ function makeImageRounded($image) {
346
+ $width = imagesx($image);
347
+ $height = imagesy($image);
348
+ $rounded = imagecreatetruecolor($width, $height);
349
+ imagesavealpha($rounded, true);
350
+ $transparent = imagecolorallocatealpha($rounded, 0, 0, 0, 127);
351
+ imagefill($rounded, 0, 0, $transparent);
352
+ $radius = min($width, $height) / 4;
353
+ for ($x = 0; $x < $width; $x++) {
354
+ for ($y = 0; $y < $height; $y++) {
355
+ $distance = sqrt(pow($x - $width/2, 2) + pow($y - $height/2, 2));
356
+ if ($distance <= $radius) {
357
+ $color = imagecolorat($image, $x, $y);
358
+ imagesetpixel($rounded, $x, $y, $color);
359
+ }
360
+ }
361
+ }
362
+ imagedestroy($image);
363
+ return $rounded;
364
+ }
365
+
366
+ function drawUltraGradientText($image, $text, $fontPath, $fontSize, $angle, $x, $y, $width, $height) {
367
+ $baseHue = mt_rand(0, 360);
368
+ $color1 = hslToRgb($baseHue / 360, 0.9, 0.6);
369
+ $color2 = hslToRgb(($baseHue + mt_rand(30, 120)) / 360, 0.9, 0.6);
370
+ $bbox = imagettfbbox($fontSize, $angle, $fontPath, $text);
371
+ if ($bbox === false) return;
372
+ $textWidth = $bbox[2] - $bbox[0];
373
+ $textHeight = $bbox[1] - $bbox[7];
374
+ $textImage = imagecreatetruecolor($textWidth, $textHeight);
375
+ imagesavealpha($textImage, true);
376
+ $transparent = imagecolorallocatealpha($textImage, 0, 0, 0, 127);
377
+ imagefill($textImage, 0, 0, $transparent);
378
+ $gradientType = mt_rand(0, 2);
379
+ if ($gradientType === 0) {
380
+ for ($i = 0; $i < $textWidth; $i++) {
381
+ $ratio = $i / $textWidth;
382
+ $r = $color1[0] + ($color2[0] - $color1[0]) * $ratio;
383
+ $g = $color1[1] + ($color2[1] - $color1[1]) * $ratio;
384
+ $b = $color1[2] + ($color2[2] - $color1[2]) * $ratio;
385
+ $color = imagecolorallocate($textImage, $r, $g, $b);
386
+ imageline($textImage, $i, 0, $i, $textHeight, $color);
387
+ }
388
+ } else {
389
+ for ($i = 0; $i < $textHeight; $i++) {
390
+ $ratio = $i / $textHeight;
391
+ $r = $color1[0] + ($color2[0] - $color1[0]) * $ratio;
392
+ $g = $color1[1] + ($color2[1] - $color1[1]) * $ratio;
393
+ $b = $color1[2] + ($color2[2] - $color1[2]) * $ratio;
394
+ $color = imagecolorallocate($textImage, $r, $g, $b);
395
+ imageline($textImage, 0, $i, $textWidth, $i, $color);
396
+ }
397
+ }
398
+ $maskColor = imagecolorallocate($textImage, 255, 255, 255);
399
+ imagettftext($textImage, $fontSize, $angle, 0, $bbox[1], $maskColor, $fontPath, $text);
400
+ imagecopymerge($image, $textImage, $x, $y - $bbox[1], 0, 0, $textWidth, $textHeight, 100);
401
+ imagedestroy($textImage);
402
+ }
403
+
404
+ function createUltraGradient($image, $colors, $direction, $width, $height) {
405
+ $colorCount = count($colors);
406
+ switch ($direction) {
407
+ case 'horizontal':
408
+ for ($i = 0; $i < $width; $i++) {
409
+ $ratio = $i / ($width - 1);
410
+ $colorIndex = $ratio * ($colorCount - 1);
411
+ $index1 = floor($colorIndex);
412
+ $index2 = min($index1 + 1, $colorCount - 1);
413
+ $fraction = $colorIndex - $index1;
414
+ $r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
415
+ $g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
416
+ $b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
417
+ $color = imagecolorallocate($image, $r, $g, $b);
418
+ imageline($image, $i, 0, $i, $height, $color);
419
+ }
420
+ break;
421
+ case 'vertical':
422
+ for ($i = 0; $i < $height; $i++) {
423
+ $ratio = $i / ($height - 1);
424
+ $colorIndex = $ratio * ($colorCount - 1);
425
+ $index1 = floor($colorIndex);
426
+ $index2 = min($index1 + 1, $colorCount - 1);
427
+ $fraction = $colorIndex - $index1;
428
+ $r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
429
+ $g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
430
+ $b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
431
+ $color = imagecolorallocate($image, $r, $g, $b);
432
+ imageline($image, 0, $i, $width, $i, $color);
433
+ }
434
+ break;
435
+ case 'diagonal':
436
+ for ($i = 0; $i < $width; $i++) {
437
+ for ($j = 0; $j < $height; $j++) {
438
+ $ratio = ($i + $j) / ($width + $height - 2);
439
+ $colorIndex = $ratio * ($colorCount - 1);
440
+ $index1 = floor($colorIndex);
441
+ $index2 = min($index1 + 1, $colorCount - 1);
442
+ $fraction = $colorIndex - $index1;
443
+ $r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
444
+ $g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
445
+ $b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
446
+ $color = imagecolorallocate($image, $r, $g, $b);
447
+ imagesetpixel($image, $i, $j, $color);
448
+ }
449
+ }
450
+ break;
451
+ case 'radial':
452
+ $centerX = $width / 2;
453
+ $centerY = $height / 2;
454
+ $maxRadius = sqrt($centerX * $centerX + $centerY * $centerY);
455
+ for ($i = 0; $i < $width; $i++) {
456
+ for ($j = 0; $j < $height; $j++) {
457
+ $dx = $i - $centerX;
458
+ $dy = $j - $centerY;
459
+ $distance = sqrt($dx * $dx + $dy * $dy);
460
+ $ratio = min(1, $distance / $maxRadius);
461
+ $colorIndex = $ratio * ($colorCount - 1);
462
+ $index1 = floor($colorIndex);
463
+ $index2 = min($index1 + 1, $colorCount - 1);
464
+ $fraction = $colorIndex - $index1;
465
+ $r = $colors[$index1][0] + ($colors[$index2][0] - $colors[$index1][0]) * $fraction;
466
+ $g = $colors[$index1][1] + ($colors[$index2][1] - $colors[$index1][1]) * $fraction;
467
+ $b = $colors[$index1][2] + ($colors[$index2][2] - $colors[$index1][2]) * $fraction;
468
+ $color = imagecolorallocate($image, $r, $g, $b);
469
+ imagesetpixel($image, $i, $j, $color);
470
+ }
471
+ }
472
+ break;
473
+ }
474
+ }
475
+
476
+ function createGeometricPattern($image, $width, $height) {
477
+ $patternType = mt_rand(0, 2);
478
+ $patternColor = imagecolorallocatealpha($image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255), mt_rand(10, 30));
479
+ switch ($patternType) {
480
+ case 0:
481
+ for ($i = 0; $i < $width; $i += 20) {
482
+ imageline($image, $i, 0, $i, $height, $patternColor);
483
+ }
484
+ for ($i = 0; $i < $height; $i += 20) {
485
+ imageline($image, 0, $i, $width, $i, $patternColor);
486
+ }
487
+ break;
488
+ case 1:
489
+ for ($i = -$width; $i < $width * 2; $i += 30) {
490
+ imageline($image, $i, 0, $i + $height, $height, $patternColor);
491
+ }
492
+ break;
493
+ case 2:
494
+ $circleSpacing = min($width, $height) / 10;
495
+ for ($i = $circleSpacing; $i < $width; $i += $circleSpacing) {
496
+ for ($j = $circleSpacing; $j < $height; $j += $circleSpacing) {
497
+ imagefilledellipse($image, $i, $j, 8, 8, $patternColor);
498
+ }
499
+ }
500
+ break;
501
+ }
502
+ }
503
+
504
+ function addVignetteEffect($image, $width, $height) {
505
+ $centerX = $width / 2;
506
+ $centerY = $height / 2;
507
+ $maxDistance = sqrt($centerX * $centerX + $centerY * $centerY);
508
+ for ($i = 0; $i < $width; $i++) {
509
+ for ($j = 0; $j < $height; $j++) {
510
+ $dx = $i - $centerX;
511
+ $dy = $j - $centerY;
512
+ $distance = sqrt($dx * $dx + $dy * $dy);
513
+ $ratio = $distance / $maxDistance;
514
+ $vignette = imagecolorallocatealpha($image, 0, 0, 0, $ratio * 60);
515
+ imagesetpixel($image, $i, $j, $vignette);
516
+ }
517
+ }
518
+ }
519
+
520
+ function hslToRgb($h, $s, $l) {
521
+ $r = $l;
522
+ $g = $l;
523
+ $b = $l;
524
+ $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s);
525
+ if ($v > 0) {
526
+ $m = $l + $l - $v;
527
+ $sv = ($v - $m) / $v;
528
+ $h *= 6.0;
529
+ $sextant = floor($h);
530
+ $fract = $h - $sextant;
531
+ $vsf = $v * $sv * $fract;
532
+ $mid1 = $m + $vsf;
533
+ $mid2 = $v - $vsf;
534
+ switch ($sextant) {
535
+ case 0:
536
+ $r = $v; $g = $mid1; $b = $m;
537
+ break;
538
+ case 1:
539
+ $r = $mid2; $g = $v; $b = $m;
540
+ break;
541
+ case 2:
542
+ $r = $m; $g = $v; $b = $mid1;
543
+ break;
544
+ case 3:
545
+ $r = $m; $g = $mid2; $b = $v;
546
+ break;
547
+ case 4:
548
+ $r = $mid1; $g = $m; $b = $v;
549
+ break;
550
+ case 5:
551
+ $r = $v; $g = $m; $b = $mid2;
552
+ break;
553
+ }
554
+ }
555
+ return [round($r * 255), round($g * 255), round($b * 255)];
556
+ }
557
+
558
+ function createErrorImage($message) {
559
+ $width = 500;
560
+ $height = 500;
561
+ $image = imagecreatetruecolor($width, $height);
562
+ $bgColor = imagecolorallocate($image, 255, 200, 200);
563
+ $textColor = imagecolorallocate($image, 255, 0, 0);
564
+ imagefill($image, 0, 0, $bgColor);
565
+ $font = 5;
566
+ $textWidth = imagefontwidth($font) * strlen($message);
567
+ $textHeight = imagefontheight($font);
568
+ $x = ($width - $textWidth) / 2;
569
+ $y = ($height - $textHeight) / 2;
570
+ imagestring($image, $font, $x, $y, $message, $textColor);
571
+ header('Content-Type: image/png');
572
+ imagepng($image);
573
+ imagedestroy($image);
574
+ }
575
+
576
+ if (!function_exists('mb_str_split')) {
577
+ function mb_str_split($string, $length = 1) {
578
+ $result = [];
579
+ for ($i = 0; $i < mb_strlen($string); $i += $length) {
580
+ $result[] = mb_substr($string, $i, $length);
581
+ }
582
+ return $result;
583
+ }
584
+ }
585
+
586
+ function estimateAverageColor($image) {
587
+ $w = imagesx($image);
588
+ $h = imagesy($image);
589
+ $stepX = max(1, (int)($w / 10));
590
+ $stepY = max(1, (int)($h / 10));
591
+ $r = $g = $b = 0;
592
+ $count = 0;
593
+ for ($x = 0; $x < $w; $x += $stepX) {
594
+ for ($y = 0; $y < $h; $y += $stepY) {
595
+ $c = imagecolorat($image, $x, $y);
596
+ $r += ($c >> 16) & 0xFF;
597
+ $g += ($c >> 8) & 0xFF;
598
+ $b += $c & 0xFF;
599
+ $count++;
600
+ }
601
+ }
602
+ return [ (int)($r / $count), (int)($g / $count), (int)($b / $count) ];
603
+ }
604
+
605
+ function processPersianText($text) {
606
+ $normalized = normalizer_is_normalized($text, Normalizer::FORM_C) ? $text : normalizer_normalize($text, Normalizer::FORM_C);
607
+ if (function_exists('fribidi_log2vis')) {
608
+ $res = @fribidi_log2vis($normalized);
609
+ if ($res !== false && is_string($res)) {
610
+ return $res;
611
+ }
612
+ }
613
+ if (class_exists('IntlChar')) {
614
+ $rtlMarkers = "\xE2\x80\x8F";
615
+ return $rtlMarkers . $normalized;
616
+ }
617
+ return $normalized;
618
+ }
619
+
620
+ set_time_limit(300);
621
+ generateTextImage();
622
+ ?>
tokens.json ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {"word": "ا", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
3
+ {"word": "آ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
4
+ {"word": "ب", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
5
+ {"word": "پ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
6
+ {"word": "ت", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
7
+ {"word": "ث", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
8
+ {"word": "ج", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
9
+ {"word": "چ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
10
+ {"word": "ح", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
11
+ {"word": "خ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
12
+ {"word": "د", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
13
+ {"word": "ذ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
14
+ {"word": "ر", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
15
+ {"word": "ز", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
16
+ {"word": "ژ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
17
+ {"word": "س", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
18
+ {"word": "ش", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
19
+ {"word": "ص", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
20
+ {"word": "ض", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
21
+ {"word": "ط", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
22
+ {"word": "ظ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
23
+ {"word": "ع", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
24
+ {"word": "غ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
25
+ {"word": "ف", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
26
+ {"word": "ق", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
27
+ {"word": "ک", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
28
+ {"word": "گ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
29
+ {"word": "ل", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
30
+ {"word": "م", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
31
+ {"word": "ن", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
32
+ {"word": "و", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
33
+ {"word": "ه", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
34
+ {"word": "ی", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
35
+ {"word": "ئ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
36
+ {"word": "ؤ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
37
+ {"word": "أ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
38
+ {"word": "إ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
39
+ {"word": "ة", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
40
+ {"word": "ۀ", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
41
+ {"word": "ء", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
42
+ {"word": "۰", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
43
+ {"word": "۱", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
44
+ {"word": "۲", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
45
+ {"word": "۳", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
46
+ {"word": "۴", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
47
+ {"word": "۵", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
48
+ {"word": "۶", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
49
+ {"word": "۷", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
50
+ {"word": "۸", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
51
+ {"word": "۹", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
52
+ {"word": "a", "font": "en", "its": "true", "language": "English"},
53
+ {"word": "b", "font": "en", "its": "true", "language": "English"},
54
+ {"word": "c", "font": "en", "its": "true", "language": "English"},
55
+ {"word": "d", "font": "en", "its": "true", "language": "English"},
56
+ {"word": "e", "font": "en", "its": "true", "language": "English"},
57
+ {"word": "f", "font": "en", "its": "true", "language": "English"},
58
+ {"word": "g", "font": "en", "its": "true", "language": "English"},
59
+ {"word": "h", "font": "en", "its": "true", "language": "English"},
60
+ {"word": "i", "font": "en", "its": "true", "language": "English"},
61
+ {"word": "j", "font": "en", "its": "true", "language": "English"},
62
+ {"word": "k", "font": "en", "its": "true", "language": "English"},
63
+ {"word": "l", "font": "en", "its": "true", "language": "English"},
64
+ {"word": "m", "font": "en", "its": "true", "language": "English"},
65
+ {"word": "n", "font": "en", "its": "true", "language": "English"},
66
+ {"word": "o", "font": "en", "its": "true", "language": "English"},
67
+ {"word": "p", "font": "en", "its": "true", "language": "English"},
68
+ {"word": "q", "font": "en", "its": "true", "language": "English"},
69
+ {"word": "r", "font": "en", "its": "true", "language": "English"},
70
+ {"word": "s", "font": "en", "its": "true", "language": "English"},
71
+ {"word": "t", "font": "en", "its": "true", "language": "English"},
72
+ {"word": "u", "font": "en", "its": "true", "language": "English"},
73
+ {"word": "v", "font": "en", "its": "true", "language": "English"},
74
+ {"word": "w", "font": "en", "its": "true", "language": "English"},
75
+ {"word": "x", "font": "en", "its": "true", "language": "English"},
76
+ {"word": "y", "font": "en", "its": "true", "language": "English"},
77
+ {"word": "z", "font": "en", "its": "true", "language": "English"},
78
+ {"word": "A", "font": "en", "its": "true", "language": "English"},
79
+ {"word": "B", "font": "en", "its": "true", "language": "English"},
80
+ {"word": "C", "font": "en", "its": "true", "language": "English"},
81
+ {"word": "D", "font": "en", "its": "true", "language": "English"},
82
+ {"word": "E", "font": "en", "its": "true", "language": "English"},
83
+ {"word": "F", "font": "en", "its": "true", "language": "English"},
84
+ {"word": "G", "font": "en", "its": "true", "language": "English"},
85
+ {"word": "H", "font": "en", "its": "true", "language": "English"},
86
+ {"word": "I", "font": "en", "its": "true", "language": "English"},
87
+ {"word": "J", "font": "en", "its": "true", "language": "English"},
88
+ {"word": "K", "font": "en", "its": "true", "language": "English"},
89
+ {"word": "L", "font": "en", "its": "true", "language": "English"},
90
+ {"word": "M", "font": "en", "its": "true", "language": "English"},
91
+ {"word": "N", "font": "en", "its": "true", "language": "English"},
92
+ {"word": "O", "font": "en", "its": "true", "language": "English"},
93
+ {"word": "P", "font": "en", "its": "true", "language": "English"},
94
+ {"word": "Q", "font": "en", "its": "true", "language": "English"},
95
+ {"word": "R", "font": "en", "its": "true", "language": "English"},
96
+ {"word": "S", "font": "en", "its": "true", "language": "English"},
97
+ {"word": "T", "font": "en", "its": "true", "language": "English"},
98
+ {"word": "U", "font": "en", "its": "true", "language": "English"},
99
+ {"word": "V", "font": "en", "its": "true", "language": "English"},
100
+ {"word": "W", "font": "en", "its": "true", "language": "English"},
101
+ {"word": "X", "font": "en", "its": "true", "language": "English"},
102
+ {"word": "Y", "font": "en", "its": "true", "language": "English"},
103
+ {"word": "Z", "font": "en", "its": "true", "language": "English"},
104
+ {"word": "0", "font": "en", "its": "true", "language": "English"},
105
+ {"word": "1", "font": "en", "its": "true", "language": "English"},
106
+ {"word": "2", "font": "en", "its": "true", "language": "English"},
107
+ {"word": "3", "font": "en", "its": "true", "language": "English"},
108
+ {"word": "4", "font": "en", "its": "true", "language": "English"},
109
+ {"word": "5", "font": "en", "its": "true", "language": "English"},
110
+ {"word": "6", "font": "en", "its": "true", "language": "English"},
111
+ {"word": "7", "font": "en", "its": "true", "language": "English"},
112
+ {"word": "8", "font": "en", "its": "true", "language": "English"},
113
+ {"word": "9", "font": "en", "its": "true", "language": "English"},
114
+ {"word": "!", "font": "en", "its": "true", "language": "English"},
115
+ {"word": "@", "font": "en", "its": "true", "language": "English"},
116
+ {"word": "#", "font": "en", "its": "true", "language": "English"},
117
+ {"word": "$", "font": "en", "its": "true", "language": "English"},
118
+ {"word": "%", "font": "en", "its": "true", "language": "English"},
119
+ {"word": "^", "font": "en", "its": "true", "language": "English"},
120
+ {"word": "&", "font": "en", "its": "true", "language": "English"},
121
+ {"word": "*", "font": "en", "its": "true", "language": "English"},
122
+ {"word": "(", "font": "en", "its": "true", "language": "English"},
123
+ {"word": ")", "font": "en", "its": "true", "language": "English"},
124
+ {"word": "-", "font": "en", "its": "true", "language": "English"},
125
+ {"word": "_", "font": "en", "its": "true", "language": "English"},
126
+ {"word": "=", "font": "en", "its": "true", "language": "English"},
127
+ {"word": "+", "font": "en", "its": "true", "language": "English"},
128
+ {"word": "[", "font": "en", "its": "true", "language": "English"},
129
+ {"word": "]", "font": "en", "its": "true", "language": "English"},
130
+ {"word": "{", "font": "en", "its": "true", "language": "English"},
131
+ {"word": "}", "font": "en", "its": "true", "language": "English"},
132
+ {"word": "|", "font": "en", "its": "true", "language": "English"},
133
+ {"word": "\\", "font": "en", "its": "true", "language": "English"},
134
+ {"word": ";", "font": "en", "its": "true", "language": "English"},
135
+ {"word": ":", "font": "en", "its": "true", "language": "English"},
136
+ {"word": "'", "font": "en", "its": "true", "language": "English"},
137
+ {"word": "\"", "font": "en", "its": "true", "language": "English"},
138
+ {"word": ",", "font": "en", "its": "true", "language": "English"},
139
+ {"word": ".", "font": "en", "its": "true", "language": "English"},
140
+ {"word": "<", "font": "en", "its": "true", "language": "English"},
141
+ {"word": ">", "font": "en", "its": "true", "language": "English"},
142
+ {"word": "/", "font": "en", "its": "true", "language": "English"},
143
+ {"word": "?", "font": "en", "its": "true", "language": "English"},
144
+ {"word": " ", "font": "en", "its": "true", "language": "English"},
145
+ {"word": "‌", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
146
+ {"word": "،", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
147
+ {"word": "؛", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
148
+ {"word": "؟", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
149
+ {"word": "!", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
150
+ {"word": "(", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
151
+ {"word": ")", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
152
+ {"word": "[", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
153
+ {"word": "]", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
154
+ {"word": "{", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
155
+ {"word": "}", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
156
+ {"word": "-", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
157
+ {"word": "_", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
158
+ {"word": "=", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
159
+ {"word": "+", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
160
+ {"word": "*", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
161
+ {"word": "/", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
162
+ {"word": "\\", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
163
+ {"word": "|", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
164
+ {"word": ".", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
165
+ {"word": ",", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
166
+ {"word": ":", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
167
+ {"word": ";", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
168
+ {"word": "'", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
169
+ {"word": "\"", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
170
+ {"word": "`", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
171
+ {"word": "~", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
172
+ {"word": "<", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
173
+ {"word": ">", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
174
+ {"word": "«", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
175
+ {"word": "»", "font": "fa", "its": "true", "language": "persian/farsi/iran"},
176
+ {"word": " ", "font": "fa", "its": "true", "language": "persian/farsi/iran"}
177
+ ]