Make Adobe fonts work with CSS3 @font-face in IE9

Internet ExplorerCssInternet Explorer-9Font Face

Internet Explorer Problem Overview


I'm in the process of building a small intranet application and try, with no luck, to use Adobe font I purchased lately. As I was informed, in our case it's not a license violation.

I converted the .ttf/.otf versions of font to .woff, .eot and .svg, so to target all major browsers. The @font-face syntax I used is basically the bulletproof one from 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');
	}

I modified the HTTP headers (added Access-Control-Allow-Origin = "*") to allow cross-domain references. In FF and Chrome it works perfectly, but in IE9 I get:

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

I noticed that when converting font from .ttf/.otf to .woff I also get an .afm file, but I don't have a clue whether it's important or not...

Any ideas how to work it out?

[Edit] - I host my websites (fonts too, but under separate directory and subdomain for static content) under IIS 7.5

Internet Explorer Solutions


Solution 1 - Internet Explorer

I can only explain you how to fix the "CSS3114" error.
You have to change the embedding level of your TTF file.

Using the appropriate tool you can set it to installable embedding allowed.
For a 64-bit version, check @user22600's answer.

Solution 2 - Internet Explorer

As Knu said, you can use this tool, however it's compiled only for MS-DOS. I compiled it for Win64. Download.

Usage:

  1. Place the .exe in the same folder as the font you need to modify

  2. Navigate to that directory in the command line

  3. type embed fontname.fonttype, replacing fontname with the filename and fonttype with the extension i.e. embed brokenFont.ttf

  4. All done! Your font should now work.

Solution 3 - Internet Explorer

You should set the format of the ie font to 'embedded-opentype' and not 'eot'. For example:

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

Solution 4 - Internet Explorer

I was getting the following error:

> CSS3114: @font-face failed OpenType embedding permission check. Permission must be Installable.
fontname.ttf

After using the below code my issue got resolved....

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

Thank you guys for helping me!
Cheers,
Renjith.

Solution 5 - Internet Explorer

Try this, add this lines in the web.config.

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

Solution 6 - Internet Explorer

There's a couple of things to note before you do this. First, to get this error, in IE, inspect element, switch your tabs, and look for the errors, I believe "CSS3114" appears in the console.

What you need to understand is this is a licensing issue. I.E. (pun intended) if you are trying to load a font that causes this error, you don't have permissions on the file to use the font, and if you don't have permission, it is highly likely that you may lose a legal battle (which itself is highly unlikely) over using this font in this manner unless you are holding the license. So, you can, for the first time, thank IE for being the only browser to tell you "no", because it at least lets you know that you are doing something questionable.

That said, here is your answer:

First ensure you're using the best code in .css, see some of the other css answers for that.
IE 11 css example (works in all modern browsers may need to be tweaked for IE9):

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

Then, ensure you have a working web-font (you probably already know this by seeing your font in other browsers). If you need an online font converter, check here: https://onlinefontconverter.com/

Finally, To get rid of the "CSS3114" error. For an online tool, click here: https://www.andrebacklund.com/fontfixer.html

Solution 7 - Internet Explorer

It is true that IE9 requires TTF fonts to have the embedding bits set to Installable. The Generator does this automatically, but we are currently blocking Adobe fonts for other reasons. We may lift this restriction in the near future.

Solution 8 - Internet Explorer

I wasted a lot of time because of this issue. Finally I found great solution myself. Before I was using .ttf font only. But I added one extra font format .eot that started to work in IE.

I used following code and it worked like charm in all browsers.

@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);
}

I hope this will help someone.

Solution 9 - Internet Explorer

As a Mac user, I was unable to use the MS-DOS and Windows command line tools that were mentioned to fix the font embedding permission. However, I found out that you can fix this using FontLab to set the permission to 'Everything is allowed'. I hope this recipe on how to set the font permission to Installable on Mac OS X is useful for others as well.

Solution 10 - Internet Explorer

If you are familiar with nodejs/npm, ttembed-js is an easy way to set the "installable embedding allowed" flag on a TTF font. This will modify the specified .ttf file:

npm install -g ttembed-js

ttembed-js somefont.ttf

Solution 11 - Internet Explorer

The issue might be to do with your server configuration - it may not be sending the right headers for the font files. Take a look at the answer given for the question IE9 blocks download of cross-origin web font.

EricLaw suggests adding the following to your Apache config

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

Solution 12 - Internet Explorer

If you want to do this with a PHP script instead of having to run C code (or you're on a Mac like me and you can't be arsed compiling with Xcode only to wait a year for it to open), here's a PHP function that you can use to remove the embedding permissions from the font:

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;
}

Make sure to backup your font file before running this code and don't blame me if it corrupts.

Original source in C can be found here.

Solution 13 - Internet Explorer

For everyone who gets the error: "tableversion must be 0, 1 or and is hex:003" when using ttfpatch, i've compiled embed for 64bit. I have not changed anything, just added need libs and compiled. Use at own risk.

Usage: ConsoleApplication1 font.ttf

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

Solution 14 - Internet Explorer

You can solve it by following code

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

Solution 15 - Internet Explorer

I found eot file should be put beyond ttf. If it's under ttf, thought the font shows correctly, IE9 will still throw an error.

Recommend:

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

Not Recommend:

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

Solution 16 - Internet Explorer

I tried the ttfpatch tool and it didn't work form me. Internet Exploder 9 and 10 still complained.

I found this nice Git gist and it solved my issues. https://gist.github.com/stefanmaric/a5043c0998d9fc35483d

Just copy and paste the code in your css.

Solution 17 - Internet Explorer

I recently encountered this issue with .eot and .otf fonts producing the CSS3114 and CSS3111 errors in the console when loading. The solution that worked for me was to use only .woff and .woff2 formats with a .ttf format fallback. The .woff formats will be used before .ttf in most browsers and don't seem to trigger the font embedding permissions issue (css3114) and the font naming incorrect format issue (css3111). I found my solution in this extremely helpful article about the CSS3111 and CSS3114 issue, and also reading this article on using @font-face.

note: This solution does not require re-compiling, converting or editing any font files. It is a css-only solution. The font I tested with did have .eot, .otf, .woff, .woff2 and .svg versions generated for it, probably from the original .ttf source which did produce the 3114 error when i tried it, however the .woff and .woff2 files seemed to be immune to this issue.

This is what DID work for me with @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');
}

This was what triggered the errors with @font-face in 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');
}

Solution 18 - Internet Explorer

This works for me:

@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');
}

Solution 19 - Internet Explorer

If you want to do this with a Python script instead of having to run C / PHP code, here's a Python3 function that you can use to remove the embedding permissions from the font:

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")

it works, but I ended up solving the problem of loading fonts in IE by https like this this

thanks NobleUplift

Original source in C can be found here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPiotr SzmydView Question on Stackoverflow
Solution 1 - Internet ExplorerKnuView Answer on Stackoverflow
Solution 2 - Internet Exploreruser22600View Answer on Stackoverflow
Solution 3 - Internet ExplorerstefannhView Answer on Stackoverflow
Solution 4 - Internet ExplorerRenjithView Answer on Stackoverflow
Solution 5 - Internet ExplorerDanView Answer on Stackoverflow
Solution 6 - Internet ExplorerPatrick KnottView Answer on Stackoverflow
Solution 7 - Internet ExplorerFont SquirrelView Answer on Stackoverflow
Solution 8 - Internet ExplorerStack DeveloperView Answer on Stackoverflow
Solution 9 - Internet ExplorerbuijsView Answer on Stackoverflow
Solution 10 - Internet ExplorerbendytreeView Answer on Stackoverflow
Solution 11 - Internet ExplorerJoseph EarlView Answer on Stackoverflow
Solution 12 - Internet ExplorerNobleUpliftView Answer on Stackoverflow
Solution 13 - Internet ExplorerChristianView Answer on Stackoverflow
Solution 14 - Internet ExplorerWajid Ali SiddiquiView Answer on Stackoverflow
Solution 15 - Internet ExplorershisaqView Answer on Stackoverflow
Solution 16 - Internet ExplorerMark O'RussaView Answer on Stackoverflow
Solution 17 - Internet ExplorerbwigsView Answer on Stackoverflow
Solution 18 - Internet ExplorerAlena KastsiukavetsView Answer on Stackoverflow
Solution 19 - Internet ExplorerMikhail RazgovorovView Answer on Stackoverflow