Использование OpenType в Веб-Типографике

    Идея


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

    Для начала поясню что же такое OpenType и зачем он понадобился. По сути дела, ОТ — это технология, позволяющая поместить в обычный шрифт большое количество дополнительной информации. Например, можно добавлять альтернативные начертания для букв или цифр, определять лигатуры, делать «малые заглавные» буквы (капитель), ну и много чего еще. Причем, к сожалению, при обычной HTML верстке, большинство ОТ-фич задать нельзя, а браузеры даже те, что есть (например капитель — small caps ) поддерживают неправильно. Тем самым, в веб-типографике остается некий «вакуум», или поле для деятельности.

    Использование ОТ в самом тексте страницы на данный момент представляется мне плохой идеей. Во-первых, мало кто из пользователей имеет на компьютере шрифты, богатые ОТ-фичами. Во-вторых, непонятно как поисковые системы, например, будут распознавать все новые буквы — ведь если на странице вместо букв f и i стоит лигатура fi, поисковой системе нужно будет откуда-то узнать что это действительно лигатура. (Напомню что написать просто две буквы рядом и пометить блок как использующий лигатуры в HTML/CSS пока невозможно.)

    Я решил выбрать цель поскромнее — создание заголовков. Для этого я обозначил примерно следующие требования:
    • Заголовки должны использовать тот функционал ОТ, который я (пользователь) считаю нужным
    • Заголовки должны использовать мой шрифт, а не шрифт пользователя, даже если у пользователя нет этого шрифта в системе
    • Заголовки должны хорошо печататься и работать с функцией zoom браузера
    • Все замены обычной типографической подстановки должны работать (например (с) на ©)

    Реализация


    Для реализации я выбрал технологию SVG, и тем самым отсек большинство пользователей — тех, кто использует IE. Поскольку разработчики IE никаких подвижек в плане SVG не делают, для этого браузера просто выводится текст. Работает же это пока под Firefox и Opera, и хотя интернет продолжает кормить нас слухами что SVG в IE не за горами, пока, увы, приходиться делать fallback. А теперь собственно технические детали.

    Алгоритм рендеринга текста с ОТ фичами в SVG прост: нужно взять исходный текст, применить к нему все нужные ОТ фичи (включая кернинг, конечно же), перевести в векторный формат и записать его как SVG. А потом просто показывать пользователям.

    Для того, чтобы получить «начинку» ОТ файла, я написал свой парсер для OTF/TTF файлов. Парсер я написал как пару XML+XQuery которая на выходе сгенерировала C# код со всеми ОТ структурами, которые описаны в официальной спецификации. Полученная библиотечка просто «воткнулась» в мое ASP.NET приложение.

    Имея у себя парсер ОТ, я написал следующую часть системы: программу, которая берет текст, размеченный специальной разметкой ОТ (разметку придумывал сам, т.к. ничего аналогичного не нашел), и «применяет» все фичи к переданному ей тексту. Конечно весь функционал я не покрыл, т.к. это задача не одного дня, а решение хотелось получить быстро. Вот приблизительный список фич, для которых я сделал поддержку (ссылки ведут в Википедию):

    Далее, написал простенький код, который берет трансформированный текст и превращает его в SVG. Собственно код для вытаскивания векторных данных я не писал — воспользовался готовым объектом FormattedText из .NET 3.0 который помимо того что перевел текст в векторные формы, так еще и применил кернинг (правильное расстояние между буквами), тем самым освободив меня от собственноручной его реализации.

    Последний штрих — это помещение результата на страницу ASP.NET и создание интерфейса для использования. Для того, чтобы поисковые системы правильно находили заголовки, я добавляю в страницу как ссылку на SVG-файл, так и невидимый (display: none) заголовок в обычном HTML. Он же используется и для показа заголовка в браузерах вроде IE.

    Обсуждение


    Для того, чтобы показать результаты, я вывесил тестовую страничку. Сразу скажу — там достаточно сыроватая версия кода, и я все еще доделываю парсер, т.к. на данный момент он не умеет парсить абслолютно все ОТ файлы (у меня достаточно большой сампл для тестирования). А еще, моя система пока не умеет строить файлы из текста, в котором используется более одной гарнитуры — достаточно серьезный недостаток, который, к сожалению, непонятно как устанить без написания своего сборщика векторных данных.

    Главный недостаток моего подхода в целом — то, что все это не работает в IE. Другой недостаток — то, что это написано на C# под .NET 3.0 и тем самым не очень полезно для разработчиков, чей сервер использует, например, Apache. Хотя с другой стороны, сам парсер ОТ (это самая трудоемкая часть работы) был написан не на C# а на XML, так что портировать ее для другой системы не так уж сложно. Просто тогда придется еще и писать код, который сделает векторный рендеринг ОТ-текста и создаст из него SVG-файл, т.к. на данный момент я полагаюсь на специфический функционал .NET.

    Одной из нерешенных проблем остается рендеринг SVG в Google Chrome а также в IE с плагином от Adobe. Я подозреваю что проблема в том, что эти браузеры не могут распознать размер файла просто его прочитав и им нужно «помочь». Если так, то этот недостаток будет исправлен в ближайшем будущем.

    Update: пофиксил для Chrome и IE.

    И вот еще один disclaimer: я не типограф, поэтому использую слова вроде «шрифт» вместо «гарнитура», и возможно не совсем тонко оперирую типографическими терминами, за что прошу сообщество меня простить.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 38

      +1
      Красиво. Но вроде бы SVG позволяет выделять и копировать текст, а в Вашем примере мне это не удалось.
        0
        Насколько я понимаю, SVG позволяет это делать только в том случае, когда у Вас действительно объект типа «текст». Тут же совсем другое — произвольная векторная графика. Конечно, можно написать алгоритм выделения и для нее, но как мне кажется, это очень трудоемкая задача. И самое главное непонятно зачем — так ли часто требуется выбрать текст в заголовке?
          +1
          Например, скопировать текст вместе с заголовком, что бы что-то потом с ним сделать. Вставить в текстовый редактор, например. Сохранить в заметках вроде гугла. Отправить цитату по электронной почте, IM. А так, все заголовки и подзаголовки, оформленные вашим методом, пропадут =(
            0
            Где-то на Хабре был пост о преимуществах SVG и проблеме того, что он, указанный в W3C, игнорируется Майкрософтом.
            Одним из плюсов выделяли то, что, скажем, волнистый векторный текст, написанный с помошью SVG можно выделять так же, как обычный плоский.
            Простите за дилетанство, а разве лигатуры и прочее отсутствует в современных шрифтах, юникоде?
              0
              Ну возьмите например Georgia и откройте в CharMap, хотя бы. Лигатур — две (и еще неизвестно, прописана ли для них фича ОТ). Альтернативных букв — нуль. Oldstyle chars — нет. То же самое и в других популярных в интернете шрифтах.
                +1
                Oldstyle chars? Если вы об oldstyle figures, то в Georgia они как раз по дефолту минускульные.
                  +1
                  Вау! Действительно, это так.
                    0
                    Да, мне тоже очень нравится.
          +1
          О, да… пара мегабайт ради красивости…
            0
            Серьезно? Так много? Я-то думал, почему так долго грузится…
              0
              Да, это одна из проблем — просто некоторые шрифты настолько детально прорисовывают каждую букву, что количество деталей зашкаливает. Зато шрифты вроде Myriad должны идти на ура — там очень мало деталей.
                0
                Может быть есть смысл придумать оптимизатор чтобы уменьшать количество деталей.
            +1
            для ie5+ можно vml скрармливать
            а ещё может пригодится habrahabr.ru/blogs/webdev/22970/
              0
              и это… в svg файлы вроде как можно встраивать шрифты… также как и во флэш или pdf
              0
              А чем вам sIFR не угодил? novemberborn.net/sifr
                0
                Ну хотя бы тем что он не печатается (а точнее печатается, наверное, на 72dpi). И я не уверен что он поддерживает фичи ОТ.
                  0
                  Тем что это flash ;)
                  0
                  Лигатуры то как раз легко разбиваются, им соответствуют, если не ошибаюсь, вполне определённые Unicode-последовательности. Google Book Search лигатуры в книгах распознает на ура.
                    +2
                    «Swash» — «Вариации прописных с росчерками»
                    «Oldstyle numerals» — «Минускульные цифры»
                      0
                      И оно кагбэ слишком жестоко тормозит для реального решения, а не proof of concept. :(

                      А так интересно и огромное спасибо за начинание! Капля камень точит. ;)
                        0
                        Ну по идее гзиповаться должно хорошо, да и генерируется один раз на всех (потом складывается в кеш). Или вы какие-то другие тормоза имели в виду?
                          0
                          Картинка открывается секунд 15. Это сервер медленный, или решение?
                            0
                            Это скорее всего последствие того, что автор не сделал тех двух вещей, о которых я упомянул в своем комменте (гзип и кеш результатов).
                              0
                              Результаты кэшируются, а вот гзип я действительно не сделал — попробую, посмотрим что получится.
                        0
                        Похожую идею на флэше реализовали тут https://www.t-mobile.nl/Persoonlijk/htdocs/page/homepage.aspx
                        Обратите внимание на текст в верхних табах.
                        0
                        в хроме не работает
                          0
                          Респект! А Вы не планируете открыть свой парсер?

                          p.s. В Хроме 0.2.149.29 — работает.
                            0
                            Пофискил для хрома и IE. Решение получилось неэлегантное — для тегов приходится из SVG файла вытаскивать размеры.
                            0
                            Ещё есть @font-face, который поддерживается в webkit и opera,
                            также существует сборка gecko с его поддержкой,
                            так что, возможно, уже скоро можно будет использовать «собственные» шрифты
                              0
                              И для Internet Explorer есть подобная технология, только сделана не так как у всех, но работает.
                                0
                                Есть, называется EOT. Интересной особенностью (в отличие от того, что используется в webkit/opera) данного решения является то, что учитываются лицензионные ограничения, прописанные в самом файле шрифта — лицензия, по которой шрифт был предоставлен в пользование, может запрещать внедрение этого шрифта в документы и веб-страницы. Также внедренный шрифт привязывается к конкретным урлам, на которых его можно использовать — и не будет отображаться на других страницах.
                                  0
                                  DRM для шрифтов как всегда от MS)))
                                    0
                                    С лицензирование тут отдельная тема…
                                +1
                                Тут даже не в этом проблема. Лично мне хочется чтобы, например, ОТ фичи сами по себе применялись к обычному тексту. То есть в идеале я хотел бы чтобы браузеры поддерживали OpenType разметку + ClearType + Hinting. Пока об этом можно мечтать.
                                  0
                                  Хинтинг в дефолтных шрифтах и так есть.

                                  P.S. Делайте страницы в PDF ;)
                                0
                                А вы думали например о том чтобы генерировать для каждой буквы отдельный SVG элемент, так сказать создать SVG шрифт?
                                Таким образом можно кстати создать что-то наподобие sIFR только вместо Flash использовать SVG :)
                                  0
                                  Непрактично. Самому делать кернинг неохота. И все равно это не решает проблему больших размеров.

                                Only users with full accounts can post comments. Log in, please.