EGYADMIN commited on
Commit
39d5fd7
·
verified ·
1 Parent(s): 61878d5

Upload 2 files

Browse files
modules/utils/arabic_charts_optimized.py ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ وحدة تحسين عرض النصوص العربية في الرسوم البيانية
4
+
5
+ هذا الملف يحتوي على دوال مساعدة لتحسين عرض النصوص العربية في الرسوم البيانية
6
+ باستخدام مكتبات arabic-reshaper و python-bidi مع خطوط عربية احترافية.
7
+ """
8
+
9
+ import arabic_reshaper
10
+ from bidi.algorithm import get_display
11
+ import matplotlib.pyplot as plt
12
+ import matplotlib.font_manager as fm
13
+ import plotly.graph_objects as go
14
+ import plotly.express as px
15
+ import numpy as np
16
+ import os
17
+ import sys
18
+ from arabic_font_config import ArabicFontManager, get_display_arabic, setup_arabic_fonts
19
+
20
+ # الحصول على أفضل خط عربي متاح
21
+ font_manager = ArabicFontManager()
22
+ BEST_ARABIC_FONT = font_manager.get_best_font()
23
+
24
+ def create_risk_matrix_plotly(risk_levels=None, width=450, height=450, font_family=BEST_ARABIC_FONT):
25
+ """
26
+ إنشاء مصفوفة المخاطر باستخدام Plotly مع دعم اللغة العربية
27
+
28
+ المعلمات:
29
+ risk_levels: مصفوفة مستويات المخاطر (اختياري)
30
+ width: عرض الرسم البياني
31
+ height: ارتفاع الرسم البياني
32
+ font_family: عائلة الخط المستخدمة
33
+
34
+ العوائد:
35
+ كائن الرسم البياني Plotly Figure
36
+ """
37
+ # بيانات مصفوفة المخاطر الافتراضية إذا لم يتم توفيرها
38
+ if risk_levels is None:
39
+ risk_levels = np.array([
40
+ [1, 2, 3],
41
+ [2, 4, 6],
42
+ [3, 6, 9]
43
+ ])
44
+
45
+ # إنشاء مصفوفة المخاطر باستخدام Plotly
46
+ fig = go.Figure()
47
+
48
+ # تحديد الألوان
49
+ colorscale = [
50
+ [0, '#1a9850'], # أخضر داكن (مخاطر منخفضة)
51
+ [0.3, '#91cf60'], # أخضر فاتح
52
+ [0.5, '#ffffbf'], # أصفر
53
+ [0.7, '#fc8d59'], # برتقالي
54
+ [1, '#d73027'] # أحمر (مخاطر عالية)
55
+ ]
56
+
57
+ # إنشاء مصفوفة المخاطر
58
+ fig.add_trace(go.Heatmap(
59
+ z=risk_levels,
60
+ x=[get_display_arabic('منخفض'), get_display_arabic('متوسط'), get_display_arabic('عالي')],
61
+ y=[get_display_arabic('منخفضة'), get_display_arabic('متوسطة'), get_display_arabic('عالية')],
62
+ text=risk_levels,
63
+ texttemplate="%{text}",
64
+ textfont={"size":20},
65
+ colorscale=colorscale,
66
+ showscale=True,
67
+ colorbar=dict(
68
+ title=get_display_arabic("درجة الخطورة"),
69
+ tickfont=dict(size=12),
70
+ )
71
+ ))
72
+
73
+ # تخصيص الرسم البياني
74
+ fig.update_layout(
75
+ title=get_display_arabic("مصفوفة المخاطر"),
76
+ height=height,
77
+ width=width,
78
+ margin=dict(l=50, r=50, t=50, b=50),
79
+ xaxis=dict(
80
+ title=get_display_arabic("التأثير"),
81
+ tickfont=dict(size=12),
82
+ ),
83
+ yaxis=dict(
84
+ title=get_display_arabic("الاحتمالية"),
85
+ tickfont=dict(size=12),
86
+ ),
87
+ font=dict(
88
+ family=font_family,
89
+ size=14
90
+ )
91
+ )
92
+
93
+ return fig
94
+
95
+ def create_pie_chart_plotly(labels, values, title="توزيع البيانات", width=400, height=380, font_family=BEST_ARABIC_FONT):
96
+ """
97
+ إنشاء مخطط دائري باستخدام Plotly مع دعم اللغة العربية
98
+
99
+ المعلمات:
100
+ labels: تسميات البيانات
101
+ values: قيم البيانات
102
+ title: عنوان الرسم البياني
103
+ width: عرض الرسم البياني
104
+ height: ارتفاع الرسم البياني
105
+ font_family: عائلة الخط المستخدمة
106
+
107
+ العوائد:
108
+ كائن الرسم البياني Plotly Figure
109
+ """
110
+ # تحويل التسميات إلى العرض الصحيح للعربية
111
+ arabic_labels = [get_display_arabic(label) for label in labels]
112
+
113
+ # إنشاء المخطط الدائري
114
+ fig = go.Figure()
115
+
116
+ # تحديد الألوان
117
+ colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b']
118
+
119
+ fig.add_trace(go.Pie(
120
+ labels=arabic_labels,
121
+ values=values,
122
+ textinfo='percent',
123
+ insidetextorientation='radial',
124
+ marker=dict(colors=colors[:len(labels)]),
125
+ hole=0.4,
126
+ textfont=dict(
127
+ family=font_family,
128
+ size=14
129
+ )
130
+ ))
131
+
132
+ # تخصيص الرسم البياني
133
+ fig.update_layout(
134
+ title=get_display_arabic(title),
135
+ height=height,
136
+ width=width,
137
+ margin=dict(l=0, r=0, t=40, b=0),
138
+ font=dict(
139
+ family=font_family,
140
+ size=14
141
+ ),
142
+ legend=dict(
143
+ orientation="h",
144
+ yanchor="bottom",
145
+ y=-0.2,
146
+ xanchor="center",
147
+ x=0.5,
148
+ font=dict(
149
+ family=font_family,
150
+ size=12
151
+ )
152
+ )
153
+ )
154
+
155
+ return fig
156
+
157
+ def create_bar_chart_plotly(x_data, y_data, x_title="الفئات", y_title="القيم", title="رسم بياني شريطي", width=450, height=400, font_family=BEST_ARABIC_FONT):
158
+ """
159
+ إنشاء رسم بياني شريطي باستخدام Plotly مع دعم اللغة العربية
160
+
161
+ المعلمات:
162
+ x_data: بيانات المحور الأفقي
163
+ y_data: بيانات المحور الرأسي
164
+ x_title: عنوان المحور الأفقي
165
+ y_title: عنوان المحور الرأسي
166
+ title: عنوان الرسم البياني
167
+ width: عرض الرسم البياني
168
+ height: ارتفاع الرسم البياني
169
+ font_family: عائلة الخط المستخدمة
170
+
171
+ العوائد:
172
+ كائن الرسم البياني Plotly Figure
173
+ """
174
+ # تحويل بيانات المحور الأفقي إلى العرض الصحيح للعربية إذا كانت نصية
175
+ if isinstance(x_data[0], str):
176
+ x_data = [get_display_arabic(x) for x in x_data]
177
+
178
+ # إنشاء الرسم البياني الشريطي
179
+ fig = go.Figure()
180
+
181
+ fig.add_trace(go.Bar(
182
+ x=x_data,
183
+ y=y_data,
184
+ marker_color='#1f77b4',
185
+ text=y_data,
186
+ textposition='auto',
187
+ textfont=dict(
188
+ family=font_family,
189
+ size=12
190
+ )
191
+ ))
192
+
193
+ # تخصيص الرسم البياني
194
+ fig.update_layout(
195
+ title=get_display_arabic(title),
196
+ height=height,
197
+ width=width,
198
+ margin=dict(l=50, r=50, t=50, b=50),
199
+ xaxis=dict(
200
+ title=get_display_arabic(x_title),
201
+ tickfont=dict(
202
+ family=font_family,
203
+ size=12
204
+ ),
205
+ ),
206
+ yaxis=dict(
207
+ title=get_display_arabic(y_title),
208
+ tickfont=dict(
209
+ family=font_family,
210
+ size=12
211
+ ),
212
+ ),
213
+ font=dict(
214
+ family=font_family,
215
+ size=14
216
+ )
217
+ )
218
+
219
+ return fig
220
+
221
+ def create_line_chart_plotly(x_data, y_data, x_title="الزمن", y_title="القيم", title="رسم بياني خطي", width=450, height=400, font_family=BEST_ARABIC_FONT):
222
+ """
223
+ إنشاء رسم بياني خطي باستخدام Plotly مع دعم اللغة العربية
224
+
225
+ المعلمات:
226
+ x_data: بيانات المحور الأفقي
227
+ y_data: بيانات المحور الرأسي
228
+ x_title: عنوان المحور الأفقي
229
+ y_title: عنوان المحور الرأسي
230
+ title: عنوان الرسم البياني
231
+ width: عرض الرسم البياني
232
+ height: ارتفاع الرسم البياني
233
+ font_family: عائلة الخط المستخدمة
234
+
235
+ العوائد:
236
+ كائن الرسم البياني Plotly Figure
237
+ """
238
+ # تحويل بيانات المحور الأفقي إلى العرض الصحيح للعربية إذا كانت نصية
239
+ if isinstance(x_data[0], str):
240
+ x_data = [get_display_arabic(x) for x in x_data]
241
+
242
+ # إنشاء الرسم البياني الخطي
243
+ fig = go.Figure()
244
+
245
+ fig.add_trace(go.Scatter(
246
+ x=x_data,
247
+ y=y_data,
248
+ mode='lines+markers',
249
+ marker=dict(size=8),
250
+ line=dict(width=2)
251
+ ))
252
+
253
+ # تخصيص الرسم البياني
254
+ fig.update_layout(
255
+ title=get_display_arabic(title),
256
+ height=height,
257
+ width=width,
258
+ margin=dict(l=50, r=50, t=50, b=50),
259
+ xaxis=dict(
260
+ title=get_display_arabic(x_title),
261
+ tickfont=dict(
262
+ family=font_family,
263
+ size=12
264
+ ),
265
+ ),
266
+ yaxis=dict(
267
+ title=get_display_arabic(y_title),
268
+ tickfont=dict(
269
+ family=font_family,
270
+ size=12
271
+ ),
272
+ ),
273
+ font=dict(
274
+ family=font_family,
275
+ size=14
276
+ )
277
+ )
278
+
279
+ return fig
280
+
281
+ def create_risk_matrix_matplotlib(risk_levels=None, figsize=(6, 5), font_family=BEST_ARABIC_FONT):
282
+ """
283
+ إنشاء مصفوفة المخاطر باستخدام Matplotlib مع دعم اللغة العربية
284
+
285
+ المعلمات:
286
+ risk_levels: مصفوفة مستويات المخاطر (اختياري)
287
+ figsize: حجم الشكل (العرض، الارتفاع) بالإنش
288
+ font_family: عائلة الخط المستخدمة
289
+
290
+ العوائد:
291
+ كائن الرسم البياني Matplotlib Figure
292
+ """
293
+ # إعداد الخطوط العربية
294
+ setup_arabic_fonts(font_family)
295
+
296
+ # بيانات مصفوفة المخاطر الافتراضية إذا لم يتم توفيرها
297
+ if risk_levels is None:
298
+ risk_levels = np.array([
299
+ [1, 2, 3],
300
+ [2, 4, 6],
301
+ [3, 6, 9]
302
+ ])
303
+
304
+ # إنشاء الشكل والمحاور
305
+ fig, ax = plt.subplots(figsize=figsize)
306
+
307
+ # تحديد الألوان
308
+ cmap = plt.cm.get_cmap('RdYlGn_r')
309
+
310
+ # إنشاء مصفوفة المخاطر
311
+ im = ax.imshow(risk_levels, cmap=cmap)
312
+
313
+ # إضافة النصوص إلى الخلايا
314
+ for i in range(len(risk_levels)):
315
+ for j in range(len(risk_levels[0])):
316
+ ax.text(j, i, risk_levels[i, j], ha='center', va='center', color='white', fontsize=14, fontfamily=font_family)
317
+
318
+ # تعيين العناوين والتسميات
319
+ ax.set_title(get_display_arabic("مصفوفة المخاطر"), fontsize=16, fontfamily=font_family)
320
+ ax.set_xlabel(get_display_arabic("التأثير"), fontsize=14, fontfamily=font_family)
321
+ ax.set_ylabel(get_display_arabic("الاحتمالية"), fontsize=14, fontfamily=font_family)
322
+
323
+ # تعيين تسميات المحاور
324
+ ax.set_xticks(np.arange(len(risk_levels[0])))
325
+ ax.set_yticks(np.arange(len(risk_levels)))
326
+ ax.set_xticklabels([get_display_arabic(label) for label in ['منخفض', 'متوسط', 'عالي']], fontfamily=font_family)
327
+ ax.set_yticklabels([get_display_arabic(label) for label in ['منخفضة', 'متوسطة', 'عالية']], fontfamily=font_family)
328
+
329
+ # إضافة شريط الألوان
330
+ cbar = fig.colorbar(im)
331
+ cbar.set_label(get_display_arabic("درجة الخطورة"), fontsize=14, fontfamily=font_family)
332
+
333
+ # تنسيق الشكل
334
+ plt.tight_layout()
335
+
336
+ return fig
337
+
338
+ # اختبار الدوال إذا تم تشغيل الملف مباشرة
339
+ if __name__ == "__main__":
340
+ # طباعة الخط العربي المستخدم
341
+ print(f"الخط العربي المستخدم: {BEST_ARABIC_FONT}")
342
+
343
+ # اختبار مصفوفة المخاطر باستخدام Plotly
344
+ risk_matrix = create_risk_matrix_plotly()
345
+ risk_matrix.write_image("risk_matrix_optimized.png")
346
+ print("تم إنشاء مصفوفة المخاطر باستخدام Plotly")
347
+
348
+ # اختبار المخطط الدائري باستخدام Plotly
349
+ labels = ["المنتجات المحلية", "الخدمات المحلية", "القوى العاملة المحلية", "غير محلي"]
350
+ values = [40, 20, 30, 10]
351
+ pie_chart = create_pie_chart_plotly(labels, values, "توزيع المحتوى المحلي")
352
+ pie_chart.write_image("pie_chart_optimized.png")
353
+ print("تم إنشاء المخطط الدائري باستخدام Plotly")
354
+
355
+ # اختبار الرسم البياني الشريطي باستخدام Plotly
356
+ x_data = ["الربع الأول", "الربع الثاني", "الربع الثالث", "الربع الرابع"]
357
+ y_data = [20, 35, 25, 40]
358
+ bar_chart = create_bar_chart_plotly(x_data, y_data, "الفترة", "المبيعات", "مبيعات السنة")
359
+ bar_chart.write_image("bar_chart_optimized.png")
360
+ print("تم إنشاء الرسم البياني الشريطي باستخدام Plotly")
361
+
362
+ # اختبار الرسم البياني الخطي باستخدام Plotly
363
+ x_data = ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو"]
364
+ y_data = [10, 15, 13, 17, 20, 25]
365
+ line_chart = create_line_chart_plotly(x_data, y_data, "الشهر", "الإيرادات", "إيرادات النصف الأول")
366
+ line_chart.write_image("line_chart_optimized.png")
367
+ print("تم إنشاء الرسم البياني الخطي باستخدام Plotly")
368
+
369
+ # اختبار مصفوفة المخاطر باستخدام Matplotlib
370
+ risk_matrix_mpl = create_risk_matrix_matplotlib()
371
+ plt.savefig("risk_matrix_matplotlib_optimized.png", dpi=150)
372
+ print("تم إنشاء مصفوفة المخاطر باستخدام Matplotlib")
373
+
374
+ print("تم إنشاء جميع الرسوم البيانية بنجاح!")
modules/utils/arabic_font_config.py ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ وحدة تكوين الخطوط العربية
4
+
5
+ هذا الملف يحتوي على أدوات لتكوين وإدارة الخطوط العربية للرسوم البيانية
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import matplotlib.font_manager as fm
11
+ import matplotlib.pyplot as plt
12
+ import arabic_reshaper
13
+ from bidi.algorithm import get_display
14
+ import json
15
+ import glob
16
+
17
+ class ArabicFontManager:
18
+ """مدير الخطوط العربية للرسوم البيانية"""
19
+
20
+ def __init__(self):
21
+ """تهيئة مدير الخطوط العربية"""
22
+ # قائمة بمسارات الخطوط العربية المعروفة
23
+ self.known_font_paths = {
24
+ 'Amiri': '/usr/share/fonts/truetype/hosny-amiri/',
25
+ 'Lateef': '/usr/share/fonts/truetype/sil/',
26
+ 'Scheherazade': '/usr/share/fonts/truetype/sil/',
27
+ 'KACST': '/usr/share/fonts/truetype/kacst/',
28
+ 'Noto Naskh Arabic': '/usr/share/fonts/truetype/noto/',
29
+ 'Harmattan': '/usr/share/fonts/truetype/sil/',
30
+ 'Alkalami': '/usr/share/fonts/truetype/sil/'
31
+ }
32
+
33
+ # قائمة بالخطوط العربية المتاحة
34
+ self.available_fonts = {}
35
+
36
+ # البحث عن الخطوط العربية المتاحة
37
+ self.scan_available_fonts()
38
+
39
+ def scan_available_fonts(self):
40
+ """البحث عن الخطوط العربية المتاحة في النظام"""
41
+ # مسح المسارات المعروفة
42
+ for font_family, font_path in self.known_font_paths.items():
43
+ if os.path.exists(font_path):
44
+ font_files = []
45
+ # البحث عن ملفات الخطوط في المسار
46
+ for font_file in os.listdir(font_path):
47
+ if font_file.endswith('.ttf') or font_file.endswith('.otf'):
48
+ full_path = os.path.join(font_path, font_file)
49
+ font_files.append(full_path)
50
+
51
+ if font_files:
52
+ self.available_fonts[font_family] = font_files
53
+
54
+ # البحث في المسارات الإضافية
55
+ additional_paths = [
56
+ '/usr/share/fonts/',
57
+ '/usr/local/share/fonts/',
58
+ os.path.expanduser('~/.fonts/')
59
+ ]
60
+
61
+ # استخدام قائمة الخطوط المتاحة في matplotlib
62
+ font_list = fm.findSystemFonts()
63
+ arabic_fonts = []
64
+
65
+ # البحث عن الخطوط العربية
66
+ for font_path in font_list:
67
+ try:
68
+ font_name = os.path.basename(font_path).split('.')[0]
69
+ if 'arab' in font_name.lower() or 'naskh' in font_name.lower() or 'kufi' in font_name.lower():
70
+ if font_name not in self.available_fonts:
71
+ self.available_fonts[font_name] = []
72
+ self.available_fonts[font_name].append(font_path)
73
+ except Exception as e:
74
+ print(f"خطأ في معالجة الخط {font_path}: {e}")
75
+
76
+ def configure_matplotlib(self, preferred_font=None):
77
+ """
78
+ تكوين matplotlib لاستخدام الخطوط العربية
79
+
80
+ المعلمات:
81
+ preferred_font: اسم الخط المفضل (اختياري)
82
+
83
+ العوائد:
84
+ قائمة بأسماء الخطوط العربية المتاحة
85
+ """
86
+ # تحديد الخط المفضل
87
+ if preferred_font and preferred_font in self.available_fonts:
88
+ primary_font = preferred_font
89
+ elif 'NotoNaskhArabic-Regular' in self.available_fonts:
90
+ primary_font = 'NotoNaskhArabic-Regular'
91
+ elif 'NotoSansArabic-Regular' in self.available_fonts:
92
+ primary_font = 'NotoSansArabic-Regular'
93
+ elif len(self.available_fonts) > 0:
94
+ primary_font = list(self.available_fonts.keys())[0]
95
+ else:
96
+ primary_font = 'sans-serif'
97
+
98
+ # تكوين الخط الافتراضي
99
+ font_list = [primary_font] + list(self.available_fonts.keys()) + ['sans-serif']
100
+ plt.rcParams['font.family'] = ', '.join(font_list)
101
+
102
+ return list(self.available_fonts.keys())
103
+
104
+ def get_font_list(self):
105
+ """
106
+ الحصول على قائمة بالخطوط العربية المتاحة
107
+
108
+ العوائد:
109
+ قائمة بأسماء الخطوط العربية المتاحة
110
+ """
111
+ return list(self.available_fonts.keys())
112
+
113
+ def get_best_font(self):
114
+ """
115
+ الحصول على أفضل خط عربي متاح
116
+
117
+ العوائد:
118
+ اسم أفضل خط عربي متاح
119
+ """
120
+ preferred_fonts = [
121
+ 'NotoNaskhArabic-Regular',
122
+ 'NotoSansArabic-Regular',
123
+ 'Amiri',
124
+ 'Scheherazade',
125
+ 'Lateef',
126
+ 'KACST'
127
+ ]
128
+
129
+ for font in preferred_fonts:
130
+ if font in self.available_fonts:
131
+ return font
132
+
133
+ if len(self.available_fonts) > 0:
134
+ return list(self.available_fonts.keys())[0]
135
+
136
+ return 'sans-serif'
137
+
138
+ def save_font_config(self, config_file='arabic_font_config.json'):
139
+ """
140
+ حفظ تكوين الخطوط العربية إلى ملف
141
+
142
+ المعلمات:
143
+ config_file: اسم ملف التكوين
144
+ """
145
+ config = {
146
+ 'available_fonts': {k: v for k, v in self.available_fonts.items()},
147
+ 'best_font': self.get_best_font()
148
+ }
149
+
150
+ with open(config_file, 'w', encoding='utf-8') as f:
151
+ json.dump(config, f, ensure_ascii=False, indent=4)
152
+
153
+ def load_font_config(self, config_file='arabic_font_config.json'):
154
+ """
155
+ تحميل تكوين الخطوط العربية من ملف
156
+
157
+ المعلمات:
158
+ config_file: اسم ملف التكوين
159
+
160
+ العوائد:
161
+ True إذا تم تحميل التكوين بنجاح، False خلاف ذلك
162
+ """
163
+ if not os.path.exists(config_file):
164
+ return False
165
+
166
+ try:
167
+ with open(config_file, 'r', encoding='utf-8') as f:
168
+ config = json.load(f)
169
+
170
+ if 'available_fonts' in config:
171
+ self.available_fonts = config['available_fonts']
172
+ return True
173
+ except Exception as e:
174
+ print(f"خطأ في تحميل ملف التكوين: {e}")
175
+
176
+ return False
177
+
178
+ def get_display_arabic(text):
179
+ """
180
+ تحويل النص العربي للعرض الصحيح في الرسوم البيانية
181
+
182
+ المعلمات:
183
+ text: النص العربي المراد تحويله
184
+
185
+ العوائد:
186
+ النص بعد المعالجة للعرض الصحيح
187
+ """
188
+ # التحقق من أن النص ليس فارغًا
189
+ if not text:
190
+ return text
191
+
192
+ # تشكيل النص العربي وتحويله للعرض الصحيح
193
+ try:
194
+ reshaped_text = arabic_reshaper.reshape(text)
195
+ bidi_text = get_display(reshaped_text)
196
+ return bidi_text
197
+ except Exception as e:
198
+ print(f"خطأ في معالجة النص العربي: {e}")
199
+ return text
200
+
201
+ def setup_arabic_fonts(preferred_font=None):
202
+ """
203
+ إعداد الخطوط العربية لاستخدامها في matplotlib
204
+
205
+ المعلمات:
206
+ preferred_font: اسم الخط المفضل (اختياري)
207
+
208
+ العوائد:
209
+ قائمة بأسماء الخطوط العربية المتاحة
210
+ """
211
+ font_manager = ArabicFontManager()
212
+ return font_manager.configure_matplotlib(preferred_font)
213
+
214
+ def test_arabic_fonts():
215
+ """
216
+ اختبار الخطوط العربية المتاحة
217
+
218
+ هذه الدالة تقوم بإنشاء رسم بياني لاختبار الخطوط العربية المتاحة
219
+ """
220
+ # إنشاء مدير الخطوط العربية
221
+ font_manager = ArabicFontManager()
222
+ available_fonts = font_manager.configure_matplotlib()
223
+
224
+ if not available_fonts:
225
+ print("لا توجد خطوط عربية متاحة!")
226
+ return
227
+
228
+ # نص الاختبار
229
+ test_text = "هذا نص عربي لاختبار الخطوط: أبجد هوز حطي كلمن"
230
+
231
+ # اختيار عدد محدود من الخطوط للاختبار
232
+ test_fonts = available_fonts[:5] if len(available_fonts) > 5 else available_fonts
233
+
234
+ # إنشاء رسم بياني لكل خط
235
+ fig, axes = plt.subplots(len(test_fonts), 1, figsize=(10, len(test_fonts) * 1.5))
236
+
237
+ if len(test_fonts) == 1:
238
+ axes = [axes]
239
+
240
+ for i, font in enumerate(test_fonts):
241
+ axes[i].text(0.5, 0.5, get_display_arabic(test_text),
242
+ fontfamily=font, fontsize=14, ha='center', va='center')
243
+ axes[i].set_title(f"Font: {font}", fontsize=10)
244
+ axes[i].axis('off')
245
+
246
+ plt.tight_layout()
247
+ plt.savefig("arabic_fonts_test.png", dpi=150)
248
+ print(f"تم إنشاء صورة اختبار الخطوط العربية: arabic_fonts_test.png")
249
+
250
+ # اختبار الوحدة إذا تم تشغيل الملف مباشرة
251
+ if __name__ == "__main__":
252
+ # إنشاء مدير الخطوط العربية
253
+ font_manager = ArabicFontManager()
254
+
255
+ # البحث عن الخطوط العربية المتاحة
256
+ available_fonts = font_manager.get_font_list()
257
+
258
+ print("الخطوط العربية المتاحة:")
259
+ for font in available_fonts:
260
+ print(f" - {font}")
261
+
262
+ # حفظ تكوين الخطوط العربية
263
+ font_manager.save_font_config()
264
+
265
+ # اختبار الخطوط العربية
266
+ try:
267
+ test_arabic_fonts()
268
+ except Exception as e:
269
+ print(f"خطأ في اختبار الخطوط العربية: {e}")
270
+
271
+ print("أفضل خط عربي متاح:", font_manager.get_best_font())