Поиск

Алгоритм сопоставления шрифтов

Рассматриваемый в данной спецификации алгоритм является расширением своего аналога, изложенного в описании CSS1. Если в таблицах стилей разработчика и читателя нет ни одного правила @font-face, то этот алгоритм сводится к своему предшественнику из CSS1.

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

  1. Пользовательский агент создает (или использует) базу данных соответствующих дескрипторов начертаний всех известных ему шрифтов. Если найдутся два шрифта с абсолютно одинаковыми дескрипторами, то один из них игнорируется. Информация о шрифте доступна пользовательскому агенту, если:
    • шрифт установлен локально;
    • шрифт объявлен с использованием правила @font-face в одной из таблиц стилей, содержащейся в текущем документе или присоединенной к нему;
    • шрифт используется в таблице стилей, применяемой пользовательским агентом по умолчанию. Концептуально она существует во всех пользовательских агентах и содержит полностью определенные правила @font-face для всех шрифтов, которые пользовательский агент будет использовать по умолчанию, а также правила @font-face для пяти специальных общедоступных гарнитур шрифтов (см. 'font-family'), определенных в CSS2
  2. Для заданного элемента и каждого содержащегося в нем символа пользовательский агент находит все применяемые к ним свойства шрифтов. На основании полного набора всех этих свойств пользовательский агент выбирает предполагаемую гарнитуру шрифтов, используя дескриптор 'font-family'. Таким образом, сопоставление по названию гарнитуры осуществляется раньше сопоставления любого другого дескриптора. Остальные свойства анализируются, исходя из типа гарнитуры, в соответствии с критериями, описываемыми каждым дескриптором отдельно. Если для всех этих свойств сопоставление осуществится, то найденное начертание шрифта оказывается тем самым, которое необходимо для данного элемента.
  3. Если в рамках гарнитуры 'font-family' на втором шаге не было найдено адекватного начертания шрифта, то для определения другой предполагаемой гарнитуры шрифта пользовательский агент, осуществляющий интеллектуальное соответствие, может воспользоваться другими дескрипторами, такими, как высота строчных букв, значение ширины глифов и panose-1. Если после этого все остальные дескрипторы будут адекватно сопоставлены, то найденное начертание шрифта оказывается тем самым, которое необходимо для данного элемента. Значение дескриптора 'font-family', отраженного в свойствах CSS2, выступает в роли названия запрашиваемой гарнитуры шрифта. Его не следует путать с произвольным названием, которое может иметь интеллектуально сопоставленный шрифт. Предполагается, что пользовательские агенты, не поддерживающие интеллектуальное сопоставление, не смогут выполнить этот шаг.
  4. Если в рамках гарнитуры 'font-family' на третьем шаге не было найдено адекватного начертания шрифта, то для определения доступного сетевого ресурса, обладающего корректным форматом, пользовательский агент, осуществляющий загрузку шрифта из сети, может воспользоваться дескриптором 'src' предполагаемого начертания шрифта, определенного на втором или третьем шаге. Если все остальные дескрипторы будут адекватно сопоставлены, то найденное начертание шрифта оказывается тем самым, которое необходимо для данного элемента, и пользовательский агент может попытаться загрузить ресурс этого шрифта. Пользовательский агент может заблокировать загрузку или перейти к следующему шагу во время загрузки шрифта. Предполагается, что любая из причин: пользовательский агент не осуществляет загрузку шрифтов или не подключен к сети, в настройках пользователя заблокирована загрузка шрифта, по какой-то причине необходимый ресурс недоступен или загруженный шрифт не удается использовать - приводит к тому, что пользовательский агент не сможет выполнить этот шаг.
  5. Если в рамках гарнитуры 'font-family' на третьем шаге не было найдено адекватного начертания шрифта, то для определения другой предполагаемой гарнитуры шрифта, которая затем будет синтезирована, пользовательский агент, осуществляющий синтез шрифта, может воспользоваться другими дескрипторами, такими, как 'x-height', значение ширины глифов и 'panose-1'. Если все остальные дескрипторы будут адекватно сопоставлены, то найденное начертание шрифта оказывается тем самым, которое необходимо для данного элемента, и пользовательский агент может приступить к синтезу подстановочного шрифта. Предполагается, что пользовательские агенты, не поддерживающие синтез шрифта, не смогут выполнить этот шаг.
  6. Если не удалось выполнить третий, четвертый и пятый шаги и в наборе шрифтов существует альтернативное значение дескриптора 'font-family', то для него осуществляется повторное выполнение всех предыдущих шагов, начиная со второго.
  7. Если необходимое начертание шрифта было найдено, но оно не содержит глиф(ы) для текущего символа(ов), и если в наборе шрифтов существует альтернативное значение дескриптора 'font-family', то для него осуществляется повторное выполнение всех предыдущих шагов, начиная со второго. Использование дескриптора 'unicode-range' позволяет быстро исключить из рассмотрения те начертания шрифтов, которые не содержат корректных глифов. Если дескриптор 'unicode-range' указывает, что в шрифте содержится несколько глифов из корректного диапазона, то пользовательский агент может проверить его на предмет существования в нем конкретного символа.
  8. Если в гарнитуре, выбранной на втором шаге, не существует ни одного шрифта, то используется наследуемое или определяемое пользовательским агентом значение дескриптора 'font-family', вместе с которым осуществляется повторное выполнение всех предыдущих шагов, начиная со второго. При этом используется наилучшее сопоставление, которое может быть получено для данного шрифта. Если с его помощью не удается отобразить некоторый символ, то пользовательский агент должен сигнализировать о невозможности вывода данного символа (например, посредством использования глифа недостающего символа).
  9. Пользовательские агенты, поддерживающие динамическое отображение и осуществляющие на данный момент загрузку шрифта, могут использовать его в качесвте гарнитуры, как только он будет успешно загружен. Символы, для которых в загруженном шрифте отсутствуют глифы, продолжают отображаться с помощью временного шрифта, содержащего требующиеся глифы.

Примечание. Представленный выше алгоритм может быть оптимизирован, во избежание повторной проверки свойств CSS2 для каждого символа в отдельности.

Правила сопоставления дескрипторов, используемые на втором шаге вышеприведенного алгоритма:

  1. Дескриптор 'font-style' проверяется первым. Курсив будет удовлетворять требованиям, если в базе данных шрифтов пользовательского агента имеется шрифт, помеченный ключевым словом 'italic' (предпочтительнее) или 'oblique'. В противном случае, необходимо потребовать точного совпадения значений или отказаться от сопоставления данного дескриптора.
  2. Затем проверяется дескриптор 'font-variant'. Нормальное начертание сопоставляется шрифту, не помеченному как 'small-caps'; капитель сопоставляется (1) шрифту, помеченному как 'small-caps', (2) шрифту, в котором возможен синтез капители, или (3) шрифту, в котором все строчные буквы заменяются прописными. Капитель может быть синтезирована электронным образом путем масштабирования прописных букв нормального начертания шрифта.
  3. Затем проверяется дескриптор 'font-weight'. Он никогда не будет нарушен. (См. ниже раздел 'font-weight'.)
  4. Сопоставление дескриптора 'font-size' должно осуществляться в рамках допустимых значений размеров, устанавливаемых пользовательским агентом. (Обычно размеры масштабируемых шрифтов округляются до ближайшего целого значения в пикселях, в то время как допуск на масштабирование растровых шрифтов не может быть установлен более 20%.) Дальнейшие вычисления, например, использующие кегельную шпацию в других свойствах, основываются на используемом, а не на указанном значении дескриптора 'font-size'.
Отображение градаций насыщенности шрифтов на их имена

Значения свойства 'font-weight' задаются в числовом формате, в котором значение '400' (или 'normal') соответствует нормальному начертанию шрифта данной гарнитуры. В качестве названия насыщенности, связанной с данным начертанием, обычно используются слова Book, Regular, Roman, Normal или иногда Medium.

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

  • Если наряду со шрифтом, помеченным словом Book, Regular, Roman или Normal, существует шрифт, помеченный словом Medium, то Medium обычно ассоциируется со значением, равным '500'.
  • Шрифт, помеченный словом "Bold", зачастую ассоциируется со значением насыщенности, равным '700'.
  • Если в данной гарнитуре имеется менее 9 градаций насыщенности, то по умолчанию пробелы заполняются следующим образом. Если значение '500' еще не ассоциировано, то оно назначается шрифту, с которым ассоциировано значение '400'. Если какое-либо из значений '600', '700', '800' или '900' остается не ассоциированным, то оно назначается следующему более темному шрифту, если такой существует, или, в противном случае, следующему более светлому шрифту.
  • Если какое-либо из значений '300', '200' или '100' остается не ассоциированным, то оно назначается следующему более светлому шрифту, если такой существует, или в противном случае, следующему более темному шрифту.

Существование более темного шрифта для каждого значения свойства 'font-weight' не гарантировано. Например, некоторые шрифты имеют только обычное и жирное начертание, а другие шрифты могут иметь восемь различных градаций насыщенности.

В следующих двух примерах показаны типичные отображения.

Допустим, что в гарнитуре "Rattlesnake" существует четыре градации насыщенности, от самой светлой и до самой темной: Regular, Medium, Bold, Heavy.

Первый пример отображения названия шрифта в значение его насыщенности
Доступные шрифты Числовое значение насыщенности Заполнение пробелов
"Rattlesnake Regular" 400 100, 200, 300
"Rattlesnake Medium" 500  
"Rattlesnake Bold" 700 600
"Rattlesnake Heavy" 800 900

Допустим, что в гарнитуре "Ice Prawn" существует шесть градаций насыщенности: Book, Medium, Bold, Heavy, Black, ExtraBlack. Обратите внимание, что в данном примере пользовательский агент решил не задавать числовое значение для градации "ExtraBlack".

Второй пример отображения названия шрифта в значение его насыщенности
Доступные шрифы Числовое значение насыщенности Заполнение пробелов
"Ice Prawn Book" 400 100, 200, 300
"Ice Prawn Medium" 500  
"Ice Prawn Bold" 700 600
"Ice Prawn Black" 900  
"Ice Prawn ExtraBlack" (none)  
Примеры сопоставления шрифтов

В следующем примере определяется специальное начертание шрифта Alabama Italic. Также предоставляются описание шрифта в системе panose и исходный URI для загрузки шрифта с сервера truetype. Для описания шрифта используются дескрипторы его насыщенности и стиля. В объявлениях говорится, что насыщенность будет сопоставляться любому значению в диапазоне от 300 до 500. Гарнитурой шрифтов является Alabama, а дополненным именем шрифта является Alabama Italic.

@font-face {
src: local("Alabama Italic"),
url(http://www.fonts.org/A/alabama-italic) format("truetype");
panose-1: 2 4 5 2 5 4 5 9 3 3;
font-family: Alabama, serif;
font-weight: 300, 400, 500;
font-style: italic, oblique;
}

В следующем примере осуществляется определение гарнитуры шрифта. Для загрузки данных о шрифте предоставляется один URI. Этот файл данных будет содержать несколько стилей и значений насыщенности указанного шрифта. Если к одному из правил @font-face было осуществлено несколько обращений, то данные будут помещены в кэш пользовательского агента для других шрифтов, использующих этот же URI.

@font-face {
src: local("Helvetica Medium"),
url(http://www.fonts.org/sans/Helvetica_family) format("truedoc");
font-family: "Helvetica";
font-style: normal
}
@font-face {
src: local("Helvetica Oblique"),
url("http://www.fonts.org/sans/Helvetica_family") format("truedoc");
font-family: "Helvetica";
font-style: oblique;
slope: -18
}

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

@font-face {
font-family: Excelsior;
src: local("Excelsior Roman"), url("http://site/er") format("intellifont");
unicode-range: U+??; /* Latin-1 */
}
@font-face {
font-family: Excelsior;
src: local("Excelsior EastA Roman"), url("http://site/ear") format("intellifont");
unicode-range: U+100-220; /* Latin Extended A and B */
}
@font-face {
font-family: Excelsior;
src: local("Excelsior Cyrillic Upright"), url("http://site/ecr") format("intellifont");
unicode-range: U+4??; /* Cyrillic */
}
@font-face {
font-family: Excelsior;
src: url("http://site/excels") format("truedoc");
unicode-range: U+??,U+100-220,U+4??;
}

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

@font-face {
src: local("Palatino"),
local("Times New Roman"),
local("New York"),
local("Utopia"),
url("http://somewhere/free/font");
font-family: serif;
font-weight: 100, 200, 300, 400, 500;
font-style: normal;
font-variant: normal;
font-size: all
}