로컬 글꼴 액세스 API는 이름, 스타일, 모음과 같은 상위 수준 세부정보와 기본 글꼴 파일의 원시 바이트를 비롯하여 로컬에 설치된 사용자 글꼴 데이터에 액세스하는 메커니즘을 제공합니다. SVG 편집 앱 Boxy SVG에서 이 API를 어떻게 활용하는지 알아보세요.
소개
이 도움말은 동영상으로도 제공됩니다.
Boxy SVG는 벡터 그래픽 편집기입니다. 주요 사용 사례는 삽화, 로고, 아이콘, 기타 그래픽 디자인 요소를 만들기 위해 SVG 파일 형식의 그림을 수정하는 것입니다. 폴란드 개발자 야로스와프 폭사가 개발했으며 2013년 3월 15일에 처음 출시되었습니다. 야로스와프는 Boxy SVG 블로그를 운영하여 앱에 새로 추가한 기능을 발표합니다. 이 개발자는 Chromium의 Project Fugu를 적극적으로 지지하며 앱의 아이디어 추적기에 Fugu 태그도 사용합니다.
Boxy SVG의 로컬 Font Access API
야르솔라프가 블로그에 소개한 기능 중 하나는 Local Font Access API입니다. Local Font Access API를 사용하면 이름, 스타일, 패밀리와 같은 상위 수준 세부정보와 기본 글꼴 파일의 원시 바이트를 비롯하여 로컬에 설치된 글꼴에 액세스할 수 있습니다. 다음 스크린샷에서 제 MacBook에 로컬로 설치된 글꼴에 대한 액세스 권한을 앱에 부여하고 텍스트에 대해 Marker Felt 글꼴을 선택한 방법을 볼 수 있습니다.
기본 코드는 매우 간단합니다. 사용자가 글꼴 모음 선택 도구를 처음으로 열면 애플리케이션은 먼저 웹 브라우저가 Local Font Access 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();
}
그런 다음 정규화된 글꼴 색인(font index)이 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와 같이 오랫동안 잊혀진 고전 게임을 확인해 보세요.