ใช้แบบอักษรขั้นสูงกับแบบอักษรในเครื่อง

ดูวิธีที่ Local Font Access API ช่วยให้คุณเข้าถึงแบบอักษรที่ผู้ใช้ติดตั้งไว้ในเครื่องและดูรายละเอียดระดับล่างเกี่ยวกับแบบอักษรเหล่านั้น

แบบอักษรที่ปลอดภัยสำหรับเว็บ

หากคุณทํางานด้านการพัฒนาเว็บมาอย่างยาวนาน คุณอาจคุ้นเคยกับสิ่งที่เรียกว่าแบบอักษรที่ปลอดภัยบนเว็บ แบบอักษรเหล่านี้เป็นที่รู้จักกันว่ามีให้บริการในอินสแตนซ์เกือบทั้งหมดของระบบปฏิบัติการที่ใช้มากที่สุด (ได้แก่ Windows, macOS, ดิสทริบิวชัน Linux ที่พบบ่อยที่สุด, Android และ iOS) ในช่วงต้นปี 2000 ทาง Microsoft ยังได้เป็นผู้ริเริ่มโครงการที่ชื่อว่า แบบอักษรหลัก TrueType สำหรับเว็บ ซึ่งให้บริการดาวน์โหลดแบบอักษรเหล่านี้ได้ฟรี โดยมีวัตถุประสงค์ว่า"เมื่อใดก็ตามที่คุณเข้าชมเว็บไซต์ที่ระบุแบบอักษรเหล่านี้ คุณจะเห็นหน้าเว็บตามที่นักออกแบบเว็บไซต์ตั้งใจไว้ทุกประการ" ใช่แล้ว โดยรวมเว็บไซต์ที่ตั้งค่าใน Comic Sans MS ด้วย ลองดูชุดแบบอักษรที่ปลอดภัยสำหรับเว็บแบบคลาสสิก (โดยใช้แบบอักษรสำรองของ sans-serif) ที่อาจมีหน้าตาดังนี้

body {
 
font-family: Helvetica, Arial, sans-serif;
}

แบบอักษรเว็บ

ยุคที่แบบอักษรที่ปลอดภัยบนเว็บมีความสำคัญมากนั้นผ่านไปนานแล้ว ปัจจุบันเรามีแบบอักษรเว็บ ซึ่งบางแบบเป็นแบบอักษรแบบผันแปรที่ปรับแต่งเพิ่มเติมได้โดยการกําหนดค่าสำหรับแกนต่างๆ ที่แสดง คุณสามารถใช้แบบอักษรบนเว็บได้โดยประกาศบล็อก @font-face ที่จุดเริ่มต้นของ CSS ซึ่งจะระบุไฟล์แบบอักษรที่จะดาวน์โหลด

@font-face {
 
font-family: 'FlamboyantSansSerif';
 
src: url('flamboyant.woff2');
}

หลังจากนั้น คุณจะใช้แบบอักษรเว็บที่กำหนดเองได้โดยระบุ font-family ตามปกติ ดังนี้

body {
 
font-family: 'FlamboyantSansSerif';
}

แบบอักษรในเครื่องเป็นเวกเตอร์ลายนิ้วมือ

แบบอักษรเว็บส่วนใหญ่มาจากเว็บ แต่ข้อเท็จจริงที่น่าสนใจคือพร็อพเพอร์ตี้ src ในประกาศ @font-face นอกเหนือจากฟังก์ชัน url() แล้ว ยังยอมรับฟังก์ชัน local() ด้วย ซึ่งจะช่วยให้โหลดแบบอักษรที่กำหนดเองในเครื่องได้ (ว้าว) หากผู้ใช้ติดตั้ง FlamboyantSansSerif ไว้ในระบบปฏิบัติการ ระบบจะใช้สำเนาในเครื่องแทนการดาวน์โหลด

@font-face {
 
font-family: 'FlamboyantSansSerif';
 
src: local('FlamboyantSansSerif'), url('flamboyant.woff2');
}

วิธีนี้มีกลไกสำรองที่ดีซึ่งอาจประหยัดแบนด์วิดท์ได้ ขออภัย เราไม่สามารถควบคุมสิ่งที่เกิดขึ้นบนอินเทอร์เน็ตได้ ปัญหาของฟังก์ชัน local() คืออาจมีการละเมิดเพื่อใช้ลายนิ้วเบราว์เซอร์ ปรากฏว่ารายการแบบอักษรที่ผู้ใช้ติดตั้งไว้มีประโยชน์ในการระบุตัวตน บริษัทจำนวนมากมีแบบอักษรขององค์กรที่ติดตั้งในแล็ปท็อปของพนักงาน เช่น Google มีแบบอักษรขององค์กรชื่อ Google Sans

แอป Font Book ของ macOS ที่แสดงตัวอย่างแบบอักษร Google Sans
แบบอักษร Google Sans ที่ติดตั้งในแล็ปท็อปของพนักงาน Google

ผู้โจมตีอาจพยายามระบุบริษัทที่ผู้ใช้ทำงานด้วยโดยทดสอบว่ามีการใช้แบบอักษรขององค์กรที่รู้จักจำนวนมากหรือไม่ เช่น Google Sans ผู้โจมตีจะพยายามแสดงผลข้อความที่ตั้งค่าแบบอักษรเหล่านี้บนผืนผ้าใบและวัดค่าแบบอักษร หากสัญลักษณ์ตรงกับรูปร่างที่รู้จักของแบบอักษรขององค์กร ผู้โจมตีก็จะพบคำที่ตรงกัน หากอักขระไม่ตรงกัน ผู้โจมตีจะทราบว่ามีการใช้แบบอักษรทดแทนเริ่มต้นเนื่องจากไม่ได้ติดตั้งแบบอักษรขององค์กร อ่านรายละเอียดทั้งหมดเกี่ยวกับการโจมตีด้วยลายนิ้วเบราว์เซอร์รูปแบบนี้และรูปแบบอื่นๆ ได้ที่บทความสํารวจโดย Laperdix et al.

แบบอักษรของบริษัทนั้นแตกต่างกัน แม้จะระบุเฉพาะรายการแบบอักษรที่ติดตั้งไว้ก็ตาม สถานการณ์เกี่ยวกับเวกเตอร์การโจมตีนี้แย่มากจนเมื่อเร็วๆ นี้ทีม WebKit ตัดสินใจ"รวมเฉพาะแบบอักษรเว็บและแบบอักษรที่มาพร้อมกับระบบปฏิบัติการ [ในรายการแบบอักษรที่ใช้ได้] แต่จะไม่รวมแบบอักษรที่ผู้ใช้ติดตั้งในเครื่อง" (และตอนนี้ฉันก็เขียนบทความเกี่ยวกับการให้สิทธิ์เข้าถึงแบบอักษรในเครื่องแล้ว)

Local Font Access API

เนื้อหาช่วงต้นของบทความนี้อาจทำให้คุณรู้สึกแย่ เราไม่ได้ใช้สิ่งดีๆ เลยหรือ ไม่ต้องกังวล เราคิดว่าทำได้ และหวังว่าทุกอย่างจะยังไม่สิ้นหวัง แต่ก่อนอื่น เราขอตอบคำถามที่คุณอาจสงสัย

เหตุใดเราจึงต้องใช้ Local Font Access API เมื่อมีแบบอักษรของเว็บ

ที่ผ่านมา เครื่องมือการออกแบบและกราฟิกคุณภาพระดับมืออาชีพนั้นใช้งานบนเว็บได้ยาก ปัญหาหนึ่งคือผู้ใช้ไม่สามารถเข้าถึงและใช้แบบอักษรที่ออกแบบและปรับให้เหมาะกับการใช้งานอย่างมืออาชีพซึ่งมีหลากหลายแบบซึ่งนักออกแบบติดตั้งไว้ในเครื่อง แบบอักษรสำหรับเว็บเปิดใช้กรณีการใช้งานการเผยแพร่บางอย่าง แต่เปิดใช้การเข้าถึงแบบเป็นโปรแกรมสำหรับรูปร่างแบบเวกเตอร์ของสัญลักษณ์และตารางแบบอักษรที่โปรแกรมแรสเตอร์ใช้แสดงผลขอบของสัญลักษณ์ไม่ได้ ในทำนองเดียวกัน คุณไม่สามารถเข้าถึงข้อมูลไบนารีของแบบอักษรเว็บ

  • เครื่องมือออกแบบต้องมีสิทธิ์เข้าถึงไบต์ของแบบอักษรเพื่อใช้งานเลย์เอาต์ OpenType ของตัวเอง และช่วยให้เครื่องมือออกแบบสามารถเชื่อมโยงได้ในระดับที่ต่ำกว่าสำหรับการดำเนินการต่างๆ เช่น การใช้ฟิลเตอร์เวกเตอร์หรือการแปลงรูปร่างรูปอักขระ
  • นักพัฒนาซอฟต์แวร์อาจมีชุดแบบอักษรเดิมสำหรับแอปพลิเคชันของตนซึ่งนำมาสู่เว็บ หากต้องการใช้แพ็กเกจเหล่านี้ โดยทั่วไปแล้วแพ็กเกจจะต้องเข้าถึงข้อมูลแบบอักษรโดยตรง ซึ่งเว็บแบบอักษรไม่มี
  • แบบอักษรบางรายการอาจไม่ได้รับอนุญาตให้แสดงผ่านเว็บ ตัวอย่างเช่น Linotype มีใบอนุญาตสำหรับแบบอักษรบางแบบที่มีไว้สำหรับการใช้งานบนเดสก์ท็อปเท่านั้น

Local Font Access API เป็นการพยายามแก้ปัญหาเหล่านี้ ซึ่งประกอบด้วย 2 ส่วน ดังนี้

  • API การแจกแจงแบบอักษร ซึ่งช่วยให้ผู้ใช้ให้สิทธิ์เข้าถึงแบบอักษรทั้งหมดของระบบได้
  • จากผลลัพธ์การแจกแจงแต่ละรายการ ความสามารถในการขอการเข้าถึงคอนเทนเนอร์ SFNT ระดับต่ำ (แบบไบต์) ที่มีข้อมูลแบบอักษรทั้งหมด

การสนับสนุนเบราว์เซอร์

การรองรับเบราว์เซอร์

  • Chrome: 103
  • Edge: 103
  • Firefox: ไม่รองรับ
  • Safari: ไม่รองรับ

แหล่งที่มา

วิธีใช้ Local Font Access API

การตรวจหาฟีเจอร์

หากต้องการตรวจสอบว่าระบบรองรับ Local Font Access API หรือไม่ ให้ใช้

if ('queryLocalFonts' in window) {
 
// The Local Font Access API is supported
}

การระบุแบบอักษรในเครื่อง

หากต้องการดูรายการแบบอักษรที่ติดตั้งไว้ในเครื่อง คุณต้องเรียกใช้ window.queryLocalFonts() การดำเนินการนี้ครั้งแรกจะทริกเกอร์ข้อความแจ้งสิทธิ์ ซึ่งผู้ใช้จะอนุมัติหรือปฏิเสธได้ หากผู้ใช้อนุญาตให้ค้นหาแบบอักษรในเครื่องได้ เบราว์เซอร์จะแสดงผลอาร์เรย์ที่มีข้อมูลแบบอักษรซึ่งคุณนำไปใช้วนซ้ำได้ แบบอักษรแต่ละแบบจะแสดงเป็นออบเจ็กต์ FontData ที่มีพร็อพเพอร์ตี้ family (เช่น "Comic Sans MS"), fullName (เช่น "Comic Sans MS"), postscriptName (เช่น "ComicSansMS") และ style (เช่น "Regular")

// Query for all available fonts and log metadata.
try {
 
const availableFonts = await window.queryLocalFonts();
 
for (const fontData of availableFonts) {
    console
.log(fontData.postscriptName);
    console
.log(fontData.fullName);
    console
.log(fontData.family);
    console
.log(fontData.style);
 
}
} catch (err) {
  console
.error(err.name, err.message);
}

หากสนใจเฉพาะแบบอักษรชุดย่อย คุณยังกรองแบบอักษรตามชื่อ PostScript ได้อีกด้วยโดยเพิ่มพารามิเตอร์ postscriptNames

const availableFonts = await window.queryLocalFonts({
  postscriptNames
: ['Verdana', 'Verdana-Bold', 'Verdana-Italic'],
});

การเข้าถึงข้อมูล SFNT

สิทธิ์เข้าถึง SFNT โดยสมบูรณ์เข้าถึงได้ผ่านเมธอด blob() ของออบเจ็กต์ FontData SFNT คือรูปแบบไฟล์แบบอักษรที่อาจมีแบบอักษรอื่นๆ เช่น PostScript, OpenType, Web Open Font Format (WOFF) และอื่นๆ

try {
 
const availableFonts = await window.queryLocalFonts({
    postscriptNames
: ['ComicSansMS'],
 
});
 
for (const fontData of availableFonts) {
   
// `blob()` returns a Blob containing valid and complete
   
// SFNT-wrapped font data.
   
const sfnt = await fontData.blob();
   
// Slice out only the bytes we need: the first 4 bytes are the SFNT
   
// version info.
   
// Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font
   
const sfntVersion = await sfnt.slice(0, 4).text();

    let outlineFormat
= 'UNKNOWN';
   
switch (sfntVersion) {
     
case '\x00\x01\x00\x00':
     
case 'true':
     
case 'typ1':
        outlineFormat
= 'truetype';
       
break;
     
case 'OTTO':
        outlineFormat
= 'cff';
       
break;
   
}
    console
.log('Outline format:', outlineFormat);
 
}
} catch (err) {
  console
.error(err.name, err.message);
}

สาธิต

คุณดูการทำงานของ Local Font Access API ได้ในเดโมด้านล่าง อย่าลืมดูซอร์สโค้ดด้วย การแสดงตัวอย่างจะแสดงองค์ประกอบที่กำหนดเองชื่อ <font-select> ที่ใช้เครื่องมือเลือกแบบอักษรในเครื่อง

ข้อควรพิจารณาด้านความเป็นส่วนตัว

สิทธิ์ "local-fonts" ดูเหมือนว่าจะมีแพลตฟอร์มที่ตรวจหาลายนิ้วมือได้สูง อย่างไรก็ตาม เบราว์เซอร์สามารถแสดงผลทุกอย่างที่ต้องการได้ฟรี ตัวอย่างเช่น เบราว์เซอร์ที่มุ่งเน้นการไม่ระบุตัวตนอาจเลือกระบุชุดแบบอักษรเริ่มต้นที่มีอยู่ในเบราว์เซอร์เท่านั้น ในทํานองเดียวกัน เบราว์เซอร์ไม่จําเป็นต้องแสดงข้อมูลตารางในลักษณะที่ปรากฏบนดิสก์

Local Font Access API ได้รับการออกแบบให้แสดงเฉพาะข้อมูลที่จําเป็นเพื่อเปิดใช้ Use Case ที่กล่าวถึงเท่านั้น System API อาจแสดงรายการแบบอักษรที่ติดตั้งไว้ไม่เรียงตามลำดับแบบสุ่มหรือจัดเรียง แต่เรียงตามลำดับการติดตั้งแบบอักษร การแสดงรายการแบบตัวอักษรที่ติดตั้งไว้ทั้งหมดซึ่ง API ของระบบดังกล่าวระบุอาจเปิดเผยข้อมูลเพิ่มเติมที่อาจใช้สำหรับลายนิ้วมือ และการจัดเรียงนี้ไม่ได้ช่วยกรณีการใช้งานที่เราต้องการเปิดใช้ API นี้จึงต้องจัดเรียงข้อมูลที่ส่งคืนก่อนที่จะส่งคืน

ความปลอดภัยและสิทธิ์

ทีม Chrome ได้ออกแบบและติดตั้งใช้งาน Local Font Access API โดยใช้หลักการหลักที่ระบุไว้ในการควบคุมการเข้าถึงฟีเจอร์ที่มีประสิทธิภาพของแพลตฟอร์มเว็บ ซึ่งรวมถึงการควบคุมของผู้ใช้ ความโปร่งใส และลักษณะการใช้งานที่สะดวกสบาย

การควบคุมของผู้ใช้

ผู้ใช้จะควบคุมการเข้าถึงแบบเต็มรูปแบบของแบบอักษรได้ และระบบจะไม่อนุญาตให้เข้าถึง เว้นแต่จะได้รับสิทธิ์ "local-fonts" ตามที่ระบุไว้ในรีจิสทรีสิทธิ์

ความโปร่งใส

เว็บไซต์ได้รับสิทธิ์เข้าถึงแบบอักษรในเครื่องของผู้ใช้หรือไม่จะปรากฏในแผ่นข้อมูลของเว็บไซต์

การเก็บรักษาสิทธิ์

สิทธิ์ "local-fonts" จะยังคงอยู่ในระหว่างการโหลดหน้าซ้ำ ซึ่งจะเพิกถอนผ่านชีตข้อมูลเว็บไซต์ได้

ความคิดเห็น

ทีม Chrome อยากทราบความคิดเห็นของคุณเกี่ยวกับ Local Font Access API

บอกเราเกี่ยวกับการออกแบบ API

มีสิ่งใดเกี่ยวกับ API ที่ไม่ทำงานตามที่คาดไว้ไหม หรือมีเมธอดหรือพร็อพเพอร์ตี้ที่ขาดหายไปซึ่งคุณต้องนำไปใช้กับแนวคิดของคุณ หากคุณมีคำถามหรือความคิดเห็นเกี่ยวกับ รูปแบบการรักษาความปลอดภัย แจ้งปัญหาเกี่ยวกับข้อกำหนดใน GitHub repo ที่เกี่ยวข้อง หรือแสดงความคิดเห็นในปัญหาที่มีอยู่

รายงานปัญหาเกี่ยวกับการติดตั้งใช้งาน

หากพบข้อบกพร่องในการใช้งาน Chrome หรือการติดตั้งใช้งานแตกต่างจากข้อมูลจำเพาะหรือไม่ รายงานข้อบกพร่องที่ new.crbug.com โปรดระบุรายละเอียดให้มากที่สุดเท่าที่จะทำได้ ระบุวิธีการง่ายๆ ในการจำลองข้อบกพร่อง และป้อน Blink>Storage>FontAccess ในช่องคอมโพเนนต์ Glitch เหมาะอย่างยิ่งสำหรับการแชร์การจำลองข้อบกพร่องที่รวดเร็วและง่ายดาย

แสดงการสนับสนุน API

คุณกำลังวางแผนที่จะใช้ Local Font Access API ใช่ไหม การสนับสนุนแบบสาธารณะของคุณจะช่วยให้ทีม Chrome จัดลำดับความสำคัญของฟีเจอร์ต่างๆ และแสดงให้เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้สำคัญกับผู้ให้บริการเบราว์เซอร์รายอื่นๆ เพียงใด

ส่งทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก #LocalFontAccess และบอกเราว่าคุณกำลังใช้ฟีเจอร์นี้ที่ไหนและอย่างไร

ขอขอบคุณ

ข้อมูลจำเพาะของ Local Font Access API ได้รับการแก้ไขโดย Emil A. Eklund, Alex Russell, Joshua Bell และ Olivier Yiptong บทความนี้ได้รับการตรวจสอบโดย Joe Medley, Dominik Röttsches และ Olivier Yiptong รูปภาพหลักโดย Brett Jordan จาก Unsplash