Обнаруживать жирную и курсивную поддержку
Некоторые шрифты не поддерживают CSS курсивом или полужирным шрифтом (например, Zapfino не поддерживает курсив, так как он уже выглядит довольно scripty-look). Я хочу определить, когда стиль шрифта не поддерживается, поэтому я могу отключить кнопки стилизации в редакторе.
Я пробовал что-то как это:
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( );
};
но он не работает... многие шрифты, которые предоставляют курсив или полужирный, сообщают о том же ширине.
Далее, я решил обнаружить это с помощью элемента canvas, но, увы, firefox даже не делает курсивный текст в холсте, так что это означает, что эта идея.
Что бы вы предложили?
Ответы
Ответ 1
Чтобы обнаружить жирный и курсивную поддержку, вы можете преобразовать текст в изображение и сравнить его.
Способ сделать это:
- создать
canvas
См. ниже (нет необходимости добавлять его в DOM)
- нарисуйте текст в
canvas
- преобразовать холст в изображение (здесь я использую
png
)
- сравнить строку base64 изображения
Относительно canvas
:
Далее, я решил обнаружить это с помощью элемента canvas, но, увы, firefox даже не делает курсивный текст в холсте, так что это означает, что эта идея.
Некоторые шрифты не выделены курсивом в холсте в Firefox, потому что родной курсивный шрифт не существует. Другие браузеры будут пытаться использовать псевдоним (наклон) шрифта.
Просмотр в jsFiddle (эта демонстрация также проверяет шрифт 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"]));
Ответ 2
Я тестировал ваш код в jsFiddle, и он дает разные размеры для естественных веб-сайтов, таких как Georgia
и Arial
, но не для внешнего загружаемого шрифта, такого как Snowburst One
(Googlefont).
JS скрипт вашего script
После некоторых исследований выяснилось, что для загружаемых шрифтов @font-face
не применяются преобразования шрифтов css. Люди загружают варианты @font-face
и применяют их так:
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;
}
Если вы используете шрифты @font-face
, у которых есть варианты, как в приведенном выше примере, вы можете найти какое-то соглашение об именах. Затем вы можете проверить, существуют ли эти шрифты, проверяя ширину по сравнению с резервным шрифтом.
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 );
}
Если стилизованные версии имеют измененную ширину по сравнению со значением по умолчанию, то это "Бинго"!
Примечание: это не будет работать для моноширинных шрифтов, так как ширина всех символов всегда одинакова.
Ответ 3
Используя Font.js, у вас может быть более надежный доступ к метрикам шрифтов для вашего расчета. http://pomax.nihongoresources.com/pages/Font.js