로컬 글꼴 액세스 API는 이름, 스타일, 모음과 같은 상위 수준 세부정보와 기본 글꼴 파일의 원시 바이트를 비롯하여 로컬에 설치된 사용자의 글꼴 데이터에 액세스하는 메커니즘을 제공합니다. SVG 편집 앱 Boxy SVG에서 이 API를 사용하는 방법을 알아봅니다.
소개
이 도움말은 동영상으로도 제공됩니다.
Boxy SVG는 벡터 그래픽 편집기입니다. 주요 사용 사례는 삽화, 로고, 아이콘, 기타 그래픽 디자인 요소를 만들기 위해 SVG 파일 형식의 그림을 수정하는 것입니다. 이 프로그램은 폴란드 개발자 Jarosław Foksa가 개발했으며 2013년 3월 15일에 처음 출시되었습니다. 야로슬라우는 앱에 추가한 새로운 기능을 발표하는 Boxy SVG 블로그를 운영하고 있습니다. 이 개발자는 Chromium의 Project Fugu를 강력하게 지지하며 앱의 아이디어 추적기에도 Fugu 태그를 지정했습니다.
Boxy SVG의 Local Fonts Access API
야르솔라프가 블로그에 소개한 기능 중 하나는 Local Font Access API입니다. Local Font Access API를 사용하면 이름, 스타일, 패밀리와 같은 상위 수준 세부정보와 기본 글꼴 파일의 원시 바이트를 비롯하여 로컬에 설치된 글꼴에 액세스할 수 있습니다. 다음 스크린샷에서는 앱에 MacBook에 로컬로 설치된 글꼴에 대한 액세스 권한을 부여하고 텍스트에 마커 펠트 글꼴을 선택한 방법을 확인할 수 있습니다.
기본 코드는 매우 간단합니다. 사용자가 글꼴 패밀리 선택 도구를 처음 열면 애플리케이션은 먼저 웹브라우저가 로컬 글꼴 액세스 API를 지원하는지 확인합니다.
또한 이전 API의 실험 버전을 확인하고 있는 경우 사용합니다. 2023년부터는 실험용 Chrome 플래그를 통해 잠시만 사용할 수 있었던 이전 API를 안전하게 무시할 수 있지만 일부 Chromium 파생 제품에서는 계속 사용할 수 있습니다.
let isLocalFontsApiEnabled = (
// Local Font Access API, Chrome >= 102
window.queryLocalFonts !== undefined ||
// Experimental Local Font Access API, Chrome < 102
navigator.fonts?.query !== undefined
);
로컬 글꼴 액세스 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 형식이 변경되고 기능이 잠시 중단되자 사용자는 즉시 이를 알아챘습니다. 야로슬라우는 위 스니펫에 표시된 것처럼 최신 Chrome 및 최신 버전으로 전환하지 않았을 수 있는 다른 Chromium 파생 제품에서 작동하는 방어 패턴으로 코드를 빠르게 변경했습니다. Boxy SVG를 사용해 보고 로컬에 설치된 글꼴을 확인하세요. Zapf Dingbats나 Webdings와 같이 오래된 서체를 발견할 수도 있습니다.