Форматы шрифтов

Шрифты в MapLibre GL JS используются для отображения текстовых подписей на карте: названий городов, улиц, рек, объектов инфраструктуры, пользовательских меток и любых других текстовых элементов, задаваемых через слои типа symbol. Качество визуализации подписей напрямую зависит от формата хранения шрифтов, способа их доставки клиенту и особенностей рендеринга движка.

В отличие от обычных веб-страниц, где браузер самостоятельно загружает и отображает файлы шрифтов (.ttf, .otf, .woff, .woff2), MapLibre GL JS использует специализированную систему хранения глифов, оптимизированную для работы с интерактивными картами.


Особенности рендеринга текста

Текст на карте обладает рядом специфических требований:

  • высокая скорость отображения;
  • масштабирование без потери качества;
  • поддержка большого количества языков;
  • возможность динамического изменения размеров;
  • корректное размещение подписей при изменении масштаба и повороте карты;
  • минимизация объёма передаваемых данных.

Для решения этих задач MapLibre GL JS использует не сами файлы шрифтов, а предварительно подготовленные наборы глифов.


Что такое глифы

Глифом называется графическое представление символа.

Например:

Символ Глиф
A изображение буквы A
Б изображение буквы Б
5 изображение цифры 5
% изображение знака процента

Когда на карте отображается строка:

Astana

движок получает отдельные глифы:

A
s
t
a
n
a

и собирает из них итоговую подпись.

Такой подход позволяет загружать только необходимые символы, а не весь файл шрифта.


Формат PBF как основной формат шрифтов

Основным форматом хранения шрифтов в MapLibre GL JS является PBF (Protocol Buffers).

Сервер шрифтов предоставляет данные в виде файлов:

Arial Unicode MS Regular/0-255.pbf
Arial Unicode MS Regular/256-511.pbf
Arial Unicode MS Regular/512-767.pbf

Каждый файл содержит диапазон Unicode-символов.

Пример URL:

https://server/fonts/{fontstack}/{range}.pbf

После подстановки параметров:

https://server/fonts/Open Sans Regular/0-255.pbf

Почему используется PBF

Использование обычных файлов TTF или OTF привело бы к ряду проблем:

  • большой размер загрузки;
  • необходимость скачивать весь шрифт целиком;
  • медленная работа при поддержке многих языков;
  • увеличение времени отображения карты.

PBF решает эти проблемы за счёт:

  • бинарного хранения;
  • компактного размера;
  • разделения символов по диапазонам;
  • выборочной загрузки.

Например, если карта содержит только латинские символы:

London
Paris
Berlin

будет загружен лишь диапазон:

0-255.pbf

Если появляются китайские символы:

北京
上海

движок автоматически запросит дополнительные диапазоны Unicode.


Структура glyphs в стиле карты

В спецификации стиля имеется свойство:

{
  "glyphs": "https://server/fonts/{fontstack}/{range}.pbf"
}

Оно определяет источник глифов для всех текстовых слоёв.

Пример:

const map = new maplibregl.Map({
    container: "map",
    style: {
        version: 8,
        glyphs: "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
        sources: {},
        layers: []
    }
});

Без корректно настроенного свойства glyphs текстовые подписи отображаться не будут.


Параметр fontstack

Плейсхолдер:

{fontstack}

означает набор используемых шрифтов.

Например:

"text-font": [
    "Open Sans Regular",
    "Arial Unicode MS Regular"
]

В этом случае MapLibre формирует запрос:

Open Sans Regular,Arial Unicode MS Regular

и подставляет его в URL:

https://server/fonts/Open Sans Regular,Arial Unicode MS Regular/0-255.pbf

Такой механизм обеспечивает резервирование шрифтов.


Резервные шрифты

Подписи могут содержать символы, отсутствующие в основном шрифте.

Например:

"text-font": [
    "Roboto Regular",
    "Arial Unicode MS Regular"
]

Если символ отсутствует в:

Roboto Regular

MapLibre попробует использовать:

Arial Unicode MS Regular

Подобная схема особенно важна для мультиязычных карт.


Unicode и диапазоны символов

Глифы разделяются на блоки по 256 символов.

Примеры диапазонов:

0-255
256-511
512-767
768-1023

При необходимости отображения текста:

Москва

движок определяет Unicode-коды букв и загружает соответствующие диапазоны.

Это позволяет значительно сократить сетевой трафик.


Генерация PBF-шрифтов

MapLibre GL JS не генерирует PBF самостоятельно в браузере.

Файлы должны быть подготовлены заранее.

Для этого используются специальные инструменты:

  • fontnik;
  • node-fontnik;
  • openmaptiles-fonts;
  • maptiler-font-server;
  • собственные генераторы.

Исходными файлами обычно выступают:

.ttf
.otf

После обработки создаётся набор PBF-файлов для различных диапазонов Unicode.


Fontnik

Одним из наиболее распространённых инструментов является Fontnik.

Схема работы выглядит следующим образом:

TTF
   ↓
Fontnik
   ↓
PBF-глифы
   ↓
MapLibre GL JS

Fontnik преобразует контуры символов в формат, пригодный для быстрого отображения на карте.


OpenMapTiles Fonts

Проект OpenMapTiles предоставляет готовый набор шрифтов для картографических проектов.

Поддерживаются:

  • латиница;
  • кириллица;
  • греческий алфавит;
  • арабская письменность;
  • китайские иероглифы;
  • японские символы;
  • корейская письменность.

Это позволяет быстро развернуть собственный сервер шрифтов без подготовки данных вручную.


Использование текстовых слоёв

Шрифты применяются через свойства слоя типа symbol.

Пример:

map.addLayer({
    id: "cities",
    type: "symbol",
    source: "cities",
    layout: {
        "text-field": ["get", "name"],
        "text-font": [
            "Open Sans Regular"
        ],
        "text-size": 14
    }
});

Здесь используется шрифт:

Open Sans Regular

который должен существовать на сервере глифов.


Поддержка нескольких начертаний

Для одного семейства шрифтов обычно создаются отдельные наборы:

Open Sans Regular
Open Sans Bold
Open Sans Italic
Open Sans Semibold

Выбор выполняется через массив:

"text-font": [
    "Open Sans Bold"
]

Каждое начертание представляет отдельный набор глифов.


Полужирные шрифты

Пример использования:

layout: {
    "text-field": "Airport",
    "text-font": [
        "Open Sans Bold"
    ]
}

В отличие от CSS, MapLibre не умеет динамически превращать обычный шрифт в полужирный.

Если требуется жирное начертание, соответствующий набор глифов должен существовать на сервере.


Курсивные шрифты

Аналогичная ситуация наблюдается с курсивом.

Правильный вариант:

"text-font": [
    "Open Sans Italic"
]

Неправильный подход:

font-style: italic

Подобного свойства в стиле MapLibre не существует.


SDF-глифы

Для рендеринга текста MapLibre использует технологию Signed Distance Field (SDF).

Суть метода заключается в том, что вместо хранения готового изображения символа сохраняется информация о расстоянии до его границы.

Преимущества:

  • масштабирование без потери качества;
  • быстрое изменение размера текста;
  • аппаратное ускорение через GPU;
  • компактное хранение.

Схема:

Контур буквы
       ↓
SDF-представление
       ↓
Текстура GPU
       ↓
Отрисовка на карте

Отличия SDF от растровых шрифтов

Растровый подход:

Буква → PNG

Недостатки:

  • размытость при увеличении;
  • необходимость хранить множество размеров.

SDF-подход:

Буква → Distance Field

Преимущества:

  • один источник для любых масштабов;
  • чёткие границы;
  • меньший объём памяти.

Поддержка многоязычных карт

Крупные картографические проекты используют десятки тысяч символов.

Например:

English
Русский
العربية
中文
日本語
한국어

Хранение всего набора в одном файле было бы крайне неэффективным.

Поэтому MapLibre загружает только нужные диапазоны Unicode по мере необходимости.


Работа с кириллицей

Для отображения русского текста требуется наличие соответствующих глифов.

Пример:

"text-field": ["get", "name_ru"]

Если сервер содержит только латиницу:

0-255.pbf

русские подписи отображаться не будут.

Необходимы диапазоны, включающие кириллические символы.


Работа с китайскими иероглифами

Китайский язык содержит тысячи символов.

Загрузка полного набора может занимать десятки мегабайт.

Поэтому особенно важны:

  • разбиение по диапазонам;
  • кэширование;
  • отложенная загрузка.

MapLibre автоматически запрашивает только необходимые блоки Unicode.


Кэширование шрифтов

После загрузки PBF-файлы обычно сохраняются:

  • в памяти браузера;
  • в HTTP-кэше;
  • в сервис-воркерах (при наличии).

Повторные запросы выполняются значительно быстрее.

Пример заголовков сервера:

Cache-Control: public, max-age=31536000

Подобная настройка существенно ускоряет отображение карты.


Самостоятельный сервер шрифтов

Типичная структура каталогов:

fonts/
├── Open Sans Regular
│   ├── 0-255.pbf
│   ├── 256-511.pbf
│   └── ...
├── Open Sans Bold
│   ├── 0-255.pbf
│   └── ...

Настройка стиля:

{
  "glyphs": "https://myserver/fonts/{fontstack}/{range}.pbf"
}

После этого любые слои могут использовать доступные наборы глифов.


Ограничения веб-шрифтов

Разработчики, привыкшие к обычному CSS, часто пытаются использовать:

@font-face

или

font-family

для подписей карты.

Однако текст внутри MapLibre GL JS рендерится собственным графическим движком и не зависит от CSS-шрифтов страницы.

Следовательно:

@font-face {
    font-family: MyFont;
}

само по себе не делает шрифт доступным для карты.

Необходим соответствующий набор PBF-глифов.


Типичные проблемы со шрифтами

Отсутствуют подписи

Причины:

  • неверный URL glyphs;
  • сервер не отдаёт PBF-файлы;
  • ошибка CORS;
  • отсутствует нужный диапазон Unicode.

Отображаются квадраты

Причины:

  • отсутствуют нужные символы;
  • повреждены файлы глифов;
  • неправильно настроен fontstack.

Работает только латиница

Причины:

  • отсутствуют кириллические диапазоны;
  • сервер содержит неполный набор шрифтов;
  • используются только западноевропейские глифы.

Рекомендации по выбору шрифтов

Для картографических интерфейсов обычно предпочтительны:

  • читаемые гротески;
  • наличие нескольких начертаний;
  • хорошая поддержка Unicode;
  • наличие кириллицы;
  • оптимизированные PBF-наборы.

Наиболее распространённые варианты:

Open Sans
Noto Sans
Roboto
Arial Unicode MS

Особенно важна поддержка различных письменностей, если карта предназначена для международной аудитории.


Взаимосвязь шрифтов и стилей карты

Система шрифтов тесно связана со стилем MapLibre.

Компоненты работают совместно:

Style JSON
      ↓
glyphs URL
      ↓
fontstack
      ↓
PBF-глифы
      ↓
SDF-текстуры
      ↓
Отображение текста

По этой причине настройка шрифтов является не отдельной задачей оформления, а важной частью всей архитектуры картографического стиля.