Рендеринг текста что это
Война браузеров: рендеринг текста

Для этого теста мы пропустим через браузеры несколько страниц и посмотрим, какой из них лучше с ними справляется. Для тестирования использовалась машина с Windows XP без включенного ClearType. Все используемые для тестов страницы содержали XHTML 1.0 Strict Doctype. Так же нам необходимо определить требуемые результаты при тестировании рендеринга текста. Лучшим решением должен быть результат, предлагающий компромисс между размытыми и резкими краями. Чтобы быть читаемым текст должен иметь гладкие края, но в тоже время достаточно четкие.
Тест рендеринга заголовков
В первом тесте мы используем 6 заголовков HTML. Мы хотим увидеть как браузеры рендерят простейшие заголовки HTML без каких-либо CSS-стилей.
При рассмотрении H1 вы можете ясно видеть, что Safari использует слишком сильное размытие краев. Результат Internet Explorer, наоборот, выглядит не сглаженным. Chrome, Firefox и Opera имеют лучший результат. Касательно Chrome, мне не понравилось то, что, например, символы e и a имеют меньшую интенсивность по сравнению с результатом других браузеров. В результате, для H1 и H2 победителями становятся Opera и Firefox. При рассмотрении H3 у нас другой победитель — Internet Explorer. По сравнению с другими браузерам Internet Explorer предлагает более читаемый текст. Такого же результата Internet Explorer достиг и в остальных заголовках, где Opera, Firefox и Chrome показывают одинаковые результаты, а у Safari текст слишком размыт.
Тест амперсандом
Для определения лучших способностей рендеринга у бразуеров мы создали простой тест, основанный на символе амперсанда. Для теста был выбран амперсанд в силу того, что это сложный символ. В зависимости от шрифта, в композиции амперсанда присутствует горизонтальная, скругленная, скошенная и прямая линии.
В этом тесте абсолютный победитель — это Safari. Safari единственный браузер с исключительным рендерингом даже на значениях более 351px. Во всех других браузерах значения более 351px приводили к очень примитивному рендерингу с грубыми краями без сглаживания. В этом тесте у IE самые худшие показатели. Как вы можете убедиться, посмотрев на картинку, движок рендеринга не способен приемлемо отобразить символ.
Тест на блоке текста
Этот тест состоит из трех блоков текста с разными шрифтами. Мы использовали популярные шрифты Arial 13px, Verdana 13px and Georgia 15px.
В этом тесте очень просто определить победителя — это Internet Explorer. Его движок рендеринга наиболее сбалансированный в отображении разнообразных шрифтов. Даже для низких значений, вроде 13px, IE предлагает приятный эффект размытия. Вопреки всеобщему мнению, Safari убог [is lame] в рендеринге текста. Его движок отображает дополнительный вес в шрифтах, делая их тяжелее, ухудшая читаемость. Opera, Firefox и Chrome имеют схожее друг с другом поведение при отображении текста.
Заключение
Каждый браузер имеет свои недостатки и преимущества, но я бы не сказал, что все они одинаковы, напротив. Браузер, показавший себя лучшим в тестах рендеринга текста — это Internet Explorer. Заметно, что Microsoft возлагает надежды на свой продукт и его будущее. Молодцы! [Kudos!]
Второе место занимают Firefox и Opera, которые с небольшими различиями имеют примерно одинаковые способности в рендеринге. На третьем месте новичок Chrome. И на последнем месте в плане рендеринга текста — Safari.
Здесь вы можете почитать первую статью про используемые в тестировании браузеры.
Урок №45. Рендеринг текста в OpenGL
Обновл. 18 Дек 2020 |
В один прекрасный момент нашего необычайно интересного путешествия по миру графического программирования OpenGL, вам наверняка захочется отобразить какой-нибудь текст. На первый взгляд может показаться, что получить на экране компьютера самую обычную строку текста, используя низкоуровневое API (по типу OpenGL), — очень простая задача. На самом деле это не так. Ведь только представьте, вам придется позаботиться о рендеринге более 128 различных символов, которые имеют разную ширину, высоту и отступ. И что делать, если вдобавок вы захотите использовать специальные символы, а также символы музыкальных нот или математических выражений? А как насчет рендеринга текста сверху вниз?
Большинство разработчиков выбирают способ визуализации текстуры символов на плоский прямоугольник. Рендеринг текстурированных прямоугольников сам по себе не должен быть слишком сложным процессом, но вот сопоставление соответствующего символа(ов) с текстурой — может оказаться задачей непростой. На этом уроке мы рассмотрим несколько методов рендеринга текста и реализуем более продвинутую, но гибкую технику его визуализации с помощью библиотеки FreeType.
Растровые шрифты
В прежние времена рендеринг текста включал в себя выбор шрифта (или самостоятельное его создание), который вы хотели бы использовать для своего приложения, и извлечение из этого шрифта всех соответствующих символов, чтобы поместить их в одну большую текстуру. Такая текстура называется растровым шрифтом, и содержит в своих строго заданных областях все символы, которые нам могут потребоваться. Символы, входящие в состав такого шрифта, называют глифами (англ. «glyphs»). Каждый глиф расположен в определенной области связанной со шрифтом текстуры. Всякий раз, когда вы хотите визуализировать символ, вы производите выборку соответствующего глифа и визуализируете на плоский прямоугольник нужную секцию растрового шрифта.
На вышеприведенной картинке вы можете увидеть, как мы будем визуализировать слово OpenGL поверх нескольких прямоугольников, используя растровый шрифт и выборку соответствующих глифов из текстуры (тщательно подбирая необходимые координаты). Включив режим смешивания и сохраняя фон прозрачным, мы получим строку символов, отображаемых на экране. Данный растровый шрифт был сгенерирован с помощью программы Font Generator.
Такой подход имеет ряд преимуществ и недостатков. Его относительно легко реализовать, поскольку растровые шрифты уже предварительно растеризованы. Однако он не отличается особой гибкостью. Если вы хотите использовать другой шрифт, вам нужно будет полностью перекомпилировать новый растровый шрифт, и при этом ваша программа будет ограничена только одним разрешением шрифта; масштабирование быстро приведет к появлению некрасивых пиксельных краев. Кроме того, шрифт может содержать лишь ограниченный набор символов, а значит, об отображении расширенных или Unicode-символов часто не может быть и речи.
Описываемый подход был довольно популярен в свое время, так как он быстр и работает на любой платформе, но на сегодняшний день существуют более гибкие методы. Одним из них является загрузка TrueType-шрифтов с помощью библиотеки FreeType.
Библиотека FreeType
Библиотека FreeType — это библиотека, которая используется для растеризации шрифтов и операций над ними. Она используется в таких продуктах, как: macOS, Java, PlayStation, Linux и Android. Что делает FreeType особенно привлекательным, так это то, что она способна загружать TrueType-шрифты.
TrueType-шрифт — это набор глифов, определяемых не пикселями или любым другим немасштабируемым решением, а математическими уравнениями (комбинацией сплайнов). Подобно векторным изображениям, растеризованные изображения шрифтов могут быть сгенерированы процедурно на основе задаваемой вами высоты шрифта. Используя TrueType-шрифты, вы можете с легкостью визуализировать глифы символов самых разных размеров без какой-либо потери качества.
Библиотека FreeType доступна на сайте разработчиков. Вы можете скомпилировать библиотеку самостоятельно или использовать одну из уже предварительно скомпилированных версий под различные целевые платформы. Обязательно прилинкуйте к вашему проекту файл библиотеки freetype.lib и убедитесь, что ваш компилятор знает, где найти соответствующие заголовочные файлы.
Затем нужно подключить в проекте необходимые заголовочные файлы:
рендеринг текста в css, что это? и как им пользоваться?
Я читал статью о text-rendering в css.
Согласно этому блогу:
В text-rendering Свойство в CSS позволяет вам выбирать качество текста, а не скорость (или наоборот), позволяя точно настроить оптимизацию, предлагая браузеру, как он должен отображать текст на экране. Он предоставляет механизму рендеринга информацию о том, что нужно оптимизировать при рендеринге текста. Браузер делает компромисс между скоростью, удобочитаемостью и геометрической точностью.
Кроме того, теперь это полезно для целей оптимизации для уменьшения времени загрузки страницы, как упоминалось там. Но некоторые термины сбили меня с толку, пока я читал эту статью, и я подумал, что здесь эксперты разработают эти термины для лучшего понимания. Итак, вот эти термины:
Что подразумевается под рендерингом? как это делается (применительно к CSS)?
Что такое разборчивость?
Также, за исключением IE, все браузеры поддерживают это свойство, поэтому у 81,0% пользователей мира не будет проблем с его использованием. Вот почему я задаю этот вопрос, чтобы прояснить понимание этих концепций.
Что подразумевается под рендерингом? как это делается (применительно к CSS)?
Я бы сказал, что «рендеринг» примерно соответствует инструкциям о том, что должен быть и материализовать его во что-то осязаемое (в данном случае в пиксели на дисплее).
Когда речь идет о веб-браузере, «рендеринг» включает в себя гораздо больше, чем текст. Рендеринг состоит из множества компонентов и этапов.
Рендеринг текста влияет на макет (ширина, высота, перенос строк и т.д.) и влияет на рисование («нарисуйте эти пиксели и / или эту строку»).
Что отображает текст?
Вот интересная цитата команды IE, которая объясняет, как этот процесс выполняется в IE9 +:
Это общая тема для большинства (всех?) Браузеров: они передают заключительный этап (ы) рендеринга текста нижележащему слою, который находится ближе к самому устройству.
Например, Webkit использует GraphicContext абстракция, чтобы поговорить с ОС. (Отличный разговор о рендеринге в WebKit). Каждая ОС может иметь разные реализации. И каждый порт WebKit может отличаться.
Это не означает, что движок рендеринга не может давать подробные подсказки / инструкции слоям, находящимся под ним. Это делает означают, что результаты будут отличаться в зависимости от оборудования, ОС, браузера и шрифтов.
Разборчивость
Это согласуется с описанием optimizeLegibility :
Браузер делает упор на удобочитаемость, а не на скорость рендеринга и геометрическую точность. Это позволяет использовать кернинг и дополнительные лигатуры.
Другими словами, браузер (через механизм рендеринга) может предпринять дополнительные шаги для отображения текста таким образом, чтобы его было легче читать и / или было лучше визуально.
Он может использовать дополнительную информацию о лигатуре, содержащуюся в шрифте, и может регулировать интервал между буквами (кернинг).
Отличия
Может ли кто-нибудь отличаться между optimizeLegibility и optimizeSpeed?
Качество (разборчивость) по сравнению с количеством (скорость, то есть количество символов, отображаемых за определенный период времени).
optimizeSpeed: При рисовании текста браузер делает упор на скорость визуализации, а не на удобочитаемость и геометрическую точность. Отключает кернинг и лигатуры.
optimizeLegibility: Браузер делает упор на удобочитаемость, а не на скорость рендеринга и геометрическую точность. Это позволяет использовать кернинг и дополнительные лигатуры.
Как и где следует использовать каждый из них или оба?
Следует использовать только один из них (если есть). Лично я бы только уточнил text-rendering увидев, что это оказало положительное влияние а также хорошо себя ведет на всех устройствах (что является непростой задачей).
Кроме того, все браузеры, кроме IE, поддерживают это свойство, поэтому у 81,0% людей в мире не будет проблем с его использованием.
Думаю, это заявление может быть излишне оптимистичным. Также не стоит сбрасывать со счетов Internet Explorer, который часто очень хорошо отображает текст из-за тесной интеграции с оборудованием.
Рендеринг текста вас ненавидит
Рендеринг текста: насколько сложным он может быть? Оказывается, невероятно сложным! Насколько мне известно, буквально ни одна система не выводит текст «идеально». Где-то лучше, где-то хуже.
Предположим, вы хотите произвольный текст с произвольными шрифтами, цветами и стилями, с переносом строк и поддержкой выделения текста. По сути, это минимальные требования для правильного отображения сложного текста, окна терминала, веб-страницы и т. д.
В общем, сразу скажем: здесь нет последовательных правильных ответов, всё намного важнее, чем вы думаете, и всё влияет на всё остальное.
Мы обсудим темы, которые не объединяются в рамках какой-то единой концепции, это просто вопросы, с которыми мне пришлось столкнуться за несколько лет работы над рендерингом текста в Firefox. Например, не будем слишком подробно обсуждать проблемы сегментации текста или управления различными текстовыми библиотеками для конкретной платформы, поскольку этим я не слишком интересуюсь.
1. Терминология
Природа текста сложна, и английский плохо передаёт все нюансы. Для настоящего документа я постараюсь придерживаться следующих терминов. Обратите внимание, что эти слова не являются «правильными», я просто считаю их полезными для передачи ключевых понятий носителям английского языка, которые не имеют опыта в лингвистике.
2. Стиль, вёрстка и форма зависят друг от друга?
Для представления, как работает типичный конвейер отрисовки текста, вот краткая схема:
Большинство шрифтов на самом деле не выдают по требованию все возможные глифы. Глифов слишком много, поэтому шрифты обычно реализуют только определённое письмо. Конечные пользователи обычно не знают или не заботятся об этом, поэтому надёжная система должна каскадировать в другие шрифты, если символы недоступны.
Например, несмотря на то, что разметка следующего текста не предполагает наличия нескольких шрифтов, но это необходимо для правильного рендеринга на любой системе: hello मनी ب بسم 好. Так мы опасно приближаемся к тому, что шаг 1 (стилизация) начинает зависеть от шага 3 (придание формы)!
(Как вариант, можете принять подход Noto и использовать один шрифт Uber, который содержит все символы. Хотя тогда пользователи не смогут настроить шрифт, а вы не сможете предоставить «нативный» текстовый интерфейс пользователям на всех платформах. Но предположим, что вам нужно более надёжное решение).
Аналогично, для вёрстки нужно знать, сколько места занимает каждый фрагмент текста, но это становится известно только после шейпинга! Шаг 2 зависит от результатов шага 3?
Но для придания формы нужно знать вёрстку и стиль, так что мы, кажется, застряли. Что же делать?
Во-первых, стилизация применяет читы. Хотя мы на самом деле хотим получить полные глифы, для стилизации достаточно скаляров. Если шрифт не поддерживает письменность должным образом, он не будет заявлять, что знает что-либо о скалярах этой письменности. Таким образом, можно легко найти «лучший» шрифт следующим образом:
Для каждого символа (EGC) в нашем тексте опрашиваем каждый шрифт в списке (каскаде), известны ли ему все скаляры, составляющие этот символ. Если да — используем их. Если мы доберёмся до конца списка без результата, то получим тофу (, индикатор отсутствующего глифа).
Вероятно, вы уже видели такой индикатор при встрече с эмодзи! Поскольку некоторые эмодзи на самом деле являются лигатурами нескольких более простых эмодзи, шрифт может сообщить о поддержке символа, выдав только отдельные компоненты. Таким образом, может буквально выглядеть как
, если шрифт «слишком стар», чтобы знать о новой лигатуре. Это также может произойти, если у вас «слишком старая» реализация Юникода, которая не знает о новом символе, заставляя систему стилей принять такое частичное совпадение.
Итак, теперь мы точно знаем, какие шрифты будем использовать, без необходимости обращаться к вёрстке или форме (хотя шейпинг может изменить наши цвета, подробнее об этом в последующих разделах). Можем ли мы аналогично разобраться со взаимозависимостью вёрстки и формы? Нет! Такие вещи, как разрывы абзацев, дают жёсткий разрыв по строкам, но единственный способ придать форму — это итеративный шейпинг!
Нужно предположить, что текст помещается на одной строке, и формировать эту строку, пока не закончится пространство. В этот момент можете выполнить операции вёрстки и выяснить, где разбить текст и начать следующую строку. Повторяйте, пока всё не будет свёрстано.
3. Текст — это не отдельные символы
Если судить только по английскому, то вы можете подумать, что лигатуры — какая-то причудливая ерунда. Я имею в виду, кого действительно волнует, что «æ» пишется как «ae»? Но оказывается, что некоторые языки по сути целиком состоят из лигатур. Например, «ड् ب بسم» состоит из отдельных символов «ड् ب ب س م». В любой продвинутой системе визуализации текста (то есть в любом из основных браузеров), эти две строки будут выглядеть очень по-разному.
И нет: речь не о разнице между скалярами Юникода и кластерами расширенных графем. Если вы попросите надёжную юникодовую систему (например, Swift) выдать кластеры расширенных графем этой строки, она выдаст эти пять символов!
Форма символа зависит от соседей: текст невозможно правильно вывести символ за символом.
То есть вы должны использовать библиотеку форм (shaping library). Отраслевым стандартом здесь является HarfBuzz, и эти задачи чрезвычайно трудно решить самостоятельно. Так что используйте HarfBuzz.
3.1. Наложения текста
В рукописных шрифтах глифы часто перекрываются, чтобы избежать швов, и это может вызвать проблемы.
Давайте ещё раз взглянем на «मनी م منش». Вроде, выглядит нормально? Теперь увеличим:
Всё ещё кажется прекрасным, но сделаем текст частично прозрачным. Если вы на Safari или Edge, то текст может выглядеть нормально! Но на Firefox или Chrome вид ужасный:
Проблема в том, что Chrome и Firefox пытаются схитрить. Они правильно формировали текст, но как только встречают такие глифы, то по-прежнему пытаются нарисовать их по отдельности. Обычно это работает нормально, за исключением случаев, когда есть прозрачность и перекрытия, на которых получаются такие затемнения.
«Корректная» реализация выведет текст на временную поверхность без прозрачности, а затем — на сцену с прозрачностью. Firefox и Chrome этого не делают, потому что это дорого и обычно не нужно для основных западных языков. Интересно, что они действительно понимают проблему, потому что специально обрабатывают такой сценарий для эмодзи (но мы вернёмся к этому позже).
3.2. Стиль может изменить лигатуру
Ладно, этот пример мы разбираем в основном из любопытства, как может сломаться разметка, хотя я не знаю каких-то разумных сценариев, где это может реально навредить. Вот два фрагмента текста с одинаковым содержанием, но разным цветовым оформлением:
Вот как они выглядят в Safari:
Так они выглядят в Chrome (при использовании его новой реализации макетирования):
И вот они в Firefox:
Он просто разделил эту лигатуру на четыре равные части с разными цветами!
Проблема в том, что на самом деле нет разумного ответа, как здесь следует поступать. Мы разделили лигатуру на разные стили, и поскольку лигатура в некотором смысле является «единицей» рендеринга, разумно просто отказаться от поддержки такого разделения (как и делает большинство).
По какой-то причине, кто-то в Firefox с настоящим энтузиазмом взялся сделать более изящную реализацию. Его подход заключается в том, чтобы отрисовать лигатуру несколько раз с оптимальными масками и разными цветами, что работает на удивление хорошо!
Есть некоторый смысл в попытке поддерживать эти «частичные лигатуры»: только шейпинг может знать, будет ли выводиться конкретная лигатура, и это зависит от системных шрифтов, поэтому лигатура может появиться там, где её никто не ожидал! Классический англоязычный пример — лигатура æ из установленного пользователем шрифта на границе гиперссылки.
Также довольно странно, что английский может из мени ть сти ль посреди слова, а рукописные шрифты не могут?
Даже не спрашивайте о коде, который ломает строки с частичными лигатурами.
4. Эмодзи ломают цвет и стиль
Если вы отображаете эмодзи так, как это делает родная система, то нужно игнорировать настройки цвета текста (за исключением прозрачности):
Обычно у эмодзи собственные родные цвета, и у этого цвета может быть даже семантическое значение, как в случае модификаторов цвета кожи. Более того: у них может быть несколько цветов!
Насколько я могу судить, до эмодзи такой проблемы не существовало, поэтому разные платформы подходят к решению по-разному. Некоторые показывают эмодзи цельной картинкой (Apple), другие — в виде серии одноцветных слоёв (Microsoft).
Последний подход неплохой, потому что он хорошо интегрируется с существующими конвейерами рендеринга текста, «просто» разбивая глиф на серию одноцветных глифов, с которыми все привыкли работать.
Однако это означает, что при рисовании «одного» глифа у вас может неоднократно изменяться стиль. Это также означает, что «один» глиф может перекрывать сам себя, что приводит к проблемам с прозрачностью, упомянутым в предыдущем разделе. И всё же браузеры действительно правильно сочетают прозрачность слоёв в эмодзи!
Это несоответствие можно объяснить тремя способами:
И ещё, как выделить смайлик курсивом или жирным? Игнорировать эти стили? Стоит ли их синтезировать? Кто знает…
Кроме того, разве эти эмодзи не кажутся странно маленькими?
Да, по какой-то причине куча систем тайно увеличивает размер шрифта для эмодзи, чтобы они выглядели лучше.
5. Сглаживание — это ад
Символы в тексте очень маленькие и детализированные. Очень важно, чтобы текст легко читался. Звучит как задача для сглаживания! Чёрт, а ведь 480p это действительно низкое разрешение. Ещё больше сглаживания.
Итак, есть два основных вида:
Термин «оттенки серого» используется для одномерного цвета, как и наша одномерная прозрачность (в противном случае глифы выводятся одним сплошным цветом). Кроме того, в типичной ситуации чёрного текста на белом фоне сглаживание буквально отображает серые оттенки по краям.
Субпиксельное сглаживание — это трюк, который злоупотребляет обычным размещением пикселей на мониторах. Он гораздо сложнее, так что если вам действительно интересно, то придётся почитать более подробную документацию, здесь же просто краткое описание концепции высокого уровня.
Пиксели вашего монитора на самом деле представляют собой три маленьких столбца красного, зелёного и синего цвета. Если вы хотите получить красный вы как бы указываете «белый чёрный чёрный». Точно так же, если хотите получить синий цвет, то указываете «чёрный чёрный белый». Другими словами, если повозиться с цветами, то можно утроить горизонтальное разрешение и получить гораздо больше деталей!
Вы можете подумать, что такая «радуга» будет очень некрасивой, но на практике система работает довольно хорошо (хотя некоторые с этим не согласны). Человеческий мозг любит распознавать закономерности и сглаживать их. Тем не менее, если сделать скриншот текста с субпиксельным сглаживанием, вы хорошо увидите все лишние цвета, если измените размер изображения или просто посмотрите на него на мониторе с другим субпиксельным макетом. Вот почему скриншоты с текстом часто выглядят очень странно и плохо.
(В целом эта система также означает, что цвет пиктограммы может случайно изменить её воспринимаемый размер и положение, что действительно раздражает).
Таким образом, субпиксельное сглаживание — это реально чистый хак, который может значительно улучшить разборчивость текста, отлично! Но, к сожалению, это ещё и огромная заноза в заднице!
Обратите внимание, что в любой системе сглаживания происходят субпиксельные смещения глифа. Вы всегда хотите, чтобы ваши растеризованные глифы были привязаны к полным пикселям, но сама растеризация предназначена для определённого субпиксельного смещения (значение между 0 и 1).
Чтобы понять это, представьте чёрный квадрат 1×1 со сглаживанием в оттенках серого:
5.1. Субпиксельные смещения ломают кэш глифов
Растеризация глифов требует удивительно много вычислений, поэтому гораздо лучше кэшировать их в текстурном атласе. Но как кэшировать текстуры с субпиксельными смещениями? У каждого смещения собственная уникальная растеризация!
Здесь нужно искать компромисс между качеством и производительностью, и это можно сделать за счёт оптимизации субпиксельных смещений. Для английского текста разумным балансом будет отсутствие вертикальной субпиксельной точности с привязкой горизонтального смещения к четверти целого числа. Это оставляет всего четыре субпиксельных позиции, что по-прежнему сильно улучшает качество, сохраняя разумный размер кэша.
5.2. Субпиксели сглаживания не могут быть составными
Одна приятная особенность сглаживания в оттенках серого в том, что вы можете свободно с ним играться, и он изящно деградирует. Например, если преобразовать текстуру с текстом (масштабирование, поворот или трансформация), он может стать немного размытым, но будет выглядеть в целом нормально.
Если вы сделаете то же самое с субпиксельным сглаживанием, это будет выглядеть ужасно. Вся его идея заключается в манипуляциях с пикселями на дисплее. Если пиксели дисплея не совпадают с пикселями вашей текстуры, то красные и синие края будут хорошо видны!
Можно подумать, что это «исправляется» просто новой растеризацией глифа в новом местоположении. И действительно, если преобразование является статическим, это может сработать. Но если преобразование является анимацией, получится ещё хуже. Это на самом деле очень распространённая ошибка браузера: если он не обнаружил, что анимация происходит с текстом, то символы будут дёргаться, поскольку каждый глиф перескакивает между различными субпиксельными привязками с хинтингом на каждом кадре.
В результате, браузеры содержат несколько эвристик для обнаружения таких анимаций, чтобы принудительно отключать субпиксельное сглаживание для этой части страницы (и в идеале даже субпиксельное позиционирование). Это довольно сложно надёжно реализовать, потому что анимацию может запустить сколь угодно сложный JS, не давая браузеру никаких чётких «подсказок».
Кроме того, субпиксельное сглаживание сложно использовать при наличии частичной прозрачности. По сути, здесь мы настраиваем наши каналы R, G и B для кодирования трёх значений прозрачности (по одному для каждого субпикселя), но у самого текста тоже есть цвет, и у фона, так что информация легко теряется.
При использовании сглаживания в оттенках серого у нас есть выделенный альфа-канал, поэтому ничего не теряется. Таким образом, для работы с полупрозрачными объектами браузеры обычно используют оттенки серого.
…Кроме Firefox. Опять же, в этой странной организации кто-то действительно увлёкся и сделал нечто сложное: альфа-компонент. Оказывается, вы можете на самом деле правильно составить текст с субпиксельным сглаживанием, но это требует трёх дополнительных каналов прозрачности для R, G и B. Неудивительно, что такое сглаживание удваивает расход памяти.
К счастью, с годами субпиксельное сглаживание стало менее актуальным:
6. Эзотерика
Эта часть — просто набор мелочей, которые не заслуживают особого обсуждения.
6.1. Шрифты могут содержать SVG
Вот же отстой. Эти шрифты в основном предоставляются Adobe, потому что некоторое время назад они хорошенько вляпались в SVG. Иногда вы можете просто игнорировать части SVG (я считаю, что шрифт Source Code Pro технически содержит некоторые глифы SVG, но на практике они фактически не используются веб-сайтами), но в целом придётся реализовать поддержку SVG, чтобы формально поддерживать все шрифты.
А ещё вы слышали об анимированных шрифтах SVG? Нет? Хорошо. Думаю, что они везде или сломаны, или не реализованы (Firefox случайно поддерживал их некоторое время из-за какого-то разработчика-энтузиаста).
6.2. Символы могут быть чертовски большими
Если вы захотите наивно удовлетворить запрос пользователя на очень большой шрифт (или очень большой уровень масштабирования), то столкнётесь с чрезвычайными проблемами управления памятью для атласа глифов такого размера, поскольку каждый символ может быть больше, чем весь экран. Есть несколько способов справиться с этим:
6.3. Выделение — это не рамка, а текст идёт во всех направлениях
Люди обычно знают, что основное направление текста может быть слева направо (английский), справа налево (арабский) или сверху вниз (японский).
Итак, вот вам забавный текст:
Всем привет بسم الله لا бип бип!!
Если на десктопе выделить текст мышью слева направо, то выделение становится прерывистым и как-то странно дёргается посередине. Это потому, что мы смешиваем в одной строке текст слева направо и справа налево, что происходит постоянно.
Сначала выделение в правую сторону увеличивает выделение, но затем уменьшает его, пока оно внезапно не начнёт увеличиваться снова. Это на самом деле совершенно правильно: выделение просто остаётся непрерывным в фактической строке. Таким образом, вы можете корректно скопировать фрагмент текста.
Нужно учитывать это в своём коде для выделения текста, а также в алгоритме разрыва строк при вёрстке.
Но это ещё не всё.
Надеюсь, вам не придётся иметь дело с такими вещами.
6.4. Как написать то, что невозможно написать?
Когда в шрифте отсутствуют символы, хорошо бы сообщить пользователю об этом. Для этого и предназначен глиф «тофу». Вы можете просто нарисовать пустой тофу (прямоугольник) и тем ограничиться. Но если хотите сообщить действительно полезную информацию, то можете записать значение отсутствующего символа для упрощения отладки.
Но подождите, мы используем текст, чтобы объяснить, что не можем вывести текст? Хм.
Вы можете сказать, что в системе должен быть базовый шрифт, который всегда покажет символы 0-9 и A-F, но это предположение для слабаков. Если пользователь действительно уничтожил свои инструменты с помощью своих инструментов, то Firefox предлагает выход: микрошрифт!
Внутри Firefox есть небольшой жёстко закодированный массив однобитного пиксель-арта с крошечным атласом именно этих 16 символов. Так что при рисовании тофу он может переслать эти символы, не беспокоясь о шрифтах.
6.5. Стиль является частью шрифта (за исключением случаев, когда это не так)
Высококачественные шрифты изначально идут в комплекте со стилями, такими как курсив и полужирный, поскольку нет простого алгоритмического способа красиво вывести эти эффекты.
Однако некоторые шрифты идут без этих стилей, поэтому всё-таки нужен простой алгоритмический способ сделать эти эффекты.
Точное обнаружение и обработка стилей сильно зависит от системы и вне моей области знаний, поэтому я не могу это хорошо объяснить. Я бы просто покопался в коде обработки шрифтов в Webrender.
В любом случае, нужен синтетический запасной вариант. К счастью, реализация на самом деле довольно проста:
Синтетический курсив: наклонить каждый глиф.
Синтетический полужирный: отрисовать каждый глиф несколько раз с небольшим смещением в направлении текста.
Честно говоря, эти подходы довольно неплохо справляются! Но пользователи могут заметить, что всё кажется «неправильным». Поэтому можно сделать лучше, если приложить усилия.
6.6. Нет идеального текстового рендеринга
У каждой платформы настолько долго были свои ошибки, оптимизации и причуды, что они стали эстетикой. Поэтому, даже если вы твёрдо верите, что определённые вещи идеальны или важны, всегда найдётся огромная группа пользователей с другими предпочтениями. Надёжная система визуализации текста поддерживает эти различные предпочтения (при выборе разумных значений по умолчанию).
Ваши конфигурации должны учитывать систему пользователя, конкретные шрифты, конкретные приложения и конкретные тексты. Вы также должны попытаться соответствовать нативному «внешнему виду» каждой платформы (такие причуды).
Это включает в себя:
7. Дополнительные ссылки
Вот ещё несколько статей о кошмаре текстового рендеринга:

