Faire fonctionner les polices Adobe avec CSS3 @ font-face dans IE9

132

Je suis en train de créer une petite application intranet et j'essaie, sans succès, d'utiliser la police Adobe que j'ai achetée récemment. Comme on m'a informé, dans notre cas, ce n'est pas une violation de licence.

J'ai converti les versions .ttf / .otf de la police en .woff, .eot et .svg, afin de cibler tous les principaux navigateurs. La syntaxe @ font-face que j'ai utilisée est essentiellement la syntaxe à l'épreuve des balles de 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');
    }

J'ai modifié les en-têtes HTTP (ajouté Access-Control-Allow-Origin = "*") pour autoriser les références inter-domaines. Dans FF et Chrome, cela fonctionne parfaitement, mais dans IE9, j'obtiens:

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

J'ai remarqué que lors de la conversion de la police de .ttf / .otf en .woff, je reçois également un fichier .afm , mais je ne sais pas si c'est important ou non ...

Des idées pour y parvenir?

[Modifier] - J'héberge mes sites Web (polices aussi, mais sous un répertoire et un sous-domaine séparés pour le contenu statique) sous IIS 7.5

Piotr Szmyd
la source
16
+1 pour une question fine, intelligente et bien formulée avec tous les devoirs faits. Nous les obtenons beaucoup trop rarement ces jours-ci!
Pekka
En effet, c'est une question bien posée, mais malheureusement, un double.
Joseph Earl
1
Non, ce n'est sûrement pas un doublon, car dans les polices non Adobe, les solutions que j'ai trouvées fonctionnent parfaitement. Ce qui diffère, c'est que ce n'est pas le cas avec le référencement de polices inter-domaines, je suppose - j'obtiens "@ font-face a rencontré une erreur inconnue" avec la police .woff par opposition à "@ font-face a échoué la demande d'origine croisée" dans l'autre mentionné cas.
Piotr Szmyd
J'ai eu des problèmes avec cette ligne après avoir modifié les options d'intégration: sa url('myfont-webfont.eot?#iehack') format('eot'), suppression a résolu la dernière erreur (erreur inconnue).
Jonathan DeMarks

Réponses:

95

Je ne peux que vous expliquer comment corriger l'erreur "CSS3114".
Vous devez modifier le niveau d'intégration de votre fichier TTF.

À l'aide de l' outil approprié , vous pouvez le définir sur l' intégration installable autorisée .
Pour une version 64 bits, consultez la réponse de @ user22600 .

Knu
la source
11
Comme note pour ttfpatch, utilisez fsType = 0.
Prix ​​Collin le
11
ttfpatch n'a pas fonctionné pour moi. Erreur: la version de table doit être 0, 1 ou et est hexadécimale: 003
Don Rolling
11
intégrer fonctionne très bien. Il suffit de télécharger la source et de compiler ... c'est StackOverflow, non? Ce n'est qu'un seul fichier. :-) Pour VS2010, vous devez ajouter:#include <string.h>
Jonathan DeMarks
3
@JonathanDeMarks: Merci pour l'encouragement - ttfpatch n'a pas fonctionné pour moi non plus, mais recompiler embed.c pour 64 bits a définitivement fait l'affaire.
Peter Majeed
4
Pour ceux qui ne sont pas au fait de la compilation de programmes C sous Windows, c'est très simple. Suivez ce guide de Microsoft: msdn.microsoft.com/en-us/library/bb384838.aspx
lee_mcmullen
36

Comme l'a dit Knu, vous pouvez utiliser cet outil , mais il n'est compilé que pour MS-DOS. Je l'ai compilé pour Win64. Téléchargez .

Usage:

  1. Placez le .exe dans le même dossier que la police que vous devez modifier

  2. Accédez à ce répertoire dans la ligne de commande

  3. type embed fontname.fonttype, en remplaçant le nom de la police par le nom du fichier et le type de police par l'extension ieembed brokenFont.ttf

  4. Terminé! Votre police devrait maintenant fonctionner.

user22600
la source
Merci pour le rapport. Fixé.
user22600
Aidez-moi vraiment beaucoup. en utilisant Win64 bit exe.
imdadhusen
Mon dieu c'est incroyable. Côté pas à tout: utilisez la ligne de commande Windows et non un remplacement comme GIT BASH, je préfère généralement bash, ne fonctionne pas ici.
Halter le
voila! brillant!!
oldboy
33

Vous devez définir le format de la police ie sur 'embedded-opentype' et non sur 'eot'. Par exemple:

src: url('fontname.eot?#iefix') format('embedded-opentype')
Stefannh
la source
Merci, mais ce n'était pas le cas. Il s'agissait d'incorporer des autorisations dans la police elle-même.
Piotr Szmyd
Cela a fonctionné pour Firefox et Chrome (IE fonctionnait de toute façon). Je vous remercie!
Dmitri Mogilevski
12

J'obtenais l'erreur suivante:

CSS3114: @ font-face a échoué la vérification des autorisations d'intégration OpenType. L'autorisation doit être installable.
fontname.ttf

Après avoir utilisé le code ci-dessous, mon problème a été résolu ....

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

Merci les gars de m'aider!
Salut,
Renjith.

Renjith
la source
Je pense que votre solution fonctionne pour certaines familles de polices mais pas pour d'autres. Cela dépend du niveau d'autorisation d'incorporation de la police. Par exemple, cela ne fonctionnera pas pour la police Abadi
Philip007
Oui, cela ne faisait absolument aucune différence avec mes fichiers .ttf, j'obtenais toujours le message "L'autorisation doit être installable." Erreur. Ce qui a résolu ce problème était de lancer le .exe de Christian (ailleurs sur cette page) pour modifier les fichiers .ttf. Après avoir fait cela, IE11 serait afficher correctement les polices .ttf sur ma page Web.
Mike Gledhill
9

Essayez ceci, ajoutez ces lignes dans le web.config.

<system.webServer>
  <staticContent>
     <mimeMap fileExtension=".woff" mimeType="application/octet-stream" />
  </staticContent>
</system.webServer>
Dan
la source
Je ne pense pas que ce soit la même erreur qu'il a signalée, mais cela sera nécessaire si vous diffusez des fichiers .woffs à partir d'IIS, oui. Vous pouvez également ajouter une clé de registre pour .woff sous HKLM \ Software \ Classes et définir la valeur «Type de contenu» à cet égard. Cependant, Wikipedia dit que le type correct estapplication/font-woff .
Rup
En effet, c'est une chose différente. J'avais cette entrée - le problème était avec une police déjà téléchargée qui ne pouvait pas être ouverte dans IE en raison des autorisations intégrées.
Piotr Szmyd
Je faisais du développement dans un environnement Apache, et lorsque j'ai déplacé mes fichiers de polices vers un serveur Windows IIS, cela a résolu mon problème.
Samuel Cook
8

Une réponse différente: les problèmes juridiques.

Il y a quelques points à noter avant de faire cela. Tout d'abord, pour obtenir cette erreur, dans IE, inspectez l'élément, changez d'onglets et recherchez les erreurs, je crois que "CSS3114" apparaît dans la console.

Ce que vous devez comprendre, c'est qu'il s'agit d'un problème de licence. IE (jeu de mots) si vous essayez de charger une police qui provoque cette erreur, vous ne disposez pas des autorisations sur le fichier pour utiliser la police, et si vous n'avez pas l'autorisation, il est fort probable que vous perdiez un bataille juridique (ce qui est en soi hautement improbable) sur l'utilisation de cette police de cette manière à moins que vous ne déteniez la licence. Ainsi, vous pouvez, pour la première fois, remercier IE d'être le seul navigateur à vous dire «non», car cela vous permet au moins de savoir que vous faites quelque chose de douteux.

Cela dit, voici votre réponse:

Assurez-vous d'abord que vous utilisez le meilleur code en .css, voyez quelques-unes des autres réponses css pour cela.
Exemple d'IE 11 css (fonctionne dans tous les navigateurs modernes, il peut être nécessaire de modifier pour IE9):

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

Ensuite, assurez-vous d'avoir une police Web fonctionnelle (vous le savez probablement déjà en voyant votre police dans d'autres navigateurs). Si vous avez besoin d'un convertisseur de polices en ligne, vérifiez ici: https://onlinefontconverter.com/

Enfin, pour se débarrasser de l'erreur "CSS3114". Pour un outil en ligne, cliquez ici: https://www.andrebacklund.com/fontfixer.html

Patrick Knott
la source
L'outil en ligne l'a corrigé pour moi. Merci!
James Hibbard
7

Il est vrai que IE9 requiert que les polices TTF aient les bits d'incorporation définis sur Installable. Le générateur le fait automatiquement, mais nous bloquons actuellement les polices Adobe pour d'autres raisons. Nous pouvons lever cette restriction dans un proche avenir.

Écureuil de police
la source
7

J'ai perdu beaucoup de temps à cause de ce problème. Enfin, j'ai trouvé moi-même une excellente solution. Avant, j'utilisais uniquement la police .ttf. Mais j'ai ajouté un format de police supplémentaire .eot qui a commencé à fonctionner dans IE.

J'ai utilisé le code suivant et cela a fonctionné comme du charme dans tous les navigateurs.

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

J'espère que cela aidera quelqu'un.

Développeur de pile
la source
4

En tant qu'utilisateur Mac, je n'ai pas pu utiliser les outils de ligne de commande MS-DOS et Windows mentionnés pour corriger l'autorisation d'incorporation de polices. Cependant, j'ai découvert que vous pouvez résoudre ce problème en utilisant FontLab pour définir l'autorisation sur «Tout est autorisé». J'espère que cette recette sur la façon de définir l'autorisation de police sur Installable sur Mac OS X sera également utile pour les autres.

buijs
la source
"Je n'ai pas pu utiliser les outils de ligne de commande MS-DOS et Windows": Le code source est fourni - je m'attendrais à ce qu'il se compile simplement sur Mac?
Rup
Désolé, je voulais dire: être un utilisateur gâté du Finder OS X.
buijs
4

Si vous êtes familier avec nodejs / npm, ttembed-js est un moyen simple de définir le drapeau "intégration installable autorisée" sur une police TTF. Cela modifiera le fichier .ttf spécifié:

npm install -g ttembed-js

ttembed-js somefont.ttf
bendytree
la source
Merci - cela a très bien fonctionné pour les polices .otf qui me causaient des problèmes dans IE11.
J Sprague
3

Le problème peut être lié à la configuration de votre serveur - il peut ne pas envoyer les bons en-têtes pour les fichiers de polices. Jetez un œil à la réponse donnée à la question IE9 bloque le téléchargement de la police Web d'origine croisée .

EricLaw suggère d'ajouter ce qui suit à votre configuration Apache

<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "http://mydomain.com"
    </IfModule>
</FilesMatch>
Joseph Earl
la source
Mais ce n'est pas le même cas. J'ai lu cet article et j'ai déjà essayé la solution que vous avez fournie. Le problème vient spécifiquement des polices Adobe. J'ai essayé d'utiliser des kits de polices de Font Squirrel et ceux-ci fonctionnent parfaitement dans tous les navigateurs (IE9 aussi). Quand j'essaie d'utiliser les polices Adobe (converties aux formats appropriés) de la même manière - IE9 crie avec des erreurs ...
Piotr Szmyd
Et - ce que j'ai oublié de dire (je modifierai ma question) - j'exécute mes sites Web sous IIS 7.5.
Piotr Szmyd
Sont-ils des polices de type 1 par hasard?
Joseph Earl
Ce sont toutes des polices .ttf (TrueType) à fichier unique. Mais d'une manière ou d'une autre, j'obtiens un fichier .afm (Adobe Font Metrics) lors de la conversion au format .woff via onlinefontconverter.com. Je ne sais pas quoi faire avec ça?
Piotr Szmyd
3

Si vous voulez faire cela avec un script PHP au lieu d'avoir à exécuter du code C (ou si vous êtes sur un Mac comme moi et que vous ne pouvez pas être obligé de compiler avec Xcode seulement pour attendre un an pour qu'il s'ouvre), voici un Fonction PHP que vous pouvez utiliser pour supprimer les autorisations d'incorporation de la police:

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

Assurez-vous de sauvegarder votre fichier de police avant d'exécuter ce code et ne me blâmez pas s'il corrompt.

La source originale en C peut être trouvée ici .

NobleUplift
la source
Cela fonctionne et devrait maintenant être la réponse numéro 1. C'est dommage qu'il ait jusqu'à présent à grimper pour dépasser les anciennes réponses.
Goose le
Merci beaucoup @Goose! J'ai écrit ceci à l'origine pour mon travail, mais le code a été jeté et remplacé, donc il vit dans Stack Overflow. Fournir du code C pour un problème d'application Web n'est certainement pas idéal.
NobleUplift
@Goose je préfère le code C. Toujours. C'est donc une question de goût et c'est pourquoi cette réponse est équivalente à la réponse. Pour info, vous pouvez également utiliser CGI pour implémenter le code C dans votre site Web.
71GA le
2

Pour tous ceux qui obtiennent l'erreur: "tableversion doit être 0, 1 ou et est hexadécimal: 003" lors de l'utilisation de ttfpatch, j'ai compilé l'embed pour 64 bits. Je n'ai rien changé, j'ai juste ajouté les bibliothèques nécessaires et compilées. Utilisez à vos risques et périls.

Utilisation: ConsoleApplication1 font.ttf

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

Christian
la source
0

Vous pouvez le résoudre en suivant le code

@font-face {
  font-family: 'Font-Name';
  src: url('../fonts/Font-Name.ttf');
  src: url('../fonts/Font-Name.eot?#iefix') format('embedded-opentype');
}
wasiddiqui
la source
Non, ça ne marchera pas. Mon cas concernait strictement les polices qui ne permettaient pas l'incorporation par conception (mais avec une licence qui le permettait). Il ne s'agit donc pas de savoir comment je l'intègre. Vérifiez-le avec une police TTF qui interdit explicitement l'intégration Web et vous comprendrez mon problème.
Piotr Szmyd
0

J'ai trouvé que le eotfichier devrait être mis au-delà ttf. S'il est sous ttf, si la police s'affiche correctement, IE9 lancera toujours une erreur.

Recommander:

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

Ne pas recommander:

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

J'ai essayé l'outil ttfpatch et cela n'a pas fonctionné pour moi. Internet Exploder 9 et 10 se plaignaient toujours.

J'ai trouvé ce joli Git et cela a résolu mes problèmes. https://gist.github.com/stefanmaric/a5043c0998d9fc35483d

Copiez et collez simplement le code dans votre css.

Mark O'Russa
la source
0

J'ai récemment rencontré ce problème avec les polices .eot et .otf produisant les erreurs CSS3114 et CSS3111 dans la console lors du chargement. La solution qui a fonctionné pour moi était d'utiliser uniquement les formats .woff et .woff2 avec un format de secours .ttf. Les formats .woff seront utilisés avant .ttf dans la plupart des navigateurs et ne semblent pas déclencher le problème des autorisations d'incorporation de polices (css3114) et le problème de format incorrect de dénomination des polices (css3111). J'ai trouvé ma solution dans cet article extrêmement utile sur le problème CSS3111 et CSS3114 , et en lisant également cet article sur l'utilisation de @ font-face .

Remarque: cette solution ne nécessite pas de recompilation, de conversion ou de modification de fichiers de polices. C'est une solution uniquement css. La police avec laquelle j'ai testé avait des versions .eot, .otf, .woff, .woff2 et .svg générées pour elle, probablement à partir de la source d'origine .ttf qui a produit l'erreur 3114 lorsque je l'ai essayé, mais les .woff et. Les fichiers woff2 semblaient à l'abri de ce problème.

C'est ce qui a fonctionné pour moi avec @ 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');
}

C'est ce qui a déclenché les erreurs avec @ font-face dans 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');
}
brindilles
la source
0

Cela fonctionne pour moi:

@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');
}
Alena Kastsiukavets
la source
0

Si vous souhaitez faire cela avec un script Python au lieu d'avoir à exécuter du code C / PHP, voici une fonction Python3 que vous pouvez utiliser pour supprimer les autorisations d'incorporation de la police:

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

cela fonctionne, mais j'ai fini par résoudre le problème du chargement des polices dans IE par https comme ceci

merci NobleUplift

La source originale en C peut être trouvée ici .

Михаил Разговоров
la source