توفّر واجهة برمجة التطبيقات Local Font Access API آلية للوصول إلى بيانات الخطوط المثبّتة محليًا على المستخدم، بما في ذلك تفاصيل ذات مستوى أعلى، مثل الأسماء والأنماط والمجموعات، بالإضافة إلى وحدات البايت الأولية لملفات الخطوط الأساسية. تعرَّف على طريقة استخدام تطبيق تعديل الرسومات الموجّهة التي يمكن تغيير حجمها (SVG) Boxy SVG لواجهة برمجة التطبيقات هذه.
مقدمة
(تتوفر هذه المقالة أيضًا في شكل فيديو).
Boxy SVG هو محرِّر رسومات متجهية. وتتمثّل حالة الاستخدام الأساسية للتطبيق في تعديل الرسومات بتنسيق ملف SVG لإنشاء رسومات توضيحية وشعارات ورموز وغيرها من عناصر التصميم الغرافيكي. وقد تم تطويره بواسطة المطوّر البولندي ياروسلاو فوكسا وتم إصداره في البداية في 15 آذار (مارس) 2013. يدير جاروسلاو مدونة Boxy SVG حيث يعلن عن الميزات الجديدة التي يضيفها إلى التطبيق. ويؤيد المطوّر بشكل كبير مشروع Fugu من Chromium، كما أنه يستخدم علامة Fugu في أداة تتبُّع أفكار التطبيق.
واجهة برمجة تطبيقات Font Access المحلية بتنسيق SVG Boxy
كانت Local Font Access API إحدى الميزات التي نشر عنها "ياروسلاو" في مدونة. تتيح واجهة برمجة التطبيقات Local Font Access API للمستخدمين الوصول إلى الخطوط المثبّتة محليًا، بما في ذلك التفاصيل ذات المستوى الأعلى، مثل الأسماء والأنماط والمجموعات، بالإضافة إلى وحدات البايت الأولية لملفات الخطوط الأساسية. في لقطة الشاشة التالية، يمكنك الاطّلاع على كيفية منح التطبيق إذن الوصول إلى الخطوط المثبّتة محليًا على جهاز MacBook واختيار خط Marker Felt للنص الخاص بي.
التعليمة البرمجية الأساسية واضحة جدًا. عندما يفتح المستخدم أداة اختيار مجموعة الخطوط لأول مرة، يتحقّق التطبيق أولاً مما إذا كان متصفّح الويب يتوافق مع Local Font Access API.
وهي تتحقّق أيضًا من الإصدار التجريبي القديم من واجهة برمجة التطبيقات وتستخدمه إن وُجدت. اعتبارًا من عام 2023، يمكنك تجاهل واجهة برمجة التطبيقات القديمة بأمان لأنّها كانت متاحة فقط لفترة قصيرة من خلال ميزات Chrome التجريبية، ولكن قد تظل بعض مشتقات Chromium تستخدمها.
let isLocalFontsApiEnabled = (
// Local Font Access API, Chrome >= 102
window.queryLocalFonts !== undefined ||
// Experimental Local Font Access API, Chrome < 102
navigator.fonts?.query !== undefined
);
إذا لم تكن واجهة برمجة تطبيقات Local Font Access API متاحة، سيتحول منتقي مجموعة الخطوط إلى اللون الرمادي. سيتم عرض نص عنصر نائب للمستخدم بدلاً من قائمة الخطوط:
if (isLocalFontsApiEnabled === false) {
showPlaceholder("no-local-fonts-api");
return;
}
وبخلاف ذلك، يتم استخدام واجهة برمجة تطبيقات Local Font Access API لاسترداد قائمة جميع الخطوط من نظام التشغيل. لاحِظ مجموعة try…catch
المطلوبة لمعالجة أخطاء الأذونات بشكل صحيح.
let localFonts;
if (isLocalFontsApiEnabled === true) {
try {
// Local Font Access API, Chrome >= 102
if (window.queryLocalFonts) {
localFonts = await window.queryLocalFonts();
}
// Experimental Local Font Access API, Chrome < 102
else if (navigator.fonts?.query) {
localFonts = await navigator.fonts.query({
persistentAccess: true,
});
}
} catch (error) {
showError(error.message, error.name);
}
}
بعد استرداد قائمة الخطوط المحلية، يتم إنشاء fontsIndex
منها بطريقة مبسّطة وتمت تسويتها:
let fontsIndex = [];
for (let localFont of localFonts) {
let face = "400";
// Determine the face name
{
let subfamily = localFont.style.toLowerCase();
subfamily = subfamily.replaceAll(" ", "");
subfamily = subfamily.replaceAll("-", "");
subfamily = subfamily.replaceAll("_", "");
if (subfamily.includes("thin")) {
face = "100";
} else if (subfamily.includes("extralight")) {
face = "200";
} else if (subfamily.includes("light")) {
face = "300";
} else if (subfamily.includes("medium")) {
face = "500";
} else if (subfamily.includes("semibold")) {
face = "600";
} else if (subfamily.includes("extrabold")) {
face = "800";
} else if (subfamily.includes("ultrabold")) {
face = "900";
} else if (subfamily.includes("bold")) {
face = "700";
}
if (subfamily.includes("italic")) {
face += "i";
}
}
let descriptor = fontsIndex.find((descriptor) => {
return descriptor.family === localFont.family);
});
if (descriptor) {
if (descriptor.faces.includes(face) === false) {
descriptor.faces.push(face);
}
} else {
let descriptor = {
family: localFont.family,
faces: [face],
};
fontsIndex.push(descriptor);
}
}
for (let descriptor of fontsIndex) {
descriptor.faces.sort();
}
بعد ذلك، يتم تخزين فهرس الخطوط الذي تمت تسويته في قاعدة بيانات IndexedDB حتى يمكن البحث عنه بسهولة، ومشاركته بين مثيلات التطبيق، والاحتفاظ به بين الجلسات. يستخدم Boxy رسومات موجّهة يمكن تغيير حجمها Dexie.js لإدارة قاعدة البيانات:
let database = new Dexie("LocalFontsManager");
database.version(1).stores({cache: "family"}).
await database.cache.clear();
await database.cache.bulkPut(fontsIndex);
بعد تعبئة قاعدة البيانات، يمكن لأداة اختيار الخطوط الاستعلام عنها وعرض النتائج على الشاشة:
من الجدير بالذكر أنّ Boxy SVG يعرض القائمة في عنصر مخصّص باسم <bx-fontfamilypicker>
ويصمّم كل عنصر في قائمة الخطوط بحيث يتم عرضه في مجموعة خطوط معيّنة. للعزل عن بقية الصفحة، يستخدم Boxy SVG Shadow DOM في هذا العنصر وغيره من العناصر المخصصة.
الاستنتاجات
ولاقت ميزة الخطوط المحلية رواجًا كبيرًا، إذ يستمتع المستخدمون بإمكانية الوصول إلى الخطوط المحلية في تصميماتهم وإبداعاتهم. عندما تغيّر شكل واجهة برمجة التطبيقات وتعطّلت الميزة لفترة وجيزة، لاحظ المستخدمون على الفور هذا الشكل. تمكّن "ياروسلاو" من تغيير الرمز بسرعة إلى النمط الدفاعي الذي يمكنك رؤيته في المقتطف أعلاه والذي يتوافق مع أحدث إصدار من Chrome بالإضافة إلى مشتقات Chromium الأخرى التي ربما لم يتم التبديل إلى أحدث إصدار منها. جرِّب استخدام تطبيق Boxy SVG للتأكّد من الخطوط التي تم تثبيتها على الجهاز. يمكنك العثور على بعض الألعاب الكلاسيكية التي لطالما نسيتها، مثل Zapf Dingbats أو Webdings.