Spraw, aby czcionki Adobe działały z CSS3 @ font-face w IE9


133

Jestem w trakcie tworzenia małej aplikacji intranetowej i próbuję, bez powodzenia, użyć ostatnio zakupionej czcionki Adobe . Jak mnie poinformowano, w naszym przypadku nie jest to naruszenie licencji.

Przekonwertowałem wersje .ttf / .otf czcionki na .woff, .eot i .svg, aby kierować reklamy na wszystkie główne przeglądarki. Użyta przeze mnie składnia @ font-face jest w zasadzie kuloodporna z 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');
    }

Zmodyfikowałem nagłówki HTTP (dodałem Access-Control-Allow-Origin = "*"), aby umożliwić odwołania między domenami. W FF i Chrome działa idealnie, ale w IE9 dostaję:

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

Zauważyłem, że konwertując czcionkę z .ttf / .otf na .woff otrzymuję również plik .afm , ale nie mam pojęcia, czy to ważne, czy nie ...

Jakieś pomysły, jak to rozwiązać?

[Edytuj] - hostuję swoje witryny internetowe (również czcionki, ale w oddzielnym katalogu i poddomenie dla zawartości statycznej) w usługach IIS 7.5


16
+1 za dobre, inteligentne, dobrze sformułowane pytanie z wykonaną pracą domową. W dzisiejszych czasach tak rzadko się to zdarza!
Pekka,

W istocie jest to dobrze postawione pytanie, ale niestety jest to duplikat.
Joseph Earl

1
Nie, na pewno nie jest to duplikat, ponieważ w czcionkach innych niż Adobe rozwiązania, które znalazłem, działają idealnie. Różnica polega na tym, że tak nie jest w przypadku odwołań do czcionek międzydomenowych, jak sądzę - otrzymuję komunikat „@ font-face napotkał nieznany błąd” z czcionką .woff w przeciwieństwie do „@ font-face nieudane żądanie cross-origin request” w innym wymienionym przypadkach.
Piotr Szmyd

Miałem problemy z tą linią po zmianie opcji osadzania: url('myfont-webfont.eot?#iehack') format('eot'), Usunięcie jej rozwiązało ostatni błąd (nieznany błąd).
Jonathan DeMarks,

Odpowiedzi:


96

Mogę tylko wyjaśnić, jak naprawić błąd „CSS3114”.
Musisz zmienić poziom osadzania pliku TTF.

Za pomocą odpowiedniego narzędzia można ustawić opcję osadzania instalowalnego dozwolonego .
Dla wersji 64-bitowej, należy sprawdzić @ user22600 na odpowiedź .


11
Uwaga dotycząca ttfpatch, użyj fsType = 0.
Collin Price,

11
ttfpatch nie działa dla mnie. Błąd: wersja tabeli musi wynosić 0, 1 lub szesnastkowo: 003
Don Rolling

11
embed działa dobrze. Po prostu pobierz źródło i skompiluj ... to jest StackOverflow, prawda? To tylko jeden plik. :-) Dla VS2010 trzeba dodać:#include <string.h>
Jonathan DeMarks

3
@JonathanDeMarks: Dzięki za zachętę - ttfpatch też nie działał dla mnie, ale rekompilacja embed.c dla wersji 64-bitowej zdecydowanie załatwiła sprawę.
Peter Majeed

4
Dla tych, którzy nie potrafią kompilować programów w C w systemie Windows, jest to bardzo proste. Postępuj zgodnie z tym przewodnikiem firmy Microsoft: msdn.microsoft.com/en-us/library/bb384838.aspx
lee_mcmullen

37

Jak powiedział Knu, możesz używać tego narzędzia , jednak jest ono kompilowane tylko dla MS-DOS. Skompilowałem to dla Win64. Pobierz .

Stosowanie:

  1. Umieść plik .exe w tym samym folderze, co czcionka, którą chcesz zmodyfikować

  2. Przejdź do tego katalogu w wierszu poleceń

  3. type embed fontname.fonttype, zastępując fontname nazwą pliku, a fonttype rozszerzeniem tjembed brokenFont.ttf

  4. Gotowe! Twoja czcionka powinna teraz działać.


Dziękuję za raport. Naprawiony.
user22600

Naprawdę bardzo mi pomóż. używając Win64 bit exe.
imdadhusen

Mój Boże, to niesamowite. Strona nie dla wszystkich: użyj wiersza poleceń systemu Windows, a nie zamiennika, takiego jak GIT BASH, zwykle wolę bash, tutaj nie działa.
Halter

voila! znakomity!!
oldboy

33

Powinieneś ustawić format czcionki ie na „embedded-opentype”, a nie na „eot”. Na przykład:

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

Dzięki, ale tak się nie stało. Chodziło o osadzenie uprawnień w samej czcionce.
Piotr Szmyd

To działało w Firefoksie i Chrome (IE i tak działało). Dziękuję Ci!
Dmitri Mogilevski

12

Otrzymałem następujący błąd:

CSS3114: @ font-face nie powiodło się sprawdzenie uprawnień do osadzania OpenType. Uprawnienie musi być możliwe do zainstalowania.
fontname.ttf

Po użyciu poniższego kodu mój problem został rozwiązany ...

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

Dziękuję wam za pomoc!
Pozdrawiam,
Renjith.


Myślę, że twoje rozwiązanie działa dla niektórych rodzin czcionek, ale nie dla innych. Zależy to od poziomu uprawnień do osadzania czcionki. Na przykład to nie zadziała w przypadku czcionki Abadi
Philip007

Tak, nie miało to absolutnie żadnego znaczenia w przypadku moich plików .ttf, nadal otrzymywałem informację „Zezwolenie musi być możliwe do zainstalowania”. błąd. Tym, co rozwiązało ten problem, było uruchomienie pliku .exe Christiana (w innym miejscu na tej stronie) w celu zmodyfikowania plików .ttf. Po wykonaniu tej czynności, IE11 będzie wyświetlanie czcionek ttf na mojej stronie poprawnie.
Mike Gledhill

9

Spróbuj tego, dodaj te linie do pliku web.config.

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

Nie sądzę, że to ten sam błąd, który zgłosił, ale będzie to wymagane, jeśli obsługujesz .woffs z IIS, tak. Alternatywnie możesz dodać klucz rejestru dla .woff w HKLM \ Software \ Classes i ustawić w nim wartość „Content Type”. Jednak Wikipedia twierdzi, że poprawny typ toapplication/font-woff .
Rup

Rzeczywiście, to inna sprawa. Miałem ten wpis - problem dotyczył już pobranej czcionki, której nie można było otworzyć w IE z powodu osadzonych uprawnień.
Piotr Szmyd

Robiłem programowanie w środowisku Apache, a kiedy przeniosłem pliki czcionek na serwer Windows IIS, rozwiązało to mój problem.
Samuel Cook

8

Inna odpowiedź: kwestie prawne.

Zanim to zrobisz, należy zwrócić uwagę na kilka rzeczy. Po pierwsze, aby uzyskać ten błąd, w IE, sprawdź element, przełącz karty i poszukaj błędów. Wydaje mi się, że w konsoli pojawia się „CSS3114”.

Musisz zrozumieć, że jest to kwestia licencji. IE (zamierzona gra słów), jeśli próbujesz załadować czcionkę, która powoduje ten błąd, nie masz uprawnień do pliku, a jeśli nie masz uprawnień, jest wysoce prawdopodobne, że możesz stracić bitwa prawna (która sama w sobie jest wysoce nieprawdopodobna) nad używaniem tej czcionki w ten sposób, chyba że masz licencję. Możesz więc po raz pierwszy podziękować IE za to, że jest jedyną przeglądarką, która mówi Ci „nie”, ponieważ przynajmniej informuje Cię, że robisz coś wątpliwego.

To powiedziawszy, oto twoja odpowiedź:

Najpierw upewnij się, że używasz najlepszego kodu w .css, zobacz inne odpowiedzi CSS na ten temat.
Przykład css w IE 11 (działa we wszystkich nowoczesnych przeglądarkach, może wymagać dostosowania dla IE9):

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

Następnie upewnij się, że masz działającą czcionkę internetową (prawdopodobnie już to wiesz, widząc swoją czcionkę w innych przeglądarkach). Jeśli potrzebujesz konwertera czcionek online, sprawdź tutaj: https://onlinefontconverter.com/

Wreszcie, aby pozbyć się błędu „CSS3114”. Aby uzyskać narzędzie online, kliknij tutaj: https://www.andrebacklund.com/fontfixer.html


Narzędzie internetowe naprawiło to za mnie. Dzięki!
James Hibbard,

7

Prawdą jest, że IE9 wymaga, aby czcionki TTF miały bity osadzania ustawione na Installable. Generator robi to automatycznie, ale obecnie blokujemy czcionki Adobe z innych powodów. W najbliższej przyszłości możemy znieść to ograniczenie.


7

Zmarnowałem dużo czasu z powodu tego problemu. W końcu sam znalazłem świetne rozwiązanie. Wcześniej używałem tylko czcionki .ttf. Ale dodałem jeden dodatkowy format czcionki .eot, który zaczął działać w IE.

Użyłem następującego kodu i działało jak urok we wszystkich przeglądarkach.

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

Mam nadzieję, że to komuś pomoże.


4

Jako użytkownik Maca nie mogłem użyć narzędzi wiersza poleceń MS-DOS i Windows, o których wspomniano, aby naprawić uprawnienia do osadzania czcionek. Jednak dowiedziałem się, że możesz to naprawić za pomocą FontLab, aby ustawić uprawnienie na „Wszystko jest dozwolone”. Mam nadzieję, że ten przepis dotyczący ustawiania uprawnień do czcionek na Installable w systemie Mac OS X będzie przydatny również dla innych.


„Nie mogłem używać narzędzi wiersza poleceń MS-DOS i Windows”: Kod źródłowy jest jednak dostarczony - spodziewałbym się, że skompiluje się po prostu na Macu?
Rup

Przepraszam, chciałem powiedzieć: być zepsutym użytkownikiem systemu OS X Finder.
buijs w marcu

4

Jeśli znasz nodejs / npm, ttembed-js jest łatwym sposobem na ustawienie flagi „dozwolone osadzanie instalowalne” dla czcionki TTF. To zmodyfikuje określony plik .ttf:

npm install -g ttembed-js

ttembed-js somefont.ttf

Dzięki - to działało świetnie w przypadku czcionek .otf, które powodowały problemy w IE11.
J Sprague

3

Problem może być związany z konfiguracją serwera - może nie wysyłać odpowiednich nagłówków dla plików czcionek. Spójrz na odpowiedź udzieloną na pytanie IE9 blokuje pobieranie czcionek internetowych pochodzących z różnych źródeł .

EricLaw sugeruje dodanie następujących elementów do konfiguracji Apache

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

Ale to nie ten sam przypadek. Przeczytałem ten post i wypróbowałem już podane przez Ciebie rozwiązanie. Problem dotyczy w szczególności czcionek Adobe. Próbowałem używać zestawów czcionek z Font Squirrel i działają one doskonale we wszystkich przeglądarkach (także IE9). Kiedy próbuję używać czcionek Adobe (przekonwertowanych do odpowiednich formatów) w ten sam sposób - IE9 krzyczy z błędami ...
Piotr Szmyd

I - o czym zapomniałem powiedzieć (zmienię moje pytanie) - uruchamiam swoje strony internetowe pod IIS 7.5.
Piotr Szmyd

Czy przypadkiem są to czcionki typu 1?
Joseph Earl,

To są wszystkie jednoplikowe czcionki .ttf (TrueType). Ale w jakiś sposób otrzymuję plik .afm (Adobe Font Metrics) podczas konwersji do formatu .woff przez onlinefontconverter.com. Nie mam pojęcia, co z tym zrobić?
Piotr Szmyd

3

Jeśli chcesz to zrobić za pomocą skryptu PHP zamiast uruchamiać kod C (lub jesteś na komputerze Mac, takim jak ja i nie możesz kompilować z Xcode tylko po to, aby poczekać rok na otwarcie), oto Funkcja PHP, której możesz użyć do usunięcia uprawnień osadzania z czcionki:

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

Upewnij się, że wykonałeś kopię zapasową pliku czcionki przed uruchomieniem tego kodu i nie obwiniaj mnie, jeśli jest uszkodzony.

Oryginalne źródło w C można znaleźć tutaj .


To działa i teraz powinno być odpowiedzią numer 1. Szkoda, że ​​tak daleko musi się wspiąć, aby wyprzedzić starsze odpowiedzi.
Goose

Wielkie dzięki @Goose! Pierwotnie napisałem to dla swojej pracy, ale kod został wyrzucony i zastąpiony, więc żyje w Stack Overflow. Dostarczanie kodu C dla problemu z aplikacją internetową zdecydowanie nie jest idealne.
NobleUplift

@Goose I perfer C. code. Zawsze. Jest to więc kwestia gustu i dlatego ta odpowiedź jest równoważna odpowiedzi. FYI, możesz również użyć CGI do zaimplementowania kodu C na swojej stronie internetowej.
71GA


0

Możesz go rozwiązać, postępując zgodnie z kodem

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

Nie, to nie zadziała. Mój przypadek dotyczył wyłącznie czcionek, które nie pozwalały na osadzanie zgodnie z projektem (ale z licencją, która na to pozwala). Więc nie chodzi o to, jak go osadzę. Sprawdź to za pomocą czcionki TTF, która wyraźnie zabrania osadzania w Internecie, a zrozumiesz mój problem.
Piotr Szmyd

0

Znalazłem eotplik powinien zostać umieszczony poza ttf. Jeśli jest poniżej ttf, myślę, że czcionka wyświetla się poprawnie, IE9 nadal będzie zgłaszać błąd.

Polecić:

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

Nie polecam:

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


0

Niedawno napotkałem ten problem z czcionkami .eot i .otf, powodując błędy CSS3114 i CSS3111 w konsoli podczas ładowania. Rozwiązaniem, które zadziałało, było użycie tylko formatów .woff i .woff2 z rezerwą formatu .ttf. Formaty .woff będą używane przed .ttf w większości przeglądarek i nie wydają się powodować problemu z uprawnieniami do osadzania czcionek (css3114) i nieprawidłowego formatu nazewnictwa czcionek (css3111). Znalazłem swoje rozwiązanie w tym niezwykle pomocnym artykule o problemie CSS3111 i CSS3114 , a także przeczytałem ten artykuł o używaniu @ font-face .

Uwaga: To rozwiązanie nie wymaga ponownej kompilacji, konwersji ani edycji żadnych plików czcionek. To jest tylko rozwiązanie CSS. Czcionka, z którą testowałem, miała wygenerowane dla niej wersje .eot, .otf, .woff, .woff2 i .svg, prawdopodobnie z oryginalnego źródła .ttf, które spowodowało błąd 3114, kiedy go wypróbowałem, jednak .woff i. Pliki woff2 wydawały się być odporne na ten problem.

Oto, co DZIAŁAŁO dla mnie z @ 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');
}

To właśnie spowodowało błędy z @ font-face w 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');
}

0

To działa dla mnie:

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

0

Jeśli chcesz to zrobić za pomocą skryptu w Pythonie zamiast uruchamiać kod C / PHP, oto funkcja Python3, której możesz użyć do usunięcia uprawnień osadzania z czcionki:

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

działa, ale skończyło się na rozwiązaniu problemu ładowania czcionek w IE przez https w ten sposób

dzięki NobleUplift

Oryginalne źródło w C można znaleźć tutaj .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.