使Adobe字体与IE9中的CSS3 @ font-face一起使用


132

我正在构建一个小型Intranet应用程序,并且尝试使用最近购买的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是一个精巧,聪明,措辞恰当的问题,并完成了所有作业。这些天我们很少得到这些!
Pekka

确实,这是一个很容易回答的问题,但可悲的是,它是一个重复的问题。
约瑟夫·伯

1
不,它肯定不是重复的,因为在非Adobe字体中,我找到的解决方案非常有效。不同之处在于,我猜想跨域字体引用不是这种情况-我在其他提到的问题中使用.woff字体遇到了“ @ font-face遇到未知错误”,而在其他提到的问题中却遇到了“ @ font-face失败的跨域请求”案件。
Piotr Szmyd 2011年

更改嵌入选项后,此行出现了问题:url('myfont-webfont.eot?#iehack') format('eot'), 删除它可以解决最后一个错误(未知错误)。
乔纳森·德马克

Answers:


95

我只能向您解释如何解决“ CSS3114”错误。
您必须更改TTF文件的嵌入级别。

使用适当的工具,可以将其设置为允许安装的嵌入
对于64位版本,请检查@ user22600的答案


11
作为ttfpatch的注释,请使用fsType = 0。
Collin价格

11
ttfpatch对我不起作用。错误:tableversion必须为0、1或十六进制:003
Don Rolling

11
嵌入效果很好。只需下载源代码并进行编译...这是StackOverflow,对吗?这只是一个文件。:-)对于VS2010,您需要添加:#include <string.h>
Jonathan DeMarks 2013年

3
@JonathanDeMarks:感谢您的鼓励-ttfpatch对我也不起作用,但是重新编译embed.c 64位绝对可以解决问题。
Peter Majeed 2014年

4
对于那些不愿意在Windows上编译C程序的人来说,这非常简单。遵循Microsoft的本指南:msdn.microsoft.com/en-us/library/bb384838.aspx
lee_mcmullen 2015年

36

正如Knu所说,您可以使用 此工具,但是它仅针对MS-DOS进行编译。我为Win64编译了它。下载

用法:

  1. 将.exe与您需要修改的字体放在同一文件夹中

  2. 在命令行中导航到该目录

  3. type embed fontname.fonttype,将fontname替换为文件名,将fonttype替换为扩展名,即embed brokenFont.ttf

  4. 全做完了!您的字体现在应该可以工作了。


感谢您的举报。固定。
user22600 2013年

真的对我有很大帮助。通过使用Win64位exe。
imdadhusen

天哪,太神奇了。并非所有方面:使用Windows命令行而不是像GIT BASH这样的替代品,我通常更喜欢bash,在这里不起作用。
露背装

瞧!辉煌!!
oldboy

33

您应该将ie字体的格式设置为'embedded-opentype'而不是'eot'。例如:

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

谢谢,但事实并非如此。这完全是关于在字体本身中嵌入权限。
Piotr Szmyd 2012年

这适用于Firefox和Chrome(IE仍在运行)。谢谢!
Dmitri Mogilevski

12

我收到以下错误:

CSS3114:@ font-face无法通过OpenType嵌入权限检查。权限必须是可安装的。
fontname.ttf

使用下面的代码后,我的问题得到解决。

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

谢谢你们对我的帮助!
干杯,
Renjith。


我认为您的解决方案适用于某些字体系列,但不适用于其他字体系列。这取决于字体的嵌入权限级别。例如,这不适用于Abadi字体
Philip007

是的,这与我的.ttf文件完全没有区别,我仍然得到“权限必须是可安装的”。错误。解决此问题的方法是运行Christian的.exe(在此页的其他位置)来修改.ttf文件。完成此操作后,IE11 在我的网页上正确显示.ttf字体。
迈克·格莱德希尔

9

尝试此操作,在web.config中添加此行。

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

我认为这与他所报告的错误不同,但是如果您要从IIS提供.woffs,则需要这样做,是的。或者,您可以在HKLM \ Software \ Classes下为.woff添加一个注册表项,并在其中设置“内容类型”值。但是,维基百科说正确的类型是application/font-woff
Rup

确实,这是另一回事。我有此条目-问题是由于嵌入的权限,已经下载的字体无法在IE中打开。
Piotr Szmyd

我当时在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


在线工具为我修复了它。谢谢!
James Hibbard

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将权限设置为“允许一切”来解决此问题。我希望有关在Mac OS X上将字体权限设置为Installable的方法对其他人也有用。


“我无法使用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

谢谢-这对导致我在IE11中出现问题的.otf字体非常有用。
J Sprague

3

问题可能与您的服务器配置有关-它可能没有发送正确的字体文件头。查看针对IE9阻止跨域Web字体下载的问题给出的答案。

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下运行我的网站。
Piotr Szmyd 2011年

他们有机会输入1种字体吗?
约瑟夫·厄尔

这些都是单文件.ttf(TrueType)字体。但是以某种方式,当通过onlinefontconverter.com转换为.woff格式时,我得到了一个.afm(Adobe字体度量标准)文件。我不知道该怎么办?
Piotr Szmyd 2011年


2

如果您想使用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语言的原始源代码可以在这里找到。


这有效,现在应该是第一个答案。到目前为止,要超越旧的答案,真是遗憾。
Goose Goose

非常感谢@Goose!我最初是为我的工作写的,但是代码被扔掉并被替换了,因此它存在于Stack Overflow中。为Web应用程序问题提供C代码绝对不是理想的选择。
NobleUplift '16

@Goose我执行C代码。总是。因此,这是一个品味问题,这就是为什么此答案与答案相同的原因。仅供参考,您还可以使用CGI在您的网站中实现C代码。
71GA

0

您可以通过以下代码解决它

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

不,它不起作用。我的案例严格来说是关于不允许按设计嵌入的字体(但允许使用的许可)。因此,这与我如何嵌入它无关。使用显式禁止网络嵌入的TTF字体进行检查,您将了解我的问题。
Piotr Szmyd

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文件似乎不受此问题的影响。

这就是DID使用@ 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');
}

这就是触发IE中@ font-face错误的原因:

@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');
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.