Local Font Access API مکانیزمی برای دسترسی به دادههای فونت نصبشده محلی کاربر، از جمله جزئیات سطح بالاتر مانند نامها، سبکها و خانوادهها، و همچنین بایتهای خام فایلهای فونت زیرین را فراهم میکند. بیاموزید که چگونه برنامه ویرایش SVG Boxy SVG از این API استفاده می کند.
مقدمه
(این مقاله به صورت ویدئویی نیز موجود است.)
Boxy SVG یک ویرایشگر گرافیک برداری است. مورد استفاده اصلی آن ویرایش نقشه ها در قالب فایل SVG برای ایجاد تصاویر، لوگوها، نمادها و سایر عناصر طراحی گرافیکی است. این توسط توسعه دهنده لهستانی Jarosław Foksa توسعه یافته است و در ابتدا در 15 مارس 2013 منتشر شد. Jarosław یک وبلاگ Boxy SVG را اجرا می کند که در آن ویژگی های جدیدی را که به برنامه اضافه می کند را اعلام می کند. توسعهدهنده از Project Fugu Chromium حمایت میکند و حتی یک برچسب Fugu در ردیاب ایدههای برنامه دارد.
Local Font Access API در Boxy SVG
یکی از ویژگی های اضافی که Jarosław در مورد آن وبلاگ نویسی کرد، Local Font Access API بود. Local Font Access API به کاربران امکان می دهد به فونت های نصب شده محلی خود، از جمله جزئیات سطح بالاتر مانند نام ها، سبک ها، و خانواده ها و همچنین بایت های خام فایل های فونت زیر دسترسی داشته باشند. در تصویر زیر می توانید ببینید که چگونه به برنامه اجازه دسترسی به فونت های نصب شده محلی در مک بوک خود داده ام و فونت Marker Felt را برای متن خود انتخاب کرده ام.
کد زیربنایی کاملاً ساده است. هنگامی که کاربر برای اولین بار انتخابگر خانواده فونت را باز می کند، برنامه ابتدا بررسی می کند که آیا مرورگر وب از Local Font Access API پشتیبانی می کند یا خیر.
همچنین نسخه آزمایشی قدیمی API را بررسی می کند و در صورت وجود از آن استفاده می کند. از سال 2023، میتوانید با خیال راحت API قدیمی را نادیده بگیرید زیرا فقط برای مدت کوتاهی از طریق پرچمهای آزمایشی 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 SVG از 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 در این و سایر عناصر سفارشی استفاده می کند.
نتیجه گیری
ویژگی فونت های محلی واقعاً محبوب بوده است و کاربران از دسترسی به فونت های محلی خود برای طرح ها و خلاقیت های خود لذت می برند. هنگامی که شکل API تغییر کرد و این ویژگی برای مدت کوتاهی از کار افتاد ، کاربران بلافاصله متوجه شدند. Jarosław سریعاً کد را به الگوی دفاعی تغییر داد که میتوانید در قطعه بالا مشاهده کنید. Boxy SVG را امتحان کنید و حتما فونت های نصب شده محلی خود را بررسی کنید. ممکن است برخی از آثار کلاسیک فراموش شده مانند Zapf Dingbats یا Webdings را کشف کنید.