Wahbi-AI / modules /utils /arabic_font_config.py
EGYADMIN's picture
Upload 2 files
39d5fd7 verified
raw
history blame
10.1 kB
# -*- coding: utf-8 -*-
"""
وحدة تكوين الخطوط العربية
هذا الملف يحتوي على أدوات لتكوين وإدارة الخطوط العربية للرسوم البيانية
"""
import os
import sys
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import arabic_reshaper
from bidi.algorithm import get_display
import json
import glob
class ArabicFontManager:
"""مدير الخطوط العربية للرسوم البيانية"""
def __init__(self):
"""تهيئة مدير الخطوط العربية"""
# قائمة بمسارات الخطوط العربية المعروفة
self.known_font_paths = {
'Amiri': '/usr/share/fonts/truetype/hosny-amiri/',
'Lateef': '/usr/share/fonts/truetype/sil/',
'Scheherazade': '/usr/share/fonts/truetype/sil/',
'KACST': '/usr/share/fonts/truetype/kacst/',
'Noto Naskh Arabic': '/usr/share/fonts/truetype/noto/',
'Harmattan': '/usr/share/fonts/truetype/sil/',
'Alkalami': '/usr/share/fonts/truetype/sil/'
}
# قائمة بالخطوط العربية المتاحة
self.available_fonts = {}
# البحث عن الخطوط العربية المتاحة
self.scan_available_fonts()
def scan_available_fonts(self):
"""البحث عن الخطوط العربية المتاحة في النظام"""
# مسح المسارات المعروفة
for font_family, font_path in self.known_font_paths.items():
if os.path.exists(font_path):
font_files = []
# البحث عن ملفات الخطوط في المسار
for font_file in os.listdir(font_path):
if font_file.endswith('.ttf') or font_file.endswith('.otf'):
full_path = os.path.join(font_path, font_file)
font_files.append(full_path)
if font_files:
self.available_fonts[font_family] = font_files
# البحث في المسارات الإضافية
additional_paths = [
'/usr/share/fonts/',
'/usr/local/share/fonts/',
os.path.expanduser('~/.fonts/')
]
# استخدام قائمة الخطوط المتاحة في matplotlib
font_list = fm.findSystemFonts()
arabic_fonts = []
# البحث عن الخطوط العربية
for font_path in font_list:
try:
font_name = os.path.basename(font_path).split('.')[0]
if 'arab' in font_name.lower() or 'naskh' in font_name.lower() or 'kufi' in font_name.lower():
if font_name not in self.available_fonts:
self.available_fonts[font_name] = []
self.available_fonts[font_name].append(font_path)
except Exception as e:
print(f"خطأ في معالجة الخط {font_path}: {e}")
def configure_matplotlib(self, preferred_font=None):
"""
تكوين matplotlib لاستخدام الخطوط العربية
المعلمات:
preferred_font: اسم الخط المفضل (اختياري)
العوائد:
قائمة بأسماء الخطوط العربية المتاحة
"""
# تحديد الخط المفضل
if preferred_font and preferred_font in self.available_fonts:
primary_font = preferred_font
elif 'NotoNaskhArabic-Regular' in self.available_fonts:
primary_font = 'NotoNaskhArabic-Regular'
elif 'NotoSansArabic-Regular' in self.available_fonts:
primary_font = 'NotoSansArabic-Regular'
elif len(self.available_fonts) > 0:
primary_font = list(self.available_fonts.keys())[0]
else:
primary_font = 'sans-serif'
# تكوين الخط الافتراضي
font_list = [primary_font] + list(self.available_fonts.keys()) + ['sans-serif']
plt.rcParams['font.family'] = ', '.join(font_list)
return list(self.available_fonts.keys())
def get_font_list(self):
"""
الحصول على قائمة بالخطوط العربية المتاحة
العوائد:
قائمة بأسماء الخطوط العربية المتاحة
"""
return list(self.available_fonts.keys())
def get_best_font(self):
"""
الحصول على أفضل خط عربي متاح
العوائد:
اسم أفضل خط عربي متاح
"""
preferred_fonts = [
'NotoNaskhArabic-Regular',
'NotoSansArabic-Regular',
'Amiri',
'Scheherazade',
'Lateef',
'KACST'
]
for font in preferred_fonts:
if font in self.available_fonts:
return font
if len(self.available_fonts) > 0:
return list(self.available_fonts.keys())[0]
return 'sans-serif'
def save_font_config(self, config_file='arabic_font_config.json'):
"""
حفظ تكوين الخطوط العربية إلى ملف
المعلمات:
config_file: اسم ملف التكوين
"""
config = {
'available_fonts': {k: v for k, v in self.available_fonts.items()},
'best_font': self.get_best_font()
}
with open(config_file, 'w', encoding='utf-8') as f:
json.dump(config, f, ensure_ascii=False, indent=4)
def load_font_config(self, config_file='arabic_font_config.json'):
"""
تحميل تكوين الخطوط العربية من ملف
المعلمات:
config_file: اسم ملف التكوين
العوائد:
True إذا تم تحميل التكوين بنجاح، False خلاف ذلك
"""
if not os.path.exists(config_file):
return False
try:
with open(config_file, 'r', encoding='utf-8') as f:
config = json.load(f)
if 'available_fonts' in config:
self.available_fonts = config['available_fonts']
return True
except Exception as e:
print(f"خطأ في تحميل ملف التكوين: {e}")
return False
def get_display_arabic(text):
"""
تحويل النص العربي للعرض الصحيح في الرسوم البيانية
المعلمات:
text: النص العربي المراد تحويله
العوائد:
النص بعد المعالجة للعرض الصحيح
"""
# التحقق من أن النص ليس فارغًا
if not text:
return text
# تشكيل النص العربي وتحويله للعرض الصحيح
try:
reshaped_text = arabic_reshaper.reshape(text)
bidi_text = get_display(reshaped_text)
return bidi_text
except Exception as e:
print(f"خطأ في معالجة النص العربي: {e}")
return text
def setup_arabic_fonts(preferred_font=None):
"""
إعداد الخطوط العربية لاستخدامها في matplotlib
المعلمات:
preferred_font: اسم الخط المفضل (اختياري)
العوائد:
قائمة بأسماء الخطوط العربية المتاحة
"""
font_manager = ArabicFontManager()
return font_manager.configure_matplotlib(preferred_font)
def test_arabic_fonts():
"""
اختبار الخطوط العربية المتاحة
هذه الدالة تقوم بإنشاء رسم بياني لاختبار الخطوط العربية المتاحة
"""
# إنشاء مدير الخطوط العربية
font_manager = ArabicFontManager()
available_fonts = font_manager.configure_matplotlib()
if not available_fonts:
print("لا توجد خطوط عربية متاحة!")
return
# نص الاختبار
test_text = "هذا نص عربي لاختبار الخطوط: أبجد هوز حطي كلمن"
# اختيار عدد محدود من الخطوط للاختبار
test_fonts = available_fonts[:5] if len(available_fonts) > 5 else available_fonts
# إنشاء رسم بياني لكل خط
fig, axes = plt.subplots(len(test_fonts), 1, figsize=(10, len(test_fonts) * 1.5))
if len(test_fonts) == 1:
axes = [axes]
for i, font in enumerate(test_fonts):
axes[i].text(0.5, 0.5, get_display_arabic(test_text),
fontfamily=font, fontsize=14, ha='center', va='center')
axes[i].set_title(f"Font: {font}", fontsize=10)
axes[i].axis('off')
plt.tight_layout()
plt.savefig("arabic_fonts_test.png", dpi=150)
print(f"تم إنشاء صورة اختبار الخطوط العربية: arabic_fonts_test.png")
# اختبار الوحدة إذا تم تشغيل الملف مباشرة
if __name__ == "__main__":
# إنشاء مدير الخطوط العربية
font_manager = ArabicFontManager()
# البحث عن الخطوط العربية المتاحة
available_fonts = font_manager.get_font_list()
print("الخطوط العربية المتاحة:")
for font in available_fonts:
print(f" - {font}")
# حفظ تكوين الخطوط العربية
font_manager.save_font_config()
# اختبار الخطوط العربية
try:
test_arabic_fonts()
except Exception as e:
print(f"خطأ في اختبار الخطوط العربية: {e}")
print("أفضل خط عربي متاح:", font_manager.get_best_font())