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

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

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

หากคุณพัฒนาเว็บมานานพอแล้ว คุณอาจจำสิ่งที่เรียกว่าแบบอักษรสำหรับเว็บที่ปลอดภัยได้ เป็นที่ทราบกันดีว่าแบบอักษรเหล่านี้ใช้ได้ในเกือบทุกอินสแตนซ์ของระบบปฏิบัติการที่ใช้บ่อยที่สุด (ได้แก่ Windows, macOS, Linux ดิสทริบิวชันที่พบบ่อยที่สุด, Android และ iOS) ในช่วงต้นทศวรรษ 2000 Microsoft ได้บุกเบิกโครงการริเริ่มที่เรียกว่า TrueType Core แบบอักษรสำหรับเว็บ ซึ่งให้ดาวน์โหลดแบบอักษรเหล่านี้ได้ฟรีโดยมีจุดประสงค์ที่ว่า "เมื่อใดก็ตามที่คุณเข้าชมเว็บไซต์ที่ระบุแบบอักษร คุณจะเห็นหน้าเว็บตามที่นักออกแบบเว็บไซต์ต้องการ" ใช่ เว็บไซต์ที่รวมอยู่ใน 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

แอป macOS Font Book แสดงตัวอย่างแบบอักษร 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 ระดับต่ำ (เน้นไบต์) ซึ่งมีข้อมูลแบบอักษรแบบเต็ม

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

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

  • 103
  • 103
  • x
  • x

แหล่งที่มา

วิธีใช้ 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, TrueType, 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);
}

ข้อมูลประชากร

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

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

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

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

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

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

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

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

ความโปร่งใส

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

ความต่อเนื่องของสิทธิ์

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

ความคิดเห็น

ทีม Chrome ต้องการทราบข้อมูลเกี่ยวกับประสบการณ์การใช้งาน Local Font Access API

บอกให้เราทราบเกี่ยวกับการออกแบบ API

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

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

คุณพบข้อบกพร่องในการใช้งาน 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