공간정보/유용한 공간 정보

Mapbox(MapLibre)의 glyphs strites와 PBF 폰트 파일 이해하기

요긴소프트 2024. 11. 12. 07:37
728x90
반응형

개요

Mapbox에서 사용하는 폰트 파일(*.pbf)은 Protocol Buffer Font의 약자로, Google의 Protocol Buffers를 기반으로 하는 벡터 글리프 포맷입니다. 오늘은 이 PBF 폰트 파일의 구조와 CJK(중국어, 일본어, 한국어) 폰트를 만드는 방법에 대해 알아보겠습니다.

PBF 폰트 파일이란?

Mapbox의 PBF 폰트 파일은 다음과 같은 특징을 가집니다:

  1. 벡터 기반 글리프 저장
  2. 용량 최적화 (바이너리 포맷)
  3. 범위별 글리프 분할 저장
  4. 동적 로딩 지원

폰트 생성 과정

1. 준비물

# 필요한 도구 설치
npm install @mapbox/fontnik
npm install glyph-pbf-composite

2. TTF/OTF 폰트 준비

CJK 폰트 파일을 준비합니다. 예시로 Noto Sans를 사용해보겠습니다:

  • NotoSansCJK-Regular.ttf
  • NotoSansCJK-Bold.ttf

3. PBF 변환 스크립트

const fontnik = require('@mapbox/fontnik');
const fs = require('fs');
const path = require('path');

async function generatePBF(fontPath, outputDir) {
  const font = fs.readFileSync(fontPath);
  const ranges = [0, 65535]; // 전체 유니코드 범위
  
  for (let start = ranges[0]; start < ranges[1]; start += 256) {
    const end = Math.min(start + 255, ranges[1]);
    
    fontnik.range({
      font: font,
      start: start,
      end: end
    }, (err, data) => {
      if (err) throw err;
      
      const outputPath = path.join(
        outputDir, 
        `${start}-${end}.pbf`
      );
      
      fs.writeFileSync(outputPath, data);
    });
  }
}

4. 글리프 스프라이트 생성

const composite = require('glyph-pbf-composite');

async function createGlyphSprite(pbfDir, outputPath) {
  const files = fs.readdirSync(pbfDir);
  const glyphs = [];
  
  for (const file of files) {
    const data = fs.readFileSync(path.join(pbfDir, file));
    glyphs.push(data);
  }
  
  const sprite = composite(glyphs);
  fs.writeFileSync(outputPath, sprite);
}

실제 적용하기

1. 스타일 JSON에 폰트 추가

{
  "glyphs": "fonts/{fontstack}/{range}.pbf",
  "layers": [
    {
      "id": "labels",
      "type": "symbol",
      "layout": {
        "text-field": "{name}",
        "text-font": ["NotoSansCJK-Regular"]
      }
    }
  ]
}

2. 서버 설정

폰트 파일을 서빙하기 위한 Express 서버 예시:

const express = require('express');
const app = express();

app.get('/fonts/:fontstack/:range.pbf', (req, res) => {
  const { fontstack, range } = req.params;
  const fontPath = `./fonts/${fontstack}/${range}.pbf`;
  
  res.sendFile(fontPath);
});

주의사항

  1. 라이선스 확인
    • 사용하는 폰트의 라이선스를 반드시 확인하세요
    • 상업용 사용 시 별도 라이선스가 필요할 수 있습니다
  2. 용량 최적화
    • 필요한 글리프 범위만 포함
    • 불필요한 문자 제거로 용량 감소
  3. 성능 고려사항
    • 적절한 캐싱 전략 수립
    • CDN 활용 검토

결론

Mapbox의 PBF 폰트 시스템은 효율적인 벡터 폰트 전달을 가능하게 합니다. CJK 폰트의 경우 특히 많은 글리프를 포함하고 있어 최적화가 중요합니다. 위 과정을 통해 자신만의 CJK 폰트 세트를 구축할 수 있습니다.

추가적인 정보나 특정 부분에 대해 더 자세히 알고 싶으시다면 말씀해 주세요.

728x90
반응형