我正在构建一个小型内部网应用程序,并尝试使用我最近购买的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/。除了。woff,我还得到一个。afm文件,但我不知道它是否重要…
有什么办法吗?
[Edit] -我在IIS 7.5下托管我的网站(字体也是,但在单独的目录和静态内容子域下)
我只能解释你如何修复"CSS3114"错误。
您必须更改TTF文件的嵌入级别。
使用适当的工具可以将其设置为可安装嵌入允许。
对于64位版本,请查看@user22600的答案。
正如Knu所说,你可以使用这个工具,但是它只针对MS-DOS编译。我为Win64编译了它。下载。
用法:
-
将。exe文件与需要修改的字体放在同一个文件夹中
-
在命令行导航到该目录
-
type
embed fontname.fonttype
,将fontname替换为文件名,将fonttype替换为扩展名即embed brokenFont.ttf
-
全部完成!
您应该将ie字体的格式设置为'embedded-opentype'而不是'eot'。例如:
src: url('fontname.eot?#iefix') format('embedded-opentype')
我得到以下错误:
CSS3114: @font-face OpenType嵌入权限检查失败。权限必须是可安装的。
fontname.ttf
使用下面的代码后,我的问题得到解决....
src: url('fontname.ttf') format('embedded-opentype')
谢谢你们的帮助!
欢呼,
Renjith。
试试这个,在web.config中添加这些行。
<system.webServer>
<staticContent>
<mimeMap fileExtension=".woff" mimeType="application/octet-stream" />
</staticContent>
</system.webServer>
一个不同的答案:法律问题。
在执行此操作之前需要注意几件事。首先,要得到这个错误,在IE中,检查元素,切换选项卡,并寻找错误,我相信"CSS3114"出现在控制台中。
你需要明白的是这是一个许可问题。也就是说(双关语)如果你试图加载一种导致这个错误的字体,你没有使用该字体的文件权限,如果你没有权限,你很可能会因为以这种方式使用该字体而输掉一场法律战(这本身是极不可能的),除非你持有许可证。所以,你可以第一次感谢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
确实,IE9要求TTF字体将嵌入位设置为可安装的。生成器会自动完成这项工作,但由于其他原因,我们目前正在阻止Adobe字体。我们可能在不久的将来取消这一限制。
因为这个问题我浪费了很多时间。最后,我自己找到了一个很好的解决方案。之前我只使用。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);
}
我希望这将帮助某人。
作为Mac用户,我无法使用上面提到的修复字体嵌入权限的MS-DOS和Windows命令行工具。然而,我发现你可以使用FontLab来解决这个问题,将权限设置为"一切都是允许的"。我希望这个关于如何在Mac OS X上设置字体权限的食谱对其他人也有用。
如果你熟悉nodejs/npm, ttembed-js是一个在TTF字体上设置"可安装嵌入"标志的简单方法。这将修改指定的.ttf文件:
npm install -g ttembed-js
ttembed-js somefont.ttf
问题可能与您的服务器配置有关-它可能没有为字体文件发送正确的标题。看看对于IE9阻止跨源网页字体下载的问题给出的答案。
EricLaw建议在Apache配置中添加以下内容
<FilesMatch ".(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://mydomain.com"
</IfModule>
</FilesMatch>
如果你想用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语言的原始源代码可以在这里找到。
对于使用ttfpatch时得到错误的每个人:"tableversion必须是0,1或并且是十六进制:003",我已经编译了64位嵌入。我没有改变任何东西,只是添加了需要的库和编译。使用风险自负。
用法:ConsoleApplication1 font.ttf
http://www.mediafire.com/download/8x1px8aqq18lcx8/ConsoleApplication1.exe
您可以通过以下代码解决
@font-face {
font-family: 'Font-Name';
src: url('../fonts/Font-Name.ttf');
src: url('../fonts/Font-Name.eot?#iefix') format('embedded-opentype');
}
我发现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');
}
我尝试了ttfpatch工具,它没有从我的工作。Internet explorer 9和10仍然抱怨。
我找到了这个很好的Git gist,它解决了我的问题。https://gist.github.com/stefanmaric/a5043c0998d9fc35483d
只是复制和粘贴代码到你的css。
我最近遇到了这个问题,.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');
}
这就是触发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');
}
这个适合我:
@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');
}
如果你想用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加载字体的问题,像这样
由于NobleUpliftC语言原文在这里