Internet explorer 使Adobe字体与IE9中的CSS3@font-face配合使用
我正在构建一个小型intranet应用程序,并尝试使用我最近购买的Adobe font,但运气不佳。据我所知,在我们的情况下,这不是违反许可证 我将font的.ttf/.otf版本转换为.woff、.eot和.svg,以便面向所有主要的浏览器。我使用的@font-face语法基本上是来自: 我修改了HTTP头(添加了Access Control Allow Origin=“*”)以允许跨域引用在FF和Chrome中工作得非常完美,但在IE9中我得到:Internet explorer 使Adobe字体与IE9中的CSS3@font-face配合使用,internet-explorer,css,internet-explorer-9,font-face,Internet Explorer,Css,Internet Explorer 9,Font Face,我正在构建一个小型intranet应用程序,并尝试使用我最近购买的Adobe font,但运气不佳。据我所知,在我们的情况下,这不是违反许可证 我将font的.ttf/.otf版本转换为.woff、.eot和.svg,以便面向所有主要的浏览器。我使用的@font-face语法基本上是来自: 我修改了HTTP头(添加了Access Control Allow Origin=“*”)以允许跨域引用在FF和Chrome中工作得非常完美,但在IE9中我得到: CSS3111: @font-face en
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下托管我的网站(也有字体,但静态内容在单独的目录和子域下)。问题可能与您的服务器配置有关-它可能没有为字体文件发送正确的标题。看看这个问题的答案 EricLaw建议在Apache配置中添加以下内容
<FilesMatch "\.(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://mydomain.com"
</IfModule>
</FilesMatch>
标题集访问控制允许原点“http://mydomain.com"
我只能解释如何修复“CSS3114”错误。您必须更改TTF文件的嵌入级别 您可以使用适当的设置将其设置为允许安装嵌入。
对于64位版本,请选中@user22600。IE9确实要求TTF字体将嵌入位设置为可安装。生成器会自动执行此操作,但由于其他原因,我们目前正在阻止Adobe字体。我们可能会在不久的将来取消此限制。您应该将ie字体的格式设置为“嵌入式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>
对于每个遇到错误的人:“tableversion必须是0、1或,并且是十六进制:003”使用ttfpatch时,我编译了64位的嵌入。我没有改变任何东西,只是添加了需要的libs并编译了。自担风险使用 用法:ConsoleApplication1 font.ttf
作为Mac用户,我无法使用上面提到的MS-DOS和Windows命令行工具来修复字体嵌入权限。但是,我发现您可以使用FontLab将权限设置为“一切都允许”来解决此问题。我希望这个关于如何使用的方法对其他人也有用。正如克伦民族联盟所说,你可以使用,但是它只为MS-DOS编译。我为Win64编译了它 用法:
嵌入fontname.fonttype
,用文件名替换fontname,用扩展名替换fonttype,即嵌入brokenFont.ttf
您可以通过以下代码来解决它
@font-face {
font-family: 'Font-Name';
src: url('../fonts/Font-Name.ttf');
src: url('../fonts/Font-Name.eot?#iefix') format('embedded-opentype');
}
因为这个问题我浪费了很多时间。 最后我自己找到了很好的解决办法。在我只使用.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);
}
我希望这会对某些人有所帮助。如果您熟悉nodejs/npm,这是在TTF字体上设置“允许安装嵌入”标志的简单方法。这将修改指定的.ttf文件:
npm install -g ttembed-js
ttembed-js somefont.ttf
如果你想用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;
}
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")
函数convertRestrictedFont($filename){
$font=fopen($filename,'r+');
如果($font==false){
抛出新异常('无法打开字体文件');
}
fseek($font,12,0);
而(!feof($font)){
$type='';
对于($i=0;$i<4;$i++){
$type.=fgetc($font);
if(feof($font)){
fclose($font);
抛出新异常('无法读取字体的表定义');
}
}
如果($type=='OS/2'){
//保存表定义的位置
//包含校验和和和指向数据的指针
$os2TableDefinition=ftell($font);
$checksum=0;
对于($i=0;$i<4;$i++){
fgetc(字体);
if(feof($font)){
fclose($font);
抛出新异常('无法读取字体的OS/2表头');
}
}
//获取指向OS/2表数据的指针
$os2TablePointer=ord(fgetc($font))我发现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');
}
不推荐推荐:
@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');
}
另一个答案是:法律问题。
在执行此操作之前,有几件事需要注意。首先,要获得此错误,请在IE中检查元素,切换选项卡并查找错误,我相信控制台中会出现“CSS3114”
您需要了解的是,这是一个许可问题。也就是说,(双关语)如果您试图加载导致此错误的字体,您对该文件没有使用该字体的权限,并且如果您没有权限,您很可能会因使用此字体而输掉一场法律战(这本身是不太可能的)
@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');
}
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")