Local Font Access API มีกลไกในการเข้าถึงข้อมูลแบบอักษรที่ผู้ใช้ติดตั้งไว้ในเครื่อง ซึ่งรวมถึงรายละเอียดระดับสูงขึ้น เช่น ชื่อ สไตล์ และตระกูล รวมถึงไบต์ดิบของไฟล์แบบอักษรที่เกี่ยวข้อง ดูวิธีที่แอปแก้ไข SVG อย่าง Boxy SVG ใช้ API นี้
บทนำ
(บทความนี้มีให้บริการในรูปแบบวิดีโอด้วย)
Boxy SVG เป็นโปรแกรมแก้ไขกราฟิกเวกเตอร์ Use Case หลักคือการแก้ไขภาพวาดในรูปแบบไฟล์ SVG สำหรับการสร้างภาพ โลโก้ ไอคอน และองค์ประกอบอื่นๆ ของการออกแบบกราฟิก เครื่องมือนี้พัฒนาขึ้นโดย Jarosław Foksa ซึ่งเป็นนักพัฒนาเกมชาวโปแลนด์ และเปิดตัวครั้งแรกเมื่อวันที่ 15 มีนาคม 2013 Jarosław ทำบล็อก Boxy SVG ซึ่งเขาได้เปิดตัวฟีเจอร์ใหม่ที่เขาเพิ่มลงในแอป นักพัฒนาซอฟต์แวร์เป็นผู้สนับสนุนที่แข็งแกร่งสำหรับโปรเจ็กต์ Fugu ของ Chromium และยังมีแท็ก Fugu บนเครื่องมือติดตามแนวคิดของแอปอีกด้วย
Local Font Access API ใน Boxy SVG
ฟีเจอร์หนึ่งที่ Jarosław เขียนบล็อกถึงคือ Local Font Access API Local Font Access API ช่วยให้ผู้ใช้เข้าถึงแบบอักษรที่ติดตั้งในเครื่อง รวมถึงรายละเอียดระดับสูงขึ้น เช่น ชื่อ สไตล์ และชุดแบบอักษร ตลอดจนไบต์ดิบของไฟล์แบบอักษรพื้นฐาน ในภาพหน้าจอต่อไปนี้ คุณจะเห็นวิธีที่ฉันให้สิทธิ์เข้าถึงแบบอักษรที่ติดตั้งในเครื่องบน MacBook แก่แอปและเลือกแบบอักษร Marker Felt สำหรับข้อความ
โค้ดพื้นฐานค่อนข้างตรงไปตรงมา เมื่อผู้ใช้เปิดเครื่องมือเลือกแบบอักษรเป็นครั้งแรก แอปพลิเคชันจะตรวจสอบก่อนว่าเว็บเบราว์เซอร์รองรับ Local Font Access API หรือไม่
นอกจากนี้ ยังตรวจสอบ API เวอร์ชันเก่าเวอร์ชันทดลองและนำไปใช้ด้วยหากมี ตั้งแต่ปี 2023 เป็นต้นไป คุณสามารถละเว้น API เก่าได้อย่างปลอดภัย เนื่องจาก API ดังกล่าวใช้งานได้เพียงระยะเวลาสั้นๆ ผ่าน Flag ทดลองของ Chrome แต่ผลิตภัณฑ์ที่มาจาก Chromium บางรายการอาจยังคงใช้ API ดังกล่าว
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 รีบเปลี่ยนโค้ดเป็นรูปแบบการป้องกันที่คุณเห็นในสนิปเพลตด้านบน ซึ่งใช้ได้กับ Chrome เวอร์ชันล่าสุดและผลิตภัณฑ์อื่นๆ ของ Chromium ที่อาจยังไม่ได้เปลี่ยนไปใช้เวอร์ชันล่าสุด ลองใช้ Boxy SVG และอย่าลืมตรวจสอบแบบอักษรที่ติดตั้งในเครื่อง คุณอาจค้นพบแบบอักษรคลาสสิกที่ลืมไปนานแล้ว เช่น Zapf Dingbats หรือ Webdings