Firefox рендеринг шрифта OpenType не соответствует спецификации шрифта
Я загружаю веб-шрифт OpenType Open Sans
через Google Fonts API / CSS.
Как в Chrome 43 (Linux+Windows), так и в Internet Explorer 11 (Windows) браузер отображает текст в точности так, как указано в шрифте. Однако в Firefox 38.0.5 ширина текста и / или интервал отображаются для некоторых символов по-разному. Все варианты шрифтов имеют значение по умолчанию ("нормальный").
В качестве примера мы можем использовать символы 1
, a
, b
, а также i
, "SansPerEm" для Open Sans равен 2048. Следовательно, при размере шрифта 18,0 пикселей ширина 30 символов каждого из указанных выше символов должна быть следующей на основе 1/u * p * c * w, где u = 2048, p = 18,0, с = 30, а w - ширина продвижения каждого символа ( уравнение Вольфрама Альфа).
+ ---------------------------------------- + -------- --- + | символ | шрифт (px) | numChars | заранее | ширина (px) | +------+----------+----------+-----------+-----------+ | 1 | 18,0 | 30 | 1171 | 308,76 | | а | 18,0 | 30 | 1139 | 300,322 | | б | 18,0 | 30 | 1255 | 330,908 | | я | 18,0 | 30 | 518 | 136,582 | +----------------------------------------+-----------+
Это ( JSFiddle) использует метод canvas measureText
вывести ширину в пикселях по 30 символов каждого из 1
, a
, b
, а также i
,
Длина текста Chrome точно соответствует ожидаемым значениям:
Длина текста в Firefox Linux не соответствует ни одному из символов, кроме a
даже после учета того факта, что Firefox не обеспечивает субпиксельной точности:
Я подтвердил, что ширина, указанная в canvas, - это действительно то, что выводится как Chrome, так и Firefox - на следующем изображении показан красный фон с текстом Chrome в черном и текстом Firefox в белом - значения ширины соответствуют вышеприведенным в соответствии инструмент Gimp "Measure". Фирефокса b
а также i
слишком широк, и 1
слишком узкий
Кроме того, длина текста в Firefox Windows даже не соответствует Firefox Linux - a
а также b
ширина теперь, как и ожидалось, но 1
а также i
все еще неверны:
Это чистый профиль Firefox с настройками по умолчанию и без установленных расширений.
Может кто-нибудь объяснить, что происходит, и как заставить Firefox отображать шрифт в соответствии со спецификацией шрифта?
ОБНОВЛЕНИЕ: В Windows, настройка предпочтений gfx.font_rendering.directwrite.enabled
в true
устраняет проблему (которую я считаю Firefox по умолчанию, когда доступно аппаратное ускорение, этот параметр просто включает его, даже если аппаратное ускорение недоступно, например, в моей тестовой системе VMWare). DirectWrite используется по умолчанию в Chrome для Windows начиная с версии 37. Поведение Linux до сих пор не объяснено. Этот пост в блоге объясняет больше о визуализации DirectWrite в Firefox на Windows.
1 ответ
(Этот ответ суммирует основные вопросы, поднятые в комментариях к вопросу, а также ряд дополнительных исследований, проведенных после того, как вопрос был опубликован.)
По разным и сложным причинам не все комбинации размеров браузера / ОС / размера шрифта отображаются на экране одинаково и не всегда соответствуют спецификациям шрифта. Поэтому, как правило, приложения должны создаваться таким образом, чтобы не требовалось идеальное позиционирование текста.
Субпиксельная конфигурация рендеринга текста
Некоторые комментарии по настройке определенных комбинаций браузера / ОС для поддержки субпиксельного рендеринга текста:
Windows
- Браузеры, которые поддерживают и включают DirectWrite (в отличие от более старого метода GDI), как правило, поддерживают линейное, не намекаемое, субпиксельное позиционирование текста и, следовательно, способны (и обычно делают) следовать спецификациям ширины продвижения шрифта. Это включает в себя Chrome 37+ и Firefox 4+.
- Firefox отключает DirectWrite по умолчанию, когда аппаратное ускорение недоступно, но его можно включить, установив свойство config
gfx.font_rendering.directwrite.enabled
вtrue
, - Chrome 37+ DirectWrite включен по умолчанию, но его можно отключить, установив флаг
Disable DirectWrite
, - Internet Explorer (9+?) DirectWrite включен по умолчанию, но его можно отключить, установив режим совместимости.
- Firefox отключает DirectWrite по умолчанию, когда аппаратное ускорение недоступно, но его можно включить, установив свойство config
Linux
Сконфигурируйте свой дисплей для сглаживания и субпиксельного рендеринга текста, настроив fontconfig для субпиксельного рендеринга (обычно через настройки дисплеев Gnome или KDE, но это можно сделать вручную через конфигурационные файлы fontconfig), установив freetype-freeworld (freetype с не бесплатная поддержка рендеринга субпикселей) и добавление Xft.lcdfilter: lcddefault
в ~/.Xresources
для приложений без поддержки fontconfig. Установите правильный тип субпиксельного рендеринга в зависимости от типа вашего ЖК-дисплея.
- Поведение браузера кажется непоследовательным, даже если базовый дисплей поддерживает и настроен для субпиксельного рендеринга.
- Последние версии Chrome (44 протестированных), по-видимому, поддерживают линейное позиционирование текста без намеков на субпиксели и, следовательно, в целом соответствуют спецификациям шрифта. Протестировано на KDE 4.14 с поддержкой рендеринга субпиксельного текста RGB.
- Firefox (протестированный 38.0.5), по-видимому, выполняет нелинейное позиционирование с подсказками, поэтому не соответствует спецификациям шрифта, даже если дисплей настроен для субпиксельного рендеринга. Я не определил способ заставить Firefox использовать субпиксельный рендеринг текста.
Mac OS X
Информации для этой платформы пока нет.
Пиксельное идеальное позиционирование
Если, несмотря на трудности, создается приложение, которое требует точного позиционирования и проверки текста с точностью до пикселя, то обычно есть два способа сделать это:
1) Измерение ширины / высоты текста на основе холста или DOM: см. Расчет ширины текста с помощью JavaScript. Смотрите также Font.js Майка Камерманса (Pomax).
2) Использование OpenType.js для определения размеров текста из исходного шрифта, который работает быстрее, чем метод, описанный выше, но работает не во всех случаях.