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

时间:2011-04-07 21:35:28

标签: css internet-explorer css3 internet-explorer-9 font-face

我正在构建一个小型Intranet应用程序,并尝试使用我最近购买的 Adob​​e字体,但没有运气。据我所知,在我们的情况下,这不是违反许可证的行为。

我将.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 文件,但我不知道它是否重要... < / p>

任何想法如何解决?

[编辑] - 我在 IIS 7.5

下托管我的网站(字体,但在单独的目录和静态内容的子域下)

19 个答案:

答案 0 :(得分:94)

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

使用相应的tool,您可以将其设置为可安装的嵌入允许
对于64位版本,请检查@ user22600的answer

答案 1 :(得分:36)

正如Knu所说,你可以使用this tool,但它只是为MS-DOS编译的。我为Win64编译了它。 Download

用法:

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

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

  3. 输入embed fontname.fonttype,将fontname替换为文件名和fonttype,扩展名为embed brokenFont.ttf

  4. 全部完成!您的字体现在应该有效。

答案 2 :(得分:33)

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

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

答案 3 :(得分:12)

我收到以下错误:

  

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

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

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

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

答案 4 :(得分:9)

试试这个,在web.config中添加这一行。

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

答案 5 :(得分:8)

一个不同的答案:法律问题。

在执行此操作之前,需要注意几点。首先,为了得到这个错误,在IE中,检查元素,切换标签,并查找错误,我相信&#34; CSS3114&#34;出现在控制台中。

您需要了解的是这是许可问题。 I.E. (双关语)如果您尝试加载导致此错误的字体,您没有权限使用该字体,如果您没有获得许可,很可能是您除非您持有许可证,否则可能会失去以这种方式使用此字体的法律斗争(本身极不可能)。因此,您可以第一次感谢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/

最后,要摆脱&#34; CSS3114&#34;错误。有关在线工具,请点击此处:https://www.andrebacklund.com/fontfixer.html

答案 6 :(得分:7)

IE9确实需要TTF字体才能将嵌入位设置为Installable。 Generator会自动执行此操作,但由于其他原因,我们目前正在阻止Adobe字体。我们可能会在不久的将来解除这一限制。

答案 7 :(得分:7)

由于这个问题,我浪费了很多时间。 最后我找到了很好的解决方案。在我使用.ttf字体之前。但我添加了一个额外的字体格式。但它开始在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);
}

我希望这会对某人有所帮助。

答案 8 :(得分:4)

作为Mac用户,我无法使用提到的MS-DOS和Windows命令行工具来修复字体嵌入权限。但是,我发现您可以使用FontLab将此权限设置为“允许一切”#39;。我希望这篇关于set the font permission to Installable on Mac OS X如何对其他人有用的方法。

答案 9 :(得分:4)

如果您熟悉nodejs / npm,ttembed-js是一种简单的方法来设置&#34;可安装的嵌入允许&#34;标志在TTF字体上。这将修改指定的.ttf文件:

00018.jpg

答案 10 :(得分:3)

问题可能与您的服务器配置有关 - 它可能没有为字体文件发送正确的标头。看一下问题IE9 blocks download of cross-origin web font给出的答案。

EricLaw建议在Apache配置中添加以下内容

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

答案 11 :(得分:2)

对于每个收到错误的人:&#34; tableversion必须为0,1或者是十六进制:003&#34;使用ttfpatch时,我编译嵌入64位。我没有改变任何东西,只是添加了需要的库和编译。使用风险自负。

用法:ConsoleApplication1 font.ttf

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

答案 12 :(得分: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中的原始来源here

答案 13 :(得分: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")

它可以工作,但是我最终通过像这样的this

解决了通过https在IE中加载字体的问题。

thanks NobleUplift

可以在here中找到C中的原始源。

答案 14 :(得分: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');
}

答案 15 :(得分:0)

我最近遇到了这个问题.eot和.otf字体在加载时在控制台中产生CSS3114和CSS3111错误。对我有用的解决方案是仅使用带有.ttf格式回退的.woff和.woff2格式。在大多数浏览器中,.wf格式将在.ttf之前使用,似乎不会触发字体嵌入权限问题(css3114)和字体命名格式错误(css3111)。我在this extremely helpful article about the CSS3111 and CSS3114 issue找到了我的解决方案,并且还在阅读this article on using @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');
}

答案 16 :(得分:0)

我尝试了ttfpatch工具,它并没有形成我的工作。 Internet Exploder 9和10仍然抱怨。

我找到了这个很好的Git要点,它解决了我的问题。 https://gist.github.com/stefanmaric/a5043c0998d9fc35483d

只需将代码复制并粘贴到您的CSS中即可。

答案 17 :(得分: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');
  }

答案 18 :(得分:0)

您可以通过以下代码解决此问题

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