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