Заставьте шрифты Adobe работать с CSS3 @ font-face в IE9


132

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

Я конвертировал версии шрифта .ttf / .otf в .woff, .eot и .svg, чтобы настроить их для всех основных браузеров. Синтаксис @ font-face, который я использовал, в основном пуленепробиваемый от Font Spring :

@font-face {
    font-family: 'MyFontFamily';
    src: url('myfont-webfont.eot');
    src: url('myfont-webfont.eot?#iehack') format('eot'), 
         url('myfont-webfont.woff') format('woff'), 
         url('myfont-webfont.ttf')  format('truetype'),
         url('myfont-webfont.svg#svgFontName') format('svg');
    }

Я изменил заголовки HTTP (добавил Access-Control-Allow-Origin = "*"), чтобы разрешить междоменные ссылки. В FF и Chrome это работает отлично, но в IE9 я получаю:

CSS3111: @font-face encountered unknown error.  
myfont-webfont.woff
CSS3114: @font-face failed OpenType embedding permission check. Permission must be Installable. 
myfont-webfont.ttf

Я заметил, что при преобразовании шрифта из .ttf / .otf в .woff я также получаю файл .afm , но понятия не имею, важно это или нет ...

Есть идеи, как это решить?

[Редактировать] - я размещаю свои веб-сайты (шрифты тоже, но в отдельном каталоге и поддомене для статического содержимого) под IIS 7.5


16
+1 за хороший, умный, хорошо сформулированный вопрос со всей домашней работой. Мы получаем это слишком редко в наши дни!
Пекка

Действительно, это хорошо поставленный вопрос, но, к сожалению, дубликат.
Джозеф Эрл

1
Нет, это точно не дубликат, так как в не-Adobe шрифтах решения, которые я нашел, работают отлично. Отличие состоит в том, что это не относится к междоменной ссылке на шрифт, я думаю - я получаю «@ font-face столкнулся с неизвестной ошибкой» со шрифтом .woff, в отличие от «@ font-face failed cross-origin request» в других упомянутых случаев.
Петр Шмыд,

После изменения параметров встраивания у меня возникли проблемы с этой строкой: url('myfont-webfont.eot?#iehack') format('eot'), ее устранение позволило устранить последнюю ошибку (неизвестная ошибка).
Джонатан Демаркс

Ответы:


95

Я могу только объяснить вам, как исправить ошибку «CSS3114».
Вы должны изменить уровень встраивания вашего файла TTF.

Используя соответствующий инструмент, вы можете установить его для допустимого встраивания .
Для 64-битной версии проверьте ответ @ user22600 .


11
В качестве примечания для ttfpatch используйте fsType = 0.
Коллин Прайс

11
ttfpatch не работает для меня. Ошибка: табличная версия должна быть 0, 1 или и является шестнадцатеричной: 003
Дон Роллинг

11
Вставить работает отлично. Просто скачайте исходный код и скомпилируйте ... это StackOverflow, верно? Это только один файл. :-) Для VS2010 вам нужно добавить:#include <string.h>
Джонатан Демаркс

3
@JonathanDeMarks: Спасибо за поддержку - ttfpatch у меня тоже не сработал, но перекомпиляция embed.c для 64-битной системы, безусловно, сработала.
Питер Маджид

4
Для тех, кто не знает, как скомпилировать программы на C в Windows, это очень просто. Следуйте этому руководству от Microsoft: msdn.microsoft.com/en-us/library/bb384838.aspx
lee_mcmullen

36

Как сказал Кну, вы можете использовать этот инструмент , однако он скомпилирован только для MS-DOS. Я скомпилировал его для Win64. Скачать .

Использование:

  1. Поместите .exe в ту же папку, что и шрифт, который нужно изменить.

  2. Перейдите к этому каталогу в командной строке

  3. тип embed fontname.fonttype, заменяя имя шрифта именем файла и тип шрифта с расширением, т.е.embed brokenFont.ttf

  4. Все сделано! Ваш шрифт должен теперь работать.


Спасибо за отчет. Исправлена.
user22600

На самом деле мне очень помогают. с помощью Win64 бит EXE.
imdadhusen

Боже мой, это удивительно. Не все: используйте командную строку Windows, а не замену, как GIT BASH, я обычно предпочитаю bash, здесь не работает.
Холтер

вуаля! блестящий !!
oldboy

33

Вы должны установить формат шрифта ie на 'embedded-opentype', а не 'eot'. Например:

src: url('fontname.eot?#iefix') format('embedded-opentype')

Спасибо, но это был не тот случай. Речь шла о встраивании разрешений в сам шрифт.
Петр Шмыд,

Это работало для Firefox и Chrome (IE работал в любом случае). Спасибо!
Дмитрий Могилевский

12

Я получил следующую ошибку:

CSS3114: @ font-face не удалось проверить разрешение на встраивание OpenType. Разрешение должно быть установлено.
fontname.ttf

После использования кода ниже моя проблема была решена ....

src: url('fontname.ttf') format('embedded-opentype')

Спасибо, ребята, что помогли мне!
Ура,
Ренджит.


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

Да, это не имело никакого значения для моих файлов .ttf, я все еще получал «Разрешение должно быть установлено». ошибка. Что действительно помогло решить эту проблему, так это запустить .exe-файл Кристиана (в другом месте на этой странице) для изменения файлов .ttf. После этого IE11 будет правильно отображать шрифты .ttf на моей веб-странице.
Майк Гледхилл,

9

Попробуйте это, добавьте эти строки в web.config.

<system.webServer>
  <staticContent>
     <mimeMap fileExtension=".woff" mimeType="application/octet-stream" />
  </staticContent>
</system.webServer>

Я не думаю, что это та же ошибка, о которой он сообщил, но она потребуется, если вы обслуживаете .woffs из IIS, да. В качестве альтернативы вы можете добавить раздел реестра для .woff в HKLM \ Software \ Classes и установить в нем значение «Тип содержимого». Однако Википедия говорит, что правильный тип - этоapplication/font-woff .
Rup

На самом деле это совсем другое. У меня была эта запись - проблема была с уже загруженным шрифтом, который не мог быть открыт в IE из-за встроенных разрешений.
Петр Шмыд

Я занимался разработкой в ​​среде Apache, и когда я переместил свои файлы шрифтов на сервер Windows IIS, это решило мою проблему.
Самуэль Кук

8

Другой ответ: правовые вопросы.

Перед тем, как сделать это, нужно кое-что отметить. Во-первых, чтобы получить эту ошибку, в IE, проверить элемент, переключить вкладки и найти ошибки, я думаю, что «CSS3114» появляется в консоли.

Что вам нужно понять, так это вопрос лицензирования. IE (каламбур), если вы пытаетесь загрузить шрифт, который вызывает эту ошибку, у вас нет разрешения на использование шрифта в файле, и если у вас нет разрешения, очень вероятно, что вы потеряете юридическая битва (что само по себе крайне маловероятно) за использование этого шрифта таким образом, если вы не обладаете лицензией. Итак, вы можете впервые поблагодарить IE за то, что он единственный браузер, который говорит вам «нет», потому что он по крайней мере позволяет вам знать, что вы делаете что-то сомнительное.

Тем не менее, вот ваш ответ:

Сначала убедитесь, что вы используете лучший код в .css, посмотрите некоторые другие ответы CSS для этого.
Пример IE 11 css (работает во всех современных браузерах, возможно, потребуется настроить для IE9):

@font-face {
font-family: "QuestionableLegalFont";
font-weight: bold;
src: url('../fonts/QuestionableLegalFont.ttf') format('truetype');
}

Затем убедитесь, что у вас есть работающий веб-шрифт (вы, вероятно, уже знаете это, увидев свой шрифт в других браузерах). Если вам нужен онлайн-конвертер шрифтов, проверьте здесь: https://onlinefontconverter.com/

Наконец, чтобы избавиться от ошибки «CSS3114». Для онлайн-инструмента, нажмите здесь: https://www.andrebacklund.com/fontfixer.html


Онлайн-инструмент исправил это для меня. Спасибо!
Джеймс Хиббард

7

Это правда, что IE9 требует шрифтов TTF, чтобы биты встраивания были установлены в Installable. Генератор делает это автоматически, но в настоящее время мы блокируем шрифты Adobe по другим причинам. Мы можем снять это ограничение в ближайшее время.


7

Я потратил много времени из-за этой проблемы. Наконец я нашел отличное решение сам. До этого я использовал только шрифт .ttf. Но я добавил один дополнительный формат шрифта .eot, который начал работать в IE.

Я использовал следующий код, и он работал как шарм во всех браузерах.

@font-face {
font-family: OpenSans;
src: url(assets/fonts/OpenSans/OpenSans-Regular.ttf), 
url(assets/fonts/OpenSans/OpenSans-Regular.eot);
}

@font-face {
font-family: OpenSans Bold;
src: url(assets/fonts/OpenSans/OpenSans-Bold.ttf),
url(assets/fonts/OpenSans/OpenSans-Bold.eot);
}

Надеюсь, это кому-нибудь поможет.


4

Как пользователь Mac, я не мог использовать инструменты командной строки MS-DOS и Windows, о которых говорилось, чтобы исправить разрешение на встраивание шрифта. Однако я обнаружил, что это можно исправить с помощью FontLab, чтобы установить разрешение «Все разрешено». Я надеюсь, что этот рецепт о том, как установить разрешение шрифта для Installlable в Mac OS X, будет полезен и для других.


«Мне не удалось использовать инструменты командной строки MS-DOS и Windows»: хотя исходный код предоставлен - я ожидаю, что он просто скомпилируется на Mac?
Rup

Извините, я хотел сказать: быть испорченным пользователем OS X Finder.
Buijs

4

Если вы знакомы с nodejs / npm, ttembed-js - это простой способ установить флаг «разрешено встраиваемое встраивание» для шрифта TTF. Это изменит указанный файл .ttf:

npm install -g ttembed-js

ttembed-js somefont.ttf

Спасибо - это отлично работает для шрифтов .otf, которые вызывают у меня проблемы в IE11.
J Sprague

3

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

EricLaw предлагает добавить следующее в вашу конфигурацию Apache

<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "http://mydomain.com"
    </IfModule>
</FilesMatch>

Но это не тот случай, хотя. Я прочитал этот пост и уже попробовал решение, которое вы предоставили. Проблема конкретно со шрифтами Adobe. Я попытался использовать наборы шрифтов от Font Squirrel, и они прекрасно работают во всех браузерах (IE9 тоже). Когда я пытаюсь использовать шрифты Adobe (преобразованные в соответствующие форматы) таким же образом - IE9 выкрикивает с ошибками ...
Петр Шмид,

И - что я забыл сказать (я отредактирую свой вопрос) - я запускаю свои сайты под IIS 7.5.
Петр Шмыд,

Являются ли они шрифтами типа 1 случайно?
Джозеф Эрл

Это все однофайловые шрифты .ttf (TrueType). Но почему-то я получаю файл .afm (Adobe Font Metrics) при преобразовании в формат .woff через onlinefontconverter.com. Понятия не имею, что с этим делать?
Петр Шмыд,

3

Если вы хотите сделать это с помощью PHP-скрипта вместо того, чтобы запускать код на C (или вы работаете на Mac, подобном мне, и вы не можете получить компиляцию с XCode только для того, чтобы ждать, пока он откроется год), вот Функция PHP, которую вы можете использовать для удаления прав на встраивание шрифта:

function convertRestrictedFont($filename) {
    $font = fopen($filename,'r+');
    if ($font === false) {
        throw new Exception('Could not open font file.');
    }

    fseek($font, 12, 0);

    while (!feof($font)) {
        $type = '';
        for ($i = 0; $i < 4; $i++) {
            $type .= fgetc($font);
            if (feof($font)) {
                fclose($font);
                throw new Exception('Could not read the table definitions of the font.');
            }
        }
        if ($type == 'OS/2') {
            // Save the location of the table definition
            // containing the checksum and pointer to the data
            $os2TableDefinition = ftell($font);
            $checksum = 0;

            for ($i = 0; $i < 4; $i++) {
                fgetc($font);
                if (feof($font)) {
                    fclose($font);
                    throw new Exception('Could not read the OS/2 table header of the font.');
                }
            }

            // Get the pointer to the OS/2 table data
            $os2TablePointer = ord(fgetc($font)) << 24;
            $os2TablePointer |= ord(fgetc($font)) << 16;
            $os2TablePointer |= ord(fgetc($font)) << 8;
            $os2TablePointer |= ord(fgetc($font));

            $length = ord(fgetc($font)) << 24;
            $length |= ord(fgetc($font)) << 16;
            $length |= ord(fgetc($font)) << 8;
            $length |= ord(fgetc($font));

            if (fseek($font, $os2TablePointer + 8, 0) !== 0) {
                fclose($font);
                throw new Exception('Could not read the embeddable type of the font.');
            }

            // Read the fsType before overriding it
            $fsType = ord(fgetc($font)) << 8;
            $fsType |= ord(fgetc($font));

            error_log('Installable Embedding: ' . ($fsType == 0));
            error_log('Reserved: ' . ($fsType & 1));
            error_log('Restricted License: ' . ($fsType & 2));
            error_log('Preview & Print: ' . ($fsType & 4));
            error_log('Editable Embedding: ' . ($fsType & 8));
            error_log('Reserved: ' . ($fsType & 16)); 
            error_log('Reserved: ' . ($fsType & 32));
            error_log('Reserved: ' . ($fsType & 64));
            error_log('Reserved: ' . ($fsType & 128));
            error_log('No subsetting: ' . ($fsType & 256));
            error_log('Bitmap embedding only: ' . ($fsType & 512));                         
            error_log('Reserved: ' . ($fsType & 1024));
            error_log('Reserved: ' . ($fsType & 2048));
            error_log('Reserved: ' . ($fsType & 4096));
            error_log('Reserved: ' . ($fsType & 8192));
            error_log('Reserved: ' . ($fsType & 16384));
            error_log('Reserved: ' . ($fsType & 32768));

            fseek($font, ftell($font) - 2);

            // Set the two bytes of fsType to 0
            fputs($font, chr(0), 1);
            fputs($font, chr(0), 1);

            // Go to the beginning of the OS/2 table data
            fseek($font, $os2TablePointer, 0);

            // Generate a new checksum based on the changed 
            for ($i = 0; $i < $length; $i++) {
                $checksum += ord(fgetc($font));
            }
            fseek($font, $os2TableDefinition, 0);
            fputs($font, chr($checksum >> 24), 1);
            fputs($font, chr(255 & ($checksum >> 16)), 1);
            fputs($font, chr(255 & ($checksum >> 8)), 1);
            fputs($font, chr(255 & $checksum), 1);

            fclose($font);

            return true;
        }
        for ($i = 0; $i < 12; $i++) {
            fgetc($font);
            if (feof($font)) {
                fclose($font);
                throw new Exception('Could not skip a table definition of the font.');
            }
        }
    }

    fclose($font);

    return false;
}

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

Первоначальный источник в C можно найти здесь .


Это работает и теперь должно быть ответом номер 1. Стыдно, что ему еще нужно взобраться, чтобы обогнать старые ответы.
Гусь

Большое спасибо @Goose! Первоначально я написал это для своей работы, но код был отброшен и заменен, так что он живет в переполнении стека. Предоставление C-кода для проблемы веб-приложения определенно не идеально.
NobleUplift

@ Гусь, я предпочитаю код С. Всегда. Так что это вопрос вкуса, и поэтому этот ответ эквивалентен ответу. К вашему сведению, вы также можете использовать CGI для реализации кода на вашем сайте.
71GA

2

Для всех, кто получает сообщение об ошибке: «tableversion должен быть 0, 1 или hex: 003» при использовании ttfpatch, я скомпилировал embed для 64-битной версии. Я ничего не изменил, просто добавил библиотеки и откомпилировал. Используйте на свой страх и риск.

Использование: ConsoleApplication1 font.ttf

http://www.mediafire.com/download/8x1px8aqq18lcx8/ConsoleApplication1.exe


0

Вы можете решить это следующим кодом

@font-face {
  font-family: 'Font-Name';
  src: url('../fonts/Font-Name.ttf');
  src: url('../fonts/Font-Name.eot?#iefix') format('embedded-opentype');
}

Нет, это не сработает. Мой случай был строго о шрифтах, которые не допускали встраивание по дизайну (но с лицензией, которая позволяет это). Так что дело не в том, как я это встраиваю. Проверьте это шрифтом TTF, который явно запрещает встраивание в Интернет, и вы поймете мою проблему.
Петр Шмыд,

0

Я нашел eotфайл должен быть помещен за пределы ttf. Если он ниже ttf, то, если шрифт отображается правильно, IE9 все равно выдаст ошибку.

Рекомендовать:

@font-face {
  font-family: 'Font-Name';
  src: url('../fonts/Font-Name.eot?#iefix') format('embedded-opentype');
  src: url('../fonts/Font-Name.ttf')  format('truetype');
}

Не рекомендую:

@font-face {
  font-family: 'Font-Name';
  src: url('../fonts/Font-Name.ttf')  format('truetype');
  src: url('../fonts/Font-Name.eot?#iefix') format('embedded-opentype');
  }


0

Недавно я столкнулся с этой проблемой со шрифтами .eot и .otf, приводящими к ошибкам CSS3114 и CSS3111 в консоли при загрузке. Решение, которое работало для меня, состояло в том, чтобы использовать только форматы .woff и .woff2 с запасным вариантом формата .ttf. Форматы .woff будут использоваться раньше .ttf в большинстве браузеров и, по-видимому, не будут вызывать проблему с разрешениями на встраивание шрифтов (css3114) и проблему неправильного формата именования шрифтов (css3111). Я нашел свое решение в этой чрезвычайно полезной статье о проблеме CSS3111 и CSS3114 , а также читал эту статью об использовании @ font-face .

примечание: это решение не требует повторной компиляции, преобразования или редактирования любых файлов шрифтов. Это решение только для CSS. У шрифта, с которым я тестировал, были версии .eot, .otf, .woff, .woff2 и .svg, сгенерированные для него, вероятно, из исходного источника .ttf, который действительно выдал ошибку 3114, когда я пытался это сделать, однако .woff и. Файлы woff2, похоже, неуязвимы для этой проблемы.

Вот что мне помогло с @ font-face:

@font-face {
  font-family: "Your Font Name";
  font-weight: normal;
  src: url('your-font-name.woff2') format('woff2'),
       url('your-font-name.woff') format('woff'),
       url('your-font-name.ttf')  format('truetype');
}

Это было то, что вызвало ошибки с @ font-face в IE:

@font-face {
  font-family: 'Your Font Name';
  src: url('your-font-name.eot');
  src: url('your-font-name.eot?#iefix') format('embedded-opentype'),
       url('your-font-name.woff2') format('woff2'),
       url('your-font-name.woff') format('woff'),
       url('your-font-name.ttf')  format('truetype'),
       url('your-font-name.svg#svgFontName') format('svg');
}

0

Это работает для меня:

@font-face {
  font-family: FontName;
  src: url('@{path-fonts}/FontName.eot?akitpd');
  src: url('@{path-fonts}/FontName.eot?akitpd#iefix') format('embedded-opentype'),
    url('@{path-fonts}/FontName.ttf?akitpd') format('truetype'),
    url('@{path-fonts}/FontName.woff?akitpd') format('woff'),
    url('@{path-fonts}/FontName.svg?akitpd#salvage') format('svg');
}

0

Если вы хотите сделать это с помощью скрипта Python вместо того, чтобы запускать код C / PHP, вот функция Python3, которую вы можете использовать для удаления разрешений на встраивание шрифта:

def convert_restricted_font(filename):
with open(filename, 'rb+') as font:

    font.read(12)
    while True:
        _type = font.read(4)
        if not _type:
            raise Exception('Could not read the table definitions of the font.')
        try:
            _type = _type.decode()
        except UnicodeDecodeError:
            pass
        except Exception as err:
            pass
        if _type != 'OS/2':
            continue
        loc = font.tell()
        font.read(4)
        os2_table_pointer = int.from_bytes(font.read(4), byteorder='big')
        length = int.from_bytes(font.read(4), byteorder='big')
        font.seek(os2_table_pointer + 8)

        fs_type = int.from_bytes(font.read(2), byteorder='big')
        print(f'Installable Embedding: {fs_type == 0}')
        print(f'Restricted License: {fs_type & 2}')
        print(f'Preview & Print: {fs_type & 4}')
        print(f'Editable Embedding: {fs_type & 8}')

        print(f'No subsetting: {fs_type & 256}')
        print(f'Bitmap embedding only: {fs_type & 512}')

        font.seek(font.tell()-2)
        installable_embedding = 0 # True
        font.write(installable_embedding.to_bytes(2, 'big'))
        font.seek(os2_table_pointer)
        checksum = 0
        for i in range(length):
            checksum += ord(font.read(1))
        font.seek(loc)
        font.write(checksum.to_bytes(4, 'big'))
        break


if __name__ == '__main__':
    convert_restricted_font("19700-webfont.ttf")

это работает, но в итоге я решил проблему загрузки шрифтов в IE по https вот так

спасибо NobleUplift

Первоначальный источник в C можно найти здесь .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.