2013-01-23 17 views
11

Niektóre czcionki nie obsługują CSS kursywy lub pogrubienia (np. Zapfino nie obsługuje kursywy, ponieważ jest już dość scripty). Chcę wykryć, kiedy styl czcionki nie jest obsługiwany, więc mogę wyłączyć przyciski stylizacji w edytorze.Wykrywanie pogrubienia i kursywy wsparcie

Próbowałem coś like this:

that.checkFontData = function(fontList) 
{ var test = $("<span style='font-size:24px;absolute;visibility:hidden;height:auto;width:auto;white-space:nowrap;'>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678910</span>"); 
    $('body').append(test); 
    for (var i= 0, iMax = fontList.length; i < iMax; ++i) 
    { test.css('fontFamily', fontList[i]); 
     var normalWidth = test.outerWidth(true); 
     var normalHeight = test.outerHeight(true); 
     test.css('fontStyle', 'italic'); 
     var italicWidth = test.outerWidth(true); 
     var italicHeight = test.outerHeight(true); 
     test.css('fontStyle', 'normal'); 
     test.css('fontWeight', 'bold'); 
     var boldWidth = test.outerWidth(true); 
     var boldHeight = test.outerHeight(true); 
     console.log(fontList[i] + ", normal: " + normalWidth + ", bold: " + boldWidth + ", italic: " + italicWidth ); 
    } 
    test.remove(); 
}; 

ale to nie działa ... wiele czcionek, które zapewniają kursywa lub pogrubioną raport tych samych szerokościach.

Następnie, pomyślałem, aby wykryć to za pomocą elementu canvas, ale, niestety, firefox nie robi nawet kursywy tekstu w obszarze roboczym, więc spartaczy ten pomysł.

Co byś zasugerował?

+1

OCR, jeśli naprawdę ważne. Nie mogę wymyślić niczego lepszego – user1721135

+1

sprawdź to ręcznie, a na twardym kodzie wyniki – P1nGu1n

+2

o twardych zakodowanych wynikach, takich jak sugeruje P1nGu1n byłoby najlepszym najbardziej logicznym rozwiązaniem w moim umyśle. Prawdopodobnie kontrolujesz własne czcionki - to powinno być łatwe. – rlemon

Odpowiedz

1

Przetestowałem kod w jsFiddle, a to daje różne rozmiary naturalnych Czcionki Webfonts jak Georgia i Arial, ale nie na zewnątrz załadowanej czcionki jak Snowburst One (Googlefont).

JS fiddle of your script

Po kilku badań odkryłem, że dla @font-face załadowanych czcionek zastosować No CSS font-transformacje. Ludzie załadować wariacje @font-face i stosuje je tak:

body { font-family:"DroidSerifRegular", Georgia, serif; } 
h1 { 
    font-family:"DroidSerifBold", Georgia, serif; 
    font-weight:normal; 
} 
em { 
    font-family:"DroidSerifItalic", Georgia, serif; 
    font-weight:normal; 
    font-style:normal; 
} 
strong em { 
    font-family:"DroidSerifBoldItalic", Georgia, serif; 
    font-weight:normal; 
    font-style:normal; 
} 

Jeśli używasz @font-face czcionek, które mają wariacje jak w przykładzie powyżej, może być w stanie wymyślić jakiegoś nazewnictwo. Następnie możesz sprawdzić, czy te czcionki istnieją, sprawdzając szerokość w porównaniu do czcionki zastępczej.

test.css('fontFamily', 'sans-serif'); 
var defaultWidth = test.outerWidth(true); 

for (var i= 0, iMax = fontList.length; i < iMax; ++i) 
{ test.css('fontFamily', fontList[i] + ', sans-serif'); 

    var normalWidth = test.outerWidth(true); 
    var normalHeight = test.outerHeight(true); 
    test.css('fontFamily', fontList[i] + 'Italic, sans-serif'); 
    var italicWidth = test.outerWidth(true); 
    var italicHeight = test.outerHeight(true); 
    test.css('fontFamily', fontList[i] + 'Bold, sans-serif'); 
    var boldWidth = test.outerWidth(true); 
    var boldHeight = test.outerHeight(true); 
    console.log("default: "+ defaultWidth + ", " fontList[i] + ", normal: " + normalWidth + ", bold: " + boldWidth + ", italic: " + italicWidth ); 
} 

Jeśli wersja stylu ma zmienioną szerokość w porównaniu do wartości domyślnej, oznacza to "Bingo"!

Uwaga: to nie będzie działać w przypadku czcionek o stałej szerokości, ponieważ szerokość wszystkich znaków jest zawsze taka sama.

+0

W swojej jsfiddle, wystarczy tylko sprawdzić Georgia , nigdy Arial. Spróbuj zastąpić pierwszy wiersz 'var fontlist = [" Georgia "," Arial "];', a zobaczysz, że Arial ma te same wymiary w normalnych i pochyłych kursach. – pieroxy

+0

Naprawiłem problem z tablicą. Te same wymiary są powodowane, ponieważ style nie są usuwane po załadowaniu nowego elementu tablicy. Zaktualizowałem mój przykład, aby to naprawić. –

+0

Ah, widzę, gdzie byłem zdezorientowany. Twoja metoda Arial daje różne rozmiary w zależności od różnych kombinacji przeglądarek/systemów operacyjnych. Windows Firefox i Chrome zgłaszają różne wymiary Arial Italic, ale IE wraz ze wszystkimi przeglądarkami w systemie Linux daje te same wymiary dla Arial Italic i Arial. Więc jest to trochę uderzające i chybione ... – pieroxy

4

Aby wykryć bold i kursywy wsparcia, można przekonwertować tekst na obrazie i porównać je.

Sposobem na to jest:

  1. stworzyć canvasPoniżej (nie ma potrzeby, aby dołączyć go do DOM)
  2. rysowania tekstu w canvas
  3. konwertować płótno w produkt image (tutaj używam png)
  4. Porównaj łańcuch podstawowy64 obrazu

chodzi canvas:

Następnie pomyślałem to wykryć za pomocą elementu canvas, ale, niestety, firefox nawet nie czynią tekst pochylony w płótnie, tak że spartaczy ten pomysł.

Niektóre czcionki nie są napisane kursywą na płótnie w przeglądarce Firefox, ponieważ natywna czcionka kursywy nie istnieje. Inne przeglądarki próbowałyby pochylić czcionkę psuedo-italicize.

View on jsFiddle (to demo testuje również dla czcionki Google Snowburst One)

function detectBoldItalic(fonts) { 
    // Create canvas 
    var canvas = document.createElement('canvas'); 
    canvas.width = 1000; 
    canvas.height = 30; 
    var context = canvas.getContext("2d"); 
    var test = {}, results = {}; 
    // Default 
    context.font = "normal 16px a base case font"; 
    context.fillText("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678910", 10, 20); 
    var standard = canvas.toDataURL("image/png"); 
    context.setTransform(1, 0, 0, 1, 0, 0); 
    context.clearRect(0, 0, canvas.width, canvas.height); 
    // Start test 
    for (var i = 0; i < fonts.length; i++) { 
     var styles = ["normal", "bold", "italic"]; 
     test[fonts[i]] = {}; 
     results[fonts[i]] = {}; 
     for (var j = 0; j < styles.length; j++) { 
      // Draw text in canvas 
      context.font = styles[j] + " 16px " + fonts[i]; 
      context.fillText("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678910", 10, 20); 
      // Convert canvas to png 
      test[fonts[i]][styles[j]] = canvas.toDataURL("image/png"); 
      // Clear canvas 
      context.setTransform(1, 0, 0, 1, 0, 0); 
      context.clearRect(0, 0, canvas.width, canvas.height); 
     } 
     if (test[fonts[i]]["normal"] !== standard) { 
      results[fonts[i]]["bold"] = test[fonts[i]]["normal"] !== test[fonts[i]]["bold"] ? true:false; // Support bold 
      results[fonts[i]]["italic"] = test[fonts[i]]["normal"] !== test[fonts[i]]["italic"] ? true:false; // Support italic 
     } else { 
      results[fonts[i]] = false; // Font does not exist 
     } 
    } 
    return results; 
} 
console.log(detectBoldItalic(["Arial","Zapfino"])); 
+0

Wierzę, że nie ma możliwości określenia "font-stretch: condensed" na elemencie canvas. Dlatego uważam, że nie ma sposobu, aby wykryć obsługę kursywy/pogrubionej czcionki 'Arial Narrow' przy użyciu twojej metody. Twoja odpowiedź jest nadal najlepsza, ale z innych względów - szczególnie dlatego, że potrafi rozróżniać bardziej precyzyjnie różne style czcionek. – pieroxy